[lxc-devel] [PATCH] Define a new lxc.init_cmd config option

Stéphane Graber stgraber at ubuntu.com
Wed Nov 26 20:34:41 UTC 2014


Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 doc/lxc.container.conf.sgml.in | 23 +++++++++++++++++++++++
 src/lxc/conf.c                 |  2 ++
 src/lxc/conf.h                 |  3 +++
 src/lxc/confile.c              | 10 ++++++++++
 src/lxc/lxc_autostart.c        |  6 +-----
 src/lxc/lxc_start.c            |  5 ++++-
 src/lxc/lxccontainer.c         | 12 ++++++++++--
 7 files changed, 53 insertions(+), 8 deletions(-)

diff --git a/doc/lxc.container.conf.sgml.in b/doc/lxc.container.conf.sgml.in
index 35907b5..6d4daac 100644
--- a/doc/lxc.container.conf.sgml.in
+++ b/doc/lxc.container.conf.sgml.in
@@ -202,6 +202,29 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     </refsect2>
 
     <refsect2>
+      <title>Init command</title>
+      <para>
+        Sets the command to use as the init system for the containers.
+
+        This option is ignored when using lxc-execute.
+
+        Defaults to: /sbin/init
+      </para>
+      <variablelist>
+    <varlistentry>
+      <term>
+        <option>lxc.init_cmd</option>
+      </term>
+      <listitem>
+        <para>
+          Absolute path from container rootfs to the binary to use as init.
+        </para>
+      </listitem>
+    </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
       <title>Network</title>
       <para>
         The network section defines how the network is virtualized in
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index ac21c77..90df4d2 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -4537,6 +4537,8 @@ void lxc_conf_free(struct lxc_conf *conf)
 		free(conf->fstab);
 	if (conf->rcfile)
 		free(conf->rcfile);
+	if (conf->init_cmd)
+		free(conf->init_cmd);
 	free(conf->unexpanded_config);
 	lxc_clear_config_network(conf);
 	if (conf->lsm_aa_profile)
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 563109c..06d3e23 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -356,6 +356,9 @@ struct lxc_conf {
 	/* text representation of the config file */
 	char *unexpanded_config;
 	size_t unexpanded_len, unexpanded_alloced;
+
+	/* init command */
+	char *init_cmd;
 };
 
 int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf,
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index 886f8a1..83dab05 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -101,6 +101,7 @@ 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 int config_environment(const char *, const char *, struct lxc_conf *);
+static int config_init_cmd(const char *, const char *, struct lxc_conf *);
 
 static struct lxc_config_t config[] = {
 
@@ -162,6 +163,7 @@ static struct lxc_config_t config[] = {
 	{ "lxc.start.order",          config_start                },
 	{ "lxc.group",                config_group                },
 	{ "lxc.environment",          config_environment          },
+	{ "lxc.init_cmd",             config_init_cmd             },
 };
 
 struct signame {
@@ -965,6 +967,12 @@ static int config_seccomp(const char *key, const char *value,
 	return config_path_item(&lxc_conf->seccomp, value);
 }
 
+static int config_init_cmd(const char *key, const char *value,
+				 struct lxc_conf *lxc_conf)
+{
+	return config_path_item(&lxc_conf->init_cmd, value);
+}
+
 static int config_hook(const char *key, const char *value,
 				 struct lxc_conf *lxc_conf)
 {
@@ -2327,6 +2335,8 @@ int lxc_get_config_item(struct lxc_conf *c, const char *key, char *retv,
 		v = c->seccomp;
 	else if (strcmp(key, "lxc.environment") == 0)
 		return lxc_get_item_environment(c, retv, inlen);
+	else if (strcmp(key, "lxc.init_cmd") == 0)
+		v = c->init_cmd;
 	else return -1;
 
 	if (!v)
diff --git a/src/lxc/lxc_autostart.c b/src/lxc/lxc_autostart.c
index d0e3bfa..db25b48 100644
--- a/src/lxc/lxc_autostart.c
+++ b/src/lxc/lxc_autostart.c
@@ -330,10 +330,6 @@ int main(int argc, char *argv[])
 	struct lxc_container **containers = NULL;
 	struct lxc_list **c_groups_lists = NULL;
 	struct lxc_list *cmd_group;
-	char *const default_start_args[] = {
-		"/sbin/init",
-		NULL,
-	};
 
 	if (lxc_arguments_parse(&my_args, argc, argv))
 		return 1;
@@ -470,7 +466,7 @@ int main(int argc, char *argv[])
 						printf("%s %d\n", c->name,
 						       get_config_integer(c, "lxc.start.delay"));
 					else {
-						if (!c->start(c, 0, default_start_args))
+						if (!c->start(c, 0, NULL))
 							fprintf(stderr, "Error starting container: %s\n", c->name);
 						else
 							sleep(get_config_integer(c, "lxc.start.delay"));
diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c
index 874bb9e..006ffc4 100644
--- a/src/lxc/lxc_start.c
+++ b/src/lxc/lxc_start.c
@@ -336,7 +336,10 @@ int main(int argc, char *argv[])
 	if (my_args.close_all_fds)
 		c->want_close_all_fds(c, true);
 
-	err = c->start(c, 0, args) ? 0 : 1;
+	if (args == default_args)
+		err = c->start(c, 0, NULL) ? 0 : 1;
+	else
+		err = c->start(c, 0, args) ? 0 : 1;
 
 	if (err) {
 		ERROR("The container failed to start.");
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 2372b19..406cead 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -555,6 +555,7 @@ static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv
 		"/sbin/init",
 		NULL,
 	};
+	char *init_cmd[2];
 
 	/* container exists */
 	if (!c)
@@ -591,8 +592,15 @@ static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv
 		return ret == 0 ? true : false;
 	}
 
-	if (!argv)
-		argv = default_args;
+	if (!argv) {
+		if (conf->init_cmd) {
+			init_cmd[0] = conf->init_cmd;
+			init_cmd[1] = NULL;
+			argv = init_cmd;
+		}
+		else
+			argv = default_args;
+	}
 
 	/*
 	* say, I'm not sure - what locks do we want here?  Any?
-- 
1.9.1



More information about the lxc-devel mailing list