Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:12.3
lxc
pivot-root_shared.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File pivot-root_shared.patch of Package lxc
From cc28d0b0a66bd956645dc7b8fc85b917711f2472 Mon Sep 17 00:00:00 2001 From: Serge Hallyn <serge.hallyn@canonical.com> Date: Wed, 19 Dec 2012 23:58:44 -0600 Subject: [PATCH] Support MS_SHARED / MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (I'll be out until Jan 2, but in the meantime, here is hopefully a little newyears gift - this seems to allow lxc-start with / being MS_SHARED on the host) When / is MS_SHARED (for instance with f18 and modern arch), lxc-start fails on pivot_root. The kernel enforces that, when doing pivot_root, the parent of current->fs->root (as well as the new root and the putold location) not be MS_SHARED. To work around this, check /proc/self/mountinfo for a 'shared:' in the '/' line. If it is there, then create a tiny MS_SLAVE tmpfs dir to serve as parent of /, recursively bind mount / into /root under that dir, make it rslave, and chroot into it. Tested with ubuntu raring image after doing 'mount --make-rshared /'. Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com> Acked-by: Stéphane Graber <stgraber@ubuntu.com> --- src/lxc/conf.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/lxc/conf.h | 3 ++ src/lxc/start.c | 8 ++++ 3 files changed, 125 insertions(+), 3 deletions(-) Index: lxc-0.7.5/src/lxc/conf.c =================================================================== --- lxc-0.7.5.orig/src/lxc/conf.c +++ lxc-0.7.5/src/lxc/conf.c @@ -716,8 +716,112 @@ static int setup_rootfs_pivot_root(const return 0; } -static int setup_rootfs(const struct lxc_rootfs *rootfs) +/* + * Detect whether / is mounted MS_SHARED. The only way I know of to + * check that is through /proc/self/mountinfo. + * I'm only checking for /. If the container rootfs or mount location + * is MS_SHARED, but not '/', then you're out of luck - figuring that + * out would be too much work to be worth it. + */ +#define LINELEN 4096 +int detect_shared_rootfs(void) { + char buf[LINELEN], *p; + FILE *f; + int i; + char *p2; + + f = fopen("/proc/self/mountinfo", "r"); + if (!f) + return 0; + while ((p = fgets(buf, LINELEN, f))) { + INFO("looking at .%s.", p); + for (p = buf, i=0; p && i < 4; i++) + p = index(p+1, ' '); + if (!p) + continue; + p2 = index(p+1, ' '); + if (!p2) + continue; + *p2 = '\0'; + INFO("now p is .%s.", p); + if (strcmp(p+1, "/") == 0) { + // this is '/'. is it shared? + p = index(p2+1, ' '); + if (strstr(p, "shared:")) + return 1; + } + } + fclose(f); + return 0; +} + +/* + * I'll forgive you for asking whether all of this is needed :) The + * answer is yes. + * pivot_root will fail if the new root, the put_old dir, or the parent + * of current->fs->root are MS_SHARED. (parent of current->fs_root may + * or may not be current->fs_root - if we assumed it always was, we could + * just mount --make-rslave /). So, + * 1. mount a tiny tmpfs to be parent of current->fs->root. + * 2. make that MS_SLAVE + * 3. make a 'root' directory under that + * 4. mount --rbind / under the $tinyroot/root. + * 5. make that rslave + * 6. chdir and chroot into $tinyroot/root + * 7. $tinyroot will be unmounted by our parent in start.c + */ +static int chroot_into_slave(struct lxc_conf *conf) +{ + char path[MAXPATHLEN]; + const char *destpath = conf->rootfs.mount; + int ret; + + if (mount(destpath, destpath, NULL, MS_BIND, 0)) { + SYSERROR("failed to mount %s bind", destpath); + return -1; + } + if (mount("", destpath, NULL, MS_SLAVE, 0)) { + SYSERROR("failed to make %s slave", destpath); + return -1; + } + if (mount("none", destpath, "tmpfs", 0, "size=10000")) { + SYSERROR("Failed to mount tmpfs / at %s", destpath); + return -1; + } + ret = snprintf(path, MAXPATHLEN, "%s/root", destpath); + if (ret < 0 || ret >= MAXPATHLEN) { + ERROR("out of memory making root path"); + return -1; + } + if (mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { + SYSERROR("Failed to create /dev/pts in container"); + return -1; + } + if (mount("/", path, NULL, MS_BIND|MS_REC, 0)) { + SYSERROR("Failed to rbind mount / to %s", path); + return -1; + } + if (mount("", destpath, NULL, MS_SLAVE|MS_REC, 0)) { + SYSERROR("Failed to make tmp-/ at %s rslave", path); + return -1; + } + if (chdir(path)) { + SYSERROR("Failed to chdir into tmp-/"); + return -1; + } + if (chroot(path)) { + SYSERROR("Failed to chroot into tmp-/"); + return -1; + } + INFO("Chrooted into tmp-/ at %s\n", path); + return 0; +} + +static int setup_rootfs(struct lxc_conf *conf) +{ + const struct lxc_rootfs *rootfs = &conf->rootfs; + if (!rootfs->path) return 0; @@ -727,6 +831,13 @@ static int setup_rootfs(const struct lxc return -1; } + if (detect_shared_rootfs()) { + if (chroot_into_slave(conf)) { + ERROR("Failed to chroot into slave /"); + return -1; + } + } + if (mount_rootfs(rootfs->path, rootfs->mount)) { ERROR("failed to mount rootfs"); return -1; @@ -848,7 +959,7 @@ static int setup_console(const struct lx return 0; } -static int setup_cgroup(const char *name, struct lxc_list *cgroups) +int setup_cgroup(const char *name, struct lxc_list *cgroups) { struct lxc_list *iterator; struct lxc_cgroup *cg; @@ -1846,7 +1957,7 @@ int lxc_setup(const char *name, struct l return -1; } - if (setup_rootfs(&lxc_conf->rootfs)) { + if (setup_rootfs(lxc_conf)) { ERROR("failed to setup rootfs for '%s'", name); return -1; } Index: lxc-0.7.5/src/lxc/conf.h =================================================================== --- lxc-0.7.5.orig/src/lxc/conf.h +++ lxc-0.7.5/src/lxc/conf.h @@ -227,6 +227,9 @@ extern int lxc_find_gateway_addresses(st extern int lxc_create_tty(const char *name, struct lxc_conf *conf); extern void lxc_delete_tty(struct lxc_tty_info *tty_info); +extern int setup_cgroup(const char *name, struct lxc_list *cgroups); +extern int detect_shared_rootfs(void); + /* * Configure the container from inside */ Index: lxc-0.7.5/src/lxc/start.c =================================================================== --- lxc-0.7.5.orig/src/lxc/start.c +++ lxc-0.7.5/src/lxc/start.c @@ -535,6 +535,14 @@ int lxc_spawn(struct lxc_handler *handle if (lxc_sync_barrier_child(handler, LXC_SYNC_POST_CONFIGURE)) return -1; + if (detect_shared_rootfs()) + umount2(handler->conf->rootfs.mount, MNT_DETACH); + + if (setup_cgroup(name, &handler->conf->cgroup)) { + ERROR("failed to setup the cgroups for '%s'", name); + goto out_delete_net; + } + if (handler->ops->post_start(handler, handler->data)) goto out_abort; From 859a6da0fac5d214230f8a52777277b5147532fb Mon Sep 17 00:00:00 2001 From: Natanael Copa <ncopa@alpinelinux.org> Date: Tue, 25 Dec 2012 10:53:50 +0100 Subject: [PATCH] define MS_SHARED if needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes build on uClibc. Signed-off-by: Natanael Copa <ncopa@alpinelinux.org> Acked-by: Stéphane Graber <stgraber@ubuntu.com> --- src/lxc/conf.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 96940b3..c82e759 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -87,6 +87,10 @@ lxc_log_define(lxc_conf, lxc); #define MNT_DETACH 2 #endif +#ifndef MS_SLAVE +#define MS_SLAVE (1<<19) +#endif + #ifndef MS_RELATIME #define MS_RELATIME (1 << 21) #endif -- 1.7.10.4
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor