[lxc-devel] [PATCH] overlay and aufs clone_paths: be more robust
Serge Hallyn
serge.hallyn at ubuntu.com
Thu Oct 16 15:10:21 UTC 2014
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>
---
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
More information about the lxc-devel
mailing list