]> git.neil.brown.name Git - lafs-utils.git/commitdiff
lafs: add "show device" and associated library routines.
authorNeilBrown <neilb@suse.de>
Sat, 19 Mar 2011 03:32:59 +0000 (14:32 +1100)
committerNeilBrown <neilb@suse.de>
Sat, 19 Mar 2011 03:32:59 +0000 (14:32 +1100)
"show device" can show a loaded device, or can show the device block
from an arbitrary location on a device.

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

index f8e37bdb7485a1e1eed8d0d0949e42a23432945e..b43a44eb096d53588385cfd22ed083f7f9a6e84f 100644 (file)
@@ -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 (file)
index 0000000..0eb7dd6
--- /dev/null
@@ -0,0 +1,47 @@
+#include <uuid/uuid.h>
+#include <lafs/lafs.h>
+#include <stdio.h>
+#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 (file)
index 0000000..993b899
--- /dev/null
@@ -0,0 +1,35 @@
+#include <uuid/uuid.h>
+#include <lafs/lafs.h>
+#include <stdio.h>
+
+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");
+}
index 0c7360cd574dbe775f8392cc922ad75af2844238..1fceaf76a39fa4db7644a254e6fad9c079960fb0 100644 (file)
@@ -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),