overlay: correctly handle dependency tracking

parent 31b204e4
...@@ -186,10 +186,11 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char ...@@ -186,10 +186,11 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
} }
} else if (!strcmp(orig->type, "overlayfs") || } else if (!strcmp(orig->type, "overlayfs") ||
!strcmp(orig->type, "overlay")) { !strcmp(orig->type, "overlay")) {
char *osrc, *odelta, *nsrc, *ndelta, *work; char *clean_old_path, *clean_new_path;
char *lastslash; char *lastslash, *ndelta, *nsrc, *odelta, *osrc, *s1, *s2, *s3,
*work;
int ret, lastslashidx; int ret, lastslashidx;
size_t len; size_t len, name_len;
osrc = strdup(orig->src); osrc = strdup(orig->src);
if (!osrc) { if (!osrc) {
...@@ -298,7 +299,93 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char ...@@ -298,7 +299,93 @@ int ovl_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, const char
return -1; return -1;
} }
return ovl_do_rsync(orig, new, conf); ret = ovl_do_rsync(orig, new, conf);
if (ret < 0)
return -1;
/* When we create an overlay snapshot of an overlay container in
* the snapshot directory under "<lxcpath>/<name>/snaps/" we
* don't need to record a dependency. If we would restore would
* also fail.
*/
clean_old_path = lxc_deslashify(oldpath);
if (!clean_old_path)
return -1;
clean_new_path = lxc_deslashify(lxcpath);
if (!clean_new_path) {
free(clean_old_path);
return -1;
}
s1 = strrchr(clean_old_path, '/');
if (!s1) {
ERROR("Failed to detect \"/\" in string \"%s\"", s1);
free(clean_old_path);
free(clean_new_path);
return -1;
}
s2 = strrchr(clean_new_path, '/');
if (!s2) {
ERROR("Failed to detect \"/\" in string \"%s\"", s2);
free(clean_old_path);
free(clean_new_path);
return -1;
}
if (!strncmp(s1, "/snaps", sizeof("/snaps") - 1)) {
s1 = clean_new_path;
s2 = clean_old_path;
s3 = (char *)cname;
name_len = strlen(cname);
len = strlen(clean_new_path);
} else if (!strncmp(s2, "/snaps", sizeof("/snaps") - 1)) {
s1 = clean_old_path;
s2 = clean_new_path;
s3 = (char *)oldname;
name_len = strlen(oldname);
len = strlen(clean_old_path);
} else {
free(clean_old_path);
free(clean_new_path);
return 0;
}
if (!strncmp(s1, s2, len)) {
char *tmp;
tmp = (char *)(s2 + len + 1);
if (*tmp == '\0') {
free(clean_old_path);
free(clean_new_path);
return 0;
}
name_len = strlen(s3);
if (strncmp(s3, tmp, name_len)) {
free(clean_old_path);
free(clean_new_path);
return 0;
}
tmp += name_len + 1;
if (*tmp == '\0') {
free(clean_old_path);
free(clean_new_path);
return 0;
}
if (!strncmp(tmp, "snaps", sizeof("snaps") - 1)) {
free(clean_old_path);
free(clean_new_path);
return LXC_CLONE_SNAPSHOT;
}
}
free(clean_old_path);
free(clean_new_path);
return 0;
} else { } else {
ERROR("overlay clone of %s container is not yet supported", ERROR("overlay clone of %s container is not yet supported",
orig->type); orig->type);
......
...@@ -386,7 +386,7 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname, ...@@ -386,7 +386,7 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname,
snap = false; snap = false;
/* If newtype is NULL and snapshot is set, then use overlay. */ /* If newtype is NULL and snapshot is set, then use overlay. */
if (!bdevtype && !keepbdevtype && snap && strcmp(orig->type, "dir") == 0) if (!bdevtype && !keepbdevtype && snap && !strcmp(orig->type, "dir"))
bdevtype = "overlay"; bdevtype = "overlay";
if (am_unpriv() && !unpriv_snap_allowed(orig, bdevtype, snap, maybe_snap)) { if (am_unpriv() && !unpriv_snap_allowed(orig, bdevtype, snap, maybe_snap)) {
...@@ -396,20 +396,23 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname, ...@@ -396,20 +396,23 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname,
} }
*needs_rdep = false; *needs_rdep = false;
if (bdevtype && !strcmp(orig->type, "dir") && if (bdevtype) {
(strcmp(bdevtype, "aufs") == 0 || if (snap && !strcmp(orig->type, "lvm") &&
strcmp(bdevtype, "overlayfs") == 0 || !lvm_is_thin_volume(orig->src))
strcmp(bdevtype, "overlay") == 0)) { *needs_rdep = true;
*needs_rdep = true; else if (!strcmp(bdevtype, "overlay") ||
} else if (snap && !strcmp(orig->type, "lvm") && !strcmp(bdevtype, "overlayfs"))
!lvm_is_thin_volume(orig->src)) { *needs_rdep = true;
*needs_rdep = true; } else {
} if (!snap && strcmp(oldpath, lxcpath))
bdevtype = "dir";
else
bdevtype = orig->type;
if (strcmp(oldpath, lxcpath) && !bdevtype && !snap) if (!strcmp(bdevtype, "overlay") ||
bdevtype = "dir"; !strcmp(bdevtype, "overlayfs"))
else if (!bdevtype) *needs_rdep = true;
bdevtype = orig->type; }
/* get new bdev type */ /* get new bdev type */
new = storage_get(bdevtype); new = storage_get(bdevtype);
...@@ -428,6 +431,15 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname, ...@@ -428,6 +431,15 @@ struct lxc_storage *storage_copy(struct lxc_container *c, const char *cname,
goto on_error_put_new; goto on_error_put_new;
} }
/* When we create an overlay snapshot of an overlay container in the
* snapshot directory under "<lxcpath>/<name>/snaps/" we don't need to
* record a dependency. If we would restore would also fail.
*/
if ((!strcmp(new->type, "overlay") ||
!strcmp(new->type, "overlayfs")) &&
ret == LXC_CLONE_SNAPSHOT)
*needs_rdep = false;
/* btrfs */ /* btrfs */
if (!strcmp(orig->type, "btrfs") && !strcmp(new->type, "btrfs")) { if (!strcmp(orig->type, "btrfs") && !strcmp(new->type, "btrfs")) {
bool bret = false; bool bret = false;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment