From: NeilBrown Date: Sat, 19 Mar 2011 03:32:59 +0000 (+1100) Subject: lafs: add "show device" and associated library routines. X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=49609fb9e512310676f8218e854a7a6367580d3d;p=lafs-utils.git lafs: add "show device" and associated library routines. "show device" can show a loaded device, or can show the device block from an arbitrary location on a device. Signed-off-by: NeilBrown --- diff --git a/include/lafs/lafs.h b/include/lafs/lafs.h index f8e37bd..b43a44e 100644 --- a/include/lafs/lafs.h +++ b/include/lafs/lafs.h @@ -65,6 +65,9 @@ void lafs_summary_update(struct lafs_ino *ino, int is_index); 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); + static inline struct lafs_dblk *dblk(struct lafs_blk *b) { return container_of(b, struct lafs_dblk, b); diff --git a/lib/lafs_print_devblock.c b/lib/lafs_print_devblock.c new file mode 100644 index 0000000..0eb7dd6 --- /dev/null +++ b/lib/lafs_print_devblock.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include "internal.h" + +void lafs_print_devblock(struct lafs_dev *dev) +{ + char uuidstr[37]; + time_t atime; + u32 crc, crc2; + printf("Superblock:\n"); + printf(" IdTag : %.16s\n", dev->idtag); + printf(" Version : %.15s\n", dev->version); + uuid_unparse(dev->uuid, uuidstr); + printf(" UUID : %s\n", uuidstr); + printf(" Checksum : %08x", (unsigned int)__le32_to_cpu(dev->checksum)); + crc = dev->checksum; + dev->checksum = 0; + crc2 = crc32(0, (uint32_t*)dev, LAFS_DEVBLK_SIZE); + dev->checksum = crc; + if (crc2 == crc) + printf(" (correct)\n"); + else + printf(" (expected %08x)\n", (unsigned int)__le32_to_cpu(crc2)); + printf(" Seq : %ld\n", (unsigned long)__le32_to_cpu(dev->seq)); + atime = (time_t)__le64_to_cpu(dev->ctime); + printf(" Creation : %.24s\n", ctime(&atime)); + printf(" Start : %llu\n", (unsigned long long)__le64_to_cpu(dev->start)); + printf(" Size : %llu\n", (unsigned long long)__le64_to_cpu(dev->size)); + printf(" Stride : %lu\n", (unsigned long)__le32_to_cpu(dev->stride)); + printf(" Width : %lu\n", (unsigned long) __le32_to_cpu(dev->width)); + printf(" StateBits : %d\n", dev->statebits); + printf(" Devblk[0] : %llu\n", (unsigned long long)__le64_to_cpu(dev->devaddr[0])); + printf(" Devblk[1] : %llu\n", (unsigned long long)__le64_to_cpu(dev->devaddr[1])); + printf(" State[0] : %llu\n", (unsigned long long)__le64_to_cpu(dev->stateaddr[0])); + printf(" State[1] : %llu\n", (unsigned long long)__le64_to_cpu(dev->stateaddr[1])); + printf(" State[2] : %llu\n", (unsigned long long)__le64_to_cpu(dev->stateaddr[2])); + printf(" State[3] : %llu\n", (unsigned long long)__le64_to_cpu(dev->stateaddr[3])); + printf(" SegSize : %lu\n", (unsigned long)__le32_to_cpu(dev->segment_size)); + printf(" SegOffs : %lu\n", (unsigned long)__le32_to_cpu(dev->segment_offset)); + printf(" SegCount : %lu\n", (unsigned long)__le32_to_cpu(dev->segment_count)); + printf(" BlkBits : %lu\n", (unsigned long)__le32_to_cpu(dev->blockbits)); + printf(" UsageInum : %lu\n", (unsigned long)__le32_to_cpu(dev->usage_inum)); + printf(" Level : %lu\n", (unsigned long)__le32_to_cpu(dev->level)); + printf("\n"); +} + diff --git a/lib/lafs_print_device.c b/lib/lafs_print_device.c new file mode 100644 index 0000000..993b899 --- /dev/null +++ b/lib/lafs_print_device.c @@ -0,0 +1,35 @@ +#include +#include +#include + +void lafs_print_device(struct lafs_device *dev) +{ + char uuidstr[37]; + + printf("Deviceblock:\n"); + printf(" IdTag : %.16s\n", "LaFS-DeviceBlock"); + printf(" Version : %.15s\n", dev->version); + uuid_unparse(dev->uuid, uuidstr); + printf(" UUID : %s\n", uuidstr); +// printf(" Checksum : %08x\n", (unsigned int)le32_to_cpu(super->checksum)); + printf(" Seq : %d\n", dev->seq); + printf(" Creation : %.24s\n", ctime(&dev->ctime.tv_sec)); + printf(" Start : %llu\n", (unsigned long long)dev->start); + printf(" Size : %llu\n", (unsigned long long)dev->size); + printf(" Stride : %lu\n", dev->stride); + printf(" Width : %lu\n", (unsigned long)dev->width); + printf(" StateSize : %d\n", dev->statesize); + printf(" Devblk[0] : %llu\n", (unsigned long long)dev->devaddr[0]); + printf(" Devblk[1] : %llu\n", (unsigned long long)dev->devaddr[1]); + printf(" State[0] : %llu\n", (unsigned long long)dev->stateaddr[0]); + printf(" State[1] : %llu\n", (unsigned long long)dev->stateaddr[1]); + printf(" State[2] : %llu\n", (unsigned long long)dev->stateaddr[2]); + printf(" State[3] : %llu\n", (unsigned long long)dev->stateaddr[3]); + printf(" SegSize : %lu\n", dev->segment_size); + printf(" SegOffs : %lu\n", dev->segment_offset); + printf(" SegCount : %lu\n", dev->segment_count); + printf(" BlkSize : %lu\n", (unsigned long)dev->blocksize); + printf(" UsageInum : %lu\n", (unsigned long)dev->usage_inum); +// printf(" Level : %lu\n", (unsigned long)le32_to_cpu(super->level)); + printf("\n"); +} diff --git a/tools/lafs.c b/tools/lafs.c index 0c7360c..1fceaf7 100644 --- a/tools/lafs.c +++ b/tools/lafs.c @@ -1092,6 +1092,115 @@ static void c_load_dev(struct state *st, void **args) } } +/****** SHOW *****/ +static struct cmd show_cmds[]; + +static char help_show[] = "Show content of various structures"; +static struct args args_show[] = { + { "STRUCT", subcommand, -1, {show_cmds}, "Structure type to show"}, + TERMINAL_ARG +}; +static void c_show(struct state *st, void **args) +{ + struct cmd *c = args[1]; + if (!c) { + printf("show: Please give a structure to show\n"); + return; + } + + c->cmd(st, args); +} + +/****** SHOW DEVICE ******/ +static char help_show_device[] = "Show the device-block stored on a device"; +static struct args args_show_device[] = { + { "DEVNAME", external, -1, {NULL}, "Device to show info for"}, + { "-file", external, 0, {NULL}, "File to read as a device"}, + { "-addr", opaque, -1, {NULL}, "Byte address to read block from"}, + TERMINAL_ARG +}; +static void c_show_device(struct state *st, void **args) +{ + struct lafs_device *dev; + char *devname = args[2]; + char *err; + long long device_bytes = 0; + long long addr; + int fd; + + if (!devname && !st->lafs->devs) { + printf("show device: no devices loaded - please give a device name\n"); + return; + } + if (args[4]) { + char *addrstr = args[4]; + char *endp; + struct lafs_dev dv; + if (!devname) { + printf("show device: device name must be given with address\n"); + return; + } + addr = strtoll(addrstr, &endp, 0); + if (endp == addrstr || *endp) { + printf("show device: %s is not a valid number\n", + addrstr); + return; + } + fd = open_device(devname, &device_bytes, args[3] != NULL, &err); + if (fd < 0) { + printf("show device: %s\n", err); + free(err); + return; + } + if (lseek64(fd, addr, 0) != addr || + read(fd, &dv, sizeof(dv)) != sizeof(dv)) { + printf("show device: Cannot read device block at %lld on %s\n", + addr, devname); + } else + lafs_print_devblock(&dv); + close(fd); + return; + } + + for (dev = st->lafs->devs; dev; dev = dev->next) { + if (devname && strcmp(devname, dev->name) != 0) + continue; + printf("Device %s: %d out of %d\n", dev->name, + dev->devnum, dev->devices); + lafs_print_device(dev); + if (devname) + return; + } + if (!devname) + return; + /* Not already loaded, try to load-and-print */ + fd = open_device(devname, &device_bytes, args[3] != NULL, &err); + if (fd < 0) { + printf("show device: %s\n", err); + free(err); + return; + } + dev = lafs_load(fd, device_bytes, &err); + if (!dev) { + printf("show device: Cannot load %s: %s\n", + devname, err); + close(fd); + return; + } + + if (err) + printf("Loaded device %s, however: %s\n", devname, err); + else + printf("Loaded device %s\n", devname); + lafs_print_device(dev); + talloc_free(dev); +} +#define SCMD(x) {#x, c_show_##x, args_show_##x, help_show_##x} +static struct cmd show_cmds[] = { + SCMD(device), + { NULL, NULL, NULL, NULL} +}; + /****** STORE ******/ static char help_store[] = "Create a file in the LaFS from an external file"; static struct args args_store[] = { @@ -1123,6 +1232,7 @@ static struct cmd lafs_cmds[] = { CMD(newfs), CMD(quit), CMD(reset), + CMD(show), CMD(store), CMD(write_checkpoint), CMD(write_dev),