1 /* 2 * Ftrace trace backend 3 * 4 * Copyright (C) 2013 Hitachi, Ltd. 5 * Created by Eiichi Tsukata <eiichi.tsukata.xh@hitachi.com> 6 * 7 * This work is licensed under the terms of the GNU GPL, version 2. See 8 * the COPYING file in the top-level directory. 9 * 10 */ 11 12 #include "qemu/osdep.h" 13 #include "trace/control.h" 14 #include "trace/ftrace.h" 15 16 int trace_marker_fd; 17 18 static int find_mount(char *mount_point, const char *fstype) 19 { 20 char type[100]; 21 FILE *fp; 22 int ret = 0; 23 24 fp = fopen("/proc/mounts", "r"); 25 if (fp == NULL) { 26 return 0; 27 } 28 29 while (fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n", 30 mount_point, type) == 2) { 31 if (strcmp(type, fstype) == 0) { 32 ret = 1; 33 break; 34 } 35 } 36 fclose(fp); 37 38 return ret; 39 } 40 41 bool ftrace_init(void) 42 { 43 char mount_point[PATH_MAX]; 44 char path[PATH_MAX]; 45 int tracefs_found; 46 int trace_fd = -1; 47 const char *subdir = ""; 48 49 tracefs_found = find_mount(mount_point, "tracefs"); 50 if (!tracefs_found) { 51 tracefs_found = find_mount(mount_point, "debugfs"); 52 subdir = "/tracing"; 53 } 54 55 if (tracefs_found) { 56 if (snprintf(path, PATH_MAX, "%s%s/tracing_on", mount_point, subdir) 57 >= sizeof(path)) { 58 fprintf(stderr, "Using tracefs mountpoint would exceed PATH_MAX\n"); 59 return false; 60 } 61 trace_fd = open(path, O_WRONLY); 62 if (trace_fd < 0) { 63 if (errno == EACCES) { 64 trace_marker_fd = open("/dev/null", O_WRONLY); 65 if (trace_marker_fd != -1) { 66 return true; 67 } 68 } 69 perror("Could not open ftrace 'tracing_on' file"); 70 return false; 71 } else { 72 if (write(trace_fd, "1", 1) < 0) { 73 perror("Could not write to 'tracing_on' file"); 74 close(trace_fd); 75 return false; 76 } 77 close(trace_fd); 78 } 79 if (snprintf(path, PATH_MAX, "%s%s/trace_marker", mount_point, subdir) 80 >= sizeof(path)) { 81 fprintf(stderr, "Using tracefs mountpoint would exceed PATH_MAX\n"); 82 return false; 83 } 84 trace_marker_fd = open(path, O_WRONLY); 85 if (trace_marker_fd < 0) { 86 perror("Could not open ftrace 'trace_marker' file"); 87 return false; 88 } 89 } else { 90 fprintf(stderr, "tracefs is not mounted\n"); 91 return false; 92 } 93 94 return true; 95 } 96