Open yodayox opened 10 months ago
think that https://github.com/eudev-project/eudev/pull/272 is incomplete because some( i mean a lot) nvme devices can belong to nvme-subsystem! see >>https://github.com/Werkov/systemd/commit/cef726986b7117dec3e827a3c5c09d2bbdc4692a 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_; \ + })
think that https://github.com/eudev-project/eudev/pull/272 is incomplete because some( i mean a lot) nvme devices can belong to nvme-subsystem! see >>https://github.com/Werkov/systemd/commit/cef726986b7117dec3e827a3c5c09d2bbdc4692a the right patch could be, like i said in the past, the following one: