示例#1
0
    def execute(self, process_name, host_name):
        def _wait_for_disable():
            service_disabled = self.novaclient.is_service_down(
                self.context, host_name, process_name)
            if service_disabled:
                raise loopingcall.LoopingCallDone()

        periodic_call = loopingcall.FixedIntervalLoopingCall(
            _wait_for_disable)
        try:
            msg = "Confirming compute service is disabled on host: '%s'" % (
                host_name)
            self.update_details(msg)

            # add a timeout to the periodic call.
            periodic_call.start(interval=CONF.verify_interval)
            etimeout.with_timeout(
                CONF.wait_period_after_service_update,
                periodic_call.wait)

            msg = "Confirmed compute service is disabled on host: '%s'" % (
                host_name)
            self.update_details(msg, 1.0)
        except etimeout.Timeout:
            msg = "Failed to disable service %(process_name)s" % {
                'process_name': process_name
            }
            self.update_details(msg, 1.0)
            raise exception.ProcessRecoveryFailureException(
                message=msg)
        finally:
            # stop the periodic call, in case of exceptions or Timeout.
            periodic_call.stop()
示例#2
0
    def _stop_after_evacuation(self, context, instance):
        def _wait_for_stop_confirmation():
            old_vm_state, new_vm_state, _ = (
                self._get_state_and_host_of_instance(context, instance))

            if new_vm_state == 'stopped':
                raise loopingcall.LoopingCallDone()

        periodic_call_stopped = loopingcall.FixedIntervalLoopingCall(
            _wait_for_stop_confirmation)

        try:
            self.novaclient.stop_server(context, instance.id)
            # confirm instance is stopped after recovery
            periodic_call_stopped.start(interval=CONF.verify_interval)
            etimeout.with_timeout(
                CONF.wait_period_after_power_off,
                periodic_call_stopped.wait)
        except etimeout.Timeout:
            with excutils.save_and_reraise_exception():
                msg = ("Instance '%s' is successfully evacuated but "
                       "failed to stop.")
                LOG.warning(msg, instance.id)
        finally:
            periodic_call_stopped.stop()
示例#3
0
文件: vmops.py 项目: jorgevgut/nova
    def _wait_for_power_off(self, instance_name, time_limit):
        """Waiting for a VM to be in a disabled state.

           :return: True if the instance is shutdown within time_limit,
                    False otherwise.
        """

        desired_vm_states = [constants.HYPERV_VM_STATE_DISABLED]

        def _check_vm_status(instance_name):
            if self._get_vm_state(instance_name) in desired_vm_states:
                raise loopingcall.LoopingCallDone()

        periodic_call = loopingcall.FixedIntervalLoopingCall(_check_vm_status,
                                                             instance_name)

        try:
            # add a timeout to the periodic call.
            periodic_call.start(interval=SHUTDOWN_TIME_INCREMENT)
            etimeout.with_timeout(time_limit, periodic_call.wait)
        except etimeout.Timeout:
            # VM did not shutdown in the expected time_limit.
            return False
        finally:
            # stop the periodic call, in case of exceptions or Timeout.
            periodic_call.stop()

        return True
示例#4
0
    def execute(self, instance_uuid):
        def _wait_for_active():
            new_instance = self.novaclient.get_server(self.context,
                                                      instance_uuid)
            vm_state = getattr(new_instance, 'OS-EXT-STS:vm_state')
            if vm_state == 'active':
                raise loopingcall.LoopingCallDone()

        periodic_call = loopingcall.FixedIntervalLoopingCall(
            _wait_for_active)
        try:
            msg = "Confirming instance '%s' vm_state is ACTIVE" % instance_uuid
            self.update_details(msg)

            # add a timeout to the periodic call.
            periodic_call.start(interval=CONF.verify_interval)
            etimeout.with_timeout(CONF.wait_period_after_power_on,
                                  periodic_call.wait)

            msg = "Confirmed instance '%s' vm_state is ACTIVE" % instance_uuid
            self.update_details(msg, 1.0)
        except etimeout.Timeout:
            msg = "Failed to start instance %(instance)s" % {
                'instance': instance_uuid
            }
            self.update_details(msg, 1.0)
            raise exception.InstanceRecoveryFailureException(
                message=msg)
        finally:
            # stop the periodic call, in case of exceptions or Timeout.
            periodic_call.stop()
    def _wait_for_power_off(self, instance_name, time_limit):
        """Waiting for a VM to be in a disabled state.

           :return: True if the instance is shutdown within time_limit,
                    False otherwise.
        """

        desired_vm_states = [constants.HYPERV_VM_STATE_DISABLED]

        def _check_vm_status(instance_name):
            if self._get_vm_state(instance_name) in desired_vm_states:
                raise loopingcall.LoopingCallDone()

        periodic_call = loopingcall.FixedIntervalLoopingCall(
            _check_vm_status, instance_name)

        try:
            # add a timeout to the periodic call.
            periodic_call.start(interval=SHUTDOWN_TIME_INCREMENT)
            etimeout.with_timeout(time_limit, periodic_call.wait)
        except etimeout.Timeout:
            # VM did not shutdown in the expected time_limit.
            return False
        finally:
            # stop the periodic call, in case of exceptions or Timeout.
            periodic_call.stop()

        return True
示例#6
0
def wait_for_power_state(instance, power_state, time_limit):
    """Waiting for a virtual machine to be in required power state.

    :param instance:    nova.objects.instance.Instance
    :param power_state: nova.compute.power_state
    :param time_limit:  (int) time limit for this task

    :return: True if the instance is in required power state
             within time_limit, False otherwise.
    """

    def _check_power_state(instance):
        current_state = get_power_state(instance)
        LOG.debug("Wait for soft shutdown: (%s, %s)", current_state,
                  power_state)
        if current_state == power_state:
            raise loopingcall.LoopingCallDone()
    response = True
    periodic_call = loopingcall.FixedIntervalLoopingCall(_check_power_state,
                                                         instance)
    try:
        # add a timeout to the periodic call.
        periodic_call.start(interval=constants.SHUTDOWN_RETRY_INTERVAL)
        etimeout.with_timeout(time_limit, periodic_call.wait)
    except etimeout.Timeout:
        # Virtual machine did not shutdown in the expected time_limit.
        response = False

    finally:
        # Stop the periodic call, in case of exceptions or Timeout.
        periodic_call.stop()

    return response
示例#7
0
    def _stop_after_evacuation(self, context, instance):
        def _wait_for_stop_confirmation():
            old_vm_state, new_vm_state, _ = (
                self._get_state_and_host_of_instance(context, instance))

            if new_vm_state == 'stopped':
                raise loopingcall.LoopingCallDone()

        periodic_call_stopped = loopingcall.FixedIntervalLoopingCall(
            _wait_for_stop_confirmation)

        try:
            self.novaclient.stop_server(context, instance.id)
            # confirm instance is stopped after recovery
            periodic_call_stopped.start(interval=CONF.verify_interval)
            etimeout.with_timeout(
                CONF.wait_period_after_power_off,
                periodic_call_stopped.wait)
        except etimeout.Timeout:
            with excutils.save_and_reraise_exception():
                msg = ("Instance '%s' is successfully evacuated but "
                       "failed to stop.")
                LOG.warning(msg, instance.id)
        finally:
            periodic_call_stopped.stop()
示例#8
0
 def test_with_timeout(self):
     self.assertRaises(timeout.Timeout, timeout.with_timeout, DELAY, greenthread.sleep, DELAY*10)
     X = object()
     r = timeout.with_timeout(DELAY, greenthread.sleep, DELAY*10, timeout_value=X)
     self.assert_(r is X, (r, X))
     r = timeout.with_timeout(DELAY*10, greenthread.sleep, 
                              DELAY, timeout_value=X)
     self.assert_(r is None, r)
示例#9
0
 def test_with_timeout(self):
     self.assertRaises(timeout.Timeout, timeout.with_timeout, DELAY, greenthread.sleep, DELAY*10)
     X = object()
     r = timeout.with_timeout(DELAY, greenthread.sleep, DELAY*10, timeout_value=X)
     assert r is X, (r, X)
     r = timeout.with_timeout(DELAY*10, greenthread.sleep,
                              DELAY, timeout_value=X)
     assert r is None, r
示例#10
0
    def execute(self, context, instance_uuid):
        """Stop the instance for recovery."""
        instance = self.novaclient.get_server(context, instance_uuid)

        # If an instance is not HA_Enabled and "process_all_instances" config
        # option is also disabled, then there is no need to take any recovery
        # action.
        if not CONF.instance_failure.process_all_instances and not (
                strutils.bool_from_string(
                    instance.metadata.get('HA_Enabled', False))):
            LOG.info(
                "Skipping recovery for instance: %s as it is "
                "not Ha_Enabled.", instance_uuid)
            raise exception.SkipInstanceRecoveryException()

        vm_state = getattr(instance, 'OS-EXT-STS:vm_state')
        if vm_state in ['paused', 'rescued']:
            msg = _("Recovery of instance '%(instance_uuid)s' is ignored as"
                    " it is in '%(vm_state)s' state.") % {
                        'instance_uuid': instance_uuid,
                        'vm_state': vm_state
                    }
            LOG.warning(msg)
            raise exception.IgnoreInstanceRecoveryException(msg)

        if vm_state != 'stopped':
            if vm_state == 'resized':
                self.novaclient.reset_instance_state(context, instance.id,
                                                     'active')

            self.novaclient.stop_server(context, instance.id)

        def _wait_for_power_off():
            new_instance = self.novaclient.get_server(context, instance_uuid)
            vm_state = getattr(new_instance, 'OS-EXT-STS:vm_state')
            if vm_state == 'stopped':
                raise loopingcall.LoopingCallDone()

        periodic_call = loopingcall.FixedIntervalLoopingCall(
            _wait_for_power_off)

        try:
            # add a timeout to the periodic call.
            periodic_call.start(interval=CONF.verify_interval)
            etimeout.with_timeout(CONF.wait_period_after_power_off,
                                  periodic_call.wait)
        except etimeout.Timeout:
            msg = _("Failed to stop instance %(instance)s") % {
                'instance': instance.id
            }
            raise exception.InstanceRecoveryFailureException(message=msg)
        finally:
            # stop the periodic call, in case of exceptions or Timeout.
            periodic_call.stop()
示例#11
0
    def execute(self, context, instance_uuid):
        """Stop the instance for recovery."""
        instance = self.novaclient.get_server(context, instance_uuid)

        # If an instance is not HA_Enabled and "process_all_instances" config
        # option is also disabled, then there is no need to take any recovery
        # action.
        if not CONF.instance_failure.process_all_instances and not (
                strutils.bool_from_string(
                    instance.metadata.get('HA_Enabled', False))):
            LOG.info("Skipping recovery for instance: %s as it is "
                     "not Ha_Enabled.", instance_uuid)
            raise exception.SkipInstanceRecoveryException()

        vm_state = getattr(instance, 'OS-EXT-STS:vm_state')
        if vm_state in ['paused', 'rescued']:
            msg = _("Recovery of instance '%(instance_uuid)s' is ignored as"
                    " it is in '%(vm_state)s' state.") % {
                'instance_uuid': instance_uuid, 'vm_state': vm_state}
            LOG.warning(msg)
            raise exception.IgnoreInstanceRecoveryException(msg)

        if vm_state != 'stopped':
            if vm_state == 'resized':
                self.novaclient.reset_instance_state(
                    context, instance.id, 'active')

            self.novaclient.stop_server(context, instance.id)

        def _wait_for_power_off():
            new_instance = self.novaclient.get_server(context, instance_uuid)
            vm_state = getattr(new_instance, 'OS-EXT-STS:vm_state')
            if vm_state == 'stopped':
                raise loopingcall.LoopingCallDone()

        periodic_call = loopingcall.FixedIntervalLoopingCall(
            _wait_for_power_off)

        try:
            # add a timeout to the periodic call.
            periodic_call.start(interval=CONF.verify_interval)
            etimeout.with_timeout(CONF.wait_period_after_power_off,
                                  periodic_call.wait)
        except etimeout.Timeout:
            msg = _("Failed to stop instance %(instance)s") % {
                'instance': instance.id
            }
            raise exception.InstanceRecoveryFailureException(message=msg)
        finally:
            # stop the periodic call, in case of exceptions or Timeout.
            periodic_call.stop()
示例#12
0
def send_request(timeout):
    try:
        start = time.clock()
        server = httplib.HTTPConnection(server_ip.strip())
        with_timeout(timeout, server.request, 'GET', '/')
        delta = time.clock() - start
        response = server.getresponse()
        assert response.status == 200
        assert response.read() == 'Pong!'
        log(str(delta))
    except Timeout:
        log('-')
    except AssertionError:
        log('!')
示例#13
0
        def _wait_for_evacuation():
            periodic_call = loopingcall.FixedIntervalLoopingCall(
                _wait_for_evacuation_confirmation)

            try:
                # add a timeout to the periodic call.
                periodic_call.start(interval=CONF.verify_interval)
                etimeout.with_timeout(CONF.wait_period_after_evacuation,
                                      periodic_call.wait)
            except etimeout.Timeout:
                # Instance is not evacuated in the expected time_limit.
                failed_evacuation_instances.append(instance.id)
            else:
                # stop the periodic call, in case of exceptions or
                # Timeout.
                periodic_call.stop()
示例#14
0
    def put(self, key, value):
        echo('Put {0}: {1}'.format(key, value))
        tid = self.unique_id()

        other_services = map(lambda x: self.__dict__['s' + str(x)],
                             range(SERVICES - 1))

        replies = []
        for service in other_services:
            reply = service.prepare. async (tid, key, value)
            replies.append(reply)

        get_all_results = lambda replies: map(lambda x: x.result(), replies)
        rvs = with_timeout(TIMEOUT,
                           get_all_results,
                           replies,
                           timeout_value=None)

        if None in rvs:
            for service in other_services:
                rv = service.abort(tid)
                assert rv == True
            return False

        for service in other_services:
            rv = service.commit(tid)
            assert rv == True

        self.storage[key] = value

        return True
示例#15
0
  def put(self, key, value):
    echo('put [{0}: {1}]'.format(key, value))
    tid = self.unique_id()

    other_services = map(lambda x: self.__dict__['s' + str(x)], range(SERVICES - 1))

    replies = []
    for service in other_services:
      reply = service.prepare.async(tid, key, value)
      assert reply != None
      replies.append(reply)

    get_all_results = lambda replies: map(lambda x: x.result(), replies)
#    t1 = time.time()
    rvs = with_timeout(TIMEOUT, get_all_results, replies, timeout_value=None)
#    t2 = time.time()
#    echo('! ' + str(t2 - t1))

    if rvs == None:
      echo('Timeout!')
      for service in other_services:
        rv = service.abort(tid)
        assert rv == True
      return False

    for service in other_services:
      rv = service.commit(tid)
      assert rv == True

    self.storage[key] = value

    return True
示例#16
0
        def _wait_for_evacuation():
            periodic_call = loopingcall.FixedIntervalLoopingCall(
                _wait_for_evacuation_confirmation)

            try:
                # add a timeout to the periodic call.
                periodic_call.start(interval=CONF.verify_interval)
                etimeout.with_timeout(
                    CONF.wait_period_after_evacuation,
                    periodic_call.wait)
            except etimeout.Timeout:
                # Instance is not evacuated in the expected time_limit.
                failed_evacuation_instances.append(instance.id)
            else:
                # stop the periodic call, in case of exceptions or
                # Timeout.
                periodic_call.stop()
示例#17
0
 def result(self, timeout=None):
     get = self._greenthread.wait
     if timeout is not None:
         get = with_timeout(timeout, get)
     try:
         return get()
     except Timeout as e:
         raise TimeoutError(e)
示例#18
0
        def _wait_for_evacuation():
            periodic_call = loopingcall.FixedIntervalLoopingCall(
                _wait_for_evacuation_confirmation)

            try:
                # add a timeout to the periodic call.
                periodic_call.start(interval=CONF.verify_interval)
                etimeout.with_timeout(
                    CONF.wait_period_after_evacuation,
                    periodic_call.wait)
            except etimeout.Timeout:
                with excutils.save_and_reraise_exception():
                    msg = ("Timeout for instance '%(uuid)s' evacuation."
                           % {'uuid': instance.id})
                    LOG.warning(msg)
            finally:
                # stop the periodic call, in case of exceptions or
                # Timeout.
                periodic_call.stop()
示例#19
0
 def wait(self, timeout=None):
     pool = self._pool
     if pool is None:
         return
     wait = pool.waitall
     if timeout is not None:
         wait = with_timeout(timeout, wait)
     try:
         wait()
     except Timeout as e:
         raise TimeoutError(e)
示例#20
0
    def execute(self, context, process_name, host_name):
        def _wait_for_disable():
            service_disabled = self.novaclient.is_service_down(
                context, host_name, process_name)
            if service_disabled:
                raise loopingcall.LoopingCallDone()

        periodic_call = loopingcall.FixedIntervalLoopingCall(_wait_for_disable)
        try:
            # add a timeout to the periodic call.
            periodic_call.start(interval=CONF.verify_interval)
            etimeout.with_timeout(CONF.wait_period_after_service_update,
                                  periodic_call.wait)
        except etimeout.Timeout:
            msg = _("Failed to disable service %(process_name)s") % {
                'process_name': process_name
            }
            raise exception.ProcessRecoveryFailureException(message=msg)
        finally:
            # stop the periodic call, in case of exceptions or Timeout.
            periodic_call.stop()
示例#21
0
    def execute(self, context, instance_list, host_name):
        failed_evacuation_instances = []
        for instance in instance_list:

            def _wait_for_evacuation():
                new_instance = self.novaclient.get_server(context, instance.id)
                instance_host = getattr(new_instance,
                                        "OS-EXT-SRV-ATTR:hypervisor_hostname")
                old_vm_state = getattr(instance, "OS-EXT-STS:vm_state")
                new_vm_state = getattr(new_instance, "OS-EXT-STS:vm_state")

                if instance_host != host_name:
                    if ((old_vm_state == 'error' and new_vm_state == 'active')
                            or old_vm_state == new_vm_state):
                        raise loopingcall.LoopingCallDone()

            periodic_call = loopingcall.FixedIntervalLoopingCall(
                _wait_for_evacuation)
            try:
                # add a timeout to the periodic call.
                periodic_call.start(interval=CONF.verify_interval)
                etimeout.with_timeout(CONF.wait_period_after_evacuation,
                                      periodic_call.wait)
            except etimeout.Timeout:
                # Instance is not evacuated in the expected time_limit.
                failed_evacuation_instances.append(instance.id)
            finally:
                # stop the periodic call, in case of exceptions or Timeout.
                periodic_call.stop()

        if failed_evacuation_instances:
            msg = _("Failed to evacuate instances %(instances)s from "
                    "host %(host_name)s.") % {
                        'instances': failed_evacuation_instances,
                        'host_name': host_name
                    }
            raise exception.HostRecoveryFailureException(message=msg)
示例#22
0
    def _evacuate_and_confirm(self, context, instance, host_name,
                              failed_evacuation_instances, reserved_host=None):
        # Before locking the instance check whether it is already locked
        # by user, if yes don't lock the instance
        instance_already_locked = self.novaclient.get_server(
            context, instance.id).locked

        if not instance_already_locked:
            # lock the instance so that until evacuation and confirmation
            # is not complete, user won't be able to perform any actions
            # on the instance.
            self.novaclient.lock_server(context, instance.id)

        def _wait_for_evacuation_confirmation():
            old_vm_state, new_vm_state, instance_host = (
                self._get_state_and_host_of_instance(context, instance))

            if instance_host != host_name:
                if ((old_vm_state == 'error' and
                    new_vm_state == 'active') or
                        old_vm_state == new_vm_state):
                    raise loopingcall.LoopingCallDone()

        try:
            vm_state = getattr(instance, "OS-EXT-STS:vm_state")

            # Nova evacuates an instance only when vm_state is in active,
            # stopped or error state. If an instance is in other than active,
            # error and stopped vm_state, masakari resets the instance state
            # to *error* so that the instance can be evacuated.
            stop_instance = True
            if vm_state not in ['active', 'error', 'stopped']:
                self.novaclient.reset_instance_state(context, instance.id)
                instance = self.novaclient.get_server(context, instance.id)
                power_state = getattr(instance, "OS-EXT-STS:power_state")
                if vm_state == 'resized' and power_state != SHUTDOWN:
                    stop_instance = False

                vm_state = getattr(instance, "OS-EXT-STS:vm_state")

            # evacuate the instance
            self.novaclient.evacuate_instance(
                context, instance.id,
                target=reserved_host.name if reserved_host else None)

            periodic_call = loopingcall.FixedIntervalLoopingCall(
                _wait_for_evacuation_confirmation)

            try:
                # add a timeout to the periodic call.
                periodic_call.start(interval=CONF.verify_interval)
                etimeout.with_timeout(
                    CONF.wait_period_after_evacuation,
                    periodic_call.wait)

                if vm_state not in ['active', 'stopped']:
                    if stop_instance:
                        self._stop_after_evacuation(context, instance)
                        # If the instance was in 'error' state before failure
                        # it should be set to 'error' after recovery.
                        if vm_state == 'error':
                            self.novaclient.reset_instance_state(
                                context, instance.id)
            except etimeout.Timeout:
                # Instance is not evacuated in the expected time_limit.
                failed_evacuation_instances.append(instance.id)
            finally:
                # stop the periodic call, in case of exceptions or
                # Timeout.
                periodic_call.stop()
        except Exception:
            # Exception is raised while resetting instance state or
            # evacuating the instance itself.
            failed_evacuation_instances.append(instance.id)
        finally:
            if not instance_already_locked:
                # Unlock the server after evacuation and confirmation
                self.novaclient.unlock_server(context, instance.id)
示例#23
0
 def longer_timeout():
     # this should not catch the outer timeout's exception
     return timeout.with_timeout(DELAY * 10, 
                                 greenthread.sleep, DELAY * 20,
                                 timeout_value='b')
示例#24
0
 def longer_timeout():
     # this should not catch the outer timeout's exception
     return timeout.with_timeout(DELAY * 10,
                                 greenthread.sleep,
                                 DELAY * 20,
                                 timeout_value='b')
示例#25
0
    def _evacuate_and_confirm(self, context, instance, host_name,
                              failed_evacuation_instances, reserved_host=None):
        # Before locking the instance check whether it is already locked
        # by user, if yes don't lock the instance
        instance_already_locked = self.novaclient.get_server(
            context, instance.id).locked

        if not instance_already_locked:
            # lock the instance so that until evacuation and confirmation
            # is not complete, user won't be able to perform any actions
            # on the instance.
            self.novaclient.lock_server(context, instance.id)

        def _wait_for_evacuation_confirmation():
            old_vm_state, new_vm_state, instance_host = (
                self._get_state_and_host_of_instance(context, instance))

            if instance_host != host_name:
                if ((old_vm_state == 'error' and
                    new_vm_state == 'active') or
                        old_vm_state == new_vm_state):
                    raise loopingcall.LoopingCallDone()

        try:
            vm_state = getattr(instance, "OS-EXT-STS:vm_state")
            task_state = getattr(instance, "OS-EXT-STS:task_state")

            # Nova evacuates an instance only when vm_state is in active,
            # stopped or error state. If an instance is in other than active,
            # error and stopped vm_state, masakari resets the instance state
            # to *error* so that the instance can be evacuated.
            stop_instance = True
            if vm_state not in ['active', 'error', 'stopped']:
                self.novaclient.reset_instance_state(context, instance.id)
                instance = self.novaclient.get_server(context, instance.id)
                power_state = getattr(instance, "OS-EXT-STS:power_state")
                if vm_state == 'resized' and power_state != SHUTDOWN:
                    stop_instance = False

                vm_state = getattr(instance, "OS-EXT-STS:vm_state")

            elif task_state is not None:
                # Nova fails evacuation when the instance's task_state is not
                # none. In this case, masakari resets the instance's vm_state
                # to 'error' and task_state to none.
                self.novaclient.reset_instance_state(context, instance.id)
                instance = self.novaclient.get_server(context, instance.id)
                if vm_state == 'active':
                    stop_instance = False

            # evacuate the instance
            self.novaclient.evacuate_instance(
                context, instance.id,
                target=reserved_host.name if reserved_host else None)

            periodic_call = loopingcall.FixedIntervalLoopingCall(
                _wait_for_evacuation_confirmation)

            try:
                # add a timeout to the periodic call.
                periodic_call.start(interval=CONF.verify_interval)
                etimeout.with_timeout(
                    CONF.wait_period_after_evacuation,
                    periodic_call.wait)

                if vm_state != 'active':
                    if stop_instance:
                        self._stop_after_evacuation(context, instance)
                        # If the instance was in 'error' state before failure
                        # it should be set to 'error' after recovery.
                        if vm_state == 'error':
                            self.novaclient.reset_instance_state(
                                context, instance.id)
            except etimeout.Timeout:
                # Instance is not evacuated in the expected time_limit.
                failed_evacuation_instances.append(instance.id)
            finally:
                # stop the periodic call, in case of exceptions or
                # Timeout.
                periodic_call.stop()
        except Exception:
            # Exception is raised while resetting instance state or
            # evacuating the instance itself.
            failed_evacuation_instances.append(instance.id)
        finally:
            if not instance_already_locked:
                # Unlock the server after evacuation and confirmation
                self.novaclient.unlock_server(context, instance.id)