]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
autostart: Define lxc.start.* and lxc.group
authorStéphane Graber <stgraber@ubuntu.com>
Sun, 22 Sep 2013 01:30:06 +0000 (21:30 -0400)
committerStéphane Graber <stgraber@ubuntu.com>
Thu, 19 Dec 2013 20:48:27 +0000 (21:48 +0100)
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@ubuntu.com>
Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
Acked-by: Dwight Engen <dwight.engen@oracle.com>
doc/lxc.conf.sgml.in
src/lxc/conf.c
src/lxc/conf.h
src/lxc/confile.c

index ba85a9778a5d99eb085339928e04bd364413cba6..e6d96891f9bd7b70acfeceb0269d1e36282fba8c 100644 (file)
@@ -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,63 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
       </variablelist>
     </refsect2>
 
+    <refsect2>
+    <title>Autostart</title>
+    <para>
+        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>
index 69f90d002a0a6ff4331e3eb56db20bbfd4516e07..fb0c593f5a14cd7196467d6addae5aee4d33d53b 100644 (file)
@@ -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);
 }
 
index f1e09035ef7c27a750e759e5677fb6b151291aab..ec76295850e24ddcd9a706a91bc65e2cb93a1a14 100644 (file)
@@ -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
index dbd140f20df3209105bdb3514fd0e4b0d6ee456f..c5ec4f3af983f6861d654244624764ed7729ace6 100644 (file)
@@ -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 groups are specified in a single line
+        * split these groups 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;
 }