This is an alternative to the pivot_root patch which I just sent. It has the advantage of being much simpler. It also won't have a problem with the container's / being a read-only mount. It has the disadvantage, of course, of being escapable. >From a91bca7f60f27e8fbdb4e3bacf3232a6cbb630d3 Mon Sep 17 00:00:00 2001 From: root <root@xxxxxxxxxxxxxxxxxxxxx> Date: Fri, 3 Apr 2009 23:35:24 -0400 Subject: [PATCH 1/1] lxc: use chroot instead of pivot_root pivot_root is too fragile. For instance, if the container's / is read-only, we can't create .oldroot. Maybe we're happy telling users that if they can't create .oldroot at container create time, then they must make sure it exists ahead of time. Or, maybe we're ok with chroot being escapable, and should just go this simple route. Signed-off-by: Serge Hallyn <serue@xxxxxxxxxx> --- src/lxc_container.c | 75 +++++++++++++-------------------------------------- 1 files changed, 19 insertions(+), 56 deletions(-) diff --git a/src/lxc_container.c b/src/lxc_container.c index 3f17b8d..142ed4d 100644 --- a/src/lxc_container.c +++ b/src/lxc_container.c @@ -264,52 +264,6 @@ static int lxcContainerChildMountSort(const void *a, const void *b) return strcmp(*sb, *sa); } -static int lxcContainerPivotRoot(virDomainFSDefPtr root) -{ - int rc; - char *oldroot; - - /* First step is to ensure the new root itself is - a mount point */ - if (mount(root->src, root->src, NULL, MS_BIND, NULL) < 0) { - virReportSystemError(NULL, errno, - _("failed to bind new root %s"), - root->src); - return -1; - } - - if (virAsprintf(&oldroot, "%s/.oldroot", root->src) < 0) { - virReportOOMError(NULL); - return -1; - } - - if ((rc = virFileMakePath(oldroot)) < 0) { - virReportSystemError(NULL, rc, - _("failed to create %s"), - oldroot); - VIR_FREE(oldroot); - return -1; - } - - /* The old root directory will live at /.oldroot after - * this and will soon be unmounted completely */ - if (pivot_root(root->src, oldroot) < 0) { - virReportSystemError(NULL, errno, - _("failed to pivot root %s to %s"), - oldroot, root->src); - VIR_FREE(oldroot); - return -1; - } - VIR_FREE(oldroot); - - /* CWD is undefined after pivot_root, so go to / */ - if (chdir("/") < 0) { - return -1; - } - - return 0; -} - static int lxcContainerPopulateDevices(void) { int i; @@ -349,10 +303,9 @@ static int lxcContainerPopulateDevices(void) _("cannot create /dev/pts")); return -1; } - if (mount("/.oldroot/dev/pts", "/dev/pts", NULL, - MS_MOVE, NULL) < 0) { + if (mount("devpts", "/dev/pts", "devpts", 0, NULL) < 0) { virReportSystemError(NULL, errno, "%s", - _("failed to move /dev/pts into container")); + _("failed to mount /dev/pts in container")); return -1; } @@ -461,15 +414,25 @@ static int lxcContainerUnmountOldFS(void) } -/* Got a FS mapped to /, we're going the pivot_root - * approach to do a better-chroot-than-chroot - * this is based on this thread http://lkml.org/lkml/2008/3/5/29 - */ -static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef, +/* Got a FS mapped to /, now chroot. + * pivot_root would work, but requires too much hand-holding + * (especially, old_root->parent must not be shared) */ +static int lxcContainerSetupChroot(virDomainDefPtr vmDef, virDomainFSDefPtr root) { - if (lxcContainerPivotRoot(root) < 0) + if (chdir(root->src) < 0) { + virReportSystemError(NULL, errno, + _("failed to chdir to %s"), + root->src); + return -1; + } + + if (chroot(root->src) < 0) { + virReportSystemError(NULL, errno, + _("failed to chroot to %s"), + root->src); return -1; + } if (virFileMakePath("/proc") < 0 || mount("none", "/proc", "proc", 0, NULL) < 0) { @@ -537,7 +500,7 @@ static int lxcContainerSetupMounts(virDomainDefPtr vmDef) } if (root) - return lxcContainerSetupPivotRoot(vmDef, root); + return lxcContainerSetupChroot(vmDef, root); else return lxcContainerSetupExtraMounts(vmDef); } -- 1.6.2 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list