[lxc-devel] [PATCH] aufs: Support unprivileged clone, mount
KATOH Yasufumi
karma at jazz.email.ne.jp
Mon Apr 27 07:53:25 UTC 2015
Current aufs supports FS_USERNS_MOUNT by using allow_userns module
parameter. It allows root in userns to mount aufs.
This patch allows an unprivileged container to use aufs.
Signed-off-by: KATOH Yasufumi <karma at jazz.email.ne.jp>
---
src/lxc/bdev.c | 65 +++++++++++++++++++++++++++++++---------------------------
1 file changed, 35 insertions(+), 30 deletions(-)
diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c
index cf7c043..eb516c8 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/aufs.xino";
if (strcmp(bdev->type, "aufs"))
return -22;
@@ -2583,41 +2583,21 @@ 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) {
- 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/aufs.xino parameter to mount options
//
// see http://www.mail-archive.com/aufs-users@lists.sourceforge.net/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=") + 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", 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=") + 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", upper, lower, xinopath);
}
- free(rundir);
-
if (ret < 0 || ret >= len) {
free(mntdata);
return -1;
@@ -2660,6 +2640,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 +2667,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 +2702,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 +3307,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 +3317,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
More information about the lxc-devel
mailing list