This patch implements the RebootInstance functionality of the
LXCHypervisor.
Reboot of the LXC container can be done by using the lxc-stop command
with the --reboot switch. Internally this just sends SIGINT to 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 CAP_SYS_BOOT was dropped from the container
and raises an error to enforce that requirement.
It is up to users to decide if they use the soft reboot of the LXC
container by 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..52007b5 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 a 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

Reply via email to