blob: 5b5eb788996e1de2f105eeedffdc1bb0cb72caba [file] [log] [blame]
Borislav Petkovcd0cfad2013-12-09 17:14:24 +01001/* TODO merge/factor in debugfs.c here */
Jiri Olsa4299a542013-11-05 15:14:45 +01002
Borislav Petkovcd0cfad2013-12-09 17:14:24 +01003#include <errno.h>
4#include <stdbool.h>
5#include <stdio.h>
6#include <string.h>
7#include <sys/vfs.h>
Jiri Olsa4299a542013-11-05 15:14:45 +01008
Borislav Petkovcd0cfad2013-12-09 17:14:24 +01009#include "debugfs.h"
10#include "fs.h"
Jiri Olsa4299a542013-11-05 15:14:45 +010011
12static const char * const sysfs__fs_known_mountpoints[] = {
13 "/sys",
14 0,
15};
16
Jiri Olsaa9862412013-11-05 15:14:46 +010017static const char * const procfs__known_mountpoints[] = {
18 "/proc",
19 0,
20};
21
Jiri Olsa4299a542013-11-05 15:14:45 +010022struct fs {
23 const char *name;
24 const char * const *mounts;
25 char path[PATH_MAX + 1];
26 bool found;
27 long magic;
28};
29
30enum {
Jiri Olsaa9862412013-11-05 15:14:46 +010031 FS__SYSFS = 0,
32 FS__PROCFS = 1,
Jiri Olsa4299a542013-11-05 15:14:45 +010033};
34
35static struct fs fs__entries[] = {
36 [FS__SYSFS] = {
37 .name = "sysfs",
38 .mounts = sysfs__fs_known_mountpoints,
39 .magic = SYSFS_MAGIC,
40 },
Jiri Olsaa9862412013-11-05 15:14:46 +010041 [FS__PROCFS] = {
42 .name = "proc",
43 .mounts = procfs__known_mountpoints,
44 .magic = PROC_SUPER_MAGIC,
45 },
Jiri Olsa4299a542013-11-05 15:14:45 +010046};
47
48static 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
70static 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
82static 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
99static 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
Arnaldo Carvalho de Melocf38fad2013-11-05 14:48:50 -0300107static const char *fs__mountpoint(int idx)
Jiri Olsa4299a542013-11-05 15:14:45 +0100108{
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
Arnaldo Carvalho de Melocf38fad2013-11-05 14:48:50 -0300117#define FS__MOUNTPOINT(name, idx) \
118const char *name##__mountpoint(void) \
119{ \
120 return fs__mountpoint(idx); \
Jiri Olsa4299a542013-11-05 15:14:45 +0100121}
122
Jiri Olsaa9862412013-11-05 15:14:46 +0100123FS__MOUNTPOINT(sysfs, FS__SYSFS);
124FS__MOUNTPOINT(procfs, FS__PROCFS);