In order to support memory hotplug, guest must have maxMemory and NUMA
configured in the xml.
For maxMemory, this patch changes xml generation at guest creation
time, adding maxMemory equals to host total memory and memory slots as
the integer number of GiB that fit inside maxMemory (by design users
will be allowed to add only memory chunks of 1GB).
For NUMA, this patch adds the simplest configuration possible, creating
only one node with all vcpus and memory set in the template.
Signed-off-by: Rodrigo Trujillo <rodrigo.trujillo(a)linux.vnet.ibm.com>
---
src/kimchi/model/vms.py | 8 ++++++++
src/kimchi/vmtemplate.py | 29 +++++++++++++++++++----------
2 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/src/kimchi/model/vms.py b/src/kimchi/model/vms.py
index f0182b9..dc7f91f 100644
--- a/src/kimchi/model/vms.py
+++ b/src/kimchi/model/vms.py
@@ -94,6 +94,14 @@ class VMsModel(object):
if pool_uri:
vm_overrides['storagepool'] = pool_uri
vm_overrides['fc_host_support'] = self.caps.fc_host_support
+
+ # Setting maxMemory and slots parameter values
+ # getInfo memory value comes in MiB, so dividing by 1024 integer,
+ # gives the interger maximum number of slots to use in chunks of
+ # 1 GB
+ vm_overrides['max_memory'] = self.conn.get().getInfo()[1] * 1024
+ vm_overrides['slots'] = self.conn.get().getInfo()[1] / 1024
+
t = TemplateModel.get_template(t_name, self.objstore, self.conn,
vm_overrides)
diff --git a/src/kimchi/vmtemplate.py b/src/kimchi/vmtemplate.py
index e047228..a20098d 100644
--- a/src/kimchi/vmtemplate.py
+++ b/src/kimchi/vmtemplate.py
@@ -270,17 +270,25 @@ class VMTemplate(object):
return input_output
def _get_cpu_xml(self):
-
+ # NUMA configuration. Necessary for memory hotplug
+ cpus = self.info.get('cpus') - 1
+ xml = E.cpu(E.numa(E.cell(
+ id='0',
+ cpus='0-' + str(cpus) if cpus > 0 else '0',
+ memory=str(self.info.get('memory') << 10),
+ unit='KiB')))
+
+ # Include CPU topology, if provided
cpu_info = self.info.get('cpu_info')
- if cpu_info is None:
- return ""
- cpu_topo = cpu_info.get('topology')
- if cpu_topo is None:
- return ""
- return etree.tostring(E.cpu(E.topology(
- sockets=str(cpu_topo['sockets']),
- cores=str(cpu_topo['cores']),
- threads=str(cpu_topo['threads']))))
+ if cpu_info is not None:
+ cpu_topo = cpu_info.get('topology')
+ if cpu_topo is not None:
+ xml.insert(0, E.topology(
+ sockets=str(cpu_topo['sockets']),
+ cores=str(cpu_topo['cores']),
+ threads=str(cpu_topo['threads'])))
+
+ return etree.tostring(xml)
def to_vm_xml(self, vm_name, vm_uuid, **kwargs):
params = dict(self.info)
@@ -313,6 +321,7 @@ class VMTemplate(object):
%(qemu-stream-cmdline)s
<name>%(name)s</name>
<uuid>%(uuid)s</uuid>
+ <maxMemory slots='%(slots)s'
unit='KiB'>%(max_memory)s</maxMemory>
<memory unit='MiB'>%(memory)s</memory>
<vcpu>%(cpus)s</vcpu>
%(cpu_info)s
--
2.1.0