}
+/**
+ * qemuDomainDefNumaCPUsRectify:
+ * @numa: pointer to numa definition
+ * @maxCpus: number of CPUs this numa is supposed to have
+ *
+ * This function emulates the (to be deprecated) behavior of filling
+ * up in node0 with the remaining CPUs, in case of an incomplete NUMA
+ * setup, up to getVcpusMax.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+int
+qemuDomainDefNumaCPUsRectify(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
+{
+ unsigned int vcpusMax, numacpus;
+
+ /* QEMU_CAPS_NUMA tells us if QEMU is able to handle disjointed
+ * NUMA CPU ranges. The filling process will create a disjointed
+ * setup in node0 most of the time. Do not proceed if QEMU
+ * can't handle it.*/
+ if (virDomainNumaGetNodeCount(def->numa) == 0 ||
+ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_NUMA))
+ return 0;
+
+ vcpusMax = virDomainDefGetVcpusMax(def);
+ numacpus = virDomainNumaGetCPUCountTotal(def->numa);
+
+ if (numacpus < vcpusMax) {
+ if (virDomainNumaFillCPUsInNode(def->numa, 0, vcpusMax) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int
+qemuDomainDefNumaCPUsPostParse(virDomainDefPtr def,
+ virQEMUCapsPtr qemuCaps)
+{
+ return qemuDomainDefNumaCPUsRectify(def, qemuCaps);
+}
+
+
static int
qemuDomainDefPostParseBasic(virDomainDefPtr def,
void *opaque G_GNUC_UNUSED)
if (qemuDomainDefTsegPostParse(def, qemuCaps) < 0)
return -1;
+ if (qemuDomainDefNumaCPUsPostParse(def, qemuCaps) < 0)
+ return -1;
+
return 0;
}
static int
qemuDomainSetVcpusMax(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
virDomainDefPtr def,
virDomainDefPtr persistentDef,
unsigned int nvcpus)
{
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+ qemuDomainObjPrivatePtr priv = vm->privateData;
unsigned int topologycpus;
if (def) {
if (virDomainDefSetVcpusMax(persistentDef, nvcpus, driver->xmlopt) < 0)
return -1;
+ if (qemuDomainDefNumaCPUsRectify(persistentDef, priv->qemuCaps) < 0)
+ return -1;
+
if (virDomainDefSave(persistentDef, driver->xmlopt, cfg->configDir) < 0)
return -1;
if (useAgent)
ret = qemuDomainSetVcpusAgent(vm, nvcpus);
else if (flags & VIR_DOMAIN_VCPU_MAXIMUM)
- ret = qemuDomainSetVcpusMax(driver, def, persistentDef, nvcpus);
+ ret = qemuDomainSetVcpusMax(driver, vm, def, persistentDef, nvcpus);
else
ret = qemuDomainSetVcpusInternal(driver, vm, def, persistentDef,
nvcpus, hotpluggable);