blob: c1b49c36a951d74b1c12b417b20428b0f4326e70 [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
Cody P Schaferf2d96272014-05-27 17:21:56 -07003#include <ctype.h>
Borislav Petkovcd0cfad2013-12-09 17:14:24 +01004#include <errno.h>
5#include <stdbool.h>
6#include <stdio.h>
Cody P Schaferf2d96272014-05-27 17:21:56 -07007#include <stdlib.h>
Borislav Petkovcd0cfad2013-12-09 17:14:24 +01008#include <string.h>
9#include <sys/vfs.h>
Jiri Olsa4299a542013-11-05 15:14:45 +010010
Borislav Petkovcd0cfad2013-12-09 17:14:24 +010011#include "debugfs.h"
12#include "fs.h"
Jiri Olsa4299a542013-11-05 15:14:45 +010013
14static const char * const sysfs__fs_known_mountpoints[] = {
15 "/sys",
16 0,
17};
18
Jiri Olsaa9862412013-11-05 15:14:46 +010019static const char * const procfs__known_mountpoints[] = {
20 "/proc",
21 0,
22};
23
Jiri Olsa4299a542013-11-05 15:14:45 +010024struct fs {
25 const char *name;
26 const char * const *mounts;
27 char path[PATH_MAX + 1];
28 bool found;
29 long magic;
30};
31
32enum {
Jiri Olsaa9862412013-11-05 15:14:46 +010033 FS__SYSFS = 0,
34 FS__PROCFS = 1,
Jiri Olsa4299a542013-11-05 15:14:45 +010035};
36
37static struct fs fs__entries[] = {
38 [FS__SYSFS] = {
39 .name = "sysfs",
40 .mounts = sysfs__fs_known_mountpoints,
41 .magic = SYSFS_MAGIC,
42 },
Jiri Olsaa9862412013-11-05 15:14:46 +010043 [FS__PROCFS] = {
44 .name = "proc",
45 .mounts = procfs__known_mountpoints,
46 .magic = PROC_SUPER_MAGIC,
47 },
Jiri Olsa4299a542013-11-05 15:14:45 +010048};
49
50static bool fs__read_mounts(struct fs *fs)
51{
52 bool found = false;
53 char type[100];
54 FILE *fp;
55
56 fp = fopen("/proc/mounts", "r");
57 if (fp == NULL)
58 return NULL;
59
60 while (!found &&
61 fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n",
62 fs->path, type) == 2) {
63
64 if (strcmp(type, fs->name) == 0)
65 found = true;
66 }
67
68 fclose(fp);
69 return fs->found = found;
70}
71
72static int fs__valid_mount(const char *fs, long magic)
73{
74 struct statfs st_fs;
75
76 if (statfs(fs, &st_fs) < 0)
77 return -ENOENT;
78 else if (st_fs.f_type != magic)
79 return -ENOENT;
80
81 return 0;
82}
83
84static bool fs__check_mounts(struct fs *fs)
85{
86 const char * const *ptr;
87
88 ptr = fs->mounts;
89 while (*ptr) {
90 if (fs__valid_mount(*ptr, fs->magic) == 0) {
91 fs->found = true;
92 strcpy(fs->path, *ptr);
93 return true;
94 }
95 ptr++;
96 }
97
98 return false;
99}
100
Cody P Schaferf2d96272014-05-27 17:21:56 -0700101static void mem_toupper(char *f, size_t len)
102{
103 while (len) {
104 *f = toupper(*f);
105 f++;
106 len--;
107 }
108}
109
110/*
111 * Check for "NAME_PATH" environment variable to override fs location (for
112 * testing). This matches the recommendation in Documentation/sysfs-rules.txt
113 * for SYSFS_PATH.
114 */
115static bool fs__env_override(struct fs *fs)
116{
117 char *override_path;
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");
124
125 override_path = getenv(upper_name);
126 if (!override_path)
127 return false;
128
129 fs->found = true;
130 strncpy(fs->path, override_path, sizeof(fs->path));
131 return true;
132}
133
Jiri Olsa4299a542013-11-05 15:14:45 +0100134static const char *fs__get_mountpoint(struct fs *fs)
135{
Cody P Schaferf2d96272014-05-27 17:21:56 -0700136 if (fs__env_override(fs))
137 return fs->path;
138
Jiri Olsa4299a542013-11-05 15:14:45 +0100139 if (fs__check_mounts(fs))
140 return fs->path;
141
Cody P Schaferf2d96272014-05-27 17:21:56 -0700142 if (fs__read_mounts(fs))
143 return fs->path;
144
145 return NULL;
Jiri Olsa4299a542013-11-05 15:14:45 +0100146}
147
Arnaldo Carvalho de Melocf38fad2013-11-05 14:48:50 -0300148static const char *fs__mountpoint(int idx)
Jiri Olsa4299a542013-11-05 15:14:45 +0100149{
150 struct fs *fs = &fs__entries[idx];
151
152 if (fs->found)
153 return (const char *)fs->path;
154
155 return fs__get_mountpoint(fs);
156}
157
Arnaldo Carvalho de Melocf38fad2013-11-05 14:48:50 -0300158#define FS__MOUNTPOINT(name, idx) \
159const char *name##__mountpoint(void) \
160{ \
161 return fs__mountpoint(idx); \
Jiri Olsa4299a542013-11-05 15:14:45 +0100162}
163
Jiri Olsaa9862412013-11-05 15:14:46 +0100164FS__MOUNTPOINT(sysfs, FS__SYSFS);
165FS__MOUNTPOINT(procfs, FS__PROCFS);