[lxc-devel] [PATCH 1/4] autostart: Define lxc.start.* and lxc.group

Serge Hallyn serge.hallyn at ubuntu.com
Thu Dec 19 15:44:09 UTC 2013


Quoting Stéphane Graber (stgraber at ubuntu.com):
> 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>

Acked-by: Serge E. Hallyn <serge.hallyn at ubuntu.com>

Code looks fine - just one comment on the manpage text.

> ---
>  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.

'were added' is historical narrative.  How about something like

"The autostart options support marking 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 */
> +	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;
>  }
> -- 
> 1.8.5.2
> 
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel


More information about the lxc-devel mailing list