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