iowatcher: wrap system() in a checker function
[blktrace.git] / iowatcher / main.c
index c9ddd9c92b6a802421f39fafd4e44dea10e105c8..2797afb918665367d0d1cd295e92eef34979ef85 100644 (file)
@@ -33,6 +33,7 @@
 #include <getopt.h>
 #include <limits.h>
 #include <float.h>
+#include <signal.h>
 
 #include "plot.h"
 #include "blkparse.h"
@@ -712,6 +713,22 @@ static int count_io_plot_types(void)
        return total_io_types;
 }
 
+static void plot_io_legend(struct plot *plot, struct graph_dot_data *gdd, char *prefix, char *rw)
+{
+       int ret = 0;
+       char *label = NULL;
+       if (io_per_process)
+               ret = asprintf(&label, "%s %s", prefix, gdd->label);
+       else
+               ret = asprintf(&label, "%s", prefix);
+       if (ret < 0) {
+               perror("Failed to process labels");
+               exit(1);
+       }
+       svg_add_legend(plot, label, rw, gdd->color);
+       free(label);
+}
+
 static void plot_io(struct plot *plot, unsigned int min_seconds,
                    unsigned int max_seconds, u64 min_offset, u64 max_offset)
 {
@@ -732,33 +749,17 @@ static void plot_io(struct plot *plot, unsigned int min_seconds,
        set_xticks(plot, num_xticks, min_seconds, max_seconds);
 
        list_for_each_entry(tf, &all_traces, list) {
-               char label[256];
-               char *pos;
-
-               if (!tf->label)
-                       label[0] = 0;
-               else {
-                       strncpy(label, tf->label, 255);
-                       label[255] = 0;
-                       if (io_per_process)
-                               strcat(label, " ");
-               }
-               pos = label + strlen(label);
+               char *prefix = tf->label ? tf->label : "";
 
                for (i = 0; i < tf->io_plots; i++) {
                        if (tf->gdd_writes[i]) {
                                svg_io_graph(plot, tf->gdd_writes[i]);
-                               if (io_per_process)
-                                       strcpy(pos, tf->gdd_writes[i]->label);
-                               svg_add_legend(plot, label, " Writes", tf->gdd_writes[i]->color);
+                               plot_io_legend(plot, tf->gdd_writes[i], prefix, " Writes");
                        }
                        if (tf->gdd_reads[i]) {
                                svg_io_graph(plot, tf->gdd_reads[i]);
-                               if (io_per_process)
-                                       strcpy(pos, tf->gdd_reads[i]->label);
-                               svg_add_legend(plot, label, " Reads", tf->gdd_reads[i]->color);
+                               plot_io_legend(plot, tf->gdd_reads[i], prefix, " Reads");
                        }
-
                }
        }
        if (plot->add_xlabel)
@@ -1015,12 +1016,22 @@ static void plot_queue_depth(struct plot *plot, unsigned int min_seconds,
        total_graphs_written++;
 }
 
+static void system_check(const char *cmd)
+{
+       if (system(cmd) < 0) {
+               int err = errno;
+
+               fprintf(stderr, "system exec failed (%d): %s\n", err, cmd);
+               exit(1);
+       }
+}
+
 static void convert_movie_files(char *movie_dir)
 {
        fprintf(stderr, "Converting svg files in %s\n", movie_dir);
        snprintf(line, line_len, "find %s -name \\*.svg | xargs -I{} -n 1 -P 8 rsvg-convert -o {}.png {}",
                 movie_dir);
-       system(line);
+       system_check(line);
 }
 
 static void mencode_movie(char *movie_dir)
@@ -1029,7 +1040,7 @@ static void mencode_movie(char *movie_dir)
        snprintf(line, line_len, "ffmpeg -r 20 -y -i %s/%%10d-%s.svg.png -b:v 250k "
                 "-vcodec %s %s", movie_dir, output_filename, ffmpeg_codec,
                 output_filename);
-       system(line);
+       system_check(line);
 }
 
 static void tencode_movie(char *movie_dir)
@@ -1037,7 +1048,7 @@ static void tencode_movie(char *movie_dir)
        fprintf(stderr, "Creating movie %s with png2theora\n", movie_dir);
        snprintf(line, line_len, "png2theora -o %s %s/%%010d-%s.svg.png",
                        output_filename, movie_dir, output_filename);
-       system(line);
+       system_check(line);
 }
 
 static void encode_movie(char *movie_dir)
@@ -1059,10 +1070,10 @@ static void cleanup_movie(char *movie_dir)
        }
        fprintf(stderr, "Removing movie dir %s\n", movie_dir);
        snprintf(line, line_len, "rm %s/*", movie_dir);
-       system(line);
+       system_check(line);
 
        snprintf(line, line_len, "rmdir %s", movie_dir);
-       system(line);
+       system_check(line);
 }
 
 static void plot_io_movie(struct plot *plot)
@@ -1092,17 +1103,7 @@ static void plot_io_movie(struct plot *plot)
                batch_count = 1;
 
        list_for_each_entry(tf, &all_traces, list) {
-               char label[256];
-               char *pos;
-
-               if (!tf->label)
-                       label[0] = 0;
-               else {
-                       strcpy(label, tf->label);
-                       if (io_per_process)
-                               strcat(label, " ");
-               }
-               pos = label + strlen(label);
+               char *prefix = tf->label ? tf->label : "";
 
                i = 0;
                while (i < cols) {
@@ -1142,16 +1143,10 @@ static void plot_io_movie(struct plot *plot)
                        history->col = i;
 
                        for (pid = 0; pid < tf->io_plots; pid++) {
-                               if (tf->gdd_reads[pid]) {
-                                       if (io_per_process)
-                                               strcpy(pos, tf->gdd_reads[pid]->label);
-                                       svg_add_legend(plot, label, " Reads", tf->gdd_reads[pid]->color);
-                               }
-                               if (tf->gdd_writes[pid]) {
-                                       if (io_per_process)
-                                               strcpy(pos, tf->gdd_writes[pid]->label);
-                                       svg_add_legend(plot, label, " Writes", tf->gdd_writes[pid]->color);
-                               }
+                               if (tf->gdd_reads[pid])
+                                       plot_io_legend(plot, tf->gdd_reads[pid], prefix, " Reads");
+                               if (tf->gdd_writes[pid])
+                                       plot_io_legend(plot, tf->gdd_writes[pid], prefix, " Writes");
                        }
 
                        batch_i = 0;
@@ -1343,7 +1338,7 @@ static void print_usage(void)
                "\t-t (--trace): trace file name (more than one allowed)\n"
                "\t-F (--fio-trace): fio bandwidth trace (more than one allowed)\n"
                "\t-l (--label): trace label in the graph\n"
-               "\t-o (--output): output file name (SVG only)\n"
+               "\t-o (--output): output file name for the SVG image or video\n"
                "\t-p (--prog): run a program while blktrace is run\n"
                "\t-K (--keep-movie-svgs keep svgs generated for movie mode\n"
                "\t-m (--movie [=spindle|rect]): create IO animations\n"
@@ -1620,16 +1615,9 @@ int main(int ac, char **av)
        }
 
        if (num_blktrace_devices) {
-               char *path;
-
+               char *path = join_path(blktrace_dest_dir, blktrace_outfile);
                dest_mkdir(blktrace_dest_dir);
-               if (num_blktrace_devices > 1) {
-                       snprintf(line, line_len, "%s/%s", blktrace_dest_dir,
-                                blktrace_outfile);
-                       dest_mkdir(line);
-               }
-
-               path = join_path(blktrace_dest_dir, blktrace_outfile);
+               dest_mkdir(path);
 
                snprintf(line, line_len, "%s.dump", path);
                unlink(line);
@@ -1637,19 +1625,24 @@ int main(int ac, char **av)
                ret = start_blktrace(blktrace_devices, num_blktrace_devices,
                                     blktrace_outfile, blktrace_dest_dir);
                if (ret) {
-                       fprintf(stderr, "exiting due to blktrace failure\n");
-                       exit(1);
+                       perror("Exiting due to blktrace failure");
+                       exit(ret);
                }
 
-               start_mpstat(path);
+               snprintf(line, line_len, "%s.mpstat", path);
+               ret = start_mpstat(line);
+               if (ret) {
+                       perror("Exiting due to mpstat failure");
+                       exit(ret);
+               }
 
                if (prog_argv && prog_argc) {
-                       ret = run_program(prog_argc, prog_argv, 1, NULL);
-                       if (ret != 127)
-                               printf("%s exited with %d\n", prog_argv[0], ret);
+                       run_program(prog_argc, prog_argv, 1, NULL, NULL);
+                       wait_for_tracers(SIGINT);
+               } else {
+                       printf("Tracing until interrupted...\n");
+                       wait_for_tracers(0);
                }
-
-               wait_for_tracers();
                free(path);
        }