Signed-off-by: Martin Kletzander <mkletzan(a)redhat.com>
---
src/qemu/qemu_command.c | 26 ++++++++++----------
.../qemuxml2argv-cpu-numa-disjoint.args | 6 +++++
.../qemuxml2argv-cpu-numa-disjoint.xml | 28 ++++++++++++++++++++++
tests/qemuxml2argvtest.c | 2 ++
tests/qemuxml2xmltest.c | 1 +
5 files changed, 51 insertions(+), 12 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-disjoint.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-disjoint.xml
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 249ce8d..284664b 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6366,11 +6366,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++) {
@@ -6382,7 +6384,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"));
@@ -6391,15 +6394,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);
@@ -7230,7 +7232,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 0000000..073e84b
--- /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 0000000..474a238
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-disjoint.xml
@@ -0,0 +1,28 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static'>16</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <cpu>
+ <topology sockets='2' cores='4' threads='2'/>
+ <numa>
+ <cell id='0' cpus='0-3,8-11' memory='109550'/>
+ <cell id='1' cpus='4-7,12-15' memory='109550'/>
+ </numa>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <controller type='usb' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index bb7f580..a2d27cb 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1178,6 +1178,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 4beb799..63eb747 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -370,6 +370,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");
--
2.0.0