diff mbox series

[v2,4/7] libtracefs: Add API tracefs_hist_show()

Message ID 20210803164811.693731-5-rostedt@goodmis.org (mailing list archive)
State Accepted
Commit 1ef1bba04ad4aa644fe702cef51ba92ddca743eb
Headers show
Series libtracefs: Updates to the histograms for tracefs_sql() | expand

Commit Message

Steven Rostedt Aug. 3, 2021, 4:48 p.m. UTC
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

Add tracefs_hist_show() that will display the commands that would be
executed in order to create the given histogram.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 Documentation/libtracefs-hist.txt |   8 +++
 include/tracefs.h                 |   2 +
 src/tracefs-hist.c                | 102 ++++++++++++++++++++++--------
 3 files changed, 85 insertions(+), 27 deletions(-)
diff mbox series

Patch

diff --git a/Documentation/libtracefs-hist.txt b/Documentation/libtracefs-hist.txt
index 9bf13ac03af7..03ac07743d1c 100644
--- a/Documentation/libtracefs-hist.txt
+++ b/Documentation/libtracefs-hist.txt
@@ -30,6 +30,9 @@  int tracefs_hist_append_filter(struct tracefs_hist pass:[*]hist,
 			       const char pass:[*]field,
 			       enum tracefs_compare compare,
 			       const char pass:[*]val);
+int tracefs_hist_show(struct trace_seq pass:[*]s, struct tracefs_instance pass:[*]instance,
+			 struct tracefs_hist pass:[*]hist,
+			 enum tracefs_hist_command command);
 int tracefs_hist_command(struct tracefs_instance pass:[*]instance,
 			 struct tracefs_hist pass:[*]hist,
 			 enum tracefs_hist_command command);
@@ -121,6 +124,11 @@  _field_, _compare_, and _val_ are ignored unless _type_ is equal to
 
 *TRACEFS_COMPARE_AND* - _field_ & _val_ : where _field_ is a flags field.
 
+*trace_hist_show*() prints the commands needed to create the given histogram
+in the given _instance_, or NULL for the top level, into the _seq_.
+The command that is printed is described by _command_ and shows the functionality
+that would be done by *tracefs_hist_command*(3).
+
 *tracefs_hist_command*() is called to process a command on the histogram
 _hist_ for its event in the given _instance_, or NULL for the top level.
 The _cmd_ can be one of:
diff --git a/include/tracefs.h b/include/tracefs.h
index 0be6e907d29b..ab781764b0ed 100644
--- a/include/tracefs.h
+++ b/include/tracefs.h
@@ -327,6 +327,8 @@  int tracefs_hist_append_filter(struct tracefs_hist *hist,
 			       const char *field,
 			       enum tracefs_compare compare,
 			       const char *val);
+int tracefs_hist_show(struct trace_seq *seq,  struct tracefs_instance *instance,
+		      struct tracefs_hist *hist, enum tracefs_hist_command command);
 int tracefs_hist_command(struct tracefs_instance *instance,
 			 struct tracefs_hist *hist, enum tracefs_hist_command cmd);
 
diff --git a/src/tracefs-hist.c b/src/tracefs-hist.c
index 1be14362f407..7c84e942d58b 100644
--- a/src/tracefs-hist.c
+++ b/src/tracefs-hist.c
@@ -50,6 +50,79 @@  static void add_list(struct trace_seq *seq, const char *start,
 	}
 }
 
+static void add_hist_commands(struct trace_seq *seq, struct tracefs_hist *hist,
+			     enum tracefs_hist_command command)
+{
+	if (command == TRACEFS_HIST_CMD_DESTROY)
+		trace_seq_putc(seq, '!');
+
+	add_list(seq, "hist:keys=", hist->keys);
+
+	if (hist->values)
+		add_list(seq, ":vals=", hist->values);
+
+	if (hist->sort)
+		add_list(seq, ":sort=", hist->sort);
+
+	if (hist->size)
+		trace_seq_printf(seq, ":size=%d", hist->size);
+
+	switch(command) {
+	case TRACEFS_HIST_CMD_START: break;
+	case TRACEFS_HIST_CMD_PAUSE: trace_seq_puts(seq, ":pause"); break;
+	case TRACEFS_HIST_CMD_CONT: trace_seq_puts(seq, ":cont"); break;
+	case TRACEFS_HIST_CMD_CLEAR: trace_seq_puts(seq, ":clear"); break;
+	default: break;
+	}
+
+	if (hist->name)
+		trace_seq_printf(seq, ":name=%s", hist->name);
+
+	if (hist->filter)
+		trace_seq_printf(seq, " if %s", hist->filter);
+
+}
+
+/*
+ * trace_hist_show - show how to start the histogram
+ * @seq: A trace_seq to store the commands to create
+ * @hist: The histogram to write into the trigger file
+ * @command: If not zero, can pause, continue or clear the histogram
+ *
+ * This shows the commands to create the histogram for an event
+ * with the given fields.
+ *
+ * Returns 0 on succes -1 on error.
+ */
+int
+tracefs_hist_show(struct trace_seq *seq, struct tracefs_instance *instance,
+		  struct tracefs_hist *hist,
+		  enum tracefs_hist_command command)
+{
+	const char *system = hist->system;
+	const char *event = hist->event_name;
+	char *path;
+
+	if (!hist->keys) {
+		errno = -EINVAL;
+		return -1;
+	}
+
+	path = tracefs_event_get_file(instance, system, event, "trigger");
+	if (!path)
+		return -1;
+
+	trace_seq_puts(seq, "echo '");
+
+	add_hist_commands(seq, hist, command);
+
+	trace_seq_printf(seq, "' > %s\n", path);
+
+	tracefs_put_tracing_file(path);
+
+	return 0;
+}
+
 /*
  * tracefs_hist_command - Create, start, pause, destroy a histogram for an event
  * @instance: The instance the histogram will be in (NULL for toplevel)
@@ -78,34 +151,9 @@  int tracefs_hist_command(struct tracefs_instance *instance,
 
 	trace_seq_init(&seq);
 
-	if (command == TRACEFS_HIST_CMD_DESTROY)
-		trace_seq_putc(&seq, '!');
-
-	add_list(&seq, "hist:keys=", hist->keys);
-
-	if (hist->values)
-		add_list(&seq, ":vals=", hist->values);
-
-	if (hist->sort)
-		add_list(&seq, ":sort=", hist->sort);
-
-	if (hist->size)
-		trace_seq_printf(&seq, ":size=%d", hist->size);
-
-	switch(command) {
-	case TRACEFS_HIST_CMD_START: break;
-	case TRACEFS_HIST_CMD_PAUSE: trace_seq_puts(&seq, ":pause"); break;
-	case TRACEFS_HIST_CMD_CONT: trace_seq_puts(&seq, ":cont"); break;
-	case TRACEFS_HIST_CMD_CLEAR: trace_seq_puts(&seq, ":clear"); break;
-	default: break;
-	}
-
-	if (hist->name)
-		trace_seq_printf(&seq, ":name=%s", hist->name);
-
-	if (hist->filter)
-		trace_seq_printf(&seq, " if %s\n", hist->filter);
+	add_hist_commands(&seq, hist, command);
 
+	trace_seq_putc(&seq, '\n');
 	trace_seq_terminate(&seq);
 
 	ret = -1;