_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)
_RemoveBlockDevLinks(iname, instance.disks)
-def InstanceReboot(instance, reboot_type):
+def InstanceReboot(instance, reboot_type, shutdown_timeout):
"""Reboot an instance.
@type instance: L{objects.Instance}
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
"""
_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)
@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: