at v4.3 3.1 kB view raw
1#define _GNU_SOURCE 2#include <errno.h> 3#include <stdio.h> 4#include <stdlib.h> 5#include <string.h> 6#include <unistd.h> 7#include <stdbool.h> 8#include <sys/vfs.h> 9#include <sys/types.h> 10#include <sys/stat.h> 11#include <sys/mount.h> 12#include <linux/kernel.h> 13 14#include "debugfs.h" 15#include "tracefs.h" 16 17#ifndef DEBUGFS_DEFAULT_PATH 18#define DEBUGFS_DEFAULT_PATH "/sys/kernel/debug" 19#endif 20 21char debugfs_mountpoint[PATH_MAX + 1] = DEBUGFS_DEFAULT_PATH; 22 23static const char * const debugfs_known_mountpoints[] = { 24 DEBUGFS_DEFAULT_PATH, 25 "/debug", 26 0, 27}; 28 29static bool debugfs_found; 30 31bool debugfs_configured(void) 32{ 33 return debugfs_find_mountpoint() != NULL; 34} 35 36/* find the path to the mounted debugfs */ 37const char *debugfs_find_mountpoint(void) 38{ 39 const char *ret; 40 41 if (debugfs_found) 42 return (const char *)debugfs_mountpoint; 43 44 ret = find_mountpoint("debugfs", (long) DEBUGFS_MAGIC, 45 debugfs_mountpoint, PATH_MAX + 1, 46 debugfs_known_mountpoints); 47 if (ret) 48 debugfs_found = true; 49 50 return ret; 51} 52 53/* mount the debugfs somewhere if it's not mounted */ 54char *debugfs_mount(const char *mountpoint) 55{ 56 /* see if it's already mounted */ 57 if (debugfs_find_mountpoint()) 58 goto out; 59 60 /* if not mounted and no argument */ 61 if (mountpoint == NULL) { 62 /* see if environment variable set */ 63 mountpoint = getenv(PERF_DEBUGFS_ENVIRONMENT); 64 /* if no environment variable, use default */ 65 if (mountpoint == NULL) 66 mountpoint = DEBUGFS_DEFAULT_PATH; 67 } 68 69 if (mount(NULL, mountpoint, "debugfs", 0, NULL) < 0) 70 return NULL; 71 72 /* save the mountpoint */ 73 debugfs_found = true; 74 strncpy(debugfs_mountpoint, mountpoint, sizeof(debugfs_mountpoint)); 75out: 76 return debugfs_mountpoint; 77} 78 79int debugfs__strerror_open(int err, char *buf, size_t size, const char *filename) 80{ 81 char sbuf[128]; 82 83 switch (err) { 84 case ENOENT: 85 if (debugfs_found) { 86 snprintf(buf, size, 87 "Error:\tFile %s/%s not found.\n" 88 "Hint:\tPerhaps this kernel misses some CONFIG_ setting to enable this feature?.\n", 89 debugfs_mountpoint, filename); 90 break; 91 } 92 snprintf(buf, size, "%s", 93 "Error:\tUnable to find debugfs\n" 94 "Hint:\tWas your kernel compiled with debugfs support?\n" 95 "Hint:\tIs the debugfs filesystem mounted?\n" 96 "Hint:\tTry 'sudo mount -t debugfs nodev /sys/kernel/debug'"); 97 break; 98 case EACCES: { 99 const char *mountpoint = debugfs_mountpoint; 100 101 if (!access(debugfs_mountpoint, R_OK) && strncmp(filename, "tracing/", 8) == 0) { 102 const char *tracefs_mntpoint = tracefs_find_mountpoint(); 103 104 if (tracefs_mntpoint) 105 mountpoint = tracefs_mntpoint; 106 } 107 108 snprintf(buf, size, 109 "Error:\tNo permissions to read %s/%s\n" 110 "Hint:\tTry 'sudo mount -o remount,mode=755 %s'\n", 111 debugfs_mountpoint, filename, mountpoint); 112 } 113 break; 114 default: 115 snprintf(buf, size, "%s", strerror_r(err, sbuf, sizeof(sbuf))); 116 break; 117 } 118 119 return 0; 120} 121 122int debugfs__strerror_open_tp(int err, char *buf, size_t size, const char *sys, const char *name) 123{ 124 char path[PATH_MAX]; 125 126 snprintf(path, PATH_MAX, "tracing/events/%s/%s", sys, name ?: "*"); 127 128 return debugfs__strerror_open(err, buf, size, path); 129}