blkparse: split off the timestamp correction code in to a separate function
[blktrace.git] / btt / args.c
index 6003f43471dfdc82cb8d99ca37bd38a7eb13fcee..5c5078ab2c81a8f86a5b1a31e647b346a5d9e736 100644 (file)
@@ -29,7 +29,7 @@
 
 #define SETBUFFER_SIZE (64 * 1024)
 
-#define S_OPTS "aAB:d:D:e:hi:I:l:M:o:p:q:s:S:t:T:u:VvX"
+#define S_OPTS "aAB:d:D:e:hi:I:l:L:m:M:o:p:P:q:Q:rs:S:t:T:u:VvXz:Z"
 static struct option l_opts[] = {
        {
                .name = "seek-absolute",
@@ -91,6 +91,18 @@ static struct option l_opts[] = {
                .flag = NULL,
                .val = 'l'
        },
+       {
+               .name = "periodic-latencies",
+               .has_arg = required_argument,
+               .flag = NULL,
+               .val = 'L'
+       },
+       {
+               .name = "seeks-per-second",
+               .has_arg = required_argument,
+               .flag = NULL,
+               .val = 'm'
+       },
        {
                .name = "dev-maps",
                .has_arg = required_argument,
@@ -109,12 +121,30 @@ static struct option l_opts[] = {
                .flag = NULL,
                .val = 'p'
        },
+       {
+               .name = "per-io-trees",
+               .has_arg = required_argument,
+               .flag = NULL,
+               .val = 'P'
+       },
        {
                .name = "q2c-latencies",
                .has_arg = required_argument,
                .flag = NULL,
                .val = 'q'
        },
+       {
+               .name = "active-queue-depth",
+               .has_arg = required_argument,
+               .flag = NULL,
+               .val = 'Q'
+       },
+       {
+               .name = "no-remaps",
+               .has_arg = no_argument,
+               .flag = NULL,
+               .val = 'r'
+       },
        {
                .name = "seeks",
                .has_arg = required_argument,
@@ -157,12 +187,24 @@ static struct option l_opts[] = {
                .flag = NULL,
                .val = 'v'
        },
+       {
+               .name = "do-active",
+               .has_arg = no_argument,
+               .flag = NULL,
+               .val = 'z'
+       },
        {
                .name = "easy-parse-avgs",
                .has_arg = no_argument,
                .flag = NULL,
                .val = 'X'
        },
+       {
+               .name = "q2d-latencies",
+               .has_arg = required_argument,
+               .flag = NULL,
+               .val = 'z'
+       },
        {
                .name = NULL,
        }
@@ -179,10 +221,15 @@ static char usage_str[] = \
        "[ -i <input name>  | --input-file=<input name> ]\n" \
        "[ -I <output name> | --iostat=<output name> ]\n" \
        "[ -l <output name> | --d2c-latencies=<output name> ]\n" \
+       "[ -L <freq>        | --periodic-latencies=<freq> ]\n" \
+       "[ -m <output name> | --seeks-per-second=<output name> ]\n" \
        "[ -M <dev map>     | --dev-maps=<dev map>\n" \
        "[ -o <output name> | --output-file=<output name> ]\n" \
        "[ -p <output name> | --per-io-dump=<output name> ]\n" \
+       "[ -P <output name> | --per-io-trees=<output name> ]\n" \
        "[ -q <output name> | --q2c-latencies=<output name> ]\n" \
+       "[ -Q <output name> | --active-queue-depth=<output name> ]\n" \
+       "[ -r               | --no-remaps ]\n" \
        "[ -s <output name> | --seeks=<output name> ]\n" \
        "[ -S <interval>    | --iostat-interval=<interval> ]\n" \
        "[ -t <sec>         | --time-start=<sec> ]\n" \
@@ -191,21 +238,20 @@ static char usage_str[] = \
        "[ -V               | --version ]\n" \
        "[ -v               | --verbose ]\n" \
        "[ -X               | --easy-parse-avgs ]\n" \
+       "[ -z <output name> | --q2d-latencies=<output name> ]\n" \
+       "[ -Z               | --do-active\n" \
        "\n";
 
-static struct file_info *arg_files = NULL;
-
 static void usage(char *prog)
 {
-       fprintf(stderr, "Usage: %s %s %s", prog, bt_timeline_version,
-               usage_str);
+       fprintf(stderr, "Usage: %s %s", prog, usage_str);
 }
 
 static FILE *setup_ofile(char *fname)
 {
        if (fname) {
                char *buf;
-               FILE *ofp = fopen(fname, "w");
+               FILE *ofp = my_fopen(fname, "w");
 
                if (!ofp) {
                        perror(fname);
@@ -213,19 +259,32 @@ static FILE *setup_ofile(char *fname)
                }
 
                buf = malloc(SETBUFFER_SIZE);
-
                setbuffer(ofp, buf, SETBUFFER_SIZE);
-               add_file(&arg_files, ofp, fname);
+
+               add_file(ofp, fname);
                add_buf(buf);
+
                return ofp;
        }
 
        return NULL;
 }
 
-void clean_args(void)
+static FILE *std_open(char *output_name, char *sfx, char *msg)
 {
-       clean_files(&arg_files);
+       FILE *fp;
+       char fname[strlen(output_name) + 32];
+
+       sprintf(fname, "%s.%s", output_name, sfx);
+       fp = my_fopen(fname, "w");
+       if (fp == NULL) {
+               perror(fname);
+               exit(1);
+       }
+       if (verbose)
+               printf("Sending %s to %s\n", msg, fname);
+
+       return fp;
 }
 
 void handle_args(int argc, char *argv[])
@@ -241,47 +300,63 @@ void handle_args(int argc, char *argv[])
                        output_all_data = 1;
                        break;
                case 'B':
-                       bno_dump_name = strdup(optarg);
+                       bno_dump_name = optarg;
                        break;
                case 'd':
                        sscanf(optarg, "%lf", &range_delta);
                        break;
                case 'D':
-                       devices = strdup(optarg);
+                       devices = optarg;
                        break;
                case 'e':
-                       exes = strdup(optarg);
+                       exes = optarg;
                        break;
                case 'h':
                        usage(argv[0]);
                        exit(0);
                case 'i':
-                       input_name = strdup(optarg);
+                       input_name = optarg;
                        break;
                case 'l':
-                       d2c_name = strdup(optarg);
+                       d2c_name = optarg;
+                       break;
+               case 'L':
+                       plat_freq = atof(optarg);
                        break;
                case 'I':
                        iostat_name = strdup(optarg);
                        break;
+               case 'm':
+                       sps_name = optarg;
+                       break;
                case 'M':
                        if (dev_map_read(optarg))
                                exit(1);
                        break;
                case 'o':
-                       output_name = strdup(optarg);
+                       output_name = optarg;
                        break;
                case 'p':
                        per_io_name = strdup(optarg);
                        break;
+               case 'P':
+                       per_io_trees = optarg;
+                       break;
                case 'q':
-                       q2c_name = strdup(optarg);
+                       q2c_name = optarg;
+                       break;
+               case 'Q':
+                       aqd_name = optarg;
+                       break;
+               case 'r':
+                       ignore_remaps = 1;
                        break;
                case 's':
-                       seek_name = strdup(optarg);
+                       seek_name = optarg;
                        break;
                case 'S': {
                        unsigned int interval;
+
                        sscanf(optarg, "%u", &interval);
                        iostat_interval = (__u64)interval * 1000000000LL;
                        break;
@@ -295,7 +370,7 @@ void handle_args(int argc, char *argv[])
                        time_bounded = 1;
                        break;
                case 'u':
-                       unplug_hist_name = strdup(optarg);
+                       unplug_hist_name = optarg;
                        break;
                case 'v':
                        verbose = 1;
@@ -306,6 +381,12 @@ void handle_args(int argc, char *argv[])
                case 'X':
                        easy_parse_avgs++;
                        break;
+               case 'z':
+                       q2d_name = optarg;
+                       break;
+               case 'Z':
+                       do_p_live = 1;
+                       break;
                default:
                        usage(argv[0]);
                        exit(1);
@@ -317,45 +398,24 @@ void handle_args(int argc, char *argv[])
                exit(1);
        }
 
+       if (sps_name && !seek_name) {
+               fprintf(stderr, "FATAL: -m option requires -s options\n");
+               exit(1);
+       }
+
        setup_ifile(input_name);
 
        if (output_name == NULL) {
-               ranges_ofp = avgs_ofp = stdout;
+               rngs_ofp = avgs_ofp = msgs_ofp = stdout;
                easy_parse_avgs = 0;
-       }
-       else {
-               char *fname = malloc(strlen(output_name) + 32);
-
-               sprintf(fname, "%s.dat", output_name);
-               ranges_ofp = fopen(fname, "w");
-               if (ranges_ofp == NULL) {
-                       perror(fname);
-                       exit(1);
-               }
-               if (verbose)
-                       printf("Sending range data to %s\n", fname);
-
-               sprintf(fname, "%s.avg", output_name);
-               avgs_ofp = fopen(fname, "w");
-               if (avgs_ofp == NULL) {
-                       perror(fname);
-                       exit(1);
-               }
-               if (verbose)
-                       printf("Sending stats data to %s\n", fname);
-
+       } else {
+               rngs_ofp = std_open(output_name, "dat", "range data");
+               avgs_ofp = std_open(output_name, "avg", "stats data");
+               msgs_ofp = std_open(output_name, "msg", "K messages");
                if (easy_parse_avgs) {
-                       sprintf(fname, "%s.xvg", output_name);
-                       xavgs_ofp = fopen(fname, "w");
-                       if (avgs_ofp == NULL) {
-                               perror(fname);
-                               exit(1);
-                       }
-                       if (verbose)
-                               printf("Sending X stats data to %s\n", fname);
+                       xavgs_ofp = std_open(output_name, "xvg",
+                                            "EZ stats data");
                }
-
-               free(fname);
        }
 
        iostat_ofp = setup_ofile(iostat_name);