summaryrefslogtreecommitdiff
path: root/libvirt-RHEL-virscsi-Introduce-and-use-virSCSIDeviceGetUnprivSGIOSysfsPath.patch
diff options
context:
space:
mode:
Diffstat (limited to 'libvirt-RHEL-virscsi-Introduce-and-use-virSCSIDeviceGetUnprivSGIOSysfsPath.patch')
-rw-r--r--libvirt-RHEL-virscsi-Introduce-and-use-virSCSIDeviceGetUnprivSGIOSysfsPath.patch272
1 files changed, 272 insertions, 0 deletions
diff --git a/libvirt-RHEL-virscsi-Introduce-and-use-virSCSIDeviceGetUnprivSGIOSysfsPath.patch b/libvirt-RHEL-virscsi-Introduce-and-use-virSCSIDeviceGetUnprivSGIOSysfsPath.patch
new file mode 100644
index 0000000..82614be
--- /dev/null
+++ b/libvirt-RHEL-virscsi-Introduce-and-use-virSCSIDeviceGetUnprivSGIOSysfsPath.patch
@@ -0,0 +1,272 @@
+From 118b5968602be2a40305dc2cc638f5b1aa442c94 Mon Sep 17 00:00:00 2001
+Message-Id: <118b5968602be2a40305dc2cc638f5b1aa442c94@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Fri, 6 Mar 2020 15:52:23 +0100
+Subject: [PATCH] RHEL: virscsi: Introduce and use
+ virSCSIDeviceGetUnprivSGIOSysfsPath()
+
+When constructing a path to the 'unpriv_sgio' file of given SCSI
+device we don't need to go through /dev/* and major() + minor()
+path. The generated path points to
+/sys/dev/block/MAJ:MIN/queue/unpriv_sgio which is wrong if the
+SCSI device in question is not a block device. We can generate a
+different path: /sys/bus/scsi/devices/X:X:X:X/unpriv_sgio where
+the file is directly accessible regardless of the SCSI device
+type.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1808390
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Signed-off-by: Andrea Bolognani <abologna@redhat.com>
+Message-Id: <20200306145226.1610708-4-abologna@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/libvirt_private.syms | 1 +
+ src/qemu/qemu_conf.c | 31 +++++++++++++++++++------------
+ src/util/virscsi.c | 19 +++++++++++++++++++
+ src/util/virscsi.h | 5 +++++
+ src/util/virutil.c | 24 ++++++------------------
+ src/util/virutil.h | 2 --
+ 6 files changed, 50 insertions(+), 32 deletions(-)
+
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index 55ae7d5b6f..1c7f776043 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -3194,6 +3194,7 @@ virSCSIDeviceGetSgName;
+ virSCSIDeviceGetShareable;
+ virSCSIDeviceGetTarget;
+ virSCSIDeviceGetUnit;
++virSCSIDeviceGetUnprivSGIOSysfsPath;
+ virSCSIDeviceIsAvailable;
+ virSCSIDeviceListAdd;
+ virSCSIDeviceListCount;
+diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
+index 12afed8aa2..e8b6ddafa1 100644
+--- a/src/qemu/qemu_conf.c
++++ b/src/qemu/qemu_conf.c
+@@ -1500,7 +1500,7 @@ qemuCheckUnprivSGIO(GHashTable *sharedDevices,
+ if (!(virHashLookup(sharedDevices, key)))
+ return 0;
+
+- if (virGetDeviceUnprivSGIO(device_path, NULL, &val) < 0)
++ if (virGetDeviceUnprivSGIO(sysfs_path, &val) < 0)
+ return -1;
+
+ /* Error message on failure needs to be handled in caller
+@@ -1852,39 +1852,46 @@ qemuSetUnprivSGIO(virDomainDeviceDef *dev)
+ virDomainDiskDef *disk = NULL;
+ virDomainHostdevDef *hostdev = NULL;
+ g_autofree char *sysfs_path = NULL;
+- g_autofree char *hostdev_path = NULL;
+- const char *path = NULL;
+ int val = 0;
+
+ /* "sgio" is only valid for block disk; cdrom
+ * and floopy disk can have empty source.
+ */
+ if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
++ const char *path;
++
+ disk = dev->data.disk;
++ path = virDomainDiskGetSource(disk);
+
+ if (disk->device != VIR_DOMAIN_DISK_DEVICE_LUN ||
+ !virStorageSourceIsBlockLocal(disk->src))
+ return 0;
+
+- path = virDomainDiskGetSource(disk);
++ if (!(sysfs_path = virGetUnprivSGIOSysfsPath(path, NULL)))
++ return -1;
++
+ } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
++ virDomainHostdevSubsysSCSI *scsisrc;
++ virDomainHostdevSubsysSCSIHost *scsihostsrc;
++
+ hostdev = dev->data.hostdev;
++ scsisrc = &hostdev->source.subsys.u.scsi;
++ scsihostsrc = &scsisrc->u.host;
+
+ if (hostdev->source.subsys.u.scsi.protocol ==
+ VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI)
+ return 0;
+
+- if (!(hostdev_path = qemuGetHostdevPath(hostdev)))
++ if (!(sysfs_path = virSCSIDeviceGetUnprivSGIOSysfsPath(NULL,
++ scsihostsrc->adapter,
++ scsihostsrc->bus,
++ scsihostsrc->target,
++ scsihostsrc->unit)))
+ return -1;
+-
+- path = hostdev_path;
+ } else {
+ return 0;
+ }
+
+- if (!(sysfs_path = virGetUnprivSGIOSysfsPath(path, NULL)))
+- return -1;
+-
+ /* By default, filter the SG_IO commands, i.e. set unpriv_sgio to 0. */
+ if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
+ if (disk->sgio == VIR_DOMAIN_DEVICE_SGIO_UNFILTERED)
+@@ -1904,11 +1911,11 @@ qemuSetUnprivSGIO(virDomainDeviceDef *dev)
+ if (virFileExists(sysfs_path) || val == 1) {
+ int curr_val;
+
+- if (virGetDeviceUnprivSGIO(path, NULL, &curr_val) < 0)
++ if (virGetDeviceUnprivSGIO(sysfs_path, &curr_val) < 0)
+ return -1;
+
+ if (curr_val != val &&
+- virSetDeviceUnprivSGIO(path, NULL, val) < 0) {
++ virSetDeviceUnprivSGIO(sysfs_path, val) < 0) {
+ return -1;
+ }
+ }
+diff --git a/src/util/virscsi.c b/src/util/virscsi.c
+index 6165196423..b437fdcac0 100644
+--- a/src/util/virscsi.c
++++ b/src/util/virscsi.c
+@@ -302,6 +302,25 @@ virSCSIDeviceGetDevName(const char *sysfs_prefix,
+ }
+ }
+
++
++char *
++virSCSIDeviceGetUnprivSGIOSysfsPath(const char *sysfs_prefix,
++ const char *adapter,
++ unsigned int bus,
++ unsigned int target,
++ unsigned long long unit)
++{
++ unsigned int adapter_id;
++ const char *prefix = sysfs_prefix ? sysfs_prefix : SYSFS_SCSI_DEVICES;
++
++ if (virSCSIDeviceGetAdapterId(adapter, &adapter_id) < 0)
++ return NULL;
++
++ return g_strdup_printf("%s/%d:%u:%u:%llu/unpriv_sgio",
++ prefix, adapter_id, bus, target, unit);
++}
++
++
+ virSCSIDevice *
+ virSCSIDeviceNew(const char *sysfs_prefix,
+ const char *adapter,
+diff --git a/src/util/virscsi.h b/src/util/virscsi.h
+index 65ad15ed76..5721985939 100644
+--- a/src/util/virscsi.h
++++ b/src/util/virscsi.h
+@@ -40,6 +40,11 @@ char *virSCSIDeviceGetDevName(const char *sysfs_prefix,
+ unsigned int bus,
+ unsigned int target,
+ unsigned long long unit);
++char *virSCSIDeviceGetUnprivSGIOSysfsPath(const char *sysfs_prefix,
++ const char *adapter,
++ unsigned int bus,
++ unsigned int target,
++ unsigned long long unit);
+
+ virSCSIDevice *virSCSIDeviceNew(const char *sysfs_prefix,
+ const char *adapter,
+diff --git a/src/util/virutil.c b/src/util/virutil.c
+index e04f1343d8..b1e37b45c5 100644
+--- a/src/util/virutil.c
++++ b/src/util/virutil.c
+@@ -1377,18 +1377,13 @@ virGetUnprivSGIOSysfsPath(const char *path,
+
+ int
+ virSetDeviceUnprivSGIO(const char *path,
+- const char *sysfs_dir,
+ int unpriv_sgio)
+ {
+- char *sysfs_path = NULL;
+ char *val = NULL;
+ int ret = -1;
+ int rc;
+
+- if (!(sysfs_path = virGetUnprivSGIOSysfsPath(path, sysfs_dir)))
+- return -1;
+-
+- if (!virFileExists(sysfs_path)) {
++ if (!virFileExists(path)) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("unpriv_sgio is not supported by this kernel"));
+ goto cleanup;
+@@ -1396,38 +1391,32 @@ virSetDeviceUnprivSGIO(const char *path,
+
+ val = g_strdup_printf("%d", unpriv_sgio);
+
+- if ((rc = virFileWriteStr(sysfs_path, val, 0)) < 0) {
+- virReportSystemError(-rc, _("failed to set %s"), sysfs_path);
++ if ((rc = virFileWriteStr(path, val, 0)) < 0) {
++ virReportSystemError(-rc, _("failed to set %s"), path);
+ goto cleanup;
+ }
+
+ ret = 0;
+ cleanup:
+- VIR_FREE(sysfs_path);
+ VIR_FREE(val);
+ return ret;
+ }
+
+ int
+ virGetDeviceUnprivSGIO(const char *path,
+- const char *sysfs_dir,
+ int *unpriv_sgio)
+ {
+- char *sysfs_path = NULL;
+ char *buf = NULL;
+ char *tmp = NULL;
+ int ret = -1;
+
+- if (!(sysfs_path = virGetUnprivSGIOSysfsPath(path, sysfs_dir)))
+- return -1;
+-
+- if (!virFileExists(sysfs_path)) {
++ if (!virFileExists(path)) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("unpriv_sgio is not supported by this kernel"));
+ goto cleanup;
+ }
+
+- if (virFileReadAll(sysfs_path, 1024, &buf) < 0)
++ if (virFileReadAll(path, 1024, &buf) < 0)
+ goto cleanup;
+
+ if ((tmp = strchr(buf, '\n')))
+@@ -1435,13 +1424,12 @@ virGetDeviceUnprivSGIO(const char *path,
+
+ if (virStrToLong_i(buf, NULL, 10, unpriv_sgio) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+- _("failed to parse value of %s"), sysfs_path);
++ _("failed to parse value of %s"), path);
+ goto cleanup;
+ }
+
+ ret = 0;
+ cleanup:
+- VIR_FREE(sysfs_path);
+ VIR_FREE(buf);
+ return ret;
+ }
+diff --git a/src/util/virutil.h b/src/util/virutil.h
+index 854b494890..da267c6446 100644
+--- a/src/util/virutil.h
++++ b/src/util/virutil.h
+@@ -120,10 +120,8 @@ int virGetDeviceID(const char *path,
+ int *maj,
+ int *min) G_GNUC_NO_INLINE;
+ int virSetDeviceUnprivSGIO(const char *path,
+- const char *sysfs_dir,
+ int unpriv_sgio);
+ int virGetDeviceUnprivSGIO(const char *path,
+- const char *sysfs_dir,
+ int *unpriv_sgio);
+ char *virGetUnprivSGIOSysfsPath(const char *path,
+ const char *sysfs_dir);
+--
+2.33.1
+