summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bcache.c2
-rw-r--r--bcache.h2
-rw-r--r--bcacheadm.c84
3 files changed, 80 insertions, 8 deletions
diff --git a/bcache.c b/bcache.c
index f64fda70..9b20e020 100644
--- a/bcache.c
+++ b/bcache.c
@@ -953,7 +953,7 @@ struct cache_sb *query_dev(char *dev, bool force_csum,
return sb;
}
-static char *dev_name(const char *ugly_path) {
+char *dev_name(const char *ugly_path) {
char buf[32];
int i, end = strlen(ugly_path);
diff --git a/bcache.h b/bcache.h
index 4cfac71f..166f6fdf 100644
--- a/bcache.h
+++ b/bcache.h
@@ -109,6 +109,8 @@ char *find_matching_uuid(char *, char *, const char*);
char *add_devices(char *const *, char *);
char *remove_device(const char *, bool);
char *bcache_get_capacity(const char *, const char *, bool);
+char *dev_name(const char *);
+
#define csum_set(i, type) \
({ \
diff --git a/bcacheadm.c b/bcacheadm.c
index 837219ed..4fa81a70 100644
--- a/bcacheadm.c
+++ b/bcacheadm.c
@@ -570,19 +570,24 @@ int bcache_query_devs(NihCommand *command, char *const *args)
int bcache_status(NihCommand *command, char *const *args)
{
- int i, seq, nr_in_set = 0;
+ int i, dev_count = 0, seq, nr_in_set = 0;
struct cache_sb *seq_sb = NULL;
+ char cache_path[MAX_PATH];
+ char *dev_names[MAX_DEVS];
+ char *dev_uuids[MAX_DEVS];
+ char intbuf[4];
+ char set_uuid[40];
for (i = 0; args[i] != NULL; i++) {
struct cache_sb *sb = query_dev(args[i], false, false,
false, NULL);
- if(!sb) {
+ if (!sb) {
printf("Unable to open superblock, bad path\n");
return -1;
}
- if(!seq_sb || sb->seq > seq) {
+ if (!seq_sb || sb->seq > seq) {
seq = sb->seq;
seq_sb = sb;
nr_in_set = sb->nr_in_set;
@@ -590,26 +595,91 @@ int bcache_status(NihCommand *command, char *const *args)
free(sb);
}
- if(!seq_sb) {
+ if (!seq_sb) {
printf("Unable to find a superblock\n");
return -1;
} else {
+ uuid_unparse(seq_sb->set_uuid.b, set_uuid);
printf("%-50s%-15s%-4s\n", "uuid", "state", "tier");
}
+ snprintf(intbuf, 4, "%d", i);
+ snprintf(cache_path, MAX_PATH, "%s/%s/%s", cset_dir, set_uuid,
+ "cache0");
+
+ /*
+ * Get a list of all the devices from sysfs first, then
+ * compare it to the list we get back from the most up
+ * to date superblock. If there are any devices in the superblock
+ * that are not in sysfs, print out 'NOT PRESENT'
+ */
+ while (true) {
+ char buf[MAX_PATH];
+ int len;
+ DIR *cache_dir;
+
+ if(((cache_dir = opendir(cache_path)) == NULL) &&
+ dev_count < MAX_DEVS)
+ break;
+
+ if((len = readlink(cache_path, buf, sizeof(buf) - 1)) != -1) {
+ struct cache_sb *sb;
+ char dev_uuid[40];
+ char dev_path[32];
+
+ buf[len] = '\0';
+ dev_names[dev_count] = dev_name(buf);
+ snprintf(dev_path, MAX_PATH, "%s/%s", "/dev",
+ dev_names[dev_count]);
+ sb = query_dev(dev_path, false, false,
+ true, dev_uuid);
+ if (!sb) {
+ printf("error reading %s\n", dev_path);
+ return -1;
+ } else
+ free(sb);
+
+ dev_uuids[dev_count] = strdup(dev_uuid);
+ } else {
+ dev_uuids[dev_count] = strdup("Nothing");
+ dev_names[dev_count] = strdup("Nothing");
+ }
+
+ cache_path[strlen(cache_path) - strlen(intbuf)] = 0;
+ dev_count++;
+
+ snprintf(intbuf, 4, "%d", dev_count);
+ strcat(cache_path, intbuf);
+ }
+
for (i = 0; i < seq_sb->nr_in_set; i++) {
char uuid_str[40];
struct cache_member *m = ((struct cache_member *) seq_sb->d) + i;
+ char dev_state[32];
+ int j;
uuid_unparse(m->uuid.b, uuid_str);
- printf("%-50s%-15s%-4llu\n", uuid_str,
- cache_state[CACHE_STATE(m)],
+ for (j = 0; j < dev_count; j++) {
+ if (!strcmp(uuid_str, dev_uuids[j])) {
+ snprintf(dev_state, MAX_PATH, "%s", cache_state[CACHE_STATE(m)]);
+ break;
+ } else if (j == dev_count - 1) {
+ snprintf(dev_state, MAX_PATH, "%s", "missing");
+ break;
+ }
+ }
+
+ printf("%-50s%-15s%-4llu\n", uuid_str, dev_state,
CACHE_TIER(m));
}
- if(seq_sb)
+ if (seq_sb)
free(seq_sb);
+ for (i = 0; i < dev_count; i++) {
+ free(dev_names[i]);
+ free(dev_uuids[i]);
+ }
return 0;
}