[lxc-devel] [lxc/master] start: add lxc_init_handler()

brauner on Github lxc-bot at linuxcontainers.org
Thu Jun 8 00:02:10 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 364 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170608/c80660db/attachment.bin>
-------------- next part --------------
From 6d5801078577af095f2e058fdee1b2a2c72217ab Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 7 Jun 2017 22:23:56 +0200
Subject: [PATCH] start: add lxc_init_handler()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/criu.c              |  5 +++-
 src/lxc/execute.c           | 15 +++++------
 src/lxc/lxc.h               |  8 +++---
 src/lxc/lxccontainer.c      | 22 ++++++++++++----
 src/lxc/start.c             | 59 +++++++++++++++++++++++++++---------------
 src/lxc/start.h             |  9 ++++---
 src/lxc/tools/lxc_execute.c | 63 +++++++++++++++++++--------------------------
 7 files changed, 103 insertions(+), 78 deletions(-)

diff --git a/src/lxc/criu.c b/src/lxc/criu.c
index 9b0ccacb6..6fa42b246 100644
--- a/src/lxc/criu.c
+++ b/src/lxc/criu.c
@@ -797,10 +797,13 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
 		close(fd);
 	}
 
-	handler = lxc_init(c->name, c->lxc_conf, c->config_path);
+	handler = lxc_init_handler(c->name, c->lxc_conf, c->config_path);
 	if (!handler)
 		goto out;
 
+	if (lxc_init(c->name, handler) < 0)
+		goto out;
+
 	if (!cgroup_init(handler)) {
 		ERROR("failed initing cgroups");
 		goto out_fini_handler;
diff --git a/src/lxc/execute.c b/src/lxc/execute.c
index cfc81a761..40fd2241e 100644
--- a/src/lxc/execute.c
+++ b/src/lxc/execute.c
@@ -111,16 +111,15 @@ static struct lxc_operations execute_start_ops = {
 };
 
 int lxc_execute(const char *name, char *const argv[], int quiet,
-		struct lxc_conf *conf, const char *lxcpath, bool backgrounded)
+		struct lxc_handler *handler, const char *lxcpath,
+		bool backgrounded)
 {
-	struct execute_args args = {
-		.argv = argv,
-		.quiet = quiet
-	};
+	struct execute_args args = {.argv = argv, .quiet = quiet};
 
-	if (lxc_check_inherited(conf, false, -1))
+	if (lxc_check_inherited(handler->conf, false, handler->conf->maincmd_fd))
 		return -1;
 
-	conf->is_execute = 1;
-	return __lxc_start(name, conf, &execute_start_ops, &args, lxcpath, backgrounded);
+	handler->conf->is_execute = 1;
+	return __lxc_start(name, handler, &execute_start_ops, &args, lxcpath,
+			   backgrounded);
 }
diff --git a/src/lxc/lxc.h b/src/lxc/lxc.h
index c6182d4e6..c3c55828a 100644
--- a/src/lxc/lxc.h
+++ b/src/lxc/lxc.h
@@ -36,6 +36,7 @@ extern "C" {
 struct lxc_msg;
 struct lxc_conf;
 struct lxc_arguments;
+struct lxc_handler;
 
 /**
  Following code is for liblxc.
@@ -51,8 +52,9 @@ struct lxc_arguments;
  * @backgrounded : whether or not the container is daemonized
  * Returns 0 on success, < 0 otherwise
  */
-extern int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf,
-		     const char *lxcpath, bool backgrounded);
+extern int lxc_start(const char *name, char *const argv[],
+		     struct lxc_handler *handler, const char *lxcpath,
+		     bool backgrounded);
 
 /*
  * Start the specified command inside an application container
@@ -64,7 +66,7 @@ extern int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf
  * Returns 0 on success, < 0 otherwise
  */
 extern int lxc_execute(const char *name, char *const argv[], int quiet,
-		       struct lxc_conf *conf, const char *lxcpath,
+		       struct lxc_handler *handler, const char *lxcpath,
 		       bool backgrounded);
 
 /*
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index ebed82bc1..367b2d3e8 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -57,6 +57,7 @@
 #include "namespace.h"
 #include "network.h"
 #include "sync.h"
+#include "start.h"
 #include "state.h"
 #include "utils.h"
 #include "version.h"
@@ -715,6 +716,7 @@ static void free_init_cmd(char **argv)
 static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const argv[])
 {
 	int ret;
+	struct lxc_handler *handler;
 	struct lxc_conf *conf;
 	bool daemonize = false;
 	FILE *pid_fp = NULL;
@@ -731,7 +733,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 	/* If anything fails before we set error_num, we want an error in there */
 	c->error_num = 1;
 
-	/* container has been setup */
+	/* container has not been setup */
 	if (!c->lxc_conf)
 		return false;
 
@@ -758,8 +760,16 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 	daemonize = c->daemonize;
 	container_mem_unlock(c);
 
+	/* initialize handler */
+	handler = lxc_init_handler(c->name, c->lxc_conf, c->config_path);
+	if (!handler)
+		return false;
+
 	if (useinit) {
-		ret = lxc_execute(c->name, argv, 1, conf, c->config_path, daemonize);
+		TRACE("calling \"lxc_execute\"");
+		ret = lxc_execute(c->name, argv, 1, handler, c->config_path,
+				  daemonize);
+		c->error_num = ret;
 		return ret == 0 ? true : false;
 	}
 
@@ -815,7 +825,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 			SYSERROR("Error chdir()ing to /.");
 			exit(1);
 		}
-		lxc_check_inherited(conf, true, -1);
+		lxc_check_inherited(conf, true, handler->conf->maincmd_fd);
 		if (null_stdfds() < 0) {
 			ERROR("failed to close fds");
 			exit(1);
@@ -869,14 +879,16 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 	}
 
 reboot:
-	if (lxc_check_inherited(conf, daemonize, -1)) {
+	if (lxc_check_inherited(conf, daemonize, handler->conf->maincmd_fd)) {
 		ERROR("Inherited fds found");
 		ret = 1;
 		goto out;
 	}
 
-	ret = lxc_start(c->name, argv, conf, c->config_path, daemonize);
+	ret = lxc_start(c->name, argv, handler, c->config_path, daemonize);
 	c->error_num = ret;
+	/* close the command socket after the fork */
+	close(handler->conf->maincmd_fd);
 
 	if (conf->reboot == 1) {
 		INFO("container requested reboot");
diff --git a/src/lxc/start.c b/src/lxc/start.c
index bd1c62697..bac5dc3f2 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -396,14 +396,17 @@ int lxc_poll(const char *name, struct lxc_handler *handler)
 	return -1;
 }
 
-struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf, const char *lxcpath)
+struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,
+				     const char *lxcpath)
 {
 	int i;
 	struct lxc_handler *handler;
 
 	handler = malloc(sizeof(*handler));
-	if (!handler)
+	if (!handler) {
+		ERROR("failed to allocate memory");
 		return NULL;
+	}
 
 	memset(handler, 0, sizeof(*handler));
 
@@ -419,12 +422,32 @@ struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf, const char
 
 	handler->name = strdup(name);
 	if (!handler->name) {
-		ERROR("Failed to allocate memory.");
-		goto out_free;
+		ERROR("failed to allocate memory");
+		goto do_partial_cleanup;
+	}
+
+	if (lxc_cmd_init(name, handler, lxcpath)) {
+		ERROR("failed to set up command socket");
+		goto do_full_cleanup;
 	}
 
-	if (lxc_cmd_init(name, handler, lxcpath))
-		goto out_free_name;
+	TRACE("unix domain socket %d for command server is ready",
+	      handler->conf->maincmd_fd);
+
+	return handler;
+
+do_full_cleanup:
+	free(handler->name);
+
+do_partial_cleanup:
+	free(handler);
+
+	return NULL;
+}
+
+int lxc_init(const char *name, struct lxc_handler *handler)
+{
+	struct lxc_conf *conf = handler->conf;
 
 	if (lxc_read_seccomp_config(conf) != 0) {
 		ERROR("Failed loading seccomp policy.");
@@ -487,7 +510,7 @@ struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf, const char
 	}
 
 	INFO("Container \"%s\" is initialized.", name);
-	return handler;
+	return 0;
 
 out_restore_sigmask:
 	sigprocmask(SIG_SETMASK, &handler->oldmask, NULL);
@@ -498,12 +521,7 @@ struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf, const char
 out_close_maincmd_fd:
 	close(conf->maincmd_fd);
 	conf->maincmd_fd = -1;
-out_free_name:
-	free(handler->name);
-	handler->name = NULL;
-out_free:
-	free(handler);
-	return NULL;
+	return -1;
 }
 
 void lxc_fini(const char *name, struct lxc_handler *handler)
@@ -1337,17 +1355,16 @@ static int lxc_spawn(struct lxc_handler *handler)
 	return -1;
 }
 
-int __lxc_start(const char *name, struct lxc_conf *conf,
+int __lxc_start(const char *name, struct lxc_handler *handler,
 		struct lxc_operations* ops, void *data, const char *lxcpath,
 		bool backgrounded)
 {
-	struct lxc_handler *handler;
-	int err = -1;
 	int status;
+	int err = -1;
 	bool removed_all_netdevs = true;
+	struct lxc_conf *conf = handler->conf;
 
-	handler = lxc_init(name, conf, lxcpath);
-	if (!handler) {
+	if (lxc_init(name, handler) < 0) {
 		ERROR("Failed to initialize container \"%s\".", name);
 		return -1;
 	}
@@ -1494,15 +1511,15 @@ static struct lxc_operations start_ops = {
 	.post_start = post_start
 };
 
-int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf,
+int lxc_start(const char *name, char *const argv[], struct lxc_handler *handler,
 	      const char *lxcpath, bool backgrounded)
 {
 	struct start_args start_arg = {
 		.argv = argv,
 	};
 
-	conf->need_utmp_watch = 1;
-	return __lxc_start(name, conf, &start_ops, &start_arg, lxcpath, backgrounded);
+	handler->conf->need_utmp_watch = 1;
+	return __lxc_start(name, handler, &start_ops, &start_arg, lxcpath, backgrounded);
 }
 
 static void lxc_destroy_container_on_signal(struct lxc_handler *handler,
diff --git a/src/lxc/start.h b/src/lxc/start.h
index 3bae8788c..7b8ebcf92 100644
--- a/src/lxc/start.h
+++ b/src/lxc/start.h
@@ -27,11 +27,11 @@
 #include <sys/param.h>
 #include <stdbool.h>
 
+#include "conf.h"
 #include "config.h"
 #include "state.h"
 #include "namespace.h"
 
-struct lxc_conf;
 
 struct lxc_handler;
 
@@ -66,11 +66,14 @@ struct lxc_handler {
 extern int lxc_poll(const char *name, struct lxc_handler *handler);
 extern int lxc_set_state(const char *name, struct lxc_handler *handler, lxc_state_t state);
 extern void lxc_abort(const char *name, struct lxc_handler *handler);
-extern struct lxc_handler *lxc_init(const char *name, struct lxc_conf *, const char *);
+extern struct lxc_handler *lxc_init_handler(const char *name,
+					    struct lxc_conf *conf,
+					    const char *lxcpath);
+extern int lxc_init(const char *name, struct lxc_handler *handler);
 extern void lxc_fini(const char *name, struct lxc_handler *handler);
 
 extern int lxc_check_inherited(struct lxc_conf *conf, bool closeall, int fd_to_ignore);
-int __lxc_start(const char *, struct lxc_conf *, struct lxc_operations *,
+int __lxc_start(const char *, struct lxc_handler *, struct lxc_operations *,
 		void *, const char *, bool);
 
 extern void resolve_clone_flags(struct lxc_handler *handler);
diff --git a/src/lxc/tools/lxc_execute.c b/src/lxc/tools/lxc_execute.c
index f26105ad6..ce59df74f 100644
--- a/src/lxc/tools/lxc_execute.c
+++ b/src/lxc/tools/lxc_execute.c
@@ -41,6 +41,8 @@
 #include "start.h"
 #include "utils.h"
 
+#include "lxc/lxccontainer.h"
+
 lxc_log_define(lxc_execute_ui, lxc);
 
 static struct lxc_list defines;
@@ -104,9 +106,8 @@ Options :\n\
 
 int main(int argc, char *argv[])
 {
-	char *rcfile;
-	struct lxc_conf *conf;
-	int ret;
+	struct lxc_container *c;
+	int bret, ret;
 
 	lxc_list_init(&defines);
 
@@ -121,50 +122,38 @@ int main(int argc, char *argv[])
 		exit(EXIT_FAILURE);
 	lxc_log_options_no_override();
 
-	/* rcfile is specified in the cli option */
-	if (my_args.rcfile)
-		rcfile = (char *)my_args.rcfile;
-	else {
-		int rc;
+	c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
+	if (!c) {
+		ERROR("Failed to create lxc_container");
+		exit(EXIT_FAILURE);
+	}
 
-		rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath[0], my_args.name);
-		if (rc == -1) {
-			SYSERROR("failed to allocate memory");
+	if (my_args.rcfile) {
+		c->clear_config(c);
+		if (!c->load_config(c, my_args.rcfile)) {
+			ERROR("Failed to load rcfile");
+			lxc_container_put(c);
 			exit(EXIT_FAILURE);
 		}
-
-		/* container configuration does not exist */
-		if (access(rcfile, F_OK)) {
-			free(rcfile);
-			rcfile = NULL;
+		c->configfile = strdup(my_args.rcfile);
+		if (!c->configfile) {
+			ERROR("Out of memory setting new config filename");
+			lxc_container_put(c);
+			exit(EXIT_FAILURE);
 		}
 	}
 
-	conf = lxc_conf_init();
-	if (!conf) {
-		ERROR("failed to initialize configuration");
-		exit(EXIT_FAILURE);
-	}
-
-	if (rcfile && lxc_config_read(rcfile, conf, NULL)) {
-		ERROR("failed to read configuration file");
-		exit(EXIT_FAILURE);
-	}
-
-	if (lxc_config_define_load(&defines, conf))
-		exit(EXIT_FAILURE);
-
 	if (my_args.uid)
-		conf->init_uid = my_args.uid;
+		c->lxc_conf->init_uid = my_args.uid;
 
 	if (my_args.gid)
-		conf->init_gid = my_args.gid;
-
-	ret = lxc_execute(my_args.name, my_args.argv, my_args.quiet, conf, my_args.lxcpath[0], false);
-
-	lxc_conf_free(conf);
+		c->lxc_conf->init_gid = my_args.gid;
 
-	if (ret < 0)
+	c->daemonize = false;
+	bret = c->start(c, 1, my_args.argv);
+	ret = c->error_num;
+	lxc_container_put(c);
+	if (!bret)
 		exit(EXIT_FAILURE);
 	exit(ret);
 }


More information about the lxc-devel mailing list