X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/ba00557a6c75f7cd55845398327f406241f803d6..4d98c5658a6d01a7be3bb08c6c7328bb6d9678ae:/lib/backend.py diff --git a/lib/backend.py b/lib/backend.py index edbbc48..4e40cb7 100644 --- a/lib/backend.py +++ b/lib/backend.py @@ -960,40 +960,48 @@ def StartInstance(instance): _Fail("Hypervisor error: %s", err, exc=True) -def InstanceShutdown(instance): +def InstanceShutdown(instance, timeout): """Shut an instance down. @note: this functions uses polling with a hardcoded timeout. @type instance: L{objects.Instance} @param instance: the instance object + @type timeout: integer + @param timeout: maximum timeout for soft shutdown @rtype: None """ hv_name = instance.hypervisor - running_instances = GetInstanceList([hv_name]) + hyper = hypervisor.GetHypervisor(hv_name) + running_instances = hyper.ListInstances() iname = instance.name if iname not in running_instances: logging.info("Instance %s not running, doing nothing", iname) return - hyper = hypervisor.GetHypervisor(hv_name) - try: - hyper.StopInstance(instance) - except errors.HypervisorError, err: - _Fail("Failed to stop instance %s: %s", iname, err) - - # test every 10secs for 2min + start = time.time() + end = start + timeout + sleep_time = 1 - time.sleep(1) - for _ in range(11): - if instance.name not in GetInstanceList([hv_name]): + tried_once = False + while not tried_once and time.time() < end: + try: + hyper.StopInstance(instance, retry=tried_once) + except errors.HypervisorError, err: + _Fail("Failed to stop instance %s: %s", iname, err) + tried_once = True + time.sleep(sleep_time) + if instance.name not in hyper.ListInstances(): break - time.sleep(10) + if sleep_time < 5: + # 1.2 behaves particularly good for our case: + # it gives us 10 increasing steps and caps just slightly above 5 seconds + sleep_time *= 1.2 else: # the shutdown did not succeed - logging.error("Shutdown of '%s' unsuccessful, using destroy", iname) + logging.error("Shutdown of '%s' unsuccessful, forcing", iname) try: hyper.StopInstance(instance, force=True) @@ -1007,7 +1015,7 @@ def InstanceShutdown(instance): _RemoveBlockDevLinks(iname, instance.disks) -def InstanceReboot(instance, reboot_type): +def InstanceReboot(instance, reboot_type, shutdown_timeout): """Reboot an instance. @type instance: L{objects.Instance} @@ -1023,6 +1031,8 @@ def InstanceReboot(instance, reboot_type): not accepted here, since that mode is handled differently, in cmdlib, and translates into full stop and start of the instance (instead of a call_instance_reboot RPC) + @type timeout: integer + @param timeout: maximum timeout for soft shutdown @rtype: None """ @@ -1039,7 +1049,7 @@ def InstanceReboot(instance, reboot_type): _Fail("Failed to soft reboot instance %s: %s", instance.name, err) elif reboot_type == constants.INSTANCE_REBOOT_HARD: try: - InstanceShutdown(instance) + InstanceShutdown(instance, shutdown_timeout) return StartInstance(instance) except errors.HypervisorError, err: _Fail("Failed to hard reboot instance %s: %s", instance.name, err) @@ -1760,7 +1770,7 @@ def OSFromDisk(name, base_dir=None): @raise RPCFail: if we don't find a valid OS """ - name_only = name.split('+',1)[0] + name_only = name.split("+", 1)[0] status, payload = _TryOSFromDisk(name_only, base_dir) if not status: