]> git.neil.brown.name Git - lafs-utils.git/commitdiff
show state command and library function
authorNeilBrown <neilb@suse.de>
Sat, 19 Mar 2011 08:37:36 +0000 (19:37 +1100)
committerNeilBrown <neilb@suse.de>
Sat, 19 Mar 2011 08:37:36 +0000 (19:37 +1100)
Shows either a state block read of disk, or similar info for
current filesystem.

Signed-off-by: NeilBrown <neilb@suse.de>
include/lafs/lafs.h
lib/lafs_alloc.c
lib/lafs_mount.c
lib/lafs_print_lafs.c [new file with mode: 0644]
lib/lafs_print_state.c [new file with mode: 0644]
tools/lafs.c

index eab54829a9daa96c31a9b468ef3f439d9d18d8a8..4181339acbb157ab925c497db7da1b121d793de5 100644 (file)
@@ -68,6 +68,8 @@ void lafs_segment_count(struct lafs *fs, loff_t addr, int diff);
 void lafs_print_device(struct lafs_device *dev);
 void lafs_print_devblock(struct lafs_dev *dev);
 char *lafs_mount(struct lafs *fs, int force);
+void lafs_print_state(struct lafs_state *state, int size);
+void lafs_print_lafs(struct lafs *fs);
 
 static inline struct lafs_dblk *dblk(struct lafs_blk *b)
 {
index 6255c5db547b8a54377f3b96c7faad32f6482df7..148a58d6af82d2f471788ee7e93c7ca2dd316088 100644 (file)
@@ -22,6 +22,7 @@ struct lafs *lafs_alloc(void)
        }
 
        memset(fs, 0, sizeof(*fs));
+       fs->statesize = 1024;
 
        INIT_LIST_HEAD(&fs->wc[0].blocks);
        INIT_LIST_HEAD(&fs->wc[1].blocks);
index 71c2e2460ca02ee94d94c6c7ba9db633393a08ee..5be0527231a2e08be04013efa94e622a2e3b527e 100644 (file)
@@ -92,7 +92,10 @@ char *lafs_mount(struct lafs *fs, int force)
 
        ssp = &fs->ss.next;
        for (s = 1; s < __le32_to_cpu(st->maxsnapshot); s++) {
-               struct lafs_snapshot *ss = talloc(fs, struct lafs_snapshot);
+               struct lafs_snapshot *ss;
+               if (st->root_inodes[s] == 0)
+                       continue;
+               ss = talloc(fs, struct lafs_snapshot);
                ss->next = NULL;
                ss->root_addr = __le64_to_cpu(st->root_inodes[s]);
                ss->root = NULL;
diff --git a/lib/lafs_print_lafs.c b/lib/lafs_print_lafs.c
new file mode 100644 (file)
index 0000000..265506c
--- /dev/null
@@ -0,0 +1,26 @@
+#include <uuid/uuid.h>
+#include <lafs/lafs.h>
+#include <stdio.h>
+#include "internal.h"
+
+void lafs_print_lafs(struct lafs *fs)
+{
+       char uuidstr[37];
+       int s;
+       struct lafs_snapshot *ss;
+
+       printf("LaFS State:\n");
+       printf(" Version    : %.15s\n", fs->version);
+       uuid_unparse(fs->uuid, uuidstr);
+       printf(" UUID       : %s\n", uuidstr);
+       printf(" Seq        : %d\n", (int)fs->seq);
+       printf(" Devices    : %d\n", fs->devices);
+       printf(" Loaded devs: %d\n", fs->loaded_devs);
+       printf(" BlockSize  : %d\n", fs->blocksize);
+       printf(" StateSize  : %d\n", fs->statesize);
+       printf(" MaxSegsize : %d\n", fs->max_segment);
+       printf(" CheckPoint : %llu\n", (unsigned long long)fs->checkpoint_cluster);
+       printf(" NextYouth  : %d\n", fs->youth_next);
+       for (s= 0, ss = &fs->ss; ss ; ss = ss->next)
+               printf(" Root[%d]    : %llu\n", s, (unsigned long long)ss->root_addr);
+}
diff --git a/lib/lafs_print_state.c b/lib/lafs_print_state.c
new file mode 100644 (file)
index 0000000..d3c8b05
--- /dev/null
@@ -0,0 +1,49 @@
+#include <uuid/uuid.h>
+#include <lafs/lafs.h>
+#include <stdio.h>
+#include "internal.h"
+
+void lafs_print_state(struct lafs_state *state, int size)
+{
+       char uuidstr[37];
+       u32 crc, crc2;
+       int l;
+       int maxss;
+
+       printf("Stateblock:\n");
+       printf(" IDtag      : %.16s\n", state->idtag);
+       printf(" Version    : %.15s\n", state->version);
+       uuid_unparse(state->uuid, uuidstr);
+       printf(" UUID       : %s\n", uuidstr);
+       printf(" Checksum   : %08x", (int) __le32_to_cpu(state->checksum));
+       crc = state->checksum;
+       state->checksum = 0;
+       crc2 = crc32(0, (uint32_t*)state, size);
+       state->checksum = crc;
+       if (crc2 == crc)
+               printf(" (correct)\n");
+       else
+               printf(" (expected %08x)\n", (unsigned int)__le32_to_cpu(crc2));
+       printf(" Seq        : %d\n", (int)__le32_to_cpu(state->seq));
+       printf(" Levels     : %d\n", (int)__le32_to_cpu(state->levels));
+       printf(" Devices    : %d\n", (int)__le32_to_cpu(state->devices));
+       printf(" MaxSnap    : %d\n", (int)__le32_to_cpu(state->maxsnapshot));
+       printf(" NextYouth  : %d\n", (int)__le16_to_cpu(state->nextyouth));
+       if (__le16_to_cpu(state->nonlog_dev) < 0xFFFF) {
+               printf(" NonLogSeg  : %d\n", (int)__le32_to_cpu(state->nonlog_segment));
+               printf(" NonLogDev  : %d\n", (int)__le16_to_cpu(state->nonlog_dev));
+               printf(" NonLogOff  : %d\n", (int)__le16_to_cpu(state->nonlog_offset));
+       }
+
+       printf(" CheckPoint : %llu\n",
+              (unsigned long long)__le64_to_cpu(state->checkpointcluster));
+       maxss = __le32_to_cpu(state->maxsnapshot);
+       if (maxss > (size - sizeof(*state)) / 4)
+               maxss = (size - sizeof(*state)) / 4;
+       for (l=0; l < maxss; l++)
+               printf(" Root[%d]    : %llu\n", l+1, 
+                      (unsigned long long)__le64_to_cpu(state->root_inodes[l]));
+
+       printf("\n");
+}
+
index 32e5de7f457daf9c70c55f587d1ace037805f4fc..12a9cc363d694aae42bf7e87accef08f29508aab 100644 (file)
@@ -1248,9 +1248,86 @@ static void c_show_device(struct state *st, void **args)
        lafs_print_device(dev);
        talloc_free(dev);
 }
+
+/****** SHOW STATE ******/
+static char help_show_state[] = "Show the current fs state or content of a state block";
+static struct args args_show_state[] = {
+       { "DEVNAME", external, -1, {NULL}, "Device to find state block on"},
+       { "-file", external, 0, {NULL}, "File to read state block from"},
+       { "-addr", opaque, -1, {NULL}, "Byte address to read block from"},
+       TERMINAL_ARG
+};
+static void c_show_state(struct state *st, void **args)
+{
+       char *devname;
+       long long addr;
+       struct lafs_device *dv;
+       struct lafs_state *state;
+       int fd;
+
+       if (args[4] && !args[2]) {
+               printf("show state: Cannot give address without device name\n");
+               return;
+       }
+       if (!args[2]) {
+               /* Show currently loaded state */
+               if (!st->lafs->ss.root_addr) {
+                       printf("show state: LaFS not mounted, no state available\n");
+                       return;
+               }
+               lafs_print_lafs(st->lafs);
+               return;
+       }
+
+       devname = args[2];
+       if (args[4]) {
+               char *addrstr = args[4];
+               char *endp;
+               long long device_bytes = 0;
+               char *err;
+
+               addr = strtoll(addrstr, &endp, 0);
+               if (endp == addrstr || *endp) {
+                       printf("show state: %s is not a valid number\n",
+                              addrstr);
+                       return;
+               }
+               dv = NULL;
+               fd = open_device(devname, &device_bytes, args[3] != NULL, &err);
+               if (fd < 0) {
+                       printf("show state: %s\n", err);
+                       free(err);
+                       return;
+               }
+       } else {
+               for (dv = st->lafs->devs; dv ; dv = dv->next)
+                       if (strcmp(devname, dv->name) == 0)
+                               break;
+               if (!dv) {
+
+                       printf("show state: device %s not loaded and no address given\n",
+                              devname);
+                       return;
+               }
+               fd = dv->fd;
+               addr = dv->stateaddr[dv->recent_state];
+       }
+       state = malloc(st->lafs->statesize);
+       if (lseek64(fd, addr, 0) != addr ||
+           read(fd, state, st->lafs->statesize) != st->lafs->statesize) {
+               printf("show state: cannot load state block\n");
+               return;
+       }
+       lafs_print_state(state, st->lafs->statesize);
+       free(state);
+       if (!dv)
+               close(fd);
+}
+
 #define SCMD(x) {#x, c_show_##x, args_show_##x, help_show_##x}
 static struct cmd show_cmds[] = {
        SCMD(device),
+       SCMD(state),
        { NULL, NULL, NULL, NULL}
 };