[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH] lxc: Prevent shutting down the host



When the container has the same '/dev' mount as host (no chroot),
calling domainShutdown(WithFlags) shouldn't shutdown the host it is
running on.

Signed-off-by: Martin Kletzander <mkletzan redhat com>
---
This is also valid for 1.0.[23]-maint branches, so in case this gets
ACK'd I'll either send a follow-up for those or push it there as well
(if the ACK says so).

 src/lxc/lxc_driver.c | 45 ++++++++++++++++++++++++++++-----------------
 1 file changed, 28 insertions(+), 17 deletions(-)

diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 8603078..ba14db7 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2012 Red Hat, Inc.
+ * Copyright (C) 2010-2013 Red Hat, Inc.
  * Copyright IBM Corp. 2008
  *
  * lxc_driver.c: linux container driver functions
@@ -2778,13 +2778,19 @@ lxcDomainShutdownFlags(virDomainPtr dom,
     virLXCDriverPtr driver = dom->conn->privateData;
     virLXCDomainObjPrivatePtr priv;
     virDomainObjPtr vm;
+    virDomainFSDefPtr root;
     char *vroot = NULL;
     int ret = -1;
-    int rc;
+    int rc = 0;
+    bool methodSignal;
+    bool methodInitctl;

     virCheckFlags(VIR_DOMAIN_SHUTDOWN_INITCTL |
                   VIR_DOMAIN_SHUTDOWN_SIGNAL, -1);

+    methodSignal = !!(flags & VIR_DOMAIN_SHUTDOWN_SIGNAL);
+    methodInitctl = !!(flags & VIR_DOMAIN_SHUTDOWN_INITCTL);
+
     lxcDriverLock(driver);
     vm = virDomainObjListFindByUUID(driver->domains, dom->uuid);
     lxcDriverUnlock(driver);
@@ -2798,6 +2804,7 @@ lxcDomainShutdownFlags(virDomainPtr dom,
     }

     priv = vm->privateData;
+    root = virDomainGetRootFilesystem(vm->def);

     if (!virDomainObjIsActive(vm)) {
         virReportError(VIR_ERR_OPERATION_INVALID,
@@ -2817,27 +2824,31 @@ lxcDomainShutdownFlags(virDomainPtr dom,
         goto cleanup;
     }

-    if (flags == 0 ||
-        (flags & VIR_DOMAIN_SHUTDOWN_INITCTL)) {
-        if ((rc = virInitctlSetRunLevel(VIR_INITCTL_RUNLEVEL_POWEROFF,
-                                        vroot)) < 0) {
+    if (root && root->src) {
+        if (flags == 0)
+            methodSignal = methodInitctl = true;
+    } else if (methodInitctl) {
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                       _("Cannot shutdown container using initctl "
+                         "without separated namespace"));
+        goto cleanup;
+    } else {
+        methodSignal = true;
+    }
+
+    if (methodInitctl) {
+        rc = virInitctlSetRunLevel(VIR_INITCTL_RUNLEVEL_POWEROFF, vroot);
+        if (rc < 0)
             goto cleanup;
-        }
-        if (rc == 0 && flags != 0 &&
-            ((flags & ~VIR_DOMAIN_SHUTDOWN_INITCTL) == 0)) {
+        if (rc == 0 && !methodSignal) {
             virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
                            _("Container does not provide an initctl pipe"));
             goto cleanup;
         }
-    } else {
-        rc = 0;
     }
-
-    if (rc == 0 &&
-        (flags == 0 ||
-         (flags & VIR_DOMAIN_SHUTDOWN_SIGNAL))) {
-        if (kill(priv->initpid, SIGTERM) < 0 &&
-            errno != ESRCH) {
+    if (rc == 0 && methodSignal) {
+        ret = kill(priv->initpid, SIGTERM);
+        if (ret < 0 && errno != ESRCH) {
             virReportSystemError(errno,
                                  _("Unable to send SIGTERM to init pid %llu"),
                                  (unsigned long long)priv->initpid);
--
1.8.1.5


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]