zed: Look for NVMe DEVPATH if no ID_BUS

We tried replacing an NVMe drive using autoreplace, only
to see zed reject it with:

zed[27955]: zed_udev_monitor: /dev/nvme5n1 no devid source

This happened because ZED saw that ID_BUS was not set by udev
for the NVMe drive, and thus didn't think it was "real drive".
This commit allows NVMe drives to be autoreplaced even if
ID_BUS is not set.

Reviewed-by: Don Brady <don.brady@intel.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tony Hutter <hutter2@llnl.gov>
Closes #13512 
Closes #13646
This commit is contained in:
Tony Hutter 2022-07-14 10:19:37 -07:00 committed by GitHub
parent 1d3ba0bf01
commit 9fe2f262aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 11 additions and 2 deletions

View File

@ -169,7 +169,7 @@ zed_udev_monitor(void *arg)
while (1) { while (1) {
struct udev_device *dev; struct udev_device *dev;
const char *action, *type, *part, *sectors; const char *action, *type, *part, *sectors;
const char *bus, *uuid; const char *bus, *uuid, *devpath;
const char *class, *subclass; const char *class, *subclass;
nvlist_t *nvl; nvlist_t *nvl;
boolean_t is_zfs = B_FALSE; boolean_t is_zfs = B_FALSE;
@ -263,10 +263,19 @@ zed_udev_monitor(void *arg)
* device id string is required in the message schema * device id string is required in the message schema
* for matching with vdevs. Preflight here for expected * for matching with vdevs. Preflight here for expected
* udev information. * udev information.
*
* Special case:
* NVMe devices don't have ID_BUS set (at least on RHEL 7-8),
* but they are valid for autoreplace. Add a special case for
* them by searching for "/nvme/" in the udev DEVPATH:
*
* DEVPATH=/devices/pci0000:00/0000:00:1e.0/nvme/nvme2/nvme2n1
*/ */
bus = udev_device_get_property_value(dev, "ID_BUS"); bus = udev_device_get_property_value(dev, "ID_BUS");
uuid = udev_device_get_property_value(dev, "DM_UUID"); uuid = udev_device_get_property_value(dev, "DM_UUID");
if (!is_zfs && (bus == NULL && uuid == NULL)) { devpath = udev_device_get_devpath(dev);
if (!is_zfs && (bus == NULL && uuid == NULL &&
strstr(devpath, "/nvme/") == NULL)) {
zed_log_msg(LOG_INFO, "zed_udev_monitor: %s no devid " zed_log_msg(LOG_INFO, "zed_udev_monitor: %s no devid "
"source", udev_device_get_devnode(dev)); "source", udev_device_get_devnode(dev));
udev_device_unref(dev); udev_device_unref(dev);