#include <getopt.h>
#include <limits.h>
#include <float.h>
+#include <signal.h>
#include "plot.h"
#include "blkparse.h"
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)
{
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)
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)
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)
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)
}
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)
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) {
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;
"\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"
}
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);
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);
}