xref: /aosp_15_r20/external/trace-cmd/tracecmd/trace-snapshot.c (revision 58e6ee5f017f6a8912852c892d18457e4bafb554)
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