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)
{
}
memset(fs, 0, sizeof(*fs));
+ fs->statesize = 1024;
INIT_LIST_HEAD(&fs->wc[0].blocks);
INIT_LIST_HEAD(&fs->wc[1].blocks);
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;
--- /dev/null
+#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);
+}
--- /dev/null
+#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");
+}
+
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}
};