]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - tools/perf/util/fs.c
perf tools: Factor sysfs code into generic fs object
[karo-tx-linux.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 struct fs {
13         const char              *name;
14         const char * const      *mounts;
15         char                     path[PATH_MAX + 1];
16         bool                     found;
17         long                     magic;
18 };
19
20 enum {
21         FS__SYSFS = 0,
22 };
23
24 static struct fs fs__entries[] = {
25         [FS__SYSFS] = {
26                 .name   = "sysfs",
27                 .mounts = sysfs__fs_known_mountpoints,
28                 .magic  = SYSFS_MAGIC,
29         },
30 };
31
32 static bool fs__read_mounts(struct fs *fs)
33 {
34         bool found = false;
35         char type[100];
36         FILE *fp;
37
38         fp = fopen("/proc/mounts", "r");
39         if (fp == NULL)
40                 return NULL;
41
42         while (!found &&
43                fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n",
44                       fs->path, type) == 2) {
45
46                 if (strcmp(type, fs->name) == 0)
47                         found = true;
48         }
49
50         fclose(fp);
51         return fs->found = found;
52 }
53
54 static int fs__valid_mount(const char *fs, long magic)
55 {
56         struct statfs st_fs;
57
58         if (statfs(fs, &st_fs) < 0)
59                 return -ENOENT;
60         else if (st_fs.f_type != magic)
61                 return -ENOENT;
62
63         return 0;
64 }
65
66 static bool fs__check_mounts(struct fs *fs)
67 {
68         const char * const *ptr;
69
70         ptr = fs->mounts;
71         while (*ptr) {
72                 if (fs__valid_mount(*ptr, fs->magic) == 0) {
73                         fs->found = true;
74                         strcpy(fs->path, *ptr);
75                         return true;
76                 }
77                 ptr++;
78         }
79
80         return false;
81 }
82
83 static const char *fs__get_mountpoint(struct fs *fs)
84 {
85         if (fs__check_mounts(fs))
86                 return fs->path;
87
88         return fs__read_mounts(fs) ? fs->path : NULL;
89 }
90
91 static const char *fs__find_mountpoint(int idx)
92 {
93         struct fs *fs = &fs__entries[idx];
94
95         if (fs->found)
96                 return (const char *)fs->path;
97
98         return fs__get_mountpoint(fs);
99 }
100
101 #define FIND_MOUNTPOINT(name, idx)              \
102 const char *name##_find_mountpoint(void)        \
103 {                                               \
104         return fs__find_mountpoint(idx);        \
105 }
106
107 FIND_MOUNTPOINT(sysfs, FS__SYSFS);