xref: /dpdk/lib/eal/unix/eal_filesystem.c (revision f4eac3a09c51a1a2dab1f2fd3a10fe0619286a0d)
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