aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColy Li <colyli@suse.de>2021-07-27 00:06:24 +0800
committerColy Li <colyli@suse.de>2021-10-25 16:39:25 +0800
commit492ef7a3b1a131f8a5d52ebf17d79f10fb85608e (patch)
tree2eb191173bffa2c8cf1a0214d86ce2cd541cb8d0
parent4a8af34ed26cb72dcaac0dd4953c6c99094284d4 (diff)
downloadbcache-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.c10
-rw-r--r--lib.c65
-rw-r--r--lib.h27
-rw-r--r--make.c2
-rw-r--r--show.c138
5 files changed, 192 insertions, 50 deletions
diff --git a/bcache.c b/bcache.c
index 3c26d31c..aa2a0783 100644
--- a/bcache.c
+++ b/bcache.c
@@ -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");
diff --git a/lib.c b/lib.c
index adad823d..1742cb7c 100644
--- a/lib.c
+++ b/lib.c
@@ -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:
diff --git a/lib.h b/lib.h
index 4c8df97e..9397b7d5 100644
--- a/lib.h
+++ b/lib.h
@@ -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);
diff --git a/make.c b/make.c
index f2cf18a7..48b1a9a1 100644
--- a/make.c
+++ b/make.c
@@ -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) {
diff --git a/show.c b/show.c
index ff498623..f1fe170c 100644
--- a/show.c
+++ b/show.c
@@ -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;
+}