[lxc-devel] [PATCH 1/4] autostart: Define lxc.start.* and lxc.group
Stéphane Graber
stgraber at ubuntu.com
Thu Dec 19 16:46:09 UTC 2013
On Thu, Dec 19, 2013 at 11:17:56AM -0500, Dwight Engen wrote:
> Hi Stephane, one very minor comment below.
>
> Acked-by: Dwight Engen <dwight.engen at oracle.com>
>
> On Thu, 19 Dec 2013 16:26:40 +0100
> Stéphane Graber <stgraber at ubuntu.com> wrote:
>
> > First patch in the set of changes required for container autostart.
> >
> > This commit adds the new configuration keys and parsers that will then
> > be used by lxc-start and lxc-stop.
> >
> > Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
> > ---
> > doc/lxc.conf.sgml.in | 60 +++++++++++++++++++++++++++++++-
> > src/lxc/conf.c | 14 ++++++++
> > src/lxc/conf.h | 6 ++++
> > src/lxc/confile.c | 97
> > ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed,
> > 176 insertions(+), 1 deletion(-)
> >
> > diff --git a/doc/lxc.conf.sgml.in b/doc/lxc.conf.sgml.in
> > index ba85a97..02b6c02 100644
> > --- a/doc/lxc.conf.sgml.in
> > +++ b/doc/lxc.conf.sgml.in
> > @@ -1246,7 +1246,7 @@ Foundation, Inc., 51 Franklin Street, Fifth
> > Floor, Boston, MA 02110-1301 USA
> > </refsect2>
> > <refsect2>
> > - <title> Logging</title>
> > + <title>Logging</title>
> > <para>
> > Logging can be configured on a per-container basis. By
> > default, depending upon how the lxc package was compiled, container
> > startup @@ -1294,6 +1294,64 @@ Foundation, Inc., 51 Franklin Street,
> > Fifth Floor, Boston, MA 02110-1301 USA </variablelist>
> > </refsect2>
> >
> > + <refsect2>
> > + <title>Autostart</title>
> > + <para>
> > + In order to support marking containers as auto-started, a few
> > + options were added, allowing users to define which
> > containers should be
> > + auto-started and in what order. These options may be used by
> > LXC tools
> > + directly or by external tooling provided by the
> > distributions.
> > + </para>
> > +
> > + <variablelist>
> > + <varlistentry>
> > + <term>
> > + <option>lxc.start.auto</option>
> > + </term>
> > + <listitem>
> > + <para>
> > + Whether the container should be auto-started.
> > + Valid values are 0 (off) and 1 (on).
> > + </para>
> > + </listitem>
> > + </varlistentry>
> > + <varlistentry>
> > + <term>
> > + <option>lxc.start.delay</option>
> > + </term>
> > + <listitem>
> > + <para>
> > + How long to wait (in seconds) after the container is
> > + started before starting the next one.
> > + </para>
> > + </listitem>
> > + </varlistentry>
> > + <varlistentry>
> > + <term>
> > + <option>lxc.start.order</option>
> > + </term>
> > + <listitem>
> > + <para>
> > + An integer used to sort the containers when
> > auto-starting
> > + a series of containers at once.
> > + </para>
> > + </listitem>
> > + </varlistentry>
> > + <varlistentry>
> > + <term>
> > + <option>lxc.group</option>
> > + </term>
> > + <listitem>
> > + <para>
> > + A multi-value key (can be used multiple times) to put
> > the
> > + container in a container group. Those groups can then
> > be
> > + used (amongst other things) to start a series of
> > related
> > + containers.
> > + </para>
> > + </listitem>
> > + </varlistentry>
> > + </variablelist>
> > + </refsect2>
> > </refsect1>
> >
> > <refsect1>
> > diff --git a/src/lxc/conf.c b/src/lxc/conf.c
> > index 69f90d0..fb0c593 100644
> > --- a/src/lxc/conf.c
> > +++ b/src/lxc/conf.c
> > @@ -2642,6 +2642,7 @@ struct lxc_conf *lxc_conf_init(void)
> > lxc_list_init(&new->id_map);
> > for (i=0; i<NUM_LXC_HOOKS; i++)
> > lxc_list_init(&new->hooks[i]);
> > + lxc_list_init(&new->groups);
> > new->lsm_aa_profile = NULL;
> > new->lsm_se_context = NULL;
> > new->lsm_umount_proc = 0;
> > @@ -3883,6 +3884,18 @@ int lxc_clear_cgroups(struct lxc_conf *c,
> > const char *key) return 0;
> > }
> >
> > +int lxc_clear_groups(struct lxc_conf *c)
> > +{
> > + struct lxc_list *it,*next;
> > +
> > + lxc_list_for_each_safe(it, &c->groups, next) {
> > + lxc_list_del(it);
> > + free(it->elem);
> > + free(it);
> > + }
> > + return 0;
> > +}
> > +
> > int lxc_clear_mount_entries(struct lxc_conf *c)
> > {
> > struct lxc_list *it,*next;
> > @@ -3970,6 +3983,7 @@ void lxc_conf_free(struct lxc_conf *conf)
> > lxc_clear_mount_entries(conf);
> > lxc_clear_saved_nics(conf);
> > lxc_clear_idmaps(conf);
> > + lxc_clear_groups(conf);
> > free(conf);
> > }
> >
> > diff --git a/src/lxc/conf.h b/src/lxc/conf.h
> > index f1e0903..ec76295 100644
> > --- a/src/lxc/conf.h
> > +++ b/src/lxc/conf.h
> > @@ -323,6 +323,11 @@ struct lxc_conf {
> > int loglevel; // loglevel as specifed in config (if any)
> >
> > int inherit_ns_fd[LXC_NS_MAX];
> > +
> > + int start_auto;
> > + int start_delay;
> > + int start_order;
> > + struct lxc_list groups;
> > };
> >
> > int run_lxc_hooks(const char *name, char *hook, struct lxc_conf
> > *conf, @@ -356,6 +361,7 @@ extern int lxc_clear_cgroups(struct
> > lxc_conf *c, const char *key); extern int
> > lxc_clear_mount_entries(struct lxc_conf *c); extern int
> > lxc_clear_hooks(struct lxc_conf *c, const char *key); extern int
> > lxc_clear_idmaps(struct lxc_conf *c); +extern int
> > lxc_clear_groups(struct lxc_conf *c);
> > /*
> > * Configure the container from inside
> > diff --git a/src/lxc/confile.c b/src/lxc/confile.c
> > index dbd140f..f6f951f 100644
> > --- a/src/lxc/confile.c
> > +++ b/src/lxc/confile.c
> > @@ -92,6 +92,8 @@ static int config_includefile(const char *, const
> > char *, struct lxc_conf *); static int config_network_nic(const char
> > *, const char *, struct lxc_conf *); static int config_autodev(const
> > char *, const char *, struct lxc_conf *); static int
> > config_stopsignal(const char *, const char *, struct lxc_conf *);
> > +static int config_start(const char *, const char *, struct lxc_conf
> > *); +static int config_group(const char *, const char *, struct
> > lxc_conf *); static struct lxc_config_t config[] = {
> >
> > @@ -142,6 +144,10 @@ static struct lxc_config_t config[] = {
> > { "lxc.include", config_includefile },
> > { "lxc.autodev", config_autodev },
> > { "lxc.stopsignal", config_stopsignal },
> > + { "lxc.start.auto", config_start },
> > + { "lxc.start.delay", config_start },
> > + { "lxc.start.order", config_start },
> > + { "lxc.group", config_group },
> > };
> >
> > struct signame {
> > @@ -925,6 +931,71 @@ static int config_pts(const char *key, const
> > char *value, return 0;
> > }
> >
> > +static int config_start(const char *key, const char *value,
> > + struct lxc_conf *lxc_conf)
> > +{
> > + if(strcmp(key, "lxc.start.auto") == 0) {
> > + lxc_conf->start_auto = atoi(value);
> > + return 0;
> > + }
> > + else if (strcmp(key, "lxc.start.delay") == 0) {
> > + lxc_conf->start_delay = atoi(value);
> > + return 0;
> > + }
> > + else if (strcmp(key, "lxc.start.order") == 0) {
> > + lxc_conf->start_order = atoi(value);
> > + return 0;
> > + }
> > + SYSERROR("Unknown key: %s", key);
> > + return -1;
> > +}
> > +
> > +static int config_group(const char *key, const char *value,
> > + struct lxc_conf *lxc_conf)
> > +{
> > + char *groups, *groupptr, *sptr, *token;
> > + struct lxc_list *grouplist;
> > + int ret = -1;
> > +
> > + if (!strlen(value))
> > + return lxc_clear_groups(lxc_conf);
> > +
> > + groups = strdup(value);
> > + if (!groups) {
> > + SYSERROR("failed to dup '%s'", value);
> > + return -1;
> > + }
> > +
> > + /* in case several capability keep is specified in a single
> > line
> > + * split these caps in a single element for the list */
>
> I'm guessing maybe this comment is left over from a cut-n-paste from
> the capability code? Otherwise I'm not sure what its trying to say
> here :)
Good catch, I indeed mostly copy/pasted the keepcaps function :)
I'll update the comment accordingly.
I guess considering we now have 4-5 similar options, it may also make
sense to have a generic function for those.
>
> > + for (groupptr = groups;;groupptr = NULL) {
> > + token = strtok_r(groupptr, " \t", &sptr);
> > + if (!token) {
> > + ret = 0;
> > + break;
> > + }
> > +
> > + grouplist = malloc(sizeof(*grouplist));
> > + if (!grouplist) {
> > + SYSERROR("failed to allocate groups list");
> > + break;
> > + }
> > +
> > + grouplist->elem = strdup(token);
> > + if (!grouplist->elem) {
> > + SYSERROR("failed to dup '%s'", token);
> > + free(grouplist);
> > + break;
> > + }
> > +
> > + lxc_list_add_tail(&lxc_conf->groups, grouplist);
> > + }
> > +
> > + free(groups);
> > +
> > + return ret;
> > +}
> > +
> > static int config_tty(const char *key, const char *value,
> > struct lxc_conf *lxc_conf)
> > {
> > @@ -1729,6 +1800,22 @@ static int lxc_get_item_hooks(struct lxc_conf
> > *c, char *retv, int inlen, return fulllen;
> > }
> >
> > +static int lxc_get_item_groups(struct lxc_conf *c, char *retv, int
> > inlen) +{
> > + int len, fulllen = 0;
> > + struct lxc_list *it;
> > +
> > + if (!retv)
> > + inlen = 0;
> > + else
> > + memset(retv, 0, inlen);
> > +
> > + lxc_list_for_each(it, &c->groups) {
> > + strprint(retv, inlen, "%s\n", (char *)it->elem);
> > + }
> > + return fulllen;
> > +}
> > +
> > static int lxc_get_item_cap_drop(struct lxc_conf *c, char *retv, int
> > inlen) {
> > int len, fulllen = 0;
> > @@ -1952,6 +2039,14 @@ int lxc_get_config_item(struct lxc_conf *c,
> > const char *key, char *retv, return lxc_get_item_network(c, retv,
> > inlen); else if (strncmp(key, "lxc.network.", 12) == 0)
> > return lxc_get_item_nic(c, retv, inlen, key + 12);
> > + else if (strcmp(key, "lxc.start.auto") == 0)
> > + return lxc_get_conf_int(c, retv, inlen,
> > c->start_auto);
> > + else if (strcmp(key, "lxc.start.delay") == 0)
> > + return lxc_get_conf_int(c, retv, inlen,
> > c->start_delay);
> > + else if (strcmp(key, "lxc.start.order") == 0)
> > + return lxc_get_conf_int(c, retv, inlen,
> > c->start_order);
> > + else if (strcmp(key, "lxc.group") == 0)
> > + return lxc_get_item_groups(c, retv, inlen);
> > else return -1;
> >
> > if (!v)
> > @@ -1977,6 +2072,8 @@ int lxc_clear_config_item(struct lxc_conf *c,
> > const char *key) return lxc_clear_mount_entries(c);
> > else if (strncmp(key, "lxc.hook", 8) == 0)
> > return lxc_clear_hooks(c, key);
> > + else if (strncmp(key, "lxc.group", 9) == 0)
> > + return lxc_clear_groups(c);
> >
> > return -1;
> > }
>
--
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20131219/acb081eb/attachment.pgp>
More information about the lxc-devel
mailing list