From e058a72c77a6deb50228d5ce42ae6b4e389633d8 Mon Sep 17 00:00:00 2001 From: Bjoern Walk Date: Thu, 23 Apr 2020 15:15:08 +0200 Subject: [PATCH] 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 Reviewed-by: Michal Privoznik Reviewed-by: Daniel Henrique Barboza --- src/qemu/qemu_command.c | 41 ++++++-------------- src/qemu/qemu_validate.c | 70 +++++++++++++++++++++++++++++++-- tests/qemuxml2argvtest.c | 84 ++++++++++++++++++++-------------------- 3 files changed, 120 insertions(+), 75 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index a76e7d6f61..6fa3f55844 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -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) diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index cd297aa734..9debac6b30 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -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; } diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index c01a412abd..4a303c0185 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -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); -- GitLab