[Kimchi-devel] [PATCH] [Kimchi 2/5] CPU Hot plug/unplug: model changes

dhbarboza82 at gmail.com dhbarboza82 at gmail.com
Thu Nov 24 10:57:28 UTC 2016


From: Daniel Henrique Barboza <danielhb at linux.vnet.ibm.com>

This patch makes changes on model/vms.py to support
the hotplug of new CPUs in a running VM.

For CPU Hot unplug in Power hypervisors there is a need
for guest software to be installed:

* guest must have packages: powerpc-utils, ppc64-diag, librtas
* guest must have service rtas_err.service running

Signed-off-by: Daniel Henrique Barboza <danielhb at linux.vnet.ibm.com>
---
 model/vms.py | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 58 insertions(+), 8 deletions(-)

diff --git a/model/vms.py b/model/vms.py
index bff7ed2..d703c89 100644
--- a/model/vms.py
+++ b/model/vms.py
@@ -82,7 +82,8 @@ DOM_STATE_MAP = {0: 'nostate',
                  7: 'pmsuspended'}
 
 # update parameters which are updatable when the VM is online
-VM_ONLINE_UPDATE_PARAMS = ['graphics', 'groups', 'memory', 'users']
+VM_ONLINE_UPDATE_PARAMS = ['cpu_info', 'graphics', 'groups',
+                           'memory', 'users']
 
 # update parameters which are updatable when the VM is offline
 VM_OFFLINE_UPDATE_PARAMS = ['cpu_info', 'graphics', 'groups', 'memory',
@@ -1028,18 +1029,33 @@ class VMModel(object):
                                                unit='Kib'))
         return ET.tostring(root, encoding="utf-8")
 
-    def _update_cpu_info(self, new_xml, dom, new_info):
+    def get_vm_cpu_cores(self, vm_xml):
+        return xpath_get_text(vm_xml, XPATH_TOPOLOGY + '/@cores')[0]
+
+    def get_vm_cpu_sockets(self, vm_xml):
+        return xpath_get_text(vm_xml, XPATH_TOPOLOGY + '/@sockets')[0]
+
+    def get_vm_cpu_threads(self, vm_xml):
+        return xpath_get_text(vm_xml, XPATH_TOPOLOGY + '/@threads')[0]
+
+    def get_vm_cpu_topology(self, dom):
         topology = {}
         if self.has_topology(dom):
-            sockets = xpath_get_text(new_xml, XPATH_TOPOLOGY + '/@sockets')[0]
-            cores = xpath_get_text(new_xml, XPATH_TOPOLOGY + '/@cores')[0]
-            threads = xpath_get_text(new_xml, XPATH_TOPOLOGY + '/@threads')[0]
+            sockets = int(self.get_vm_cpu_sockets(dom.XMLDesc(0)))
+            cores = int(self.get_vm_cpu_cores(dom.XMLDesc(0)))
+            threads = int(self.get_vm_cpu_threads(dom.XMLDesc(0)))
+
             topology = {
-                'sockets': int(sockets),
-                'cores': int(cores),
-                'threads': int(threads),
+                'sockets': sockets,
+                'cores': cores,
+                'threads': threads,
             }
 
+        return topology
+
+    def _update_cpu_info(self, new_xml, dom, new_info):
+        topology = self.get_vm_cpu_topology(dom)
+
         # if current is not defined in vcpu, vcpus is equal to maxvcpus
         xml_maxvcpus = xpath_get_text(new_xml, 'vcpu')
         maxvcpus = int(xml_maxvcpus[0])
@@ -1064,6 +1080,40 @@ class VMModel(object):
         if (('memory' in params) and ('current' in params['memory'])):
             self._update_memory_live(dom, params)
 
+        if 'vcpus' in params.get('cpu_info', {}):
+            self.cpu_hotplug_precheck(dom, params)
+            vcpus = params['cpu_info'].get('vcpus')
+            self.update_cpu_live(dom, vcpus)
+
+    def cpu_hotplug_precheck(self, dom, params):
+
+        if (('maxvcpus' in params['cpu_info']) or
+                ('topology' in params['cpu_info'])):
+            raise InvalidParameter('KCHCPUHOTP0001E')
+
+        topology = self.get_vm_cpu_topology(dom)
+
+        xml_maxvcpus = xpath_get_text(dom.XMLDesc(0), 'vcpu')
+        maxvcpus = int(xml_maxvcpus[0])
+        vcpus = params['cpu_info'].get('vcpus')
+
+        cpu_info = {
+            'maxvcpus': maxvcpus,
+            'vcpus': vcpus,
+            'topology': topology,
+        }
+
+        cpu_model = CPUInfoModel(conn=self.conn)
+        cpu_model.check_cpu_info(cpu_info)
+
+    def update_cpu_live(self, dom, vcpus):
+        flags = libvirt.VIR_DOMAIN_AFFECT_LIVE | \
+                libvirt.VIR_DOMAIN_AFFECT_CONFIG
+        try:
+            dom.setVcpusFlags(vcpus, flags)
+        except libvirt.libvirtError as e:
+            raise OperationFailed('KCHCPUHOTP0002E', {'err': e.message})
+
     def _get_mem_dev_total_size(self, xml):
         root = ET.fromstring(xml)
         totMemDevs = 0
-- 
2.7.4




More information about the Kimchi-devel mailing list