render / rpms / libvirt

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