This patch implements RebootInstance function of the LXCHypervisor. Reboot of the LXC container can be done by using lxc-stop command with --reboot switch. Internally this is just sending SIGINT for the init process of the container. Since the init process is working on the host machine natively, it requires CAP_SYS_BOOT capability to call the reboot(2) system call. This function detects if the CAP_SYS_BOOT is dropped from the container and raise an error to claim that requirement. It is up to users if they use the soft reboot of the LXC container with allowing CAP_SYS_BOOT or drop it and do not use the soft reboot.
Signed-off-by: Yuto KAWAMURA(kawamuray) <[email protected]> --- lib/hypervisor/hv_lxc.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/hypervisor/hv_lxc.py b/lib/hypervisor/hv_lxc.py index dfd47e6..6ddf08e 100644 --- a/lib/hypervisor/hv_lxc.py +++ b/lib/hypervisor/hv_lxc.py @@ -94,6 +94,7 @@ class LXCHypervisor(hv_base.BaseHypervisor): # Let beta version following micro version, but don't care about it _LXC_VERSION_RE = re.compile(r"^(\d+)\.(\d+)\.(\d+)") + _REBOOT_TIMEOUT = 120 # secs def __init__(self): hv_base.BaseHypervisor.__init__(self) @@ -686,12 +687,20 @@ class LXCHypervisor(hv_base.BaseHypervisor): def RebootInstance(self, instance): """Reboot an instance. - This is not (yet) implemented (in Ganeti) for the LXC hypervisor. - """ - # TODO: implement reboot - raise HypervisorError("The LXC hypervisor doesn't implement the" - " reboot functionality") + if "sys_boot" in self._GetInstanceDropCapabilities(instance.hvparams): + raise HypervisorError("The LXC container can't perform reboot with the" + " SYS_BOOT capability dropped.") + + # We can't use the --timeout=-1 approach as same as the StopInstance due to + # the following patch was applied in lxc-1.0.5 and we are supporting + # LXC >= 1.0.0. + # http://lists.linuxcontainers.org/pipermail/lxc-devel/2014-July/009742.html + result = utils.RunCmd(["lxc-stop", "-n", instance.name, "--reboot", + "--timeout", str(self._REBOOT_TIMEOUT)]) + if result.failed: + raise HypervisorError("Failed to reboot instance %s: %s" % + (instance.name, result.output)) def BalloonInstanceMemory(self, instance, mem): """Balloon an instance memory to a certain value. -- 2.0.4
