A new qemuDomainDefValidateNuma() function was created to host
all the QEMU caps validation being done inside qemuBuildNumaArgStr().
This new function is called by qemuDomainValidateCpuCount()
to allow NUMA validation in domain define time.
Tests were changed to account for the QEMU capabilities
that need to be present at domain define time.
Signed-off-by: Daniel Henrique Barboza <danielhb413(a)gmail.com>
---
src/qemu/qemu_command.c | 42 -------------------------
src/qemu/qemu_domain.c | 66 ++++++++++++++++++++++++++++++++++++++++
tests/qemuxml2argvtest.c | 14 ++++-----
tests/qemuxml2xmltest.c | 51 +++++++++++++++++--------------
4 files changed, 102 insertions(+), 71 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 7849607b16..f0f245d730 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7442,26 +7442,6 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
int rc;
int ret = -1;
size_t ncells = virDomainNumaGetNodeCount(def->numa);
- const long system_page_size = virGetSystemPageSizeKB();
-
- if (virDomainNumatuneHasPerNodeBinding(def->numa) &&
- !(virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) ||
- virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE) ||
- virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_MEMFD))) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Per-node memory binding is not supported "
- "with this QEMU"));
- goto cleanup;
- }
-
- if (def->mem.nhugepages &&
- def->mem.hugepages[0].size != system_page_size &&
- !virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("huge pages per NUMA node are not "
- "supported with this QEMU"));
- goto cleanup;
- }
if (!virDomainNumatuneNodesetIsAvailable(def->numa, priv->autoNodeset))
goto cleanup;
@@ -7482,13 +7462,6 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
if (rc == 0)
needBackend = true;
- } else {
- if (virDomainNumaGetNodeMemoryAccessMode(def->numa, i)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Shared memory mapping is not supported "
- "with this QEMU"));
- goto cleanup;
- }
}
}
@@ -7501,14 +7474,6 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
if (!(cpumask = virBitmapFormat(virDomainNumaGetNodeCpumask(def->numa, i))))
goto cleanup;
- if (strchr(cpumask, ',') &&
- !virQEMUCapsGet(qemuCaps, QEMU_CAPS_NUMA)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("disjoint NUMA cpu ranges are not supported "
- "with this QEMU"));
- goto cleanup;
- }
-
if (needBackend) {
virCommandAddArg(cmd, "-object");
virCommandAddArgBuffer(cmd, &nodeBackends[i]);
@@ -7537,13 +7502,6 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
* of nodes, we have to specify all the distances. Even
* though they might be the default ones. */
if (virDomainNumaNodesDistancesAreBeingSet(def->numa)) {
- if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_NUMA_DIST)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("setting NUMA distances is not "
- "supported with this qemu"));
- goto cleanup;
- }
-
for (i = 0; i < ncells; i++) {
for (j = 0; j < ncells; j++) {
size_t distance = virDomainNumaGetNodeDistance(def->numa, i, j);
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index b77b3cf845..503892a40f 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -5104,6 +5104,69 @@ qemuDomainDefValidateMemory(const virDomainDef *def,
}
+static int
+qemuDomainDefValidateNuma(const virDomainDef *def,
+ virQEMUCapsPtr qemuCaps)
+{
+ const long system_page_size = virGetSystemPageSizeKB();
+ size_t ncells = virDomainNumaGetNodeCount(def->numa);
+ size_t i;
+ bool hasMemoryCap = virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) ||
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE) ||
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_MEMFD);
+
+ if (virDomainNumatuneHasPerNodeBinding(def->numa) && !hasMemoryCap) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Per-node memory binding is not supported "
+ "with this QEMU"));
+ return -1;
+ }
+
+ if (def->mem.nhugepages &&
+ def->mem.hugepages[0].size != system_page_size &&
+ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("huge pages per NUMA node are not "
+ "supported with this QEMU"));
+ return -1;
+ }
+
+ for (i = 0; i < ncells; i++) {
+ g_autofree char * cpumask = NULL;
+
+ if (!hasMemoryCap &&
+ virDomainNumaGetNodeMemoryAccessMode(def->numa, i)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Shared memory mapping is not supported "
+ "with this QEMU"));
+ return -1;
+ }
+
+ if (!(cpumask = virBitmapFormat(virDomainNumaGetNodeCpumask(def->numa, i))))
+ return -1;
+
+ if (strchr(cpumask, ',') &&
+ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_NUMA)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("disjoint NUMA cpu ranges are not supported "
+ "with this QEMU"));
+ return -1;
+ }
+
+ }
+
+ if (virDomainNumaNodesDistancesAreBeingSet(def->numa) &&
+ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_NUMA_DIST)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("setting NUMA distances is not "
+ "supported with this qemu"));
+ return -1;
+ }
+
+ return 0;
+}
+
+
static int
qemuDomainValidateCpuCount(const virDomainDef *def,
virQEMUCapsPtr qemuCaps)
@@ -5270,6 +5333,9 @@ qemuDomainDefValidate(const virDomainDef *def,
if (qemuDomainDefValidateMemory(def, qemuCaps) < 0)
goto cleanup;
+ if (qemuDomainDefValidateNuma(def, qemuCaps) < 0)
+ goto cleanup;
+
if (cfg->vncTLS && cfg->vncTLSx509secretUUID &&
!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_TLS_CREDS_X509)) {
for (i = 0; i < def->ngraphics; i++) {
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index cc1a82488e..3c081651cf 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -944,11 +944,11 @@ mymain(void)
QEMU_CAPS_DEVICE_PC_DIMM,
QEMU_CAPS_OBJECT_MEMORY_FILE,
QEMU_CAPS_OBJECT_MEMORY_FILE_DISCARD);
- DO_TEST("hugepages-default", NONE);
- DO_TEST("hugepages-default-2M", NONE);
+ DO_TEST("hugepages-default", QEMU_CAPS_OBJECT_MEMORY_FILE);
+ DO_TEST("hugepages-default-2M", QEMU_CAPS_OBJECT_MEMORY_FILE);
DO_TEST("hugepages-default-system-size", NONE);
DO_TEST_PARSE_ERROR("hugepages-default-1G-nodeset-2M", NONE);
- DO_TEST("hugepages-nodeset", NONE);
+ DO_TEST("hugepages-nodeset", QEMU_CAPS_OBJECT_MEMORY_FILE);
DO_TEST_PARSE_ERROR("hugepages-nodeset-nonexist",
QEMU_CAPS_DEVICE_PC_DIMM,
QEMU_CAPS_OBJECT_MEMORY_FILE,
@@ -1711,10 +1711,10 @@ mymain(void)
DO_TEST("cpu-numa2", NONE);
DO_TEST("cpu-numa-no-memory-element", NONE);
DO_TEST_PARSE_ERROR("cpu-numa3", NONE);
- DO_TEST_FAILURE("cpu-numa-disjoint", NONE);
+ DO_TEST_PARSE_ERROR("cpu-numa-disjoint", NONE);
DO_TEST("cpu-numa-disjoint", QEMU_CAPS_NUMA);
DO_TEST_FAILURE("cpu-numa-memshared", QEMU_CAPS_OBJECT_MEMORY_RAM);
- DO_TEST_FAILURE("cpu-numa-memshared", NONE);
+ DO_TEST_PARSE_ERROR("cpu-numa-memshared", NONE);
DO_TEST("cpu-numa-memshared", QEMU_CAPS_OBJECT_MEMORY_FILE);
DO_TEST("cpu-host-model", NONE);
DO_TEST("cpu-host-model-vendor", NONE);
@@ -1777,12 +1777,12 @@ mymain(void)
DO_TEST("numatune-memnode",
QEMU_CAPS_NUMA,
QEMU_CAPS_OBJECT_MEMORY_RAM);
- DO_TEST_FAILURE("numatune-memnode", NONE);
+ DO_TEST_PARSE_ERROR("numatune-memnode", NONE);
DO_TEST("numatune-memnode-no-memory",
QEMU_CAPS_NUMA,
QEMU_CAPS_OBJECT_MEMORY_RAM);
- DO_TEST_FAILURE("numatune-memnode-no-memory", NONE);
+ DO_TEST_PARSE_ERROR("numatune-memnode-no-memory", NONE);
DO_TEST("numatune-distances", QEMU_CAPS_NUMA, QEMU_CAPS_NUMA_DIST);
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 0e2933e13e..215d6b78cd 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -289,20 +289,21 @@ mymain(void)
DO_TEST("pmu-feature-off", NONE);
DO_TEST("pages-discard", NONE);
- DO_TEST("pages-discard-hugepages", NONE);
+ DO_TEST("pages-discard-hugepages", QEMU_CAPS_OBJECT_MEMORY_FILE);
DO_TEST("pages-dimm-discard", NONE);
- DO_TEST("hugepages-default", NONE);
- DO_TEST("hugepages-default-2M", NONE);
+ DO_TEST("hugepages-default", QEMU_CAPS_OBJECT_MEMORY_FILE);
+ DO_TEST("hugepages-default-2M", QEMU_CAPS_OBJECT_MEMORY_FILE);
DO_TEST("hugepages-default-system-size", NONE);
- DO_TEST("hugepages-nodeset", NONE);
- DO_TEST("hugepages-numa-default-2M", NONE);
- DO_TEST("hugepages-numa-default-dimm", NONE);
- DO_TEST("hugepages-numa-nodeset", NONE);
- DO_TEST("hugepages-numa-nodeset-part", NONE);
- DO_TEST("hugepages-shared", NONE);
- DO_TEST("hugepages-memaccess", NONE);
- DO_TEST("hugepages-memaccess2", NONE);
- DO_TEST("hugepages-nvdimm", QEMU_CAPS_DEVICE_NVDIMM);
+ DO_TEST("hugepages-nodeset", QEMU_CAPS_OBJECT_MEMORY_FILE);
+ DO_TEST("hugepages-numa-default-2M", QEMU_CAPS_OBJECT_MEMORY_FILE);
+ DO_TEST("hugepages-numa-default-dimm", QEMU_CAPS_OBJECT_MEMORY_FILE);
+ DO_TEST("hugepages-numa-nodeset", QEMU_CAPS_OBJECT_MEMORY_FILE);
+ DO_TEST("hugepages-numa-nodeset-part", QEMU_CAPS_OBJECT_MEMORY_FILE);
+ DO_TEST("hugepages-shared", QEMU_CAPS_OBJECT_MEMORY_FILE);
+ DO_TEST("hugepages-memaccess", QEMU_CAPS_OBJECT_MEMORY_FILE);
+ DO_TEST("hugepages-memaccess2", QEMU_CAPS_OBJECT_MEMORY_FILE);
+ DO_TEST("hugepages-nvdimm", QEMU_CAPS_DEVICE_NVDIMM,
+ QEMU_CAPS_OBJECT_MEMORY_FILE);
DO_TEST("nosharepages", NONE);
DO_TEST("restore-v2", NONE);
DO_TEST("migrate", NONE);
@@ -490,7 +491,8 @@ mymain(void)
DO_TEST("event_idx", NONE);
DO_TEST("vhost_queues", NONE);
DO_TEST("interface-driver", NONE);
- DO_TEST("interface-server", QEMU_CAPS_DEVICE_CIRRUS_VGA);
+ DO_TEST("interface-server", QEMU_CAPS_DEVICE_CIRRUS_VGA,
+ QEMU_CAPS_OBJECT_MEMORY_FILE);
DO_TEST("virtio-lun", NONE);
DO_TEST("usb-none", NONE);
@@ -538,7 +540,8 @@ mymain(void)
DO_TEST("seclabel-dynamic-none", NONE);
DO_TEST("seclabel-device-multiple", NONE);
DO_TEST_FULL("seclabel-dynamic-none-relabel", WHEN_INACTIVE,
- ARG_QEMU_CAPS, QEMU_CAPS_DEVICE_CIRRUS_VGA, NONE);
+ ARG_QEMU_CAPS, QEMU_CAPS_DEVICE_CIRRUS_VGA,
+ QEMU_CAPS_OBJECT_MEMORY_FILE, NONE);
DO_TEST("numad-static-vcpu-no-numatune", NONE);
DO_TEST("disk-scsi-lun-passthrough-sgio",
@@ -572,7 +575,8 @@ mymain(void)
DO_TEST("pseries-phb-numa-node",
QEMU_CAPS_NUMA,
QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE,
- QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE);
+ QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE,
+ QEMU_CAPS_OBJECT_MEMORY_FILE);
DO_TEST("pseries-many-devices",
QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE,
@@ -1006,12 +1010,12 @@ mymain(void)
DO_TEST("cpu-numa2", NONE);
DO_TEST("cpu-numa-no-memory-element", NONE);
DO_TEST("cpu-numa-disordered", NONE);
- DO_TEST("cpu-numa-disjoint", NONE);
- DO_TEST("cpu-numa-memshared", NONE);
+ DO_TEST("cpu-numa-disjoint", QEMU_CAPS_NUMA);
+ DO_TEST("cpu-numa-memshared", QEMU_CAPS_OBJECT_MEMORY_FILE);
DO_TEST("numatune-auto-prefer", NONE);
- DO_TEST("numatune-memnode", NONE);
- DO_TEST("numatune-memnode-no-memory", NONE);
+ DO_TEST("numatune-memnode", QEMU_CAPS_NUMA, QEMU_CAPS_OBJECT_MEMORY_FILE);
+ DO_TEST("numatune-memnode-no-memory", QEMU_CAPS_OBJECT_MEMORY_FILE);
DO_TEST("bios-nvram", NONE);
DO_TEST("bios-nvram-os-interleave", NONE);
@@ -1200,10 +1204,12 @@ mymain(void)
DO_TEST("memfd-memory-numa",
QEMU_CAPS_OBJECT_MEMORY_MEMFD,
- QEMU_CAPS_OBJECT_MEMORY_MEMFD_HUGETLB);
+ QEMU_CAPS_OBJECT_MEMORY_MEMFD_HUGETLB,
+ QEMU_CAPS_OBJECT_MEMORY_FILE);
DO_TEST("memfd-memory-default-hugepage",
QEMU_CAPS_OBJECT_MEMORY_MEMFD,
- QEMU_CAPS_OBJECT_MEMORY_MEMFD_HUGETLB);
+ QEMU_CAPS_OBJECT_MEMORY_MEMFD_HUGETLB,
+ QEMU_CAPS_OBJECT_MEMORY_FILE);
DO_TEST("acpi-table", NONE);
@@ -1264,7 +1270,8 @@ mymain(void)
DO_TEST("user-aliases",
QEMU_CAPS_DEVICE_CIRRUS_VGA,
- QEMU_CAPS_QCOW2_LUKS);
+ QEMU_CAPS_QCOW2_LUKS,
+ QEMU_CAPS_OBJECT_MEMORY_FILE);
DO_TEST("input-virtio-ccw",
QEMU_CAPS_CCW,
QEMU_CAPS_VIRTIO_KEYBOARD,
--
2.23.0