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(a)redhat.com>
---
src/qemu/qemu_command.c | 31 +---------------------
src/qemu/qemu_driver.c | 56 +++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_hotplug.c | 3 +++
src/qemu/qemu_process.c | 57 ++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_process.h | 2 ++
tests/qemuxml2argvtest.c | 18 +++++++++++++
6 files changed, 137 insertions(+), 30 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 5e7454a6e8..87ebdf4170 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4537,19 +4537,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)
@@ -4626,9 +4613,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)))
@@ -5119,23 +5104,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 79fc8baa5c..b6d5c856a1 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 85943594fa..70b8d39db9 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)
{
@@ -6595,6 +6648,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 7270f2c3cc..3c1bec804a 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++) {
--
2.26.2