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