[lxc-devel] [PATCH 1/1] overlayfs_clonepaths: if unpriv then rsync in a userns
Stéphane Graber
stgraber at ubuntu.com
Thu Feb 13 15:10:08 UTC 2014
On Thu, Feb 13, 2014 at 12:52:52AM -0600, Serge Hallyn wrote:
> This allows lxc-snapshot and lxc-clone -s from an overlayfs container
> to work unprivileged. (lxc-clone -s from a directory backed container
> already did work)
>
> Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
Acked-by: Stéphane Graber <stgraber at ubuntu.com>
> ---
> src/lxc/bdev.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
> src/lxc/bdev.h | 2 +-
> 2 files changed, 62 insertions(+), 10 deletions(-)
>
> diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c
> index 1df602c..67fe72b 100644
> --- a/src/lxc/bdev.c
> +++ b/src/lxc/bdev.c
> @@ -442,7 +442,7 @@ static char *dir_new_path(char *src, const char *oldname, const char *name,
> */
> static int dir_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
> const char *cname, const char *oldpath, const char *lxcpath, int snap,
> - uint64_t newsize)
> + uint64_t newsize, struct lxc_conf *conf)
> {
> int len, ret;
>
> @@ -667,7 +667,7 @@ static int zfs_clone(const char *opath, const char *npath, const char *oname,
>
> static int zfs_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
> const char *cname, const char *oldpath, const char *lxcpath, int snap,
> - uint64_t newsize)
> + uint64_t newsize, struct lxc_conf *conf)
> {
> int len, ret;
>
> @@ -1001,7 +1001,7 @@ static int is_blktype(struct bdev *b)
>
> static int lvm_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
> const char *cname, const char *oldpath, const char *lxcpath, int snap,
> - uint64_t newsize)
> + uint64_t newsize, struct lxc_conf *conf)
> {
> char fstype[100];
> uint64_t size = newsize;
> @@ -1374,7 +1374,7 @@ out:
>
> 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)
> + uint64_t newsize, struct lxc_conf *conf)
> {
> if (!orig->dest || !orig->src)
> return -1;
> @@ -1626,7 +1626,7 @@ static int do_loop_create(const char *path, uint64_t size, const char *fstype)
> */
> static int loop_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
> const char *cname, const char *oldpath, const char *lxcpath, int snap,
> - uint64_t newsize)
> + uint64_t newsize, struct lxc_conf *conf)
> {
> char fstype[100];
> uint64_t size = newsize;
> @@ -1826,9 +1826,40 @@ 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) {
> + 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;
> + }
> + if (do_rsync(data->src, data->dest) < 0) {
> + ERROR("rsyncing %s to %s", data->src, data->dest);
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +static int rsync_delta_wrapper(void *data)
> +{
> + struct rsync_data_char *arg = data;
> + return rsync_delta(arg);
> +}
> +
> static int overlayfs_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
> const char *cname, const char *oldpath, const char *lxcpath, int snap,
> - uint64_t newsize)
> + uint64_t newsize, struct lxc_conf *conf)
> {
> if (!snap) {
> ERROR("overlayfs is only for snapshot clones");
> @@ -1844,6 +1875,9 @@ static int overlayfs_clonepaths(struct bdev *orig, struct bdev *new, const char
> 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;
> int ret, len;
> @@ -1864,6 +1898,8 @@ static int overlayfs_clonepaths(struct bdev *orig, struct bdev *new, const char
> 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 'overlayfs:lowerdir:upperdir'
> len = strlen(delta) + strlen(orig->src) + 12;
> @@ -1897,7 +1933,22 @@ static int overlayfs_clonepaths(struct bdev *orig, struct bdev *new, const char
> free(osrc);
> return -ENOMEM;
> }
> - if (do_rsync(odelta, ndelta) < 0) {
> + if ((ret = mkdir(ndelta, 0755)) < 0) {
> + 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 overlayfs delta");
> @@ -2079,7 +2130,7 @@ static int aufs_umount(struct bdev *bdev)
>
> static int aufs_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
> const char *cname, const char *oldpath, const char *lxcpath, int snap,
> - uint64_t newsize)
> + uint64_t newsize, struct lxc_conf *conf)
> {
> if (!snap) {
> ERROR("aufs is only for snapshot clones");
> @@ -2491,7 +2542,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
> return NULL;
> }
>
> - if (new->ops->clone_paths(orig, new, oldname, cname, oldpath, lxcpath, snap, newsize) < 0) {
> + if (new->ops->clone_paths(orig, new, oldname, cname, oldpath, lxcpath,
> + snap, newsize, c0->lxc_conf) < 0) {
> ERROR("failed getting pathnames for cloned storage: %s", src);
> bdev_put(orig);
> bdev_put(new);
> diff --git a/src/lxc/bdev.h b/src/lxc/bdev.h
> index 250e320..7efc164 100644
> --- a/src/lxc/bdev.h
> +++ b/src/lxc/bdev.h
> @@ -62,7 +62,7 @@ struct bdev_ops {
> /* given original mount, rename the paths for cloned container */
> int (*clone_paths)(struct bdev *orig, struct bdev *new, const char *oldname,
> const char *cname, const char *oldpath, const char *lxcpath,
> - int snap, uint64_t newsize);
> + int snap, uint64_t newsize, struct lxc_conf *conf);
> bool can_snapshot;
> };
>
> --
> 1.9.rc1
>
> _______________________________________________
> 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/20140213/4e76d3c2/attachment.pgp>
More information about the lxc-devel
mailing list