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