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 <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Peter Krempa 2020-10-15 15:06:01 +02:00
parent 609497876c
commit 7b0ced89e7
6 changed files with 137 additions and 30 deletions

View 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:

View 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;

View 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;

View 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;

View 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);

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