mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-22 13:33:56 +03:00
udev: support by-path devlink for multipath nvme block devices
If multipath feature is enabled, nvme block devices may belong to the "nvme-subsystem" subsystem, instead of "nvme" subsystem. (What a confusing name...) Then, the syspath is something like the following, /sys/devices/virtual/nvme-subsystem/nvme-subsys0/nvme0n1 Hence, we need to find the 'real parent' device, such as /sys/devices/pci0000:00/0000:00:1c.4/0000:3c:00.0/nvme/nvme0 Fixes https://bugzilla.redhat.com/show_bug.cgi?id=2031810. Fixes https://bugzilla.redhat.com/show_bug.cgi?id=2124964. Replaces #24748. (cherry picked from commit67c3e1f63a
) (cherry picked from commit3137ac6ef5
)
This commit is contained in:
parent
3f074e438a
commit
d24b858687
@ -88,6 +88,7 @@ KERNEL=="msblk[0-9]p[0-9]|mspblk[0-9]p[0-9]", ENV{ID_NAME}=="?*", ENV{ID_SERIAL}
|
|||||||
|
|
||||||
# by-path
|
# by-path
|
||||||
ENV{DEVTYPE}=="disk", DEVPATH!="*/virtual/*", IMPORT{builtin}="path_id"
|
ENV{DEVTYPE}=="disk", DEVPATH!="*/virtual/*", IMPORT{builtin}="path_id"
|
||||||
|
ENV{DEVTYPE}=="disk", SUBSYSTEMS=="nvme-subsystem", IMPORT{builtin}="path_id"
|
||||||
KERNEL=="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-boot%n"
|
KERNEL=="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-boot%n"
|
||||||
KERNEL!="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}"
|
KERNEL!="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}"
|
||||||
ENV{DEVTYPE}=="partition", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n"
|
ENV{DEVTYPE}=="partition", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n"
|
||||||
|
@ -543,19 +543,55 @@ static sd_device *handle_ap(sd_device *parent, char **path) {
|
|||||||
return skip_subsystem(parent, "ap");
|
return skip_subsystem(parent, "ap");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int find_real_nvme_parent(sd_device *dev, sd_device **ret) {
|
||||||
|
_cleanup_(sd_device_unrefp) sd_device *nvme = NULL;
|
||||||
|
const char *sysname, *end;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
/* 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(nvme);
|
||||||
|
|
||||||
|
r = sd_device_get_sysname(dev, &sysname);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
/* 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, DIGITS);
|
||||||
|
sysname = strndupa(sysname, end - sysname);
|
||||||
|
|
||||||
|
r = sd_device_new_from_subsystem_sysname(&nvme, "nvme", sysname);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
*ret = TAKE_PTR(nvme);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int builtin_path_id(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
static int builtin_path_id(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
|
||||||
sd_device *parent;
|
_cleanup_(sd_device_unrefp) sd_device *dev_other_branch = NULL;
|
||||||
_cleanup_free_ char *path = NULL;
|
_cleanup_free_ char *path = NULL, *compat_path = NULL;
|
||||||
_cleanup_free_ char *compat_path = NULL;
|
bool supported_transport = false, supported_parent = false;
|
||||||
bool supported_transport = false;
|
|
||||||
bool supported_parent = false;
|
|
||||||
const char *subsystem;
|
const char *subsystem;
|
||||||
|
int r;
|
||||||
|
|
||||||
assert(dev);
|
assert(dev);
|
||||||
|
|
||||||
/* walk up the chain of devices and compose path */
|
/* walk up the chain of devices and compose path */
|
||||||
parent = dev;
|
for (sd_device *parent = dev; parent; ) {
|
||||||
while (parent) {
|
|
||||||
const char *subsys, *sysname;
|
const char *subsys, *sysname;
|
||||||
|
|
||||||
if (sd_device_get_subsystem(parent, &subsys) < 0 ||
|
if (sd_device_get_subsystem(parent, &subsys) < 0 ||
|
||||||
@ -642,13 +678,22 @@ static int builtin_path_id(sd_device *dev, sd_netlink **rtnl, int argc, char *ar
|
|||||||
parent = skip_subsystem(parent, "iucv");
|
parent = skip_subsystem(parent, "iucv");
|
||||||
supported_transport = true;
|
supported_transport = true;
|
||||||
supported_parent = true;
|
supported_parent = true;
|
||||||
} else if (streq(subsys, "nvme")) {
|
} else if (STR_IN_SET(subsys, "nvme", "nvme-subsystem")) {
|
||||||
const char *nsid;
|
const char *nsid;
|
||||||
|
|
||||||
if (sd_device_get_sysattr_value(dev, "nsid", &nsid) >= 0) {
|
if (sd_device_get_sysattr_value(dev, "nsid", &nsid) >= 0) {
|
||||||
path_prepend(&path, "nvme-%s", nsid);
|
path_prepend(&path, "nvme-%s", nsid);
|
||||||
if (compat_path)
|
if (compat_path)
|
||||||
path_prepend(&compat_path, "nvme-%s", nsid);
|
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");
|
parent = skip_subsystem(parent, "nvme");
|
||||||
supported_parent = true;
|
supported_parent = true;
|
||||||
supported_transport = true;
|
supported_transport = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user