diff mbox series

[v3,4/5] trace-cmd: Extend option "-v" to delete an ftrace instance

Message ID 20200603121506.49992-5-tz.stoyanov@gmail.com (mailing list archive)
State Accepted
Headers show
Series New trace-cmd "set" command and changes in "start" | expand

Commit Message

Tzvetomir Stoyanov (VMware) June 3, 2020, 12:15 p.m. UTC
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.

Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
---
 Documentation/trace-cmd-set.1.txt | 19 +++++++----
 tracecmd/include/trace-local.h    |  1 +
 tracecmd/trace-record.c           | 55 ++++++++++++++++++++++++++++---
 tracecmd/trace-usage.c            |  4 +--
 4 files changed, 65 insertions(+), 14 deletions(-)
diff mbox series

Patch

diff --git a/Documentation/trace-cmd-set.1.txt b/Documentation/trace-cmd-set.1.txt
index faf0b740..af1f69c6 100644
--- a/Documentation/trace-cmd-set.1.txt
+++ b/Documentation/trace-cmd-set.1.txt
@@ -77,15 +77,20 @@  OPTIONS
     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 5ec05149..d148aa16 100644
--- a/tracecmd/include/trace-local.h
+++ b/tracecmd/include/trace-local.h
@@ -205,6 +205,7 @@  struct buffer_instance {
 	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 d5515c52..ab085f80 100644
--- a/tracecmd/trace-record.c
+++ b/tracecmd/trace-record.c
@@ -5797,6 +5797,27 @@  static inline void cmd_check_die(struct common_record_context *ctx,
 		    "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,
@@ -5810,8 +5831,8 @@  static void parse_record_options(int argc,
 	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;
@@ -5881,6 +5902,7 @@  static void parse_record_options(int argc,
 			}
 			break;
 		case 'e':
+			check_instance_die(ctx->instance, "-e");
 			ctx->events = 1;
 			event = malloc(sizeof(*event));
 			if (!event)
@@ -5888,7 +5910,7 @@  static void parse_record_options(int argc,
 			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;
 
@@ -5954,6 +5976,7 @@  static void parse_record_options(int argc,
 			ctx->global = 1;
 			break;
 		case 'P':
+			check_instance_die(ctx->instance, "-P");
 			test_set_event_pid(ctx->instance);
 			pids = strdup(optarg);
 			if (!pids)
@@ -5969,6 +5992,7 @@  static void parse_record_options(int argc,
 			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) {
@@ -5985,13 +6009,14 @@  static void parse_record_options(int argc,
 				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,
@@ -5999,15 +6024,18 @@  static void parse_record_options(int argc,
 			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++)
@@ -6057,14 +6085,17 @@  static void parse_record_options(int argc,
 			}
 			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;
@@ -6109,6 +6140,7 @@  static void parse_record_options(int argc,
 			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':
@@ -6119,13 +6151,20 @@  static void parse_record_options(int argc,
 				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;
@@ -6144,6 +6183,7 @@  static void parse_record_options(int argc,
 		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:
@@ -6166,6 +6206,7 @@  static void parse_record_options(int argc,
 			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;
@@ -6190,6 +6231,7 @@  static void parse_record_options(int argc,
 			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)
@@ -6206,6 +6248,7 @@  static void parse_record_options(int argc,
 			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, "*");
@@ -6226,6 +6269,8 @@  static void parse_record_options(int argc,
 		}
 	}
 
+	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 0c0e12f4..96647a1e 100644
--- a/tracecmd/trace-usage.c
+++ b/tracecmd/trace-usage.c
@@ -34,7 +34,7 @@  static struct usage_help usage_help[] = {
 		"          -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 @@  static struct usage_help usage_help[] = {
 		"          -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"