[Kimchi-devel] [PATCH 2/3][Kimchi] Issue #753: Adds max_memory checkings and settings properly

Rodrigo Trujillo rodrigo.trujillo at linux.vnet.ibm.com
Wed Dec 16 13:25:48 UTC 2015


When Kimchi creates a new template, it is recording the value of
max_memory. This value is related to host and guest memory assigned or
updated. If the value remains in objectstore, Kimchi will always use
it, what is wrong, since host total memory or guest memory can change,
and this should update max_memory value as well.

This patch includes a new memory test during Template creation.
An error will be raised if memory greater than max memory allowed.
It also adds max memory settings to vmtemplate.py

Signed-off-by: Rodrigo Trujillo <rodrigo.trujillo at linux.vnet.ibm.com>
---
 i18n.py            |  2 +-
 model/templates.py |  5 +++++
 model/vms.py       |  6 +++---
 vmtemplate.py      | 39 ++++++++++++++++++++++++++++++++-------
 4 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/i18n.py b/i18n.py
index 96729ef..7c96d73 100644
--- a/i18n.py
+++ b/i18n.py
@@ -99,7 +99,7 @@ messages = {
     "KCHVM0038E": _("Unable to suspend VM '%(name)s'. Details: %(err)s"),
     "KCHVM0039E": _("Cannot resume VM '%(name)s' because it is not paused."),
     "KCHVM0040E": _("Unable to resume VM '%(name)s'. Details: %(err)s"),
-    "KCHVM0041E": _("Memory assigned is higher then the maximum allowed in the host."),
+    "KCHVM0041E": _("Memory assigned is higher then the maximum allowed in the host: %(maxmem)sMib."),
     "KCHVM0042E": _("VM '%(name)s' does not support live memory update. Update the memory with the machine offline to enable this feature."),
     "KCHVM0043E": _("Only increase memory is allowed in active VMs"),
     "KCHVM0044E": _("For live memory update, new memory value must be equal old memory value plus multiples of 1024 Mib"),
diff --git a/model/templates.py b/model/templates.py
index 84cdd02..c9b11c3 100644
--- a/model/templates.py
+++ b/model/templates.py
@@ -82,6 +82,11 @@ class TemplatesModel(object):
         # will be raised here
         t = LibvirtVMTemplate(params, scan=True, conn=self.conn)
 
+        # Validate max memory
+        maxMem = (t._get_max_memory(t.info.get('memory')) >> 10)
+        if t.info.get('memory') > maxMem:
+            raise OperationFailed("KCHVM0041E", {'maxmem': str(maxMem)})
+
         # Validate volumes
         for disk in t.info.get('disks'):
             volume = disk.get('volume')
diff --git a/model/vms.py b/model/vms.py
index 47dd0ce..3faee5a 100644
--- a/model/vms.py
+++ b/model/vms.py
@@ -48,7 +48,6 @@ from wok.plugins.kimchi import model
 from wok.plugins.kimchi import vnc
 from wok.plugins.kimchi.config import READONLY_POOL_TYPE, get_kimchi_version
 from wok.plugins.kimchi.kvmusertests import UserTests
-from wok.plugins.kimchi.osinfo import PPC_MEM_ALIGN
 from wok.plugins.kimchi.model.config import CapabilitiesModel
 from wok.plugins.kimchi.model.cpuinfo import CPUInfoModel
 from wok.plugins.kimchi.model.featuretests import FeatureTests
@@ -57,9 +56,9 @@ from wok.plugins.kimchi.model.utils import get_ascii_nonascii_name, get_vm_name
 from wok.plugins.kimchi.model.utils import get_metadata_node
 from wok.plugins.kimchi.model.utils import remove_metadata_node
 from wok.plugins.kimchi.model.utils import set_metadata_node
-from wok.plugins.kimchi.osinfo import MAX_MEM_LIM
 from wok.plugins.kimchi.screenshot import VMScreenshot
 from wok.plugins.kimchi.utils import template_name_from_uri
+from wok.plugins.kimchi.vmtemplate import MAX_MEM_LIM, PPC_MEM_ALIGN
 from wok.plugins.kimchi.xmlutils.cpu import get_cpu_xml, get_numa_xml
 from wok.plugins.kimchi.xmlutils.disk import get_vm_disk_info, get_vm_disks
 
@@ -887,7 +886,8 @@ class VMModel(object):
                 slots = (maxMem - params['memory']) >> 10
                 # Libvirt does not accepts slots <= 1
                 if slots < 0:
-                    raise OperationFailed("KCHVM0041E")
+                    raise OperationFailed("KCHVM0041E",
+                                          {'maxmem': str(maxMem)})
                 elif slots == 0:
                     slots = 1
 
diff --git a/vmtemplate.py b/vmtemplate.py
index 5c6a8d8..d629226 100644
--- a/vmtemplate.py
+++ b/vmtemplate.py
@@ -19,6 +19,7 @@
 
 import os
 import platform
+import psutil
 import stat
 import time
 import urlparse
@@ -41,6 +42,12 @@ from wok.plugins.kimchi.xmlutils.qemucmdline import get_qemucmdline_xml
 from wok.plugins.kimchi.xmlutils.serial import get_serial_xml
 
 
+# In PowerPC, memories must be aligned to 256 MiB
+PPC_MEM_ALIGN = 256
+# Max memory 1TB, in KiB
+MAX_MEM_LIM = 1073741824
+
+
 class VMTemplate(object):
     def __init__(self, args, scan=False):
         """
@@ -324,6 +331,27 @@ class VMTemplate(object):
                            self.info.get('memory') << 10,
                            cpu_topo)
 
+    def _get_max_memory(self, guest_memory):
+        # Setting maxMemory of the VM, which will be lesser value between:
+        # 1TB,  (Template Memory * 4),  Host Physical Memory.
+        max_memory = MAX_MEM_LIM
+        if hasattr(psutil, 'virtual_memory'):
+            host_memory = psutil.virtual_memory().total >> 10
+        else:
+            host_memory = psutil.TOTAL_PHYMEM >> 10
+        if host_memory < max_memory:
+            max_memory = host_memory
+        if (((guest_memory * 4) << 10) < max_memory):
+            max_memory = (guest_memory * 4) << 10
+
+        # set up arch to ppc64 instead of ppc64le due to libvirt compatibility
+        if self.info["arch"] == "ppc64":
+            # in Power, memory must be aligned in 256MiB
+            if (max_memory >> 10) % PPC_MEM_ALIGN != 0:
+                alignment = max_memory % (PPC_MEM_ALIGN << 10)
+                max_memory -= alignment
+        return max_memory
+
     def to_vm_xml(self, vm_name, vm_uuid, **kwargs):
         params = dict(self.info)
         params['name'] = vm_name
@@ -352,12 +380,8 @@ class VMTemplate(object):
         else:
             params['cdroms'] = cdrom_xml
 
-        # In order to avoid problems with live migration, setting maxMemory of
-        # the VM, which will be lesser value between:
-        # [ 1TB,  (Template Memory * 4),  Host Physical Memory.
-        tmp_max_mem = (params['memory'] << 10) * 4
-        if tmp_max_mem < params['max_memory']:
-            params['max_memory'] = tmp_max_mem
+        # max memory
+        params['max_memory'] = self._get_max_memory(params['memory'])
 
         # Setting maximum number of slots to avoid errors when hotplug memory
         # Number of slots are the numbers of chunks of 1GB that fit inside
@@ -366,7 +390,8 @@ class VMTemplate(object):
         params['slots'] = ((params['max_memory'] >> 10) -
                            params['memory']) >> 10
         if params['slots'] < 0:
-            raise OperationFailed("KCHVM0041E")
+            raise OperationFailed("KCHVM0041E",
+                                  {'maxmem': str(params['max_memory'] >> 10)})
         elif params['slots'] == 0:
             params['slots'] = 1
         elif params['slots'] > 32:
-- 
2.1.0




More information about the Kimchi-devel mailing list