]> xenbits.xensource.com Git - libvirt.git/commitdiff
conf: Don't always recalculate initial memory size from NUMA size totals
authorPeter Krempa <pkrempa@redhat.com>
Fri, 18 Sep 2015 15:24:32 +0000 (17:24 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 22 Sep 2015 14:09:28 +0000 (16:09 +0200)
When implementing memory hotplug I've opted to recalculate the initial
memory size (contents of the <memory> element) as a sum of the sizes of
NUMA nodes when NUMA was enabled. This was based on an assumption that
qemu did not allow starting when the NUMA node size total didn't equal
to the initial memory size. Unfortunately the check was introduced to
qemu just lately.

This patch uses the new XML parser flag to decide whether it's safe to
update the memory size total from the NUMA cell sizes or not.

As an additional improvement we now report an error in case when the
size of hotplug memory would exceed the total memory size.

The rest of the changes assures that the function is called with correct
flags.

src/conf/domain_conf.c
src/conf/domain_conf.h
src/qemu/qemu_command.c

index 2cc03d92acedf55a94ca317525a2233da94f45c8..2c723f97be8d8827b6a521742b094225020d8c33 100644 (file)
@@ -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 <memory> 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 */
index ab250bd1be6b38ec8ee3335998c9be557953a694..25914b47b33b5a88edf6ac2fbe2ed7951c693c12 100644 (file)
@@ -2459,6 +2459,7 @@ virDomainXMLOptionGetNamespace(virDomainXMLOptionPtr xmlopt)
 int
 virDomainDefPostParse(virDomainDefPtr def,
                       virCapsPtr caps,
+                      unsigned int parseFlags,
                       virDomainXMLOptionPtr xmlopt);
 
 static inline bool
index 3044b11b205323081ba2f1f4d916ca6048beae16..7a1c9feaf714bf2c825b3ab1fe9b62d454bc41c2 100644 (file)
@@ -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) {