diff options
author | Jan Kara <jack@suse.cz> | 2012-08-31 11:37:49 +0200 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2012-09-10 20:53:05 -0400 |
commit | d140b434b75b786062803158a4b6807aaf67be36 (patch) | |
tree | 2734d460e9c6a805e975b8c341d32785efffd15e | |
parent | 35686f9be692c9b9dde821df8b0947e6fe5dce7f (diff) | |
download | blktrace-d140b434b75b786062803158a4b6807aaf67be36.tar.gz |
iowatcher: Add options to limit time and sector range
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
-rw-r--r-- | iowatcher/main.c | 105 |
1 files changed, 104 insertions, 1 deletions
diff --git a/iowatcher/main.c b/iowatcher/main.c index 1385676..a3148ac 100644 --- a/iowatcher/main.c +++ b/iowatcher/main.c @@ -31,6 +31,8 @@ #include <time.h> #include <math.h> #include <getopt.h> +#include <limits.h> +#include <float.h> #include "plot.h" #include "blkparse.h" @@ -52,6 +54,11 @@ static int opt_graph_height = 0; static int columns = 1; static int num_xticks = 9; +static double min_time = 0; +static double max_time = DBL_MAX; +static unsigned long long min_mb = 0; +static unsigned long long max_mb = ULLONG_MAX >> 20; + /* * this doesn't include the IO graph, * but it counts the other graphs as they go out @@ -472,6 +479,14 @@ static void set_all_minmax_tf(int min_seconds, int max_seconds, u64 min_offset, list_for_each_entry(tf, &all_traces, list) { tf->min_seconds = min_seconds; tf->max_seconds = max_seconds; + if (tf->stop_seconds > max_seconds) + tf->stop_seconds = max_seconds; + if (tf->mpstat_max_seconds) { + tf->mpstat_min_seconds = min_seconds; + tf->mpstat_max_seconds = max_seconds; + if (tf->mpstat_stop_seconds > max_seconds) + tf->mpstat_stop_seconds = max_seconds; + } tf->min_offset = min_offset; tf->max_offset = max_offset; } @@ -1010,7 +1025,7 @@ enum { HELP_LONG_OPT = 1, }; -char *option_string = "T:t:o:l:r:O:N:d:p:m::h:w:c:"; +char *option_string = "T:t:o:l:r:O:N:d:p:m::h:w:c:x:y:"; static struct option long_options[] = { {"columns", required_argument, 0, 'c'}, {"title", required_argument, 0, 'T'}, @@ -1025,6 +1040,8 @@ static struct option long_options[] = { {"movie", optional_argument, 0, 'm'}, {"width", required_argument, 0, 'w'}, {"height", required_argument, 0, 'h'}, + {"xzoom", required_argument, 0, 'x'}, + {"yzoom", required_argument, 0, 'y'}, {"help", no_argument, 0, HELP_LONG_OPT}, {0, 0, 0, 0} }; @@ -1046,10 +1063,65 @@ static void print_usage(void) "\t-h (--height): set the height of each graph\n" "\t-w (--width): set the width of each graph\n" "\t-c (--columns): numbers of columns in graph output\n" + "\t-x (--xzoom): limit processed time to min:max\n" + "\t-y (--yzoom): limit processed sectors to min:max\n" ); exit(1); } +static int parse_double_range(char *str, double *min, double *max) +{ + char *end; + + /* Empty lower bound - leave original value */ + if (str[0] != ':') { + *min = strtod(str, &end); + if (*min == HUGE_VAL || *min == -HUGE_VAL) + return -ERANGE; + if (*end != ':') + return -EINVAL; + } else + end = str; + /* Empty upper bound - leave original value */ + if (end[1]) { + *max = strtod(end+1, &end); + if (*max == HUGE_VAL || *max == -HUGE_VAL) + return -ERANGE; + if (*end != 0) + return -EINVAL; + } + if (*min > *max) + return -EINVAL; + return 0; +} + +static int parse_ull_range(char *str, unsigned long long *min, + unsigned long long *max) +{ + char *end; + + /* Empty lower bound - leave original value */ + if (str[0] != ':') { + *min = strtoull(str, &end, 10); + if (*min == ULLONG_MAX && errno == ERANGE) + return -ERANGE; + if (*end != ':') + return -EINVAL; + } else + end = str; + /* Empty upper bound - leave original value */ + if (end[1]) { + *max = strtoull(end+1, &end, 10); + if (*max == ULLONG_MAX && errno == ERANGE) + return -ERANGE; + if (*end != 0) + return -EINVAL; + } + if (*min > *max) + return -EINVAL; + return 0; +} + static int parse_options(int ac, char **av) { int c; @@ -1119,6 +1191,29 @@ static int parse_options(int ac, char **av) case 'c': columns = atoi(optarg); break; + case 'x': + if (parse_double_range(optarg, &min_time, &max_time) + < 0) { + fprintf(stderr, "Cannot parse time range %s\n", + optarg); + exit(1); + } + break; + case 'y': + if (parse_ull_range(optarg, &min_mb, &max_mb) + < 0) { + fprintf(stderr, + "Cannot parse offset range %s\n", + optarg); + exit(1); + } + if (max_mb > ULLONG_MAX >> 20) { + fprintf(stderr, + "Upper range limit too big." + " Maximum is %llu.\n", ULLONG_MAX >> 20); + exit(1); + } + break; case '?': case HELP_LONG_OPT: print_usage(); @@ -1204,6 +1299,14 @@ int main(int ac, char **av) /* step two, find the maxes for time and offset */ list_for_each_entry(tf, &all_traces, list) compare_minmax_tf(tf, &max_seconds, &min_offset, &max_offset); + min_seconds = min_time; + if (max_seconds > max_time) + max_seconds = ceil(max_time); + if (min_offset < min_mb << 20) + min_offset = min_mb << 20; + if (max_offset > max_mb << 20) + max_offset = max_mb << 20; + /* push the max we found into all the tfs */ set_all_minmax_tf(min_seconds, max_seconds, min_offset, max_offset); |