Commit f25ffc27 by Serge Hallyn Committed by Stéphane Graber

clone: don't ever mark the clone's rootfs as being the old, on disk

Otherwise an interrupted clone can lead to the original rootfs being delete. There is a period during lxcapi_clone during which we have written down a temporary configuration file on disk, for the new container, using the old rootfs. Interruption of clone doesn't allow us to do the cleanup we do in error paths, so a subsequent lxc-destroy removes the old rootfs. Fix this by doing the copy_storage as early as possible, and not writing down the rootfs when we write down the temporary configuration file. (note - I tested this by putting a series of 'if (strcmp(newname, "u%d") == 0) exit(1)' inline to trigger interruption between most blocks. If someone has a good idea for a generic way to regression-test this henceforth that'd be great) See https://bugs.launchpad.net/lxc/+bug/1285850Signed-off-by: 's avatarSerge Hallyn <serge.hallyn@ubuntu.com> Acked-by: 's avatarStéphane Graber <stgraber@ubuntu.com>
parent 83876d75
...@@ -2610,6 +2610,7 @@ static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *n ...@@ -2610,6 +2610,7 @@ static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *n
char newpath[MAXPATHLEN]; char newpath[MAXPATHLEN];
int ret, storage_copied = 0; int ret, storage_copied = 0;
const char *n, *l; const char *n, *l;
char *origroot = NULL;
struct clone_update_data data; struct clone_update_data data;
FILE *fout; FILE *fout;
pid_t pid; pid_t pid;
...@@ -2645,6 +2646,10 @@ static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *n ...@@ -2645,6 +2646,10 @@ static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *n
} }
// copy the configuration, tweak it as needed, // copy the configuration, tweak it as needed,
if (c->lxc_conf->rootfs.path) {
origroot = c->lxc_conf->rootfs.path;
c->lxc_conf->rootfs.path = NULL;
}
fout = fopen(newpath, "w"); fout = fopen(newpath, "w");
if (!fout) { if (!fout) {
SYSERROR("open %s", newpath); SYSERROR("open %s", newpath);
...@@ -2652,6 +2657,7 @@ static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *n ...@@ -2652,6 +2657,7 @@ static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *n
} }
write_config(fout, c->lxc_conf); write_config(fout, c->lxc_conf);
fclose(fout); fclose(fout);
c->lxc_conf->rootfs.path = origroot;
sprintf(newpath, "%s/%s/rootfs", l, n); sprintf(newpath, "%s/%s/rootfs", l, n);
if (mkdir(newpath, 0755) < 0) { if (mkdir(newpath, 0755) < 0) {
...@@ -2671,6 +2677,12 @@ static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *n ...@@ -2671,6 +2677,12 @@ static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *n
ERROR("clone: failed to create new container (%s %s)", n, l); ERROR("clone: failed to create new container (%s %s)", n, l);
goto out; goto out;
} }
c2->lxc_conf->rootfs.path = origroot;
// copy/snapshot rootfs's
ret = copy_storage(c, c2, bdevtype, flags, bdevdata, newsize);
if (ret < 0)
goto out;
// update utsname // update utsname
if (!set_config_item_locked(c2, "lxc.utsname", newname)) { if (!set_config_item_locked(c2, "lxc.utsname", newname)) {
...@@ -2694,11 +2706,6 @@ static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *n ...@@ -2694,11 +2706,6 @@ static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *n
if (!(flags & LXC_CLONE_KEEPMACADDR)) if (!(flags & LXC_CLONE_KEEPMACADDR))
network_new_hwaddrs(c2); network_new_hwaddrs(c2);
// copy/snapshot rootfs's
ret = copy_storage(c, c2, bdevtype, flags, bdevdata, newsize);
if (ret < 0)
goto out;
// We've now successfully created c2's storage, so clear it out if we // We've now successfully created c2's storage, so clear it out if we
// fail after this // fail after this
storage_copied = 1; storage_copied = 1;
......
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