How to look up an ns cdev from block maj:min?

Sagi Grimberg sagi at grimberg.me
Wed Feb 15 00:41:08 PST 2023


> Hi,
> Is there an official way for userspace to look up an ns cdev from a
> block maj:min?
> 
> For example, how should a userspace program determine that /dev/ng0n1 is
> the corresponding ns cdev when given just the block device node
> /dev/nvme0n1?
> 
> Parsing the filename is an obvious option but it makes assumptions about
> the naming convention of both the block device node and the character
> device node.
> 
> Is there a better way via sysfs? (I couldn't find it.)

Not that I can see... It follows the same rules as the
normal namespace, which means that it takes the subsystem or ctrl
instance number (depending if multipathing is enabled) and it will have
the same namespace instance number.

In other words, every namespace nvmeXnY will present an 'nvme generic'
chardev in the form of ngXnY.

Looks like nvme-cli is missing the generic representation in the json
output as well. Perhaps that is the best tool to use (once fixed with
the json output with the below):

--
diff --git a/nvme-print-json.c b/nvme-print-json.c
index df5616e88119..489e9e15c3b5 100644
--- a/nvme-print-json.c
+++ b/nvme-print-json.c
@@ -2507,6 +2507,7 @@ static void json_detail_list(nvme_root_t r)
                                         uint64_t nuse = 
nvme_ns_get_lba_util(n) * lba;

 
json_object_add_value_string(jns, "NameSpace", nvme_ns_get_name(n));
+ 
json_object_add_value_string(jns, "Generic", nvme_ns_get_generic_name(n));
                                         json_object_add_value_int(jns, 
"NSID", nvme_ns_get_nsid(n));
 
json_object_add_value_uint64(jns, "UsedBytes", nuse);
 
json_object_add_value_uint64(jns, "MaximumLBA", nvme_ns_get_lba_count(n));
@@ -2565,15 +2566,18 @@ static struct json_object 
*json_list_item(nvme_ns_t n)
  {
         struct json_object *jdevice = json_create_object();
         char devname[128] = { 0 };
+       char genname[128] = { 0 };

         int lba = nvme_ns_get_lba_size(n);
         uint64_t nsze = nvme_ns_get_lba_count(n) * lba;
         uint64_t nuse = nvme_ns_get_lba_util(n) * lba;

         nvme_dev_full_path(n, devname, sizeof(devname));
+       nvme_generic_full_path(n, genname, sizeof(genname));

         json_object_add_value_int(jdevice, "NameSpace", 
nvme_ns_get_nsid(n));
         json_object_add_value_string(jdevice, "DevicePath", devname);
+       json_object_add_value_string(jdevice, "GenericPath", genname);
         json_object_add_value_string(jdevice, "Firmware", 
nvme_ns_get_firmware(n));
         json_object_add_value_string(jdevice, "ModelNumber", 
nvme_ns_get_model(n));
         json_object_add_value_string(jdevice, "SerialNumber", 
nvme_ns_get_serial(n));
diff --git a/nvme-print.c b/nvme-print.c
index fee9aabfc176..ec98fe304c4b 100644
--- a/nvme-print.c
+++ b/nvme-print.c
@@ -5108,7 +5108,7 @@ void nvme_dev_full_path(nvme_ns_t n, char *path, 
size_t len)
         snprintf(path, len, "%s", nvme_ns_get_name(n));
  }

-static void nvme_generic_full_path(nvme_ns_t n, char *path, size_t len)
+void nvme_generic_full_path(nvme_ns_t n, char *path, size_t len)
  {
         int head_instance;
         int instance;
diff --git a/nvme-print.h b/nvme-print.h
index ab11774daa28..7a4ceeea5131 100644
--- a/nvme-print.h
+++ b/nvme-print.h
@@ -149,6 +149,7 @@ const char *nvme_feature_to_string(enum 
nvme_features_id feature);
  const char *nvme_register_to_string(int reg);

  void nvme_dev_full_path(nvme_ns_t n, char *path, size_t len);
+void nvme_generic_full_path(nvme_ns_t n, char *path, size_t len);
  char *zone_type_to_string(__u8 cond);
  char *zone_state_to_string(__u8 state);
  const char *nvme_pel_event_to_string(int type);
--




More information about the Linux-nvme mailing list