diff --git a/bcache.c b/bcache.c index 06b06cf1..2c1f2322 100644 --- a/bcache.c +++ b/bcache.c @@ -963,7 +963,7 @@ 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) { +char *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 @@ -974,6 +974,7 @@ void find_matching_uuid(char *stats_dir, char *subdir, const char *stats_dev_uui struct stat cache_stat; char intbuf[4]; char entry[MAX_PATH]; + char *err = NULL; snprintf(entry, MAX_PATH, "%s%s", stats_dir, subdir); snprintf(intbuf, 4, "%d", i); @@ -1010,7 +1011,7 @@ void find_matching_uuid(char *stats_dir, char *subdir, const char *stats_dev_uui query_dev(devname, false, false, true, dev_uuid); if(!strcmp(stats_dev_uuid, dev_uuid)) { strcat(subdir, intbuf); - return; + return err; } } @@ -1022,17 +1023,20 @@ void find_matching_uuid(char *stats_dir, char *subdir, const char *stats_dev_uui } - printf("dev uuid doesn't exist in cache_set\n"); - exit(1); + err = "dev uuid doesn't exist in cache_set"; + return err; } -int list_cachesets(char *cset_dir, bool list_devs) +char *list_cachesets(char *cset_dir, bool list_devs) { struct dirent *ent; - DIR *dir = opendir(cset_dir); + DIR *dir; + char *err = NULL; + + dir = opendir(cset_dir); if (!dir) { - fprintf(stderr, "Failed to open dir %s\n", cset_dir); - return 1; + err = "Failed to open cacheset dir"; + goto err; } while ((ent = readdir(dir)) != NULL) { @@ -1045,8 +1049,8 @@ int list_cachesets(char *cset_dir, bool list_devs) snprintf(entry, MAX_PATH, "%s/%s", cset_dir, ent->d_name); if(stat(entry, &statbuf) == -1) { - fprintf(stderr, "Failed to stat %s\n", entry); - return 1; + err = "Failed to stat cacheset subdir"; + goto err; } if (S_ISDIR(statbuf.st_mode)) { @@ -1058,55 +1062,63 @@ int list_cachesets(char *cset_dir, bool list_devs) } } +err: closedir(dir); - - return 0; + return err; } -static int get_bcache_fd(void) -{ - int bcachefd = open("/dev/bcache", O_RDWR); - - if (bcachefd < 0) { - perror("Can't open bcache device\n"); - exit(EXIT_FAILURE); - } - return bcachefd; -} - -int register_bcache(char *const *devs) +char *register_bcache(char *const *devs) { int ret, bcachefd; + char *err = NULL; - bcachefd = get_bcache_fd(); + bcachefd = open("/dev/bcache", O_RDWR); + if (bcachefd < 0) { + err = "Can't open bcache device"; + goto err; + } ret = ioctl(bcachefd, BCH_IOCTL_REGISTER, devs); if (ret < 0) { - fprintf(stderr, "ioctl register error: %s\n", strerror(ret)); - exit(EXIT_FAILURE); + char tmp[64]; + snprintf(tmp, 64, "ioctl register error: %s\n", + strerror(ret)); + err = strdup(tmp); + goto err; } - close(bcachefd); - return 0; +err: + if (bcachefd) + close(bcachefd); + return err; } -int unregister_bcache(char *const *devs) +char *unregister_bcache(char *const *devs) { int ret, bcachefd; + char *err = NULL; - bcachefd = get_bcache_fd(); + bcachefd = open("/dev/bcache", O_RDWR); + if (bcachefd < 0) { + err = "Can't open bcache device"; + goto err; + } ret = ioctl(bcachefd, BCH_IOCTL_UNREGISTER, devs); if (ret < 0) { - fprintf(stderr, "ioctl unregister error: %s\n", strerror(ret)); - exit(EXIT_FAILURE); + char tmp[64]; + snprintf(tmp, 64, "ioctl unregister error: %s\n", + strerror(ret)); + err = strdup(tmp); + goto err; } +err: close(bcachefd); - return 0; + return err; } -int probe(char *dev, int udev) +char *probe(char *dev, int udev) { struct cache_sb sb; char uuid[40]; @@ -1164,9 +1176,8 @@ int probe(char *dev, int udev) return 0; - err: - fprintf(stderr, "Probe exit with error: %s", err); - return -1; +err: + return err; } void sb_state(struct cache_sb *sb, char *dev) @@ -1181,15 +1192,18 @@ void sb_state(struct cache_sb *sb, char *dev) } -void read_stat_dir(DIR *dir, char *stats_dir, char *stat_name, bool print_val) +char *read_stat_dir(DIR *dir, char *stats_dir, char *stat_name, bool print_val) { struct stat statbuf; char entry[MAX_PATH]; + char *err = NULL; snprintf(entry, MAX_PATH, "%s/%s", stats_dir, stat_name); if(stat(entry, &statbuf) == -1) { - fprintf(stderr, "Failed to stat %s\n", entry); - return; + char tmp[MAX_PATH]; + snprintf(tmp, MAX_PATH, "Failed to stat %s\n", entry); + err = strdup(tmp); + goto err; } if (S_ISREG(statbuf.st_mode)) { @@ -1200,7 +1214,7 @@ void read_stat_dir(DIR *dir, char *stats_dir, char *stat_name, bool print_val) if(!fp) { /* If we can't open the file, this is probably because * of permissions, just move to the next file */ - return; + return NULL; } while(fgets(buf, MAX_PATH, fp)); @@ -1211,4 +1225,6 @@ void read_stat_dir(DIR *dir, char *stats_dir, char *stat_name, bool print_val) printf("%s\n", stat_name); fclose(fp); } +err: + return err; } diff --git a/bcache.h b/bcache.h index 3737facc..99307e64 100644 --- a/bcache.h +++ b/bcache.h @@ -59,14 +59,14 @@ 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, char *dev_uuid); -int list_cachesets(char *, bool); +char *list_cachesets(char *, bool); char *parse_array_to_list(char *const *); -int register_bcache(char *const *); -int unregister_bcache(char *const *); -int probe(char *, int); +char *register_bcache(char *const *); +char *unregister_bcache(char *const *); +char *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*); +char *read_stat_dir(DIR *, char *, char *, bool); +char *find_matching_uuid(char *, char *, const char*); //int add_device(char *); //int remove_device(char *); diff --git a/bcacheadm.c b/bcacheadm.c index 15260b0e..913fcefd 100644 --- a/bcacheadm.c +++ b/bcacheadm.c @@ -112,14 +112,12 @@ static int set_block_size(NihOption *option, const char *arg) static int set_cache(NihOption *option, const char *arg) { bdev = 0; - cache_devices[nr_cache_devices] = (char *)malloc(sizeof(char *) * - strlen(arg) + 1); cache_devices[nr_cache_devices] = strdup(arg); if(!tier) tier_mapping[nr_cache_devices] = 0; else { int ntier = atoi(tier); - if(tier == 0 || tier == 1) + if(ntier == 0 || ntier == 1) tier_mapping[nr_cache_devices] = ntier; else printf("Invalid tier\n"); @@ -133,14 +131,9 @@ static int set_bdev(NihOption *option, const char *arg) { bdev = 1; - if(label) { - backing_dev_labels[nr_backing_devices] = - (char *)malloc(sizeof(char *) * strlen(label) + 1); + if(label) backing_dev_labels[nr_backing_devices] = strdup(label); - } - backing_devices[nr_backing_devices] = (char *)malloc(sizeof(char *) * - strlen(arg) + 1); backing_devices[nr_backing_devices] = strdup(arg); nr_backing_devices++; @@ -350,9 +343,14 @@ int make_bcache(NihCommand *command, char *const *args) int probe_bcache(NihCommand *command, char *const *args) { int i; + char *err = NULL; for (i = 0; args[i] != NULL; i++) { - probe(args[i], udev); + err = probe(args[i], udev); + if(err) { + printf("probe_bcache error: %s\n", err); + return -1; + } } return 0; @@ -360,21 +358,40 @@ int probe_bcache(NihCommand *command, char *const *args) int bcache_register(NihCommand *command, char *const *args) { - int ret = register_bcache(args); + char *err = NULL; - return ret; + err = register_bcache(args); + if (err) { + printf("bcache_register error: %s\n", err); + return -1; + } + + return 0; } int bcache_unregister(NihCommand *command, char *const *args) { - int ret = unregister_bcache(args); + char *err = NULL; - return ret; + err = unregister_bcache(args); + if (err) { + printf("bcache_unregister error: %s\n", err); + return -1; + } + + return 0; } int bcache_list_cachesets(NihCommand *command, char *const *args) { - return list_cachesets(cset_dir, list_devs); + char *err = NULL; + err = list_cachesets(cset_dir, list_devs); + if (err) { + printf("bcache_list_cachesets error :%s\n", err); + return -1; + } + + return 0; } int bcache_query_devs(NihCommand *command, char *const *args) @@ -416,12 +433,15 @@ int bcache_status(NihCommand *command, char *const *args) if (sb_tier1) sb_state(sb_tier1, dev1); } -static void stats_subdir(char* stats_dir) +static char *stats_subdir(char* stats_dir) { char tmp[50] = "/"; + char *err = NULL; if(stats_dev_uuid) { strcat(tmp, "cache"); - find_matching_uuid(stats_dir, tmp, stats_dev_uuid); + err = find_matching_uuid(stats_dir, tmp, stats_dev_uuid); + if(err) + goto err; } else if(stats_cache_num) { strcat(tmp, "cache"); strcat(tmp, stats_cache_num); @@ -434,9 +454,12 @@ static void stats_subdir(char* stats_dir) else if (stats_total) strcat(tmp, "stats_total"); else - return; + return err; strcat(stats_dir, tmp); + +err: + return err; } int bcache_stats(NihCommand *command, char *const *args) @@ -445,29 +468,46 @@ int bcache_stats(NihCommand *command, char *const *args) char stats_dir[MAX_PATH]; DIR *dir = NULL; struct dirent *ent = NULL; + char *err = NULL; if (stats_uuid) { snprintf(stats_dir, MAX_PATH, "%s/%s", cset_dir, stats_uuid); - stats_subdir(stats_dir); + err = stats_subdir(stats_dir); + if(err) + goto err; + dir = opendir(stats_dir); if (!dir) { - fprintf(stderr, "Failed to open dir %s\n", cset_dir); - return 1; + err = "Failed to open dir"; + goto err; } } else { - printf("Must provide a cacheset uuid\n"); - exit(EXIT_FAILURE); + err = "Must provide a cacheset uuid"; + goto err; } - if(stats_list || stats_all) - while ((ent = readdir(dir)) != NULL) - read_stat_dir(dir, stats_dir, ent->d_name, stats_all); + if(stats_list || stats_all) { + while ((ent = readdir(dir)) != NULL) { + err = read_stat_dir(dir, stats_dir, ent->d_name, stats_all); + if (err) + goto err; + } + } - for (i = 0; args[i] != NULL; i++) - read_stat_dir(dir, stats_dir, args[i], true); + for (i = 0; args[i] != NULL; i++) { + err = read_stat_dir(dir, stats_dir, args[i], true); + if (err) + goto err; + } closedir(dir); + return 0; + +err: + closedir(dir); + printf("bcache_stats error: %s\n", err); + return -1; } static NihCommand commands[] = {