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