at v2.6.33 241 lines 4.6 kB view raw
1#include "util.h" 2#include "debugfs.h" 3#include "cache.h" 4 5static int debugfs_premounted; 6static char debugfs_mountpoint[MAX_PATH+1]; 7 8static const char *debugfs_known_mountpoints[] = { 9 "/sys/kernel/debug/", 10 "/debug/", 11 0, 12}; 13 14/* use this to force a umount */ 15void debugfs_force_cleanup(void) 16{ 17 debugfs_find_mountpoint(); 18 debugfs_premounted = 0; 19 debugfs_umount(); 20} 21 22/* construct a full path to a debugfs element */ 23int debugfs_make_path(const char *element, char *buffer, int size) 24{ 25 int len; 26 27 if (strlen(debugfs_mountpoint) == 0) { 28 buffer[0] = '\0'; 29 return -1; 30 } 31 32 len = strlen(debugfs_mountpoint) + strlen(element) + 1; 33 if (len >= size) 34 return len+1; 35 36 snprintf(buffer, size-1, "%s/%s", debugfs_mountpoint, element); 37 return 0; 38} 39 40static int debugfs_found; 41 42/* find the path to the mounted debugfs */ 43const char *debugfs_find_mountpoint(void) 44{ 45 const char **ptr; 46 char type[100]; 47 FILE *fp; 48 49 if (debugfs_found) 50 return (const char *) debugfs_mountpoint; 51 52 ptr = debugfs_known_mountpoints; 53 while (*ptr) { 54 if (debugfs_valid_mountpoint(*ptr) == 0) { 55 debugfs_found = 1; 56 strcpy(debugfs_mountpoint, *ptr); 57 return debugfs_mountpoint; 58 } 59 ptr++; 60 } 61 62 /* give up and parse /proc/mounts */ 63 fp = fopen("/proc/mounts", "r"); 64 if (fp == NULL) 65 die("Can't open /proc/mounts for read"); 66 67 while (fscanf(fp, "%*s %" 68 STR(MAX_PATH) 69 "s %99s %*s %*d %*d\n", 70 debugfs_mountpoint, type) == 2) { 71 if (strcmp(type, "debugfs") == 0) 72 break; 73 } 74 fclose(fp); 75 76 if (strcmp(type, "debugfs") != 0) 77 return NULL; 78 79 debugfs_found = 1; 80 81 return debugfs_mountpoint; 82} 83 84/* verify that a mountpoint is actually a debugfs instance */ 85 86int debugfs_valid_mountpoint(const char *debugfs) 87{ 88 struct statfs st_fs; 89 90 if (statfs(debugfs, &st_fs) < 0) 91 return -ENOENT; 92 else if (st_fs.f_type != (long) DEBUGFS_MAGIC) 93 return -ENOENT; 94 95 return 0; 96} 97 98 99int debugfs_valid_entry(const char *path) 100{ 101 struct stat st; 102 103 if (stat(path, &st)) 104 return -errno; 105 106 return 0; 107} 108 109/* mount the debugfs somewhere */ 110 111int debugfs_mount(const char *mountpoint) 112{ 113 char mountcmd[128]; 114 115 /* see if it's already mounted */ 116 if (debugfs_find_mountpoint()) { 117 debugfs_premounted = 1; 118 return 0; 119 } 120 121 /* if not mounted and no argument */ 122 if (mountpoint == NULL) { 123 /* see if environment variable set */ 124 mountpoint = getenv(PERF_DEBUGFS_ENVIRONMENT); 125 /* if no environment variable, use default */ 126 if (mountpoint == NULL) 127 mountpoint = "/sys/kernel/debug"; 128 } 129 130 /* save the mountpoint */ 131 strncpy(debugfs_mountpoint, mountpoint, sizeof(debugfs_mountpoint)); 132 133 /* mount it */ 134 snprintf(mountcmd, sizeof(mountcmd), 135 "/bin/mount -t debugfs debugfs %s", mountpoint); 136 return system(mountcmd); 137} 138 139/* umount the debugfs */ 140 141int debugfs_umount(void) 142{ 143 char umountcmd[128]; 144 int ret; 145 146 /* if it was already mounted, leave it */ 147 if (debugfs_premounted) 148 return 0; 149 150 /* make sure it's a valid mount point */ 151 ret = debugfs_valid_mountpoint(debugfs_mountpoint); 152 if (ret) 153 return ret; 154 155 snprintf(umountcmd, sizeof(umountcmd), 156 "/bin/umount %s", debugfs_mountpoint); 157 return system(umountcmd); 158} 159 160int debugfs_write(const char *entry, const char *value) 161{ 162 char path[MAX_PATH+1]; 163 int ret, count; 164 int fd; 165 166 /* construct the path */ 167 snprintf(path, sizeof(path), "%s/%s", debugfs_mountpoint, entry); 168 169 /* verify that it exists */ 170 ret = debugfs_valid_entry(path); 171 if (ret) 172 return ret; 173 174 /* get how many chars we're going to write */ 175 count = strlen(value); 176 177 /* open the debugfs entry */ 178 fd = open(path, O_RDWR); 179 if (fd < 0) 180 return -errno; 181 182 while (count > 0) { 183 /* write it */ 184 ret = write(fd, value, count); 185 if (ret <= 0) { 186 if (ret == EAGAIN) 187 continue; 188 close(fd); 189 return -errno; 190 } 191 count -= ret; 192 } 193 194 /* close it */ 195 close(fd); 196 197 /* return success */ 198 return 0; 199} 200 201/* 202 * read a debugfs entry 203 * returns the number of chars read or a negative errno 204 */ 205int debugfs_read(const char *entry, char *buffer, size_t size) 206{ 207 char path[MAX_PATH+1]; 208 int ret; 209 int fd; 210 211 /* construct the path */ 212 snprintf(path, sizeof(path), "%s/%s", debugfs_mountpoint, entry); 213 214 /* verify that it exists */ 215 ret = debugfs_valid_entry(path); 216 if (ret) 217 return ret; 218 219 /* open the debugfs entry */ 220 fd = open(path, O_RDONLY); 221 if (fd < 0) 222 return -errno; 223 224 do { 225 /* read it */ 226 ret = read(fd, buffer, size); 227 if (ret == 0) { 228 close(fd); 229 return EOF; 230 } 231 } while (ret < 0 && errno == EAGAIN); 232 233 /* close it */ 234 close(fd); 235 236 /* make *sure* there's a null character at the end */ 237 buffer[ret] = '\0'; 238 239 /* return the number of chars read */ 240 return ret; 241}