xref: /openbmc/linux/tools/lib/api/fs/fs.c (revision b34e08d5)
1 /* TODO merge/factor in debugfs.c here */
2 
3 #include <errno.h>
4 #include <stdbool.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <sys/vfs.h>
8 
9 #include "debugfs.h"
10 #include "fs.h"
11 
12 static const char * const sysfs__fs_known_mountpoints[] = {
13 	"/sys",
14 	0,
15 };
16 
17 static const char * const procfs__known_mountpoints[] = {
18 	"/proc",
19 	0,
20 };
21 
22 struct fs {
23 	const char		*name;
24 	const char * const	*mounts;
25 	char			 path[PATH_MAX + 1];
26 	bool			 found;
27 	long			 magic;
28 };
29 
30 enum {
31 	FS__SYSFS  = 0,
32 	FS__PROCFS = 1,
33 };
34 
35 static struct fs fs__entries[] = {
36 	[FS__SYSFS] = {
37 		.name	= "sysfs",
38 		.mounts	= sysfs__fs_known_mountpoints,
39 		.magic	= SYSFS_MAGIC,
40 	},
41 	[FS__PROCFS] = {
42 		.name	= "proc",
43 		.mounts	= procfs__known_mountpoints,
44 		.magic	= PROC_SUPER_MAGIC,
45 	},
46 };
47 
48 static bool fs__read_mounts(struct fs *fs)
49 {
50 	bool found = false;
51 	char type[100];
52 	FILE *fp;
53 
54 	fp = fopen("/proc/mounts", "r");
55 	if (fp == NULL)
56 		return NULL;
57 
58 	while (!found &&
59 	       fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n",
60 		      fs->path, type) == 2) {
61 
62 		if (strcmp(type, fs->name) == 0)
63 			found = true;
64 	}
65 
66 	fclose(fp);
67 	return fs->found = found;
68 }
69 
70 static int fs__valid_mount(const char *fs, long magic)
71 {
72 	struct statfs st_fs;
73 
74 	if (statfs(fs, &st_fs) < 0)
75 		return -ENOENT;
76 	else if (st_fs.f_type != magic)
77 		return -ENOENT;
78 
79 	return 0;
80 }
81 
82 static bool fs__check_mounts(struct fs *fs)
83 {
84 	const char * const *ptr;
85 
86 	ptr = fs->mounts;
87 	while (*ptr) {
88 		if (fs__valid_mount(*ptr, fs->magic) == 0) {
89 			fs->found = true;
90 			strcpy(fs->path, *ptr);
91 			return true;
92 		}
93 		ptr++;
94 	}
95 
96 	return false;
97 }
98 
99 static const char *fs__get_mountpoint(struct fs *fs)
100 {
101 	if (fs__check_mounts(fs))
102 		return fs->path;
103 
104 	return fs__read_mounts(fs) ? fs->path : NULL;
105 }
106 
107 static const char *fs__mountpoint(int idx)
108 {
109 	struct fs *fs = &fs__entries[idx];
110 
111 	if (fs->found)
112 		return (const char *)fs->path;
113 
114 	return fs__get_mountpoint(fs);
115 }
116 
117 #define FS__MOUNTPOINT(name, idx)	\
118 const char *name##__mountpoint(void)	\
119 {					\
120 	return fs__mountpoint(idx);	\
121 }
122 
123 FS__MOUNTPOINT(sysfs,  FS__SYSFS);
124 FS__MOUNTPOINT(procfs, FS__PROCFS);
125