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++) {