xref: /openbmc/qemu/trace/ftrace.c (revision 2c9b15ca)
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 <stdio.h>
13 #include <string.h>
14 #include <fcntl.h>
15 #include <limits.h>
16 #include "trace.h"
17 #include "trace/control.h"
18 
19 int trace_marker_fd;
20 
21 static int find_debugfs(char *debugfs)
22 {
23     char type[100];
24     FILE *fp;
25 
26     fp = fopen("/proc/mounts", "r");
27     if (fp == NULL) {
28         return 0;
29     }
30 
31     while (fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n",
32                   debugfs, type) == 2) {
33         if (strcmp(type, "debugfs") == 0) {
34             break;
35         }
36     }
37     fclose(fp);
38 
39     if (strcmp(type, "debugfs") != 0) {
40         return 0;
41     }
42     return 1;
43 }
44 
45 void trace_print_events(FILE *stream, fprintf_function stream_printf)
46 {
47     TraceEventID i;
48 
49     for (i = 0; i < trace_event_count(); i++) {
50         TraceEvent *ev = trace_event_id(i);
51         stream_printf(stream, "%s [Event ID %u] : state %u\n",
52                       trace_event_get_name(ev), i, trace_event_get_state_dynamic(ev));
53     }
54 }
55 
56 void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state)
57 {
58     ev->dstate = state;
59 }
60 
61 bool trace_backend_init(const char *events, const char *file)
62 {
63     char debugfs[PATH_MAX];
64     char path[PATH_MAX];
65     int debugfs_found;
66     int trace_fd = -1;
67 
68     if (file) {
69         fprintf(stderr, "error: -trace file=...: "
70                 "option not supported by the selected tracing backend\n");
71         return false;
72     }
73 
74     debugfs_found = find_debugfs(debugfs);
75     if (debugfs_found) {
76         snprintf(path, PATH_MAX, "%s/tracing/tracing_on", debugfs);
77         trace_fd = open(path, O_WRONLY);
78         if (trace_fd < 0) {
79             perror("Could not open ftrace 'tracing_on' file");
80             return false;
81         } else {
82             if (write(trace_fd, "1", 1) < 0) {
83                 perror("Could not write to 'tracing_on' file");
84                 close(trace_fd);
85                 return false;
86             }
87             close(trace_fd);
88         }
89         snprintf(path, PATH_MAX, "%s/tracing/trace_marker", debugfs);
90         trace_marker_fd = open(path, O_WRONLY);
91         if (trace_marker_fd < 0) {
92             perror("Could not open ftrace 'trace_marker' file");
93             return false;
94         }
95     } else {
96         fprintf(stderr, "debugfs is not mounted\n");
97         return false;
98     }
99 
100     trace_backend_init_events(events);
101     return true;
102 }
103