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@xxxxxxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list