[lxc-devel] [PATCH] btrfs: support unprivileged create and clone
Stéphane Graber
stgraber at ubuntu.com
Wed May 7 03:29:58 UTC 2014
On Tue, May 06, 2014 at 08:50:45PM +0000, Serge Hallyn wrote:
> btrfs subvolume ioctls are usable by unprivileged users, so allow
> unprivileged containers to reside on btrfs.
>
> This patch does not yet enable destroy.
>
> Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
Acked-by: Stéphane Graber <stgraber at ubuntu.com>
> ---
> src/lxc/bdev.c | 41 +++++++++++++++++++++++++++++++++--------
> src/lxc/lxc_create.c | 5 +++--
> src/lxc/lxccontainer.c | 4 ++--
> 3 files changed, 38 insertions(+), 12 deletions(-)
>
> diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c
> index 49ba8ae..20e9fb3 100644
> --- a/src/lxc/bdev.c
> +++ b/src/lxc/bdev.c
> @@ -66,6 +66,11 @@
>
> lxc_log_define(bdev, lxc);
>
> +struct rsync_data_char {
> + char *src;
> + char *dest;
> +};
> +
> static int do_rsync(const char *src, const char *dest)
> {
> // call out to rsync
> @@ -1433,6 +1438,22 @@ out:
> return ret;
> }
>
> +static int btrfs_snapshot_wrapper(void *data)
> +{
> + struct rsync_data_char *arg = data;
> + if (setgid(0) < 0) {
> + ERROR("Failed to setgid to 0");
> + return -1;
> + }
> + if (setgroups(0, NULL) < 0)
> + WARN("Failed to clear groups");
> + if (setuid(0) < 0) {
> + ERROR("Failed to setuid to 0");
> + return -1;
> + }
> + return btrfs_snapshot(arg->src, arg->dest);
> +}
> +
> static int btrfs_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
> const char *cname, const char *oldpath, const char *lxcpath, int snap,
> uint64_t newsize, struct lxc_conf *conf)
> @@ -1467,8 +1488,14 @@ static int btrfs_clonepaths(struct bdev *orig, struct bdev *new, const char *old
> if (orig->mntopts && (new->mntopts = strdup(orig->mntopts)) == NULL)
> return -1;
>
> - if (snap)
> - return btrfs_snapshot(orig->dest, new->dest);
> + if (snap) {
> + struct rsync_data_char sdata;
> + if (!am_unpriv())
> + return btrfs_snapshot(orig->dest, new->dest);
> + sdata.dest = new->dest;
> + sdata.src = orig->dest;
> + return userns_exec_1(conf, btrfs_snapshot_wrapper, &sdata);
> + }
>
> if (rmdir(new->dest) < 0 && errno != -ENOENT) {
> SYSERROR("removing %s", new->dest);
> @@ -1510,6 +1537,8 @@ static int btrfs_destroy(struct bdev *orig)
> args.name[BTRFS_SUBVOL_NAME_MAX-1] = 0;
> ret = ioctl(fd, BTRFS_IOC_SNAP_DESTROY, &args);
> INFO("btrfs: snapshot create ioctl returned %d", ret);
> + if (ret < 0 && errno == EPERM)
> + INFO("Is the rootfs mounted with -o user_subvol_rm_allowed?");
>
> free(newfull);
> close(fd);
> @@ -1887,11 +1916,6 @@ static int overlayfs_umount(struct bdev *bdev)
> return umount(bdev->dest);
> }
>
> -struct rsync_data_char {
> - char *src;
> - char *dest;
> -};
> -
> static int rsync_delta(struct rsync_data_char *data)
> {
> if (setgid(0) < 0) {
> @@ -2538,6 +2562,7 @@ static bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap,
> // overlayfs -- which is also allowed)
> if (strcmp(b->type, "dir") == 0 ||
> strcmp(b->type, "overlayfs") == 0 ||
> + strcmp(b->type, "btrfs") == 0 ||
> strcmp(b->type, "loop") == 0)
> return true;
> return false;
> @@ -2546,7 +2571,7 @@ 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, "loop") == 0)
> + strcmp(t, "btrfs") == 0 || strcmp(t, "loop") == 0)
> return true;
> return false;
> }
> diff --git a/src/lxc/lxc_create.c b/src/lxc/lxc_create.c
> index caca056..2cc866a 100644
> --- a/src/lxc/lxc_create.c
> +++ b/src/lxc/lxc_create.c
> @@ -229,8 +229,9 @@ int main(int argc, char *argv[])
> fprintf(stderr, "You lack access to %s\n", my_args.lxcpath[0]);
> exit(1);
> }
> - if (strcmp(my_args.bdevtype, "dir") && strcmp(my_args.bdevtype, "_unset")) {
> - fprintf(stderr, "Unprivileged users can only create directory backed containers\n");
> + if (strcmp(my_args.bdevtype, "dir") && strcmp(my_args.bdevtype, "_unset") &&
> + strcmp(my_args.bdevtype, "btrfs")) {
> + fprintf(stderr, "Unprivileged users cannot create %s containers", my_args.bdevtype);
> exit(1);
> }
> }
> diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> index 270b8fc..9e23c7b 100644
> --- a/src/lxc/lxccontainer.c
> +++ b/src/lxc/lxccontainer.c
> @@ -918,9 +918,9 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool quiet
> }
> }
> }
> - if (strcmp(bdev->type, "dir") != 0) {
> + if (strcmp(bdev->type, "dir") && strcmp(bdev->type, "btrfs")) {
> if (geteuid() != 0) {
> - ERROR("non-root users can only create directory-backed containers");
> + ERROR("non-root users can only create btrfs and directory-backed containers");
> exit(1);
> }
> if (bdev->ops->mount(bdev) < 0) {
> --
> 1.7.9.5
>
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel
--
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20140506/7555d026/attachment.sig>
More information about the lxc-devel
mailing list