]> Git Repo - linux.git/blob - tools/lib/api/fs/fs.c
selinux: Remove security_ops extern
[linux.git] / tools / lib / api / fs / fs.c
1 /* TODO merge/factor in debugfs.c here */
2
3 #include <ctype.h>
4 #include <errno.h>
5 #include <stdbool.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/vfs.h>
10
11 #include "debugfs.h"
12 #include "fs.h"
13
14 static const char * const sysfs__fs_known_mountpoints[] = {
15         "/sys",
16         0,
17 };
18
19 static const char * const procfs__known_mountpoints[] = {
20         "/proc",
21         0,
22 };
23
24 struct fs {
25         const char              *name;
26         const char * const      *mounts;
27         char                     path[PATH_MAX + 1];
28         bool                     found;
29         long                     magic;
30 };
31
32 enum {
33         FS__SYSFS  = 0,
34         FS__PROCFS = 1,
35 };
36
37 static struct fs fs__entries[] = {
38         [FS__SYSFS] = {
39                 .name   = "sysfs",
40                 .mounts = sysfs__fs_known_mountpoints,
41                 .magic  = SYSFS_MAGIC,
42         },
43         [FS__PROCFS] = {
44                 .name   = "proc",
45                 .mounts = procfs__known_mountpoints,
46                 .magic  = PROC_SUPER_MAGIC,
47         },
48 };
49
50 static 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
72 static 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
84 static 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
101 static 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  */
115 static 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
134 static const char *fs__get_mountpoint(struct fs *fs)
135 {
136         if (fs__env_override(fs))
137                 return fs->path;
138
139         if (fs__check_mounts(fs))
140                 return fs->path;
141
142         if (fs__read_mounts(fs))
143                 return fs->path;
144
145         return NULL;
146 }
147
148 static const char *fs__mountpoint(int idx)
149 {
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
158 #define FS__MOUNTPOINT(name, idx)       \
159 const char *name##__mountpoint(void)    \
160 {                                       \
161         return fs__mountpoint(idx);     \
162 }
163
164 FS__MOUNTPOINT(sysfs,  FS__SYSFS);
165 FS__MOUNTPOINT(procfs, FS__PROCFS);
This page took 0.039471 seconds and 4 git commands to generate.