]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
Destroy container with snapshots & clone-snapshots
authorChristian Brauner <christianvanbrauner@gmail.com>
Tue, 18 Aug 2015 11:40:11 +0000 (13:40 +0200)
committerSerge Hallyn <serge.hallyn@ubuntu.com>
Thu, 27 Aug 2015 20:14:24 +0000 (15:14 -0500)
- 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 <christianvanbrauner@gmail.com>
Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
src/lxc/lxc_destroy.c

index 32bd2b42df8db185bf8c7e24e0591f8ee068d8bd..6a522200765be36797a4ab0aecb4b2ef26b4e44c 100644 (file)
@@ -17,6 +17,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#define _GNU_SOURCE
 #include <lxc/lxccontainer.h>
 
 #include <stdio.h>
@@ -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;
 }