Blame view

tools/lib/api/fs/fs.c 3.44 KB
cd0cfad74   Borislav Petkov   perf tools: Move ...
1
  /* TODO merge/factor in debugfs.c here */
4299a5499   Jiri Olsa   perf tools: Facto...
2

f2d9627b2   Cody P Schafer   perf tools: Allow...
3
  #include <ctype.h>
cd0cfad74   Borislav Petkov   perf tools: Move ...
4
5
6
  #include <errno.h>
  #include <stdbool.h>
  #include <stdio.h>
f2d9627b2   Cody P Schafer   perf tools: Allow...
7
  #include <stdlib.h>
cd0cfad74   Borislav Petkov   perf tools: Move ...
8
9
  #include <string.h>
  #include <sys/vfs.h>
3a351127c   Arnaldo Carvalho de Melo   tools lib fs: Ado...
10
11
12
13
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <fcntl.h>
  #include <unistd.h>
4299a5499   Jiri Olsa   perf tools: Facto...
14

cd0cfad74   Borislav Petkov   perf tools: Move ...
15
16
  #include "debugfs.h"
  #include "fs.h"
4299a5499   Jiri Olsa   perf tools: Facto...
17
18
19
20
21
  
  static const char * const sysfs__fs_known_mountpoints[] = {
  	"/sys",
  	0,
  };
a98624185   Jiri Olsa   perf fs: Add proc...
22
23
24
25
  static const char * const procfs__known_mountpoints[] = {
  	"/proc",
  	0,
  };
4299a5499   Jiri Olsa   perf tools: Facto...
26
27
28
29
30
31
32
33
34
  struct fs {
  	const char		*name;
  	const char * const	*mounts;
  	char			 path[PATH_MAX + 1];
  	bool			 found;
  	long			 magic;
  };
  
  enum {
a98624185   Jiri Olsa   perf fs: Add proc...
35
36
  	FS__SYSFS  = 0,
  	FS__PROCFS = 1,
4299a5499   Jiri Olsa   perf tools: Facto...
37
38
39
40
41
42
43
44
  };
  
  static struct fs fs__entries[] = {
  	[FS__SYSFS] = {
  		.name	= "sysfs",
  		.mounts	= sysfs__fs_known_mountpoints,
  		.magic	= SYSFS_MAGIC,
  	},
a98624185   Jiri Olsa   perf fs: Add proc...
45
46
47
48
49
  	[FS__PROCFS] = {
  		.name	= "proc",
  		.mounts	= procfs__known_mountpoints,
  		.magic	= PROC_SUPER_MAGIC,
  	},
4299a5499   Jiri Olsa   perf tools: Facto...
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
  };
  
  static bool fs__read_mounts(struct fs *fs)
  {
  	bool found = false;
  	char type[100];
  	FILE *fp;
  
  	fp = fopen("/proc/mounts", "r");
  	if (fp == NULL)
  		return NULL;
  
  	while (!found &&
  	       fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d
  ",
  		      fs->path, type) == 2) {
  
  		if (strcmp(type, fs->name) == 0)
  			found = true;
  	}
  
  	fclose(fp);
  	return fs->found = found;
  }
  
  static int fs__valid_mount(const char *fs, long magic)
  {
  	struct statfs st_fs;
  
  	if (statfs(fs, &st_fs) < 0)
  		return -ENOENT;
  	else if (st_fs.f_type != magic)
  		return -ENOENT;
  
  	return 0;
  }
  
  static bool fs__check_mounts(struct fs *fs)
  {
  	const char * const *ptr;
  
  	ptr = fs->mounts;
  	while (*ptr) {
  		if (fs__valid_mount(*ptr, fs->magic) == 0) {
  			fs->found = true;
  			strcpy(fs->path, *ptr);
  			return true;
  		}
  		ptr++;
  	}
  
  	return false;
  }
f2d9627b2   Cody P Schafer   perf tools: Allow...
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
  static void mem_toupper(char *f, size_t len)
  {
  	while (len) {
  		*f = toupper(*f);
  		f++;
  		len--;
  	}
  }
  
  /*
   * Check for "NAME_PATH" environment variable to override fs location (for
   * testing). This matches the recommendation in Documentation/sysfs-rules.txt
   * for SYSFS_PATH.
   */
  static bool fs__env_override(struct fs *fs)
  {
  	char *override_path;
  	size_t name_len = strlen(fs->name);
  	/* name + "_PATH" + '\0' */
  	char upper_name[name_len + 5 + 1];
  	memcpy(upper_name, fs->name, name_len);
  	mem_toupper(upper_name, name_len);
  	strcpy(&upper_name[name_len], "_PATH");
  
  	override_path = getenv(upper_name);
  	if (!override_path)
  		return false;
  
  	fs->found = true;
  	strncpy(fs->path, override_path, sizeof(fs->path));
  	return true;
  }
4299a5499   Jiri Olsa   perf tools: Facto...
135
136
  static const char *fs__get_mountpoint(struct fs *fs)
  {
f2d9627b2   Cody P Schafer   perf tools: Allow...
137
138
  	if (fs__env_override(fs))
  		return fs->path;
4299a5499   Jiri Olsa   perf tools: Facto...
139
140
  	if (fs__check_mounts(fs))
  		return fs->path;
f2d9627b2   Cody P Schafer   perf tools: Allow...
141
142
143
144
  	if (fs__read_mounts(fs))
  		return fs->path;
  
  	return NULL;
4299a5499   Jiri Olsa   perf tools: Facto...
145
  }
cf38fadad   Arnaldo Carvalho de Melo   perf fs: Rename N...
146
  static const char *fs__mountpoint(int idx)
4299a5499   Jiri Olsa   perf tools: Facto...
147
148
149
150
151
152
153
154
  {
  	struct fs *fs = &fs__entries[idx];
  
  	if (fs->found)
  		return (const char *)fs->path;
  
  	return fs__get_mountpoint(fs);
  }
cf38fadad   Arnaldo Carvalho de Melo   perf fs: Rename N...
155
156
157
158
  #define FS__MOUNTPOINT(name, idx)	\
  const char *name##__mountpoint(void)	\
  {					\
  	return fs__mountpoint(idx);	\
4299a5499   Jiri Olsa   perf tools: Facto...
159
  }
a98624185   Jiri Olsa   perf fs: Add proc...
160
161
  FS__MOUNTPOINT(sysfs,  FS__SYSFS);
  FS__MOUNTPOINT(procfs, FS__PROCFS);
3a351127c   Arnaldo Carvalho de Melo   tools lib fs: Ado...
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
  
  int filename__read_int(const char *filename, int *value)
  {
  	char line[64];
  	int fd = open(filename, O_RDONLY), err = -1;
  
  	if (fd < 0)
  		return -1;
  
  	if (read(fd, line, sizeof(line)) > 0) {
  		*value = atoi(line);
  		err = 0;
  	}
  
  	close(fd);
  	return err;
  }
42e3c4a12   Arnaldo Carvalho de Melo   tools lib fs: Add...
179
180
181
182
183
184
185
186
187
188
189
190
191
  
  int sysctl__read_int(const char *sysctl, int *value)
  {
  	char path[PATH_MAX];
  	const char *procfs = procfs__mountpoint();
  
  	if (!procfs)
  		return -1;
  
  	snprintf(path, sizeof(path), "%s/sys/%s", procfs, sysctl);
  
  	return filename__read_int(path, value);
  }