xref: /aosp_15_r20/external/trace-cmd/tracecmd/trace-clear.c (revision 58e6ee5f017f6a8912852c892d18457e4bafb554)
1 // SPDX-License-Identifier: LGPL-2.1
2 /*
3  * Copyright (C) 2008, 2009, 2010 Red Hat Inc, Steven Rostedt <[email protected]>
4  *
5  * Updates:
6  * Copyright (C) 2020, VMware, Tzvetomir Stoyanov <[email protected]>
7  *
8  */
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <getopt.h>
12 
13 #include "tracefs.h"
14 #include "trace-local.h"
15 
16 struct instances_list {
17 	struct instances_list *next;
18 	struct tracefs_instance *instance;
19 };
20 
add_new_instance(struct instances_list ** list,char * name)21 static int add_new_instance(struct instances_list **list, char *name)
22 {
23 	struct instances_list *new;
24 
25 	if (!tracefs_instance_exists(name))
26 		return -1;
27 	new = calloc(1, sizeof(*new));
28 	if (!new)
29 		return -1;
30 	new->instance = tracefs_instance_create(name);
31 	if (!new->instance) {
32 		free(new);
33 		return -1;
34 	}
35 
36 	new->next = *list;
37 	*list = new;
38 	return 0;
39 }
40 
add_instance_walk(const char * name,void * data)41 static int add_instance_walk(const char *name, void *data)
42 {
43 	return add_new_instance((struct instances_list **)data, (char *)name);
44 }
45 
clear_list(struct instances_list * list)46 static void clear_list(struct instances_list *list)
47 {
48 	struct instances_list *del;
49 
50 	while (list) {
51 		del = list;
52 		list = list->next;
53 		tracefs_instance_free(del->instance);
54 		free(del);
55 	}
56 }
57 
clear_instance_trace(struct tracefs_instance * instance)58 static void clear_instance_trace(struct tracefs_instance *instance)
59 {
60 	FILE *fp;
61 	char *path;
62 
63 	/* reset the trace */
64 	path = tracefs_instance_get_file(instance, "trace");
65 	fp = fopen(path, "w");
66 	if (!fp)
67 		die("writing to '%s'", path);
68 	tracefs_put_tracing_file(path);
69 	fwrite("0", 1, 1, fp);
70 	fclose(fp);
71 }
72 
clear_trace(struct instances_list * instances)73 static void clear_trace(struct instances_list *instances)
74 {
75 	if (instances) {
76 		while (instances) {
77 			clear_instance_trace(instances->instance);
78 			instances = instances->next;
79 		}
80 	} else
81 		clear_instance_trace(NULL);
82 }
83 
trace_clear(int argc,char ** argv)84 void trace_clear(int argc, char **argv)
85 {
86 	struct instances_list *instances = NULL;
87 	bool all = false;
88 	int c;
89 
90 	for (;;) {
91 		int option_index = 0;
92 		static struct option long_options[] = {
93 			{"all", no_argument, NULL, 'a'},
94 			{"help", no_argument, NULL, '?'},
95 			{NULL, 0, NULL, 0}
96 		};
97 
98 		c = getopt_long (argc-1, argv+1, "+haB:",
99 				 long_options, &option_index);
100 		if (c == -1)
101 			break;
102 		switch (c) {
103 		case 'B':
104 			if (add_new_instance(&instances, optarg))
105 				die("Failed to allocate instance %s", optarg);
106 			break;
107 		case 'a':
108 			all = true;
109 			if (tracefs_instances_walk(add_instance_walk, &instances))
110 				die("Failed to add all instances");
111 			break;
112 		case 'h':
113 		case '?':
114 		default:
115 			usage(argv);
116 			break;
117 		}
118 	}
119 
120 	clear_trace(instances);
121 	if (all)
122 		clear_trace(NULL);
123 	clear_list(instances);
124 	exit(0);
125 }
126