diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 63a49e305c3e4b811c774ec5423bc846a65f3cff..b6caaf7c8f6d457a41a2552641ae24f3b68c2c73 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6376,11 +6376,13 @@ qemuBuildSmpArgStr(const virDomainDef *def, } static int -qemuBuildNumaArgStr(const virDomainDef *def, virCommandPtr cmd) +qemuBuildNumaArgStr(const virDomainDef *def, + virCommandPtr cmd, + virQEMUCapsPtr qemuCaps) { size_t i; virBuffer buf = VIR_BUFFER_INITIALIZER; - char *cpumask = NULL; + char *cpumask = NULL, *tmpmask = NULL, *next = NULL; int ret = -1; for (i = 0; i < def->cpu->ncells; i++) { @@ -6392,7 +6394,8 @@ qemuBuildNumaArgStr(const virDomainDef *def, virCommandPtr cmd) if (!(cpumask = virBitmapFormat(def->cpu->cells[i].cpumask))) goto cleanup; - if (strchr(cpumask, ',')) { + if (strchr(cpumask, ',') && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_NUMA)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("disjoint NUMA cpu ranges are not supported " "with this QEMU")); @@ -6401,15 +6404,14 @@ qemuBuildNumaArgStr(const virDomainDef *def, virCommandPtr cmd) virCommandAddArg(cmd, "-numa"); virBufferAsprintf(&buf, "node,nodeid=%zu", i); - virBufferAddLit(&buf, ",cpus="); - /* Up through qemu 1.4, -numa does not accept a cpus - * argument any more complex than start-stop. - * - * XXX For qemu 1.5, the syntax has not yet been decided; - * but when it is, we need a capability bit and - * translation of our cpumask into the qemu syntax. */ - virBufferAdd(&buf, cpumask, -1); + for (tmpmask = cpumask; tmpmask; tmpmask = next) { + if ((next = strchr(tmpmask, ','))) + *(next++) = '\0'; + virBufferAddLit(&buf, ",cpus="); + virBufferAdd(&buf, tmpmask, -1); + } + virBufferAsprintf(&buf, ",mem=%d", cellmem); virCommandAddArgBuffer(cmd, &buf); @@ -7313,7 +7315,7 @@ qemuBuildCommandLine(virConnectPtr conn, VIR_FREE(smp); if (def->cpu && def->cpu->ncells) - if (qemuBuildNumaArgStr(def, cmd) < 0) + if (qemuBuildNumaArgStr(def, cmd, qemuCaps) < 0) goto error; if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_UUID)) diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-disjoint.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-disjoint.args new file mode 100644 index 0000000000000000000000000000000000000000..073e84b4d6567caa5b3a8ebee8f9c5d2cb5fea62 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-disjoint.args @@ -0,0 +1,6 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ +/usr/bin/qemu -S -M pc \ +-m 214 -smp 16 -numa node,nodeid=0,cpus=0-3,cpus=8-11,mem=107 \ +-numa node,nodeid=1,cpus=4-7,cpus=12-15,mem=107 -nographic -monitor \ +unix:/tmp/test-monitor,server,nowait -no-acpi -boot n -usb -net none -serial none \ +-parallel none diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-disjoint.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-disjoint.xml new file mode 100644 index 0000000000000000000000000000000000000000..474a238810253ab2e6a27a9b8a109cac890d9720 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-disjoint.xml @@ -0,0 +1,28 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219100 + 219100 + 16 + + hvm + + + + + + + + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 3a76aa6beeb886c2e7cccb45d9df8d48f6ce35a4..1fd106679e3982e391e6a1aa5f67111e327b46f4 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1179,6 +1179,8 @@ mymain(void) DO_TEST("cpu-numa1", NONE); DO_TEST("cpu-numa2", QEMU_CAPS_SMP_TOPOLOGY); DO_TEST_PARSE_ERROR("cpu-numa3", NONE); + DO_TEST_FAILURE("cpu-numa-disjoint", NONE); + DO_TEST("cpu-numa-disjoint", QEMU_CAPS_NUMA); DO_TEST("cpu-host-model", NONE); skipLegacyCPUs = true; DO_TEST("cpu-host-model-fallback", NONE); diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index cbeabad3073a664844a2c155aed64d3467642b62..cefe05b2b67aed7633b037da04f1110a5b62f6fb 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -372,6 +372,7 @@ mymain(void) DO_TEST_DIFFERENT("cpu-numa1"); DO_TEST_DIFFERENT("cpu-numa2"); + DO_TEST("cpu-numa-disjoint"); DO_TEST_DIFFERENT("numatune-auto-prefer"); DO_TEST_DIFFERENT("numatune-memnode");