All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Tzvetomir Stoyanov (VMware)" <tz.stoyanov@gmail.com>
To: rostedt@goodmis.org
Cc: linux-trace-devel@vger.kernel.org
Subject: [PATCH v3 4/5] trace-cmd: Extend option "-v" to delete an ftrace instance
Date: Wed,  3 Jun 2020 15:15:05 +0300	[thread overview]
Message-ID: <20200603121506.49992-5-tz.stoyanov@gmail.com> (raw)
In-Reply-To: <20200603121506.49992-1-tz.stoyanov@gmail.com>

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 --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"
-- 
2.26.2


  parent reply	other threads:[~2020-06-03 12:15 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-03 12:15 [PATCH v3 0/5] New trace-cmd "set" command and changes in "start" Tzvetomir Stoyanov (VMware)
2020-06-03 12:15 ` [PATCH v3 1/5] trace-cmd: Enable "trace-cmd start" to run a command Tzvetomir Stoyanov (VMware)
2020-06-08 19:35   ` Steven Rostedt
2020-06-08 20:39     ` [PATCH] trace-cmd: Have trace-cmd start wait for command unless --fork is specified Steven Rostedt
2020-06-03 12:15 ` [PATCH v3 2/5] trace-cmd: Add new subcommand "set" Tzvetomir Stoyanov (VMware)
2020-06-03 12:15 ` [PATCH v3 3/5] trace-cmd: Man page for "set" subcommand Tzvetomir Stoyanov (VMware)
2020-06-04 15:50   ` Steven Rostedt
2020-06-03 12:15 ` Tzvetomir Stoyanov (VMware) [this message]
2020-06-03 12:15 ` [PATCH v3 5/5] trace-cmd: Add description of "-G" option Tzvetomir Stoyanov (VMware)
2020-06-04 15:51   ` Steven Rostedt
2020-06-08 21:42     ` Steven Rostedt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200603121506.49992-5-tz.stoyanov@gmail.com \
    --to=tz.stoyanov@gmail.com \
    --cc=linux-trace-devel@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.