[PATCH v3 4/5] trace-cmd snapshot: Fully support multiple instances

From: Howard Cochran
Date: Wed Apr 22 2015 - 00:57:50 EST


Add support for multiple -B instances, the same as
stop, reset, restart, and extract sub-commands.
-a operates on all instances except the top one
-t also includes the top instance

Signed-off-by: Howard Cochran <hcochran@xxxxxxxxxxxxxxxx>
---
Documentation/trace-cmd-snapshot.1.txt | 16 +++++-
trace-cmd.c | 2 +-
trace-local.h | 4 ++
trace-record.c | 4 +-
trace-snapshot.c | 90 ++++++++++++++++++----------------
trace-usage.c | 8 ++-
6 files changed, 75 insertions(+), 49 deletions(-)

diff --git a/Documentation/trace-cmd-snapshot.1.txt b/Documentation/trace-cmd-snapshot.1.txt
index 98b8924..767ab67 100644
--- a/Documentation/trace-cmd-snapshot.1.txt
+++ b/Documentation/trace-cmd-snapshot.1.txt
@@ -41,8 +41,20 @@ OPTIONS

*-B* 'buf'::
If a buffer instance was created, then the *-B* option will operate on
- the snapshot within the buffer.
-
+ the snapshot within the buffer. This may be used multiple times to
+ specify different buffers. When this option is used, the top level
+ instance will be ignored unless *-t* is given.
+
+*-a*::
+ Operate on the snapshot for all existing buffer instances.
+ When this option is used, the top level instance will be ignored
+ unless *-t* is given.
+
+*-t*::
+ Operate on the snapshot within the top level instance buffer. Without
+ the *-B* or *-a* option this is the same as the default. But if *-B*
+ or *-a* is used, this is required if the top level instance buffer
+ should also be affected.

SEE ALSO
--------
diff --git a/trace-cmd.c b/trace-cmd.c
index 4c5b564..647a2b4 100644
--- a/trace-cmd.c
+++ b/trace-cmd.c
@@ -72,7 +72,7 @@ void *malloc_or_die(unsigned int size)
return data;
}

-static void dump_file_content(const char *path)
+void dump_file_content(const char *path)
{
char buf[BUFSIZ];
ssize_t n;
diff --git a/trace-local.h b/trace-local.h
index fb2ce71..982fe6f 100644
--- a/trace-local.h
+++ b/trace-local.h
@@ -47,7 +47,9 @@ struct pid_record_data {
struct pevent_record *record;
};

+void dump_file_content(const char *path);
void show_file(const char *name);
+int write_file(const char *file, const char *str, const char *type);

struct tracecmd_input *read_trace_header(const char *file);
int read_trace_files(void);
@@ -179,6 +181,8 @@ extern struct buffer_instance *first_instance;
struct buffer_instance *create_instance(const char *name);
void add_instance(struct buffer_instance *instance);
char *get_instance_file(struct buffer_instance *instance, const char *file);
+void add_all_instances(void);
+void update_first_instance(int topt);

void show_instance_file(struct buffer_instance *instance, const char *name);
int count_cpus(void);
diff --git a/trace-record.c b/trace-record.c
index 7c6b7e9..ae0ebbf 100644
--- a/trace-record.c
+++ b/trace-record.c
@@ -1466,7 +1466,7 @@ static void reset_events(void)
reset_events_instance(instance);
}

-static int write_file(const char *file, const char *str, const char *type)
+int write_file(const char *file, const char *str, const char *type)
{
char buf[BUFSIZ];
int fd;
@@ -3778,7 +3778,7 @@ static void add_hook(struct buffer_instance *instance, const char *arg)
}
}

-static void update_first_instance(int topt)
+void update_first_instance(int topt)
{
if (topt || !buffer_instances)
first_instance = &top_instance;
diff --git a/trace-snapshot.c b/trace-snapshot.c
index 9d3608c..22f88df 100644
--- a/trace-snapshot.c
+++ b/trace-snapshot.c
@@ -29,27 +29,8 @@

#include "trace-local.h"

-static void write_file(const char *name, char *val)
-{
- char *path;
- int fd;
- ssize_t n;
-
- path = tracecmd_get_tracing_file(name);
- fd = open(path, O_WRONLY);
- if (fd < 0)
- die("writing %s", path);
-
- n = write(fd, val, strlen(val));
- if (n < 0)
- die("failed to write '%d' to %s\n", path);
- tracecmd_put_tracing_file(path);
- close(fd);
-}
-
void trace_snapshot (int argc, char **argv)
{
- const char *buffer = NULL;
const char *file = "snapshot";
struct stat st;
char *name;
@@ -58,8 +39,10 @@ void trace_snapshot (int argc, char **argv)
int reset_snap = 0;
int free_snap = 0;
int cpu = -1;
+ int topt = 0;
int ret;
int c;
+ struct buffer_instance *instance;

if (argc < 2)
usage(argv);
@@ -67,7 +50,7 @@ void trace_snapshot (int argc, char **argv)
if (strcmp(argv[1], "snapshot") != 0)
usage(argv);

- while ((c = getopt(argc-1, argv+1, "srfB:c:")) >= 0) {
+ while ((c = getopt(argc-1, argv+1, "srfB:c:ta")) >= 0) {
switch (c) {
case 'h':
usage(argv);
@@ -86,9 +69,15 @@ void trace_snapshot (int argc, char **argv)
reset_snap = 1;
break;
case 'B':
- if (buffer)
- die("Can only do one buffer at a time");
- buffer = optarg;
+ add_instance(create_instance(optarg));
+ break;
+ case 'a':
+ add_all_instances();
+ break;
+ case 't':
+ /* Include top instance (with -B or -a) */
+ topt = 1;
+ first_instance = &top_instance;
break;
case 'c':
if (cpu >= 0)
@@ -99,29 +88,46 @@ void trace_snapshot (int argc, char **argv)
usage(argv);
}
}
+ update_first_instance(topt);

- if (cpu >= 0) {
- snprintf(cpu_path, 128, "per_cpu/cpu%d/%s", cpu, file);
- file = cpu_path;
- }
+ for_all_instances(instance) {
+ name = get_instance_file(instance, "trace");
+ ret = stat(name, &st);
+ tracecmd_put_tracing_file(name);
+ if (ret < 0) {
+ printf("Ignoring non-existant instance: %s\n",
+ instance->name);
+ continue;
+ }

- name = tracecmd_get_tracing_file(file);
- ret = stat(name, &st);
- if (ret < 0)
- die("Snapshot feature is not supported by this kernel");
- tracecmd_put_tracing_file(name);
+ if (cpu >= 0) {
+ snprintf(cpu_path, 128, "per_cpu/cpu%d/%s", cpu, file);
+ file = cpu_path;
+ }

- if (!reset_snap && !take_snap && !free_snap) {
- show_file(file);
- exit(0);
- }
+ name = get_instance_file(instance, file);
+ ret = stat(name, &st);
+ if (ret < 0)
+ die("Snapshot feature is not supported by this kernel");

- if (reset_snap)
- write_file(file, "2");
+ if (!reset_snap && !take_snap && !free_snap) {
+ if (instance != &top_instance) {
+ printf("\nSnapshot for instance \"%s\"\n"
+ "==================================\n",
+ instance->name);
+ }

- if (free_snap)
- write_file(file, "0");
+ dump_file_content(name);
+ }

- if (take_snap)
- write_file(file, "1");
+ if (reset_snap)
+ write_file(name, "2", "snapshot");
+
+ if (free_snap)
+ write_file(name, "0", "snapshot");
+
+ if (take_snap)
+ write_file(name, "1", "snapshot");
+ tracecmd_put_tracing_file(name);
+ }
}
diff --git a/trace-usage.c b/trace-usage.c
index c56661b..56c68b4 100644
--- a/trace-usage.c
+++ b/trace-usage.c
@@ -244,13 +244,17 @@ static struct usage_help usage_help[] = {
{
"snapshot",
"take snapshot of running trace",
- " %s snapshot [-s][-r][-f][-B buf][-c cpu]\n"
+ " %s snapshot [-s][-r][-f][-c cpu][-B buf][-a][-t]\n"
" -s take a snapshot of the trace buffer\n"
" -r reset current snapshot\n"
" -f free the snapshot buffer\n"
" without the above three options, display snapshot\n"
" -c operate on the snapshot buffer for the given CPU\n"
- " -B operate on the snapshot buffer for a tracing buffer instance.\n"
+ " -B operate on the snapshot for a given instance\n"
+ " (maybe be specified multiple times)\n"
+ " -a operate on the snapshot for all instances\n"
+ " -t also operate on the snapshot for top instance\n"
+ " (useful with -B or -a)\n"
},
{
"stack",
--
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/