[lxc-devel] [lxc/master] reboot fixes

brauner on Github lxc-bot at linuxcontainers.org
Wed May 13 11:03:38 UTC 2020


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/20200513/d2125ff7/attachment.bin>
-------------- next part --------------
From fb1a080dafb017d0cce0e09b969878789df6b0b1 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 13 May 2020 12:25:25 +0200
Subject: [PATCH 1/4] lxccontainer: small cleanup to lxc_check_inherited()
 calls

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/lxccontainer.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 487d83894d..ea70464ce7 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -867,7 +867,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 		NULL,
 	};
 	char **init_cmd = NULL;
-	int keepfds[3] = {-1, -1, -1};
+	int keepfds[3] = {-EBADF, -EBADF, -EBADF};
 
 	/* container does exist */
 	if (!c)
@@ -1001,8 +1001,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 		keepfds[0] = handler->conf->maincmd_fd;
 		keepfds[1] = handler->state_socket_pair[0];
 		keepfds[2] = handler->state_socket_pair[1];
-		ret = lxc_check_inherited(conf, true, keepfds,
-					  sizeof(keepfds) / sizeof(keepfds[0]));
+		ret = lxc_check_inherited(conf, true, keepfds, ARRAY_SIZE(keepfds));
 		if (ret < 0)
 			_exit(EXIT_FAILURE);
 
@@ -1092,8 +1091,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 	keepfds[0] = handler->conf->maincmd_fd;
 	keepfds[1] = handler->state_socket_pair[0];
 	keepfds[2] = handler->state_socket_pair[1];
-	ret = lxc_check_inherited(conf, c->daemonize, keepfds,
-				  sizeof(keepfds) / sizeof(keepfds[0]));
+	ret = lxc_check_inherited(conf, c->daemonize, keepfds, ARRAY_SIZE(keepfds));
 	if (ret < 0) {
 		lxc_free_handler(handler);
 		ret = 1;

From 824c5efae308139434ac16d8c13d715b0e03a1d4 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 13 May 2020 12:32:38 +0200
Subject: [PATCH 2/4] start: remove unused lxc_zero_handler()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/start.c | 25 -------------------------
 src/lxc/start.h |  1 -
 2 files changed, 26 deletions(-)

diff --git a/src/lxc/start.c b/src/lxc/start.c
index b7c86bd6cc..599f08f88b 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -605,31 +605,6 @@ int lxc_poll(const char *name, struct lxc_handler *handler)
 	return ret;
 }
 
-void lxc_zero_handler(struct lxc_handler *handler)
-{
-	memset(handler, 0, sizeof(struct lxc_handler));
-
-	handler->state = STOPPED;
-
-	handler->pinfd = -EBADF;
-
-	handler->pidfd = -EBADF;
-
-	handler->sigfd = -EBADF;
-
-	for (int i = 0; i < LXC_NS_MAX; i++)
-		handler->nsfd[i] = -EBADF;
-
-	handler->data_sock[0] = -EBADF;
-	handler->data_sock[1] = -EBADF;
-
-	handler->state_socket_pair[0] = -EBADF;
-	handler->state_socket_pair[1] = -EBADF;
-
-	handler->sync_sock[0] = -EBADF;
-	handler->sync_sock[1] = -EBADF;
-}
-
 void lxc_free_handler(struct lxc_handler *handler)
 {
 	close_prot_errno_disarm(handler->pinfd);
diff --git a/src/lxc/start.h b/src/lxc/start.h
index 7e2371c74b..3e742affa4 100644
--- a/src/lxc/start.h
+++ b/src/lxc/start.h
@@ -147,7 +147,6 @@ extern struct lxc_handler *lxc_init_handler(const char *name,
 					    struct lxc_conf *conf,
 					    const char *lxcpath,
 					    bool daemonize);
-extern void lxc_zero_handler(struct lxc_handler *handler);
 extern void lxc_free_handler(struct lxc_handler *handler);
 extern int lxc_init(const char *name, struct lxc_handler *handler);
 extern void lxc_end(struct lxc_handler *handler);

From f1426d583ce46e0f57433ea6dc8bf14b58e21e07 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 13 May 2020 12:39:28 +0200
Subject: [PATCH 3/4] lxccontainer: use close_prot_errno_disarm() on
 state_socket_pair

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/lxccontainer.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index ea70464ce7..718b570d2e 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -830,14 +830,12 @@ static bool wait_on_daemonized_start(struct lxc_handler *handler, int pid)
 		DEBUG("First child %d exited", pid);
 
 	/* Close write end of the socket pair. */
-	close(handler->state_socket_pair[1]);
-	handler->state_socket_pair[1] = -1;
+	close_prot_errno_disarm(handler->state_socket_pair[1]);
 
 	state = lxc_rcv_status(handler->state_socket_pair[0]);
 
 	/* Close read end of the socket pair. */
-	close(handler->state_socket_pair[0]);
-	handler->state_socket_pair[0] = -1;
+	close_prot_errno_disarm(handler->state_socket_pair[0]);
 
 	if (state < 0) {
 		SYSERROR("Failed to receive the container state");

From a42abccecc79bf8b8acec4641885763fa4eddd2a Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 13 May 2020 12:59:59 +0200
Subject: [PATCH 4/4] start: fix container reboot

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/criu.c         |  2 +-
 src/lxc/lxccontainer.c | 29 +++++++++++++++--------------
 src/lxc/start.c        | 22 +++++++++++++---------
 src/lxc/start.h        |  8 ++++----
 4 files changed, 33 insertions(+), 28 deletions(-)

diff --git a/src/lxc/criu.c b/src/lxc/criu.c
index 288f1f5157..a8af09f7b0 100644
--- a/src/lxc/criu.c
+++ b/src/lxc/criu.c
@@ -942,7 +942,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
 		close(fd);
 	}
 
-	handler = lxc_init_handler(c->name, c->lxc_conf, c->config_path, false);
+	handler = lxc_init_handler(NULL, c->name, c->lxc_conf, c->config_path, false);
 	if (!handler)
 		goto out;
 
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 718b570d2e..80f2f66d3f 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -899,7 +899,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 	conf = c->lxc_conf;
 
 	/* initialize handler */
-	handler = lxc_init_handler(c->name, conf, c->config_path, c->daemonize);
+	handler = lxc_init_handler(NULL, c->name, conf, c->config_path, c->daemonize);
 
 	container_mem_unlock(c);
 	if (!handler)
@@ -916,7 +916,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 	if (!argv) {
 		if (useinit) {
 			ERROR("No valid init detected");
-			lxc_free_handler(handler);
+			lxc_put_handler(handler);
 			return false;
 		}
 		argv = default_args;
@@ -934,7 +934,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 		pid_first = fork();
 		if (pid_first < 0) {
 			free_init_cmd(init_cmd);
-			lxc_free_handler(handler);
+			lxc_put_handler(handler);
 			return false;
 		}
 
@@ -951,7 +951,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 			started = wait_on_daemonized_start(handler, pid_first);
 
 			free_init_cmd(init_cmd);
-			lxc_free_handler(handler);
+			lxc_put_handler(handler);
 			return started;
 		}
 
@@ -983,7 +983,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 		/* second parent */
 		if (pid_second != 0) {
 			free_init_cmd(init_cmd);
-			lxc_free_handler(handler);
+			lxc_put_handler(handler);
 			_exit(EXIT_SUCCESS);
 		}
 
@@ -1017,7 +1017,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 	} else if (!am_single_threaded()) {
 		ERROR("Cannot start non-daemonized container when threaded");
 		free_init_cmd(init_cmd);
-		lxc_free_handler(handler);
+		lxc_put_handler(handler);
 		return false;
 	}
 
@@ -1031,7 +1031,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 		w = snprintf(pidstr, sizeof(pidstr), "%d", lxc_raw_getpid());
 		if (w < 0 || (size_t)w >= sizeof(pidstr)) {
 			free_init_cmd(init_cmd);
-			lxc_free_handler(handler);
+			lxc_put_handler(handler);
 
 			SYSERROR("Failed to write monitor pid to \"%s\"", c->pidfile);
 
@@ -1044,7 +1044,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 		ret = lxc_write_to_file(c->pidfile, pidstr, w, false, 0600);
 		if (ret < 0) {
 			free_init_cmd(init_cmd);
-			lxc_free_handler(handler);
+			lxc_put_handler(handler);
 
 			SYSERROR("Failed to write monitor pid to \"%s\"", c->pidfile);
 
@@ -1062,7 +1062,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 		ret = unshare(CLONE_NEWNS);
 		if (ret < 0) {
 			SYSERROR("Failed to unshare mount namespace");
-			lxc_free_handler(handler);
+			lxc_put_handler(handler);
 			ret = 1;
 			goto on_error;
 		}
@@ -1070,7 +1070,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 		ret = mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL);
 		if (ret < 0) {
 			SYSERROR("Failed to make / rslave at startup");
-			lxc_free_handler(handler);
+			lxc_put_handler(handler);
 			ret = 1;
 			goto on_error;
 		}
@@ -1079,19 +1079,20 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 reboot:
 	if (conf->reboot == REBOOT_INIT) {
 		/* initialize handler */
-		handler = lxc_init_handler(c->name, conf, c->config_path, c->daemonize);
+		handler = lxc_init_handler(handler, c->name, conf, c->config_path, c->daemonize);
 		if (!handler) {
 			ret = 1;
 			goto on_error;
 		}
+	} else {
+		keepfds[1] = handler->state_socket_pair[0];
+		keepfds[2] = handler->state_socket_pair[1];
 	}
 
 	keepfds[0] = handler->conf->maincmd_fd;
-	keepfds[1] = handler->state_socket_pair[0];
-	keepfds[2] = handler->state_socket_pair[1];
 	ret = lxc_check_inherited(conf, c->daemonize, keepfds, ARRAY_SIZE(keepfds));
 	if (ret < 0) {
-		lxc_free_handler(handler);
+		lxc_put_handler(handler);
 		ret = 1;
 		goto on_error;
 	}
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 599f08f88b..49714e6ad3 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -605,7 +605,7 @@ int lxc_poll(const char *name, struct lxc_handler *handler)
 	return ret;
 }
 
-void lxc_free_handler(struct lxc_handler *handler)
+void lxc_put_handler(struct lxc_handler *handler)
 {
 	close_prot_errno_disarm(handler->pinfd);
 	close_prot_errno_disarm(handler->pidfd);
@@ -617,22 +617,26 @@ void lxc_free_handler(struct lxc_handler *handler)
 	close_prot_errno_disarm(handler->state_socket_pair[0]);
 	close_prot_errno_disarm(handler->state_socket_pair[1]);
 	cgroup_exit(handler->cgroup_ops);
-	handler->conf = NULL;
-	free_disarm(handler);
+	if (handler->conf && handler->conf->reboot == REBOOT_NONE)
+		free_disarm(handler);
+	else
+		handler->conf = NULL;
 }
 
-struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,
+struct lxc_handler *lxc_init_handler(struct lxc_handler *old,
+				     const char *name, struct lxc_conf *conf,
 				     const char *lxcpath, bool daemonize)
 {
 	int ret;
 	struct lxc_handler *handler;
 
-	handler = malloc(sizeof(*handler));
+	if (!old)
+		handler = zalloc(sizeof(*handler));
+	else
+		handler = old;
 	if (!handler)
 		return NULL;
 
-	memset(handler, 0, sizeof(*handler));
-
 	/* Note that am_guest_unpriv() checks the effective uid. We
 	 * probably don't care if we are real root only if we are running
 	 * as root so this should be fine.
@@ -692,7 +696,7 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,
 	return handler;
 
 on_error:
-	lxc_free_handler(handler);
+	lxc_put_handler(handler);
 
 	return NULL;
 }
@@ -983,7 +987,7 @@ void lxc_end(struct lxc_handler *handler)
 	if (handler->conf->ephemeral == 1 && handler->conf->reboot != REBOOT_REQ)
 		lxc_destroy_container_on_signal(handler, name);
 
-	lxc_free_handler(handler);
+	lxc_put_handler(handler);
 }
 
 void lxc_abort(struct lxc_handler *handler)
diff --git a/src/lxc/start.h b/src/lxc/start.h
index 3e742affa4..88afc79b1e 100644
--- a/src/lxc/start.h
+++ b/src/lxc/start.h
@@ -143,11 +143,11 @@ extern int lxc_serve_state_clients(const char *name,
 				   struct lxc_handler *handler,
 				   lxc_state_t state);
 extern void lxc_abort(struct lxc_handler *handler);
-extern struct lxc_handler *lxc_init_handler(const char *name,
+extern struct lxc_handler *lxc_init_handler(struct lxc_handler *old,
+					    const char *name,
 					    struct lxc_conf *conf,
-					    const char *lxcpath,
-					    bool daemonize);
-extern void lxc_free_handler(struct lxc_handler *handler);
+					    const char *lxcpath, bool daemonize);
+extern void lxc_put_handler(struct lxc_handler *handler);
 extern int lxc_init(const char *name, struct lxc_handler *handler);
 extern void lxc_end(struct lxc_handler *handler);
 


More information about the lxc-devel mailing list