diff options
Diffstat (limited to 'src/tracefs-utils.c')
-rw-r--r-- | src/tracefs-utils.c | 163 |
1 files changed, 149 insertions, 14 deletions
diff --git a/src/tracefs-utils.c b/src/tracefs-utils.c index 7b1f816..9acf2ad 100644 --- a/src/tracefs-utils.c +++ b/src/tracefs-utils.c @@ -29,6 +29,7 @@ #define STR(x) _STR(x) static int log_level = TEP_LOG_CRITICAL; +static char *custom_tracing_dir; /** * tracefs_set_loglevel - set log level of the library @@ -84,13 +85,8 @@ static int mount_debugfs(void) return ret; } -/** - * trace_find_tracing_dir - Find tracing directory - * - * Returns string containing the full path to the system's tracing directory. - * The string must be freed by free() - */ -__hidden char *trace_find_tracing_dir(void) +/* Exported for testing purpose only */ +__hidden char *find_tracing_dir(bool debugfs, bool mount) { char *debug_str = NULL; char fspath[PATH_MAX+1]; @@ -109,9 +105,11 @@ __hidden char *trace_find_tracing_dir(void) STR(PATH_MAX) "s %99s %*s %*d %*d\n", fspath, type) == 2) { - if (strcmp(type, "tracefs") == 0) + if (!debugfs && strcmp(type, "tracefs") == 0) break; if (!debug_str && strcmp(type, "debugfs") == 0) { + if (debugfs) + break; debug_str = strdup(fspath); if (!debug_str) { fclose(fp); @@ -121,14 +119,21 @@ __hidden char *trace_find_tracing_dir(void) } fclose(fp); - if (strcmp(type, "tracefs") != 0) { - if (mount_tracefs() < 0) { + if (debugfs) { + if (strcmp(type, "debugfs") != 0) { + if (!mount || mount_debugfs() < 0) + return NULL; + strcpy(fspath, DEBUGFS_PATH); + } + } else if (strcmp(type, "tracefs") != 0) { + if (!mount || mount_tracefs() < 0) { if (debug_str) { strncpy(fspath, debug_str, PATH_MAX); fspath[PATH_MAX] = 0; } else { - if (mount_debugfs() < 0) { - tracefs_warning("debugfs not mounted, please mount"); + if (!mount || mount_debugfs() < 0) { + if (mount) + tracefs_warning("debugfs not mounted, please mount"); free(debug_str); return NULL; } @@ -156,6 +161,86 @@ __hidden char *trace_find_tracing_dir(void) } /** + * tracefs_tracing_dir_is_mounted - test if the tracing dir is already mounted + * @mount: Mount it if it is not already mounted + * @path: the path to the tracing directory if mounted or was mounted + * + * Returns 1 if the tracing directory is already mounted and 0 if it is not. + * If @mount is set and it fails to mount, it returns -1. + * + * If path is not NULL, and the tracing directory is or was mounted, it holds + * the path to the tracing directory. It must not be freed. + */ +int tracefs_tracing_dir_is_mounted(bool mount, const char **path) +{ + const char *dir; + + dir = find_tracing_dir(false, false); + if (dir) { + if (path) + *path = dir; + return 1; + } + if (!mount) + return 0; + + dir = find_tracing_dir(false, mount); + if (!dir) + return -1; + if (path) + *path = dir; + return 0; +} + +/** + * trace_find_tracing_dir - Find tracing directory + * @debugfs: Boolean to just return the debugfs directory + * + * Returns string containing the full path to the system's tracing directory. + * The string must be freed by free() + */ +__hidden char *trace_find_tracing_dir(bool debugfs) +{ + return find_tracing_dir(debugfs, false); +} + +/** + * tracefs_set_tracing_dir - Set location of the tracing directory + * @tracing_dir: full path to the system's tracing directory mount point. + * + * Set the location to the system's tracing directory. This API should be used + * to set a custom location of the tracing directory. There is no need to call + * it if the location is standard, in that case the library will auto detect it. + * + * Returns 0 on success, -1 otherwise. + */ +int tracefs_set_tracing_dir(char *tracing_dir) +{ + if (custom_tracing_dir) { + free(custom_tracing_dir); + custom_tracing_dir = NULL; + } + + if (tracing_dir) { + custom_tracing_dir = strdup(tracing_dir); + if (!custom_tracing_dir) + return -1; + } + + return 0; +} + +/* Used to check if the directory is still mounted */ +static int test_dir(const char *dir, const char *file) +{ + char path[strlen(dir) + strlen(file) + 2]; + struct stat st; + + sprintf(path, "%s/%s", dir, file); + return stat(path, &st) < 0 ? 0 : 1; +} + +/** * tracefs_tracing_dir - Get tracing directory * * Returns string containing the full path to the system's tracing directory. @@ -165,14 +250,36 @@ const char *tracefs_tracing_dir(void) { static const char *tracing_dir; - if (tracing_dir) + /* Do not check custom_tracing_dir */ + if (custom_tracing_dir) + return custom_tracing_dir; + + if (tracing_dir && test_dir(tracing_dir, "trace")) return tracing_dir; - tracing_dir = trace_find_tracing_dir(); + tracing_dir = find_tracing_dir(false, true); return tracing_dir; } /** + * tracefs_debug_dir - Get debugfs directory path + * + * Returns string containing the full path to the system's debugfs directory. + * + * The returned string must *not* be freed. + */ +const char *tracefs_debug_dir(void) +{ + static const char *debug_dir; + + if (debug_dir && test_dir(debug_dir, "tracing")) + return debug_dir; + + debug_dir = find_tracing_dir(true, true); + return debug_dir; +} + +/** * tracefs_get_tracing_file - Get tracing file * @name: tracing file name * @@ -487,3 +594,31 @@ int tracefs_list_size(char **list) list--; return (int)*(unsigned long *)list; } + +/** + * tracefs_tracer_available - test if a tracer is available + * @tracing_dir: The directory that contains the tracing directory + * @tracer: The name of the tracer + * + * Return true if the tracer is available + */ +bool tracefs_tracer_available(const char *tracing_dir, const char *tracer) +{ + bool ret = false; + char **tracers = NULL; + int i; + + tracers = tracefs_tracers(tracing_dir); + if (!tracers) + return false; + + for (i = 0; tracers[i]; i++) { + if (strcmp(tracer, tracers[i]) == 0) { + ret = true; + break; + } + } + + tracefs_list_free(tracers); + return ret; +} |