[lxc-devel] [PATCH] overlay and aufs clone_paths: be more robust

Stéphane Graber stgraber at ubuntu.com
Mon Oct 27 21:38:32 UTC 2014


On Thu, Oct 16, 2014 at 03:10:21PM +0000, Serge Hallyn wrote:
> Currently when we clone a container, bdev_copy passes NULL as dst argument
> of bdev_init, then sees bdev->dest (as a result) is NULL, and sets
> bdev->dest to $lxcpath/$name/rootfs.  so $ops->clone_paths() can
> assume that "/rootfs" is at the end of the path.  The overlayfs and
> aufs clonepaths do assume that and index to endofstring-6 and append
> delta0.  Let's be more robust by actually finding the last / in
> the path.
> 
> Then, instead of always setting oldbdev->dest to $lxcpath/$name/rootfs,
> set it to oldbdev->src.  Else dir_clonepaths fails when mounting src
> onto dest bc dest does not exist.  We could also fix that by creating
> bdev->dest if needed, but that addes an empty directory to the old
> container.
> 
> This fixes 'lxc-clone -o x1 -n x2' if x1 has lxc.rootfs = /var/lib/lxc/x1/x
> and makes the overlayfs and aufs paths less fragile should something else
> change.
> 
> Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>

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

> ---
>  src/lxc/bdev.c | 68 ++++++++++++++++++++++++++--------------------------------
>  1 file changed, 30 insertions(+), 38 deletions(-)
> 
> diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c
> index 4fc10f2..8a819ab 100644
> --- a/src/lxc/bdev.c
> +++ b/src/lxc/bdev.c
> @@ -2265,20 +2265,24 @@ static int overlayfs_clonepaths(struct bdev *orig, struct bdev *new, const char
>  		WARN("Failed to update ownership of %s", new->dest);
>  
>  	if (strcmp(orig->type, "dir") == 0) {
> -		char *delta;
> -		int ret, len;
> +		char *delta, *lastslash;
> +		int ret, len, lastslashidx;
>  
>  		// if we have /var/lib/lxc/c2/rootfs, then delta will be
>  		//            /var/lib/lxc/c2/delta0
> -		delta = strdup(new->dest);
> -		if (!delta) {
> -			return -1;
> -		}
> -		if (strlen(delta) < 6) {
> -			free(delta);
> +		lastslash = strrchr(new->dest, '/');
> +		if (!lastslash)
>  			return -22;
> -		}
> -		strcpy(&delta[strlen(delta)-6], "delta0");
> +		if (strlen(lastslash) < 7)
> +			return -22;
> +		lastslash++;
> +		lastslashidx = lastslash - new->dest;
> +
> +		delta = malloc(lastslashidx + 7);
> +		if (!delta)
> +			return -1;
> +		strncpy(delta, new->dest, lastslashidx+1);
> +		strcpy(delta+lastslashidx, "delta0");
>  		if ((ret = mkdir(delta, 0755)) < 0) {
>  			SYSERROR("error: mkdir %s", delta);
>  			free(delta);
> @@ -2319,7 +2323,7 @@ static int overlayfs_clonepaths(struct bdev *orig, struct bdev *new, const char
>  			free(osrc);
>  			return -ENOMEM;
>  		}
> -		if ((ret = mkdir(ndelta, 0755)) < 0) {
> +		if ((ret = mkdir(ndelta, 0755)) < 0 && errno != EEXIST) {
>  			SYSERROR("error: mkdir %s", ndelta);
>  			free(osrc);
>  			free(ndelta);
> @@ -2560,20 +2564,24 @@ static int aufs_clonepaths(struct bdev *orig, struct bdev *new, const char *oldn
>  		return -1;
>  
>  	if (strcmp(orig->type, "dir") == 0) {
> -		char *delta;
> -		int ret, len;
> +		char *delta, *lastslash;
> +		int ret, len, lastslashidx;
>  
>  		// if we have /var/lib/lxc/c2/rootfs, then delta will be
>  		//            /var/lib/lxc/c2/delta0
> -		delta = strdup(new->dest);
> -		if (!delta) {
> -			return -1;
> -		}
> -		if (strlen(delta) < 6) {
> -			free(delta);
> +		lastslash = strrchr(new->dest, '/');
> +		if (!lastslash)
>  			return -22;
> -		}
> -		strcpy(&delta[strlen(delta)-6], "delta0");
> +		if (strlen(lastslash) < 7)
> +			return -22;
> +		lastslash++;
> +		lastslashidx = lastslash - new->dest;
> +
> +		delta = malloc(lastslashidx + 7);
> +		if (!delta)
> +			return -1;
> +		strncpy(delta, new->dest, lastslashidx+1);
> +		strcpy(delta+lastslashidx, "delta0");
>  		if ((ret = mkdir(delta, 0755)) < 0) {
>  			SYSERROR("error: mkdir %s", delta);
>  			free(delta);
> @@ -3248,28 +3256,12 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
>  		return NULL;
>  	}
>  
> -	orig = bdev_init(c0->lxc_conf, src, NULL, NULL);
> +	orig = bdev_init(c0->lxc_conf, src, src, NULL);
>  	if (!orig) {
>  		ERROR("failed to detect blockdev type for %s", src);
>  		return NULL;
>  	}
>  
> -	if (!orig->dest) {
> -		int ret;
> -		orig->dest = malloc(MAXPATHLEN);
> -		if (!orig->dest) {
> -			ERROR("out of memory");
> -			bdev_put(orig);
> -			return NULL;
> -		}
> -		ret = snprintf(orig->dest, MAXPATHLEN, "%s/%s/rootfs", oldpath, oldname);
> -		if (ret < 0 || ret >= MAXPATHLEN) {
> -			ERROR("rootfs path too long");
> -			bdev_put(orig);
> -			return NULL;
> -		}
> -	}
> -
>  	/*
>  	 * special case for snapshot - if caller requested maybe_snapshot and
>  	 * keepbdevtype and backing store is directory, then proceed with a copy
> -- 
> 2.1.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/20141027/58f31136/attachment-0001.sig>


More information about the lxc-devel mailing list