qemu: move virtio capability validation

Move capability validation of virtio options from command line
generation to post-parse device validation where it belongs.

Signed-off-by: Bjoern Walk <bwalk@linux.ibm.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
This commit is contained in:
Bjoern Walk 2020-04-23 15:15:08 +02:00 committed by Michal Privoznik
parent 6f858bbc42
commit e058a72c77
3 changed files with 120 additions and 75 deletions

View File

@ -588,39 +588,20 @@ qemuBuildVirtioDevStr(virBufferPtr buf,
static int
qemuBuildVirtioOptionsStr(virBufferPtr buf,
virDomainVirtioOptionsPtr virtio,
virQEMUCapsPtr qemuCaps)
virDomainVirtioOptionsPtr virtio)
{
if (!virtio)
return 0;
if (virtio->iommu != VIR_TRISTATE_SWITCH_ABSENT) {
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_PCI_IOMMU_PLATFORM)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("the iommu setting is not supported "
"with this QEMU binary"));
return -1;
}
virBufferAsprintf(buf, ",iommu_platform=%s",
virTristateSwitchTypeToString(virtio->iommu));
}
if (virtio->ats != VIR_TRISTATE_SWITCH_ABSENT) {
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_PCI_ATS)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("the ats setting is not supported with this "
"QEMU binary"));
return -1;
}
virBufferAsprintf(buf, ",ats=%s",
virTristateSwitchTypeToString(virtio->ats));
}
if (virtio->packed != VIR_TRISTATE_SWITCH_ABSENT) {
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_PACKED_QUEUES)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("the packed setting is not supported with this "
"QEMU binary"));
return -1;
}
virBufferAsprintf(buf, ",packed=%s",
virTristateSwitchTypeToString(virtio->packed));
}
@ -2158,7 +2139,7 @@ qemuBuildDiskDeviceStr(const virDomainDef *def,
virBufferAsprintf(&opt, ",num-queues=%u", disk->queues);
}
if (qemuBuildVirtioOptionsStr(&opt, disk->virtio, qemuCaps) < 0)
if (qemuBuildVirtioOptionsStr(&opt, disk->virtio) < 0)
return NULL;
if (qemuBuildDeviceAddressStr(&opt, def, &disk->info, qemuCaps) < 0)
@ -2623,7 +2604,7 @@ qemuBuildVHostUserFsCommandLine(virCommandPtr cmd,
virBufferAsprintf(&opt, ",queue-size=%llu", fs->queue_size);
virBufferAddLit(&opt, ",tag=");
virQEMUBuildBufferEscapeComma(&opt, fs->dst);
if (qemuBuildVirtioOptionsStr(&opt, fs->virtio, priv->qemuCaps) < 0)
if (qemuBuildVirtioOptionsStr(&opt, fs->virtio) < 0)
return -1;
if (qemuBuildDeviceAddressStr(&opt, def, &fs->info, priv->qemuCaps) < 0)
@ -2693,7 +2674,7 @@ qemuBuildFSDevStr(const virDomainDef *def,
virBufferAddLit(&opt, ",mount_tag=");
virQEMUBuildBufferEscapeComma(&opt, fs->dst);
if (qemuBuildVirtioOptionsStr(&opt, fs->virtio, qemuCaps) < 0)
if (qemuBuildVirtioOptionsStr(&opt, fs->virtio) < 0)
return NULL;
if (qemuBuildDeviceAddressStr(&opt, def, &fs->info, qemuCaps) < 0)
@ -2925,7 +2906,7 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef,
def->iothread);
}
if (qemuBuildVirtioOptionsStr(&buf, def->virtio, qemuCaps) < 0)
if (qemuBuildVirtioOptionsStr(&buf, def->virtio) < 0)
return -1;
break;
case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC:
@ -2972,7 +2953,7 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef,
virBufferAsprintf(&buf, ",vectors=%d",
def->opts.vioserial.vectors);
}
if (qemuBuildVirtioOptionsStr(&buf, def->virtio, qemuCaps) < 0)
if (qemuBuildVirtioOptionsStr(&buf, def->virtio) < 0)
return -1;
break;
@ -3924,7 +3905,7 @@ qemuBuildNicDevStr(virDomainDefPtr def,
if (bootindex)
virBufferAsprintf(&buf, ",bootindex=%u", bootindex);
if (usingVirtio &&
qemuBuildVirtioOptionsStr(&buf, net->virtio, qemuCaps) < 0)
qemuBuildVirtioOptionsStr(&buf, net->virtio) < 0)
return NULL;
return virBufferContentAndReset(&buf);
@ -4166,7 +4147,7 @@ qemuBuildMemballoonCommandLine(virCommandPtr cmd,
virTristateSwitchTypeToString(def->memballoon->autodeflate));
}
if (qemuBuildVirtioOptionsStr(&buf, def->memballoon->virtio, qemuCaps) < 0)
if (qemuBuildVirtioOptionsStr(&buf, def->memballoon->virtio) < 0)
return -1;
if (qemuCommandAddExtDevice(cmd, &def->memballoon->info) < 0)
@ -4258,7 +4239,7 @@ qemuBuildVirtioInputDevStr(const virDomainDef *def,
if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
return NULL;
if (qemuBuildVirtioOptionsStr(&buf, dev->virtio, qemuCaps) < 0)
if (qemuBuildVirtioOptionsStr(&buf, dev->virtio) < 0)
return NULL;
return virBufferContentAndReset(&buf);
@ -4569,7 +4550,7 @@ qemuBuildDeviceVideoStr(const virDomainDef *def,
if (qemuBuildDeviceAddressStr(&buf, def, &video->info, qemuCaps) < 0)
return NULL;
if (qemuBuildVirtioOptionsStr(&buf, video->virtio, qemuCaps) < 0)
if (qemuBuildVirtioOptionsStr(&buf, video->virtio) < 0)
return NULL;
return virBufferContentAndReset(&buf);
@ -5785,7 +5766,7 @@ qemuBuildRNGDevStr(const virDomainDef *def,
virBufferAddLit(&buf, ",period=1000");
}
if (qemuBuildVirtioOptionsStr(&buf, dev->virtio, qemuCaps) < 0)
if (qemuBuildVirtioOptionsStr(&buf, dev->virtio) < 0)
return NULL;
if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)

View File

@ -1078,6 +1078,40 @@ qemuValidateNetSupportsCoalesce(virDomainNetType type)
}
static int
qemuValidateDomainVirtioOptions(const virDomainVirtioOptions *virtio,
virQEMUCapsPtr qemuCaps)
{
if (!virtio)
return 0;
if (virtio->iommu != VIR_TRISTATE_SWITCH_ABSENT &&
!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_PCI_IOMMU_PLATFORM)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("the iommu setting is not supported "
"with this QEMU binary"));
return -1;
}
if (virtio->ats != VIR_TRISTATE_SWITCH_ABSENT &&
!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_PCI_ATS)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("the ats setting is not supported with this "
"QEMU binary"));
return -1;
}
if (virtio->packed != VIR_TRISTATE_SWITCH_ABSENT &&
!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_PACKED_QUEUES)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("the packed setting is not supported with this "
"QEMU binary"));
return -1;
}
return 0;
}
static int
qemuValidateDomainDeviceDefNetwork(const virDomainNetDef *net,
virQEMUCapsPtr qemuCaps)
@ -1155,6 +1189,8 @@ qemuValidateDomainDeviceDefNetwork(const virDomainNetDef *net,
_("tx_queue_size has to be a power of two"));
return -1;
}
if (qemuValidateDomainVirtioOptions(net->virtio, qemuCaps) < 0)
return -1;
}
if (net->mtu &&
@ -1502,12 +1538,15 @@ qemuValidateDomainSmartcardDef(const virDomainSmartcardDef *def,
static int
qemuValidateDomainRNGDef(const virDomainRNGDef *def,
virQEMUCapsPtr qemuCaps G_GNUC_UNUSED)
virQEMUCapsPtr qemuCaps)
{
if (def->backend == VIR_DOMAIN_RNG_BACKEND_EGD &&
qemuValidateDomainChrSourceDef(def->source.chardev, qemuCaps) < 0)
return -1;
if (qemuValidateDomainVirtioOptions(def->virtio, qemuCaps) < 0)
return -1;
return 0;
}
@ -1851,6 +1890,9 @@ qemuValidateDomainDeviceDefVideo(const virDomainVideoDef *video,
}
}
if (qemuValidateDomainVirtioOptions(video->virtio, qemuCaps) < 0)
return -1;
return 0;
}
@ -1949,6 +1991,11 @@ qemuValidateDomainDeviceDefDisk(const virDomainDiskDef *disk,
return -1;
}
if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO &&
qemuValidateDomainVirtioOptions(disk->virtio, qemuCaps) < 0) {
return -1;
}
return 0;
}
@ -2179,7 +2226,8 @@ virValidateControllerPCIModelNameToQEMUCaps(int modelName)
static int
qemuValidateDomainDeviceDefControllerAttributes(const virDomainControllerDef *controller)
qemuValidateDomainDeviceDefControllerAttributes(const virDomainControllerDef *controller,
virQEMUCapsPtr qemuCaps)
{
if (!(controller->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI &&
(controller->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI ||
@ -2210,6 +2258,13 @@ qemuValidateDomainDeviceDefControllerAttributes(const virDomainControllerDef *co
_("'iothread' is only supported for virtio-scsi controller"));
return -1;
}
if (qemuValidateDomainVirtioOptions(controller->virtio, qemuCaps) < 0)
return -1;
}
if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL &&
qemuValidateDomainVirtioOptions(controller->virtio, qemuCaps) < 0) {
return -1;
}
return 0;
@ -2752,7 +2807,7 @@ qemuValidateDomainDeviceDefController(const virDomainControllerDef *controller,
!qemuValidateCheckSCSIControllerModel(qemuCaps, controller->model))
return -1;
if (qemuValidateDomainDeviceDefControllerAttributes(controller) < 0)
if (qemuValidateDomainDeviceDefControllerAttributes(controller, qemuCaps) < 0)
return -1;
switch ((virDomainControllerType)controller->type) {
@ -3089,6 +3144,9 @@ qemuValidateDomainDeviceDefFS(virDomainFSDefPtr fs,
return -1;
}
if (qemuValidateDomainVirtioOptions(fs->virtio, qemuCaps) < 0)
return -1;
return 0;
}
@ -3357,6 +3415,9 @@ qemuValidateDomainDeviceDefInput(const virDomainInputDef *input,
return -1;
}
if (qemuValidateDomainVirtioOptions(input->virtio, qemuCaps) < 0)
return -1;
return 0;
}
@ -3386,6 +3447,9 @@ qemuValidateDomainDeviceDefMemballoon(const virDomainMemballoonDef *memballoon,
return -1;
}
if (qemuValidateDomainVirtioOptions(memballoon->virtio, qemuCaps) < 0)
return -1;
return 0;
}

View File

@ -3058,48 +3058,48 @@ mymain(void)
DO_TEST_CAPS_LATEST("virtio-options-net-packed");
DO_TEST_CAPS_LATEST("virtio-options-rng-packed");
DO_TEST_CAPS_LATEST("virtio-options-video-packed");
DO_TEST_FAILURE("virtio-options-controller-iommu", QEMU_CAPS_VIRTIO_SCSI);
DO_TEST_FAILURE("virtio-options-disk-iommu", NONE);
DO_TEST_FAILURE("virtio-options-fs-iommu", NONE);
DO_TEST_FAILURE("virtio-options-input-iommu", QEMU_CAPS_VIRTIO_MOUSE,
QEMU_CAPS_VIRTIO_KEYBOARD);
DO_TEST_FAILURE("virtio-options-memballoon-iommu", NONE);
DO_TEST_FAILURE("virtio-options-net-iommu", NONE);
DO_TEST_FAILURE("virtio-options-rng-iommu", QEMU_CAPS_DEVICE_VIRTIO_RNG,
QEMU_CAPS_OBJECT_RNG_RANDOM);
DO_TEST_FAILURE("virtio-options-video-iommu", QEMU_CAPS_DEVICE_VIRTIO_GPU,
QEMU_CAPS_DEVICE_VIRTIO_GPU,
QEMU_CAPS_VIRTIO_GPU_VIRGL,
QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
QEMU_CAPS_DEVICE_VHOST_USER_GPU);
DO_TEST_FAILURE("virtio-options-controller-ats", QEMU_CAPS_VIRTIO_SCSI);
DO_TEST_FAILURE("virtio-options-disk-ats", NONE);
DO_TEST_FAILURE("virtio-options-fs-ats", NONE);
DO_TEST_FAILURE("virtio-options-input-ats", QEMU_CAPS_VIRTIO_MOUSE,
QEMU_CAPS_VIRTIO_KEYBOARD);
DO_TEST_FAILURE("virtio-options-memballoon-ats", NONE);
DO_TEST_FAILURE("virtio-options-net-ats", NONE);
DO_TEST_FAILURE("virtio-options-rng-ats", QEMU_CAPS_DEVICE_VIRTIO_RNG,
QEMU_CAPS_OBJECT_RNG_RANDOM);
DO_TEST_FAILURE("virtio-options-video-ats", QEMU_CAPS_DEVICE_VIRTIO_GPU,
QEMU_CAPS_DEVICE_VIRTIO_GPU,
QEMU_CAPS_VIRTIO_GPU_VIRGL,
QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
QEMU_CAPS_DEVICE_VHOST_USER_GPU);
DO_TEST_FAILURE("virtio-options-controller-packed", QEMU_CAPS_VIRTIO_SCSI);
DO_TEST_FAILURE("virtio-options-disk-packed", NONE);
DO_TEST_FAILURE("virtio-options-fs-packed", NONE);
DO_TEST_FAILURE("virtio-options-input-packed", QEMU_CAPS_VIRTIO_MOUSE,
QEMU_CAPS_VIRTIO_KEYBOARD);
DO_TEST_FAILURE("virtio-options-memballoon-packed", NONE);
DO_TEST_FAILURE("virtio-options-net-packed", NONE);
DO_TEST_FAILURE("virtio-options-rng-packed", QEMU_CAPS_DEVICE_VIRTIO_RNG,
QEMU_CAPS_OBJECT_RNG_RANDOM);
DO_TEST_FAILURE("virtio-options-video-packed", QEMU_CAPS_DEVICE_VIRTIO_GPU,
QEMU_CAPS_DEVICE_VIRTIO_GPU,
QEMU_CAPS_VIRTIO_GPU_VIRGL,
QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
QEMU_CAPS_DEVICE_VHOST_USER_GPU);
DO_TEST_PARSE_ERROR("virtio-options-controller-iommu", QEMU_CAPS_VIRTIO_SCSI);
DO_TEST_PARSE_ERROR("virtio-options-disk-iommu", NONE);
DO_TEST_PARSE_ERROR("virtio-options-fs-iommu", NONE);
DO_TEST_PARSE_ERROR("virtio-options-input-iommu", QEMU_CAPS_VIRTIO_MOUSE,
QEMU_CAPS_VIRTIO_KEYBOARD);
DO_TEST_PARSE_ERROR("virtio-options-net-iommu", NONE);
DO_TEST_PARSE_ERROR("virtio-options-memballoon-iommu", NONE);
DO_TEST_PARSE_ERROR("virtio-options-rng-iommu", QEMU_CAPS_DEVICE_VIRTIO_RNG,
QEMU_CAPS_OBJECT_RNG_RANDOM);
DO_TEST_PARSE_ERROR("virtio-options-video-iommu", QEMU_CAPS_DEVICE_VIRTIO_GPU,
QEMU_CAPS_DEVICE_VIRTIO_GPU,
QEMU_CAPS_VIRTIO_GPU_VIRGL,
QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
QEMU_CAPS_DEVICE_VHOST_USER_GPU);
DO_TEST_PARSE_ERROR("virtio-options-controller-ats", QEMU_CAPS_VIRTIO_SCSI);
DO_TEST_PARSE_ERROR("virtio-options-disk-ats", NONE);
DO_TEST_PARSE_ERROR("virtio-options-fs-ats", NONE);
DO_TEST_PARSE_ERROR("virtio-options-input-ats", QEMU_CAPS_VIRTIO_MOUSE,
QEMU_CAPS_VIRTIO_KEYBOARD);
DO_TEST_PARSE_ERROR("virtio-options-memballoon-ats", NONE);
DO_TEST_PARSE_ERROR("virtio-options-net-ats", NONE);
DO_TEST_PARSE_ERROR("virtio-options-rng-ats", QEMU_CAPS_DEVICE_VIRTIO_RNG,
QEMU_CAPS_OBJECT_RNG_RANDOM);
DO_TEST_PARSE_ERROR("virtio-options-video-ats", QEMU_CAPS_DEVICE_VIRTIO_GPU,
QEMU_CAPS_DEVICE_VIRTIO_GPU,
QEMU_CAPS_VIRTIO_GPU_VIRGL,
QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
QEMU_CAPS_DEVICE_VHOST_USER_GPU);
DO_TEST_PARSE_ERROR("virtio-options-controller-packed", QEMU_CAPS_VIRTIO_SCSI);
DO_TEST_PARSE_ERROR("virtio-options-disk-packed", NONE);
DO_TEST_PARSE_ERROR("virtio-options-fs-packed", NONE);
DO_TEST_PARSE_ERROR("virtio-options-input-packed", QEMU_CAPS_VIRTIO_MOUSE,
QEMU_CAPS_VIRTIO_KEYBOARD);
DO_TEST_PARSE_ERROR("virtio-options-memballoon-packed", NONE);
DO_TEST_PARSE_ERROR("virtio-options-net-packed", NONE);
DO_TEST_PARSE_ERROR("virtio-options-rng-packed", QEMU_CAPS_DEVICE_VIRTIO_RNG,
QEMU_CAPS_OBJECT_RNG_RANDOM);
DO_TEST_PARSE_ERROR("virtio-options-video-packed", QEMU_CAPS_DEVICE_VIRTIO_GPU,
QEMU_CAPS_DEVICE_VIRTIO_GPU,
QEMU_CAPS_VIRTIO_GPU_VIRGL,
QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
QEMU_CAPS_DEVICE_VHOST_USER_GPU);
DO_TEST("fd-memory-numa-topology", QEMU_CAPS_OBJECT_MEMORY_FILE,
QEMU_CAPS_KVM);