Remove exit points from libbache and return error messages instead.

Change-Id: Ibd238bb63354dae841c2a70e5ded550b3c603d4b
Signed-off-by: Jacob Malevich <jam@daterainc.com>
This commit is contained in:
Jacob Malevich 2014-11-24 17:16:55 -08:00
parent 0098187201
commit 7763a86ca8
3 changed files with 132 additions and 76 deletions

View File

@ -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 /* Do a query-dev --uuid only to get the uuid
* repeat on each dev until we find a matching one * repeat on each dev until we find a matching one
* append that cache# to subdir and return * 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; struct stat cache_stat;
char intbuf[4]; char intbuf[4];
char entry[MAX_PATH]; char entry[MAX_PATH];
char *err = NULL;
snprintf(entry, MAX_PATH, "%s%s", stats_dir, subdir); snprintf(entry, MAX_PATH, "%s%s", stats_dir, subdir);
snprintf(intbuf, 4, "%d", i); 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); query_dev(devname, false, false, true, dev_uuid);
if(!strcmp(stats_dev_uuid, dev_uuid)) { if(!strcmp(stats_dev_uuid, dev_uuid)) {
strcat(subdir, intbuf); 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"); err = "dev uuid doesn't exist in cache_set";
exit(1); return err;
} }
int list_cachesets(char *cset_dir, bool list_devs) char *list_cachesets(char *cset_dir, bool list_devs)
{ {
struct dirent *ent; struct dirent *ent;
DIR *dir = opendir(cset_dir); DIR *dir;
char *err = NULL;
dir = opendir(cset_dir);
if (!dir) { if (!dir) {
fprintf(stderr, "Failed to open dir %s\n", cset_dir); err = "Failed to open cacheset dir";
return 1; goto err;
} }
while ((ent = readdir(dir)) != NULL) { 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); snprintf(entry, MAX_PATH, "%s/%s", cset_dir, ent->d_name);
if(stat(entry, &statbuf) == -1) { if(stat(entry, &statbuf) == -1) {
fprintf(stderr, "Failed to stat %s\n", entry); err = "Failed to stat cacheset subdir";
return 1; goto err;
} }
if (S_ISDIR(statbuf.st_mode)) { if (S_ISDIR(statbuf.st_mode)) {
@ -1058,55 +1062,63 @@ int list_cachesets(char *cset_dir, bool list_devs)
} }
} }
err:
closedir(dir); closedir(dir);
return err;
return 0;
} }
static int get_bcache_fd(void) char *register_bcache(char *const *devs)
{
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)
{ {
int ret, bcachefd; 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); ret = ioctl(bcachefd, BCH_IOCTL_REGISTER, devs);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "ioctl register error: %s\n", strerror(ret)); char tmp[64];
exit(EXIT_FAILURE); snprintf(tmp, 64, "ioctl register error: %s\n",
strerror(ret));
err = strdup(tmp);
goto err;
} }
err:
if (bcachefd)
close(bcachefd); close(bcachefd);
return 0; return err;
} }
int unregister_bcache(char *const *devs) char *unregister_bcache(char *const *devs)
{ {
int ret, bcachefd; 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); ret = ioctl(bcachefd, BCH_IOCTL_UNREGISTER, devs);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "ioctl unregister error: %s\n", strerror(ret)); char tmp[64];
exit(EXIT_FAILURE); snprintf(tmp, 64, "ioctl unregister error: %s\n",
strerror(ret));
err = strdup(tmp);
goto err;
} }
err:
close(bcachefd); close(bcachefd);
return 0; return err;
} }
int probe(char *dev, int udev) char *probe(char *dev, int udev)
{ {
struct cache_sb sb; struct cache_sb sb;
char uuid[40]; char uuid[40];
@ -1164,9 +1176,8 @@ int probe(char *dev, int udev)
return 0; return 0;
err: err:
fprintf(stderr, "Probe exit with error: %s", err); return err;
return -1;
} }
void sb_state(struct cache_sb *sb, char *dev) 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; struct stat statbuf;
char entry[MAX_PATH]; char entry[MAX_PATH];
char *err = NULL;
snprintf(entry, MAX_PATH, "%s/%s", stats_dir, stat_name); snprintf(entry, MAX_PATH, "%s/%s", stats_dir, stat_name);
if(stat(entry, &statbuf) == -1) { if(stat(entry, &statbuf) == -1) {
fprintf(stderr, "Failed to stat %s\n", entry); char tmp[MAX_PATH];
return; snprintf(tmp, MAX_PATH, "Failed to stat %s\n", entry);
err = strdup(tmp);
goto err;
} }
if (S_ISREG(statbuf.st_mode)) { 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(!fp) {
/* If we can't open the file, this is probably because /* If we can't open the file, this is probably because
* of permissions, just move to the next file */ * of permissions, just move to the next file */
return; return NULL;
} }
while(fgets(buf, MAX_PATH, fp)); 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); printf("%s\n", stat_name);
fclose(fp); fclose(fp);
} }
err:
return err;
} }

View File

@ -59,14 +59,14 @@ void show_super_backingdev(struct cache_sb *, bool);
void show_super_cache(struct cache_sb *, bool); void show_super_cache(struct cache_sb *, bool);
struct cache_sb *query_dev(char *, bool, bool, bool, char *dev_uuid); 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 *); char *parse_array_to_list(char *const *);
int register_bcache(char *const *); char *register_bcache(char *const *);
int unregister_bcache(char *const *); char *unregister_bcache(char *const *);
int probe(char *, int); char *probe(char *, int);
void sb_state(struct cache_sb *, char *); void sb_state(struct cache_sb *, char *);
void read_stat_dir(DIR *, char *, char *, bool); char *read_stat_dir(DIR *, char *, char *, bool);
void find_matching_uuid(char *, char *, const char*); char *find_matching_uuid(char *, char *, const char*);
//int add_device(char *); //int add_device(char *);
//int remove_device(char *); //int remove_device(char *);

View File

@ -112,14 +112,12 @@ static int set_block_size(NihOption *option, const char *arg)
static int set_cache(NihOption *option, const char *arg) static int set_cache(NihOption *option, const char *arg)
{ {
bdev = 0; bdev = 0;
cache_devices[nr_cache_devices] = (char *)malloc(sizeof(char *) *
strlen(arg) + 1);
cache_devices[nr_cache_devices] = strdup(arg); cache_devices[nr_cache_devices] = strdup(arg);
if(!tier) if(!tier)
tier_mapping[nr_cache_devices] = 0; tier_mapping[nr_cache_devices] = 0;
else { else {
int ntier = atoi(tier); int ntier = atoi(tier);
if(tier == 0 || tier == 1) if(ntier == 0 || ntier == 1)
tier_mapping[nr_cache_devices] = ntier; tier_mapping[nr_cache_devices] = ntier;
else else
printf("Invalid tier\n"); printf("Invalid tier\n");
@ -133,14 +131,9 @@ static int set_bdev(NihOption *option, const char *arg)
{ {
bdev = 1; bdev = 1;
if(label) { if(label)
backing_dev_labels[nr_backing_devices] =
(char *)malloc(sizeof(char *) * strlen(label) + 1);
backing_dev_labels[nr_backing_devices] = strdup(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); backing_devices[nr_backing_devices] = strdup(arg);
nr_backing_devices++; nr_backing_devices++;
@ -350,9 +343,14 @@ int make_bcache(NihCommand *command, char *const *args)
int probe_bcache(NihCommand *command, char *const *args) int probe_bcache(NihCommand *command, char *const *args)
{ {
int i; int i;
char *err = NULL;
for (i = 0; args[i] != NULL; i++) { 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; return 0;
@ -360,21 +358,40 @@ int probe_bcache(NihCommand *command, char *const *args)
int bcache_register(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 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) 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) 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); 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 tmp[50] = "/";
char *err = NULL;
if(stats_dev_uuid) { if(stats_dev_uuid) {
strcat(tmp, "cache"); 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) { } else if(stats_cache_num) {
strcat(tmp, "cache"); strcat(tmp, "cache");
strcat(tmp, stats_cache_num); strcat(tmp, stats_cache_num);
@ -434,9 +454,12 @@ static void stats_subdir(char* stats_dir)
else if (stats_total) else if (stats_total)
strcat(tmp, "stats_total"); strcat(tmp, "stats_total");
else else
return; return err;
strcat(stats_dir, tmp); strcat(stats_dir, tmp);
err:
return err;
} }
int bcache_stats(NihCommand *command, char *const *args) 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]; char stats_dir[MAX_PATH];
DIR *dir = NULL; DIR *dir = NULL;
struct dirent *ent = NULL; struct dirent *ent = NULL;
char *err = NULL;
if (stats_uuid) { if (stats_uuid) {
snprintf(stats_dir, MAX_PATH, "%s/%s", cset_dir, 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); dir = opendir(stats_dir);
if (!dir) { if (!dir) {
fprintf(stderr, "Failed to open dir %s\n", cset_dir); err = "Failed to open dir";
return 1; goto err;
} }
} else { } else {
printf("Must provide a cacheset uuid\n"); err = "Must provide a cacheset uuid";
exit(EXIT_FAILURE); goto err;
} }
if(stats_list || stats_all) if(stats_list || stats_all) {
while ((ent = readdir(dir)) != NULL) while ((ent = readdir(dir)) != NULL) {
read_stat_dir(dir, stats_dir, ent->d_name, stats_all); err = read_stat_dir(dir, stats_dir, ent->d_name, stats_all);
if (err)
goto err;
}
}
for (i = 0; args[i] != NULL; i++) for (i = 0; args[i] != NULL; i++) {
read_stat_dir(dir, stats_dir, args[i], true); err = read_stat_dir(dir, stats_dir, args[i], true);
if (err)
goto err;
}
closedir(dir); closedir(dir);
return 0;
err:
closedir(dir);
printf("bcache_stats error: %s\n", err);
return -1;
} }
static NihCommand commands[] = { static NihCommand commands[] = {