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