[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