2 * Copyright (C) 2008,2009, Steven Rostedt <srostedt@redhat.com>
4 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License (not later!)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 #include <sys/types.h>
36 #include "trace-event.h"
42 #define STR(x) _STR(x)
45 #define TRACE_CTRL "tracing_on"
47 #define AVAILABLE "available_tracers"
48 #define CURRENT "current_tracer"
49 #define ITER_CTRL "trace_options"
50 #define MAX_LATENCY "tracing_max_latency"
52 unsigned int page_size;
54 static const char *output_file = "trace.info";
58 struct event_list *next;
63 struct events *sibling;
64 struct events *children;
71 static void die(const char *fmt, ...)
83 vfprintf(stderr, fmt, ap);
86 fprintf(stderr, "\n");
90 void *malloc_or_die(unsigned int size)
100 static const char *find_debugfs(void)
102 static char debugfs[MAX_PATH+1];
103 static int debugfs_found;
110 if ((fp = fopen("/proc/mounts","r")) == NULL)
111 die("Can't open /proc/mounts for read");
113 while (fscanf(fp, "%*s %"
115 "s %99s %*s %*d %*d\n",
116 debugfs, type) == 2) {
117 if (strcmp(type, "debugfs") == 0)
122 if (strcmp(type, "debugfs") != 0)
123 die("debugfs not mounted, please mount");
131 * Finds the path to the debugfs/tracing
132 * Allocates the string and stores it.
134 static const char *find_tracing_dir(void)
136 static char *tracing;
137 static int tracing_found;
143 debugfs = find_debugfs();
145 tracing = malloc_or_die(strlen(debugfs) + 9);
147 sprintf(tracing, "%s/tracing", debugfs);
153 static char *get_tracing_file(const char *name)
158 tracing = find_tracing_dir();
162 file = malloc_or_die(strlen(tracing) + strlen(name) + 2);
164 sprintf(file, "%s/%s", tracing, name);
168 static void put_tracing_file(char *file)
173 static ssize_t write_or_die(const void *buf, size_t len)
177 ret = write(output_fd, buf, len);
179 die("writing to '%s'", output_file);
186 unsigned char str[] = { 0x1, 0x2, 0x3, 0x4, 0x0, 0x0, 0x0, 0x0};
189 ptr = (unsigned int *)str;
190 return *ptr == 0x01020304;
193 static unsigned long long copy_file_fd(int fd)
195 unsigned long long size = 0;
200 r = read(fd, buf, BUFSIZ);
203 write_or_die(buf, r);
210 static unsigned long long copy_file(const char *file)
212 unsigned long long size = 0;
215 fd = open(file, O_RDONLY);
217 die("Can't read '%s'", file);
218 size = copy_file_fd(fd);
224 static unsigned long get_size_fd(int fd)
226 unsigned long long size = 0;
231 r = read(fd, buf, BUFSIZ);
236 lseek(fd, 0, SEEK_SET);
241 static unsigned long get_size(const char *file)
243 unsigned long long size = 0;
246 fd = open(file, O_RDONLY);
248 die("Can't read '%s'", file);
249 size = get_size_fd(fd);
255 static void read_header_files(void)
257 unsigned long long size, check_size;
261 path = get_tracing_file("events/header_page");
262 fd = open(path, O_RDONLY);
264 die("can't read '%s'", path);
266 /* unfortunately, you can not stat debugfs files for size */
267 size = get_size_fd(fd);
269 write_or_die("header_page", 12);
270 write_or_die(&size, 8);
271 check_size = copy_file_fd(fd);
272 if (size != check_size)
273 die("wrong size for '%s' size=%lld read=%lld",
274 path, size, check_size);
275 put_tracing_file(path);
277 path = get_tracing_file("events/header_event");
278 fd = open(path, O_RDONLY);
280 die("can't read '%s'", path);
282 size = get_size_fd(fd);
284 write_or_die("header_event", 13);
285 write_or_die(&size, 8);
286 check_size = copy_file_fd(fd);
287 if (size != check_size)
288 die("wrong size for '%s'", path);
289 put_tracing_file(path);
292 static void copy_event_system(const char *sys)
294 unsigned long long size, check_size;
304 die("can't read directory '%s'", sys);
306 while ((dent = readdir(dir))) {
307 if (strcmp(dent->d_name, ".") == 0 ||
308 strcmp(dent->d_name, "..") == 0)
310 format = malloc_or_die(strlen(sys) + strlen(dent->d_name) + 10);
311 sprintf(format, "%s/%s/format", sys, dent->d_name);
312 ret = stat(format, &st);
319 write_or_die(&count, 4);
322 while ((dent = readdir(dir))) {
323 if (strcmp(dent->d_name, ".") == 0 ||
324 strcmp(dent->d_name, "..") == 0)
326 format = malloc_or_die(strlen(sys) + strlen(dent->d_name) + 10);
327 sprintf(format, "%s/%s/format", sys, dent->d_name);
328 ret = stat(format, &st);
331 /* unfortunately, you can not stat debugfs files for size */
332 size = get_size(format);
333 write_or_die(&size, 8);
334 check_size = copy_file(format);
335 if (size != check_size)
336 die("error in size of file '%s'", format);
343 static void read_ftrace_files(void)
347 path = get_tracing_file("events/ftrace");
349 copy_event_system(path);
351 put_tracing_file(path);
354 static void read_event_files(void)
364 path = get_tracing_file("events");
368 die("can't read directory '%s'", path);
370 while ((dent = readdir(dir))) {
371 if (strcmp(dent->d_name, ".") == 0 ||
372 strcmp(dent->d_name, "..") == 0 ||
373 strcmp(dent->d_name, "ftrace") == 0)
375 sys = malloc_or_die(strlen(path) + strlen(dent->d_name) + 2);
376 sprintf(sys, "%s/%s", path, dent->d_name);
377 ret = stat(sys, &st);
381 if (S_ISDIR(st.st_mode))
385 write_or_die(&count, 4);
388 while ((dent = readdir(dir))) {
389 if (strcmp(dent->d_name, ".") == 0 ||
390 strcmp(dent->d_name, "..") == 0 ||
391 strcmp(dent->d_name, "ftrace") == 0)
393 sys = malloc_or_die(strlen(path) + strlen(dent->d_name) + 2);
394 sprintf(sys, "%s/%s", path, dent->d_name);
395 ret = stat(sys, &st);
397 if (S_ISDIR(st.st_mode)) {
398 write_or_die(dent->d_name, strlen(dent->d_name) + 1);
399 copy_event_system(sys);
405 put_tracing_file(path);
408 static void read_proc_kallsyms(void)
410 unsigned int size, check_size;
411 const char *path = "/proc/kallsyms";
415 ret = stat(path, &st);
419 write_or_die(&size, 4);
422 size = get_size(path);
423 write_or_die(&size, 4);
424 check_size = copy_file(path);
425 if (size != check_size)
426 die("error in size of file '%s'", path);
430 static void read_ftrace_printk(void)
432 unsigned int size, check_size;
437 path = get_tracing_file("printk_formats");
438 ret = stat(path, &st);
442 write_or_die(&size, 4);
445 size = get_size(path);
446 write_or_die(&size, 4);
447 check_size = copy_file(path);
448 if (size != check_size)
449 die("error in size of file '%s'", path);
453 void read_tracing_data(void)
457 output_fd = open(output_file, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0644);
459 die("creating file '%s'", output_file);
464 memcpy(buf + 3, "tracing", 7);
466 write_or_die(buf, 10);
468 write_or_die(VERSION, strlen(VERSION) + 1);
476 write_or_die(buf, 1);
478 /* save size of long */
479 buf[0] = sizeof(long);
480 write_or_die(buf, 1);
483 page_size = getpagesize();
484 write_or_die(&page_size, 4);
489 read_proc_kallsyms();
490 read_ftrace_printk();