[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