diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index f99e363507..7b0879d5cc 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4145,16 +4145,8 @@ qemuBuildDriveStr(virConnectPtr conn, static bool qemuCheckIOThreads(virDomainDefPtr def, - virQEMUCapsPtr qemuCaps, virDomainDiskDefPtr disk) { - /* Have capability */ - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_IOTHREAD)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("IOThreads not supported for this QEMU")); - return false; - } - /* Right "type" of disk" */ if (disk->bus != VIR_DOMAIN_DISK_BUS_VIRTIO || (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI && @@ -4208,7 +4200,7 @@ qemuBuildDriveDevStr(virDomainDefPtr def, if (!qemuCheckCCWS390AddressSupport(def, disk->info, qemuCaps, disk->dst)) goto error; - if (disk->iothread && !qemuCheckIOThreads(def, qemuCaps, disk)) + if (disk->iothread && !qemuCheckIOThreads(def, disk)) goto error; switch (disk->bus) { @@ -9462,8 +9454,13 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, smp); VIR_FREE(smp); - if (def->niothreadids > 0 && - virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_IOTHREAD)) { + if (def->niothreadids) { + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_IOTHREAD)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("IOThreads not supported for this QEMU")); + goto error; + } + /* Create iothread objects using the defined iothreadids list * and the defined id and name from the list. These may be used * by a disk definition which will associate to an iothread by diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index e31885b37e..07e41f0cda 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -2296,8 +2296,32 @@ qemuProcessDetectIOThreadPIDs(virQEMUDriverPtr driver, int ret = -1; size_t i; - if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_OBJECT_IOTHREAD)) + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_OBJECT_IOTHREAD)) { + /* The following check is because at one time a domain could + * define iothreadids and start the domain - only failing the + * capability check when attempting to add a disk. Because the + * iothreads and [n]iothreadids were left untouched other code + * assumed it could use the ->thread_id value to make thread_id + * based adjustments (e.g. pinning, scheduling) which while + * succeeding would execute on the calling thread. + */ + if (vm->def->niothreadids) { + for (i = 0; i < vm->def->niothreadids; i++) { + /* Check if the domain had defined any iothreadid elements + * and supply a VIR_INFO indicating that it's being removed. + */ + if (!vm->def->iothreadids[i]->autofill) + VIR_INFO("IOThreads not supported, remove iothread id '%u'", + vm->def->iothreadids[i]->iothread_id); + virDomainIOThreadIDDefFree(vm->def->iothreadids[i]); + } + /* Remove any trace */ + VIR_FREE(vm->def->iothreadids); + vm->def->niothreadids = 0; + vm->def->iothreads = 0; + } return 0; + } /* Get the list of IOThreads from qemu */ if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.args b/tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.args index 481f72ffd2..affe648089 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.args @@ -1,5 +1,6 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ /usr/bin/qemu-system-x86_64 -S -M pc-q35-2.3 -m 128 \ -smp 2,maxcpus=6,sockets=6,cores=1,threads=1 \ +-object iothread,id=iothread1 -object iothread,id=iothread2 \ -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi \ -boot c -net none -serial none -parallel none diff --git a/tests/qemuxml2argvdata/qemuxml2argv-iothreads-nocap.xml b/tests/qemuxml2argvdata/qemuxml2argv-iothreads-nocap.xml new file mode 100644 index 0000000000..61871e7b6c --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-iothreads-nocap.xml @@ -0,0 +1,37 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219136 + 219136 + 2 + 4 + + + + + + + + + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + +
+ + + + + + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 80cb55ec3e..53580e3d68 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1285,6 +1285,7 @@ mymain(void) DO_TEST("iothreads", QEMU_CAPS_OBJECT_IOTHREAD); DO_TEST("iothreads-ids", QEMU_CAPS_OBJECT_IOTHREAD); DO_TEST("iothreads-ids-partial", QEMU_CAPS_OBJECT_IOTHREAD); + DO_TEST_FAILURE("iothreads-nocap", NONE); DO_TEST("iothreads-disk", QEMU_CAPS_OBJECT_IOTHREAD, QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE); DO_TEST("iothreads-disk-virtio-ccw", QEMU_CAPS_OBJECT_IOTHREAD, QEMU_CAPS_DEVICE, @@ -1338,6 +1339,7 @@ mymain(void) DO_TEST_PARSE_ERROR("cputune-vcpusched-overlap", QEMU_CAPS_NAME); DO_TEST("cputune-numatune", QEMU_CAPS_SMP_TOPOLOGY, QEMU_CAPS_KVM, + QEMU_CAPS_OBJECT_IOTHREAD, QEMU_CAPS_OBJECT_MEMORY_RAM, QEMU_CAPS_OBJECT_MEMORY_FILE);