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(a)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