diff options
Diffstat (limited to 'trace/ftrace.c')
-rw-r--r-- | trace/ftrace.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/trace/ftrace.c b/trace/ftrace.c new file mode 100644 index 000000000..9749543d9 --- /dev/null +++ b/trace/ftrace.c @@ -0,0 +1,95 @@ +/* + * Ftrace trace backend + * + * Copyright (C) 2013 Hitachi, Ltd. + * Created by Eiichi Tsukata <eiichi.tsukata.xh@hitachi.com> + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "trace/control.h" +#include "trace/ftrace.h" + +int trace_marker_fd; + +static int find_mount(char *mount_point, const char *fstype) +{ + char type[100]; + FILE *fp; + int ret = 0; + + fp = fopen("/proc/mounts", "r"); + if (fp == NULL) { + return 0; + } + + while (fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n", + mount_point, type) == 2) { + if (strcmp(type, fstype) == 0) { + ret = 1; + break; + } + } + fclose(fp); + + return ret; +} + +bool ftrace_init(void) +{ + char mount_point[PATH_MAX]; + char path[PATH_MAX]; + int tracefs_found; + int trace_fd = -1; + const char *subdir = ""; + + tracefs_found = find_mount(mount_point, "tracefs"); + if (!tracefs_found) { + tracefs_found = find_mount(mount_point, "debugfs"); + subdir = "/tracing"; + } + + if (tracefs_found) { + if (snprintf(path, PATH_MAX, "%s%s/tracing_on", mount_point, subdir) + >= sizeof(path)) { + fprintf(stderr, "Using tracefs mountpoint would exceed PATH_MAX\n"); + return false; + } + trace_fd = open(path, O_WRONLY); + if (trace_fd < 0) { + if (errno == EACCES) { + trace_marker_fd = open("/dev/null", O_WRONLY); + if (trace_marker_fd != -1) { + return true; + } + } + perror("Could not open ftrace 'tracing_on' file"); + return false; + } else { + if (write(trace_fd, "1", 1) < 0) { + perror("Could not write to 'tracing_on' file"); + close(trace_fd); + return false; + } + close(trace_fd); + } + if (snprintf(path, PATH_MAX, "%s%s/trace_marker", mount_point, subdir) + >= sizeof(path)) { + fprintf(stderr, "Using tracefs mountpoint would exceed PATH_MAX\n"); + return false; + } + trace_marker_fd = open(path, O_WRONLY); + if (trace_marker_fd < 0) { + perror("Could not open ftrace 'trace_marker' file"); + return false; + } + } else { + fprintf(stderr, "tracefs is not mounted\n"); + return false; + } + + return true; +} |