Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nvme issue #273

Open
yodayox opened this issue Jan 10, 2024 · 0 comments
Open

nvme issue #273

yodayox opened this issue Jan 10, 2024 · 0 comments

Comments

@yodayox
Copy link

yodayox commented Jan 10, 2024

think that #272 is incomplete because some( i mean a lot) nvme devices can belong to nvme-subsystem! see >>Werkov/systemd@cef7269
the right patch could be, like i said in the past, the following one:

--- a/src/udev/udev-builtin-path_id.c	2022-11-27 20:07:00.000000000 +0200
+++ b/src/udev/udev-builtin-path_id.c	2022-11-28 08:49:17.518446117 +0200
@@ -614,12 +614,51 @@
         return parent;
 }
 
+static int find_real_nvme_parent(struct udev_device *dev, struct udev_device **ret) {
+        _cleanup_free_ struct udev_device *nvme = NULL;
+        const char *sysname, *end;
+        struct udev *udev = udev_device_get_udev(dev);
+
+        /* If the device belongs to "nvme-subsystem" (not to be confused with "nvme"), which happens when
+         * NVMe multipathing is enabled in the kernel (/sys/module/nvme_core/parameters/multipath is Y),
+         * then the syspath is something like the following:
+         *   /sys/devices/virtual/nvme-subsystem/nvme-subsys0/nvme0n1
+         * Hence, we need to find the 'real parent' in "nvme" subsystem, e.g,
+         *   /sys/devices/pci0000:00/0000:00:1c.4/0000:3c:00.0/nvme/nvme0 */
+
+        assert(dev);
+        assert(ret);
+
+        sysname = udev_device_get_sysname(dev);
+        if (sysname  ==  NULL)
+                return -1;
+
+        /* The sysname format of nvme block device is nvme%d[c%d]n%d[p%d], e.g. nvme0n1p2 or nvme0c1n2.
+         * (Note, nvme device with 'c' can be ignored, as they are hidden. )
+         * The sysname format of nvme subsystem device is nvme%d.
+         * See nvme_alloc_ns() and nvme_init_ctrl() in drivers/nvme/host/core.c for more details. */
+        end = startswith(sysname, "nvme");
+        if (!end)
+                return -ENXIO;
+
+        end += strspn(end, "0123456789");
+        sysname = strndupa(sysname, end - sysname);
+
+        nvme = udev_device_new_from_subsystem_sysname(udev, "nvme", sysname);
+        if (nvme == NULL)
+                return -1;
+
+        *ret = TAKE_PTR(nvme);
+        return 0;
+}
+
 static int builtin_path_id(struct udev_device *dev, int argc __attribute__((unused)), char *argv[] __attribute__((unused)), bool test) {
         struct udev_device *parent;
         char *path = NULL;
         bool supported_transport = false;
         bool supported_parent = false;
         char *compat_path = NULL;
+        _cleanup_free_ struct udev_device *dev_other_branch = NULL;
         
         /* S390 ccw bus */
         parent = udev_device_get_parent_with_subsystem_devtype(dev, "ccw", NULL);
@@ -685,6 +724,36 @@
                         parent = skip_subsystem(parent, "scm");
                         supported_transport = true;
                         supported_parent = true;
+                } else if (streq(subsys, "nvme") || streq(subsys, "nvme-subsystem")) {
+                        const char *nsid;
+                        int r;
+                        
+                        nsid = udev_device_get_sysattr_value(dev, "nsid");
+                        if (nsid != NULL) {
+                                path_prepend(&path, "nvme-%s", nsid);
+                                if (compat_path)
+                                        path_prepend(&compat_path, "nvme-%s", nsid);
+
+                                if (streq(subsys, "nvme-subsystem")) {
+                                        r = find_real_nvme_parent(dev, &dev_other_branch);
+                                        if (r < 0)
+                                                return r;
+
+                                        parent = dev_other_branch;
+                                }
+
+                                parent = skip_subsystem(parent, "nvme");
+                                supported_parent = true;
+                                supported_transport = true;
+                        }
+                } else if (streq(subsys, "spi")) {
+                        const char *sysnum;
+                        
+                        sysnum = udev_device_get_sysname(parent);
+                        if (sysnum !=NULL) {
+                                path_prepend(&path, "cs-%s", sysnum);
+                                parent = skip_subsystem(parent, "spi");
+                        }
                 }
 
                 parent = udev_device_get_parent(parent);

--- a/src/udev/udev.h	2022-06-14 02:44:42.000000000 +0300
+++ b/src/udev/udev.h	2022-11-28 11:51:02.744444816 +0200
@@ -212,3 +212,11 @@
 extern const struct udevadm_cmd udevadm_hwdb;
 extern const struct udevadm_cmd udevadm_test;
 extern const struct udevadm_cmd udevadm_test_builtin;
+
+#define TAKE_PTR(ptr)                           \
+        ({                                      \
+                typeof(ptr) *_pptr_ = &(ptr);   \
+                typeof(ptr) _ptr_ = *_pptr_;    \
+                *_pptr_ = NULL;                 \
+                _ptr_;                          \
+        })
@yodayox yodayox mentioned this issue Mar 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant