]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: Prepare hostdev data which depends on the host state separately
authorPeter Krempa <pkrempa@redhat.com>
Thu, 15 Oct 2020 13:06:01 +0000 (15:06 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 20 Oct 2020 13:08:22 +0000 (15:08 +0200)
SCSI hostdev setup requires querying the host os for the actual path of
the configured hostdev. This was historically done in the command line
formatter. Our new approach is to split out this part into
'qemuProcessPrepareHost' which is designed to be skipped in tests.

Refactor the hostdev code to use this new semantics, and add appropriate
handlers filling in the data for tests and the qemuConnectDomainXMLToNative
users.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/qemu/qemu_command.c
src/qemu/qemu_driver.c
src/qemu/qemu_hotplug.c
src/qemu/qemu_process.c
src/qemu/qemu_process.h
tests/qemuxml2argvtest.c

index d58c76306cdcbd8d486b1247f50406718c2deb0c..700f6d781c8a33e48d65392625b8d29fbdad6d79 100644 (file)
@@ -4401,19 +4401,6 @@ qemuBuildHubCommandLine(virCommandPtr cmd,
 }
 
 
-static char *
-qemuBuildSCSIHostHostdevDrvStr(virDomainHostdevDefPtr dev)
-{
-    virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
-    virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
-
-    return virSCSIDeviceGetSgName(NULL,
-                                  scsihostsrc->adapter,
-                                  scsihostsrc->bus,
-                                  scsihostsrc->target,
-                                  scsihostsrc->unit);
-}
-
 static char *
 qemuBuildSCSIiSCSIHostdevDrvStr(virDomainHostdevDefPtr dev,
                                 virQEMUCapsPtr qemuCaps)
@@ -4484,9 +4471,7 @@ qemuBuildSCSIHostdevDrvStr(virDomainHostdevDefPtr dev,
             return NULL;
         virBufferAdd(&buf, source, -1);
     } else {
-        if (!(source = qemuBuildSCSIHostHostdevDrvStr(dev)))
-            return NULL;
-        virBufferAsprintf(&buf, "file=/dev/%s,if=none,format=raw", source);
+        virBufferAsprintf(&buf, "file=%s,if=none,format=raw", scsisrc->u.host.src->path);
     }
 
     if (!(drivealias = qemuAliasFromHostdev(dev)))
@@ -4977,23 +4962,9 @@ qemuBuildHostdevSCSIAttachPrepare(virDomainHostdevDefPtr hostdev,
     virStorageSourcePtr src = NULL;
 
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV_HOSTDEV_SCSI)) {
-        g_autofree char *devstr = NULL;
-
         switch ((virDomainHostdevSCSIProtocolType) scsisrc->protocol) {
         case VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_NONE:
-            if (!scsisrc->u.host.src) {
-                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                               _("SCSI host device data structure was not initialized"));
-                return NULL;
-            }
-
-            if (!(devstr = qemuBuildSCSIHostHostdevDrvStr(hostdev)))
-                return NULL;
-
             src = scsisrc->u.host.src;
-
-            src->path = g_strdup_printf("/dev/%s", devstr);
-
             break;
 
         case VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI:
index f07a27d52519ad64e3f16a4deff5ffd2e013254f..bb4a46be986b915bb32ef798445e5e0d161b2510 100644 (file)
@@ -6398,6 +6398,59 @@ static char
 }
 
 
+static int
+qemuConnectDomainXMLToNativePrepareHostHostdev(virDomainHostdevDefPtr hostdev)
+{
+    if (virHostdevIsSCSIDevice(hostdev)) {
+        virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi;
+
+        switch ((virDomainHostdevSCSIProtocolType) scsisrc->protocol) {
+        case VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_NONE: {
+            virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
+            virStorageSourcePtr src = scsisrc->u.host.src;
+            g_autofree char *devstr = NULL;
+
+            if (!(devstr = virSCSIDeviceGetSgName(NULL,
+                                                  scsihostsrc->adapter,
+                                                  scsihostsrc->bus,
+                                                  scsihostsrc->target,
+                                                  scsihostsrc->unit)))
+                return -1;
+
+            src->path = g_strdup_printf("/dev/%s", devstr);
+            break;
+        }
+
+        case VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI:
+            break;
+
+        case VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_LAST:
+        default:
+            virReportEnumRangeError(virDomainHostdevSCSIProtocolType, scsisrc->protocol);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+
+static int
+qemuConnectDomainXMLToNativePrepareHost(virDomainObjPtr vm)
+{
+    size_t i;
+
+    for (i = 0; i < vm->def->nhostdevs; i++) {
+        virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
+
+        if (qemuConnectDomainXMLToNativePrepareHostHostdev(hostdev) < 0)
+            return -1;
+    }
+
+    return 0;
+}
+
+
 static char *qemuConnectDomainXMLToNative(virConnectPtr conn,
                                           const char *format,
                                           const char *xmlData,
@@ -6455,6 +6508,9 @@ static char *qemuConnectDomainXMLToNative(virConnectPtr conn,
                                            VIR_QEMU_PROCESS_START_COLD) < 0)
         goto cleanup;
 
+    if (qemuConnectDomainXMLToNativePrepareHost(vm) < 0)
+        goto cleanup;
+
     if (!(cmd = qemuProcessCreatePretendCmdBuild(driver, vm, NULL,
                                                  qemuCheckFips(), true, false)))
         goto cleanup;
index f76e773f640dcd5d4015dd9f11a0c16d0542f572..3841c993b896a59e959240d279c8eb335cfae9e8 100644 (file)
@@ -2608,6 +2608,9 @@ qemuDomainAttachHostSCSIDevice(virQEMUDriverPtr driver,
     if (qemuDomainPrepareHostdev(hostdev, priv) < 0)
         goto cleanup;
 
+    if (qemuProcessPrepareHostHostdev(hostdev) < 0)
+        goto cleanup;
+
     if (!(data = qemuBuildHostdevSCSIAttachPrepare(hostdev, &backendalias,
                                                    priv->qemuCaps)))
         goto cleanup;
index 1f504011cbcb851f96b2ea85280cc040a350f56a..fae386917d330ab4cf983c3a056a88e3a4bef1f6 100644 (file)
@@ -6213,6 +6213,59 @@ qemuProcessPrepareDomainHostdevs(virDomainObjPtr vm,
 }
 
 
+int
+qemuProcessPrepareHostHostdev(virDomainHostdevDefPtr hostdev)
+{
+    if (virHostdevIsSCSIDevice(hostdev)) {
+        virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi;
+
+        switch ((virDomainHostdevSCSIProtocolType) scsisrc->protocol) {
+        case VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_NONE: {
+            virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
+            virStorageSourcePtr src = scsisrc->u.host.src;
+            g_autofree char *devstr = NULL;
+
+            if (!(devstr = virSCSIDeviceGetSgName(NULL,
+                                                  scsihostsrc->adapter,
+                                                  scsihostsrc->bus,
+                                                  scsihostsrc->target,
+                                                  scsihostsrc->unit)))
+                return -1;
+
+            src->path = g_strdup_printf("/dev/%s", devstr);
+            break;
+        }
+
+        case VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI:
+            break;
+
+        case VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_LAST:
+        default:
+            virReportEnumRangeError(virDomainHostdevSCSIProtocolType, scsisrc->protocol);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+
+static int
+qemuProcessPrepareHostHostdevs(virDomainObjPtr vm)
+{
+    size_t i;
+
+    for (i = 0; i < vm->def->nhostdevs; i++) {
+        virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
+
+        if (qemuProcessPrepareHostHostdev(hostdev) < 0)
+            return -1;
+    }
+
+    return 0;
+}
+
+
 static void
 qemuProcessPrepareAllowReboot(virDomainObjPtr vm)
 {
@@ -6618,6 +6671,10 @@ qemuProcessPrepareHost(virQEMUDriverPtr driver,
     if (qemuProcessPrepareHostStorage(driver, vm, flags) < 0)
         return -1;
 
+    VIR_DEBUG("Preparing hostdevs (host-side)");
+    if (qemuProcessPrepareHostHostdevs(vm) < 0)
+        return -1;
+
     VIR_DEBUG("Preparing external devices");
     if (qemuExtDevicesPrepareHost(driver, vm) < 0)
         return -1;
index 830b2b23d6d8651c50d2a0cc1c77779e1c1a8293..f4feeaa68fa6ee618dfda463ca75b8f3b590a92e 100644 (file)
@@ -122,6 +122,8 @@ int qemuProcessPrepareDomain(virQEMUDriverPtr driver,
 
 int qemuProcessOpenVhostVsock(virDomainVsockDefPtr vsock);
 
+int qemuProcessPrepareHostHostdev(virDomainHostdevDefPtr hostdev);
+
 int qemuProcessPrepareHost(virQEMUDriverPtr driver,
                            virDomainObjPtr vm,
                            unsigned int flags);
index 8cab2da6268c3b645ed81d9385693380c1d15dec..abc982890fd92180984d7c73c4fbc94cc1408356 100644 (file)
@@ -413,6 +413,24 @@ testCompareXMLToArgvCreateArgs(virQEMUDriverPtr drv,
             hostdev->source.subsys.u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT) {
             hostdev->source.subsys.u.pci.backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO;
         }
+
+        if (virHostdevIsSCSIDevice(hostdev)) {
+            virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi;
+
+            switch ((virDomainHostdevSCSIProtocolType) scsisrc->protocol) {
+            case VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_NONE:
+                scsisrc->u.host.src->path = g_strdup("/dev/sg0");
+                break;
+
+            case VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI:
+                break;
+
+            case VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_LAST:
+            default:
+                virReportEnumRangeError(virDomainHostdevSCSIProtocolType, scsisrc->protocol);
+                return NULL;
+            }
+        }
     }
 
     for (i = 0; i < vm->def->nfss; i++) {