From 6f5e3575e6d250ac58b3aa4383bfc493723cc601 Mon Sep 17 00:00:00 2001 From: Minwoo Im Date: Thu, 23 Mar 2023 07:59:03 +0900 Subject: [PATCH] tree: fix generic device open failure If scan_namespace is called with a generic device (e.g., /dev/ng0n1) given, it fails to scan a namespace based on the generic device because there's no entry point in /sys/block/ for the generic device. This patch provides two helpers to change the given generic device name to a block device name based on the instances: ng0n1 -> nvme0n1 This patch fixes command failure: root@vm:~/work/nvme-cli.git# nvme show-regs /dev/ng0n1 Unable to find ng0n1 get-property: Invalid argument Signed-off-by: Minwoo Im [dwagner: also catch blkdev allocation failures] Signed-off-by: Daniel Wagner --- src/nvme/tree.c | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 83e35c48..34844634 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1864,27 +1864,62 @@ free_ns: return NULL; } +static inline bool nvme_ns_is_generic(const char *name) +{ + int instance, head_instance; + + if (sscanf(name, "ng%dn%d", &instance, &head_instance) != 2) + return false; + return true; +} + +static char *nvme_ns_generic_to_blkdev(const char *generic) +{ + + int instance, head_instance; + char blkdev[PATH_MAX]; + + if (!nvme_ns_is_generic(generic)) + return strdup(generic); + + sscanf(generic, "ng%dn%d", &instance, &head_instance); + sprintf(blkdev, "nvme%dn%d", instance, head_instance); + + return strdup(blkdev); +} + static struct nvme_ns *__nvme_scan_namespace(const char *sysfs_dir, const char *name) { struct nvme_ns *n; char *path; int ret; + char *blkdev; - ret = asprintf(&path, "%s/%s", sysfs_dir, name); - if (ret < 0) { + blkdev = nvme_ns_generic_to_blkdev(name); + if (!blkdev) { errno = ENOMEM; return NULL; } - n = nvme_ns_open(name); + ret = asprintf(&path, "%s/%s", sysfs_dir, blkdev); + if (ret < 0) { + errno = ENOMEM; + goto free_blkdev; + } + + n = nvme_ns_open(blkdev); if (!n) goto free_path; n->sysfs_dir = path; + + free(blkdev); return n; free_path: free(path); +free_blkdev: + free(blkdev); return NULL; } -- 2.50.1