[lxc-devel] [PATCH 1/1] lxc startup: manually mark every shared mount entry as slave
Serge Hallyn
serge.hallyn at ubuntu.com
Wed Apr 16 16:01:22 UTC 2014
If you 'ip netns add x1', this creates /run/netns and /run/netns/x1
as shared mounts. When a container starts, it umounts these after
pivot_root, and the umount is propagated to the host.
Worse, doing mount("", "/", NULL, MS_SLAVE|MS_REC, NULL) does not
suffice to change those, even after binding /proc/mounts onto
/etc/mtab.
So, I give up. Do this manually, walking over /proc/self/mountinfo
and changing the mount propagation on everything marked as shared.
With this patch, lxc-start no longer unmounts /run/netns/* on the
host.
Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
---
src/lxc/conf.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 62 insertions(+), 6 deletions(-)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 06235fb..4052c5f 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -3706,6 +3706,66 @@ void tmp_proc_unmount(struct lxc_conf *lxc_conf)
}
}
+static void null_endofword(char *word)
+{
+ while (*word && *word != ' ' && *word != '\t')
+ word++;
+ *word = '\0';
+}
+
+/*
+ * skip @nfields spaces in @src
+ */
+static char *get_field(char *src, int nfields)
+{
+ char *p = src;
+ int i;
+
+ for (i = 0; i < nfields; i++) {
+ while (*p && *p != ' ' && *p != '\t')
+ p++;
+ if (!p)
+ break;
+ p++;
+ }
+ return p;
+}
+
+static void remount_all_slave(void)
+{
+ /* walk /proc/mounts and change any shared entries to slave */
+ FILE *f = fopen("/proc/self/mountinfo", "r");
+ char *line = NULL;
+ size_t len = 0;
+
+ if (!f) {
+ SYSERROR("Failed to open /proc/self/mountinfo to mark all shared");
+ ERROR("Continuing container startup...");
+ return;
+ }
+
+ while (getline(&line, &len, f) != -1) {
+ char *target, *opts;
+ target = get_field(line, 4);
+ if (!target)
+ continue;
+ opts = get_field(target, 2);
+ if (!opts)
+ continue;
+ null_endofword(opts);
+ if (!strstr(opts, "shared"))
+ continue;
+ null_endofword(target);
+ if (mount(NULL, target, NULL, MS_SLAVE, NULL)) {
+ SYSERROR("Failed to make %s rslave", target);
+ ERROR("Continuing...");
+ }
+ }
+ fclose(f);
+ if (line)
+ free(line);
+}
+
int lxc_setup(struct lxc_handler *handler)
{
const char *name = handler->name;
@@ -3713,12 +3773,6 @@ int lxc_setup(struct lxc_handler *handler)
const char *lxcpath = handler->lxcpath;
void *data = handler->data;
- if (detect_shared_rootfs()) {
- if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
- SYSERROR("Failed to make / rslave");
- ERROR("Continuing...");
- }
- }
if (detect_ramfs_rootfs()) {
if (chroot_into_slave(lxc_conf)) {
ERROR("Failed to chroot into slave /");
@@ -3726,6 +3780,8 @@ int lxc_setup(struct lxc_handler *handler)
}
}
+ remount_all_slave();
+
if (lxc_conf->inherit_ns_fd[LXC_NS_UTS] == -1) {
if (setup_utsname(lxc_conf->utsname)) {
ERROR("failed to setup the utsname for '%s'", name);
--
1.9.1
More information about the lxc-devel
mailing list