Ensure SR-IOV NIC states are updated on migration
This commit is contained in:
		| @@ -555,6 +555,33 @@ def disable_vm(zkhandler, domain): | ||||
|     return True, 'Marked VM "{}" as disable.'.format(domain) | ||||
|  | ||||
|  | ||||
| def update_vm_sriov_nics(zkhandler, dom_uuid, source_node, target_node): | ||||
|     # Update all the SR-IOV device states on both nodes, used during migrations but called by the node-side | ||||
|     vm_config = zkhandler.read(('domain.xml', dom_uuid)) | ||||
|     parsed_xml = lxml.objectify.fromstring(vm_config) | ||||
|     dnetworks = common.getDomainNetworks(parsed_xml, {}) | ||||
|     retcode = True | ||||
|     retmsg = '' | ||||
|     for network in dnetworks: | ||||
|         if network['type'] in ['direct', 'hostdev']: | ||||
|             # Check if the network is already in use | ||||
|             is_used = zkhandler.read(('node.sriov.vf', target_node, 'sriov_vf.used', network['source'])) | ||||
|             if is_used == 'True': | ||||
|                 used_by_name = searchClusterByUUID(zkhandler, zkhandler.read(('node.sriov.vf', target_node, 'sriov_vf.used_by', network['source']))) | ||||
|                 if retcode: | ||||
|                     retcode = False | ||||
|                     retmsg = 'Attempting to use SR-IOV network "{}" which is already used by VM "{}"'.format(network['source'], used_by_name) | ||||
|  | ||||
|             # We must update the "used" section | ||||
|             if retcode: | ||||
|                 # This conditional ensure that if we failed the is_used check, we don't try to overwrite the information of a VF that belongs to another VM | ||||
|                 set_sriov_vf_vm(zkhandler, dom_uuid, target_node, network['source'], network['mac'], network['type']) | ||||
|             # ... but we still want to free the old node in an case | ||||
|             unset_sriov_vf_vm(zkhandler, source_node, network['source']) | ||||
|  | ||||
|     return retcode, retmsg | ||||
|  | ||||
|  | ||||
| def move_vm(zkhandler, domain, target_node, wait=False, force_live=False): | ||||
|     # Validate that VM exists in cluster | ||||
|     dom_uuid = getDomainUUID(zkhandler, domain) | ||||
|   | ||||
| @@ -34,6 +34,8 @@ import pvcnoded.VMConsoleWatcherInstance as VMConsoleWatcherInstance | ||||
|  | ||||
| import daemon_lib.common as daemon_common | ||||
|  | ||||
| from daemon_lib.vm import update_vm_sriov_nics | ||||
|  | ||||
|  | ||||
| def flush_locks(zkhandler, logger, dom_uuid, this_node=None): | ||||
|     logger.out('Flushing RBD locks for VM "{}"'.format(dom_uuid), state='i') | ||||
| @@ -672,6 +674,11 @@ class VMInstance(object): | ||||
|         self.logger.out('Acquired write lock for synchronization phase D', state='o', prefix='Domain {}'.format(self.domuuid)) | ||||
|         time.sleep(0.5)  # Time for reader to acquire the lock | ||||
|  | ||||
|         # Update any SR-IOV NIC states now | ||||
|         sriov_update_result, sriov_update_error = update_vm_sriov_nics(self.zkhandler, self.domuuid, self.last_currentnode, self.node) | ||||
|         if not sriov_update_result: | ||||
|             self.logger.out('{}; VM will likely fail to start.'.format(sriov_update_error), state='w', prefix='Domain {}'.format(self.domuuid)) | ||||
|  | ||||
|         self.state = self.zkhandler.read(('domain.state', self.domuuid)) | ||||
|         self.dom = self.lookupByUUID(self.domuuid) | ||||
|         if self.dom: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user