diff options
author | Gabriel <g2p.code@gmail.com> | 2013-03-09 13:22:24 +0100 |
---|---|---|
committer | Gabriel <g2p.code@gmail.com> | 2013-03-09 14:33:08 +0100 |
commit | 865a3b1f0b3093ffbdf1ac91076f1c7ac7d22238 (patch) | |
tree | a6704d782142db2ec318ddf52866966ba502e705 /bcache-super-show.c | |
parent | 42c182c6ab1530b5e3b18893f284da3eaec46e74 (diff) |
Add a command to display a bcache superblock.
Diffstat (limited to 'bcache-super-show.c')
-rw-r--r-- | bcache-super-show.c | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/bcache-super-show.c b/bcache-super-show.c new file mode 100644 index 0000000..6f9f6a7 --- /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 <errno.h> +#include <fcntl.h> +#include <inttypes.h> +#include <linux/fs.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <uuid/uuid.h> + +#include "bcache.h" + + +static void usage() +{ + fprintf(stderr, "Usage: bcache-super-show [-f] <device>\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; +} |