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

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