1 #ifndef _GNU_SOURCE 2 # define _GNU_SOURCE 3 #endif 4 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <string.h> 8 #include <errno.h> 9 #include <unistd.h> 10 #include "fs.h" 11 12 #include "tracing_path.h" 13 14 15 char tracing_path[PATH_MAX + 1] = "/sys/kernel/debug/tracing"; 16 char tracing_events_path[PATH_MAX + 1] = "/sys/kernel/debug/tracing/events"; 17 18 19 static void __tracing_path_set(const char *tracing, const char *mountpoint) 20 { 21 snprintf(tracing_path, sizeof(tracing_path), "%s/%s", 22 mountpoint, tracing); 23 snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s%s", 24 mountpoint, tracing, "events"); 25 } 26 27 static const char *tracing_path_tracefs_mount(void) 28 { 29 const char *mnt; 30 31 mnt = tracefs__mount(); 32 if (!mnt) 33 return NULL; 34 35 __tracing_path_set("", mnt); 36 37 return mnt; 38 } 39 40 static const char *tracing_path_debugfs_mount(void) 41 { 42 const char *mnt; 43 44 mnt = debugfs__mount(); 45 if (!mnt) 46 return NULL; 47 48 __tracing_path_set("tracing/", mnt); 49 50 return mnt; 51 } 52 53 const char *tracing_path_mount(void) 54 { 55 const char *mnt; 56 57 mnt = tracing_path_tracefs_mount(); 58 if (mnt) 59 return mnt; 60 61 mnt = tracing_path_debugfs_mount(); 62 63 return mnt; 64 } 65 66 void tracing_path_set(const char *mntpt) 67 { 68 __tracing_path_set("tracing/", mntpt); 69 } 70 71 char *get_tracing_file(const char *name) 72 { 73 char *file; 74 75 if (asprintf(&file, "%s/%s", tracing_path, name) < 0) 76 return NULL; 77 78 return file; 79 } 80 81 void put_tracing_file(char *file) 82 { 83 free(file); 84 } 85 86 static int strerror_open(int err, char *buf, size_t size, const char *filename) 87 { 88 char sbuf[128]; 89 90 switch (err) { 91 case ENOENT: 92 /* 93 * We will get here if we can't find the tracepoint, but one of 94 * debugfs or tracefs is configured, which means you probably 95 * want some tracepoint which wasn't compiled in your kernel. 96 * - jirka 97 */ 98 if (debugfs__configured() || tracefs__configured()) { 99 snprintf(buf, size, 100 "Error:\tFile %s/%s not found.\n" 101 "Hint:\tPerhaps this kernel misses some CONFIG_ setting to enable this feature?.\n", 102 tracing_events_path, filename); 103 break; 104 } 105 snprintf(buf, size, "%s", 106 "Error:\tUnable to find debugfs/tracefs\n" 107 "Hint:\tWas your kernel compiled with debugfs/tracefs support?\n" 108 "Hint:\tIs the debugfs/tracefs filesystem mounted?\n" 109 "Hint:\tTry 'sudo mount -t debugfs nodev /sys/kernel/debug'"); 110 break; 111 case EACCES: { 112 const char *mountpoint = debugfs__mountpoint(); 113 114 if (!access(mountpoint, R_OK) && strncmp(filename, "tracing/", 8) == 0) { 115 const char *tracefs_mntpoint = tracefs__mountpoint(); 116 117 if (tracefs_mntpoint) 118 mountpoint = tracefs__mountpoint(); 119 } 120 121 snprintf(buf, size, 122 "Error:\tNo permissions to read %s/%s\n" 123 "Hint:\tTry 'sudo mount -o remount,mode=755 %s'\n", 124 tracing_events_path, filename, mountpoint); 125 } 126 break; 127 default: 128 snprintf(buf, size, "%s", strerror_r(err, sbuf, sizeof(sbuf))); 129 break; 130 } 131 132 return 0; 133 } 134 135 int tracing_path__strerror_open_tp(int err, char *buf, size_t size, const char *sys, const char *name) 136 { 137 char path[PATH_MAX]; 138 139 snprintf(path, PATH_MAX, "%s/%s", sys, name ?: "*"); 140 141 return strerror_open(err, buf, size, path); 142 } 143