From: "Steven Rostedt (VMware)" <rostedt@xxxxxxxxxxx> 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@xxxxxxxxxxx> --- Documentation/libtracefs-hist.txt | 8 +++ include/tracefs.h | 2 + src/tracefs-hist.c | 102 ++++++++++++++++++++++-------- 3 files changed, 85 insertions(+), 27 deletions(-) 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; -- 2.30.2