[lxc-devel] [PATCH] api: convert lxc_start

Serge Hallyn serge.hallyn at ubuntu.com
Thu Aug 22 15:27:40 UTC 2013


Normal lxc-start usage tends to be "lxc-start -n name [-P lxcpath]".
This causes $lxcpath/$name/config to be the configuration for the
container.  However, lxc-start is more flexible than that.  You can
specify a custom configuration file, in which case $lxcpath/$name/config
is not used.  You can also (in addition or in place of either of these)
specify configuration entries one-by-one using "-s lxc.utsname=xxx".

To support this using the API, if we are not using
$lxcpath/$name/config then we put ourselves into a custom lxcpath
called (configurable using LXCPATH) /var/lib/lxc_anon.  To stop a
container so created, then, you would use

	lxc-stop -P /var/lib/lxc_anon -n name

TODO: we should walk over the list of &defines by hand and set them
using c->set_config_item.  I haven't done that in this patch.

Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
---
 src/lxc/lxc_start.c | 74 +++++++++++++++++++++++++++++++----------------------
 1 file changed, 43 insertions(+), 31 deletions(-)

diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c
index 3a12410..125284c 100644
--- a/src/lxc/lxc_start.c
+++ b/src/lxc/lxc_start.c
@@ -43,6 +43,7 @@
 #include "log.h"
 #include "caps.h"
 #include "lxc.h"
+#include "lxccontainer.h"
 #include "conf.h"
 #include "cgroup.h"
 #include "utils.h"
@@ -151,6 +152,8 @@ int main(int argc, char *argv[])
 		'\0',
 	};
 	FILE *pid_fp = NULL;
+	struct lxc_container *c;
+	char *anonpath;
 
 	lxc_list_init(&defines);
 
@@ -169,13 +172,32 @@ int main(int argc, char *argv[])
 			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
 		return err;
 
+	anonpath = alloca(strlen(LXCPATH) + 6);
+	sprintf(anonpath, "%s_anon", LXCPATH);
+	/*
+	 * rcfile possibilities:
+	 * 1. rcfile from random path specified in cli option
+	 * 2. rcfile not specified, use $lxcpath/$lxcname/config
+	 * 3. rcfile not specified and does not exist.
+	 */
 	/* rcfile is specified in the cli option */
-	if (my_args.rcfile)
+	if (my_args.rcfile) {
 		rcfile = (char *)my_args.rcfile;
-	else {
+		c = lxc_container_new(my_args.name, anonpath);
+		if (!c) {
+			ERROR("Failed to create lxc_container");
+			return err;
+		}
+		if (!c->load_config(c, rcfile)) {
+			ERROR("Failed to load rcfile");
+			lxc_container_put(c);
+			return err;
+		}
+	} else {
 		int rc;
+		const char *lxcpath = my_args.lxcpath[0];
 
-		rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath[0], my_args.name);
+		rc = asprintf(&rcfile, "%s/%s/config", lxcpath, my_args.name);
 		if (rc == -1) {
 			SYSERROR("failed to allocate memory");
 			return err;
@@ -186,25 +208,28 @@ int main(int argc, char *argv[])
 		if (access(rcfile, F_OK)) {
 			free(rcfile);
 			rcfile = NULL;
+			lxcpath = anonpath;
+		}
+		c = lxc_container_new(my_args.name, lxcpath);
+		if (!c) {
+			ERROR("Failed to create lxc_container");
+			return err;
 		}
 	}
 
-	conf = lxc_conf_init();
-	if (!conf) {
-		ERROR("failed to initialize configuration");
-		return err;
-	}
-
-	if (rcfile && lxc_config_read(rcfile, conf)) {
-		ERROR("failed to read configuration file");
-		goto out;
-	}
+	/*
+	 * We should use set_config_item() over &defines, which would handle
+	 * unset c->lxc_conf for us and let us not use lxc_config_define_load()
+	 */
+	if (!c->lxc_conf)
+		c->lxc_conf = lxc_conf_init();
+	conf = c->lxc_conf;
 
 	if (lxc_config_define_load(&defines, conf))
 		goto out;
 
 	if (!rcfile && !strcmp("/sbin/init", args[0])) {
-		ERROR("no configuration file for '/sbin/init' (may crash the host)");
+		ERROR("Executing '/sbin/init' with no configuration file may crash the host");
 		goto out;
 	}
 
@@ -228,10 +253,7 @@ int main(int argc, char *argv[])
 	}
 
 	if (my_args.daemonize) {
-		if (daemon(0, 0)) {
-			SYSERROR("failed to daemonize '%s'", my_args.name);
-			goto out;
-		}
+		c->want_daemonize(c);
 	}
 
 	if (pid_fp != NULL) {
@@ -245,23 +267,13 @@ int main(int argc, char *argv[])
 	if (my_args.close_all_fds)
 		conf->close_all_fds = 1;
 
-	err = lxc_start(my_args.name, args, conf, my_args.lxcpath[0]);
-
-	/*
-	 * exec ourself, that requires to have all opened fd
-	 * with the close-on-exec flag set
-	 */
-	if (conf->reboot) {
-		INFO("rebooting container");
-		execvp(argv[0], argv);
-		SYSERROR("failed to exec");
-		err = -1;
-	}
+	err = c->start(c, 0, args) ? 0 : -1;
 
 	if (my_args.pidfile)
 		unlink(my_args.pidfile);
+
 out:
-	lxc_conf_free(conf);
+	lxc_container_put(c);
 	return err;
 }
 
-- 
1.8.3.2





More information about the lxc-devel mailing list