trace-cmd: Extend option "-v" to delete an ftrace instance
Extended the "trace-cmd set" option "-v" to delete the instance specified
after it on the command line with "-B". For example:
trace-cmd set -v -B bar -B foo
will delete instance bar and create a new instance foo.
Link: http://lore.kernel.org/linux-trace-devel/20200603121506.49992-5-tz.stoyanov@gmail.com
Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
diff --git a/Documentation/trace-cmd-set.1.txt b/Documentation/trace-cmd-set.1.txt
index 203c8de..2f95e07 100644
--- a/Documentation/trace-cmd-set.1.txt
+++ b/Documentation/trace-cmd-set.1.txt
@@ -77,15 +77,20 @@
information on triggers.
*-v*::
- This will cause all events specified after it on the command line to not
- be traced. This is useful for selecting a subsystem to be traced but to
- leave out various events. For Example: "-e sched -v -e "\*stat\*"" will
- enable all events in the sched subsystem except those that have "stat" in
- their names.
-
+ This will negate options specified after it on the command line. It affects:
+[verse]
+--
+ *-e*: Causes all specified events to not be traced. This is useful for
+ selecting a subsystem to be traced but to leave out various events.
+ For example: "-e sched -v -e "\*stat\*"" will enable all events in
+ the sched subsystem except those that have "stat" in their names.
+ *-B*: Deletes the specified ftrace instance. There must be no
+ configuration options related to this instance in the command line.
+ For example: "-v -B bar -B foo" will delete instance bar and create
+ a new instance foo.
Note: the *-v* option was taken from the way grep(1) inverts the following
matches.
-
+--
*-P* 'pid'::
This will filter only the specified process IDs. Using *-P* will let you
trace only events that are caused by the process.
diff --git a/tracecmd/include/trace-local.h b/tracecmd/include/trace-local.h
index 5ec0514..d148aa1 100644
--- a/tracecmd/include/trace-local.h
+++ b/tracecmd/include/trace-local.h
@@ -205,6 +205,7 @@
char *output_file;
struct event_list *events;
struct event_list **event_next;
+ bool delete;
struct event_list *sched_switch_event;
struct event_list *sched_wakeup_event;
diff --git a/tracecmd/trace-record.c b/tracecmd/trace-record.c
index fd6e2f6..bd00457 100644
--- a/tracecmd/trace-record.c
+++ b/tracecmd/trace-record.c
@@ -5814,6 +5814,27 @@
"Did you mean 'record'?", param, cmd);
}
+static inline void remove_instances(struct buffer_instance *instances)
+{
+ struct buffer_instance *del;
+
+ while (instances) {
+ del = instances;
+ instances = instances->next;
+ tracefs_instance_destroy(del->tracefs);
+ tracefs_instance_free(del->tracefs);
+ free(del);
+ }
+}
+
+static inline void
+check_instance_die(struct buffer_instance *instance, char *param)
+{
+ if (instance->delete)
+ die("Instance %s is marked for deletion, invalid option %s",
+ tracefs_instance_get_name(instance->tracefs), param);
+}
+
static void parse_record_options(int argc,
char **argv,
enum trace_cmd curr_cmd,
@@ -5827,8 +5848,8 @@
char *pid;
char *sav;
int name_counter = 0;
- int neg_event = 0;
- struct buffer_instance *instance;
+ int negative = 0;
+ struct buffer_instance *instance, *del_list = NULL;
bool guest_sync_set = false;
int do_children = 0;
int fpids_count = 0;
@@ -5899,6 +5920,7 @@
}
break;
case 'e':
+ check_instance_die(ctx->instance, "-e");
ctx->events = 1;
event = malloc(sizeof(*event));
if (!event)
@@ -5906,7 +5928,7 @@
memset(event, 0, sizeof(*event));
event->event = optarg;
add_event(ctx->instance, event);
- event->neg = neg_event;
+ event->neg = negative;
event->filter = NULL;
last_event = event;
@@ -5972,6 +5994,7 @@
ctx->global = 1;
break;
case 'P':
+ check_instance_die(ctx->instance, "-P");
test_set_event_pid(ctx->instance);
pids = strdup(optarg);
if (!pids)
@@ -5987,6 +6010,7 @@
free(pids);
break;
case 'c':
+ check_instance_die(ctx->instance, "-c");
test_set_event_pid(ctx->instance);
do_children = 1;
if (!ctx->instance->have_event_fork) {
@@ -6003,13 +6027,14 @@
save_option(ctx->instance, "function-fork");
break;
case 'C':
+ check_instance_die(ctx->instance, "-C");
ctx->instance->clock = optarg;
ctx->instance->flags |= BUFFER_FL_HAS_CLOCK;
if (is_top_instance(ctx->instance))
guest_sync_set = true;
break;
case 'v':
- neg_event = 1;
+ negative = 1;
break;
case 'l':
add_func(&ctx->instance->filter_funcs,
@@ -6017,15 +6042,18 @@
ctx->filtered = 1;
break;
case 'n':
+ check_instance_die(ctx->instance, "-n");
add_func(&ctx->instance->notrace_funcs,
ctx->instance->filter_mod, optarg);
ctx->filtered = 1;
break;
case 'g':
+ check_instance_die(ctx->instance, "-g");
add_func(&graph_funcs, ctx->instance->filter_mod, optarg);
ctx->filtered = 1;
break;
case 'p':
+ check_instance_die(ctx->instance, "-p");
if (ctx->instance->plugin)
die("only one plugin allowed");
for (plugin = optarg; isspace(*plugin); plugin++)
@@ -6075,14 +6103,17 @@
}
break;
case 'O':
+ check_instance_die(ctx->instance, "-O");
option = optarg;
save_option(ctx->instance, option);
break;
case 'T':
+ check_instance_die(ctx->instance, "-T");
save_option(ctx->instance, "stacktrace");
break;
case 'H':
cmd_check_die(ctx, CMD_set, *(argv+1), "-H");
+ check_instance_die(ctx->instance, "-H");
add_hook(ctx->instance, optarg);
ctx->events = 1;
break;
@@ -6127,6 +6158,7 @@
max_kb = atoi(optarg);
break;
case 'M':
+ check_instance_die(ctx->instance, "-M");
ctx->instance->cpumask = alloc_mask_from_hex(ctx->instance, optarg);
break;
case 't':
@@ -6137,13 +6169,20 @@
use_tcp = 1;
break;
case 'b':
+ check_instance_die(ctx->instance, "-b");
ctx->instance->buffer_size = atoi(optarg);
break;
case 'B':
ctx->instance = create_instance(optarg);
if (!ctx->instance)
die("Failed to create instance");
- add_instance(ctx->instance, local_cpu_count);
+ ctx->instance->delete = negative;
+ negative = 0;
+ if (ctx->instance->delete) {
+ ctx->instance->next = del_list;
+ del_list = ctx->instance;
+ } else
+ add_instance(ctx->instance, local_cpu_count);
if (IS_PROFILE(ctx))
ctx->instance->flags |= BUFFER_FL_PROFILE;
break;
@@ -6162,6 +6201,7 @@
case OPT_procmap:
cmd_check_die(ctx, CMD_start, *(argv+1), "--proc-map");
cmd_check_die(ctx, CMD_set, *(argv+1), "--proc-map");
+ check_instance_die(ctx->instance, "--proc-map");
ctx->instance->get_procmap = 1;
break;
case OPT_date:
@@ -6184,6 +6224,7 @@
break;
case OPT_profile:
cmd_check_die(ctx, CMD_set, *(argv+1), "--profile");
+ check_instance_die(ctx->instance, "--profile");
handle_init = trace_init_profile;
ctx->instance->flags |= BUFFER_FL_PROFILE;
ctx->events = 1;
@@ -6208,6 +6249,7 @@
ctx->data_flags |= DATA_FL_OFFSET;
break;
case OPT_max_graph_depth:
+ check_instance_die(ctx->instance, "--max-graph-depth");
free(ctx->instance->max_graph_depth);
ctx->instance->max_graph_depth = strdup(optarg);
if (!ctx->instance->max_graph_depth)
@@ -6224,6 +6266,7 @@
tracecmd_set_debug(true);
break;
case OPT_module:
+ check_instance_die(ctx->instance, "--module");
if (ctx->instance->filter_mod)
add_func(&ctx->instance->filter_funcs,
ctx->instance->filter_mod, "*");
@@ -6249,6 +6292,8 @@
}
}
+ remove_instances(del_list);
+
/* If --date is specified, prepend it to all guest VM flags */
if (ctx->date) {
struct buffer_instance *instance;
diff --git a/tracecmd/trace-usage.c b/tracecmd/trace-usage.c
index 6af435e..c4e8c10 100644
--- a/tracecmd/trace-usage.c
+++ b/tracecmd/trace-usage.c
@@ -34,7 +34,7 @@
" -n do not trace function\n"
" -m max size per CPU in kilobytes\n"
" -M set CPU mask to trace\n"
- " -v will negate all -e after it (disable those events)\n"
+ " -v will negate all -e (disable those events) and -B (delete those instances) after it\n"
" -d disable function tracer when running\n"
" -D Full disable of function tracing (for all users)\n"
" -o data output file [default trace.dat]\n"
@@ -84,7 +84,7 @@
" -n do not trace function\n"
" -m max size per CPU in kilobytes\n"
" -M set CPU mask to trace\n"
- " -v will negate all -e after it (disable those events)\n"
+ " -v will negate all -e (disable those events) and -B (delete those instances) after it\n"
" -d disable function tracer when running\n"
" -D Full disable of function tracing (for all users)\n"
" -O option to enable (or disable)\n"