1 /* TODO merge/factor in debugfs.c here */
14 static const char * const sysfs__fs_known_mountpoints[] = {
19 static const char * const procfs__known_mountpoints[] = {
26 const char * const *mounts;
27 char path[PATH_MAX + 1];
37 static struct fs fs__entries[] = {
40 .mounts = sysfs__fs_known_mountpoints,
45 .mounts = procfs__known_mountpoints,
46 .magic = PROC_SUPER_MAGIC,
50 static bool fs__read_mounts(struct fs *fs)
56 fp = fopen("/proc/mounts", "r");
61 fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n",
62 fs->path, type) == 2) {
64 if (strcmp(type, fs->name) == 0)
69 return fs->found = found;
72 static int fs__valid_mount(const char *fs, long magic)
76 if (statfs(fs, &st_fs) < 0)
78 else if (st_fs.f_type != magic)
84 static bool fs__check_mounts(struct fs *fs)
86 const char * const *ptr;
90 if (fs__valid_mount(*ptr, fs->magic) == 0) {
92 strcpy(fs->path, *ptr);
101 static void mem_toupper(char *f, size_t len)
111 * Check for "NAME_PATH" environment variable to override fs location (for
112 * testing). This matches the recommendation in Documentation/sysfs-rules.txt
115 static bool fs__env_override(struct fs *fs)
118 size_t name_len = strlen(fs->name);
119 /* name + "_PATH" + '\0' */
120 char upper_name[name_len + 5 + 1];
121 memcpy(upper_name, fs->name, name_len);
122 mem_toupper(upper_name, name_len);
123 strcpy(&upper_name[name_len], "_PATH");
125 override_path = getenv(upper_name);
130 strncpy(fs->path, override_path, sizeof(fs->path));
134 static const char *fs__get_mountpoint(struct fs *fs)
136 if (fs__env_override(fs))
139 if (fs__check_mounts(fs))
142 if (fs__read_mounts(fs))
148 static const char *fs__mountpoint(int idx)
150 struct fs *fs = &fs__entries[idx];
153 return (const char *)fs->path;
155 return fs__get_mountpoint(fs);
158 #define FS__MOUNTPOINT(name, idx) \
159 const char *name##__mountpoint(void) \
161 return fs__mountpoint(idx); \
164 FS__MOUNTPOINT(sysfs, FS__SYSFS);
165 FS__MOUNTPOINT(procfs, FS__PROCFS);