From 5aee93396a979771f59d8accc4f4c168fd31b584 Mon Sep 17 00:00:00 2001
From: wujing <wujing50@huawei.com>
Date: Mon, 13 Apr 2020 06:32:37 -0400
Subject: [PATCH 11/49] add exit fifo to monitor state of lxc monitor

Signed-off-by: wujing <wujing50@huawei.com>
---
 src/lxc/conf.c            |  4 ++++
 src/lxc/conf.h            |  2 ++
 src/lxc/lxccontainer.c    | 30 ++++++++++++++++++++++++++++++
 src/lxc/lxccontainer.h    |  8 ++++++++
 src/lxc/start.c           | 20 ++++++++++++++++++++
 src/lxc/start.h           |  5 +++++
 src/lxc/tools/arguments.h |  1 +
 src/lxc/tools/lxc_start.c | 14 ++++++++++++++
 8 files changed, 84 insertions(+)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 1487b73..a904348 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -2668,6 +2668,7 @@ struct lxc_conf *lxc_conf_init(void)
 #ifdef HAVE_ISULAD
 	/* isulad add begin */
 	lxc_list_init(&new->populate_devs);
+	new->exit_fd = -1;
 	new->umask = 0027; /*default umask 0027*/
 	new->console.init_fifo[0] = NULL;
 	new->console.init_fifo[1] = NULL;
@@ -4097,6 +4098,9 @@ void lxc_conf_free(struct lxc_conf *conf)
 	free(conf->shmount.path_cont);
 #ifdef HAVE_ISULAD
 	free(conf->container_info_file);
+	if (conf->exit_fd != -1) {
+		close(conf->exit_fd);
+	}
 	lxc_clear_init_args(conf);
 	lxc_clear_populate_devices(conf);
 #endif
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 23942ac..c5b70e1 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -430,6 +430,8 @@ struct lxc_conf {
 	mode_t umask;  //umask value
 
 	char *container_info_file;
+
+	int exit_fd; /* exit fifo fd*/
 #endif
 
 };
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 891fc62..64cde99 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -281,6 +281,11 @@ static void lxc_container_free(struct lxc_container *c)
 	free(c->config_path);
 	c->config_path = NULL;
 
+#ifdef HAVE_ISULAD
+	free(c->exit_fifo);
+	c->exit_fifo = NULL;
+#endif
+
 	free(c);
 }
 
@@ -894,7 +899,11 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 		NULL,
 	};
 	char **init_cmd = NULL;
+#ifdef HAVE_ISULAD
+	int keepfds[] = {-1, -1, -1, -1, -1};
+#else
 	int keepfds[3] = {-1, -1, -1};
+#endif
 
 	/* container does exist */
 	if (!c)
@@ -1091,6 +1100,19 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 		}
 	}
 
+#ifdef HAVE_ISULAD
+	/* isulad: open exit fifo */
+	if (c->exit_fifo) {
+		conf->exit_fd = lxc_open(c->exit_fifo, O_WRONLY | O_NONBLOCK | O_CLOEXEC, 0);
+		if (conf->exit_fd < 0) {
+			ERROR("Failed to open exit fifo %s: %s.", c->exit_fifo, strerror(errno));
+			lxc_free_handler(handler);
+			ret = 1;
+			goto on_error;
+		}
+	}
+#endif
+
 	conf->reboot = REBOOT_NONE;
 
 	/* Unshare the mount namespace if requested */
@@ -1125,6 +1147,14 @@ reboot:
 	keepfds[0] = handler->conf->maincmd_fd;
 	keepfds[1] = handler->state_socket_pair[0];
 	keepfds[2] = handler->state_socket_pair[1];
+
+#ifdef HAVE_ISULAD
+	/* keep exit fifo fd */
+	if (conf->exit_fd >= 0) {
+		keepfds[3] = conf->exit_fd;
+	}
+#endif
+
 	ret = lxc_check_inherited(conf, c->daemonize, keepfds,
 				  sizeof(keepfds) / sizeof(keepfds[0]));
 	if (ret < 0) {
diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h
index 4a9ba13..fa9bd5e 100644
--- a/src/lxc/lxccontainer.h
+++ b/src/lxc/lxccontainer.h
@@ -107,6 +107,14 @@ struct lxc_container {
 	/*! Full path to configuration file */
 	char *config_path;
 
+#ifdef HAVE_ISULAD
+	/*! isulad:
+	 * \private
+	 * exit FIFO File to open used monitor the state of lxc monitor process.
+	 */
+	char *exit_fifo;
+#endif
+
 	/*!
 	 * \brief Determine if \c /var/lib/lxc/$name/config exists.
 	 *
diff --git a/src/lxc/start.c b/src/lxc/start.c
index f5f9565..70e8282 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -681,6 +681,11 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,
 		handler->nsfd[i] = -EBADF;
 
 	handler->name = name;
+
+#ifdef HAVE_ISULAD
+	handler->exit_code = -1; /* isulad: record exit code of container */
+#endif
+
 	if (daemonize)
 		handler->transient_pid = lxc_raw_getpid();
 	else
@@ -953,6 +958,16 @@ void lxc_end(struct lxc_handler *handler)
 		 */
 		lxc_monitor_send_state(name, STOPPED, handler->lxcpath);
 
+#ifdef HAVE_ISULAD
+		/* isuald: write exit code to exit fifo */
+		if (handler->conf->exit_fd >= 0) {
+			ret = write(handler->conf->exit_fd, &handler->exit_code, sizeof(int));
+			if (ret != sizeof(int)) {
+				SYSERROR("Failed to write to exit code to exit fifo.");
+			}
+		}
+#endif
+
 		/* The command socket is closed so no one can acces the command
 		 * socket anymore so there's no need to lock it.
 		 */
@@ -2127,10 +2142,15 @@ int __lxc_start(struct lxc_handler *handler, struct lxc_operations *ops,
 #else
 	lxc_monitor_send_exit_code(name, status, handler->lxcpath);
 #endif
+
 	lxc_error_set_and_log(handler->pid, status);
 	if (error_num)
 		*error_num = handler->exit_status;
 
+#ifdef HAVE_ISULAD
+	handler->exit_code = exit_code; /* record exit code */
+#endif
+
 /* These are not the droids you are looking for. */
 __private_goto1:
 	lxc_delete_network(handler);
diff --git a/src/lxc/start.h b/src/lxc/start.h
index 7e2371c..1368d0e 100644
--- a/src/lxc/start.h
+++ b/src/lxc/start.h
@@ -122,6 +122,11 @@ struct lxc_handler {
 	int exit_status;
 
 	struct cgroup_ops *cgroup_ops;
+
+#ifdef HAVE_ISULAD
+	int exit_code;/* isulad: record the exit code of container */
+#endif
+
 };
 
 struct execute_args {
diff --git a/src/lxc/tools/arguments.h b/src/lxc/tools/arguments.h
index 214949b..ea5f938 100644
--- a/src/lxc/tools/arguments.h
+++ b/src/lxc/tools/arguments.h
@@ -43,6 +43,7 @@ struct lxc_arguments {
 #ifdef HAVE_ISULAD
 	const char *container_info; /* isulad: file used to store pid and ppid info of container */
 	char *terminal_fifos[3]; /* isulad add, fifos used to redirct stdin/out/err */
+	const char *exit_monitor_fifo; /* isulad: fifo used to monitor state of monitor process */
 #endif
 
 	/* for lxc-console */
diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c
index 4c4c820..8041f02 100644
--- a/src/lxc/tools/lxc_start.c
+++ b/src/lxc/tools/lxc_start.c
@@ -28,6 +28,10 @@
 #include "confile.h"
 #include "log.h"
 
+#ifdef HAVE_ISULAD
+#include "isulad_utils.h"
+#endif
+
 lxc_log_define(lxc_start, lxc);
 
 static int my_parser(struct lxc_arguments *args, int c, char *arg);
@@ -50,6 +54,7 @@ static const struct option my_longopts[] = {
 	{"share-pid", required_argument, 0, OPT_SHARE_PID},
 #ifdef HAVE_ISULAD
 	{"container-pidfile", required_argument, 0, OPT_CONTAINER_INFO},
+	{"exit-fifo", required_argument, 0, OPT_EXIT_FIFO},
 #endif
 	LXC_COMMON_OPTIONS
 };
@@ -121,6 +126,7 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg)
 	case OPT_SHARE_PID:
 		args->share_ns[LXC_NS_PID] = arg;
 		break;
+
 #ifdef HAVE_ISULAD
 	case OPT_CONTAINER_INFO:
 		args->container_info = arg;
@@ -133,8 +139,11 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg)
 		break;
 	case OPT_STDERR_FIFO:
 		args->terminal_fifos[2] = arg;
+	case OPT_EXIT_FIFO:
+		args->exit_monitor_fifo = arg;
 		break;
 #endif
+
 	}
 	return 0;
 }
@@ -315,8 +324,13 @@ int main(int argc, char *argv[])
 			goto out;
 		}
 	}
+
 	if (my_args.terminal_fifos[0] || my_args.terminal_fifos[1] || my_args.terminal_fifos[2]) {
 		c->set_terminal_init_fifos(c, my_args.terminal_fifos[0], my_args.terminal_fifos[1], my_args.terminal_fifos[2]);
+
+	/* isulad: fifo used to monitor state of monitor process */
+	if (my_args.exit_monitor_fifo != NULL) {
+		c->exit_fifo = safe_strdup(my_args.exit_monitor_fifo);
 	}
 #endif
 
-- 
1.8.3.1

