From: Christian Brauner Date: Tue, 18 Aug 2015 11:40:11 +0000 (+0200) Subject: Destroy container with snapshots & clone-snapshots X-Git-Tag: lxc-2.0.0.beta1~179 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=19712e0473f1caacb8833157a888f7efc3656ff6;p=thirdparty%2Flxc.git Destroy container with snapshots & clone-snapshots - This enables lxc-destroy to destroy a container with all its snapshots including clone-snapshots not located in the snaps/ folder. Signed-off-by: Christian Brauner Acked-by: Serge E. Hallyn --- diff --git a/src/lxc/lxc_destroy.c b/src/lxc/lxc_destroy.c index 32bd2b42d..6a5222007 100644 --- a/src/lxc/lxc_destroy.c +++ b/src/lxc/lxc_destroy.c @@ -17,6 +17,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#define _GNU_SOURCE #include #include @@ -138,12 +139,79 @@ static int do_destroy(struct lxc_container *c) static int do_destroy_with_snapshots(struct lxc_container *c) { - if (!c->destroy_with_snapshots(c)) { - fprintf(stderr, "Destroying %s failed\n", my_args.name); + struct lxc_container *c1; + struct stat fbuf; + char path[MAXPATHLEN]; + char *buf = NULL; + char *lxcpath = NULL; + char *lxcname = NULL; + char *scratch = NULL; + int fd; + int ret; + int counter = 0; + + /* Destroy snapshots created with lxc-clone listed in lxc-snapshots. */ + ret = snprintf(path, MAXPATHLEN, "%s/%s/lxc_snapshots", c->config_path, c->name); + + fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd > 0) { + ret = fstat(fd, &fbuf); + if (ret < 0) { + close(fd); + return -1; + } + + /* Make sure that the string is \0 terminated. */ + buf = calloc(fbuf.st_size + 1, sizeof(char)); + if (!buf) { + SYSERROR("failed to allocate memory"); + close(fd); + free(buf); + return -1; + } + + ret = read(fd, buf, fbuf.st_size); + if (ret < 0) { + ERROR("could not read %s", path); + close(fd); + free(buf); + return -1; + } + close(fd); + + while ((lxcpath = strtok_r(!counter ? buf : NULL, "\n", &scratch))) { + if (!(lxcname = strtok_r(NULL, "\n", &scratch))) + break; + c1 = lxc_container_new(lxcname, lxcpath); + if (!c1->destroy(c1)) { + fprintf(stderr, "Destroying snapshot %s of %s failed\n", lxcname, my_args.name); + lxc_container_put(c1); + free(buf); + return -1; + } + lxc_container_put(c1); + counter++; + } + free(buf); + } + + /* Destroy snapshots located in the containers snap/ folder. */ + ret = snprintf(path, MAXPATHLEN, "%s/%s/snaps", c->config_path, c->name); + if (ret < 0 || ret >= MAXPATHLEN) return -1; + if (dir_exists(path)) { + if (!c->destroy_with_snapshots(c)) { + fprintf(stderr, "Destroying %s failed\n", my_args.name); + return -1; + } + } else { + if (!c->destroy(c)) { + fprintf(stderr, "Destroying %s failed\n", my_args.name); + return -1; + } } - printf("Destroyed container including snapshots %s\n", my_args.name); + printf("Destroyed container %s including snapshots \n", my_args.name); return 0; }