From 6dfdc50564c3d2147f36c4cf6c252cad7a0e9381 Mon Sep 17 00:00:00 2001 Message-Id: <6dfdc50564c3d2147f36c4cf6c252cad7a0e9381@dist-git> From: Michal Privoznik Date: Fri, 6 Mar 2020 15:51:46 +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=1808388 Signed-off-by: Michal Privoznik Signed-off-by: Andrea Bolognani Message-Id: <20200306145149.1610286-4-abologna@redhat.com> Reviewed-by: Jiri Denemark --- src/libvirt_private.syms | 1 + src/qemu/qemu_conf.c | 19 +++++++++++-------- src/util/virscsi.c | 21 +++++++++++++++++++++ src/util/virscsi.h | 5 +++++ 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 2ad21a68bc..5e1d73c148 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2727,6 +2727,7 @@ virSCSIDeviceGetSgName; virSCSIDeviceGetShareable; virSCSIDeviceGetTarget; virSCSIDeviceGetUnit; +virSCSIDeviceGetUnprivSGIOSysfsPath; virSCSIDeviceIsAvailable; virSCSIDeviceListAdd; virSCSIDeviceListCount; diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index a81298326f..5636277888 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1648,7 +1648,6 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev) virDomainDiskDefPtr disk = NULL; virDomainHostdevDefPtr hostdev = NULL; char *sysfs_path = NULL; - char *hostdev_path = NULL; const char *path = NULL; int val = 0; int ret = -1; @@ -1664,24 +1663,29 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev) return 0; path = virDomainDiskGetSource(disk); + + if (!(sysfs_path = virGetUnprivSGIOSysfsPath(path, NULL))) + goto cleanup; + } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) { hostdev = dev->data.hostdev; + virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi; + virDomainHostdevSubsysSCSIHostPtr 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))) goto cleanup; - - path = hostdev_path; } else { return 0; } - if (!(sysfs_path = virGetUnprivSGIOSysfsPath(path, NULL))) - goto cleanup; - /* 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) @@ -1705,7 +1709,6 @@ qemuSetUnprivSGIO(virDomainDeviceDefPtr dev) ret = 0; cleanup: - VIR_FREE(hostdev_path); VIR_FREE(sysfs_path); return ret; } diff --git a/src/util/virscsi.c b/src/util/virscsi.c index 6c3fd8a562..5aab43fc88 100644 --- a/src/util/virscsi.c +++ b/src/util/virscsi.c @@ -342,6 +342,27 @@ virSCSIDeviceGetDevName(const char *sysfs_prefix, } +char * +virSCSIDeviceGetUnprivSGIOSysfsPath(const char *sysfs_prefix, + const char *adapter, + unsigned int bus, + unsigned int target, + unsigned long long unit) +{ + char *path = NULL; + unsigned int adapter_id; + const char *prefix = sysfs_prefix ? sysfs_prefix : SYSFS_SCSI_DEVICES; + + if (virSCSIDeviceGetAdapterId(adapter, &adapter_id) < 0) + return NULL; + + ignore_value(virAsprintf(&path, + "%s/%d:%u:%u:%llu/unpriv_sgio", + prefix, adapter_id, bus, target, unit)); + return path; +} + + virSCSIDevicePtr virSCSIDeviceNew(const char *sysfs_prefix, const char *adapter, diff --git a/src/util/virscsi.h b/src/util/virscsi.h index 9f8b3ecf1e..5dea2a9f5d 100644 --- a/src/util/virscsi.h +++ b/src/util/virscsi.h @@ -43,6 +43,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); virSCSIDevicePtr virSCSIDeviceNew(const char *sysfs_prefix, const char *adapter, -- 2.25.1