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