diff --git a/lib/hypervisor/hv_base.py b/lib/hypervisor/hv_base.py index db8bcb49a952f72fbd374e4d20cd918b62d86fb2..af7aa957596c910a8754ecc5092b8929ac0ca786 100644 --- a/lib/hypervisor/hv_base.py +++ b/lib/hypervisor/hv_base.py @@ -113,7 +113,7 @@ class BaseHypervisor(object): """Start an instance.""" raise NotImplementedError - def StopInstance(self, instance, force=False, retry=False): + def StopInstance(self, instance, force=False, retry=False, name=None): """Stop an instance @type instance: L{objects.Instance} @@ -122,6 +122,10 @@ class BaseHypervisor(object): @param force: whether to do a "hard" stop (destroy) @type retry: boolean @param retry: whether this is just a retry call + @type name: string or None + @param name: if this parameter is passed, the the instance object + should not be used (will be passed as None), and the shutdown + must be done by name only """ raise NotImplementedError diff --git a/lib/hypervisor/hv_chroot.py b/lib/hypervisor/hv_chroot.py index cf40c5936d551456bd4120784da65660dfbd0bda..36b37a8eb1261f9e13c2133dc653d147cad7f7f4 100644 --- a/lib/hypervisor/hv_chroot.py +++ b/lib/hypervisor/hv_chroot.py @@ -177,7 +177,7 @@ class ChrootManager(hv_base.BaseHypervisor): raise HypervisorError("Can't run the chroot start script: %s" % result.output) - def StopInstance(self, instance, force=False, retry=False): + def StopInstance(self, instance, force=False, retry=False, name=None): """Stop an instance. This method has complicated cleanup tests, as we must: @@ -186,7 +186,10 @@ class ChrootManager(hv_base.BaseHypervisor): - finally unmount the instance dir """ - root_dir = self._InstanceDir(instance.name) + if name is None: + name = instance.name + + root_dir = self._InstanceDir(name) if not os.path.exists(root_dir) or not self._IsDirLive(root_dir): return diff --git a/lib/hypervisor/hv_fake.py b/lib/hypervisor/hv_fake.py index d607d0de8fe45b4b3ed942fc48a26ffb43229018..cea05d61ef7c2cdd8e629915cdf4d5e3b26c5b27 100644 --- a/lib/hypervisor/hv_fake.py +++ b/lib/hypervisor/hv_fake.py @@ -136,13 +136,13 @@ class FakeHypervisor(hv_base.BaseHypervisor): finally: fh.close() - def _MarkDown(self, instance): + def _MarkDown(self, instance_name): """Mark the instance as running. This does no checks, which should be done by its callers. """ - file_name = self._InstanceFile(instance.name) + file_name = self._InstanceFile(instance_name) utils.RemoveFile(file_name) def StartInstance(self, instance, block_devices): @@ -162,17 +162,19 @@ class FakeHypervisor(hv_base.BaseHypervisor): raise errors.HypervisorError("Failed to start instance %s: %s" % (instance.name, err)) - def StopInstance(self, instance, force=False, retry=False): + def StopInstance(self, instance, force=False, retry=False, name=None): """Stop an instance. For the fake hypervisor, this just removes the file in the base dir, if it exist, otherwise we raise an exception. """ - if not self._IsAlive(instance.name): + if name is None: + name = instance.name + if not self._IsAlive(name): raise errors.HypervisorError("Failed to stop instance %s: %s" % - (instance.name, "not running")) - self._MarkDown(instance) + (name, "not running")) + self._MarkDown(name) def RebootInstance(self, instance): """Reboot an instance. @@ -252,7 +254,7 @@ class FakeHypervisor(hv_base.BaseHypervisor): logging.debug("Fake hypervisor migrating %s to %s (live=%s)", instance, target, live) - self._MarkDown(instance) + self._MarkDown(instance.name) def FinalizeMigration(self, instance, info, success): """Finalize an instance migration. @@ -267,4 +269,4 @@ class FakeHypervisor(hv_base.BaseHypervisor): self._MarkUp(instance) else: # ensure it's down - self._MarkDown(instance) + self._MarkDown(instance.name) diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py index 2035e2d6ac6c7c268323c7b989c1b3ee31149058..b9f20f3dd3ef7f9aab766252a00ede34eabb5597 100644 --- a/lib/hypervisor/hv_kvm.py +++ b/lib/hypervisor/hv_kvm.py @@ -613,19 +613,26 @@ class KVMHypervisor(hv_base.BaseHypervisor): return result - def StopInstance(self, instance, force=False, retry=False): + def StopInstance(self, instance, force=False, retry=False, name=None): """Stop an instance. """ - pidfile, pid, alive = self._InstancePidAlive(instance.name) + if name is not None and not force: + raise errors.HypervisorError("Cannot shutdown cleanly by name only") + if name is None: + name = instance.name + acpi = instance.hvparams[constants.HV_ACPI] + else: + acpi = False + pidfile, pid, alive = self._InstancePidAlive(name) if pid > 0 and alive: - if force or not instance.hvparams[constants.HV_ACPI]: + if force or not acpi: utils.KillProcess(pid) else: - self._CallMonitorCommand(instance.name, 'system_powerdown') + self._CallMonitorCommand(name, 'system_powerdown') - if not self._InstancePidAlive(instance.name)[2]: - self._RemoveInstanceRuntimeFiles(pidfile, instance.name) + if not self._InstancePidAlive(name)[2]: + self._RemoveInstanceRuntimeFiles(pidfile, name) return True else: return False diff --git a/lib/hypervisor/hv_xen.py b/lib/hypervisor/hv_xen.py index e16c030804aa232b26ac383d12d41fc2de2b879e..575e3b9404e990bd1de7589c1da3939ba8958897 100644 --- a/lib/hypervisor/hv_xen.py +++ b/lib/hypervisor/hv_xen.py @@ -189,21 +189,22 @@ class XenHypervisor(hv_base.BaseHypervisor): (instance.name, result.fail_reason, result.output)) - def StopInstance(self, instance, force=False, retry=False): + def StopInstance(self, instance, force=False, retry=False, name=None): """Stop an instance. """ - self._RemoveConfigFile(instance.name) + if name is None: + name = instance.name + self._RemoveConfigFile(name) if force: - command = ["xm", "destroy", instance.name] + command = ["xm", "destroy", name] else: - command = ["xm", "shutdown", instance.name] + command = ["xm", "shutdown", name] result = utils.RunCmd(command) if result.failed: raise errors.HypervisorError("Failed to stop instance %s: %s, %s" % - (instance.name, result.fail_reason, - result.output)) + (name, result.fail_reason, result.output)) def RebootInstance(self, instance): """Reboot an instance.