[PATCH 0/2] node_device: Treat NVMe disks as regular disks

Apparently udev doesn't think that NVMe disk is really a disk because it doesn't set ID_TYPE attribute to "disk" (it doesn't set the attribute at all). But it does set DEVTYPE=disk so with a little bit of work we can report NVMe disks as devices with VIR_NODE_DEV_CAP_STORAGE capability. Michal Prívozník (2): node_device: Rework udevKludgeStorageType() node_device: Treat NVMe disks as regular disks src/node_device/node_device_udev.c | 43 ++++++++++++++++-------------- 1 file changed, 23 insertions(+), 20 deletions(-) -- 2.34.1

The udevKludgeStorageType() function looks at devlink name (/dev/XXX) and guesses the type of the (storage) device using a series of STRPREFIX() calls. Well those can be turn into an array and a for() loop, especially if we are about to add a new case (in the next commit). Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/node_device/node_device_udev.c | 40 +++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index cd1722f934..14acb3fee0 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -890,32 +890,32 @@ udevProcessDASD(struct udev_device *device, static int udevKludgeStorageType(virNodeDeviceDef *def) { + size_t i; + const char *fixups[][2] = { + /* virtio disk */ + { "/dev/vd", "disk" }, + + /* For Direct Access Storage Devices (DASDs) there are + * currently no identifiers in udev besides ID_PATH. Since + * ID_TYPE=disk does not exist on DASDs they fall through + * the udevProcessStorage detection logic. */ + { "/dev/dasd", "dasd" }, + }; + VIR_DEBUG("Could not find definitive storage type for device " "with sysfs path '%s', trying to guess it", def->sysfs_path); - /* virtio disk */ - if (STRPREFIX(def->caps->data.storage.block, "/dev/vd")) { - def->caps->data.storage.drive_type = g_strdup("disk"); - VIR_DEBUG("Found storage type '%s' for device " - "with sysfs path '%s'", - def->caps->data.storage.drive_type, - def->sysfs_path); - return 0; + for (i = 0; i < G_N_ELEMENTS(fixups); i++) { + if (STRPREFIX(def->caps->data.storage.block, fixups[i][0])) { + def->caps->data.storage.drive_type = g_strdup(fixups[i][1]); + VIR_DEBUG("Found storage type '%s' for device with sysfs path '%s'", + def->caps->data.storage.drive_type, + def->sysfs_path); + return 0; + } } - /* For Direct Access Storage Devices (DASDs) there are - * currently no identifiers in udev besides ID_PATH. Since - * ID_TYPE=disk does not exist on DASDs they fall through - * the udevProcessStorage detection logic. */ - if (STRPREFIX(def->caps->data.storage.block, "/dev/dasd")) { - def->caps->data.storage.drive_type = g_strdup("dasd"); - VIR_DEBUG("Found storage type '%s' for device " - "with sysfs path '%s'", - def->caps->data.storage.drive_type, - def->sysfs_path); - return 0; - } VIR_DEBUG("Could not determine storage type " "for device with sysfs path '%s'", def->sysfs_path); return -1; -- 2.34.1

On Wed, Jan 26, 2022 at 14:13:20 +0100, Michal Privoznik wrote:
The udevKludgeStorageType() function looks at devlink name (/dev/XXX) and guesses the type of the (storage) device using a series of STRPREFIX() calls. Well those can be turn into an array and a for() loop, especially if we are about to add a new case (in the next commit).
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/node_device/node_device_udev.c | 40 +++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index cd1722f934..14acb3fee0 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -890,32 +890,32 @@ udevProcessDASD(struct udev_device *device, static int udevKludgeStorageType(virNodeDeviceDef *def) { + size_t i; + const char *fixups[][2] = { + /* virtio disk */ + { "/dev/vd", "disk" }, + + /* For Direct Access Storage Devices (DASDs) there are + * currently no identifiers in udev besides ID_PATH. Since + * ID_TYPE=disk does not exist on DASDs they fall through + * the udevProcessStorage detection logic. */ + { "/dev/dasd", "dasd" }, + };
I'd probably slightly prefer if this was an array of structs where the fields are named ...
+ VIR_DEBUG("Could not find definitive storage type for device " "with sysfs path '%s', trying to guess it", def->sysfs_path);
- /* virtio disk */ - if (STRPREFIX(def->caps->data.storage.block, "/dev/vd")) { - def->caps->data.storage.drive_type = g_strdup("disk"); - VIR_DEBUG("Found storage type '%s' for device " - "with sysfs path '%s'", - def->caps->data.storage.drive_type, - def->sysfs_path); - return 0; + for (i = 0; i < G_N_ELEMENTS(fixups); i++) { + if (STRPREFIX(def->caps->data.storage.block, fixups[i][0])) { + def->caps->data.storage.drive_type = g_strdup(fixups[i][1]);
So that's a bit more obvious which field here is used in a particular situation. Granted this is just a single function. Reviewed-by: Peter Krempa <pkrempa@redhat.com>

Unfortunately, udev doesn't set ID_TYPE attribute for NVMe disks, therefore we have to add another case into udevKludgeStorageType() to treat /dev/nvme* devlinks as any other disk. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2045953 Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/node_device/node_device_udev.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index 14acb3fee0..27efda1ab0 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -900,6 +900,9 @@ udevKludgeStorageType(virNodeDeviceDef *def) * ID_TYPE=disk does not exist on DASDs they fall through * the udevProcessStorage detection logic. */ { "/dev/dasd", "dasd" }, + + /* NVMe disk */ + { "/dev/nvme", "disk" }, }; VIR_DEBUG("Could not find definitive storage type for device " -- 2.34.1

On Wed, Jan 26, 2022 at 14:13:21 +0100, Michal Privoznik wrote:
Unfortunately, udev doesn't set ID_TYPE attribute for NVMe disks, therefore we have to add another case into udevKludgeStorageType() to treat /dev/nvme* devlinks as any other disk.
I had to do a bit digging because /dev/nvme0 a controller and not a storage device, but it turns out the function below is called only for the namespace portion which is a storage device and not even the partition portion, so the code itself is good.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2045953 Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/node_device/node_device_udev.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index 14acb3fee0..27efda1ab0 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -900,6 +900,9 @@ udevKludgeStorageType(virNodeDeviceDef *def) * ID_TYPE=disk does not exist on DASDs they fall through * the udevProcessStorage detection logic. */ { "/dev/dasd", "dasd" }, + + /* NVMe disk */
e.g. for example note here that this is called for /dev/nvme0n1 and alike only so doing a prefix match is okay.
+ { "/dev/nvme", "disk" }, };
VIR_DEBUG("Could not find definitive storage type for device "
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
participants (2)
-
Michal Privoznik
-
Peter Krempa