diff --git a/bcache.c b/bcache.c index 72adccad..1e3668a1 100644 --- a/bcache.c +++ b/bcache.c @@ -718,10 +718,8 @@ static void print_encode(char *in) printf("%%%x", *pos); } -static void show_uuid_only(struct cache_sb *sb) { - char uuid[40]; - uuid_unparse(sb->uuid.b, uuid); - printf("%s\n", uuid); +static void show_uuid_only(struct cache_sb *sb, char *dev_uuid) { + uuid_unparse(sb->uuid.b, dev_uuid); } static void show_super_common(struct cache_sb *sb, bool force_csum) @@ -871,7 +869,7 @@ void show_super_cache(struct cache_sb *sb, bool force_csum) } struct cache_sb *query_dev(char *dev, bool force_csum, - bool print_sb, bool uuid_only) + bool print_sb, bool uuid_only, char *dev_uuid) { struct cache_sb sb_stack, *sb = &sb_stack; size_t bytes = sizeof(*sb); @@ -898,7 +896,7 @@ struct cache_sb *query_dev(char *dev, bool force_csum, } if(uuid_only) { - show_uuid_only(sb); + show_uuid_only(sb, dev_uuid); return sb; } @@ -968,6 +966,70 @@ static void list_cacheset_devs(char *cset_dir, char *cset_name, bool parse_dev_n } } +void find_matching_uuid(char *stats_dir, char *subdir, const char *stats_dev_uuid) { + /* Do a query-dev --uuid only to get the uuid + * repeat on each dev until we find a matching one + * append that cache# to subdir and return + */ + + int i = 0; + DIR *cachedir; + struct stat cache_stat; + char intbuf[4]; + char entry[256]; + + strcpy(entry, stats_dir); + strcat(entry, subdir); + snprintf(intbuf, 4, "%d", i); + strcat(entry, intbuf); + + while(true) { + char buf[256]; + int len; + + if((cachedir = opendir(entry)) == NULL) + break; + + if(stat(entry, &cache_stat)) + break; + + if((len = readlink(entry, buf, sizeof(buf) - 1)) != -1) { + char dev_uuid[40]; + buf[len] = '\0'; + int i, end = strlen(buf); + char tmp[32], devname[32]; + + /* Chop off "/bcache", then look for the + * next '/' from the end + */ + for (i = end - 8; ; i--) + if(buf[i] == '/') + break; + + strcpy(tmp, buf + i); + tmp[end - i - 7] = 0; + strcpy(devname, "/dev"); + strcat(devname, tmp); + + query_dev(devname, false, false, true, dev_uuid); + if(!strcmp(stats_dev_uuid, dev_uuid)) { + strcat(subdir, intbuf); + return; + } + } + + /* remove i from end and append i++ */ + entry[strlen(entry)-strlen(intbuf)] = 0; + i++; + snprintf(intbuf, 4, "%d", i); + strcat(entry, intbuf); + } + + + printf("dev uuid doesn't exist in cache_set\n"); + exit(1); +} + int list_cachesets(char *cset_dir, bool list_devs) { struct dirent *ent; @@ -1129,7 +1191,7 @@ void read_stat_dir(DIR *dir, char *stats_dir, char *stat_name, bool print_val) while(fgets(buf, 100, fp)); if(print_val) - printf("%s\t%s", stat_name, buf); + printf("%s\n", buf); else printf("%s\n", stat_name); fclose(fp); diff --git a/bcache.h b/bcache.h index e10c73c7..efd7525e 100644 --- a/bcache.h +++ b/bcache.h @@ -57,14 +57,14 @@ long strtoul_or_die(const char *, size_t, const char *); void show_super_backingdev(struct cache_sb *, bool); void show_super_cache(struct cache_sb *, bool); -struct cache_sb *query_dev(char *, bool, bool, bool); +struct cache_sb *query_dev(char *, bool, bool, bool, char *dev_uuid); int list_cachesets(char *, bool); char *parse_array_to_list(char *const *); int register_bcache(); int probe(char *, int); void sb_state(struct cache_sb *, char *); void read_stat_dir(DIR *, char *, char *, bool); - +void find_matching_uuid(char *, char *, const char*); #define csum_set(i, type) \ ({ \ diff --git a/bcacheadm.8 b/bcacheadm.8 index 84d919c1..0ff96697 100644 --- a/bcacheadm.8 +++ b/bcacheadm.8 @@ -134,9 +134,12 @@ List all stats and their values for the given device. .BR \-l,\ --list List the names of the different stats for the given device. .TP -.BR \-u,\ --uuid= +.BR \-u,\ --set= UUID for the cacheset .TP +.BR \-d,\ --dev= +UUID for a device within the cacheset. Must pass in the cacheset UUID in order to search for a dev. +.TP .BR \-c,\ --cache= Cache number, starts from 0 .TP diff --git a/bcacheadm.c b/bcacheadm.c index 76ad0c6b..e1d92509 100644 --- a/bcacheadm.c +++ b/bcacheadm.c @@ -95,6 +95,7 @@ bool status_all = false; bool stats_all = false; bool stats_list = false; static const char *stats_uuid = NULL; +static const char *stats_dev_uuid = NULL; static const char *stats_cache_num = NULL; bool stats_five_min = false; bool stats_hour = false; @@ -218,7 +219,8 @@ static NihOption status_options[] = { static NihOption stats_options[] = { {'a', "all", N_("all"), NULL, NULL, &stats_all, NULL}, {'l', "list", N_("list"), NULL, NULL, &stats_list, NULL}, - {'u', "uuid", N_("cache_set UUID"), NULL, "UUID", &stats_uuid, NULL}, + {'u', "set", N_("cache_set UUID"), NULL, "UUID", &stats_uuid, NULL}, + {'d', "dev", N_("dev UUID"), NULL, "UUID", &stats_dev_uuid, NULL}, {'c', "cache", N_("cache number (starts from 0)"), NULL, "CACHE#", &stats_cache_num, NULL}, {0, "five-min-stats", N_("stats accumulated in last 5 minutes"), NULL, NULL, &stats_five_min, NULL}, {0, "hour-stats", N_("stats accumulated in last hour"), NULL, NULL, &stats_hour, NULL}, @@ -363,9 +365,12 @@ int bcache_query_devs (NihCommand *command, char *const *args) { int i; - - for (i = 0; args[i] != NULL; i++) - query_dev(args[i], force_csum, true, uuid_only); + for (i = 0; args[i] != NULL; i++){ + char dev_uuid[40]; + query_dev(args[i], force_csum, true, uuid_only, dev_uuid); + if(uuid_only) + printf("%s\n", dev_uuid); + } } int bcache_status (NihCommand *command, char *const *args) @@ -375,7 +380,7 @@ int bcache_status (NihCommand *command, char *const *args) char *dev0 = NULL, *dev1 = NULL; for (i = 0; args[i] != NULL; i++) { - struct cache_sb *sb = query_dev(args[i], false, false, false); + struct cache_sb *sb = query_dev(args[i], false, false, false, NULL); struct cache_member *m = ((struct cache_member *) sb->d) + sb->nr_this_dev; long long unsigned cache_tier = CACHE_TIER(m); @@ -398,7 +403,10 @@ int bcache_status (NihCommand *command, char *const *args) static void stats_subdir(char* stats_dir) { char tmp[50] = "/"; - if(stats_cache_num) { + if(stats_dev_uuid) { + strcat(tmp, "cache"); + find_matching_uuid(stats_dir, tmp, stats_dev_uuid); + } else if(stats_cache_num) { strcat(tmp, "cache"); strcat(tmp, stats_cache_num); } else if (stats_five_min)