diff options
author | Coly Li <colyli@suse.de> | 2021-07-27 00:06:24 +0800 |
---|---|---|
committer | Coly Li <colyli@suse.de> | 2021-10-25 16:39:25 +0800 |
commit | 492ef7a3b1a131f8a5d52ebf17d79f10fb85608e (patch) | |
tree | 2eb191173bffa2c8cf1a0214d86ce2cd541cb8d0 | |
parent | 4a8af34ed26cb72dcaac0dd4953c6c99094284d4 (diff) | |
download | bcache-tools-nvdimm_meta.tar.gz |
bcache-tools: support "bcache show -d" for nvdimm-meta devicenvdimm_meta
This patch adds support to display detail information of a nvdimm-meta
device by command "bcache show -d".
struct mdev is added into lib.h to represent nvdimm-meta device
information.
At this moment, commands "bcache show" and "bcache show -m" don't
support nvdimm-meta device yet.
Signed-off-by: Coly Li <colyli@suse.de>
Cc: Jianpeng Ma <jianpeng.ma@intel.com>
Cc: Qiaowei Ren <qiaowei.ren@intel.com>
-rw-r--r-- | bcache.c | 10 | ||||
-rw-r--r-- | lib.c | 65 | ||||
-rw-r--r-- | lib.h | 27 | ||||
-rw-r--r-- | make.c | 2 | ||||
-rw-r--r-- | show.c | 138 |
5 files changed, 192 insertions, 50 deletions
@@ -227,7 +227,7 @@ int attach_both(char *cdev, char *backdev) int ret; char buf[100]; - ret = detail_dev(backdev, &bd, &cd, &type); + ret = detail_dev(backdev, &bd, &cd, NULL, &type); if (ret != 0) return ret; if (type != BCACHE_SB_VERSION_BDEV @@ -242,7 +242,7 @@ int attach_both(char *cdev, char *backdev) } if (strlen(cdev) != 36) { - ret = detail_dev(cdev, &bd, &cd, &type); + ret = detail_dev(cdev, &bd, &cd, NULL, &type); if (type != BCACHE_SB_VERSION_CDEV && type != BCACHE_SB_VERSION_CDEV_WITH_UUID) { fprintf(stderr, "%s is not an cache device\n", cdev); @@ -356,7 +356,7 @@ int main(int argc, char **argv) int type = 1; int ret; - ret = detail_dev(devname, &bd, &cd, &type); + ret = detail_dev(devname, &bd, &cd, NULL, &type); if (ret != 0) return ret; if (type == BCACHE_SB_VERSION_BDEV) { @@ -401,7 +401,7 @@ int main(int argc, char **argv) int type = 1; int ret; - ret = detail_dev(devname, &bd, &cd, &type); + ret = detail_dev(devname, &bd, &cd, NULL, &type); if (ret != 0) { fprintf(stderr, "This device doesn't exist or failed to receive info from this device\n"); @@ -427,7 +427,7 @@ int main(int argc, char **argv) int type = 5; int ret; - ret = detail_dev(devname, &bd, &cd, &type); + ret = detail_dev(devname, &bd, &cd, NULL, &type); if (ret != 0) { fprintf(stderr, "This device doesn't exist or failed to receive info from this device\n"); @@ -13,10 +13,14 @@ #include <string.h> #include <malloc.h> #include <regex.h> +#include <libgen.h> #include "bcache.h" +#include "nvmpg_format.h" #include "lib.h" #include "bitwise.h" + + /* * utils function */ @@ -540,10 +544,61 @@ Fail: return 1; } -int detail_dev(char *devname, struct bdev *bd, struct cdev *cd, int *type) +int __detail_mdev(char *devname, struct bch_nvmpg_sb *nvm_sb, struct mdev *md) +{ + uint64_t expected_csum; + int ret = 1; + + if (memcmp(nvm_sb->magic, bch_nvmpg_magic, 16)) { + fprintf(stderr, + "Bad magic, make sure this is an bcache nvdimm meta device\n"); + goto out; + } + + if (nvm_sb->sb_offset != BCH_NVMPG_SB_OFFSET) { + fprintf(stderr, "Invalid superblock (bad sector)\n"); + goto out; + } + + expected_csum = csum_set(nvm_sb); + if (expected_csum != nvm_sb->csum) { + fprintf(stderr, "Csum is not match with expected one\n"); + goto out; + } + + memset(md, 0, sizeof(struct mdev)); + + md->magic = "ok"; + md->csum = nvm_sb->csum; + md->ns_start = nvm_sb->ns_start; + md->sb_offset = nvm_sb->sb_offset; + md->version = nvm_sb->version; + uuid_unparse(nvm_sb->uuid, md->uuid); + md->page_size = nvm_sb->page_size; + md->total_ns = nvm_sb->total_ns; + md->this_ns = nvm_sb->this_ns; + uuid_unparse(nvm_sb->set_uuid, md->set_uuid); + md->flags = nvm_sb->flags; + md->seq = nvm_sb->seq; + strncpy(md->bname, basename(devname), 40); + md->feature_compat = nvm_sb->feature_compat; + md->feature_ro_compat = nvm_sb->feature_ro_compat; + md->feature_incompat = nvm_sb->feature_incompat; + md->pages_offset = nvm_sb->pages_offset; + md->pages_total = nvm_sb->pages_total; + md->set_header_offset = nvm_sb->set_header_offset; + + ret = 0; +out: + return ret; +} + +int detail_dev(char *devname, struct bdev *bd, struct cdev *cd, + struct mdev *md, int *type) { char *buf = NULL; struct cache_sb_disk *sb_disk = NULL; + struct bch_nvmpg_sb *nvm_sb = NULL; int buf_size = 16<<10, ret = 1; int fd; @@ -572,6 +627,14 @@ int detail_dev(char *devname, struct bdev *bd, struct cdev *cd, int *type) goto out_memory; } + /* Try whether it is nvm_pages super block */ + nvm_sb = (struct bch_nvmpg_sb *)(buf + BCH_NVMPG_SB_OFFSET); + if (!memcmp(nvm_sb->magic, bch_nvmpg_magic, 16)) { + ret = __detail_mdev(devname, nvm_sb, md); + *type = -1; + goto out_memory; + } + fprintf(stderr, "Error: Bad magic, not bcache device\n"); out_memory: @@ -43,9 +43,34 @@ struct cdev { unsigned int replacement; }; +struct mdev { + struct cache_sb *sb; + uint64_t csum; + uint64_t sb_offset; + uint64_t ns_start; + uint64_t version; + char *magic; + char uuid[40]; + uint32_t page_size; + uint32_t total_ns; + uint32_t this_ns; + union { + char set_uuid[40]; + uint64_t set_magic; + }; + uint64_t flags; + uint64_t seq; + char bname[40]; + uint64_t feature_compat; + uint64_t feature_ro_compat; + uint64_t feature_incompat; + uint64_t pages_offset; + uint64_t pages_total; + uint64_t set_header_offset; +}; int list_bdevs(struct list_head *head); -int detail_dev(char *devname, struct bdev *bd, struct cdev *cd, int *type); +int detail_dev(char *devname, struct bdev *bd, struct cdev *cd, struct mdev *md, int *type); int register_dev(char *devname); int stop_backdev(char *devname); int unregister_cset(char *cset); @@ -269,7 +269,7 @@ static void write_sb(char *dev, struct sb_context *sbc, bool bdev, bool force) int type = 1; int ret; - ret = detail_dev(dev, &bd, &cd, &type); + ret = detail_dev(dev, &bd, &cd, NULL, &type); if (ret != 0) exit(EXIT_FAILURE); if (type == BCACHE_SB_VERSION_BDEV) { @@ -148,43 +148,33 @@ int show_bdevs(void) return 0; } -int detail_single(char *devname) +int detail_single_dev(char *devname, struct bdev *bd, struct cdev *cd, int type) { - struct bdev bd; - struct cdev cd; - int type = 1; - int ret; - - ret = detail_dev(devname, &bd, &cd, &type); - if (ret != 0) { - fprintf(stderr, "Failed to detail device\n"); - return ret; - } if (type == BCACHE_SB_VERSION_BDEV || type == BCACHE_SB_VERSION_BDEV_WITH_OFFSET || type == BCACHE_SB_VERSION_BDEV_WITH_FEATURES) { - printf("sb.magic\t\t%s\n", bd.base.magic); + printf("sb.magic\t\t%s\n", bd->base.magic); printf("sb.first_sector\t\t%" PRIu64 "\n", - bd.base.first_sector); - printf("sb.csum\t\t\t%" PRIX64 "\n", bd.base.csum); - printf("sb.version\t\t%" PRIu64, bd.base.version); + bd->base.first_sector); + printf("sb.csum\t\t\t%" PRIX64 "\n", bd->base.csum); + printf("sb.version\t\t%" PRIu64, bd->base.version); printf(" [backing device]\n"); putchar('\n'); printf("dev.label\t\t"); - if (*bd.base.label) - print_encode(bd.base.label); + if (*bd->base.label) + print_encode(bd->base.label); else printf("(empty)"); putchar('\n'); - printf("dev.uuid\t\t%s\n", bd.base.uuid); + printf("dev.uuid\t\t%s\n", bd->base.uuid); printf("dev.sectors_per_block\t%u\n" "dev.sectors_per_bucket\t%u\n", - bd.base.sectors_per_block, - bd.base.sectors_per_bucket); + bd->base.sectors_per_block, + bd->base.sectors_per_bucket); printf("dev.data.first_sector\t%u\n" "dev.data.cache_mode\t%d", - bd.first_sector, bd.cache_mode); - switch (bd.cache_mode) { + bd->first_sector, bd->cache_mode); + switch (bd->cache_mode) { case CACHE_MODE_WRITETHROUGH: printf(" [writethrough]\n"); break; @@ -200,8 +190,8 @@ int detail_single(char *devname) default: putchar('\n'); } - printf("dev.data.cache_state\t%u", bd.cache_state); - switch (bd.cache_state) { + printf("dev.data.cache_state\t%u", bd->cache_state); + switch (bd->cache_state) { case BDEV_STATE_NONE: printf(" [detached]\n"); break; @@ -219,29 +209,29 @@ int detail_single(char *devname) } putchar('\n'); - printf("cset.uuid\t\t%s\n", bd.base.cset); + printf("cset.uuid\t\t%s\n", bd->base.cset); } else if (type == BCACHE_SB_VERSION_CDEV || type == BCACHE_SB_VERSION_CDEV_WITH_UUID || type == BCACHE_SB_VERSION_CDEV_WITH_FEATURES) { - printf("sb.magic\t\t%s\n", cd.base.magic); + printf("sb.magic\t\t%s\n", cd->base.magic); printf("sb.first_sector\t\t%" PRIu64 "\n", - cd.base.first_sector); - printf("sb.csum\t\t\t%" PRIX64 "\n", cd.base.csum); - printf("sb.version\t\t%" PRIu64, cd.base.version); + cd->base.first_sector); + printf("sb.csum\t\t\t%" PRIX64 "\n", cd->base.csum); + printf("sb.version\t\t%" PRIu64, cd->base.version); printf(" [cache device]\n"); - print_cache_set_supported_feature_sets(&cd.base.sb); + print_cache_set_supported_feature_sets(&cd->base.sb); putchar('\n'); printf("dev.label\t\t"); - if (*cd.base.label) - print_encode(cd.base.label); + if (*cd->base.label) + print_encode(cd->base.label); else printf("(empty)"); putchar('\n'); - printf("dev.uuid\t\t%s\n", cd.base.uuid); + printf("dev.uuid\t\t%s\n", cd->base.uuid); printf("dev.sectors_per_block\t%u\n" "dev.sectors_per_bucket\t%u\n", - cd.base.sectors_per_block, - cd.base.sectors_per_bucket); + cd->base.sectors_per_block, + cd->base.sectors_per_bucket); printf("dev.cache.first_sector\t%u\n" "dev.cache.cache_sectors\t%ju\n" "dev.cache.total_sectors\t%ju\n" @@ -249,12 +239,12 @@ int detail_single(char *devname) "dev.cache.discard\t%s\n" "dev.cache.pos\t\t%u\n" "dev.cache.replacement\t%d", - cd.first_sector, - cd.cache_sectors, - cd.total_sectors, - cd.ordered ? "yes" : "no", - cd.discard ? "yes" : "no", cd.pos, cd.replacement); - switch (cd.replacement) { + cd->first_sector, + cd->cache_sectors, + cd->total_sectors, + cd->ordered ? "yes" : "no", + cd->discard ? "yes" : "no", cd->pos, cd->replacement); + switch (cd->replacement) { case CACHE_REPLACEMENT_LRU: printf(" [lru]\n"); break; @@ -269,9 +259,73 @@ int detail_single(char *devname) } putchar('\n'); - printf("cset.uuid\t\t%s\n", cd.base.cset); + printf("cset.uuid\t\t%s\n", cd->base.cset); } else { return 1; } return 0; } + +int detail_single_mdev(char *devname, struct mdev *md) +{ + printf( "sb.csum\t\t\t%" PRIX64 "\n" + "sb.sb_offset\t\t0x%" PRIX64 "\n" + "sb.ns_start\t\t0x%" PRIX64 "\n" + "sb.version\t\t%" PRIu64 " [nvdimm-meta device]\n" + "sb.magic\t\t%s\n" + "sb.uuid\t\t\t%s\n" + "sb.page_size\t\t%u\n" + "sb.total_ns\t\t%u\n" + "sb.this_ns\t\t%u\n" + "sb.set_uuid\t\t%s\n" + "sb.flags\t\t%" PRIX64 "\n" + "sb.seq\t\t\t%" PRIX64 "\n" + "sb.feature_compat\t0x%" PRIX64 "\n" + "sb.feature_ro_compat\t0x%" PRIX64 "\n" + "sb.feature_incompat\t0x%" PRIX64 "\n" + "sb.pages_offset\t\t0x%" PRIX64 "\n" + "sb.pages_total\t\t%" PRIu64 "\n" + "sb.set_header_offset\t%" PRIu64 "\n", + md->csum, + md->sb_offset, + md->ns_start, + md->version, + md->magic, + md->uuid, + md->page_size, + md->total_ns, + md->this_ns, + md->set_uuid, + md->flags, + md->seq, + md->feature_compat, + md->feature_ro_compat, + md->feature_incompat, + md->pages_offset, + md->pages_total, + md->set_header_offset); + putchar('\n'); + + return 0; +} + +int detail_single(char *devname) +{ + struct bdev bd; + struct cdev cd; + struct mdev md; + int type = 0; + int ret = 0; + + ret = detail_dev(devname, &bd, &cd, &md, &type); + if (ret != 0) + goto out; + + if (type >= 0 && type <= BCACHE_SB_MAX_VERSION) + ret = detail_single_dev(devname, &bd, &cd, type); + else + ret = detail_single_mdev(devname, &md); + +out: + return ret; +} |