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