1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2018 Intel Corporation. 3 * Copyright(c) 2012-2014 6WIND S.A. 4 */ 5 6 #include <errno.h> 7 #include <limits.h> 8 #include <stddef.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <sys/stat.h> 13 #include <sys/types.h> 14 #include <unistd.h> 15 16 #include <rte_common.h> 17 #include <rte_log.h> 18 19 #include "eal_private.h" 20 #include "eal_filesystem.h" 21 22 int eal_create_runtime_dir(void) 23 { 24 const char *directory; 25 char run_dir[PATH_MAX]; 26 char tmp[PATH_MAX]; 27 int ret; 28 29 /* from RuntimeDirectory= see systemd.exec */ 30 directory = getenv("RUNTIME_DIRECTORY"); 31 if (directory == NULL) { 32 /* 33 * Used standard convention defined in 34 * XDG Base Directory Specification and 35 * Filesystem Hierarchy Standard. 36 */ 37 if (getuid() == 0) 38 directory = "/var/run"; 39 else 40 directory = getenv("XDG_RUNTIME_DIR") ? : "/tmp"; 41 } 42 43 /* create DPDK subdirectory under runtime dir */ 44 ret = snprintf(tmp, sizeof(tmp), "%s/dpdk", directory); 45 if (ret < 0 || ret == sizeof(tmp)) { 46 RTE_LOG(ERR, EAL, "Error creating DPDK runtime path name\n"); 47 return -1; 48 } 49 50 /* create prefix-specific subdirectory under DPDK runtime dir */ 51 ret = snprintf(run_dir, sizeof(run_dir), "%s/%s", 52 tmp, eal_get_hugefile_prefix()); 53 if (ret < 0 || ret == sizeof(run_dir)) { 54 RTE_LOG(ERR, EAL, "Error creating prefix-specific runtime path name\n"); 55 return -1; 56 } 57 58 /* create the path if it doesn't exist. no "mkdir -p" here, so do it 59 * step by step. 60 */ 61 ret = mkdir(tmp, 0700); 62 if (ret < 0 && errno != EEXIST) { 63 RTE_LOG(ERR, EAL, "Error creating '%s': %s\n", 64 tmp, strerror(errno)); 65 return -1; 66 } 67 68 ret = mkdir(run_dir, 0700); 69 if (ret < 0 && errno != EEXIST) { 70 RTE_LOG(ERR, EAL, "Error creating '%s': %s\n", 71 run_dir, strerror(errno)); 72 return -1; 73 } 74 75 if (eal_set_runtime_dir(run_dir)) 76 return -1; 77 78 return 0; 79 } 80 81 /* parse a sysfs (or other) file containing one integer value */ 82 int eal_parse_sysfs_value(const char *filename, unsigned long *val) 83 { 84 FILE *f; 85 char buf[BUFSIZ]; 86 char *end = NULL; 87 88 if ((f = fopen(filename, "r")) == NULL) { 89 RTE_LOG(ERR, EAL, "%s(): cannot open sysfs value %s\n", 90 __func__, filename); 91 return -1; 92 } 93 94 if (fgets(buf, sizeof(buf), f) == NULL) { 95 RTE_LOG(ERR, EAL, "%s(): cannot read sysfs value %s\n", 96 __func__, filename); 97 fclose(f); 98 return -1; 99 } 100 *val = strtoul(buf, &end, 0); 101 if ((buf[0] == '\0') || (end == NULL) || (*end != '\n')) { 102 RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs value %s\n", 103 __func__, filename); 104 fclose(f); 105 return -1; 106 } 107 fclose(f); 108 return 0; 109 } 110