1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2013 Red Hat Inc, Steven Rostedt <[email protected]>
4 *
5 */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <getopt.h>
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <fcntl.h>
13 #include <unistd.h>
14
15 #include "tracefs.h"
16 #include "trace-local.h"
17
write_file(const char * name,char * val)18 static void write_file(const char *name, char *val)
19 {
20 char *path;
21 int fd;
22 ssize_t n;
23
24 path = tracefs_get_tracing_file(name);
25 fd = open(path, O_WRONLY);
26 if (fd < 0)
27 die("writing %s", path);
28
29 n = write(fd, val, strlen(val));
30 if (n < 0)
31 die("failed to write to %s\n", path);
32
33 tracefs_put_tracing_file(path);
34 close(fd);
35 }
36
trace_snapshot(int argc,char ** argv)37 void trace_snapshot (int argc, char **argv)
38 {
39 const char *buffer = NULL;
40 const char *file = "snapshot";
41 struct stat st;
42 char *name;
43 char cpu_path[128];
44 int take_snap = 0;
45 int reset_snap = 0;
46 int free_snap = 0;
47 int cpu = -1;
48 int ret;
49 int c;
50
51 if (argc < 2)
52 usage(argv);
53
54 if (strcmp(argv[1], "snapshot") != 0)
55 usage(argv);
56
57 while ((c = getopt(argc-1, argv+1, "srfB:c:")) >= 0) {
58 switch (c) {
59 case 'h':
60 usage(argv);
61 break;
62 case 's':
63 take_snap = 1;
64 if (free_snap)
65 die("can't take snapshot and free it at the same time");
66 break;
67 case 'f':
68 free_snap = 1;
69 if (take_snap)
70 die("can't take snapshot and free it at the same time");
71 break;
72 case 'r':
73 reset_snap = 1;
74 break;
75 case 'B':
76 if (buffer)
77 die("Can only do one buffer at a time");
78 buffer = optarg;
79 break;
80 case 'c':
81 if (cpu >= 0)
82 die("Can only do one CPU (or all) at a time");
83 cpu = atoi(optarg);
84 break;
85 default:
86 usage(argv);
87 }
88 }
89
90 if (cpu >= 0) {
91 snprintf(cpu_path, 128, "per_cpu/cpu%d/%s", cpu, file);
92 file = cpu_path;
93 }
94
95 name = tracefs_get_tracing_file(file);
96 ret = stat(name, &st);
97 if (ret < 0)
98 die("Snapshot feature is not supported by this kernel");
99 tracefs_put_tracing_file(name);
100
101 if (!reset_snap && !take_snap && !free_snap) {
102 show_file(file);
103 exit(0);
104 }
105
106 if (reset_snap)
107 write_file(file, "2");
108
109 if (free_snap)
110 write_file(file, "0");
111
112 if (take_snap)
113 write_file(file, "1");
114 }
115