Hi, Current aufs supports FS_USERNS_MOUNT by using module parameter 'allow_userns'. So we can start an unprivileged container using aufs. (But ubuntu kernel do not support it?) https://github.com/sfjro/aufs3-linux/commit/548fa48dbf52ad80e55deb8ca945c4f7814dbf94
How about support unprivileged aufs container? I tried creating the patch. (but I have not done enough test.) This moves the place of xino file to /dev/shm, because get_rundir always return '/run' when mount aufs, so unpriv container can't write. This idea is from docker(https://github.com/docker/docker/pull/826). From 2c489a3887d904f2a4fe771d250fda55947f27d3 Mon Sep 17 00:00:00 2001 From: KATOH Yasufumi <[email protected]> Date: Tue, 21 Apr 2015 19:29:19 +0900 Subject: [PATCH] aufs: Support unprivileged clone, mount Current aufs supports FS_USERNS_MOUNT by using allow_userns module parameter. Signed-off-by: KATOH Yasufumi <[email protected]> --- src/lxc/bdev.c | 62 ++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c index cf7c043..051c34d 100644 --- a/src/lxc/bdev.c +++ b/src/lxc/bdev.c @@ -2552,12 +2552,12 @@ static int aufs_detect(const char *path) // static int aufs_mount(struct bdev *bdev) { - char *options, *dup, *lower, *upper, *rundir; + char *options, *dup, *lower, *upper; int len; unsigned long mntflags; char *mntdata; - char *runpath; int ret; + const char *xinopath = "/dev/shm/lxc"; if (strcmp(bdev->type, "aufs")) return -22; @@ -2583,41 +2583,26 @@ static int aufs_mount(struct bdev *bdev) // TODO We should check whether bdev->src is a blockdev, and if so // but for now, only support aufs of a basic directory - rundir = get_rundir(); - if (!rundir) - return -1; - - len = strlen(rundir) + strlen("/lxc") + 1; - runpath = alloca(len); - ret = snprintf(runpath, len, "%s/lxc", rundir); - if (ret < 0 || ret >= len) { + if (mkdir_p(xinopath, 0755) < 0) { free(mntdata); - free(rundir); - return -1; - } - if (mkdir_p(runpath, 0755) < 0) { - free(mntdata); - free(rundir); return -1; } // AUFS does not work on top of certain filesystems like (XFS or Btrfs) - // so add xino=RUNDIR/lxc/aufs.xino parameter to mount options + // so add xino=/dev/shm/lxc/aufs.xino parameter to mount options // // see http://www.mail-archive.com/[email protected]/msg02587.html if (mntdata) { - len = strlen(lower) + strlen(upper) + strlen(runpath) + strlen("br==rw:=ro,,xino=/aufs.xino") + strlen(mntdata) + 1; + len = strlen(lower) + strlen(upper) + strlen(xinopath) + strlen("br==rw:=ro,,xino=/aufs.xino") + strlen(mntdata) + 1; options = alloca(len); - ret = snprintf(options, len, "br=%s=rw:%s=ro,%s,xino=%s/aufs.xino", upper, lower, mntdata, runpath); + ret = snprintf(options, len, "br=%s=rw:%s=ro,%s,xino=%s/aufs.xino", upper, lower, mntdata, xinopath); } else { - len = strlen(lower) + strlen(upper) + strlen(runpath) + strlen("br==rw:=ro,xino=/aufs.xino") + 1; + len = strlen(lower) + strlen(upper) + strlen(xinopath) + strlen("br==rw:=ro,xino=/aufs.xino") + 1; options = alloca(len); - ret = snprintf(options, len, "br=%s=rw:%s=ro,xino=%s/aufs.xino", upper, lower, runpath); + ret = snprintf(options, len, "br=%s=rw:%s=ro,xino=%s/aufs.xino", upper, lower, xinopath); } - free(rundir); - if (ret < 0 || ret >= len) { free(mntdata); return -1; @@ -2660,6 +2645,9 @@ static int aufs_clonepaths(struct bdev *orig, struct bdev *new, const char *oldn if (mkdir_p(new->dest, 0755) < 0) return -1; + if (am_unpriv() && chown_mapped_root(new->dest, conf) < 0) + WARN("Failed to update ownership of %s", new->dest); + if (strcmp(orig->type, "dir") == 0) { char *delta, *lastslash; int ret, len, lastslashidx; @@ -2684,6 +2672,8 @@ static int aufs_clonepaths(struct bdev *orig, struct bdev *new, const char *oldn free(delta); return -1; } + if (am_unpriv() && chown_mapped_root(delta, conf) < 0) + WARN("Failed to update ownership of %s", delta); // the src will be 'aufs:lowerdir:upperdir' len = strlen(delta) + strlen(orig->src) + 12; @@ -2717,7 +2707,23 @@ static int aufs_clonepaths(struct bdev *orig, struct bdev *new, const char *oldn free(osrc); return -ENOMEM; } - if (do_rsync(odelta, ndelta) < 0) { + if ((ret = mkdir(ndelta, 0755)) < 0 && errno != EEXIST) { + SYSERROR("error: mkdir %s", ndelta); + free(osrc); + free(ndelta); + return -1; + } + if (am_unpriv() && chown_mapped_root(ndelta, conf) < 0) + WARN("Failed to update ownership of %s", ndelta); + + struct rsync_data_char rdata; + rdata.src = odelta; + rdata.dest = ndelta; + if (am_unpriv()) + ret = userns_exec_1(conf, rsync_delta_wrapper, &rdata); + else + ret = rsync_delta(&rdata); + if (ret) { free(osrc); free(ndelta); ERROR("copying aufs delta"); @@ -3306,6 +3312,7 @@ static bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap, // (unless snap && b->type == dir, in which case it will be // overlayfs -- which is also allowed) if (strcmp(b->type, "dir") == 0 || + strcmp(b->type, "aufs") == 0 || strcmp(b->type, "overlayfs") == 0 || strcmp(b->type, "btrfs") == 0 || strcmp(b->type, "loop") == 0) @@ -3315,8 +3322,11 @@ static bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap, // unprivileged users can copy and snapshot dir, overlayfs, // and loop. In particular, not zfs, btrfs, or lvm. - if (strcmp(t, "dir") == 0 || strcmp(t, "overlayfs") == 0 || - strcmp(t, "btrfs") == 0 || strcmp(t, "loop") == 0) + if (strcmp(t, "dir") == 0 || + strcmp(t, "aufs") == 0 || + strcmp(t, "overlayfs") == 0 || + strcmp(t, "btrfs") == 0 || + strcmp(t, "loop") == 0) return true; return false; } -- 2.2.1 _______________________________________________ lxc-devel mailing list [email protected] http://lists.linuxcontainers.org/listinfo/lxc-devel
