From d39c04ca13e3bbc5e47107a8428e348414a65b5c Mon Sep 17 00:00:00 2001 From: "Alan D. Brunelle" Date: Wed, 31 Aug 2005 08:49:05 +0200 Subject: [PATCH] [PATCH] Add argument parsing for blktrace This patch adds the option of specifying the trace mask for blktrace, so you can register an interest in only certain events. --- CHANGELOG | 3 ++ README | 13 ++++- blktrace.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 147 insertions(+), 9 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ef2bfb4..377369c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +20050830: + - Added argument parsing + - Added action mask set up 20050829: - Improved error handling - Remove _dat files, include the payload in _out diff --git a/README b/README index 673683f..6167b84 100644 --- a/README +++ b/README @@ -26,7 +26,18 @@ Usage ----- To run: - % blktrace + % blktrace -d [-a [-a ]] + -a is one of: (use multiple -a options to get more) + READ + WRITE + BARRIER + SYNC + QUEUE + REQUEUE + ISSUE + COMPLETE + FS + PC --- run task to generate load to be traced --- --- Generates: diff --git a/blktrace.c b/blktrace.c index 1af2783..db1c840 100644 --- a/blktrace.c +++ b/blktrace.c @@ -2,7 +2,6 @@ * block queue tracing application * * TODO (in no particular order): - * - Add ability to specify capture mask instead of logging all events * - Add option for relayfs mount point * */ @@ -18,12 +17,68 @@ #include #include #include +#include +#include #include "blktrace.h" #define BUF_SIZE (128 *1024) #define BUF_NR (4) +#define DECLARE_MASK_MAP(mask) { BLK_TC_##mask, #mask, "BLK_TC_"#mask } +#define COMPARE_MASK_MAP(mmp, str) \ + (!strcmp(mmp->short_form, toupper(str)) || \ + !strcmp(mmp->long_form, toupper(str))) + +#define VALID_SET(x) ((1 <= (x)) && ((x) < (1 << BLK_TC_SHIFT))) + +struct mask_map { + int mask; + char *short_form; + char *long_form; +}; + +struct mask_map mask_maps[] = { + DECLARE_MASK_MAP( READ ), + DECLARE_MASK_MAP( WRITE ), + DECLARE_MASK_MAP( BARRIER ), + DECLARE_MASK_MAP( SYNC ), + DECLARE_MASK_MAP( QUEUE ), + DECLARE_MASK_MAP( REQUEUE ), + DECLARE_MASK_MAP( ISSUE ), + DECLARE_MASK_MAP( COMPLETE ), + DECLARE_MASK_MAP( FS ), + DECLARE_MASK_MAP( PC ), +}; + +#define S_OPTS "d:a:A:" +struct option l_opts[] = { + { + .name = "dev", + .has_arg = 1, + .flag = NULL, + .val = 'd' + }, + { + .name = "act-mask", + .has_arg = 1, + .flag = NULL, + .val = 'a' + }, + { + .name = "set-mask", + .has_arg = 1, + .flag = NULL, + .val = 'A' + }, + { + .name = NULL, + .has_arg = 0, + .flag = NULL, + .val = 0 + } +}; + struct thread_information { int cpu; pthread_t thread; @@ -38,6 +93,30 @@ static volatile int done; static int devfd, ncpus; static struct thread_information *thread_information; static char *buts_name_p; +static char *dev; +static int act_mask = ~0; + +inline int compare_mask_map(struct mask_map *mmp, char *string) +{ + int i; + char *s, *ustring = strdup(string); + + for (i = 0, s = ustring; i < strlen(ustring); i++, s++) + *s = toupper(*s); + + return !strcmp(mmp->short_form, ustring) || + !strcmp(mmp->long_form, ustring); +} + +int find_mask_map(char *string) +{ + int i; + + for (i = 0; i < sizeof(mask_maps)/sizeof(mask_maps[0]); i++) + if (compare_mask_map(&mask_maps[i], string)) + return mask_maps[i].mask; + return -1; +} static int start_trace(char *dev) { @@ -52,6 +131,7 @@ static int start_trace(char *dev) memset(&buts, sizeof(buts), 0); buts.buf_size = BUF_SIZE; buts.buf_nr = BUF_NR; + buts.act_mask = act_mask; printf("Starting trace on %s\n", dev); if (ioctl(devfd, BLKSTARTTRACE, &buts) < 0) { @@ -245,21 +325,65 @@ void handle_sigint(int sig) int main(int argc, char *argv[]) { struct stat st; - int i; + int i, c; + int act_mask_tmp = 0; + + while ((c = getopt_long(argc, argv, S_OPTS, l_opts, NULL)) >= 0) { + switch (c) { + case 'a': + i = find_mask_map(optarg); + if (i < 0) { + fprintf(stderr,"Invalid action mask %s\n", + optarg); + return 4; + } + act_mask_tmp |= i; + break; + + case 'A': + if ((sscanf(optarg, "%x", &i) != 1) || !VALID_SET(i)) { + fprintf(stderr, + "Invalid set action mask %s/0x%x\n", + optarg, i); + return 4; + } + act_mask_tmp = i; + break; - if (argc < 2) { - fprintf(stderr, "Usage: %s \n", argv[0]); - return 1; + case 'd': + dev = strdup(optarg); + break; + + default: + fprintf(stderr,"Usage: %s -d " + "[-a [-a ]]\n", argv[0]); + return 4; + } + } + + if ((dev == NULL) || (optind < argc)) { + fprintf(stderr,"Usage: %s -d " + "[-a [-a ]]\n", argv[0]); + return 4; + } + + if (act_mask_tmp != 0) { + act_mask = act_mask_tmp; + printf("Tracing 0x%04x: ", act_mask); + for (i = 0; i < BLK_TC_SHIFT; i++) + if (act_mask & (1 << i)) + printf("%s ", mask_maps[i].short_form); + printf("\n"); } if (stat(relay_path, &st) < 0) { - fprintf(stderr,"%s does not appear to be mounted\n", + fprintf(stderr,"%s does not appear to be mounted\n", relay_path); return 2; } - if (start_trace(argv[1])) { - fprintf(stderr, "Failed to start trace\n"); + if (start_trace(dev)) { + fprintf(stderr, "Failed to start trace on %s\n", dev); stop_trace(); return 3; } -- 2.25.1