diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 2cc03d92acedf55a94ca317525a2233da94f45c8..2c723f97be8d8827b6a521742b094225020d8c33 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3726,15 +3726,34 @@ virDomainDefRemoveDuplicateMetadata(virDomainDefPtr def) static int -virDomainDefPostParseMemory(virDomainDefPtr def) +virDomainDefPostParseMemory(virDomainDefPtr def, + unsigned int parseFlags) { size_t i; + unsigned long long numaMemory = 0; + unsigned long long hotplugMemory = 0; - if ((def->mem.initial_memory = virDomainNumaGetMemorySize(def->numa)) == 0) { - def->mem.initial_memory = def->mem.total_memory; + /* Attempt to infer the initial memory size from the sum NUMA memory sizes + * in case ABI updates are allowed or the element wasn't specified */ + if (def->mem.total_memory == 0 || + parseFlags & VIR_DOMAIN_DEF_PARSE_ABI_UPDATE) + numaMemory = virDomainNumaGetMemorySize(def->numa); + if (numaMemory) { + virDomainDefSetMemoryInitial(def, numaMemory); + } else { + /* calculate the sizes of hotplug memory */ for (i = 0; i < def->nmems; i++) - def->mem.initial_memory -= def->mems[i]->size; + hotplugMemory += def->mems[i]->size; + + if (hotplugMemory > def->mem.total_memory) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Total size of memory devices exceeds the total " + "memory size")); + return -1; + } + + virDomainDefSetMemoryInitial(def, def->mem.total_memory - hotplugMemory); } if (virDomainDefGetMemoryInitial(def) == 0) { @@ -3770,7 +3789,8 @@ virDomainDefPostParseMemory(virDomainDefPtr def) static int virDomainDefPostParseInternal(virDomainDefPtr def, - virCapsPtr caps ATTRIBUTE_UNUSED) + virCapsPtr caps ATTRIBUTE_UNUSED, + unsigned int parseFlags) { size_t i; @@ -3781,7 +3801,7 @@ virDomainDefPostParseInternal(virDomainDefPtr def, return -1; } - if (virDomainDefPostParseMemory(def) < 0) + if (virDomainDefPostParseMemory(def, parseFlags) < 0) return -1; /* @@ -4274,6 +4294,7 @@ virDomainDefPostParseDeviceIterator(virDomainDefPtr def ATTRIBUTE_UNUSED, int virDomainDefPostParse(virDomainDefPtr def, virCapsPtr caps, + unsigned int parseFlags, virDomainXMLOptionPtr xmlopt) { int ret; @@ -4299,7 +4320,7 @@ virDomainDefPostParse(virDomainDefPtr def, return ret; - if ((ret = virDomainDefPostParseInternal(def, caps)) < 0) + if ((ret = virDomainDefPostParseInternal(def, caps, parseFlags)) < 0) return ret; return 0; @@ -16426,7 +16447,7 @@ virDomainDefParseXML(xmlDocPtr xml, goto error; /* callback to fill driver specific domain aspects */ - if (virDomainDefPostParse(def, caps, xmlopt) < 0) + if (virDomainDefPostParse(def, caps, flags, xmlopt) < 0) goto error; /* Auto-add any implied controllers which aren't present */ diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index ab250bd1be6b38ec8ee3335998c9be557953a694..25914b47b33b5a88edf6ac2fbe2ed7951c693c12 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2459,6 +2459,7 @@ virDomainXMLOptionGetNamespace(virDomainXMLOptionPtr xmlopt) int virDomainDefPostParse(virDomainDefPtr def, virCapsPtr caps, + unsigned int parseFlags, virDomainXMLOptionPtr xmlopt); static inline bool diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 3044b11b205323081ba2f1f4d916ca6048beae16..7a1c9feaf714bf2c825b3ab1fe9b62d454bc41c2 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -13958,7 +13958,8 @@ qemuParseCommandLine(virCapsPtr qemuCaps, if (virDomainDefAddImplicitControllers(def) < 0) goto error; - if (virDomainDefPostParse(def, qemuCaps, xmlopt) < 0) + if (virDomainDefPostParse(def, qemuCaps, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE, + xmlopt) < 0) goto error; if (cmd->num_args || cmd->num_env) {