[libvirt] [PATCH 1/2] LXC: fix the problem that libvirt lxc fail to start on latest kernel

Gao feng gaofeng at cn.fujitsu.com
Tue Nov 19 09:53:20 UTC 2013


After kernel commit 5ff9d8a65ce80efb509ce4e8051394e9ed2cd942
vfs: Lock in place mounts from more privileged users,

unprivileged user has no rights to move the mounts that
inherited from parent mountns. we use this feature to move
the /stateDir/domain-name.{dev, devpts} to the /dev/ and
/dev/pts directroy of container. this commit breaks libvirt lxc.

this patch do the moving on host side, we are privileged user
at this moment.

Signed-off-by: Gao feng <gaofeng at cn.fujitsu.com>
---
 src/lxc/lxc_container.c  | 81 +-----------------------------------------------
 src/lxc/lxc_controller.c | 53 +++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+), 80 deletions(-)

diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 2bdf957..61283e4 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -953,76 +953,6 @@ static int lxcContainerMountProcFuse(virDomainDefPtr def ATTRIBUTE_UNUSED,
 }
 #endif
 
-static int lxcContainerMountFSDev(virDomainDefPtr def,
-                                  const char *stateDir)
-{
-    int ret = -1;
-    char *path = NULL;
-
-    VIR_DEBUG("Mount /dev/ stateDir=%s", stateDir);
-
-    if ((ret = virAsprintf(&path, "/.oldroot/%s/%s.dev",
-                           stateDir, def->name)) < 0)
-        return ret;
-
-    if (virFileMakePath("/dev") < 0) {
-        virReportSystemError(errno, "%s",
-                             _("Cannot create /dev"));
-        goto cleanup;
-    }
-
-    VIR_DEBUG("Trying to move %s to /dev", path);
-
-    if (mount(path, "/dev", NULL, MS_MOVE, NULL) < 0) {
-        virReportSystemError(errno,
-                             _("Failed to mount %s on /dev"),
-                             path);
-        goto cleanup;
-    }
-
-    ret = 0;
-
-cleanup:
-    VIR_FREE(path);
-    return ret;
-}
-
-static int lxcContainerMountFSDevPTS(virDomainDefPtr def,
-                                     const char *stateDir)
-{
-    int ret;
-    char *path = NULL;
-
-    VIR_DEBUG("Mount /dev/pts stateDir=%s", stateDir);
-
-    if ((ret = virAsprintf(&path,
-                           "/.oldroot/%s/%s.devpts",
-                           stateDir,
-                           def->name)) < 0)
-        return ret;
-
-    if (virFileMakePath("/dev/pts") < 0) {
-        virReportSystemError(errno, "%s",
-                             _("Cannot create /dev/pts"));
-        goto cleanup;
-    }
-
-    VIR_DEBUG("Trying to move %s to /dev/pts", path);
-
-    if ((ret = mount(path, "/dev/pts",
-                     NULL, MS_MOVE, NULL)) < 0) {
-        virReportSystemError(errno,
-                             _("Failed to mount %s on /dev/pts"),
-                             path);
-        goto cleanup;
-    }
-
-cleanup:
-    VIR_FREE(path);
-
-    return ret;
-}
-
 static int lxcContainerSetupDevices(char **ttyPaths, size_t nttyPaths)
 {
     size_t i;
@@ -1683,14 +1613,6 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef,
     if (virCgroupIsolateMount(cgroup, "/.oldroot/", sec_mount_options) < 0)
         goto cleanup;
 
-    /* Mounts /dev */
-    if (lxcContainerMountFSDev(vmDef, stateDir) < 0)
-        goto cleanup;
-
-    /* Mounts /dev/pts */
-    if (lxcContainerMountFSDevPTS(vmDef, stateDir) < 0)
-        goto cleanup;
-
     /* Setup device nodes in /dev/ */
     if (lxcContainerSetupDevices(ttyPaths, nttyPaths) < 0)
         goto cleanup;
@@ -1853,8 +1775,7 @@ static int lxcContainerChild(void *data)
         const char *tty = argv->ttyPaths[0];
         if (STRPREFIX(tty, "/dev/pts/"))
             tty += strlen("/dev/pts/");
-        if (virAsprintf(&ttyPath, "%s/%s.devpts/%s",
-                        LXC_STATE_DIR, vmDef->name, tty) < 0)
+        if (virAsprintf(&ttyPath, "%s/dev/pts/%s", root->src, tty) < 0)
             goto cleanup;
     } else if (VIR_STRDUP(ttyPath, "/dev/null") < 0) {
             goto cleanup;
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index c013147..f7b4127 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -2020,6 +2020,56 @@ cleanup:
 }
 
 
+static int
+virLXCControllerMoveMount(char *name, char *root,
+                          const char *s, const char *d)
+{
+    int ret = -1;
+    char *src = NULL;
+    char *dst = NULL;
+
+    if ((ret = virAsprintf(&src, "%s/%s.%s",
+                           LXC_STATE_DIR, name, s)) < 0)
+        return ret;
+
+    if ((ret = virAsprintf(&dst, "%s%s", root, d)) < 0)
+        goto cleanup;
+
+    if (virFileMakePath(dst) < 0) {
+        virReportSystemError(errno, _("Cannot create %s"), dst);
+        goto cleanup;
+    }
+
+    if (mount(src, dst, NULL, MS_MOVE, NULL) < 0) {
+        virReportSystemError(errno,
+                             _("Failed to mount %s on %s"),
+                             src, dst);
+        goto cleanup;
+    }
+
+    ret = 0;
+cleanup:
+    VIR_FREE(src);
+    VIR_FREE(dst);
+    return ret;
+}
+
+static int
+virLXCControllerMoveMounts(virDomainDefPtr def)
+{
+    virDomainFSDefPtr root = virDomainGetRootFilesystem(def);
+
+    if (virLXCControllerMoveMount(def->name, root->src,
+                                  "dev", "/dev") < 0)
+        return -1;
+
+    if (virLXCControllerMoveMount(def->name, root->src,
+                                  "devpts", "/dev/pts") < 0)
+        return -1;
+
+    return 0;
+}
+
 static void
 virLXCControllerEventSend(virLXCControllerPtr ctrl,
                           int procnr,
@@ -2167,6 +2217,9 @@ virLXCControllerRun(virLXCControllerPtr ctrl)
     if (virLXCControllerSetupConsoles(ctrl, containerTTYPaths) < 0)
         goto cleanup;
 
+    if (virLXCControllerMoveMounts(ctrl->def) < 0)
+        goto cleanup;
+
     if (lxcSetPersonality(ctrl->def) < 0)
         goto cleanup;
 
-- 
1.8.3.1




More information about the libvir-list mailing list