[lxc-devel] lxc-clone rewrite

Christian Brauner christianvanbrauner at gmail.com
Fri Sep 4 17:59:59 UTC 2015


Consider it done. :)
On Sep 4, 2015 7:47 PM, "Stéphane Graber" <stgraber at ubuntu.com> wrote:

> On Fri, Sep 04, 2015 at 07:42:50PM +0200, Christian Brauner wrote:
> > On Fri, Sep 04, 2015 at 01:11:14PM -0400, Stéphane Graber wrote:
> > > On Fri, Sep 04, 2015 at 04:21:42PM +0200, Christian Brauner wrote:
> > > > On Fri, Sep 04, 2015 at 02:04:29PM +0000, Serge Hallyn wrote:
> > > > > Quoting Christian Brauner (christianvanbrauner at gmail.com):
> > > > > > On Mon, Aug 31, 2015 at 09:53:03PM +0200, Christian Brauner
> wrote:
> > > > > > > On Mon Aug 31, 2015 at 04:08:33PM +0000, Serge Hallyn wrote:
> > > > > > > > Quoting Stéphane Graber (stgraber at ubuntu.com):
> > > > > > > > > On Mon, Aug 31, 2015 at 01:43:07PM +0000, Serge Hallyn
> wrote:
> > > > > > > > > > Quoting Christian Brauner (christianvanbrauner at
> gmail.com):
> > > > > > > > > > > On Fri, Aug 28, 2015 at 12:46:17AM +0200, Christian
> Brauner wrote:
> > > > > > > > > > > > On Thu, Aug 27, 2015 at 03:41:03PM -0400, Stéphane
> Graber wrote:
> > > > > > > > > > > > > On Sun, Aug 16, 2015 at 04:46:31PM +0000, Serge
> Hallyn wrote:
> > > > > > > > > > > > > > Quoting Christian Brauner (christianvanbrauner
> at gmail.com):
> > > > > > > > > > > > > > Hey,
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > I'll leave this to Stéphane, as he's pretty keen
> on leaving the #
> > > > > > > > > > > > > > commands
> > > > > > > > > > > > > > low.  As you say we might eventually be able to
> deprecate
> > > > > > > > > > > > > > lxc-clone,
> > > > > > > > > > > > > > and
> > > > > > > > > > > > > > lxc-copy might eventually be a nice hook for
> migration.
> > > > > > > > > > > > >
> > > > > > > > > > > > > That'd be fine with me I think, bonus point if we
> can somehow merge
> > > > > > > > > > > > > lxc-start-ephemeral in there and kill two birds
> with one stone
> > > > > > > > > > > > > (lxc-clone & lxc-start-ephemeral).
> > > > > > > > > > > > >
> > > > > > > > > > > > > The timeline for this would be having lxc-copy in
> 1.2 with both
> > > > > > > > > > > > > lxc-clone and lxc-start-ephemeral doing arg
> swapping + re-exec
> > > > > > > > > > > > > tricks
> > > > > > > > > > > > > with a warning that they'll go away for good in
> 2.0.
> > > > > > > > > > > > >
> > > > > > > > > > > > > How does that sound?
> > > > > > > > > > > >
> > > > > > > > > > > > Sounds good! I'm on it!
> > > > > > > > > > > >
> > > > > > > > > > > > Christian
> > > > > > > > > > >
> > > > > > > > > > > In the current python implementation of
> lxc-start-ephemeral we generate
> > > > > > > > > > > a
> > > > > > > > > > > pre-mount and post-stop script. The post-stop script
> seems to be used to
> > > > > > > > > > > destroy
> > > > > > > > > > > the container. For the rewrite in C and the merge with
> lxc-clone I
> > > > > > > > > > > thought
> > > > > > > > > > > about
> > > > > > > > > > > using a simple snapshot-clone with c->clone() with a
> random name, start
> > > > > > > > > > > it
> > > > > > > > > > > c->start() and when the container is shutdown destroy
> it with
> > > > > > > > > > > c->destroy().
> > > > > > > > > > > This seems cleaner to me then generating scripts. Are
> there any reasons
> > > > > > > > > > > to
> > > > > > > > > > > not
> > > > > > > > > > > do it this way? And if so what would you prefer?
> > > > > > > > > >
> > > > > > > > > > If you can do this robustly and cleanly then I prefer
> this.
> > > > > > > > >
> > > > > > > > > The reason was that the container could be started
> backgrounded (-d) in
> > > > > > > > > which case lxc-start-ephemeral wasn't around anymore to
> clean things up
> > > > > > > > > when the container exits.
> > > > > > > > >
> > > > > > > > > The post-stop method ensured that the container would be
> destroyed
> > > > > > > > > whenever it finally dies and regardless of how it was
> killed (either
> > > > > > > > > shutdown from inside the container or
> lxc-stop/lxc-destroy).
> > > > > > > >
> > > > > > > > Right, so to do this without post-stop we'd probably have to
> hack a special
> > > > > > > > case into the reboot: loop around container-start.  Maybe
> even hardcode the
> > > > > > > > 'transient' case into the lxc_handler struct.  Or just have
> a 'special'
> > > > > > > > post-stop hook (doesn't even have to be a script, just a
> hard-code value
> > > > > > > > checked for before we run the script) telling us 'delete
> this thing'.
> > > > > > > >
> > > > > > > > It could end up looking nice, or could end up a mess.  I
> reserve final
> > > > > > > > judgement until there's code :)
> > > > > > > Agreed. Let's see how mess-less I can code this.
> > > > > > >
> > > > > > > As long as the container is started in foreground mode the
> container will be
> > > > > > > destroyed regardless of whether it was killed by lxc-stop or
> shutdown from
> > > > > > > inside. The only problematic case is when the container is
> started daemonized.
> > > > > > >
> > > > > > > I need to think about how to handle that case for a bit. I'd
> like to code more
> > > > > > > than one option I think. Unless there's need for rush. :)
> Suggestions of course
> > > > > > > welcome.
> > > > > > I'm currently in favour of the lxc.hook.post-stop version for
> daemonized
> > > > > > containers. The rest means fiddling with a lot of the
> api-functions for the
> > > > > > a rather special case. But there are two things I would like to
> have input
> > > > > > about:
> > > > > >
> > > > > > 1) Should we register ephemeral clone-snapshots in the
> lxc_snapshots file of the
> > > > > >    original container? (I would think not.)
> > > > >
> > > > > If for instance it is a overlayfs based snapshot, and you allow
> the parent
> > > > > to be deleted, then the ephemeral container will misbehave.  I'm
> pretty
> > > > > sure that's the case now and I haven't heard any complaints, but
> it is
> > > > > non-ideal.
> > > > >
> > > > > > 2) Should we have an additional state TRANSIENT in addition to
> RUNNING,
> > > > > >    STARTING, etc.?
> > > > >
> > > > > What exactly would it mean?  STARTING is already inherently
> TRANSIENT.  Would
> > > > > TRANSIENT mean 'building but not yet starting'?
> > > > I was unclear. TRANSIENT or EPHEMERAL in the sense of "this is a
> running
> > > > container but it will be deleted once it is shutdown". So when you
> do work on a
> > > > container and you're unsure whether it is an ephemeral container you
> could check
> > > > with lxc-info -n NAME and see TRANSIENT or EPHEMERAL and know "this
> thing is
> > > > going to be deleted when I shut it down."
> > >
> > > It seems to me like this has the potential to break a fair amount of
> > > existing tools which wait for "RUNNING" before interacting with a
> > > container. If we were to have multiple "RUNNING" equivalent state, we
> > > ought to add a new exported function that'd check whether the container
> > > is running regardless of the state's name but requiring the use of this
> > > would only be possible when we break backward compatibility (so LXC
> > > 2.0).
> >
> > Agreed!.
> >
> > >
> > > I suspect a cleaner way would be to have a config option for ephemeral
> > > containers, something like lxc.ephemeral=1 that will cause LXC to
> > > destroy the container when it dies and can be used by API clients to
> > > query whether a container is ephemeral.
> >
> > I actually already done that. I just need to bring it in final shape.
> But here
> > is a sneak-preview so you can stop me if you'd rather have it a
> different way.
> > And thanks for all the feedback and quick answers!
> >
> > PRELIMINARY: Destroy ephemeral overlayfs container
>
> I personally prefer ephemeral as a name, if only because that's what
> we've been using for years in both LXC and LXD, so one less thing to
> confuse people with :)
>
> >
> > ---
> >  src/lxc/conf.h    |  3 +++
> >  src/lxc/confile.c | 16 ++++++++++++++++
> >  src/lxc/start.c   | 14 ++++++++++++++
> >  3 files changed, 33 insertions(+)
> >
> > diff --git a/src/lxc/conf.h b/src/lxc/conf.h
> > index dc5328a..6e75713 100644
> > --- a/src/lxc/conf.h
> > +++ b/src/lxc/conf.h
> > @@ -370,6 +370,9 @@ struct lxc_conf {
> >        * should run under when using lxc-execute */
> >       uid_t init_uid;
> >       gid_t init_gid;
> > +
> > +     /* transient */
> > +     int transient;
> >  };
> >
> >  #ifdef HAVE_TLS
> > diff --git a/src/lxc/confile.c b/src/lxc/confile.c
> > index ca3b8d8..356d85f 100644
> > --- a/src/lxc/confile.c
> > +++ b/src/lxc/confile.c
> > @@ -108,6 +108,8 @@ static int config_environment(const char *, const
> char *, struct lxc_conf *);
> >  static int config_init_cmd(const char *, const char *, struct lxc_conf
> *);
> >  static int config_init_uid(const char *, const char *, struct lxc_conf
> *);
> >  static int config_init_gid(const char *, const char *, struct lxc_conf
> *);
> > +static int config_transient(const char *key, const char *value,
> > +                         struct lxc_conf *lxc_conf);
> >
> >  static struct lxc_config_t config[] = {
> >
> > @@ -176,6 +178,7 @@ static struct lxc_config_t config[] = {
> >       { "lxc.init_cmd",             config_init_cmd             },
> >       { "lxc.init_uid",             config_init_uid             },
> >       { "lxc.init_gid",             config_init_gid             },
> > +     { "lxc.transient",            config_transient            },
> >  };
> >
> >  struct signame {
> > @@ -2490,6 +2493,8 @@ int lxc_get_config_item(struct lxc_conf *c, const
> char *key, char *retv,
> >               return lxc_get_conf_int(c, retv, inlen, c->init_uid);
> >       else if (strcmp(key, "lxc.init_gid") == 0)
> >               return lxc_get_conf_int(c, retv, inlen, c->init_gid);
> > +     else if (strcmp(key, "lxc.transient") == 0)
> > +             return lxc_get_conf_int(c, retv, inlen, c->transient);
> >       else return -1;
> >
> >       if (!v)
> > @@ -2759,3 +2764,14 @@ bool network_new_hwaddrs(struct lxc_conf *conf)
> >       }
> >       return true;
> >  }
> > +
> > +static int config_transient(const char *key, const char *value,
> > +                         struct lxc_conf *lxc_conf)
> > +{
> > +     int v = atoi(value);
> > +
> > +     lxc_conf->transient = v;
> > +
> > +     return 0;
> > +}
> > +
> > diff --git a/src/lxc/start.c b/src/lxc/start.c
> > index ffb8d12..e551ca4 100644
> > --- a/src/lxc/start.c
> > +++ b/src/lxc/start.c
> > @@ -495,6 +495,20 @@ void lxc_fini(const char *name, struct lxc_handler
> *handler)
> >               close(handler->ttysock[0]);
> >               close(handler->ttysock[1]);
> >       }
> > +     if (handler->conf->transient > 0) {
> > +             char *check_rootfs = handler->conf->rootfs.path;
> > +             if (strncmp(check_rootfs, "overlayfs:", 10) == 0) {
> > +                     int ret;
> > +                     char destroy[MAXPATHLEN];
> > +                     ret = snprintf(destroy, MAXPATHLEN, "%s/%s",
> handler->lxcpath, name);
> > +                     if (ret < 0)
> > +                             ERROR("Error creating string");
> > +                     INFO(destroy);
> > +                     ret = lxc_rmdir_onedev(destroy, NULL);
> > +                     if (ret < 0)
> > +                             ERROR("Destroying container failed");
> > +             }
> > +     }
> >       cgroup_destroy(handler);
> >       free(handler);
> >  }
> > --
> > 2.5.1
> >
>
>
>
> --
> Stéphane Graber
> Ubuntu developer
> http://www.ubuntu.com
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20150904/bc4e83c3/attachment.html>


More information about the lxc-devel mailing list