diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py index 3fd2b4db235a388f399a48bf55ca4decf95d4e09..8ea1d71904468cedf51da1a4eca0c02db1d8014f 100644 --- a/lib/hypervisor/hv_kvm.py +++ b/lib/hypervisor/hv_kvm.py @@ -839,33 +839,21 @@ class KVMHypervisor(hv_base.BaseHypervisor): return result - def _ExecuteCpuAffinity(self, instance_name, cpu_mask, startup_paused): - """Complete CPU pinning and resume instance execution if needed. + def _ExecuteCpuAffinity(self, instance_name, cpu_mask): + """Complete CPU pinning. @type instance_name: string @param instance_name: name of instance @type cpu_mask: string @param cpu_mask: CPU pinning mask as entered by user - @type startup_paused: bool - @param startup_paused: was instance requested to pause before startup """ - try: - # Get KVM process ID, to be used if need to pin entire VM - _, pid, _ = self._InstancePidAlive(instance_name) - # Get vCPU thread IDs, to be used if need to pin vCPUs separately - thread_dict = self._GetVcpuThreadIds(instance_name) - # Run CPU pinning, based on configured mask - self._AssignCpuAffinity(cpu_mask, pid, thread_dict) - - finally: - # To control CPU pinning, the VM was started frozen, so we need - # to resume its execution, but only if freezing was not - # explicitly requested. - # Note: this is done even when an exception occurred so the VM - # is not unintentionally frozen. - if not startup_paused: - self._CallMonitorCommand(instance_name, self._CONT_CMD) + # Get KVM process ID, to be used if need to pin entire VM + _, pid, _ = self._InstancePidAlive(instance_name) + # Get vCPU thread IDs, to be used if need to pin vCPUs separately + thread_dict = self._GetVcpuThreadIds(instance_name) + # Run CPU pinning, based on configured mask + self._AssignCpuAffinity(cpu_mask, pid, thread_dict) def ListInstances(self): """Get the list of running instances. @@ -1388,10 +1376,10 @@ class KVMHypervisor(hv_base.BaseHypervisor): continue self._ConfigureNIC(instance, nic_seq, nic, taps[nic_seq]) - # Before running the KVM command, capture wether the instance is - # supposed to start paused. This is used later when changing CPU - # affinity in order to know whether to resume instance execution. - startup_paused = _KVM_START_PAUSED_FLAG in kvm_cmd + # CPU affinity requires kvm to start paused, so we set this flag if the + # instance is not already paused and if we are not going to accept a + # migrating instance. In the latter case, pausing is not needed. + start_kvm_paused = not (_KVM_START_PAUSED_FLAG in kvm_cmd) and not incoming # Note: CPU pinning is using up_hvp since changes take effect # during instance startup anyway, and to avoid problems when soft @@ -1399,7 +1387,7 @@ class KVMHypervisor(hv_base.BaseHypervisor): cpu_pinning = False if up_hvp.get(constants.HV_CPU_MASK, None): cpu_pinning = True - if not startup_paused: + if start_kvm_paused: kvm_cmd.extend([_KVM_START_PAUSED_FLAG]) if security_model == constants.HT_SM_POOL: @@ -1455,8 +1443,16 @@ class KVMHypervisor(hv_base.BaseHypervisor): # If requested, set CPU affinity and resume instance execution if cpu_pinning: - self._ExecuteCpuAffinity(instance.name, up_hvp[constants.HV_CPU_MASK], - startup_paused) + try: + self._ExecuteCpuAffinity(instance.name, up_hvp[constants.HV_CPU_MASK]) + finally: + if start_kvm_paused: + # To control CPU pinning, the VM was started frozen, so we need + # to resume its execution, but only if freezing was not + # explicitly requested. + # Note: this is done even when an exception occurred so the VM + # is not unintentionally frozen. + self._CallMonitorCommand(instance.name, self._CONT_CMD) def StartInstance(self, instance, block_devices, startup_paused): """Start an instance.