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