Revert "overlay: simplify and adapt to "overlay""

This reverts commit 7f79cc4c. Signed-off-by: 's avatarChristian Brauner <christian.brauner@ubuntu.com>
parent 16811e0b
...@@ -194,7 +194,6 @@ static const struct bdev_type bdevs[] = { ...@@ -194,7 +194,6 @@ static const struct bdev_type bdevs[] = {
{ .name = "btrfs", .ops = &btrfs_ops, }, { .name = "btrfs", .ops = &btrfs_ops, },
{ .name = "dir", .ops = &dir_ops, }, { .name = "dir", .ops = &dir_ops, },
{ .name = "aufs", .ops = &aufs_ops, }, { .name = "aufs", .ops = &aufs_ops, },
{ .name = "overlay", .ops = &ovl_ops, },
{ .name = "overlayfs", .ops = &ovl_ops, }, { .name = "overlayfs", .ops = &ovl_ops, },
{ .name = "loop", .ops = &loop_ops, }, { .name = "loop", .ops = &loop_ops, },
{ .name = "nbd", .ops = &nbd_ops, }, { .name = "nbd", .ops = &nbd_ops, },
...@@ -375,11 +374,10 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname, ...@@ -375,11 +374,10 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
*/ */
if (!bdevtype && !keepbdevtype && snap && if (!bdevtype && !keepbdevtype && snap &&
strcmp(orig->type, "dir") == 0) strcmp(orig->type, "dir") == 0)
bdevtype = "overlay"; bdevtype = "overlayfs";
if (am_unpriv() && !unpriv_snap_allowed(orig, bdevtype, snap, maybe_snap)) { if (am_unpriv() && !unpriv_snap_allowed(orig, bdevtype, snap, maybe_snap)) {
ERROR("Unsupported snapshot type \"%s\" for unprivileged users", ERROR("Unsupported snapshot type for unprivileged users");
bdevtype ? bdevtype : "(null)");
bdev_put(orig); bdev_put(orig);
return NULL; return NULL;
} }
...@@ -387,8 +385,7 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname, ...@@ -387,8 +385,7 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
*needs_rdep = 0; *needs_rdep = 0;
if (bdevtype && strcmp(orig->type, "dir") == 0 && if (bdevtype && strcmp(orig->type, "dir") == 0 &&
(strcmp(bdevtype, "aufs") == 0 || (strcmp(bdevtype, "aufs") == 0 ||
strcmp(bdevtype, "overlayfs") == 0 || strcmp(bdevtype, "overlayfs") == 0)) {
strcmp(bdevtype, "overlay") == 0)) {
*needs_rdep = 1; *needs_rdep = 1;
} else if (snap && strcmp(orig->type, "lvm") == 0 && } else if (snap && strcmp(orig->type, "lvm") == 0 &&
!lvm_is_thin_volume(orig->src)) { !lvm_is_thin_volume(orig->src)) {
...@@ -414,10 +411,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname, ...@@ -414,10 +411,8 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
goto err; goto err;
} }
if (!strcmp(new->type, "overlay") || !strcmp(new->type, "overlayfs"))
src_no_prefix = ovl_get_lower(new->src);
else
src_no_prefix = lxc_storage_get_path(new->src, new->type); src_no_prefix = lxc_storage_get_path(new->src, new->type);
if (am_unpriv() && chown_mapped_root(src_no_prefix, c0->lxc_conf) < 0) if (am_unpriv() && chown_mapped_root(src_no_prefix, c0->lxc_conf) < 0)
WARN("Failed to update ownership of %s", new->dest); WARN("Failed to update ownership of %s", new->dest);
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include "lxccontainer.h" #include "lxccontainer.h"
#include "lxcoverlay.h" #include "lxcoverlay.h"
#include "lxcrsync.h" #include "lxcrsync.h"
#include "storage_utils.h"
#include "utils.h" #include "utils.h"
lxc_log_define(lxcoverlay, lxc); lxc_log_define(lxcoverlay, lxc);
...@@ -42,6 +41,10 @@ lxc_log_define(lxcoverlay, lxc); ...@@ -42,6 +41,10 @@ lxc_log_define(lxcoverlay, lxc);
static char *ovl_name; static char *ovl_name;
static char *ovl_version[] = {"overlay", "overlayfs"}; static char *ovl_version[] = {"overlay", "overlayfs"};
/* defined in lxccontainer.c: needs to become common helper */
extern char *dir_new_path(char *src, const char *oldname, const char *name,
const char *oldpath, const char *lxcpath);
static char *ovl_detect_name(void); static char *ovl_detect_name(void);
static int ovl_do_rsync(struct bdev *orig, struct bdev *new, static int ovl_do_rsync(struct bdev *orig, struct bdev *new,
struct lxc_conf *conf); struct lxc_conf *conf);
...@@ -58,18 +61,16 @@ int ovl_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname, ...@@ -58,18 +61,16 @@ int ovl_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
char *src; char *src;
if (!snap) { if (!snap) {
ERROR("overlay is only for snapshot clones"); ERROR("overlayfs is only for snapshot clones");
return -22; return -22;
} }
if (!orig->src || !orig->dest) if (!orig->src || !orig->dest)
return -1; return -1;
new->dest = lxc_string_join( new->dest = dir_new_path(orig->dest, oldname, cname, oldpath, lxcpath);
"/", (const char *[]){lxcpath, cname, "rootfs", NULL}, false);
if (!new->dest) if (!new->dest)
return -1; return -1;
if (mkdir_p(new->dest, 0755) < 0) if (mkdir_p(new->dest, 0755) < 0)
return -1; return -1;
...@@ -142,11 +143,11 @@ int ovl_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname, ...@@ -142,11 +143,11 @@ int ovl_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
free(delta); free(delta);
return -ENOMEM; return -ENOMEM;
} }
ret = snprintf(new->src, len, "overlay:%s:%s", src, delta); ret = snprintf(new->src, len, "overlayfs:%s:%s", src, delta);
free(delta); free(delta);
if (ret < 0 || ret >= len) if (ret < 0 || ret >= len)
return -1; return -ENOMEM;
} else if (!strcmp(orig->type, "overlayfs") || !strcmp(orig->type, "overlay")) { } else if (strcmp(orig->type, "overlayfs") == 0) {
/* /*
* What exactly do we want to do here? I think we want to use * What exactly do we want to do here? I think we want to use
* the original lowerdir, with a private delta which is * the original lowerdir, with a private delta which is
...@@ -155,44 +156,26 @@ int ovl_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname, ...@@ -155,44 +156,26 @@ int ovl_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
char *osrc, *odelta, *nsrc, *ndelta, *work; char *osrc, *odelta, *nsrc, *ndelta, *work;
char *lastslash; char *lastslash;
int len, ret, lastslashidx; int len, ret, lastslashidx;
if (!(osrc = strdup(orig->src)))
osrc = strdup(orig->src);
if (!osrc) {
SYSERROR("Failed to duplicate \"%s\"", orig->src);
return -22; return -22;
}
nsrc = strchr(osrc, ':') + 1; nsrc = strchr(osrc, ':') + 1;
if ((nsrc != osrc + 8) && (nsrc != osrc + 10)) { if (nsrc != osrc + 10 || (odelta = strchr(nsrc, ':')) == NULL) {
free(osrc);
ERROR("Detected \":\" in \"%s\" at wrong position", osrc);
return -22;
}
odelta = strchr(nsrc, ':');
if (!odelta) {
free(osrc); free(osrc);
ERROR("Failed to find \":\" in \"%s\"", nsrc);
return -22; return -22;
} }
*odelta = '\0'; *odelta = '\0';
odelta++; odelta++;
ndelta = lxc_string_join("/", (const char *[]){lxcpath, cname, "rootfs", NULL}, false); ndelta = dir_new_path(odelta, oldname, cname, oldpath, lxcpath);
if (!ndelta) { if (!ndelta) {
free(osrc); free(osrc);
ERROR("Failed to create new path");
return -ENOMEM; return -ENOMEM;
} }
if ((ret = mkdir(ndelta, 0755)) < 0 && errno != EEXIST) {
ret = mkdir(ndelta, 0755); SYSERROR("error: mkdir %s", ndelta);
if (ret < 0 && errno != EEXIST) {
free(osrc); free(osrc);
free(ndelta); free(ndelta);
SYSERROR("Failed to create \"%s\"", ndelta);
return -1; return -1;
} }
if (am_unpriv() && chown_mapped_root(ndelta, conf) < 0) if (am_unpriv() && chown_mapped_root(ndelta, conf) < 0)
WARN("Failed to update ownership of %s", ndelta); WARN("Failed to update ownership of %s", ndelta);
...@@ -204,7 +187,6 @@ int ovl_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname, ...@@ -204,7 +187,6 @@ int ovl_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
if (!lastslash) { if (!lastslash) {
free(osrc); free(osrc);
free(ndelta); free(ndelta);
ERROR("Failed to detect \"/\" in \"%s\"", ndelta);
return -1; return -1;
} }
lastslash++; lastslash++;
...@@ -214,43 +196,37 @@ int ovl_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname, ...@@ -214,43 +196,37 @@ int ovl_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
if (!work) { if (!work) {
free(osrc); free(osrc);
free(ndelta); free(ndelta);
ERROR("Failed to allocate memory");
return -1; return -1;
} }
strncpy(work, ndelta, lastslashidx + 1); strncpy(work, ndelta, lastslashidx + 1);
strcpy(work + lastslashidx, "olwork"); strcpy(work + lastslashidx, "olwork");
ret = mkdir(work, 0755); if ((mkdir(work, 0755) < 0) && errno != EEXIST) {
if (ret < 0 && errno != EEXIST) { SYSERROR("error: mkdir %s", work);
free(osrc); free(osrc);
free(ndelta); free(ndelta);
free(work); free(work);
SYSERROR("Failed to create \"%s\"", ndelta);
return -1; return -1;
} }
if (am_unpriv() && chown_mapped_root(work, conf) < 0) if (am_unpriv() && chown_mapped_root(work, conf) < 0)
WARN("Failed to update ownership of %s", work); WARN("Failed to update ownership of %s", work);
free(work); free(work);
len = strlen(nsrc) + strlen(ndelta) + 10; len = strlen(nsrc) + strlen(ndelta) + 12;
new->src = malloc(len); new->src = malloc(len);
if (!new->src) { if (!new->src) {
free(osrc); free(osrc);
free(ndelta); free(ndelta);
ERROR("Failed to allocate memory");
return -ENOMEM; return -ENOMEM;
} }
ret = snprintf(new->src, len, "overlay:%s:%s", nsrc, ndelta); ret = snprintf(new->src, len, "overlayfs:%s:%s", nsrc, ndelta);
free(osrc); free(osrc);
free(ndelta); free(ndelta);
if (ret < 0 || ret >= len) { if (ret < 0 || ret >= len)
ERROR("Failed to create string"); return -ENOMEM;
return -1;
}
return ovl_do_rsync(orig, new, conf); return ovl_do_rsync(orig, new, conf);
} else { } else {
ERROR("overlay clone of %s container is not yet supported", ERROR("overlayfs clone of %s container is not yet supported",
orig->type); orig->type);
/* /*
* Note, supporting this will require ovl_mount supporting * Note, supporting this will require ovl_mount supporting
...@@ -263,7 +239,7 @@ int ovl_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname, ...@@ -263,7 +239,7 @@ int ovl_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
} }
/* /*
* to say 'lxc-create -t ubuntu -n o1 -B overlay' means you want * to say 'lxc-create -t ubuntu -n o1 -B overlayfs' means you want
* $lxcpath/$lxcname/rootfs to have the created container, while all * $lxcpath/$lxcname/rootfs to have the created container, while all
* changes after starting the container are written to * changes after starting the container are written to
* $lxcpath/$lxcname/delta0 * $lxcpath/$lxcname/delta0
...@@ -291,14 +267,14 @@ int ovl_create(struct bdev *bdev, const char *dest, const char *n, ...@@ -291,14 +267,14 @@ int ovl_create(struct bdev *bdev, const char *dest, const char *n,
return -1; return -1;
} }
// overlay:lower:upper // overlayfs:lower:upper
newlen = (2 * len) + strlen("overlay:") + 2; newlen = (2 * len) + strlen("overlayfs:") + 2;
bdev->src = malloc(newlen); bdev->src = malloc(newlen);
if (!bdev->src) { if (!bdev->src) {
ERROR("Out of memory"); ERROR("Out of memory");
return -1; return -1;
} }
ret = snprintf(bdev->src, newlen, "overlay:%s:%s", dest, delta); ret = snprintf(bdev->src, newlen, "overlayfs:%s:%s", dest, delta);
if (ret < 0 || ret >= newlen) if (ret < 0 || ret >= newlen)
return -1; return -1;
...@@ -312,23 +288,14 @@ int ovl_create(struct bdev *bdev, const char *dest, const char *n, ...@@ -312,23 +288,14 @@ int ovl_create(struct bdev *bdev, const char *dest, const char *n,
int ovl_destroy(struct bdev *orig) int ovl_destroy(struct bdev *orig)
{ {
bool ovl; char *upper;
char *upper = orig->src;
ovl = !strncmp(upper, "overlay:", 8); if (strncmp(orig->src, "overlayfs:", 10) != 0)
if (!ovl && strncmp(upper, "overlayfs:", 10))
return -22; return -22;
upper = strchr(orig->src + 10, ':');
if (ovl)
upper += 8;
else
upper += 10;
upper = strchr(upper, ':');
if (!upper) if (!upper)
return -22; return -22;
upper++; upper++;
return lxc_rmdir_onedev(upper, NULL); return lxc_rmdir_onedev(upper, NULL);
} }
...@@ -339,6 +306,14 @@ int ovl_detect(const char *path) ...@@ -339,6 +306,14 @@ int ovl_detect(const char *path)
return 0; return 0;
} }
char *ovl_getlower(char *p)
{
char *p1 = strchr(p, ':');
if (p1)
*p1 = '\0';
return p;
}
int ovl_mount(struct bdev *bdev) int ovl_mount(struct bdev *bdev)
{ {
char *tmp, *options, *dup, *lower, *upper; char *tmp, *options, *dup, *lower, *upper;
...@@ -349,9 +324,8 @@ int ovl_mount(struct bdev *bdev) ...@@ -349,9 +324,8 @@ int ovl_mount(struct bdev *bdev)
char *mntdata; char *mntdata;
int ret, ret2; int ret, ret2;
if (strcmp(bdev->type, "overlay") && strcmp(bdev->type, "overlayfs")) if (strcmp(bdev->type, "overlayfs"))
return -22; return -22;
if (!bdev->src || !bdev->dest) if (!bdev->src || !bdev->dest)
return -22; return -22;
...@@ -445,7 +419,7 @@ int ovl_mount(struct bdev *bdev) ...@@ -445,7 +419,7 @@ int ovl_mount(struct bdev *bdev)
ret = ovl_remount_on_enodev(lower, bdev->dest, ovl_name, ret = ovl_remount_on_enodev(lower, bdev->dest, ovl_name,
MS_MGC_VAL | mntflags, options_work); MS_MGC_VAL | mntflags, options_work);
if (ret < 0) { if (ret < 0) {
INFO("Overlay: Error mounting %s onto %s with options %s. " INFO("Overlayfs: Error mounting %s onto %s with options %s. "
"Retrying without workdir: %s.", "Retrying without workdir: %s.",
lower, bdev->dest, options_work, strerror(errno)); lower, bdev->dest, options_work, strerror(errno));
...@@ -453,15 +427,15 @@ int ovl_mount(struct bdev *bdev) ...@@ -453,15 +427,15 @@ int ovl_mount(struct bdev *bdev)
ret = ovl_remount_on_enodev(lower, bdev->dest, ovl_name, ret = ovl_remount_on_enodev(lower, bdev->dest, ovl_name,
MS_MGC_VAL | mntflags, options); MS_MGC_VAL | mntflags, options);
if (ret < 0) if (ret < 0)
SYSERROR("Overlay: Error mounting %s onto %s with " SYSERROR("Overlayfs: Error mounting %s onto %s with "
"options %s: %s.", "options %s: %s.",
lower, bdev->dest, options, lower, bdev->dest, options,
strerror(errno)); strerror(errno));
else else
INFO("Overlay: Mounted %s onto %s with options %s.", INFO("Overlayfs: Mounted %s onto %s with options %s.",
lower, bdev->dest, options); lower, bdev->dest, options);
} else { } else {
INFO("Overlay: Mounted %s onto %s with options %s.", lower, INFO("Overlayfs: Mounted %s onto %s with options %s.", lower,
bdev->dest, options_work); bdev->dest, options_work);
} }
return ret; return ret;
...@@ -469,31 +443,13 @@ int ovl_mount(struct bdev *bdev) ...@@ -469,31 +443,13 @@ int ovl_mount(struct bdev *bdev)
int ovl_umount(struct bdev *bdev) int ovl_umount(struct bdev *bdev)
{ {
if (strcmp(bdev->type, "overlay") && strcmp(bdev->type, "overlayfs")) if (strcmp(bdev->type, "overlayfs"))
return -22; return -22;
if (!bdev->src || !bdev->dest) if (!bdev->src || !bdev->dest)
return -22; return -22;
return umount(bdev->dest); return umount(bdev->dest);
} }
char *ovl_get_lower(const char *rootfs_path)
{
char *s1;
s1 = strstr(rootfs_path, ":/");
if (!s1)
return NULL;
s1++;
s1 = strstr(s1, ":/");
if (!s1)
return NULL;
s1++;
return s1;
}
char *ovl_get_rootfs(const char *rootfs_path, size_t *rootfslen) char *ovl_get_rootfs(const char *rootfs_path, size_t *rootfslen)
{ {
char *rootfsdir = NULL; char *rootfsdir = NULL;
...@@ -802,7 +758,7 @@ static int ovl_do_rsync(struct bdev *orig, struct bdev *new, struct lxc_conf *co ...@@ -802,7 +758,7 @@ static int ovl_do_rsync(struct bdev *orig, struct bdev *new, struct lxc_conf *co
else else
ret = ovl_rsync(&rdata); ret = ovl_rsync(&rdata);
if (ret) if (ret)
ERROR("copying overlay delta"); ERROR("copying overlayfs delta");
return ret; return ret;
} }
......
...@@ -76,7 +76,7 @@ int ovl_update_abs_paths(struct lxc_conf *lxc_conf, const char *lxc_path, ...@@ -76,7 +76,7 @@ int ovl_update_abs_paths(struct lxc_conf *lxc_conf, const char *lxc_path,
* To be called from functions in lxccontainer.c: Get lower directory for * To be called from functions in lxccontainer.c: Get lower directory for
* overlay rootfs. * overlay rootfs.
*/ */
char *ovl_get_lower(const char *rootfs_path); char *ovl_getlower(char *p);
/* /*
* Get rootfs path for overlay backed containers. Allocated memory must be freed * Get rootfs path for overlay backed containers. Allocated memory must be freed
......
...@@ -415,7 +415,6 @@ bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap, ...@@ -415,7 +415,6 @@ bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap,
// overlayfs -- which is also allowed) // overlayfs -- which is also allowed)
if (strcmp(b->type, "dir") == 0 || if (strcmp(b->type, "dir") == 0 ||
strcmp(b->type, "aufs") == 0 || strcmp(b->type, "aufs") == 0 ||
strcmp(b->type, "overlay") == 0 ||
strcmp(b->type, "overlayfs") == 0 || strcmp(b->type, "overlayfs") == 0 ||
strcmp(b->type, "btrfs") == 0 || strcmp(b->type, "btrfs") == 0 ||
strcmp(b->type, "loop") == 0) strcmp(b->type, "loop") == 0)
...@@ -428,7 +427,6 @@ bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap, ...@@ -428,7 +427,6 @@ bool unpriv_snap_allowed(struct bdev *b, const char *t, bool snap,
// and loop. In particular, not zfs, btrfs, or lvm. // and loop. In particular, not zfs, btrfs, or lvm.
if (strcmp(t, "dir") == 0 || if (strcmp(t, "dir") == 0 ||
strcmp(t, "aufs") == 0 || strcmp(t, "aufs") == 0 ||
strcmp(t, "overlay") == 0 ||
strcmp(t, "overlayfs") == 0 || strcmp(t, "overlayfs") == 0 ||
strcmp(t, "btrfs") == 0 || strcmp(t, "btrfs") == 0 ||
strcmp(t, "loop") == 0) strcmp(t, "loop") == 0)
......
...@@ -3623,6 +3623,7 @@ int chown_mapped_root(char *path, struct lxc_conf *conf) ...@@ -3623,6 +3623,7 @@ int chown_mapped_root(char *path, struct lxc_conf *conf)
{ {
uid_t rootuid, rootgid; uid_t rootuid, rootgid;
unsigned long val; unsigned long val;
char *chownpath = path;
int hostuid, hostgid, ret; int hostuid, hostgid, ret;
struct stat sb; struct stat sb;
char map1[100], map2[100], map3[100], map4[100], map5[100]; char map1[100], map2[100], map3[100], map4[100], map5[100];
...@@ -3658,6 +3659,23 @@ int chown_mapped_root(char *path, struct lxc_conf *conf) ...@@ -3658,6 +3659,23 @@ int chown_mapped_root(char *path, struct lxc_conf *conf)
} }
rootgid = (gid_t)val; rootgid = (gid_t)val;
/*
* In case of overlay, we want only the writeable layer to be chowned
*/
if (strncmp(path, "overlayfs:", 10) == 0 || strncmp(path, "aufs:", 5) == 0) {
chownpath = strchr(path, ':');
if (!chownpath) {
ERROR("Bad overlay path: %s", path);
return -1;
}
chownpath = strchr(chownpath + 1, ':');
if (!chownpath) {
ERROR("Bad overlay path: %s", path);
return -1;
}
chownpath++;
}
path = chownpath;
if (hostuid == 0) { if (hostuid == 0) {
if (chown(path, rootuid, rootgid) < 0) { if (chown(path, rootuid, rootgid) < 0) {
ERROR("Error chowning %s", path); ERROR("Error chowning %s", path);
......
...@@ -3225,8 +3225,8 @@ static int clone_update_rootfs_wrapper(void *data) ...@@ -3225,8 +3225,8 @@ static int clone_update_rootfs_wrapper(void *data)
sudo lxc-clone -o o1 -n n1 -s -L|-fssize fssize -v|--vgname vgname \ sudo lxc-clone -o o1 -n n1 -s -L|-fssize fssize -v|--vgname vgname \
-p|--lvprefix lvprefix -t|--fstype fstype -B backingstore -p|--lvprefix lvprefix -t|--fstype fstype -B backingstore
-s [ implies overlay] -s [ implies overlayfs]
-s -B overlay -s -B overlayfs
-s -B aufs -s -B aufs
only rootfs gets converted (copied/snapshotted) on clone. only rootfs gets converted (copied/snapshotted) on clone.
...@@ -3600,7 +3600,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile) ...@@ -3600,7 +3600,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
if (bdev_is_dir(c->lxc_conf, c->lxc_conf->rootfs.path)) { if (bdev_is_dir(c->lxc_conf, c->lxc_conf->rootfs.path)) {
ERROR("Snapshot of directory-backed container requested."); ERROR("Snapshot of directory-backed container requested.");
ERROR("Making a copy-clone. If you do want snapshots, then"); ERROR("Making a copy-clone. If you do want snapshots, then");
ERROR("please create an aufs or overlay clone first, snapshot that"); ERROR("please create an aufs or overlayfs clone first, snapshot that");
ERROR("and keep the original container pristine."); ERROR("and keep the original container pristine.");
flags &= ~LXC_CLONE_SNAPSHOT | LXC_CLONE_MAYBE_SNAPSHOT; flags &= ~LXC_CLONE_SNAPSHOT | LXC_CLONE_MAYBE_SNAPSHOT;
} }
......
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