From 865a3b1f0b3093ffbdf1ac91076f1c7ac7d22238 Mon Sep 17 00:00:00 2001 From: Gabriel Date: Sat, 9 Mar 2013 13:22:24 +0100 Subject: [PATCH] Add a command to display a bcache superblock. --- .gitignore | 1 + Makefile | 12 ++-- README | 3 + bcache-super-show.c | 145 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 156 insertions(+), 5 deletions(-) create mode 100644 bcache-super-show.c diff --git a/.gitignore b/.gitignore index c1743e26..e86f2562 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +bcache-super-show make-bcache probe-bcache .* diff --git a/Makefile b/Makefile index d15525b5..ce8c0c46 100644 --- a/Makefile +++ b/Makefile @@ -2,21 +2,23 @@ PREFIX=/usr CFLAGS+=-O2 -Wall -g -all: make-bcache probe-bcache +all: make-bcache probe-bcache bcache-super-show -install: make-bcache probe-bcache - install -m0755 make-bcache $(DESTDIR)${PREFIX}/sbin/ +install: make-bcache probe-bcache bcache-super-show + install -m0755 make-bcache bcache-super-show $(DESTDIR)${PREFIX}/sbin/ install -m0755 probe-bcache $(DESTDIR)/sbin/ install -m0644 61-bcache.rules $(DESTDIR)/lib/udev/rules.d/ -install -m0755 initramfs/script $(DESTDIR)/etc/initramfs-tools/scripts/init-premount/bcache -install -m0755 initramfs/hook $(DESTDIR)/etc/initramfs-tools/hooks/bcache - install -m0644 *.8 $(DESTDIR)${PREFIX}/share/man/man8 + install -m0644 -- *.8 $(DESTDIR)${PREFIX}/share/man/man8 # install -m0755 bcache-test $(DESTDIR)${PREFIX}/sbin/ clean: - $(RM) -f make-bcache probe-bcache bcache-test *.o + $(RM) -f make-bcache probe-bcache bcache-super-show bcache-test *.o bcache-test: LDLIBS += -lm -lssl -lcrypto make-bcache: LDLIBS += -luuid make-bcache: bcache.o probe-bcache: LDLIBS += -luuid +bcache-super-show: LDLIBS += -luuid +bcache-super-show: bcache.o diff --git a/README b/README index 3aa525f3..4a13db68 100644 --- a/README +++ b/README @@ -22,3 +22,6 @@ Only necessary until support for the bcache superblock is included in blkid; in the meantime, provides just enough functionality for a udev script to create the /dev/disk/by-uuid symlink. The arguments it does support are the same as for blkid. + +bcache-super-show +Prints the bcache superblock of a cache device or a backing device. diff --git a/bcache-super-show.c b/bcache-super-show.c new file mode 100644 index 00000000..6f9f6a75 --- /dev/null +++ b/bcache-super-show.c @@ -0,0 +1,145 @@ +#define _FILE_OFFSET_BITS 64 +#define __USE_FILE_OFFSET64 +#define _XOPEN_SOURCE 500 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bcache.h" + + +static void usage() +{ + fprintf(stderr, "Usage: bcache-super-show [-f] \n"); +} + + +int main(int argc, char **argv) +{ + bool force_csum = false; + int o; + extern char *optarg; + struct cache_sb sb; + char uuid[40]; + uint64_t expected_csum; + + while ((o = getopt(argc, argv, "f")) != EOF) + switch (o) { + case 'f': + force_csum = 1; + break; + + default: + usage(); + exit(1); + } + + argv += optind; + argc -= optind; + + if (argc != 1) { + usage(); + exit(1); + } + + int fd = open(argv[0], O_RDONLY); + if (fd < 0) { + printf("Can't open dev %s: %s\n", argv[0], strerror(errno)); + exit(2); + } + + if (pread(fd, &sb, sizeof(sb), 4096) != sizeof(sb)) { + fprintf(stderr, "Couldn't read\n"); + exit(2); + } + + printf("sb.magic\t\t"); + if (! memcmp(sb.magic, bcache_magic, 16)) { + printf("ok\n"); + } else { + printf("bad magic\n"); + fprintf(stderr, "Invalid superblock (bad magic)\n"); + exit(2); + } + + printf("sb.first_sector\t\t%" PRIu64, sb.offset); + if (sb.offset == SB_SECTOR) { + printf(" [match]\n"); + } else { + printf(" [expected %ds]\n", SB_SECTOR); + fprintf(stderr, "Invalid superblock (bad sector)\n"); + exit(2); + } + + printf("sb.csum\t\t\t0x%" PRIx64, sb.csum); + expected_csum = csum_set(&sb); + if (sb.csum == expected_csum) { + printf(" [match]\n"); + } else { + printf(" [expected %" PRIX64 "]\n", expected_csum); + if (! force_csum) { + fprintf(stderr, "Corrupt superblock (bad csum)\n"); + exit(2); + } + } + + printf("sb.version\t\t%" PRIu64, sb.version); + switch (sb.version) { + case 1: + printf(" [backing device]\n"); + break; + + case 2: + printf(" [cache device]\n"); + break; + + case 3: + printf(" [backing device with offset]\n"); + // XXX Kernel side bcache.h says different, and implements neither + return 0; //break; + + default: + printf(" [unknown]\n"); + // exit code? + return 0; + } + + putchar('\n'); + + uuid_unparse(sb.uuid, uuid); + printf("dev.uuid\t\t%s\n", uuid); + + printf( + "dev.sectors_per_block\t%u\n" + "dev.sectors_per_bucket\t%u\n" + "dev.bucket_count\t%ju\n" + "dev.cache_count\t\t%u\n" // expect version == 2 ? 1 : 0 + "dev.data.first_bucket\t%u\n", + sb.block_size, + sb.bucket_size, + sb.nbuckets, + sb.nr_this_dev, + sb.first_bucket); + + printf("dev.data.first_sector\t%u\n", sb.bucket_size * sb.first_bucket); + putchar('\n'); + + uuid_unparse(sb.set_uuid, uuid); + printf("cset.uuid\t\t%s\n", uuid); + + printf("cset.cache_count\t%u\n\n", sb.nr_in_set); + + return 0; +}