From: Peter Krempa Date: Thu, 15 Oct 2020 13:06:01 +0000 (+0200) Subject: qemu: Prepare hostdev data which depends on the host state separately X-Git-Tag: v6.9.0-rc1~71 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7b0ced89e7eea2adddfae9afa8def7b8b8dbe076;p=thirdparty%2Flibvirt.git qemu: Prepare hostdev data which depends on the host state separately 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 Reviewed-by: Michal Privoznik --- diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index d58c76306c..700f6d781c 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -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: diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index f07a27d525..bb4a46be98 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -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; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index f76e773f64..3841c993b8 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -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; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 1f504011cb..fae386917d 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -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; diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index 830b2b23d6..f4feeaa68f 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -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); diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 8cab2da626..abc982890f 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -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++) {