Blame SOURCES/libvirt-RHEL-virscsi-Check-device-type-before-getting-it-s-dev-node-name.patch

Pablo Greco 40546a
From 521a2285cfee3d2fdd59cb7a3270e9ef91bcc14f Mon Sep 17 00:00:00 2001
Pablo Greco 40546a
Message-Id: <521a2285cfee3d2fdd59cb7a3270e9ef91bcc14f@dist-git>
Pablo Greco 40546a
From: Michal Privoznik <mprivozn@redhat.com>
Pablo Greco 40546a
Date: Fri, 6 Mar 2020 15:51:44 +0100
Pablo Greco 40546a
Subject: [PATCH] RHEL: virscsi: Check device type before getting it's /dev
Pablo Greco 40546a
 node name
Pablo Greco 40546a
Pablo Greco 40546a
Not all SCSI devices are block devices, therefore
Pablo Greco 40546a
/sys/bus/scsi/devices/X:X:X:X/block/ directory does not always
Pablo Greco 40546a
exist. Check if the SCSI device is a block device beforehand.
Pablo Greco 40546a
Pablo Greco 40546a
https://bugzilla.redhat.com/show_bug.cgi?id=1808388
Pablo Greco 40546a
Pablo Greco 40546a
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Pablo Greco 40546a
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Pablo Greco 40546a
Message-Id: <20200306145149.1610286-2-abologna@redhat.com>
Pablo Greco 40546a
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Pablo Greco 40546a
---
Pablo Greco 40546a
 src/util/virscsi.c             | 149 ++++++++++++++++++++++++++++++---
Pablo Greco 40546a
 tests/virscsidata/0-0-0-0/type |   1 +
Pablo Greco 40546a
 tests/virscsidata/1-0-0-0/type |   1 +
Pablo Greco 40546a
 3 files changed, 138 insertions(+), 13 deletions(-)
Pablo Greco 40546a
 create mode 100644 tests/virscsidata/0-0-0-0/type
Pablo Greco 40546a
 create mode 100644 tests/virscsidata/1-0-0-0/type
Pablo Greco 40546a
Pablo Greco 40546a
diff --git a/src/util/virscsi.c b/src/util/virscsi.c
Pablo Greco 40546a
index b51103a86d..af908107d9 100644
Pablo Greco 40546a
--- a/src/util/virscsi.c
Pablo Greco 40546a
+++ b/src/util/virscsi.c
Pablo Greco 40546a
@@ -56,6 +56,32 @@ struct _virUsedByInfo {
Pablo Greco 40546a
 };
Pablo Greco 40546a
 typedef struct _virUsedByInfo *virUsedByInfoPtr;
Pablo Greco 40546a
 
Pablo Greco 40546a
+
Pablo Greco 40546a
+/* Keep in sync with scsi/scsi_proto.h */
Pablo Greco 40546a
+typedef enum {
Pablo Greco 40546a
+    VIR_SCSI_DEVICE_TYPE_NONE = -1,
Pablo Greco 40546a
+    VIR_SCSI_DEVICE_TYPE_DISK = 0x00,
Pablo Greco 40546a
+    VIR_SCSI_DEVICE_TYPE_TAPE = 0x01,
Pablo Greco 40546a
+    VIR_SCSI_DEVICE_TYPE_PRINTER = 0x02,
Pablo Greco 40546a
+    VIR_SCSI_DEVICE_TYPE_PROCESSOR = 0x03,
Pablo Greco 40546a
+    VIR_SCSI_DEVICE_TYPE_WORM = 0x04,
Pablo Greco 40546a
+    VIR_SCSI_DEVICE_TYPE_ROM = 0x05,
Pablo Greco 40546a
+    VIR_SCSI_DEVICE_TYPE_SCANNER = 0x06,
Pablo Greco 40546a
+    VIR_SCSI_DEVICE_TYPE_MOD = 0x07,
Pablo Greco 40546a
+    VIR_SCSI_DEVICE_TYPE_MEDIUM_CHANGER = 0x08,
Pablo Greco 40546a
+    VIR_SCSI_DEVICE_TYPE_COMM = 0x09,
Pablo Greco 40546a
+    VIR_SCSI_DEVICE_TYPE_RAID = 0x0c,
Pablo Greco 40546a
+    VIR_SCSI_DEVICE_TYPE_ENCLOSURE = 0x0d,
Pablo Greco 40546a
+    VIR_SCSI_DEVICE_TYPE_RBC = 0x0e,
Pablo Greco 40546a
+    VIR_SCSI_DEVICE_TYPE_OSD = 0x11,
Pablo Greco 40546a
+    VIR_SCSI_DEVICE_TYPE_ZBC = 0x14,
Pablo Greco 40546a
+    VIR_SCSI_DEVICE_TYPE_WLUN = 0x1e,
Pablo Greco 40546a
+    VIR_SCSI_DEVICE_TYPE_NO_LUN = 0x7f,
Pablo Greco 40546a
+
Pablo Greco 40546a
+    VIR_SCSI_DEVICE_TYPE_LAST,
Pablo Greco 40546a
+} virSCSIDeviceType;
Pablo Greco 40546a
+
Pablo Greco 40546a
+
Pablo Greco 40546a
 struct _virSCSIDevice {
Pablo Greco 40546a
     unsigned int adapter;
Pablo Greco 40546a
     unsigned int bus;
Pablo Greco 40546a
@@ -143,6 +169,86 @@ virSCSIDeviceGetSgName(const char *sysfs_prefix,
Pablo Greco 40546a
     return sg;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
+
Pablo Greco 40546a
+static int
Pablo Greco 40546a
+virSCSIDeviceGetType(const char *prefix,
Pablo Greco 40546a
+                     unsigned int adapter,
Pablo Greco 40546a
+                     unsigned int bus,
Pablo Greco 40546a
+                     unsigned int target,
Pablo Greco 40546a
+                     unsigned long long unit,
Pablo Greco 40546a
+                     virSCSIDeviceType *type)
Pablo Greco 40546a
+{
Pablo Greco 40546a
+    int intType;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (virFileReadValueInt(&intType,
Pablo Greco 40546a
+                            "%s/%d:%u:%u:%llu/type",
Pablo Greco 40546a
+                            prefix, adapter, bus, target, unit) < 0)
Pablo Greco 40546a
+        return -1;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    switch (intType) {
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_DISK:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_TAPE:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_PRINTER:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_PROCESSOR:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_WORM:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_ROM:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_SCANNER:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_MOD:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_MEDIUM_CHANGER:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_COMM:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_RAID:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_ENCLOSURE:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_RBC:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_OSD:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_ZBC:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_WLUN:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_NO_LUN:
Pablo Greco 40546a
+        *type = intType;
Pablo Greco 40546a
+        break;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    default:
Pablo Greco 40546a
+        virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
+                       _("unknown SCSI device type: %x"),
Pablo Greco 40546a
+                       intType);
Pablo Greco 40546a
+        return -1;
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+
Pablo Greco 40546a
+    return 0;
Pablo Greco 40546a
+}
Pablo Greco 40546a
+
Pablo Greco 40546a
+
Pablo Greco 40546a
+static char *
Pablo Greco 40546a
+virSCSIDeviceGetDevNameBlock(const char *prefix,
Pablo Greco 40546a
+                             unsigned int adapter,
Pablo Greco 40546a
+                             unsigned int bus,
Pablo Greco 40546a
+                             unsigned int target,
Pablo Greco 40546a
+                             unsigned long long unit)
Pablo Greco 40546a
+{
Pablo Greco 40546a
+    DIR *dir = NULL;
Pablo Greco 40546a
+    struct dirent *entry;
Pablo Greco 40546a
+    char *path = NULL;
Pablo Greco 40546a
+    char *name = NULL;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (virAsprintf(&path,
Pablo Greco 40546a
+                    "%s/%d:%u:%u:%llu/block",
Pablo Greco 40546a
+                    prefix, adapter, bus, target, unit) < 0)
Pablo Greco 40546a
+        return NULL;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (virDirOpen(&dir, path) < 0)
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    while (virDirRead(dir, &entry, path) > 0) {
Pablo Greco 40546a
+        ignore_value(VIR_STRDUP(name, entry->d_name));
Pablo Greco 40546a
+        break;
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+
Pablo Greco 40546a
+ cleanup:
Pablo Greco 40546a
+    VIR_DIR_CLOSE(dir);
Pablo Greco 40546a
+    VIR_FREE(path);
Pablo Greco 40546a
+    return name;
Pablo Greco 40546a
+}
Pablo Greco 40546a
+
Pablo Greco 40546a
+
Pablo Greco 40546a
 /* Returns device name (e.g. "sdc") on success, or NULL
Pablo Greco 40546a
  * on failure.
Pablo Greco 40546a
  */
Pablo Greco 40546a
@@ -153,35 +259,52 @@ virSCSIDeviceGetDevName(const char *sysfs_prefix,
Pablo Greco 40546a
                         unsigned int target,
Pablo Greco 40546a
                         unsigned long long unit)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    DIR *dir = NULL;
Pablo Greco 40546a
-    struct dirent *entry;
Pablo Greco 40546a
-    char *path = NULL;
Pablo Greco 40546a
     char *name = NULL;
Pablo Greco 40546a
     unsigned int adapter_id;
Pablo Greco 40546a
+    virSCSIDeviceType type;
Pablo Greco 40546a
     const char *prefix = sysfs_prefix ? sysfs_prefix : SYSFS_SCSI_DEVICES;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (virSCSIDeviceGetAdapterId(adapter, &adapter_id) < 0)
Pablo Greco 40546a
         return NULL;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (virAsprintf(&path,
Pablo Greco 40546a
-                    "%s/%d:%u:%u:%llu/block",
Pablo Greco 40546a
-                    prefix, adapter_id, bus, target, unit) < 0)
Pablo Greco 40546a
+    if (virSCSIDeviceGetType(prefix, adapter_id,
Pablo Greco 40546a
+                             bus, target, unit, &type) < 0)
Pablo Greco 40546a
         return NULL;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (virDirOpen(&dir, path) < 0)
Pablo Greco 40546a
-        goto cleanup;
Pablo Greco 40546a
+    switch (type) {
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_DISK:
Pablo Greco 40546a
+        name = virSCSIDeviceGetDevNameBlock(prefix, adapter_id, bus, target, unit);
Pablo Greco 40546a
+        break;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    while (virDirRead(dir, &entry, path) > 0) {
Pablo Greco 40546a
-        ignore_value(VIR_STRDUP(name, entry->d_name));
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_TAPE:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_PRINTER:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_PROCESSOR:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_WORM:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_ROM:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_SCANNER:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_MOD:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_MEDIUM_CHANGER:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_COMM:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_RAID:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_ENCLOSURE:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_RBC:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_OSD:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_ZBC:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_WLUN:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_NO_LUN:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_NONE:
Pablo Greco 40546a
+    case VIR_SCSI_DEVICE_TYPE_LAST:
Pablo Greco 40546a
+    default:
Pablo Greco 40546a
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
Pablo Greco 40546a
+                       _("unsupported SCSI device type: %x"),
Pablo Greco 40546a
+                       type);
Pablo Greco 40546a
         break;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
- cleanup:
Pablo Greco 40546a
-    VIR_DIR_CLOSE(dir);
Pablo Greco 40546a
-    VIR_FREE(path);
Pablo Greco 40546a
     return name;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
+
Pablo Greco 40546a
 virSCSIDevicePtr
Pablo Greco 40546a
 virSCSIDeviceNew(const char *sysfs_prefix,
Pablo Greco 40546a
                  const char *adapter,
Pablo Greco 40546a
diff --git a/tests/virscsidata/0-0-0-0/type b/tests/virscsidata/0-0-0-0/type
Pablo Greco 40546a
new file mode 100644
Pablo Greco 40546a
index 0000000000..573541ac97
Pablo Greco 40546a
--- /dev/null
Pablo Greco 40546a
+++ b/tests/virscsidata/0-0-0-0/type
Pablo Greco 40546a
@@ -0,0 +1 @@
Pablo Greco 40546a
+0
Pablo Greco 40546a
diff --git a/tests/virscsidata/1-0-0-0/type b/tests/virscsidata/1-0-0-0/type
Pablo Greco 40546a
new file mode 100644
Pablo Greco 40546a
index 0000000000..573541ac97
Pablo Greco 40546a
--- /dev/null
Pablo Greco 40546a
+++ b/tests/virscsidata/1-0-0-0/type
Pablo Greco 40546a
@@ -0,0 +1 @@
Pablo Greco 40546a
+0
Pablo Greco 40546a
-- 
Pablo Greco 40546a
2.25.1
Pablo Greco 40546a