[Kimchi-devel] [PATCH][Kimchi 1/2] Change memory hotplug to support more than 32GB

Rodrigo Trujillo rodrigo.trujillo at linux.vnet.ibm.com
Thu May 19 12:17:49 UTC 2016


Please, ignore this patch

Rodrigo

On 05/17/2016 04:15 PM, Rodrigo Trujillo wrote:
> This patch removes the restriction of only allow 32 memory devices
> of 1GB. Now, Kimchi is going to add an unique memory device with the
> amount of memory to be increased (per request).
>
> Signed-off-by: Rodrigo Trujillo <rodrigo.trujillo at linux.vnet.ibm.com>
> ---
>   i18n.py      |  3 +--
>   model/vms.py | 81 ++++++++++++++++++++++++++----------------------------------
>   2 files changed, 36 insertions(+), 48 deletions(-)
>
> diff --git a/i18n.py b/i18n.py
> index 2301e60..9f40298 100644
> --- a/i18n.py
> +++ b/i18n.py
> @@ -97,8 +97,7 @@ messages = {
>       "KCHVM0041E": _("Memory assigned is higher then the maximum allowed in the host: %(maxmem)sMib."),
>       "KCHVM0042E": _("Guest '%(name)s' does not support live memory update. Please, with the guest offline, set Maximum Memory with a value greater then Memory 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"),
> -    "KCHVM0045E": _("There are not enough free slots of 1024 Mib in the guest."),
> +    "KCHVM0045E": _("There are not enough free slots to add a new memory device."),
>       "KCHVM0046E": _("Host's libvirt or qemu version does not support memory devices and memory hotplug. Libvirt must be >= 1.2.14 and QEMU must be >= 2.1."),
>       "KCHVM0047E": _("Error attaching memory device. Details: %(error)s"),
>       "KCHVM0048E": _("Cannot start %(name)s. Virtual machine is already running."),
> diff --git a/model/vms.py b/model/vms.py
> index ef53e38..ae77d3d 100644
> --- a/model/vms.py
> +++ b/model/vms.py
> @@ -971,6 +971,15 @@ class VMModel(object):
>              dom.isActive()):
>               self._update_memory_live(dom, params)
>
> +    def _get_mem_dev_total_size(self, xml):
> +        root = ET.fromstring(xml)
> +        totMemDevs = 0
> +        for size in root.findall('./devices/memory/target/size'):
> +            totMemDevs += convert_data_size(size.text,
> +                                            size.get('unit'),
> +                                            'MiB')
> +        return totMemDevs
> +
>       def _update_memory_live(self, dom, params):
>           # Check if host supports memory device
>           if not self.caps.mem_hotplug_support:
> @@ -979,56 +988,42 @@ class VMModel(object):
>           xml = dom.XMLDesc(0)
>           max_mem = xpath_get_text(xml, './maxMemory')
>           if max_mem == []:
> -            raise OperationFailed('KCHVM0042E', {'name': dom.name()})
> +            raise InvalidOperation('KCHVM0042E', {'name': dom.name()})
>
> -        # Memory live update must be done in chunks of 1024 Mib or 1Gib
>           new_mem = params['memory']['current']
>           old_mem = int(xpath_get_text(xml, XPATH_DOMAIN_MEMORY)[0]) >> 10
> -        if new_mem < old_mem:
> -            raise OperationFailed('KCHVM0043E')
> -        if (new_mem - old_mem) % 1024 != 0:
> -            raise OperationFailed('KCHVM0044E')
> +        memory = new_mem - old_mem
> +        flags = libvirt.VIR_DOMAIN_MEM_CONFIG | libvirt.VIR_DOMAIN_MEM_LIVE
>
> -        # make sure memory is alingned in 256MiB in PowerPC
>           distro, _, _ = platform.linux_distribution()
> -        if (distro == "IBM_PowerKVM" and new_mem % PPC_MEM_ALIGN != 0):
> -            raise InvalidParameter('KCHVM0071E',
> -                                   {'param': "Memory",
> -                                    'mem': str(new_mem),
> -                                    'alignment': str(PPC_MEM_ALIGN)})
> -
> -        # Check slot spaces:
> -        total_slots = int(xpath_get_text(xml, './maxMemory/@slots')[0])
> -        needed_slots = (new_mem - old_mem) >> 10
> -        used_slots = len(xpath_get_text(xml, './devices/memory'))
> -        if needed_slots > (total_slots - used_slots):
> -            raise OperationFailed('KCHVM0045E')
> -        elif needed_slots == 0:
> -            # New memory value is same that current memory set
> +        if distro == "IBM_PowerKVM":
> +            # make sure memory is alingned in 256MiB in PowerPC
> +            if (new_mem % PPC_MEM_ALIGN != 0):
> +                raise InvalidParameter('KCHVM0071E',
> +                                       {'param': "Memory",
> +                                        'mem': str(new_mem),
> +                                        'alignment': str(PPC_MEM_ALIGN)})
> +            # PPC suports only 32 memory slots
> +            if len(xpath_get_text(xml, './devices/memory')) == 32:
> +                raise InvalidOperation('KCHVM0045E')
> +
> +        if memory == 0:
> +            # Nothing to do
>               return
> +        if memory < 0:
> +            raise InvalidOperation('KCHVM0043E')
>
> -        distro, _, _ = platform.linux_distribution()
> -        if distro == "IBM_PowerKVM" and needed_slots > 32:
> -            raise OperationFailed('KCHVM0045E')
> -
> -        # Finally, we are ok to hot add the memory devices
> +        # Finally HotPlug operation ( memory > 0 )
>           try:
> -            self._hot_add_memory_devices(dom, needed_slots)
> +            # Create memory device xml
> +            tmp_xml = E.memory(E.target(E.size(str(memory),
> +                                        unit='MiB')), model='dimm')
> +            if has_cpu_numa(dom):
> +                tmp_xml.find('target').append(E.node('0'))
> +            dom.attachDeviceFlags(etree.tostring(tmp_xml), flags)
>           except Exception as e:
>               raise OperationFailed("KCHVM0047E", {'error': e.message})
>
> -    def _hot_add_memory_devices(self, dom, amount):
> -        # Hot add given number of memory devices in the guest
> -        flags = libvirt.VIR_DOMAIN_MEM_CONFIG | libvirt.VIR_DOMAIN_MEM_LIVE
> -        # Create memory device xml
> -        tmp_xml = E.memory(E.target(E.size('1', unit='GiB')), model='dimm')
> -        if has_cpu_numa(dom):
> -            tmp_xml.find('target').append(E.node('0'))
> -        mem_dev_xml = etree.tostring(tmp_xml)
> -        # Add chunks of 1G of memory
> -        for i in range(amount):
> -            dom.attachDeviceFlags(mem_dev_xml, flags)
> -
>       def _has_video(self, dom):
>           dom = ElementTree.fromstring(dom.XMLDesc(0))
>           return dom.find('devices/video') is not None
> @@ -1217,13 +1212,7 @@ class VMModel(object):
>           memory = dom.maxMemory() >> 10
>           curr_mem = (info[2] >> 10)
>           if memory != curr_mem:
> -            root = ET.fromstring(xml)
> -            totMemDevs = 0
> -            for size in root.findall('./devices/memory/target/size'):
> -                totMemDevs += convert_data_size(size.text,
> -                                                size.get('unit'),
> -                                                'MiB')
> -            memory = curr_mem + totMemDevs
> +            memory = curr_mem + self._get_mem_dev_total_size(xml)
>
>           # assure there is no zombie process left
>           for proc in self._serial_procs[:]:




More information about the Kimchi-devel mailing list