On Mon, Sep 14, 2015 at 03:03:58PM +0000, Serge Hallyn wrote:
> Quoting Christian Brauner (christianvanbrau...@gmail.com):
> > When creating ephemeral containers that have the option lxc.ephemeral = 1 
> > set
> > in their config, they will be destroyed on shutdown. As they are simple 
> > overlay
> > clones of an existing container they should be registered in the 
> > lxc_snapshots
> > file of the original container to stay consistent and adhere to the
> > expectancies of the users. Most of all, it ensure that we cannot remove a
> > container that has clones, even if they are just ephemeral snapshot-clones. 
> > The
> > function adds further consistency because remove_snapshots_entry() ensures 
> > that
> > ephemeral clone-snapshots deregister themselves from the lxc_snapshots file
> > when they are destroyed.
> > 
> > Signed-off-by: Christian Brauner <christianvanbrau...@gmail.com>
> > ---
> >  src/lxc/start.c | 123 
> > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 123 insertions(+)
> > 
> > diff --git a/src/lxc/start.c b/src/lxc/start.c
> > index 8fe08a1..f58d9a4 100644
> > --- a/src/lxc/start.c
> > +++ b/src/lxc/start.c
> > @@ -33,6 +33,7 @@
> >  #include <fcntl.h>
> >  #include <grp.h>
> >  #include <poll.h>
> > +#include <sys/mman.h>
> >  #include <sys/param.h>
> >  #include <sys/file.h>
> >  #include <sys/mount.h>
> > @@ -83,6 +84,7 @@ const struct ns_info ns_info[LXC_NS_MAX] = {
> >     [LXC_NS_NET] = {"net", CLONE_NEWNET}
> >  };
> >  
> > +static void remove_snapshot_entry(struct lxc_handler *handler, const char 
> > *name);
> >  static bool do_destroy_container(struct lxc_conf *conf);
> >  static int lxc_rmdir_onedev_wrapper(void *data);
> >  static void lxc_destroy_container_on_signal(struct lxc_handler *handler,
> > @@ -1322,6 +1324,8 @@ static void lxc_destroy_container_on_signal(struct 
> > lxc_handler *handler,
> >             return;
> >     }
> >  
> > +   remove_snapshot_entry(handler, name);
> 
> There's probably a reason I haven't considered - but shouldn't this
> really be using mod_all_rdeps(c, false)?
> 
> Well, technically mod_all_rdeps takes a lxc_container which you don't have
> here.  So mod_all_rdeps() and remove_snapshot_entry() should be sharing a
> common fn which takes lxcpath and lxcname and does the bulk of the work.

There's only one reason, I didn't want to make a function public without your
permission. :) I'll rewrite and resend the patch.

> 
> > +
> >     if (am_unpriv())
> >             ret = userns_exec_1(handler->conf, lxc_rmdir_onedev_wrapper, 
> > destroy);
> >     else
> > @@ -1349,3 +1353,122 @@ static bool do_destroy_container(struct lxc_conf 
> > *conf) {
> >          return bdev_destroy(conf);
> >  }
> >  
> > +static void remove_snapshot_entry(struct lxc_handler *handler, const char 
> > *name)
> > +{
> > +   char rdepfile[MAXPATHLEN];
> > +   char path[MAXPATHLEN];
> > +   char newpath[MAXPATHLEN];
> > +   char *base = NULL;
> > +   char *buf = NULL;
> > +   char *del = NULL;
> > +   char *scratch = NULL;
> > +   char *origpath = NULL;
> > +   char *origname = NULL;
> > +   int ret = 0;
> > +   int bytes = 0;
> > +   int fd = -1;
> > +   size_t len = 0;
> > +   struct stat fbuf;
> > +
> > +   ret = snprintf(rdepfile, MAXPATHLEN, "%s/%s/lxc_rdepends", 
> > handler->lxcpath, name);
> > +   if (ret < 0 || ret >= MAXPATHLEN)
> > +           return;
> > +
> > +   fd = open(rdepfile, O_RDONLY | O_CLOEXEC);
> > +   if (fd < 0)
> > +           return;
> > +
> > +   ret = fstat(fd, &fbuf);
> > +   if (ret < 0) {
> > +           close(fd);
> > +           return;
> > +   }
> > +
> > +   base = calloc(fbuf.st_size + 1, sizeof(char));
> > +   if (!base) {
> > +           close(fd);
> > +           return;
> > +   }
> > +
> > +   ret = read(fd, (void *)base, fbuf.st_size);
> > +   if (ret <= 0) {
> > +           free(base);
> > +           close(fd);
> > +           return;
> > +   }
> > +
> > +   origpath = strtok_r(base, "\n", &scratch);
> > +   if (!origpath) {
> > +           free(base);
> > +           close(fd);
> > +           return;
> > +   }
> > +
> > +   origname = strtok_r(NULL, "\n", &scratch);
> > +   if (!origname) {
> > +           free(base);
> > +           close(fd);
> > +           return;
> > +   }
> > +
> > +   close(fd);
> > +
> > +   ret = snprintf(path, MAXPATHLEN, "%s/%s/lxc_snapshots", origpath, 
> > origname);
> > +   if (ret < 0 || ret >= MAXPATHLEN) {
> > +           free(base);
> > +           return;
> > +   }
> > +   free(base);
> > +
> > +   ret = snprintf(newpath, MAXPATHLEN, "%s\n%s\n", handler->lxcpath, name);
> > +   if (ret < 0 || ret >= MAXPATHLEN)
> > +           return;
> > +
> > +   fd = open(path, O_RDWR | O_CLOEXEC);
> > +   if (fd < 0)
> > +           return;
> > +
> > +   ret = fstat(fd, &fbuf);
> > +   if (ret < 0) {
> > +           close(fd);
> > +           return;
> > +   }
> > +
> > +   if (fbuf.st_size != 0) {
> > +           /* write terminating \0-byte to file */
> > +           if (pwrite(fd, "", 1, fbuf.st_size) <= 0) {
> > +                   close(fd);
> > +                   return;
> > +           }
> > +
> > +           buf = mmap(NULL, fbuf.st_size + 1, PROT_READ | PROT_WRITE, 
> > MAP_SHARED, fd, 0);
> > +           if (buf == MAP_FAILED) {
> > +                   SYSERROR("Failed to create mapping %s", path);
> > +                   close(fd);
> > +                   return;
> > +           }
> > +
> > +           len = strlen(newpath);
> > +           while ((del = strstr((char *)buf, newpath))) {
> > +                   memmove(del, del + len, strlen(del) - len + 1);
> > +                   bytes += len;
> > +           }
> > +
> > +           munmap(buf, fbuf.st_size + 1);
> > +           if (ftruncate(fd, fbuf.st_size - bytes) < 0) {
> > +                   SYSERROR("Failed to truncate file %s", path);
> > +                   close(fd);
> > +                   return;
> > +           }
> > +   }
> > +
> > +   close(fd);
> > +
> > +   /* If the lxc-snapshot file is empty, remove it. */
> > +   if (stat(path, &fbuf) < 0)
> > +           return;
> > +   if (!fbuf.st_size) {
> > +           remove(path);
> > +   }
> > +}
> > +
> > -- 
> > 2.5.1
> > 

Attachment: signature.asc
Description: PGP signature

_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to