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 <hcoch...@kernelspring.com>
---
 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to