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