[lxc-devel] [PATCH] overlayfs_clone: rsync the mounted rootfs

Stéphane Graber stgraber at ubuntu.com
Mon Sep 21 15:38:11 UTC 2015


On Thu, Sep 17, 2015 at 05:26:12PM +0000, Serge Hallyn wrote:
> Closes #655
> 
> We can't rsync the delta as unpriv user because we can't create
> the chardevs representing a whiteout.  We can however rsync the
> rootfs and have the kernel create the whiteouts for us.
> 
> do_rsync: pass --delete
> 
> Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>

Acked-by: Stéphane Graber <stgraber at ubuntu.com>

> ---
>  src/lxc/bdev.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++----------
>  1 file changed, 70 insertions(+), 14 deletions(-)
> 
> diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c
> index ada3958..1694adb 100644
> --- a/src/lxc/bdev.c
> +++ b/src/lxc/bdev.c
> @@ -72,6 +72,11 @@
>  
>  lxc_log_define(bdev, lxc);
>  
> +struct ovl_rsync_data {
> +	struct bdev *orig;
> +	struct bdev *new;
> +};
> +
>  struct rsync_data_char {
>  	char *src;
>  	char *dest;
> @@ -98,7 +103,7 @@ static int do_rsync(const char *src, const char *dest)
>  	s[l-2] = '/';
>  	s[l-1] = '\0';
>  
> -	execlp("rsync", "rsync", "-aHX", s, dest, (char *)NULL);
> +	execlp("rsync", "rsync", "-aHX", "--delete", s, dest, (char *)NULL);
>  	exit(1);
>  }
>  
> @@ -2328,6 +2333,68 @@ static int rsync_delta_wrapper(void *data)
>  	return rsync_delta(arg);
>  }
>  
> +static int ovl_rsync(struct ovl_rsync_data *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 (unshare(CLONE_NEWNS) < 0) {
> +		SYSERROR("Unable to unshare mounts ns");
> +		return -1;
> +	}
> +	if (detect_shared_rootfs()) {
> +		if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
> +			SYSERROR("Failed to make / rslave");
> +			ERROR("Continuing...");
> +		}
> +	}
> +	if (overlayfs_mount(data->orig) < 0) {
> +		ERROR("Failed mounting original container fs");
> +		return -1;
> +	}
> +	if (overlayfs_mount(data->new) < 0) {
> +		ERROR("Failed mounting new container fs");
> +		return -1;
> +	}
> +	if (do_rsync(data->orig->dest, data->new->dest) < 0) {
> +		ERROR("rsyncing %s to %s", data->orig->dest, data->new->dest);
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int ovl_rsync_wrapper(void *data)
> +{
> +	struct ovl_rsync_data *arg = data;
> +	return ovl_rsync(arg);
> +}
> +
> +static int ovl_do_rsync(struct bdev *orig, struct bdev *new, struct lxc_conf *conf)
> +{
> +	int ret = -1;
> +	struct ovl_rsync_data rdata;
> +
> +	rdata.orig = orig;
> +	rdata.new = new;
> +	if (am_unpriv())
> +		ret = userns_exec_1(conf, ovl_rsync_wrapper, &rdata);
> +	else
> +		ret = ovl_rsync(&rdata);
> +	if (ret)
> +		ERROR("copying overlayfs delta");
> +
> +	return ret;
> +}
> +
>  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, struct lxc_conf *conf)
> @@ -2460,19 +2527,6 @@ static int overlayfs_clonepaths(struct bdev *orig, struct bdev *new, const char
>  			WARN("Failed to update ownership of %s", work);
>  		free(work);
>  
> -		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");
> -			return -1;
> -		}
>  		len = strlen(nsrc) + strlen(ndelta) + 12;
>  		new->src = malloc(len);
>  		if (!new->src) {
> @@ -2485,6 +2539,8 @@ static int overlayfs_clonepaths(struct bdev *orig, struct bdev *new, const char
>  		free(ndelta);
>  		if (ret < 0 || ret >= len)
>  			return -ENOMEM;
> +
> +		return ovl_do_rsync(orig, new, conf);
>  	} else {
>  		ERROR("overlayfs clone of %s container is not yet supported",
>  			orig->type);
> -- 
> 2.5.0
> 
> _______________________________________________
> 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/20150921/2622ef0f/attachment-0001.sig>


More information about the lxc-devel mailing list