2020-04-23 11:50:43 +08:00
|
|
|
From 52aa8985248200041b2a093634a8c36cb4bb8414 Mon Sep 17 00:00:00 2001
|
|
|
|
|
From: haozi007 <liuhao27@huawei.com>
|
|
|
|
|
Date: Tue, 14 Apr 2020 18:33:53 +0800
|
|
|
|
|
Subject: [PATCH 25/49] support oci hooks
|
2019-09-30 11:03:07 -04:00
|
|
|
|
2020-04-23 11:50:43 +08:00
|
|
|
Signed-off-by: haozi007 <liuhao27@huawei.com>
|
2019-09-30 11:03:07 -04:00
|
|
|
---
|
2020-04-23 11:50:43 +08:00
|
|
|
src/lxc/conf.c | 542 +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
src/lxc/conf.h | 17 ++
|
|
|
|
|
src/lxc/lxccontainer.c | 110 ++++++++++
|
|
|
|
|
src/lxc/lxccontainer.h | 28 +++
|
|
|
|
|
src/lxc/start.c | 277 +++++++++++++++++++++++++
|
|
|
|
|
src/lxc/start.h | 8 +
|
|
|
|
|
src/lxc/sync.h | 4 +
|
|
|
|
|
src/lxc/utils.c | 38 ++++
|
|
|
|
|
src/lxc/utils.h | 2 +
|
|
|
|
|
9 files changed, 1026 insertions(+)
|
2019-09-30 11:03:07 -04:00
|
|
|
|
|
|
|
|
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
|
2020-04-23 11:50:43 +08:00
|
|
|
index e0a6f98..71fd6f9 100644
|
2019-09-30 11:03:07 -04:00
|
|
|
--- a/src/lxc/conf.c
|
|
|
|
|
+++ b/src/lxc/conf.c
|
2020-04-23 11:50:43 +08:00
|
|
|
@@ -33,6 +33,11 @@
|
2019-09-30 11:03:07 -04:00
|
|
|
#include <time.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
2020-04-23 11:50:43 +08:00
|
|
|
+#ifdef HAVE_ISULAD
|
|
|
|
|
+#include <pthread.h>
|
|
|
|
|
+#include "sync.h"
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
2019-09-30 11:03:07 -04:00
|
|
|
#include "af_unix.h"
|
|
|
|
|
#include "caps.h"
|
2020-04-23 11:50:43 +08:00
|
|
|
#include "cgroup.h"
|
|
|
|
|
@@ -121,7 +126,14 @@ char *lxchook_names[NUM_LXC_HOOKS] = {
|
2019-09-30 11:03:07 -04:00
|
|
|
"post-stop",
|
|
|
|
|
"clone",
|
|
|
|
|
"destroy",
|
2020-04-23 11:50:43 +08:00
|
|
|
+#ifdef HAVE_ISULAD
|
2019-09-30 11:03:07 -04:00
|
|
|
+ "start-host",
|
|
|
|
|
+ "oci-prestart",
|
|
|
|
|
+ "oci-poststart",
|
|
|
|
|
+ "oci-poststop"
|
2020-04-23 11:50:43 +08:00
|
|
|
+#else
|
|
|
|
|
"start-host"
|
|
|
|
|
+#endif
|
2019-09-30 11:03:07 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct mount_opt {
|
2020-04-23 11:50:43 +08:00
|
|
|
@@ -3947,6 +3959,530 @@ static int setup_rootfs_mountopts(const struct lxc_rootfs *rootfs)
|
|
|
|
|
}
|
2019-09-30 11:03:07 -04:00
|
|
|
return 0;
|
|
|
|
|
}
|
2020-04-23 11:50:43 +08:00
|
|
|
+
|
2019-09-30 11:03:07 -04:00
|
|
|
+struct oci_hook_conf {
|
|
|
|
|
+ defs_hook *ocihook;
|
|
|
|
|
+
|
|
|
|
|
+ int errfd;
|
|
|
|
|
+ int which;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+struct wait_conf {
|
|
|
|
|
+ pid_t pid;
|
|
|
|
|
+ unsigned long long startat;
|
|
|
|
|
+ int timeout;
|
|
|
|
|
+ int errfd;
|
|
|
|
|
+ int which;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+static char* generate_json_str(const char *name, const char *lxcpath, const char *rootfs)
|
|
|
|
|
+{
|
|
|
|
|
+ char *cpid = NULL;
|
|
|
|
|
+ char *inmsg = NULL;
|
|
|
|
|
+ int rc = 0, ret = 0;
|
|
|
|
|
+ size_t size;
|
|
|
|
|
+
|
|
|
|
|
+ if (!name || !lxcpath || !rootfs) {
|
|
|
|
|
+ ERROR("Invalid arguments");
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+ cpid = getenv("LXC_PID");
|
|
|
|
|
+ if (!cpid) {
|
|
|
|
|
+ ERROR("Get container %s pid failed: %s", name, strerror(errno));
|
|
|
|
|
+ cpid = "-1";
|
|
|
|
|
+ }
|
2020-04-23 11:50:43 +08:00
|
|
|
+
|
|
|
|
|
+ if ((strlen(name) + strlen(cpid) + strlen(rootfs) + strlen(lxcpath) + strlen(name)) >
|
|
|
|
|
+ SIZE_MAX - (strlen("{\"ociVersion\":\"\",\"id\":\"\",\"pid\":,\"root\":\"\",\"bundle\":\"\"}") - 1 - 1)) {
|
|
|
|
|
+ ERROR("Out of memory");
|
|
|
|
|
+ ret = -1;
|
|
|
|
|
+ goto out_free;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // {"ociVersion":"","id":"xxx","pid":777,"root":"xxx","bundle":"xxx"}
|
|
|
|
|
+ size = strlen("{\"ociVersion\":\"\",\"id\":\"\",\"pid\":,\"root\":\"\",\"bundle\":\"\"}") +
|
|
|
|
|
+ strlen(name) + strlen(cpid) + strlen(rootfs) + strlen(lxcpath) + 1 + strlen(name) + 1;
|
2019-09-30 11:03:07 -04:00
|
|
|
+ inmsg = malloc(size);
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (inmsg == NULL) {
|
2019-09-30 11:03:07 -04:00
|
|
|
+ ERROR("Out of memory");
|
|
|
|
|
+ ret = -1;
|
|
|
|
|
+ goto out_free;
|
|
|
|
|
+ }
|
|
|
|
|
+ rc = snprintf(inmsg, size,
|
2020-04-23 11:50:43 +08:00
|
|
|
+ "{\"ociVersion\":\"\",\"id\":\"%s\",\"pid\":%s,\"root\":\"%s\",\"bundle\":\"%s/%s\"}",
|
|
|
|
|
+ name, cpid, rootfs, lxcpath, name);
|
2019-09-30 11:03:07 -04:00
|
|
|
+ if (rc < 0 || rc >= size) {
|
|
|
|
|
+ ERROR("Create json string failed");
|
|
|
|
|
+ ret = -1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+out_free:
|
|
|
|
|
+ if (ret) {
|
|
|
|
|
+ free(inmsg);
|
|
|
|
|
+ inmsg = NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+ return inmsg;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static char **merge_ocihook_env(char **oldenvs, size_t env_len, size_t *merge_env_len)
|
|
|
|
|
+{
|
2020-04-23 11:50:43 +08:00
|
|
|
+ char **result = NULL;
|
2019-09-30 11:03:07 -04:00
|
|
|
+ size_t result_len = env_len;
|
|
|
|
|
+ size_t i, j;
|
2020-04-23 11:50:43 +08:00
|
|
|
+ char *tmpenv = NULL;
|
|
|
|
|
+ char *lxc_envs[] = {"LD_LIBRARY_PATH", "PATH", "LXC_CGNS_AWARE", "LXC_PID", "LXC_ROOTFS_MOUNT",
|
|
|
|
|
+ "LXC_CONFIG_FILE", "LXC_CGROUP_PATH", "LXC_ROOTFS_PATH", "LXC_NAME"
|
|
|
|
|
+ };
|
|
|
|
|
+ char *lxcenv_buf = NULL;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (result_len > SIZE_MAX - (sizeof(lxc_envs) / sizeof(char *)) - 1)
|
|
|
|
|
+ return NULL;
|
2019-09-30 11:03:07 -04:00
|
|
|
+ result_len += (sizeof(lxc_envs) / sizeof(char *)) + 1;
|
|
|
|
|
+ result = malloc(sizeof(char *) * result_len);
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (result == NULL)
|
2019-09-30 11:03:07 -04:00
|
|
|
+ return NULL;
|
|
|
|
|
+ memset(result, 0, sizeof(char *) * result_len);
|
|
|
|
|
+
|
|
|
|
|
+ for(i = 0; i < env_len; i++) {
|
|
|
|
|
+ if (oldenvs[i])
|
2020-04-23 11:50:43 +08:00
|
|
|
+ result[i] = safe_strdup(oldenvs[i]);
|
2019-09-30 11:03:07 -04:00
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ for(j = 0; j < (sizeof(lxc_envs) / sizeof(char *)); j++) {
|
2020-04-23 11:50:43 +08:00
|
|
|
+ size_t env_buf_len = 0;
|
2019-09-30 11:03:07 -04:00
|
|
|
+ tmpenv = getenv(lxc_envs[j]);
|
|
|
|
|
+ if (tmpenv && i < (result_len - 1)) {
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (strlen(tmpenv) > (SIZE_MAX - 1 - 1 - strlen(lxc_envs[j]))) {
|
|
|
|
|
+ lxc_free_array((void **)result, free);
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+ env_buf_len = ((strlen(tmpenv) + 1) + strlen(lxc_envs[j])) + 1;
|
|
|
|
|
+ lxcenv_buf = malloc(env_buf_len);
|
|
|
|
|
+ if (lxcenv_buf == NULL) {
|
2019-09-30 11:03:07 -04:00
|
|
|
+ lxc_free_array((void **)result, free);
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ }
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (snprintf(lxcenv_buf, env_buf_len, "%s=%s", lxc_envs[j], tmpenv) < 0) {
|
2019-09-30 11:03:07 -04:00
|
|
|
+ free(lxcenv_buf);
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ result[i++] = lxcenv_buf;
|
|
|
|
|
+ lxcenv_buf = NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ *merge_env_len = i;
|
|
|
|
|
+ return result;
|
|
|
|
|
+}
|
|
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+static struct lxc_popen_FILE *lxc_popen_ocihook(const char *commandpath, char **args, int args_len,
|
|
|
|
|
+ char **envs, int env_len, const char *instr)
|
2019-09-30 11:03:07 -04:00
|
|
|
+{
|
|
|
|
|
+ int ret;
|
|
|
|
|
+ struct lxc_popen_FILE *fp = NULL;
|
|
|
|
|
+ int pipe_fds[2] = {-1, -1};
|
|
|
|
|
+ int pipe_msg[2] = {-1, -1};
|
|
|
|
|
+ pid_t child_pid;
|
|
|
|
|
+
|
|
|
|
|
+ ret = pipe2(pipe_fds, O_CLOEXEC | O_NONBLOCK);
|
|
|
|
|
+ if (ret < 0)
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+
|
|
|
|
|
+ ret = pipe2(pipe_msg, O_CLOEXEC | O_NONBLOCK);
|
|
|
|
|
+ if (ret < 0) {
|
|
|
|
|
+ ERROR("Pipe msg failure");
|
|
|
|
|
+ close(pipe_fds[0]);
|
|
|
|
|
+ close(pipe_fds[1]);
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ child_pid = fork();
|
|
|
|
|
+ if (child_pid < 0)
|
|
|
|
|
+ goto on_error;
|
|
|
|
|
+
|
|
|
|
|
+ if (child_pid == 0) {
|
|
|
|
|
+ close(pipe_msg[1]);
|
|
|
|
|
+ if (pipe_msg[0] != STDIN_FILENO)
|
|
|
|
|
+ dup2(pipe_msg[0], STDIN_FILENO);
|
|
|
|
|
+ else {
|
|
|
|
|
+ if (fcntl(pipe_msg[0], F_SETFD, 0) != 0) {
|
2020-04-23 11:50:43 +08:00
|
|
|
+ fprintf(stderr, "Failed to remove FD_CLOEXEC from fd.");
|
2019-09-30 11:03:07 -04:00
|
|
|
+ exit(127);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ close(pipe_msg[0]);
|
|
|
|
|
+
|
|
|
|
|
+ close(pipe_fds[0]);
|
|
|
|
|
+
|
|
|
|
|
+ /* duplicate stdout */
|
|
|
|
|
+ if (pipe_fds[1] != STDOUT_FILENO)
|
|
|
|
|
+ ret = dup2(pipe_fds[1], STDOUT_FILENO);
|
|
|
|
|
+ else
|
|
|
|
|
+ ret = fcntl(pipe_fds[1], F_SETFD, 0);
|
|
|
|
|
+ if (ret < 0) {
|
|
|
|
|
+ close(pipe_fds[1]);
|
|
|
|
|
+ _exit(EXIT_FAILURE);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* duplicate stderr */
|
|
|
|
|
+ if (pipe_fds[1] != STDERR_FILENO)
|
|
|
|
|
+ ret = dup2(pipe_fds[1], STDERR_FILENO);
|
|
|
|
|
+ else
|
|
|
|
|
+ ret = fcntl(pipe_fds[1], F_SETFD, 0);
|
|
|
|
|
+ close(pipe_fds[1]);
|
|
|
|
|
+ if (ret < 0)
|
|
|
|
|
+ _exit(EXIT_FAILURE);
|
|
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (lxc_check_inherited(NULL, true, NULL, 0) != 0) {
|
|
|
|
|
+ fprintf(stderr, "check inherited fd failed");
|
|
|
|
|
+ exit(127);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
2019-09-30 11:03:07 -04:00
|
|
|
+ /*
|
|
|
|
|
+ * Unblock signals.
|
|
|
|
|
+ * This is the main/only reason
|
|
|
|
|
+ * why we do our lousy popen() emulation.
|
|
|
|
|
+ */
|
|
|
|
|
+ {
|
|
|
|
|
+ sigset_t mask;
|
|
|
|
|
+ sigfillset(&mask);
|
|
|
|
|
+ sigprocmask(SIG_UNBLOCK, &mask, NULL);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (env_len > 0)
|
2020-04-23 11:50:43 +08:00
|
|
|
+ execvpe(commandpath, args, envs);
|
2019-09-30 11:03:07 -04:00
|
|
|
+ else
|
2020-04-23 11:50:43 +08:00
|
|
|
+ execvp(commandpath, args);
|
|
|
|
|
+ fprintf(stderr, "fork/exec %s: %s", commandpath, strerror(errno));
|
2019-09-30 11:03:07 -04:00
|
|
|
+ exit(127);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* parent */
|
|
|
|
|
+
|
|
|
|
|
+ close(pipe_fds[1]);
|
|
|
|
|
+ pipe_fds[1] = -1;
|
|
|
|
|
+
|
|
|
|
|
+ close(pipe_msg[0]);
|
|
|
|
|
+ pipe_msg[0]= -1;
|
|
|
|
|
+ if (instr) {
|
|
|
|
|
+ size_t len = strlen(instr);
|
|
|
|
|
+ if (lxc_write_nointr(pipe_msg[1], instr, len) != len) {
|
|
|
|
|
+ WARN("Write instr: %s failed", instr);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ close(pipe_msg[1]);
|
|
|
|
|
+ pipe_msg[1]= -1;
|
|
|
|
|
+
|
|
|
|
|
+ fp = calloc(1, sizeof(*fp));
|
|
|
|
|
+ if (!fp) {
|
|
|
|
|
+ ERROR("Failed to allocate memory");
|
|
|
|
|
+ goto on_error;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ fp->child_pid = child_pid;
|
|
|
|
|
+ fp->pipe = pipe_fds[0];
|
|
|
|
|
+
|
|
|
|
|
+ return fp;
|
|
|
|
|
+
|
|
|
|
|
+on_error:
|
|
|
|
|
+
|
|
|
|
|
+ if (pipe_fds[0] >= 0)
|
|
|
|
|
+ close(pipe_fds[0]);
|
|
|
|
|
+
|
|
|
|
|
+ if (pipe_fds[1] >= 0)
|
|
|
|
|
+ close(pipe_fds[1]);
|
|
|
|
|
+
|
|
|
|
|
+ if (pipe_msg[0] >= 0)
|
|
|
|
|
+ close(pipe_msg[0]);
|
|
|
|
|
+
|
|
|
|
|
+ if (pipe_msg[1] >= 0)
|
|
|
|
|
+ close(pipe_msg[1]);
|
|
|
|
|
+
|
|
|
|
|
+ if (fp)
|
|
|
|
|
+ free(fp);
|
|
|
|
|
+
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void* wait_ocihook_timeout(void *arg)
|
|
|
|
|
+{
|
|
|
|
|
+ bool alive = false;
|
|
|
|
|
+ struct wait_conf *conf = (struct wait_conf *)arg;
|
|
|
|
|
+
|
|
|
|
|
+ if (!conf || conf->timeout < 1)
|
|
|
|
|
+ goto out;
|
|
|
|
|
+
|
|
|
|
|
+ sleep(conf->timeout);
|
|
|
|
|
+
|
|
|
|
|
+ alive = lxc_process_alive(conf->pid, conf->startat);
|
|
|
|
|
+
|
|
|
|
|
+ if (alive) {
|
|
|
|
|
+ ERROR("%s:%d: running %s hook caused \"hook ran past specified timeout of %.1fs\"",
|
2020-04-23 11:50:43 +08:00
|
|
|
+ __FILE__, __LINE__, lxchook_names[conf->which],
|
|
|
|
|
+ (double)conf->timeout);
|
|
|
|
|
+
|
|
|
|
|
+ lxc_write_error_message(conf->errfd, "%s:%d: running %s hook caused \"hook ran past specified timeout of %.1fs\".",
|
|
|
|
|
+ __FILE__, __LINE__, lxchook_names[conf->which],
|
|
|
|
|
+ (double)conf->timeout);
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
|
|
|
|
+ if (kill(conf->pid, SIGKILL) && errno != ESRCH) {
|
|
|
|
|
+ ERROR("Send kill signal failed");
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+out:
|
|
|
|
|
+ free(conf);
|
|
|
|
|
+ return ((void *)0);
|
|
|
|
|
+}
|
|
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+static int run_ocihook_buffer(struct oci_hook_conf *oconf, const char *inmsg)
|
2019-09-30 11:03:07 -04:00
|
|
|
+{
|
|
|
|
|
+ struct lxc_popen_FILE *f;
|
|
|
|
|
+ char output[LXC_LOG_BUFFER_SIZE] = {0};
|
|
|
|
|
+ int ret;
|
|
|
|
|
+ pthread_t ptid;
|
|
|
|
|
+ int err;
|
|
|
|
|
+ struct wait_conf *conf = NULL;
|
|
|
|
|
+ pthread_attr_t attr;
|
|
|
|
|
+ char *buffer = oconf->ocihook->path;
|
|
|
|
|
+ char *err_args_msg = NULL;
|
|
|
|
|
+ char *err_envs_msg = NULL;
|
|
|
|
|
+ char **hookenvs = NULL;
|
|
|
|
|
+ size_t hookenvs_len = 0;
|
|
|
|
|
+
|
|
|
|
|
+ hookenvs = merge_ocihook_env(oconf->ocihook->env, oconf->ocihook->env_len, &hookenvs_len);
|
|
|
|
|
+ if (!hookenvs) {
|
|
|
|
|
+ ERROR("Out of memory.");
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ f = lxc_popen_ocihook(buffer, oconf->ocihook->args, oconf->ocihook->args_len, hookenvs, hookenvs_len, inmsg);
|
|
|
|
|
+ lxc_free_array((void **)hookenvs, free);
|
|
|
|
|
+ if (!f) {
|
|
|
|
|
+ SYSERROR("Failed to popen() %s.", buffer);
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ conf = malloc(sizeof(struct wait_conf));
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (conf == NULL) {
|
2019-09-30 11:03:07 -04:00
|
|
|
+ SYSERROR("Failed to malloc.");
|
|
|
|
|
+ goto on_error;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ memset(conf, 0x00, sizeof(struct wait_conf));
|
|
|
|
|
+
|
|
|
|
|
+ conf->pid = f->child_pid;
|
|
|
|
|
+ conf->startat = lxc_get_process_startat(conf->pid);
|
|
|
|
|
+
|
|
|
|
|
+ INFO("hook_conf timeout %d", oconf->ocihook->timeout);
|
|
|
|
|
+ if(oconf->ocihook->timeout > 0)
|
|
|
|
|
+ conf->timeout = oconf->ocihook->timeout;
|
|
|
|
|
+ else {
|
|
|
|
|
+ conf->timeout = 30;
|
|
|
|
|
+ INFO("Set hook timeout 30s");
|
|
|
|
|
+ }
|
|
|
|
|
+ conf->errfd = oconf->errfd;
|
|
|
|
|
+ conf->which = oconf->which;
|
|
|
|
|
+
|
|
|
|
|
+ pthread_attr_init(&attr);
|
|
|
|
|
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
|
|
|
+ err = pthread_create(&ptid, &attr, wait_ocihook_timeout, conf);
|
|
|
|
|
+ if (err != 0) {
|
|
|
|
|
+ ERROR("Create wait timeout thread failed");
|
2020-04-23 11:50:43 +08:00
|
|
|
+ free(conf);
|
2019-09-30 11:03:07 -04:00
|
|
|
+ goto on_error;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ret = lxc_wait_for_pid_status(f->child_pid);
|
|
|
|
|
+
|
|
|
|
|
+ lxc_read_nointr(f->pipe, output, sizeof(output) - 1);
|
|
|
|
|
+ close(f->pipe);
|
|
|
|
|
+ free(f);
|
|
|
|
|
+
|
|
|
|
|
+ if (ret == -1) {
|
|
|
|
|
+ SYSERROR("Script exited with error.");
|
|
|
|
|
+ goto print_hook;
|
|
|
|
|
+ } else if (WIFEXITED(ret) && WEXITSTATUS(ret) != 0) {
|
2020-04-23 11:50:43 +08:00
|
|
|
+ ERROR("Script exited with status %d. output: %s", WEXITSTATUS(ret), output);
|
|
|
|
|
+ lxc_write_error_message(oconf->errfd, "%s:%d: running %s hook caused \"error running hook: exit status %d, output: %s\".",
|
|
|
|
|
+ __FILE__, __LINE__,
|
|
|
|
|
+ (oconf->which >= NUM_LXC_HOOKS) ? "invalid type" : lxchook_names[oconf->which],
|
|
|
|
|
+ WEXITSTATUS(ret), output);
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
|
|
|
|
+ goto print_hook;
|
|
|
|
|
+ } else if (WIFSIGNALED(ret)) {
|
|
|
|
|
+ ERROR("Script terminated by signal %d.", WTERMSIG(ret));
|
2020-04-23 11:50:43 +08:00
|
|
|
+ lxc_write_error_message(oconf->errfd, "%s:%d: running %s hook caused \"error running hook: Script terminated by signal %d\".",
|
|
|
|
|
+ __FILE__, __LINE__,
|
|
|
|
|
+ (oconf->which >= NUM_LXC_HOOKS) ? "invalid type" : lxchook_names[oconf->which],
|
|
|
|
|
+ WTERMSIG(ret));
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
|
|
|
|
+ goto print_hook;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return 0;
|
|
|
|
|
+
|
|
|
|
|
+on_error:
|
|
|
|
|
+ if (f) {
|
|
|
|
|
+ if (f->pipe >= 0)
|
|
|
|
|
+ close(f->pipe);
|
|
|
|
|
+ free(f);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+print_hook:
|
|
|
|
|
+ if (oconf->ocihook->args)
|
|
|
|
|
+ err_args_msg = lxc_string_join(" ", (const char **)oconf->ocihook->args, false);
|
|
|
|
|
+ if (oconf->ocihook->env)
|
|
|
|
|
+ err_envs_msg = lxc_string_join(" ", (const char **)oconf->ocihook->env, false);
|
|
|
|
|
+ ERROR("Hook script command: \"%s\", args: \"%s\", envs: \"%s\", timeout: %d.",
|
2020-04-23 11:50:43 +08:00
|
|
|
+ buffer, err_args_msg ? err_args_msg : "",
|
|
|
|
|
+ err_envs_msg ? err_envs_msg : "", oconf->ocihook->timeout);
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
|
|
|
|
+ free(err_args_msg);
|
|
|
|
|
+ free(err_envs_msg);
|
|
|
|
|
+ return -1;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static int run_ocihook_script_argv(const char *name, const char *section,
|
2020-04-23 11:50:43 +08:00
|
|
|
+ struct oci_hook_conf *oconf,
|
|
|
|
|
+ const char *lxcpath, const char *rootfs)
|
2019-09-30 11:03:07 -04:00
|
|
|
+{
|
|
|
|
|
+ int ret;
|
|
|
|
|
+ const char *script = oconf->ocihook->path;
|
2020-04-23 11:50:43 +08:00
|
|
|
+ char *inmsg = NULL;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
|
|
|
|
+ INFO("Executing script \"%s\" for container \"%s\", config section \"%s\".",
|
|
|
|
|
+ script, name, section);
|
|
|
|
|
+
|
|
|
|
|
+ inmsg = generate_json_str(name, lxcpath, rootfs);
|
|
|
|
|
+ if (!inmsg) {
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ret = run_ocihook_buffer(oconf, inmsg);
|
|
|
|
|
+ free(inmsg);
|
|
|
|
|
+ inmsg = NULL;
|
|
|
|
|
+ return ret;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static char *get_root_path(const char *path, const char *backend)
|
|
|
|
|
+{
|
|
|
|
|
+ char *ret = NULL;
|
|
|
|
|
+ char *tmp = NULL;
|
|
|
|
|
+
|
|
|
|
|
+ if (!path) {
|
2020-04-23 11:50:43 +08:00
|
|
|
+ ret = safe_strdup("/");
|
2019-09-30 11:03:07 -04:00
|
|
|
+ return ret;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!backend) {
|
|
|
|
|
+ goto default_out;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (strcmp(backend, "aufs") == 0 ||
|
2020-04-23 11:50:43 +08:00
|
|
|
+ strcmp(backend, "overlayfs") == 0 ||
|
|
|
|
|
+ strcmp(backend, "loop") == 0) {
|
2019-09-30 11:03:07 -04:00
|
|
|
+ tmp = strrchr(path, ':');
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (tmp == NULL) {
|
|
|
|
|
+ ERROR("Invalid root path format");
|
2019-09-30 11:03:07 -04:00
|
|
|
+ return NULL;
|
|
|
|
|
+ }
|
2020-04-23 11:50:43 +08:00
|
|
|
+ tmp++;
|
|
|
|
|
+ ret = safe_strdup(tmp);
|
2019-09-30 11:03:07 -04:00
|
|
|
+ return ret;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+default_out:
|
2020-04-23 11:50:43 +08:00
|
|
|
+ ret = safe_strdup(path);
|
2019-09-30 11:03:07 -04:00
|
|
|
+ return ret;
|
|
|
|
|
+}
|
|
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+static int do_run_oci_hooks(const char *name, const char *lxcpath, struct lxc_conf *lc, int which, int errfd)
|
2019-09-30 11:03:07 -04:00
|
|
|
+{
|
|
|
|
|
+ struct oci_hook_conf work_conf = {0};
|
|
|
|
|
+ size_t i;
|
|
|
|
|
+ int ret = 0;
|
2020-04-23 11:50:43 +08:00
|
|
|
+ int nret = 0;
|
|
|
|
|
+ char *rootpath = NULL;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (!lc) {
|
2019-09-30 11:03:07 -04:00
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (!lc->ocihooks) {
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
|
|
|
|
+ rootpath = get_root_path(lc->rootfs.path, lc->rootfs.bdev_type);
|
|
|
|
|
+ if (!rootpath) {
|
|
|
|
|
+ ERROR("Get container %s rootpath failed.", name);
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ work_conf.errfd = errfd;
|
|
|
|
|
+ work_conf.which = which;
|
|
|
|
|
+ switch (which) {
|
2020-04-23 11:50:43 +08:00
|
|
|
+ case OCI_HOOK_PRESTART:
|
|
|
|
|
+ for (i = 0; i < lc->ocihooks->prestart_len; i++) {
|
|
|
|
|
+ work_conf.ocihook = lc->ocihooks->prestart[i];
|
|
|
|
|
+ ret = run_ocihook_script_argv(name, "lxc", &work_conf, lxcpath, rootpath);
|
|
|
|
|
+ if (ret != 0)
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case OCI_HOOK_POSTSTART:
|
|
|
|
|
+ for (i = 0; i < lc->ocihooks->poststart_len; i++) {
|
|
|
|
|
+ work_conf.ocihook = lc->ocihooks->poststart[i];
|
|
|
|
|
+ nret = run_ocihook_script_argv(name, "lxc", &work_conf, lxcpath, rootpath);
|
|
|
|
|
+ if (nret != 0)
|
|
|
|
|
+ WARN("running poststart hook %zu failed, ContainerId: %s", i, name);
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case OCI_HOOK_POSTSTOP:
|
|
|
|
|
+ for (i = 0; i < lc->ocihooks->poststop_len; i++) {
|
|
|
|
|
+ work_conf.ocihook = lc->ocihooks->poststop[i];
|
|
|
|
|
+ nret = run_ocihook_script_argv(name, "lxc", &work_conf, lxcpath, rootpath);
|
|
|
|
|
+ if (nret != 0)
|
|
|
|
|
+ WARN("running poststart hook %zu failed, ContainerId: %s", i, name);
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ default:
|
|
|
|
|
+ ret = -1;
|
2019-09-30 11:03:07 -04:00
|
|
|
+ }
|
|
|
|
|
+ if (rootpath)
|
|
|
|
|
+ free(rootpath);
|
|
|
|
|
+ return ret;
|
|
|
|
|
+}
|
|
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+int run_oci_hooks(const char *name, const char *hookname, struct lxc_conf *conf, const char *lxcpath)
|
|
|
|
|
+{
|
|
|
|
|
+ int which = -1;
|
|
|
|
|
+
|
2019-09-30 11:03:07 -04:00
|
|
|
+ if (strcmp(hookname, "oci-prestart") == 0) {
|
|
|
|
|
+ which = OCI_HOOK_PRESTART;
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (!lxcpath) {
|
2019-09-30 11:03:07 -04:00
|
|
|
+ ERROR("oci hook require lxcpath");
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
2020-04-23 11:50:43 +08:00
|
|
|
+ return do_run_oci_hooks(name, lxcpath, conf, which, conf->errpipe[1]);
|
2019-09-30 11:03:07 -04:00
|
|
|
+ } else if (strcmp(hookname, "oci-poststart") == 0) {
|
|
|
|
|
+ which = OCI_HOOK_POSTSTART;
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (!lxcpath) {
|
2019-09-30 11:03:07 -04:00
|
|
|
+ ERROR("oci hook require lxcpath");
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
2020-04-23 11:50:43 +08:00
|
|
|
+ return do_run_oci_hooks(name, lxcpath, conf, which, conf->errpipe[1]);
|
2019-09-30 11:03:07 -04:00
|
|
|
+ } else if (strcmp(hookname, "oci-poststop") == 0) {
|
|
|
|
|
+ which = OCI_HOOK_POSTSTOP;
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (!lxcpath) {
|
2019-09-30 11:03:07 -04:00
|
|
|
+ ERROR("oci hook require lxcpath");
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
2020-04-23 11:50:43 +08:00
|
|
|
+ return do_run_oci_hooks(name, lxcpath, conf, which, conf->errpipe[1]);
|
|
|
|
|
+ } else
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
int lxc_setup(struct lxc_handler *handler)
|
|
|
|
|
@@ -4083,6 +4619,12 @@ int lxc_setup(struct lxc_handler *handler)
|
|
|
|
|
if (ret < 0)
|
|
|
|
|
return log_error(-1, "Failed to \"/proc\" LSMs");
|
2019-09-30 11:03:07 -04:00
|
|
|
|
2020-04-23 11:50:43 +08:00
|
|
|
+#ifdef HAVE_ISULAD
|
|
|
|
|
+ /* Ask father to run oci prestart hooks and wait for him to finish. */
|
|
|
|
|
+ if (lxc_sync_barrier_parent(handler, LXC_SYNC_OCI_PRESTART_HOOK)) {
|
|
|
|
|
+ return log_error(-1, "Failed to sync parent to start host hook");
|
|
|
|
|
+ }
|
|
|
|
|
+#endif
|
|
|
|
|
ret = lxc_setup_rootfs_switch_root(&lxc_conf->rootfs);
|
|
|
|
|
if (ret < 0)
|
|
|
|
|
return log_error(-1, "Failed to pivot root into rootfs");
|
2019-09-30 11:03:07 -04:00
|
|
|
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
|
2020-04-23 11:50:43 +08:00
|
|
|
index 22c554d..61c3383 100644
|
2019-09-30 11:03:07 -04:00
|
|
|
--- a/src/lxc/conf.h
|
|
|
|
|
+++ b/src/lxc/conf.h
|
2020-04-23 11:50:43 +08:00
|
|
|
@@ -23,6 +23,10 @@
|
|
|
|
|
#include "start.h"
|
|
|
|
|
#include "terminal.h"
|
2019-09-30 11:03:07 -04:00
|
|
|
|
2020-04-23 11:50:43 +08:00
|
|
|
+#ifdef HAVE_ISULAD
|
2019-09-30 11:03:07 -04:00
|
|
|
+#include "oci_runtime_hooks.h"
|
2020-04-23 11:50:43 +08:00
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
#if HAVE_SYS_RESOURCE_H
|
|
|
|
|
#include <sys/resource.h>
|
|
|
|
|
#endif
|
|
|
|
|
@@ -212,6 +216,11 @@ enum lxchooks {
|
2019-09-30 11:03:07 -04:00
|
|
|
LXCHOOK_CLONE,
|
|
|
|
|
LXCHOOK_DESTROY,
|
|
|
|
|
LXCHOOK_START_HOST,
|
2020-04-23 11:50:43 +08:00
|
|
|
+#ifdef HAVE_ISULAD
|
2019-09-30 11:03:07 -04:00
|
|
|
+ OCI_HOOK_PRESTART,
|
|
|
|
|
+ OCI_HOOK_POSTSTART,
|
|
|
|
|
+ OCI_HOOK_POSTSTOP,
|
2020-04-23 11:50:43 +08:00
|
|
|
+#endif
|
2019-09-30 11:03:07 -04:00
|
|
|
NUM_LXC_HOOKS
|
|
|
|
|
};
|
|
|
|
|
|
2020-04-23 11:50:43 +08:00
|
|
|
@@ -433,6 +442,11 @@ struct lxc_conf {
|
|
|
|
|
} shmount;
|
2019-09-30 11:03:07 -04:00
|
|
|
|
2020-04-23 11:50:43 +08:00
|
|
|
#ifdef HAVE_ISULAD
|
2019-09-30 11:03:07 -04:00
|
|
|
+ /*
|
|
|
|
|
+ * isulad: support oci hook
|
|
|
|
|
+ * */
|
|
|
|
|
+ oci_runtime_spec_hooks *ocihooks;
|
|
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
/* isulad add: init args used to repalce init_cmd*/
|
|
|
|
|
char **init_argv;
|
|
|
|
|
size_t init_argc;
|
|
|
|
|
@@ -447,6 +461,8 @@ struct lxc_conf {
|
|
|
|
|
|
|
|
|
|
char *errmsg; /* record error messages */
|
|
|
|
|
|
|
|
|
|
+ int errpipe[2];//pipdfd for get error message of child or grandchild process.
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
char *systemd; //systemd value
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
@@ -535,5 +551,6 @@ int lxc_clear_init_args(struct lxc_conf *lxc_conf);
|
|
|
|
|
int lxc_clear_populate_devices(struct lxc_conf *c);
|
|
|
|
|
int lxc_clear_rootfs_masked_paths(struct lxc_conf *c);
|
|
|
|
|
int lxc_clear_rootfs_ro_paths(struct lxc_conf *c);
|
|
|
|
|
+int run_oci_hooks(const char *name, const char *hookname, struct lxc_conf *conf, const char *lxcpath);
|
|
|
|
|
#endif
|
|
|
|
|
#endif /* __LXC_CONF_H */
|
|
|
|
|
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
|
|
|
|
|
index 821cfa1..9b3ab75 100644
|
|
|
|
|
--- a/src/lxc/lxccontainer.c
|
|
|
|
|
+++ b/src/lxc/lxccontainer.c
|
|
|
|
|
@@ -288,6 +288,8 @@ static void lxc_container_free(struct lxc_container *c)
|
|
|
|
|
#ifdef HAVE_ISULAD
|
|
|
|
|
free(c->exit_fifo);
|
|
|
|
|
c->exit_fifo = NULL;
|
|
|
|
|
+ free(c->ocihookfile);
|
|
|
|
|
+ c->ocihookfile = NULL;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
free(c);
|
|
|
|
|
@@ -632,6 +634,66 @@ static bool load_config_locked(struct lxc_container *c, const char *fname)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+#ifdef HAVE_ISULAD
|
|
|
|
|
+static bool load_ocihooks_locked(struct lxc_container *c)
|
|
|
|
|
+{
|
|
|
|
|
+ parser_error err = NULL;
|
|
|
|
|
+ oci_runtime_spec_hooks *hooks = NULL;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (!c->lxc_conf)
|
|
|
|
|
+ c->lxc_conf = lxc_conf_init();
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (!c->lxc_conf)
|
|
|
|
|
+ return false;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ hooks = oci_runtime_spec_hooks_parse_file(c->ocihookfile, NULL, &err);
|
|
|
|
|
+ if (!hooks) {
|
|
|
|
|
+ fprintf(stderr, "parse oci hooks config failed: %s\n", err);
|
|
|
|
|
+ free(err);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ c->lxc_conf->ocihooks = hooks;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (err)
|
|
|
|
|
+ free(err);
|
|
|
|
|
+ return true;
|
2019-09-30 11:03:07 -04:00
|
|
|
+}
|
|
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+/*
|
|
|
|
|
+ * isulad: set oci hook file path
|
|
|
|
|
+ * */
|
|
|
|
|
+static bool set_oci_hook_config_filename(struct lxc_container *c)
|
|
|
|
|
+{
|
|
|
|
|
+#define OCI_HOOK_JSON_FILE_NAME "ocihooks.json"
|
|
|
|
|
+ char *newpath = NULL;
|
|
|
|
|
+ int len, ret;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (!c->config_path)
|
|
|
|
|
+ return false;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ /* $lxc_path + "/" + c->name + "/" + "config" + '\0' */
|
|
|
|
|
+ if (strlen(c->config_path) + strlen(c->name) > SIZE_MAX - strlen(OCI_HOOK_JSON_FILE_NAME) - 3)
|
|
|
|
|
+ return false;
|
|
|
|
|
+ len = strlen(c->config_path) + strlen(c->name) + strlen(OCI_HOOK_JSON_FILE_NAME) + 3;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ newpath = malloc(len);
|
|
|
|
|
+ if (newpath == NULL)
|
|
|
|
|
+ return false;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ ret = snprintf(newpath, len, "%s/%s/%s", c->config_path, c->name, OCI_HOOK_JSON_FILE_NAME);
|
|
|
|
|
+ if (ret < 0 || ret >= len) {
|
|
|
|
|
+ fprintf(stderr, "Error printing out config file name\n");
|
|
|
|
|
+ free(newpath);
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ free(c->ocihookfile);
|
|
|
|
|
+ c->ocihookfile = newpath;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ return true;
|
2019-09-30 11:03:07 -04:00
|
|
|
+}
|
2020-04-23 11:50:43 +08:00
|
|
|
+#endif
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
static bool do_lxcapi_load_config(struct lxc_container *c, const char *alt_file)
|
|
|
|
|
{
|
|
|
|
|
int lret;
|
|
|
|
|
@@ -665,6 +727,11 @@ static bool do_lxcapi_load_config(struct lxc_container *c, const char *alt_file)
|
|
|
|
|
|
|
|
|
|
ret = load_config_locked(c, fname);
|
|
|
|
|
|
|
|
|
|
+#ifdef HAVE_ISULAD
|
|
|
|
|
+ if (ret && file_exists(c->ocihookfile))
|
|
|
|
|
+ ret = load_ocihooks_locked(c);
|
|
|
|
|
+#endif
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
if (need_disklock)
|
|
|
|
|
container_disk_unlock(c);
|
|
|
|
|
else
|
|
|
|
|
@@ -5492,6 +5559,40 @@ static bool do_lxcapi_set_exec_terminal_winch(struct lxc_container *c, const cha
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WRAP_API_3(bool, lxcapi_set_exec_terminal_winch, const char *, unsigned int, unsigned int)
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+/* isulad add clean resources */
|
|
|
|
|
+static bool do_lxcapi_clean_container_resource(struct lxc_container *c, pid_t pid)
|
|
|
|
|
+{
|
|
|
|
|
+ int ret;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (!c)
|
|
|
|
|
+ return false;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ ret = do_lxcapi_clean_resource(c->name, c->config_path, c->lxc_conf, pid);
|
|
|
|
|
+ if (ret)
|
|
|
|
|
+ ERROR("Failed to clean container %s resource", c->name);
|
|
|
|
|
+ return ret == 0;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+WRAP_API_1(bool, lxcapi_clean_container_resource, pid_t)
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+/* isulad get coantainer pids */
|
|
|
|
|
+static bool do_lxcapi_get_container_pids(struct lxc_container *c, pid_t **pids,size_t *pids_len)
|
|
|
|
|
+{
|
|
|
|
|
+ int ret;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (!c)
|
|
|
|
|
+ return false;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ ret = do_lxcapi_get_pids(c->name, c->config_path, c->lxc_conf, pids,pids_len);
|
|
|
|
|
+ if (ret)
|
|
|
|
|
+ ERROR("Failed to get container %s pids", c->name);
|
|
|
|
|
+ return ret == 0;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+WRAP_API_2(bool, lxcapi_get_container_pids, pid_t **,size_t *)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
struct lxc_container *lxc_container_new(const char *name, const char *configpath)
|
|
|
|
|
@@ -5547,6 +5648,13 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+#ifdef HAVE_ISULAD
|
|
|
|
|
+ if (!set_oci_hook_config_filename(c)) {
|
|
|
|
|
+ fprintf(stderr, "Error allocating oci hooks file pathname\n");
|
|
|
|
|
+ goto err;
|
|
|
|
|
+ }
|
|
|
|
|
+#endif
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
if (file_exists(c->configfile) && !lxcapi_load_config(c, NULL)) {
|
|
|
|
|
fprintf(stderr, "Failed to load config for %s\n", name);
|
|
|
|
|
goto err;
|
|
|
|
|
@@ -5643,6 +5751,8 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
|
|
|
|
|
c->set_exec_terminal_winch = lxcapi_set_exec_terminal_winch;
|
|
|
|
|
c->want_disable_pty = lxcapi_want_disable_pty;
|
|
|
|
|
c->want_open_stdin = lxcapi_want_open_stdin;
|
|
|
|
|
+ c->clean_container_resource = lxcapi_clean_container_resource;
|
|
|
|
|
+ c->get_container_pids = lxcapi_get_container_pids;
|
|
|
|
|
#endif
|
|
|
|
|
return c;
|
|
|
|
|
|
|
|
|
|
diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h
|
|
|
|
|
index de2ee46..f1621f9 100644
|
|
|
|
|
--- a/src/lxc/lxccontainer.h
|
|
|
|
|
+++ b/src/lxc/lxccontainer.h
|
|
|
|
|
@@ -118,6 +118,13 @@ struct lxc_container {
|
|
|
|
|
|
|
|
|
|
/*! Whether container wishes to keep stdin active */
|
|
|
|
|
bool open_stdin;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ /*!
|
|
|
|
|
+ * \private
|
|
|
|
|
+ * isulad: support oci hook from json file
|
|
|
|
|
+ * full path of json file
|
|
|
|
|
+ * */
|
|
|
|
|
+ char *ocihookfile;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
@@ -935,6 +942,27 @@ struct lxc_container {
|
|
|
|
|
* \return \c true on success, else \c false.
|
|
|
|
|
*/
|
|
|
|
|
bool (*want_open_stdin)(struct lxc_container *c, bool state);
|
|
|
|
|
+
|
|
|
|
|
+ /*! isulad add
|
|
|
|
|
+ * \brief An API call to clean resources of container
|
|
|
|
|
+ *
|
|
|
|
|
+ * \param c Container.
|
|
|
|
|
+ * \param pid Value of container process.
|
|
|
|
|
+ *
|
|
|
|
|
+ * \return \c true on success, else \c false.
|
|
|
|
|
+ */
|
|
|
|
|
+ bool (*clean_container_resource) (struct lxc_container *c, pid_t pid);
|
|
|
|
|
+
|
|
|
|
|
+ /*! isulad add
|
|
|
|
|
+ * \brief An API call to get container pids
|
|
|
|
|
+ *
|
|
|
|
|
+ * \param c Container.
|
|
|
|
|
+ * \param pids Value of container pids.
|
|
|
|
|
+ * \param pids_len Value of container pids len.
|
|
|
|
|
+ * \param pid Value of container pid.
|
|
|
|
|
+ * \return \c true on success, else \c false.
|
|
|
|
|
+ */
|
|
|
|
|
+ bool (*get_container_pids)(struct lxc_container *c,pid_t **pids,size_t *pids_len);
|
|
|
|
|
#endif
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
diff --git a/src/lxc/start.c b/src/lxc/start.c
|
|
|
|
|
index f6a96b4..4f45776 100644
|
|
|
|
|
--- a/src/lxc/start.c
|
|
|
|
|
+++ b/src/lxc/start.c
|
|
|
|
|
@@ -2239,6 +2239,20 @@ static int lxc_spawn(struct lxc_handler *handler)
|
|
|
|
|
ERROR("Failed to run lxc.hook.start-host");
|
|
|
|
|
goto out_delete_net;
|
|
|
|
|
}
|
|
|
|
|
+#ifdef HAVE_ISULAD
|
|
|
|
|
+ /* isulad: Run oci prestart hook at here */
|
|
|
|
|
+ ret = run_oci_hooks(name, "oci-prestart", conf, lxcpath);
|
|
|
|
|
+ if (ret < 0) {
|
|
|
|
|
+ ERROR("Failed to run oci prestart hooks");
|
|
|
|
|
+ goto out_delete_net;
|
|
|
|
|
+ }
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ /* Tell the child to continue its initialization. We'll get
|
|
|
|
|
+ * LXC_SYNC_POST_OCI_PRESTART_HOOK when it is ready for us to run oci prestart hooks.
|
|
|
|
|
+ */
|
|
|
|
|
+ if (lxc_sync_barrier_child(handler, LXC_SYNC_POST_OCI_PRESTART_HOOK))
|
|
|
|
|
+ goto out_delete_net;
|
|
|
|
|
+#endif
|
|
|
|
|
|
|
|
|
|
/* Tell the child to complete its initialization and wait for it to exec
|
|
|
|
|
* or return an error. (The child will never return
|
|
|
|
|
@@ -2282,6 +2296,15 @@ static int lxc_spawn(struct lxc_handler *handler)
|
|
|
|
|
if (ret < 0)
|
|
|
|
|
goto out_abort;
|
|
|
|
|
|
|
|
|
|
+#ifdef HAVE_ISULAD
|
|
|
|
|
+ /* isulad: Run oci prestart hook at here */
|
|
|
|
|
+ ret = run_oci_hooks(name, "oci-poststart", conf, lxcpath);
|
|
|
|
|
+ if (ret < 0) {
|
|
|
|
|
+ ERROR("Failed to run oci poststart hooks");
|
|
|
|
|
+ goto out_abort;
|
|
|
|
|
+ }
|
|
|
|
|
+#endif
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
ret = lxc_set_state(name, handler, RUNNING);
|
|
|
|
|
if (ret < 0) {
|
|
|
|
|
ERROR("Failed to set state to \"%s\"", lxc_state2str(RUNNING));
|
|
|
|
|
@@ -2592,3 +2615,257 @@ static bool do_destroy_container(struct lxc_handler *handler)
|
|
|
|
|
|
|
|
|
|
return storage_destroy(handler->conf);
|
|
|
|
|
}
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+#ifdef HAVE_ISULAD
|
|
|
|
|
+/*isulad: set env for clean resources */
|
|
|
|
|
+static int clean_resource_set_env(struct lxc_handler *handler)
|
|
|
|
|
+{
|
|
|
|
|
+ const char *name = handler->name;
|
|
|
|
|
+ struct lxc_conf *conf = handler->conf;
|
|
|
|
|
+ char bufstr[PATH_MAX + 1];
|
|
|
|
|
+ int i = 0;
|
|
|
|
|
+ int j = 0;
|
|
|
|
|
+ int len = 2; //set "LXC_PID" and "LXC_CGNS_AWARE"
|
|
|
|
|
+
|
|
|
|
|
+ if (conf == NULL || conf->ocihooks == NULL || conf->ocihooks->poststop_len == 0) {
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (name) {
|
|
|
|
|
+ len++;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (conf->rcfile) {
|
|
|
|
|
+ len++;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (conf->rootfs.mount) {
|
|
|
|
|
+ len++;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (conf->rootfs.path) {
|
|
|
|
|
+ len++;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (conf->console.path) {
|
|
|
|
|
+ len++;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (conf->console.log_path) {
|
|
|
|
|
+ len++;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (handler->cgroup_ops->container_cgroup) {
|
|
|
|
|
+ len++;
|
|
|
|
|
+ }
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ for (; i < conf->ocihooks->poststop_len; i++) {
|
|
|
|
|
+ size_t cap = conf->ocihooks->poststop[i]->env_len;
|
|
|
|
|
+ size_t newcap = cap + len + 1;
|
|
|
|
|
+ if (lxc_grow_array((void ***)&(conf->ocihooks->poststop[i]->env), &cap, newcap, 1) != 0) {
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+ j = conf->ocihooks->poststop[i]->env_len;
|
|
|
|
|
+ /* Start of environment variable setup for hooks. */
|
|
|
|
|
+ if (name) {
|
|
|
|
|
+ snprintf(bufstr, PATH_MAX + 1, "LXC_NAME=%s", name);
|
|
|
|
|
+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup(bufstr);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (conf->rcfile) {
|
|
|
|
|
+ snprintf(bufstr, PATH_MAX + 1, "LXC_CONFIG_FILE=%s", conf->rcfile);
|
|
|
|
|
+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup(bufstr);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (conf->rootfs.mount) {
|
|
|
|
|
+ snprintf(bufstr, PATH_MAX + 1, "LXC_ROOTFS_MOUNT=%s", conf->rootfs.mount);
|
|
|
|
|
+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup(bufstr);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (conf->rootfs.path) {
|
|
|
|
|
+ snprintf(bufstr, PATH_MAX + 1, "LXC_ROOTFS_PATH=%s", conf->rootfs.path);
|
|
|
|
|
+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup(bufstr);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (conf->console.path) {
|
|
|
|
|
+ snprintf(bufstr, PATH_MAX + 1, "LXC_CONSOLE=%s", conf->console.path);
|
|
|
|
|
+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup(bufstr);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (conf->console.log_path) {
|
|
|
|
|
+ snprintf(bufstr, PATH_MAX + 1, "LXC_CONSOLE_LOGPATH=%s", conf->console.log_path);
|
|
|
|
|
+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup(bufstr);
|
|
|
|
|
+ }
|
|
|
|
|
+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup("LXC_CGNS_AWARE=1");
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ snprintf(bufstr, PATH_MAX + 1, "LXC_PID=%d", handler->pid);
|
|
|
|
|
+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup(bufstr);
|
|
|
|
|
+ if (handler->cgroup_ops->container_cgroup) {
|
|
|
|
|
+ snprintf(bufstr, PATH_MAX + 1, "LXC_CGROUP_PATH=%s", handler->cgroup_ops->container_cgroup);
|
|
|
|
|
+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup(bufstr);
|
|
|
|
|
+ }
|
|
|
|
|
+ conf->ocihooks->poststop[i]->env_len = j;
|
|
|
|
|
+ /* End of environment variable setup for hooks. */
|
|
|
|
|
+ }
|
|
|
|
|
+ return 0;
|
2019-09-30 11:03:07 -04:00
|
|
|
+}
|
|
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+/*isulad: init handler for clean */
|
|
|
|
|
+static struct lxc_handler *lxc_init_clean_handler(char *name, char *lxcpath, struct lxc_conf *conf, pid_t pid)
|
|
|
|
|
+{
|
|
|
|
|
+ int i;
|
|
|
|
|
+ struct lxc_handler *handler;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ handler = malloc(sizeof(*handler));
|
|
|
|
|
+ if (handler == NULL)
|
|
|
|
|
+ return NULL;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ 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.
|
|
|
|
|
+ */
|
|
|
|
|
+ handler->am_root = !am_guest_unpriv();
|
|
|
|
|
+ handler->data_sock[0] = handler->data_sock[1] = -1;
|
|
|
|
|
+ handler->conf = conf;
|
|
|
|
|
+ handler->lxcpath = lxcpath;
|
|
|
|
|
+ handler->pinfd = -1;
|
|
|
|
|
+ handler->sigfd = -EBADF;
|
|
|
|
|
+ handler->init_died = false;
|
|
|
|
|
+ handler->pid = pid;
|
|
|
|
|
+ handler->state_socket_pair[0] = handler->state_socket_pair[1] = -1;
|
|
|
|
|
+ if (handler->conf->reboot == REBOOT_NONE)
|
|
|
|
|
+ lxc_list_init(&handler->conf->state_clients);
|
|
|
|
|
+
|
|
|
|
|
+ for (i = 0; i < LXC_NS_MAX; i++)
|
|
|
|
|
+ handler->nsfd[i] = -1;
|
|
|
|
|
+
|
|
|
|
|
+ handler->name = name;
|
|
|
|
|
+ handler->exit_code = -1; /* isulad: record exit code of container */
|
|
|
|
|
+
|
|
|
|
|
+ handler->cgroup_ops = cgroup_init(conf);
|
|
|
|
|
+ if (!handler->cgroup_ops) {
|
|
|
|
|
+ ERROR("Failed to initialize cgroup driver");
|
|
|
|
|
+ goto on_error;
|
|
|
|
|
+ }
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ INFO("Container \"%s\" 's clean handler is initialized.", name);
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ return handler;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+on_error:
|
|
|
|
|
+ lxc_free_handler(handler);
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ return NULL;
|
2019-09-30 11:03:07 -04:00
|
|
|
+}
|
|
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+/*isulad: init handler for clean */
|
|
|
|
|
+static struct lxc_handler *lxc_init_pids_handler(char *name, char *lxcpath, struct lxc_conf *conf)
|
|
|
|
|
+{
|
|
|
|
|
+ int i;
|
|
|
|
|
+ struct lxc_handler *handler;
|
|
|
|
|
+
|
|
|
|
|
+ handler = malloc(sizeof(*handler));
|
|
|
|
|
+ if (handler == NULL)
|
|
|
|
|
+ return NULL;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ 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.
|
|
|
|
|
+ */
|
|
|
|
|
+ handler->am_root = !am_guest_unpriv();
|
|
|
|
|
+ handler->data_sock[0] = handler->data_sock[1] = -1;
|
|
|
|
|
+ handler->conf = conf;
|
|
|
|
|
+ handler->lxcpath = lxcpath;
|
|
|
|
|
+ handler->pinfd = -1;
|
|
|
|
|
+ handler->sigfd = -EBADF;
|
|
|
|
|
+ handler->init_died = false;
|
|
|
|
|
+ handler->state_socket_pair[0] = handler->state_socket_pair[1] = -1;
|
|
|
|
|
+ if (handler->conf->reboot == REBOOT_NONE)
|
|
|
|
|
+ lxc_list_init(&handler->conf->state_clients);
|
|
|
|
|
+
|
|
|
|
|
+ for (i = 0; i < LXC_NS_MAX; i++)
|
|
|
|
|
+ handler->nsfd[i] = -1;
|
|
|
|
|
+
|
|
|
|
|
+ handler->name = name;
|
|
|
|
|
+ handler->exit_code = -1; /* isulad: record exit code of container */
|
|
|
|
|
+
|
|
|
|
|
+ handler->cgroup_ops = cgroup_init(conf);
|
|
|
|
|
+ if (!handler->cgroup_ops) {
|
|
|
|
|
+ ERROR("Failed to initialize cgroup driver");
|
|
|
|
|
+ goto on_error;
|
|
|
|
|
+ }
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ INFO("Container \"%s\" 's clean handler is initialized.", name);
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ return handler;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+on_error:
|
|
|
|
|
+ lxc_free_handler(handler);
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ return NULL;
|
2019-09-30 11:03:07 -04:00
|
|
|
+}
|
|
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+/*isulad: do_lxcapi_clean_resource */
|
|
|
|
|
+int do_lxcapi_clean_resource(char *name, char *lxcpath, struct lxc_conf *conf, pid_t pid)
|
|
|
|
|
+{
|
|
|
|
|
+ int ret = 0;
|
|
|
|
|
+ struct lxc_handler *handler = NULL;
|
|
|
|
|
+ int retry_count = 0;
|
|
|
|
|
+ int max_retry = 10;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ handler = lxc_init_clean_handler(name, lxcpath, conf, pid);
|
|
|
|
|
+ if (!handler) {
|
|
|
|
|
+ ERROR("Failed to init container %s clean handler", name);
|
|
|
|
|
+ ret = -1;
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (clean_resource_set_env(handler) != 0) {
|
|
|
|
|
+ ERROR("Failed to set env for poststop hooks");
|
|
|
|
|
+ ret = -1;
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ if (run_oci_hooks(handler->name, "oci-poststop", handler->conf, handler->lxcpath)) {
|
|
|
|
|
+ ERROR("Failed to run lxc.hook.post-stop for container \"%s\".", handler->name);
|
|
|
|
|
+ ret = -1;
|
|
|
|
|
+ }
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+retry:
|
|
|
|
|
+ if (!handler->cgroup_ops->payload_destroy(handler->cgroup_ops, handler)) {
|
|
|
|
|
+ TRACE("Trying to kill all subprocess");
|
|
|
|
|
+ signal_all_processes(handler);
|
|
|
|
|
+ TRACE("Finished kill all subprocess");
|
|
|
|
|
+ if (retry_count < max_retry) {
|
|
|
|
|
+ usleep(100 * 1000); /* 100 millisecond */
|
|
|
|
|
+ retry_count++;
|
|
|
|
|
+ goto retry;
|
|
|
|
|
+ }
|
|
|
|
|
+ SYSERROR("Failed to destroy cgroup path for container: \"%s\"", handler->name);
|
|
|
|
|
+ ret = -1;
|
|
|
|
|
+ }
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
|
|
|
|
+out:
|
2020-04-23 11:50:43 +08:00
|
|
|
+ lxc_free_handler(handler);
|
|
|
|
|
+ return ret;
|
2019-09-30 11:03:07 -04:00
|
|
|
+}
|
|
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+/*isulad: do_lxcapi_get_pids */
|
|
|
|
|
+int do_lxcapi_get_pids(char *name, char *lxcpath, struct lxc_conf *conf, pid_t **pids,size_t *pids_len)
|
2019-09-30 11:03:07 -04:00
|
|
|
+{
|
2020-04-23 11:50:43 +08:00
|
|
|
+ int ret = 0;
|
|
|
|
|
+ struct lxc_handler *handler = NULL;
|
|
|
|
|
+ struct cgroup_ops *cg_ops = NULL;
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ handler = lxc_init_pids_handler(name, lxcpath, conf);
|
|
|
|
|
+ if (!handler) {
|
|
|
|
|
+ ERROR("Failed to init container %s clean handler", name);
|
|
|
|
|
+ ret = -1;
|
|
|
|
|
+ goto out;
|
2019-09-30 11:03:07 -04:00
|
|
|
+ }
|
|
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+ cg_ops = handler->cgroup_ops;
|
|
|
|
|
+ ret = get_all_pids(cg_ops, pids, pids_len);
|
|
|
|
|
+ if (ret < 0) {
|
|
|
|
|
+ WARN("failed to get all pids");
|
2019-09-30 11:03:07 -04:00
|
|
|
+ }
|
|
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+out:
|
|
|
|
|
+ lxc_free_handler(handler);
|
|
|
|
|
+ return ret;
|
2019-09-30 11:03:07 -04:00
|
|
|
+}
|
|
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+#endif
|
|
|
|
|
diff --git a/src/lxc/start.h b/src/lxc/start.h
|
|
|
|
|
index 5ea5fe2..4fc3ff7 100644
|
|
|
|
|
--- a/src/lxc/start.h
|
|
|
|
|
+++ b/src/lxc/start.h
|
|
|
|
|
@@ -175,4 +175,12 @@ extern int __lxc_start(struct lxc_handler *, struct lxc_operations *, void *,
|
2019-09-30 11:03:07 -04:00
|
|
|
|
2020-04-23 11:50:43 +08:00
|
|
|
extern int resolve_clone_flags(struct lxc_handler *handler);
|
2019-09-30 11:03:07 -04:00
|
|
|
|
2020-04-23 11:50:43 +08:00
|
|
|
+#ifdef HAVE_ISULAD
|
|
|
|
|
+/*isulad: do_lxcapi_clean_resource */
|
|
|
|
|
+extern int do_lxcapi_clean_resource(char *name, char *lxcpath, struct lxc_conf *conf, pid_t pid);
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+/*isulad: do_lxcapi_get_pids */
|
|
|
|
|
+extern int do_lxcapi_get_pids(char *name, char *lxcpath, struct lxc_conf *conf, pid_t **pids,size_t *pids_len);
|
|
|
|
|
+#endif
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
#endif
|
|
|
|
|
diff --git a/src/lxc/sync.h b/src/lxc/sync.h
|
|
|
|
|
index ff7a1eb..56c1dfc 100644
|
|
|
|
|
--- a/src/lxc/sync.h
|
|
|
|
|
+++ b/src/lxc/sync.h
|
|
|
|
|
@@ -11,6 +11,10 @@ enum {
|
|
|
|
|
LXC_SYNC_POST_CONFIGURE,
|
|
|
|
|
LXC_SYNC_CGROUP,
|
|
|
|
|
LXC_SYNC_CGROUP_UNSHARE,
|
|
|
|
|
+#ifdef HAVE_ISULAD
|
|
|
|
|
+ LXC_SYNC_OCI_PRESTART_HOOK,
|
|
|
|
|
+ LXC_SYNC_POST_OCI_PRESTART_HOOK,
|
|
|
|
|
+#endif
|
|
|
|
|
LXC_SYNC_CGROUP_LIMITS,
|
|
|
|
|
LXC_SYNC_READY_START,
|
|
|
|
|
LXC_SYNC_RESTART,
|
2019-09-30 11:03:07 -04:00
|
|
|
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
|
2020-04-23 11:50:43 +08:00
|
|
|
index 27078e2..39413ee 100644
|
2019-09-30 11:03:07 -04:00
|
|
|
--- a/src/lxc/utils.c
|
|
|
|
|
+++ b/src/lxc/utils.c
|
2020-04-23 11:50:43 +08:00
|
|
|
@@ -2122,4 +2122,42 @@ set_env:
|
|
|
|
|
return 0;
|
2019-09-30 11:03:07 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+bool lxc_process_alive(pid_t pid, unsigned long long start_time)
|
|
|
|
|
+{
|
|
|
|
|
+ int sret = 0;
|
|
|
|
|
+ bool alive = true;
|
|
|
|
|
+ proc_t *pid_info = NULL;
|
|
|
|
|
+ char filename[PATH_MAX] = {0};
|
|
|
|
|
+ char sbuf[1024] = {0}; /* bufs for stat */
|
|
|
|
|
+
|
|
|
|
|
+ sret = kill(pid, 0);
|
|
|
|
|
+ if (sret < 0 && errno == ESRCH)
|
|
|
|
|
+ return false;
|
|
|
|
|
+
|
|
|
|
|
+ sret = snprintf(filename, sizeof(filename), "/proc/%d/stat", pid);
|
|
|
|
|
+ if (sret < 0 || sret >= sizeof(filename)) {
|
|
|
|
|
+ ERROR("Failed to sprintf filename");
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if ((lxc_file2str(filename, sbuf, sizeof(sbuf))) == -1) {
|
|
|
|
|
+ ERROR("Failed to read pidfile %s", filename);
|
|
|
|
|
+ alive = false;
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ pid_info = lxc_stat2proc(sbuf);
|
|
|
|
|
+ if (!pid_info) {
|
|
|
|
|
+ ERROR("Failed to get proc stat info");
|
|
|
|
|
+ alive = false;
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (start_time != pid_info->start_time)
|
|
|
|
|
+ alive = false;
|
|
|
|
|
+out:
|
|
|
|
|
+ free(pid_info);
|
|
|
|
|
+ return alive;
|
|
|
|
|
+}
|
2020-04-23 11:50:43 +08:00
|
|
|
+
|
|
|
|
|
#endif
|
2019-09-30 11:03:07 -04:00
|
|
|
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
|
2020-04-23 11:50:43 +08:00
|
|
|
index 36c458e..a213ba7 100644
|
2019-09-30 11:03:07 -04:00
|
|
|
--- a/src/lxc/utils.h
|
|
|
|
|
+++ b/src/lxc/utils.h
|
2020-04-23 11:50:43 +08:00
|
|
|
@@ -322,6 +322,8 @@ extern int lxc_file2str(const char *filename, char ret[], int cap);
|
2019-09-30 11:03:07 -04:00
|
|
|
extern int unsigned long long lxc_get_process_startat(pid_t pid);
|
2020-04-23 11:50:43 +08:00
|
|
|
// set env home in container
|
|
|
|
|
extern int lxc_setup_env_home(uid_t uid);
|
2019-09-30 11:03:07 -04:00
|
|
|
+
|
2020-04-23 11:50:43 +08:00
|
|
|
+extern bool lxc_process_alive(pid_t pid, unsigned long long start_time);
|
|
|
|
|
#endif
|
|
|
|
|
|
2019-09-30 11:03:07 -04:00
|
|
|
#endif /* __LXC_UTILS_H */
|
|
|
|
|
--
|
2020-01-05 22:20:49 -05:00
|
|
|
1.8.3.1
|
2019-09-30 11:03:07 -04:00
|
|
|
|