diff --git a/0001-iSulad-add-HAVE_ISULAD-macro.patch b/0001-iSulad-add-HAVE_ISULAD-macro.patch new file mode 100644 index 0000000000000000000000000000000000000000..cbae9794ed2982d7074e202b214f969bbe36d3a5 --- /dev/null +++ b/0001-iSulad-add-HAVE_ISULAD-macro.patch @@ -0,0 +1,50 @@ +From 49f7dc89e5ae690a0b81570a81321b1593aeb994 Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Sat, 11 Apr 2020 15:43:38 +0800 +Subject: [PATCH 01/49] iSulad: add HAVE_ISULAD macro + +Signed-off-by: LiFeng +--- + configure.ac | 11 +++++++++++ + src/lxc/Makefile.am | 3 +++ + 2 files changed, 14 insertions(+) + +diff --git a/configure.ac b/configure.ac +index 90a4bd4..5f386d9 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -791,6 +791,17 @@ else + AC_MSG_RESULT([no]) + fi + ++AC_MSG_CHECKING([Whether adapt to iSulad]) ++AC_ARG_ENABLE([isulad], ++ [AC_HELP_STRING([--enable-isulad], [enable adapt to iSulad [default=yes]])], ++ [adapt_isulad=$enableval], [adapt_isulad=yes]) ++AM_CONDITIONAL([HAVE_ISULAD], [test "x$adapt_isulad" = "xyes"]) ++if test "x$adapt_isulad" = "xyes"; then ++ AC_DEFINE([HAVE_ISULAD], 1, [adapt to iSulad]) ++ AC_MSG_RESULT([yes]) ++else ++ AC_MSG_RESULT([no]) ++fi + # Files requiring some variable expansion + AC_CONFIG_FILES([ + Makefile +diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am +index c374c2d..e7fc844 100644 +--- a/src/lxc/Makefile.am ++++ b/src/lxc/Makefile.am +@@ -212,6 +212,9 @@ AM_CFLAGS = -DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \ + -I $(top_srcdir)/src/lxc/storage \ + -I $(top_srcdir)/src/lxc/cgroups + ++if HAVE_ISULAD ++AM_CFLAGS += -DHAVE_ISULAD ++endif + if ENABLE_APPARMOR + AM_CFLAGS += -DHAVE_APPARMOR + endif +-- +1.8.3.1 + diff --git a/0001-confile-add-lxc.isulad.init.args-config-interface.patch b/0002-confile-add-lxc.isulad.init.args-config-interface.patch similarity index 57% rename from 0001-confile-add-lxc.isulad.init.args-config-interface.patch rename to 0002-confile-add-lxc.isulad.init.args-config-interface.patch index ffddf8bf0782f537da4c142aa2087bb3dff3ece4..cb8adf79e4a8ad954f3af70b4b72385dbca542ac 100644 --- a/0001-confile-add-lxc.isulad.init.args-config-interface.patch +++ b/0002-confile-add-lxc.isulad.init.args-config-interface.patch @@ -1,31 +1,43 @@ -From dd7c0b3cc5f4ce91f81dcb4f02bc8c4aaa023024 Mon Sep 17 00:00:00 2001 +From 549a0a959b84a483d9f733cf7a157900f4c889c4 Mon Sep 17 00:00:00 2001 From: LiFeng -Date: Thu, 10 Jan 2019 06:54:37 -0500 -Subject: [PATCH 001/140] confile: add lxc.isulad.init.args config interface +Date: Sat, 11 Apr 2020 16:16:15 +0800 +Subject: [PATCH 02/49] confile: add lxc.isulad.init.args config interface lxc.isulad.init.args config interface is used to specify the args for the container. Signed-off-by: LiFeng --- - src/lxc/conf.c | 13 +++++++++++ - src/lxc/conf.h | 8 +++++++ - src/lxc/confile.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ - src/lxc/lxccontainer.c | 30 +++++++++++++++++++++++++ - 4 files changed, 112 insertions(+) + src/lxc/conf.c | 17 ++++++++++++++ + src/lxc/conf.h | 11 ++++++++- + src/lxc/confile.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ + src/lxc/lxccontainer.c | 33 +++++++++++++++++++++++++++ + 4 files changed, 122 insertions(+), 1 deletion(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index d95bc4c..f20d629 100644 +index 2f6be9f..62a6979 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c -@@ -4014,6 +4014,18 @@ void lxc_clear_includes(struct lxc_conf *conf) - } +@@ -3835,6 +3835,9 @@ void lxc_conf_free(struct lxc_conf *conf) + free(conf->cgroup_meta.controllers); + free(conf->shmount.path_host); + free(conf->shmount.path_cont); ++#ifdef HAVE_ISULAD ++ lxc_clear_init_args(conf); ++#endif + free(conf); } +@@ -4645,3 +4648,17 @@ struct lxc_list *sort_cgroup_settings(struct lxc_list *cgroup_settings) + + return result; + } ++ ++#ifdef HAVE_ISULAD +/*isulad clear init args*/ +int lxc_clear_init_args(struct lxc_conf *lxc_conf) +{ -+ int i; ++ size_t i; + + for (i = 0; i < lxc_conf->init_argc; i++) + free(lxc_conf->init_argv[i]); @@ -33,72 +45,65 @@ index d95bc4c..f20d629 100644 + + return 0; +} -+ - void lxc_conf_free(struct lxc_conf *conf) - { - if (!conf) -@@ -4057,6 +4069,7 @@ void lxc_conf_free(struct lxc_conf *conf) - lxc_clear_limits(conf, "lxc.prlimit"); - lxc_clear_sysctls(conf, "lxc.sysctl"); - lxc_clear_procs(conf, "lxc.proc"); -+ lxc_clear_init_args(conf); - free(conf->cgroup_meta.dir); - free(conf->cgroup_meta.controllers); - free(conf); ++#endif diff --git a/src/lxc/conf.h b/src/lxc/conf.h -index 41f67cf..95c3027 100644 +index 64885c3..8a198e4 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h -@@ -376,6 +376,10 @@ struct lxc_conf { - - /* procs */ - struct lxc_list procs; +@@ -398,6 +398,13 @@ struct lxc_conf { + /* Absolute path (in the container) to the shared mount point */ + char *path_cont; + } shmount; + -+ /* isulad add: init args used to repalce init_cmd*/ ++#ifdef HAVE_ISULAD ++ /* isulad add: init args used to repalce init_cmd*/ + char **init_argv; + size_t init_argc; ++#endif ++ }; extern int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf, -@@ -442,4 +446,8 @@ extern int lxc_clear_sysctls(struct lxc_conf *c, const char *key); - extern int setup_proc_filesystem(struct lxc_list *procs, pid_t pid); - extern int lxc_clear_procs(struct lxc_conf *c, const char *key); - -+/* isulad add begin */ +@@ -470,5 +477,7 @@ extern int lxc_clear_namespace(struct lxc_conf *c); + extern int userns_exec_minimal(const struct lxc_conf *conf, + int (*fn_parent)(void *), void *fn_parent_data, + int (*fn_child)(void *), void *fn_child_data); +- ++#ifdef HAVE_ISULAD +int lxc_clear_init_args(struct lxc_conf *lxc_conf); -+/* isulad add end */ -+ ++#endif #endif /* __LXC_CONF_H */ diff --git a/src/lxc/confile.c b/src/lxc/confile.c -index 05c6823..7297b35 100644 +index 0ca577f..e535beb 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c -@@ -150,6 +150,10 @@ lxc_config_define(tty_dir); +@@ -147,6 +147,9 @@ lxc_config_define(tty_dir); lxc_config_define(uts_name); lxc_config_define(sysctl); lxc_config_define(proc); -+/*isulad add begin*/ ++#ifdef HAVE_ISULAD +lxc_config_define(init_args); -+/*isulad add end*/ -+ ++#endif - static struct lxc_config_t config_jump_table[] = { - { "lxc.arch", set_config_personality, get_config_personality, clr_config_personality, }, -@@ -234,6 +238,10 @@ static struct lxc_config_t config_jump_table[] = { + /* + * Important Note: +@@ -259,6 +262,10 @@ static struct lxc_config_t config_jump_table[] = { { "lxc.uts.name", set_config_uts_name, get_config_uts_name, clr_config_uts_name, }, { "lxc.sysctl", set_config_sysctl, get_config_sysctl, clr_config_sysctl, }, { "lxc.proc", set_config_proc, get_config_proc, clr_config_proc, }, ++#ifdef HAVE_ISULAD ++ { "lxc.isulad.init.args", set_config_init_args, get_config_init_args, clr_config_init_args, }, + -+ /*isulad add begin*/ -+ { "lxc.isulad.init.args", set_config_init_args, get_config_init_args, clr_config_init_args, }, -+ /*isulad add end*/ ++#endif }; static const size_t config_jump_table_size = sizeof(config_jump_table) / sizeof(struct lxc_config_t); -@@ -2184,6 +2192,33 @@ static int set_config_namespace_share(const char *key, const char *value, - return set_config_string_item(&lxc_conf->ns_share[ns_idx], value); - } +@@ -6094,3 +6101,58 @@ int lxc_list_net(struct lxc_conf *c, const char *key, char *retv, int inlen) + return fulllen; + } ++ ++#ifdef HAVE_ISULAD +/* isulad: set config for init args */ +static int set_config_init_args(const char *key, const char *value, + struct lxc_conf *lxc_conf, void *data) @@ -126,13 +131,6 @@ index 05c6823..7297b35 100644 + return 0; +} + - struct parse_line_conf { - struct lxc_conf *conf; - bool from_include; -@@ -3716,6 +3751,25 @@ static int get_config_namespace_share(const char *key, char *retv, int inlen, - return fulllen; - } - +/* isulad: get config init args */ +static int get_config_init_args(const char *key, char *retv, int inlen, + struct lxc_conf *c, void *data) @@ -152,31 +150,22 @@ index 05c6823..7297b35 100644 + return fulllen; +} + - /* Callbacks to clear config items. */ - static inline int clr_config_personality(const char *key, struct lxc_conf *c, - void *data) -@@ -4520,6 +4574,13 @@ static int clr_config_net_ipv6_address(const char *key, - return 0; - } - +/* isulad: clr config init args*/ +static inline int clr_config_init_args(const char *key, struct lxc_conf *c, + void *data) +{ + return lxc_clear_init_args(c); +} -+ - static int get_config_net_nic(const char *key, char *retv, int inlen, - struct lxc_conf *c, void *data) - { ++#endif diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index ad70886..b4cacce 100644 +index 487d838..f4462fd 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c -@@ -847,6 +847,31 @@ static bool wait_on_daemonized_start(struct lxc_handler *handler, int pid) +@@ -857,6 +857,33 @@ static bool wait_on_daemonized_start(struct lxc_handler *handler, int pid) return true; } ++#ifdef HAVE_ISULAD +/* isulad: use init argv as init cmd */ +static char **use_init_args(char **init_argv, size_t init_args) +{ @@ -201,18 +190,20 @@ index ad70886..b4cacce 100644 + } + return argv; +} ++#endif + static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const argv[]) { int ret; -@@ -903,6 +928,11 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a +@@ -914,6 +941,12 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a argv = init_cmd = split_init_cmd(conf->init_cmd); } -+ /* isulad: use init argv as init cmd */ ++#ifdef HAVE_ISULAD + if (!argv) { + argv = init_cmd = use_init_args(conf->init_argv, conf->init_argc); + } ++#endif + /* ... otherwise use default_args. */ if (!argv) { diff --git a/0002-namespace-add-support-share-namespace-by-path.patch b/0002-namespace-add-support-share-namespace-by-path.patch deleted file mode 100644 index dab8b2f49782a3141030e16a30a8124a69b57160..0000000000000000000000000000000000000000 --- a/0002-namespace-add-support-share-namespace-by-path.patch +++ /dev/null @@ -1,35 +0,0 @@ -From bcc0965a02a571c39713056536d63f3378dcba3a Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Thu, 10 Jan 2019 08:42:19 -0500 -Subject: [PATCH 002/140] namespace: add support share namespace by path - -Signed-off-by: LiFeng ---- - src/lxc/confile_utils.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/src/lxc/confile_utils.c b/src/lxc/confile_utils.c -index 7280463..9049ce8 100644 ---- a/src/lxc/confile_utils.c -+++ b/src/lxc/confile_utils.c -@@ -789,6 +789,17 @@ int lxc_inherit_namespace(const char *lxcname_or_pid, const char *lxcpath, - int fd, pid; - char *dup, *lastslash; - -+ /* isulad: add support share namespace by path. -+ * e.g. "lxc.namespace.share.net = /proc/PID/ns/net or /var/run/netns/net" -+ */ -+ if (file_exists(lxcname_or_pid) && !dir_exists(lxcname_or_pid)) { -+ fd = open(lxcname_or_pid, O_RDONLY | O_CLOEXEC); -+ if (fd < 0) -+ return -EINVAL; -+ -+ return fd; -+ } -+ - lastslash = strrchr(lxcname_or_pid, '/'); - if (lastslash) { - dup = strdup(lxcname_or_pid); --- -1.8.3.1 - diff --git a/0003-confile-add-lxc.isulad.populate.device-interface.patch b/0003-confile-add-lxc.isulad.populate.device-interface.patch index 146239f56f4318746488911d1349fc9f62d21795..3b26bf1b73248581d6b29c56005c44b0a2208885 100644 --- a/0003-confile-add-lxc.isulad.populate.device-interface.patch +++ b/0003-confile-add-lxc.isulad.populate.device-interface.patch @@ -1,62 +1,105 @@ -From b4e5d9e162a17f50367aad1ea92df7dc09fa34e9 Mon Sep 17 00:00:00 2001 +From 481e3bf2c164d5303c6f827fc2bcbb67508d0ff5 Mon Sep 17 00:00:00 2001 From: LiFeng -Date: Fri, 11 Jan 2019 01:51:25 -0500 -Subject: [PATCH 003/140] confile: add lxc.isulad.populate.device interface +Date: Sat, 11 Apr 2020 17:12:44 +0800 +Subject: [PATCH 03/49] confile: add lxc.isulad.populate.device interface Signed-off-by: LiFeng --- - src/lxc/conf.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++--- - src/lxc/conf.h | 28 +++++++++++- - src/lxc/confile.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 269 insertions(+), 8 deletions(-) + src/lxc/Makefile.am | 9 + + src/lxc/conf.c | 126 ++++++++++ + src/lxc/conf.h | 25 ++ + src/lxc/confile.c | 120 ++++++++- + src/lxc/isulad_utils.c | 99 ++++++++ + src/lxc/isulad_utils.h | 20 ++ + src/lxc/path.c | 655 +++++++++++++++++++++++++++++++++++++++++++++++++ + src/lxc/path.h | 65 +++++ + src/lxc/utils.h | 3 + + 9 files changed, 1121 insertions(+), 1 deletion(-) + create mode 100644 src/lxc/isulad_utils.c + create mode 100644 src/lxc/isulad_utils.h + create mode 100644 src/lxc/path.c + create mode 100644 src/lxc/path.h +diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am +index e7fc844..21441c0 100644 +--- a/src/lxc/Makefile.am ++++ b/src/lxc/Makefile.am +@@ -52,6 +52,10 @@ noinst_HEADERS = api_extensions.h \ + utils.h \ + uuid.h + ++#if HAVE_ISULAD ++noinst_HEADERS += isulad_utils.h path.h ++#endif ++ + if IS_BIONIC + noinst_HEADERS += ../include/fexecve.h \ + ../include/lxcmntent.h \ +@@ -154,6 +158,11 @@ liblxc_la_SOURCES = af_unix.c af_unix.h \ + version.h \ + $(LSM_SOURCES) + ++#if HAVE_ISULAD ++liblxc_la_SOURCES += isulad_utils.c isulad_utils.h \ ++ path.c path.h ++#endif ++ + if IS_BIONIC + liblxc_la_SOURCES += ../include/fexecve.c ../include/fexecve.h \ + ../include/lxcmntent.c ../include/lxcmntent.h \ diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index f20d629..20b7aba 100644 +index 62a6979..e9c0a37 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c -@@ -2745,6 +2745,10 @@ struct lxc_conf *lxc_conf_init(void) - memset(&new->cgroup_meta, 0, sizeof(struct lxc_cgroup)); +@@ -2564,6 +2564,11 @@ struct lxc_conf *lxc_conf_init(void) memset(&new->ns_share, 0, sizeof(char *) * LXC_NS_MAX); + seccomp_conf_init(new); ++#ifdef HAVE_ISULAD + /* isulad add begin */ + lxc_list_init(&new->populate_devs); -+ /* isulad add end */ ++#endif + return new; } -@@ -3487,6 +3491,85 @@ static bool execveat_supported(void) - return true; +@@ -3274,6 +3279,99 @@ static int lxc_setup_boot_id(void) + return 0; } ++#ifdef HAVE_ISULAD +/* isulad: setup devices which will be populated in the container.*/ +static int setup_populate_devs(const struct lxc_rootfs *rootfs, struct lxc_list *devs) +{ -+ int ret; -+ char *pathdirname; ++ int ret = 0; ++ char *pathdirname = NULL; + char path[MAXPATHLEN]; -+ mode_t cmask; + mode_t file_mode = 0; -+ struct lxc_populate_devs *dev_elem; -+ struct lxc_list *it; ++ struct lxc_populate_devs *dev_elem = NULL; ++ struct lxc_list *it = NULL; ++ mode_t cur_mask; + + INFO("Populating devices into container"); -+ cmask = umask(S_IXUSR | S_IXGRP | S_IXOTH); ++ cur_mask = umask(0000); + lxc_list_for_each(it, devs) { ++ ret = 0; + dev_elem = it->elem; + + ret = snprintf(path, MAXPATHLEN, "%s/%s", rootfs->path ? rootfs->mount : "", dev_elem->name); -+ if (ret < 0 || ret >= MAXPATHLEN) -+ return -1; ++ if (ret < 0 || ret >= MAXPATHLEN) { ++ ret = -1; ++ goto reset_umask; ++ } + + /* create any missing directories */ -+ pathdirname = strdup(path); ++ pathdirname = safe_strdup(path); + pathdirname = dirname(pathdirname); -+ ret = mkdir_p(pathdirname, 0750); ++ ret = mkdir_p(pathdirname, 0755); + free(pathdirname); + if (ret < 0) { + WARN("Failed to create target directory"); -+ return -1; ++ ret = -1; ++ goto reset_umask; + } + + if (!strcmp(dev_elem->type, "c")) { @@ -65,95 +108,95 @@ index f20d629..20b7aba 100644 + file_mode = dev_elem->file_mode | S_IFBLK; + } else { + ERROR("Failed to parse devices type '%s'", dev_elem->type); -+ return -1; ++ ret = -1; ++ goto reset_umask; + } + + DEBUG("Try to mknod '%s':'%d':'%d':'%d'\n", path, -+ file_mode, dev_elem->maj, dev_elem->min); ++ file_mode, dev_elem->maj, dev_elem->min); + + ret = mknod(path, file_mode, makedev(dev_elem->maj, dev_elem->min)); + if (ret && errno != EEXIST) { + SYSERROR("Failed to mknod '%s':'%d':'%d':'%d'", dev_elem->name, -+ file_mode, dev_elem->maj, dev_elem->min); ++ file_mode, dev_elem->maj, dev_elem->min); + + char hostpath[MAXPATHLEN]; -+ FILE *pathfile; ++ FILE *pathfile = NULL; + + // Unprivileged containers cannot create devices, so + // try to bind mount the device from the host + ret = snprintf(hostpath, MAXPATHLEN, "/dev/%s", dev_elem->name); -+ if (ret < 0 || ret >= MAXPATHLEN) -+ return -1; -+ pathfile = fopen(path, "wb"); ++ if (ret < 0 || ret >= MAXPATHLEN) { ++ ret = -1; ++ goto reset_umask; ++ } ++ pathfile = lxc_fopen(path, "wb"); + if (!pathfile) { + SYSERROR("Failed to create device mount target '%s'", path); -+ return -1; ++ ret = -1; ++ goto reset_umask; + } + fclose(pathfile); + if (safe_mount(hostpath, path, 0, MS_BIND, NULL, -+ rootfs->path ? rootfs->mount : NULL) != 0) { ++ rootfs->path ? rootfs->mount : NULL) != 0) { + SYSERROR("Failed bind mounting device %s from host into container", -+ dev_elem->name); -+ return -1; ++ dev_elem->name); ++ ret = -1; ++ goto reset_umask; + } + } + if (chown(path, dev_elem->uid, dev_elem->gid) < 0) { + ERROR("Error chowning %s", path); -+ return -1; ++ ret = -1; ++ goto reset_umask; + } + } -+ umask(cmask); ++ ++reset_umask: ++ (void)umask(cur_mask); + + INFO("Populated devices into container /dev"); -+ return 0; ++ return ret; +} ++#endif + int lxc_setup(struct lxc_handler *handler) { int ret; -@@ -3584,6 +3667,16 @@ int lxc_setup(struct lxc_handler *handler) - return -1; +@@ -3382,6 +3480,15 @@ int lxc_setup(struct lxc_handler *handler) + return log_error(-1, "Failed to populate \"/dev\""); } -+ /*isulad: move mount entrues here, before we do lxc_fill_autodev and populate devices */ -+ if (!lxc_list_empty(&lxc_conf->mount_list)) { -+ ret = setup_mount_entries(lxc_conf, &lxc_conf->rootfs, -+ &lxc_conf->mount_list, name, lxcpath); -+ if (ret < 0) { -+ ERROR("Failed to setup mount entries"); -+ return -1; ++#ifdef HAVE_ISULAD ++ /* isulad: setup devices which will be populated in the container. */ ++ if (!lxc_list_empty(&lxc_conf->populate_devs)) { ++ if (setup_populate_devs(&lxc_conf->rootfs, &lxc_conf->populate_devs) != 0) { ++ return log_error(-1, "Failed to setup devices in the container"); + } + } ++#endif + - ret = run_lxc_hooks(name, "mount", lxc_conf, NULL); - if (ret < 0) { - ERROR("Failed to run mount hooks"); -@@ -3604,12 +3697,11 @@ int lxc_setup(struct lxc_handler *handler) - } - } - -- if (!lxc_list_empty(&lxc_conf->mount_list)) { -- ret = setup_mount_entries(lxc_conf, &lxc_conf->rootfs, -- &lxc_conf->mount_list, name, lxcpath); -- if (ret < 0) { -- ERROR("Failed to setup mount entries"); -- return -1; -+ /* isulad: setup devices which will be populated in the container. */ -+ if (!lxc_list_empty(&lxc_conf->populate_devs)) { -+ if (setup_populate_devs(&lxc_conf->rootfs, &lxc_conf->populate_devs)) { -+ ERROR("Failed to setup devices in the container"); -+ return -1;; - } - } + /* Make sure any start hooks are in the container */ + if (!verify_start_hooks(lxc_conf)) + return log_error(-1, "Failed to verify start hooks"); +@@ -3837,6 +3944,7 @@ void lxc_conf_free(struct lxc_conf *conf) + free(conf->shmount.path_cont); + #ifdef HAVE_ISULAD + lxc_clear_init_args(conf); ++ lxc_clear_populate_devices(conf); + #endif + free(conf); + } +@@ -4661,4 +4769,22 @@ int lxc_clear_init_args(struct lxc_conf *lxc_conf) -@@ -4026,6 +4118,22 @@ int lxc_clear_init_args(struct lxc_conf *lxc_conf) return 0; } - ++ +/*isulad: clear populate devices*/ +int lxc_clear_populate_devices(struct lxc_conf *c) +{ -+ struct lxc_list *it,*next; ++ struct lxc_list *it = NULL; ++ struct lxc_list *next = NULL; + + lxc_list_for_each_safe(it, &c->populate_devs, next) { + struct lxc_populate_devs *dev_elem = it->elem; @@ -166,31 +209,17 @@ index f20d629..20b7aba 100644 + return 0; +} + - void lxc_conf_free(struct lxc_conf *conf) - { - if (!conf) -@@ -4069,9 +4177,12 @@ void lxc_conf_free(struct lxc_conf *conf) - lxc_clear_limits(conf, "lxc.prlimit"); - lxc_clear_sysctls(conf, "lxc.sysctl"); - lxc_clear_procs(conf, "lxc.proc"); -- lxc_clear_init_args(conf); - free(conf->cgroup_meta.dir); - free(conf->cgroup_meta.controllers); -+ /* isulad add begin */ -+ lxc_clear_init_args(conf); -+ lxc_clear_populate_devices(conf); -+ /* isulad add end */ - free(conf); - } - + #endif diff --git a/src/lxc/conf.h b/src/lxc/conf.h -index 95c3027..cced868 100644 +index 8a198e4..452458c 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h -@@ -171,6 +171,26 @@ struct lxc_rootfs { +@@ -230,6 +230,27 @@ struct device_item { + int global_rule; }; - /* ++#ifdef HAVE_ISULAD ++/* + * iSulad: Defines a structure to store the devices which will + * be attached in container + * @name : the target device name in container @@ -208,164 +237,146 @@ index 95c3027..cced868 100644 + uid_t uid; + gid_t gid; +}; ++#endif + -+ -+/* - * Automatic mounts for LXC to perform inside the container - */ - enum { -@@ -377,9 +397,13 @@ struct lxc_conf { - /* procs */ - struct lxc_list procs; - -- /* isulad add: init args used to repalce init_cmd*/ -+ /* isulad add begin */ -+ /* init args used to repalce init_cmd*/ + struct lxc_conf { + /* Pointer to the name of the container. Do not free! */ + const char *name; +@@ -403,6 +424,9 @@ struct lxc_conf { + /* isulad add: init args used to repalce init_cmd*/ char **init_argv; size_t init_argc; ++ + /* populate devices*/ + struct lxc_list populate_devs; -+ /* isulad add end */ - }; + #endif - extern int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf, -@@ -448,6 +472,8 @@ extern int lxc_clear_procs(struct lxc_conf *c, const char *key); - - /* isulad add begin */ + }; +@@ -479,5 +503,6 @@ extern int userns_exec_minimal(const struct lxc_conf *conf, + int (*fn_child)(void *), void *fn_child_data); + #ifdef HAVE_ISULAD int lxc_clear_init_args(struct lxc_conf *lxc_conf); +int lxc_clear_populate_devices(struct lxc_conf *c); -+ - /* isulad add end */ - + #endif #endif /* __LXC_CONF_H */ diff --git a/src/lxc/confile.c b/src/lxc/confile.c -index 7297b35..e3212d3 100644 +index e535beb..f0772f9 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c -@@ -152,6 +152,7 @@ lxc_config_define(sysctl); +@@ -149,6 +149,7 @@ lxc_config_define(sysctl); lxc_config_define(proc); - /*isulad add begin*/ + #ifdef HAVE_ISULAD lxc_config_define(init_args); +lxc_config_define(populate_device); - /*isulad add end*/ - + #endif -@@ -241,6 +242,7 @@ static struct lxc_config_t config_jump_table[] = { - - /*isulad add begin*/ - { "lxc.isulad.init.args", set_config_init_args, get_config_init_args, clr_config_init_args, }, -+ { "lxc.isulad.populate.device", set_config_populate_device, get_config_populate_device, clr_config_populate_device, }, - /*isulad add end*/ + /* +@@ -264,7 +265,7 @@ static struct lxc_config_t config_jump_table[] = { + { "lxc.proc", set_config_proc, get_config_proc, clr_config_proc, }, + #ifdef HAVE_ISULAD + { "lxc.isulad.init.args", set_config_init_args, get_config_init_args, clr_config_init_args, }, +- ++ { "lxc.isulad.populate.device", set_config_populate_device, get_config_populate_device, clr_config_populate_device, }, + #endif }; -@@ -2219,6 +2221,93 @@ static int set_config_init_args(const char *key, const char *value, - return 0; +@@ -6155,4 +6156,121 @@ static inline int clr_config_init_args(const char *key, struct lxc_conf *c, + { + return lxc_clear_init_args(c); } - -+/* isulad: set config for init args */ ++ ++/* isulad: set config for populate device */ +static int set_config_populate_device(const char *key, const char *value, -+ struct lxc_conf *lxc_conf, void *data) ++ struct lxc_conf *lxc_conf, void *data) +{ -+ int ret = 0, major = 0, minor = 0; -+ uid_t uid = (uid_t)-1; -+ gid_t gid = (gid_t)-1; -+ char name[PATH_MAX] = {0}; -+ char type[3] = {0}; -+ char *replace_value = NULL; -+ mode_t filemode = 0; -+ struct lxc_list *iter; -+ struct lxc_list *dev_list = NULL; -+ struct lxc_populate_devs *dev_elem = NULL; -+ -+ if (lxc_config_value_empty(value)) -+ return lxc_clear_populate_devices(lxc_conf); -+ -+ /* lxc.populate.device = PATH_IN_CONTAINER:DEVICETYPE:MAJOR:MINOR:MODE:UID:GID -+ * For e.g. lxc.populate.device = /dev/sda:b:8:0:0666:0:0 -+ */ -+ ret = sscanf(value, "%[^:]:%2[^:]:%i:%i:%i:%u:%u", name, type, &major, &minor, &filemode, &uid, &gid); -+ if (ret != 7) -+ return -1; -+ -+ /* find existing list element */ -+ lxc_list_for_each(iter, &lxc_conf->populate_devs) { -+ dev_elem = iter->elem; -+ -+ if (strcmp(name, dev_elem->name) != 0) -+ continue; -+ -+ replace_value = strdup(type); -+ if (!replace_value) -+ return -1; -+ -+ free(dev_elem->type); -+ dev_elem->type = replace_value; -+ dev_elem->file_mode = filemode; -+ dev_elem->maj = major; -+ dev_elem->min = minor; -+ dev_elem->uid = (uid_t)uid; -+ dev_elem->gid = (gid_t)gid; -+ return 0; -+ } -+ -+ /* allocate list element */ -+ dev_list = malloc(sizeof(*dev_list)); -+ if (!dev_list) -+ goto on_error; -+ -+ lxc_list_init(dev_list); -+ -+ dev_elem = malloc(sizeof(*dev_elem)); -+ if (!dev_elem) -+ goto on_error; -+ memset(dev_elem, 0, sizeof(*dev_elem)); -+ -+ dev_elem->name = strdup(name); -+ if (!dev_elem->name) -+ goto on_error; -+ -+ dev_elem->type = strdup(type); -+ if (!dev_elem->type) -+ goto on_error; -+ -+ dev_elem->file_mode = filemode; -+ dev_elem->maj = major; -+ dev_elem->min = minor; -+ -+ lxc_list_add_elem(dev_list, dev_elem); -+ -+ lxc_list_add_tail(&lxc_conf->populate_devs, dev_list); -+ -+ return 0; ++ int ret = 0, major = 0, minor = 0; ++ uid_t uid = (uid_t)-1; ++ gid_t gid = (gid_t)-1; ++ char name[4096] = {0}; /* MAX dev path name */ ++ char type[3] = {0}; ++ char *replace_value = NULL; ++ mode_t filemode = 0; ++ struct lxc_list *iter = NULL; ++ struct lxc_list *dev_list = NULL; ++ struct lxc_populate_devs *dev_elem = NULL; + -+on_error: -+ free(dev_list); -+ if (dev_elem) { -+ free(dev_elem->name); -+ free(dev_elem->type); -+ free(dev_elem); -+ } -+ return -1; ++ if (lxc_config_value_empty(value)) ++ return lxc_clear_populate_devices(lxc_conf); ++ ++ /* lxc.populate.device = PATH_IN_CONTAINER:DEVICETYPE:MAJOR:MINOR:MODE:UID:GID ++ * For e.g. lxc.populate.device = /dev/sda:b:8:0:0666:0:0 ++ */ ++ ret = sscanf(value, "%4095[^:]:%2[^:]:%i:%i:%i:%u:%u", name, type, &major, &minor, &filemode, &uid, &gid); ++ if (ret != 7) ++ return -1; ++ ++ /* find existing list element */ ++ lxc_list_for_each(iter, &lxc_conf->populate_devs) { ++ dev_elem = iter->elem; ++ ++ if (strcmp(name, dev_elem->name) != 0) ++ continue; ++ ++ replace_value = safe_strdup(type); ++ ++ free(dev_elem->type); ++ dev_elem->type = replace_value; ++ dev_elem->file_mode = filemode; ++ dev_elem->maj = major; ++ dev_elem->min = minor; ++ dev_elem->uid = (uid_t)uid; ++ dev_elem->gid = (gid_t)gid; ++ return 0; ++ } ++ ++ /* allocate list element */ ++ dev_list = malloc(sizeof(*dev_list)); ++ if (dev_list == NULL) ++ goto on_error; ++ ++ lxc_list_init(dev_list); ++ ++ dev_elem = malloc(sizeof(*dev_elem)); ++ if (dev_elem == NULL) ++ goto on_error; ++ memset(dev_elem, 0, sizeof(*dev_elem)); ++ ++ dev_elem->name = safe_strdup(name); ++ ++ dev_elem->type = safe_strdup(type); ++ ++ dev_elem->file_mode = filemode; ++ dev_elem->maj = major; ++ dev_elem->min = minor; ++ dev_elem->uid = (uid_t)uid; ++ dev_elem->gid = (gid_t)gid; ++ ++ lxc_list_add_elem(dev_list, dev_elem); ++ ++ lxc_list_add_tail(&lxc_conf->populate_devs, dev_list); + ++ return 0; ++ ++on_error: ++ free(dev_list); ++ if (dev_elem) { ++ free(dev_elem->name); ++ free(dev_elem->type); ++ free(dev_elem); ++ } ++ return -1; +} + - struct parse_line_conf { - struct lxc_conf *conf; - bool from_include; -@@ -3770,6 +3859,34 @@ static int get_config_init_args(const char *key, char *retv, int inlen, - return fulllen; - } - +/* isulad: get config populate device + * If you ask for 'lxc.populate.device', then all populate device + * entries will be printed, in 'lxc.populate.device = path_in_container:type:major:minor:mode:uid:gid' format. + * For e.g. lxc.populate.device = /dev/sda:b:8:0:0666:0:0 + */ +static int get_config_populate_device(const char *key, char *retv, int inlen, -+ struct lxc_conf *c, void *data) ++ struct lxc_conf *c, void *data) +{ + int len; -+ struct lxc_list *it; ++ struct lxc_list *it = NULL; + int fulllen = 0; + + if (!retv) @@ -376,31 +387,898 @@ index 7297b35..e3212d3 100644 + lxc_list_for_each(it, &c->populate_devs) { + struct lxc_populate_devs *elem = it->elem; + strprint(retv, inlen, "lxc.populate.device = %s:%s:%d:%d:%o:%u:%u\n", -+ elem->name, elem->type, elem->maj, -+ elem->min, elem->file_mode, elem->uid, elem->gid); ++ elem->name, elem->type, elem->maj, ++ elem->min, elem->file_mode, elem->uid, elem->gid); + } + + return fulllen; +} + -+ - /* Callbacks to clear config items. */ - static inline int clr_config_personality(const char *key, struct lxc_conf *c, - void *data) -@@ -4581,6 +4698,13 @@ static inline int clr_config_init_args(const char *key, struct lxc_conf *c, - return lxc_clear_init_args(c); - } - +/* isulad: clr config populate devices*/ +static inline int clr_config_populate_device(const char *key, struct lxc_conf *c, -+ void *data) ++ void *data) +{ + return lxc_clear_populate_devices(c); +} + - static int get_config_net_nic(const char *key, char *retv, int inlen, - struct lxc_conf *c, void *data) - { + #endif +diff --git a/src/lxc/isulad_utils.c b/src/lxc/isulad_utils.c +new file mode 100644 +index 0000000..b282404 +--- /dev/null ++++ b/src/lxc/isulad_utils.c +@@ -0,0 +1,99 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++/****************************************************************************** ++ * Copyright (c) Huawei Technologies Co., Ltd. 2020. Allrights reserved ++ * Description: isulad utils ++ * Author: lifeng ++ * Create: 2020-04-11 ++******************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "isulad_utils.h" ++#include "log.h" ++#include "path.h" ++#include "file_utils.h" ++ ++lxc_log_define(isulad_utils, lxc); ++ ++void *lxc_common_calloc_s(size_t size) ++{ ++ if (size == 0 || size > SIZE_MAX) { ++ return NULL; ++ } ++ ++ return calloc((size_t)1, size); ++} ++ ++int lxc_mem_realloc(void **newptr, size_t newsize, void *oldptr, size_t oldsize) ++{ ++ void *tmp = NULL; ++ ++ if (newsize == 0) { ++ goto err_out; ++ } ++ ++ tmp = lxc_common_calloc_s(newsize); ++ if (tmp == NULL) { ++ ERROR("Failed to malloc memory"); ++ goto err_out; ++ } ++ ++ if (oldptr != NULL) { ++ memcpy(tmp, oldptr, (newsize < oldsize) ? newsize : oldsize); ++ ++ memset(oldptr, 0, oldsize); ++ ++ free(oldptr); ++ } ++ ++ *newptr = tmp; ++ return 0; ++ ++err_out: ++ return -1; ++} ++ ++char *safe_strdup(const char *src) ++{ ++ char *dst = NULL; ++ ++ if (src == NULL) { ++ return NULL; ++ } ++ ++ dst = strdup(src); ++ if (dst == NULL) { ++ abort(); ++ } ++ ++ return dst; ++} ++ ++int lxc_open(const char *filename, int flags, mode_t mode) ++{ ++ char rpath[PATH_MAX] = {0x00}; ++ ++ if (cleanpath(filename, rpath, sizeof(rpath)) == NULL) { ++ return -1; ++ } ++ if (mode) { ++ return open(rpath, (int)((unsigned int)flags | O_CLOEXEC), mode); ++ } else { ++ return open(rpath, (int)((unsigned int)flags | O_CLOEXEC)); ++ } ++} ++ ++FILE *lxc_fopen(const char *filename, const char *mode) ++{ ++ char rpath[PATH_MAX] = {0x00}; ++ ++ if (cleanpath(filename, rpath, sizeof(rpath)) == NULL) { ++ return NULL; ++ } ++ ++ return fopen_cloexec(rpath, mode); ++} +diff --git a/src/lxc/isulad_utils.h b/src/lxc/isulad_utils.h +new file mode 100644 +index 0000000..7a6ab00 +--- /dev/null ++++ b/src/lxc/isulad_utils.h +@@ -0,0 +1,20 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++/****************************************************************************** ++ * Copyright (c) Huawei Technologies Co., Ltd. 2020. Allrights reserved ++ * Description: isulad utils ++ * Author: lifeng ++ * Create: 2020-04-11 ++******************************************************************************/ ++#ifndef __iSULAD_UTILS_H ++#define __iSULAD_UTILS_H ++ ++#include ++ ++extern int lxc_mem_realloc(void **newptr, size_t newsize, void *oldptr, size_t oldsize); ++extern void *lxc_common_calloc_s(size_t size); ++extern char *safe_strdup(const char *src); ++ ++extern int lxc_open(const char *filename, int flags, mode_t mode); ++extern FILE *lxc_fopen(const char *filename, const char *mode); ++ ++#endif +diff --git a/src/lxc/path.c b/src/lxc/path.c +new file mode 100644 +index 0000000..65b8aad +--- /dev/null ++++ b/src/lxc/path.c +@@ -0,0 +1,655 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++/****************************************************************************** ++ * Copyright (c) Huawei Technologies Co., Ltd. 2020. Allrights reserved ++ * Description: isulad utils ++ * Author: lifeng ++ * Create: 2020-04-11 ++******************************************************************************/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "path.h" ++#include "log.h" ++#include "isulad_utils.h" ++ ++lxc_log_define(lxc_path_ui, lxc); ++ ++#define ISSLASH(C) ((C) == '/') ++#define IS_ABSOLUTE_FILE_NAME(F) (ISSLASH ((F)[0])) ++#define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F)) ++ ++bool specify_current_dir(const char *path) ++{ ++ char *basec = NULL, *bname = NULL; ++ bool res = false; ++ ++ basec = safe_strdup(path); ++ ++ bname = basename(basec); ++ if (bname == NULL) { ++ free(basec); ++ ERROR("Out of memory"); ++ return false; ++ } ++ res = !strcmp(bname, "."); ++ free(basec); ++ return res; ++} ++ ++bool has_traling_path_separator(const char *path) ++{ ++ return path && strlen(path) && (path[strlen(path) - 1] == '/'); ++} ++ ++// PreserveTrailingDotOrSeparator returns the given cleaned path ++// and appends a trailing `/.` or `/` if its corresponding original ++// path ends with a trailing `/.` or `/`. If the cleaned ++// path already ends in a `.` path segment, then another is not added. If the ++// clean path already ends in a path separator, then another is not added. ++char *preserve_trailing_dot_or_separator(const char *cleanedpath, ++ const char *originalpath) ++{ ++ char *respath = NULL; ++ size_t len; ++ ++ if (strlen(cleanedpath) > (SIZE_MAX - 3)) { ++ return NULL; ++ } ++ ++ len = strlen(cleanedpath) + 3; ++ respath = malloc(len); ++ if (respath == NULL) { ++ ERROR("Out of memory"); ++ return NULL; ++ } ++ memset(respath, 0x00, len); ++ strcat(respath, cleanedpath); ++ ++ if (!specify_current_dir(cleanedpath) && specify_current_dir(originalpath)) { ++ if (!has_traling_path_separator(respath)) ++ strcat(respath, "/"); ++ strcat(respath, "."); ++ } ++ ++ if (!has_traling_path_separator(respath) && ++ has_traling_path_separator(originalpath)) ++ strcat(respath, "/"); ++ ++ return respath; ++} ++ ++ ++// Split splits path immediately following the final Separator, ++// separating it into a directory and file name component. ++// If there is no Separator in path, Split returns an empty dir ++// and file set to path. ++// The returned values have the property that path = dir+file. ++bool filepath_split(const char *path, char **dir, char **base) ++{ ++ ssize_t i; ++ size_t len; ++ ++ len = strlen(path); ++ if (len >= PATH_MAX) { ++ ERROR("Invalid path"); ++ return false; ++ } ++ i = len - 1; ++ while (i >= 0 && path[i] != '/') ++ i--; ++ ++ *dir = malloc(i + 2); ++ if (*dir == NULL) { ++ ERROR("Out of memory"); ++ return false; ++ } ++ memcpy(*dir, path, i + 1); ++ *(*dir + i + 1) = '\0'; ++ ++ *base = safe_strdup(path + i + 1); ++ ++ return true; ++} ++ ++ ++static bool do_clean_path_continue(const char *endpos, const char *stpos, const char *respath, char **dst) ++{ ++ if (endpos - stpos == 1 && stpos[0] == '.') { ++ return true; ++ } else if (endpos - stpos == 2 && stpos[0] == '.' && stpos[1] == '.') { ++ char *dest = *dst; ++ if (dest <= respath + 1) { ++ return true; ++ } ++ for (--dest; dest > respath && !ISSLASH(dest[-1]); --dest) { ++ *dst = dest; ++ return true; ++ } ++ *dst = dest; ++ return true; ++ } ++ return false; ++} ++ ++int do_clean_path(const char *respath, const char *limit_respath, ++ const char *stpos, char **dst) ++{ ++ char *dest = *dst; ++ const char *endpos = NULL; ++ ++ for (endpos = stpos; *stpos; stpos = endpos) { ++ while (ISSLASH(*stpos)) { ++ ++stpos; ++ } ++ ++ for (endpos = stpos; *endpos && !ISSLASH(*endpos); ++endpos) { ++ } ++ ++ if (endpos - stpos == 0) { ++ break; ++ } else if (do_clean_path_continue(endpos, stpos, respath, &dest)) { ++ continue; ++ } ++ ++ if (!ISSLASH(dest[-1])) { ++ *dest++ = '/'; ++ } ++ ++ if (dest + (endpos - stpos) >= limit_respath) { ++ ERROR("Path is too long"); ++ if (dest > respath + 1) { ++ dest--; ++ } ++ *dest = '\0'; ++ return -1; ++ } ++ ++ memcpy(dest, stpos, (size_t)(endpos - stpos)); ++ dest += endpos - stpos; ++ *dest = '\0'; ++ } ++ *dst = dest; ++ return 0; ++} ++ ++char *cleanpath(const char *path, char *realpath, size_t realpath_len) ++{ ++ char *respath = NULL; ++ char *dest = NULL; ++ const char *stpos = NULL; ++ const char *limit_respath = NULL; ++ ++ if (path == NULL || path[0] == '\0' || \ ++ realpath == NULL || (realpath_len < PATH_MAX)) { ++ return NULL; ++ } ++ ++ respath = realpath; ++ ++ memset(respath, 0, realpath_len); ++ limit_respath = respath + PATH_MAX; ++ ++ if (!IS_ABSOLUTE_FILE_NAME(path)) { ++ if (!getcwd(respath, PATH_MAX)) { ++ ERROR("Failed to getcwd"); ++ respath[0] = '\0'; ++ goto error; ++ } ++ dest = strchr(respath, '\0'); ++ if (dest == NULL) { ++ ERROR("Failed to get the end of respath"); ++ goto error; ++ } ++ if (strlen(path) > (PATH_MAX - strlen(respath) - 1)) { ++ ERROR("Path is too long"); ++ goto error; ++ } ++ strcat(respath, path); ++ stpos = path; ++ } else { ++ dest = respath; ++ *dest++ = '/'; ++ stpos = path; ++ } ++ ++ if (do_clean_path(respath, limit_respath, stpos, &dest)) { ++ goto error; ++ } ++ ++ if (dest > respath + 1 && ISSLASH(dest[-1])) { ++ --dest; ++ } ++ *dest = '\0'; ++ ++ return respath; ++ ++error: ++ return NULL; ++} ++ ++static int do_path_realloc(const char *start, const char *end, ++ char **rpath, char **dest, const char **rpath_limit) ++{ ++ long long dest_offset = *dest - *rpath; ++ char *new_rpath = NULL; ++ size_t new_size; ++ int nret = 0; ++ size_t gap = 0; ++ ++ if (*dest + (end - start) < *rpath_limit) { ++ return 0; ++ } ++ ++ gap = (size_t)(end - start) + 1; ++ new_size = (size_t)(*rpath_limit - *rpath); ++ if (new_size > SIZE_MAX - gap) { ++ ERROR("Out of range!"); ++ return -1; ++ } ++ ++ if (gap > PATH_MAX) { ++ new_size += gap; ++ } else { ++ new_size += PATH_MAX; ++ } ++ nret = lxc_mem_realloc((void **)&new_rpath, new_size, *rpath, PATH_MAX); ++ if (nret) { ++ ERROR("Failed to realloc memory for files limit variables"); ++ return -1; ++ } ++ *rpath = new_rpath; ++ *rpath_limit = *rpath + new_size; ++ ++ *dest = *rpath + dest_offset; ++ ++ return 0; ++} ++ ++static int do_get_symlinks_copy_buf(const char *buf, const char *prefix, size_t prefix_len, ++ char **rpath, char **dest) ++{ ++ if (IS_ABSOLUTE_FILE_NAME(buf)) { ++ if (prefix_len) { ++ memcpy(*rpath, prefix, prefix_len); ++ } ++ *dest = *rpath + prefix_len; ++ *(*dest)++ = '/'; ++ } else { ++ if (*dest > *rpath + prefix_len + 1) { ++ for (--(*dest); *dest > *rpath && !ISSLASH((*dest)[-1]); --(*dest)) { ++ continue; ++ } ++ } ++ } ++ return 0; ++} ++ ++static int do_get_symlinks(const char **fullpath, const char *prefix, size_t prefix_len, ++ char **rpath, char **dest, const char **end, ++ int *num_links, char **extra_buf) ++{ ++ char *buf = NULL; ++ size_t len; ++ ssize_t n; ++ int ret = -1; ++ ++ if (++(*num_links) > MAXSYMLINKS) { ++ ERROR("Too many links in '%s'", *fullpath); ++ goto out; ++ } ++ ++ buf = lxc_common_calloc_s(PATH_MAX); ++ if (buf == NULL) { ++ ERROR("Out of memory"); ++ goto out; ++ } ++ ++ n = readlink(*rpath, buf, PATH_MAX - 1); ++ if (n < 0) { ++ goto out; ++ } ++ buf[n] = '\0'; ++ ++ if (*extra_buf == NULL) { ++ *extra_buf = lxc_common_calloc_s(PATH_MAX); ++ if (*extra_buf == NULL) { ++ ERROR("Out of memory"); ++ goto out; ++ } ++ } ++ ++ len = strlen(*end); ++ if (len >= PATH_MAX - n) { ++ ERROR("Path is too long"); ++ goto out; ++ } ++ ++ memmove(&(*extra_buf)[n], *end, len + 1); ++ memcpy(*extra_buf, buf, (size_t)n); ++ ++ *fullpath = *end = *extra_buf; ++ ++ if (do_get_symlinks_copy_buf(buf, prefix, prefix_len, rpath, dest) != 0) { ++ goto out; ++ } ++ ++ ret = 0; ++out: ++ free(buf); ++ return ret; ++} ++ ++static bool do_eval_symlinks_in_scope_is_symlink(const char *path) ++{ ++ struct stat st; ++ ++ if (lstat(path, &st) < 0) { ++ return true; ++ } ++ ++ if (!S_ISLNK(st.st_mode)) { ++ return true; ++ } ++ return false; ++} ++ ++static void do_eval_symlinks_skip_slash(const char **start, const char **end) ++{ ++ while (ISSLASH(**start)) { ++ ++(*start); ++ } ++ ++ for (*end = *start; **end && !ISSLASH(**end); ++(*end)) { ++ } ++} ++ ++static inline void skip_dest_traling_slash(char **dest, char **rpath, size_t prefix_len) ++{ ++ if (*dest > *rpath + prefix_len + 1) { ++ for (--(*dest); *dest > *rpath && !ISSLASH((*dest)[-1]); --(*dest)) { ++ continue; ++ } ++ } ++} ++ ++static inline bool is_current_char(const char c) ++{ ++ return c == '.'; ++} ++ ++static inline bool is_specify_current(const char *end, const char *start) ++{ ++ return (end - start == 1) && is_current_char(start[0]); ++} ++ ++static inline bool is_specify_parent(const char *end, const char *start) ++{ ++ return (end - start == 2) && is_current_char(start[0]) && is_current_char(start[1]); ++} ++ ++static int do_eval_symlinks_in_scope(const char *fullpath, const char *prefix, ++ size_t prefix_len, ++ char **rpath, char **dest, const char *rpath_limit) ++{ ++ const char *start = NULL; ++ const char *end = NULL; ++ char *extra_buf = NULL; ++ int nret = 0; ++ int num_links = 0; ++ ++ start = fullpath + prefix_len; ++ for (end = start; *start; start = end) { ++ do_eval_symlinks_skip_slash(&start, &end); ++ if (end - start == 0) { ++ break; ++ } else if (is_specify_current(end, start)) { ++ ; ++ } else if (is_specify_parent(end, start)) { ++ skip_dest_traling_slash(dest, rpath, prefix_len); ++ } else { ++ if (!ISSLASH((*dest)[-1])) { ++ *(*dest)++ = '/'; ++ } ++ ++ nret = do_path_realloc(start, end, rpath, dest, &rpath_limit); ++ if (nret != 0) { ++ nret = -1; ++ goto out; ++ } ++ ++ memcpy(*dest, start, (size_t)(end - start)); ++ *dest += end - start; ++ **dest = '\0'; ++ ++ if (do_eval_symlinks_in_scope_is_symlink(*rpath)) { ++ continue; ++ } ++ ++ nret = do_get_symlinks(&fullpath, prefix, prefix_len, rpath, dest, &end, &num_links, &extra_buf); ++ if (nret != 0) { ++ nret = -1; ++ goto out; ++ } ++ } ++ } ++out: ++ free(extra_buf); ++ return nret; ++} ++static char *eval_symlinks_in_scope(const char *fullpath, const char *rootpath) ++{ ++ char resroot[PATH_MAX] = {0}; ++ char *root = NULL; ++ char *rpath = NULL; ++ char *dest = NULL; ++ char *prefix = NULL; ++ const char *rpath_limit = NULL; ++ size_t prefix_len; ++ ++ if (fullpath == NULL || rootpath == NULL) { ++ return NULL; ++ } ++ ++ root = cleanpath(rootpath, resroot, sizeof(resroot)); ++ if (root == NULL) { ++ ERROR("Failed to get cleaned path"); ++ return NULL; ++ } ++ ++ if (!strcmp(fullpath, root)) { ++ return safe_strdup(fullpath); ++ } ++ ++ if (strstr(fullpath, root) == NULL) { ++ ERROR("Path '%s' is not in '%s'", fullpath, root); ++ return NULL; ++ } ++ ++ rpath = lxc_common_calloc_s(PATH_MAX); ++ if (rpath == NULL) { ++ ERROR("Out of memory"); ++ goto out; ++ } ++ rpath_limit = rpath + PATH_MAX; ++ ++ prefix = root; ++ prefix_len = (size_t)strlen(prefix); ++ if (!strcmp(prefix, "/")) { ++ prefix_len = 0; ++ } ++ ++ dest = rpath; ++ if (prefix_len) { ++ memcpy(rpath, prefix, prefix_len); ++ dest += prefix_len; ++ } ++ *dest++ = '/'; ++ ++ if (do_eval_symlinks_in_scope(fullpath, prefix, prefix_len, &rpath, &dest, ++ rpath_limit)) { ++ goto out; ++ } ++ ++ if (dest > rpath + prefix_len + 1 && ISSLASH(dest[-1])) { ++ --dest; ++ } ++ *dest = '\0'; ++ return rpath; ++ ++out: ++ free(rpath); ++ return NULL; ++} ++ ++// FollowSymlinkInScope is a wrapper around evalSymlinksInScope that returns an ++// absolute path. This function handles paths in a platform-agnostic manner. ++char *follow_symlink_in_scope(const char *fullpath, const char *rootpath) ++{ ++ char resfull[PATH_MAX] = {0}, *full = NULL; ++ char resroot[PATH_MAX] = {0}, *root = NULL; ++ ++ full = cleanpath(fullpath, resfull, PATH_MAX); ++ if (!full) { ++ ERROR("Failed to get cleaned path"); ++ return NULL; ++ } ++ ++ root = cleanpath(rootpath, resroot, PATH_MAX); ++ if (!root) { ++ ERROR("Failed to get cleaned path"); ++ return NULL; ++ } ++ ++ return eval_symlinks_in_scope(full, root); ++} ++ ++// GetResourcePath evaluates `path` in the scope of the container's rootpath, with proper path ++// sanitisation. Symlinks are all scoped to the rootpath of the container, as ++// though the container's rootpath was `/`. ++// ++// The BaseFS of a container is the host-facing path which is bind-mounted as ++// `/` inside the container. This method is essentially used to access a ++// particular path inside the container as though you were a process in that ++// container. ++int get_resource_path(const char *rootpath, const char *path, ++ char **scopepath) ++{ ++ char resolved[PATH_MAX] = {0}, *cleanedpath = NULL; ++ char *fullpath = NULL; ++ size_t len; ++ ++ if (!rootpath || !path || !scopepath) ++ return -1; ++ ++ *scopepath = NULL; ++ ++ cleanedpath = cleanpath(path, resolved, PATH_MAX); ++ if (!cleanedpath) { ++ ERROR("Failed to get cleaned path"); ++ return -1; ++ } ++ ++ len = strlen(rootpath) + strlen(cleanedpath) + 1; ++ fullpath = malloc(len); ++ if (!fullpath) { ++ ERROR("Out of memory"); ++ return -1; ++ } ++ snprintf(fullpath, len, "%s%s", rootpath, cleanedpath); ++ ++ *scopepath = follow_symlink_in_scope(fullpath, rootpath); ++ ++ free(fullpath); ++ return 0; ++} ++ ++// Rel returns a relative path that is lexically equivalent to targpath when ++// joined to basepath with an intervening separator. That is, ++// Join(basepath, Rel(basepath, targpath)) is equivalent to targpath itself. ++// On success, the returned path will always be relative to basepath, ++// even if basepath and targpath share no elements. ++// An error is returned if targpath can't be made relative to basepath or if ++// knowing the current working directory would be necessary to compute it. ++// Rel calls Clean on the result. ++char *path_relative(const char *basepath, const char *targpath) ++{ ++ char resbase[PATH_MAX] = {0}, *base = NULL; ++ char restarg[PATH_MAX] = {0}, *targ = NULL; ++ size_t bl = 0, tl = 0, b0 = 0, bi = 0, t0 = 0, ti = 0; ++ ++ base = cleanpath(basepath, resbase, PATH_MAX); ++ if (!base) { ++ ERROR("Failed to get cleaned path"); ++ return NULL; ++ } ++ ++ targ = cleanpath(targpath, restarg, PATH_MAX); ++ if (!targ) { ++ ERROR("Failed to get cleaned path"); ++ return NULL; ++ } ++ ++ if (strcmp(base, targ) == 0) ++ return safe_strdup("."); ++ ++ bl = strlen(base); ++ tl = strlen(targ); ++ while(true) { ++ while(bi < bl && !ISSLASH(base[bi])) ++ bi++; ++ while(ti < tl && !ISSLASH(targ[ti])) ++ ti++; ++ //not the same string ++ if (((bi - b0) != (ti - t0)) || strncmp(base + b0, targ + t0, bi - b0)) ++ break; ++ if (bi < bl) ++ bi++; ++ if (ti < tl) ++ ti++; ++ b0 = bi; ++ t0 = ti; ++ } ++ ++ if (b0 != bl) { ++ // Base elements left. Must go up before going down. ++ int seps = 0, i; ++ size_t ncopyed = 0, seps_size; ++ char *buf = NULL; ++ ++ for (bi = b0; bi < bl; bi++) { ++ if (ISSLASH(base[bi])) ++ seps++; ++ } ++ //strlen(..) + strlen(/..) + '\0' ++ seps_size = 2 + seps * 3 + 1; ++ if (t0 != tl) ++ seps_size += 1 + tl - t0; ++ ++ buf = calloc(seps_size, 1); ++ if (!buf) { ++ ERROR("Out of memory"); ++ return NULL; ++ } ++ buf[ncopyed++] = '.'; ++ buf[ncopyed++] = '.'; ++ for (i = 0; i < seps; i++) { ++ buf[ncopyed++] = '/'; ++ buf[ncopyed++] = '.'; ++ buf[ncopyed++] = '.'; ++ } ++ if (t0 != tl) { ++ buf[ncopyed++] = '/'; ++ memcpy(buf + ncopyed, targ + t0, tl - t0 + 1); ++ } ++ return buf; ++ } ++ ++ return safe_strdup(targ + t0); ++} +diff --git a/src/lxc/path.h b/src/lxc/path.h +new file mode 100644 +index 0000000..2c60fb9 +--- /dev/null ++++ b/src/lxc/path.h +@@ -0,0 +1,65 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++/****************************************************************************** ++ * Copyright (c) Huawei Technologies Co., Ltd. 2020. Allrights reserved ++ * Description: isulad utils ++ * Author: lifeng ++ * Create: 2020-04-11 ++******************************************************************************/ ++#ifndef __ISULAD_PATH_H_ ++#define __ISULAD_PATH_H_ ++ ++#include ++ ++bool specify_current_dir(const char *path); ++ ++bool has_traling_path_separator(const char *path); ++ ++// PreserveTrailingDotOrSeparator returns the given cleaned path ++// and appends a trailing `/.` or `/` if its corresponding original ++// path ends with a trailing `/.` or `/`. If the cleaned ++// path already ends in a `.` path segment, then another is not added. If the ++// clean path already ends in a path separator, then another is not added. ++char *preserve_trailing_dot_or_separator(const char *cleanedpath, ++ const char *originalpath); ++ ++ ++// Split splits path immediately following the final Separator, ++// separating it into a directory and file name component. ++// If there is no Separator in path, Split returns an empty dir ++// and file set to path. ++// The returned values have the property that path = dir+file. ++bool filepath_split(const char *path, char **dir, char **base); ++ ++/* ++ * cleanpath is similar to realpath of glibc, but not expands symbolic links, ++ * and not check the existence of components of the path. ++ */ ++char *cleanpath(const char *path, char *realpath, size_t realpath_len); ++ ++ ++// FollowSymlinkInScope is a wrapper around evalSymlinksInScope that returns an ++// absolute path. This function handles paths in a platform-agnostic manner. ++char *follow_symlink_in_scope(const char *fullpath, const char *rootpath); ++ ++// GetResourcePath evaluates `path` in the scope of the container's rootpath, with proper path ++// sanitisation. Symlinks are all scoped to the rootpath of the container, as ++// though the container's rootpath was `/`. ++// ++// The BaseFS of a container is the host-facing path which is bind-mounted as ++// `/` inside the container. This method is essentially used to access a ++// particular path inside the container as though you were a process in that ++// container. ++int get_resource_path(const char *rootpath, const char *path, ++ char **scopepath); ++ ++// Rel returns a relative path that is lexically equivalent to targpath when ++// joined to basepath with an intervening separator. That is, ++// Join(basepath, Rel(basepath, targpath)) is equivalent to targpath itself. ++// On success, the returned path will always be relative to basepath, ++// even if basepath and targpath share no elements. ++// An error is returned if targpath can't be made relative to basepath or if ++// knowing the current working directory would be necessary to compute it. ++// Rel calls Clean on the result. ++char *path_relative(const char *basepath, const char *targpath); ++ ++#endif +diff --git a/src/lxc/utils.h b/src/lxc/utils.h +index 339217c..7b36133 100644 +--- a/src/lxc/utils.h ++++ b/src/lxc/utils.h +@@ -27,6 +27,9 @@ + #include "memory_utils.h" + #include "raw_syscalls.h" + #include "string_utils.h" ++#ifdef HAVE_ISULAD ++#include "isulad_utils.h" ++#endif + + /* returns 1 on success, 0 if there were any failures */ + extern int lxc_rmdir_onedev(const char *path, const char *exclude); -- 1.8.3.1 diff --git a/0057-confile-add-support-umask.patch b/0004-confile-add-support-umask.patch similarity index 49% rename from 0057-confile-add-support-umask.patch rename to 0004-confile-add-support-umask.patch index 58e513c990956d42f0a7e4c247404b69de32074b..bcea2b7c8484a580a8166751ebf5b3ff5a0b15bc 100644 --- a/0057-confile-add-support-umask.patch +++ b/0004-confile-add-support-umask.patch @@ -1,91 +1,93 @@ -From 5712305711a0f57d2d167b49da1093204abaffcd Mon Sep 17 00:00:00 2001 +From e1bf4afdac0f4e1c19ad24c7c9fb915ce72906ed Mon Sep 17 00:00:00 2001 From: LiFeng -Date: Wed, 30 Jan 2019 03:39:42 -0500 -Subject: [PATCH 057/140] confile: add support umask +Date: Sat, 11 Apr 2020 17:24:47 +0800 +Subject: [PATCH 04/49] confile: add support umask lxc.isulad.umask=normal make the container umask to 0022 lxc.isulad.umask=secure make the container umask to 0027 (default) Signed-off-by: LiFeng --- - src/lxc/attach.c | 4 ++-- - src/lxc/conf.c | 5 +++-- + src/lxc/attach.c | 5 +++++ + src/lxc/conf.c | 6 ++++++ src/lxc/conf.h | 1 + src/lxc/confile.c | 38 ++++++++++++++++++++++++++++++++++++++ - 4 files changed, 44 insertions(+), 4 deletions(-) + 4 files changed, 50 insertions(+) diff --git a/src/lxc/attach.c b/src/lxc/attach.c -index b44ea74..9768897 100644 +index 406b8ec..56d62ed 100644 --- a/src/lxc/attach.c +++ b/src/lxc/attach.c -@@ -768,8 +768,8 @@ static int attach_child_main(struct attach_clone_payload *payload) - msg_fd = init_ctx->container->lxc_conf->errpipe[1]; - init_ctx->container->lxc_conf->errpipe[1] = -1; +@@ -659,6 +659,11 @@ static int attach_child_main(struct attach_clone_payload *payload) + (options->attach_flags & LXC_ATTACH_LSM) && + init_ctx->lsm_label; -- /*isulad: set system umask 0027 for safe control */ -- umask(0027); -+ /*isulad: set system umask */ ++#ifdef HAVE_ISULAD ++ /*isulad: set system umask */ + umask(init_ctx->container->lxc_conf->umask); - - /*isulad: restore default signal handlers and unblock all signals*/ - for (i = 1; i < NSIG; i++) ++#endif ++ + /* A description of the purpose of this functionality is provided in the + * lxc-attach(1) manual page. We have to remount here and not in the + * parent process, otherwise /proc may not properly reflect the new pid diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 0c6aa28..67beefe 100644 +index e9c0a37..e3fce51 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c -@@ -3163,6 +3163,7 @@ struct lxc_conf *lxc_conf_init(void) - new->errmsg = NULL; - new->errpipe[0] = -1; - new->errpipe[1] = -1; +@@ -2567,6 +2567,7 @@ struct lxc_conf *lxc_conf_init(void) + #ifdef HAVE_ISULAD + /* isulad add begin */ + lxc_list_init(&new->populate_devs); + new->umask = 0027; /*default umask 0027*/ - /* isulad add end */ + #endif return new; -@@ -4216,8 +4217,8 @@ int lxc_setup(struct lxc_handler *handler) - } - } +@@ -3522,6 +3523,11 @@ int lxc_setup(struct lxc_handler *handler) + if (ret < 0) + return -1; -- /*isulad: set system umask 0027 for safe control*/ -- umask(0027); ++#ifdef HAVE_ISULAD + /*isulad: set system umask */ + umask(lxc_conf->umask); - ++#endif ++ ret = setup_personality(lxc_conf->personality); - if (ret < 0) { + if (ret < 0) + return log_error(-1, "Failed to set personality"); diff --git a/src/lxc/conf.h b/src/lxc/conf.h -index 88f5b41..93cf15d 100644 +index 452458c..7ed3cd0 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -427,6 +427,7 @@ struct lxc_conf { - char *errmsg; /* record error messages */ - int errpipe[2];//pipdfd for get error message of child or grandchild process. + /* populate devices*/ + struct lxc_list populate_devs; + mode_t umask; //umask value - /* isulad add end */ - }; + #endif + }; diff --git a/src/lxc/confile.c b/src/lxc/confile.c -index f66d01b..3940b32 100644 +index f0772f9..2df269a 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c -@@ -155,6 +155,7 @@ lxc_config_define(proc); - /*isulad add begin*/ +@@ -150,6 +150,7 @@ lxc_config_define(proc); + #ifdef HAVE_ISULAD lxc_config_define(init_args); lxc_config_define(populate_device); +lxc_config_define(umask); - /*isulad add end*/ + #endif - -@@ -247,6 +248,7 @@ static struct lxc_config_t config_jump_table[] = { + /* +@@ -266,6 +267,7 @@ static struct lxc_config_t config_jump_table[] = { + #ifdef HAVE_ISULAD + { "lxc.isulad.init.args", set_config_init_args, get_config_init_args, clr_config_init_args, }, { "lxc.isulad.populate.device", set_config_populate_device, get_config_populate_device, clr_config_populate_device, }, - { "lxc.isulad.rootfs.maskedpaths", set_config_rootfs_masked_paths, get_config_rootfs_masked_paths, clr_config_rootfs_masked_paths, }, - { "lxc.isulad.rootfs.ropaths", set_config_rootfs_ro_paths, get_config_rootfs_ro_paths, clr_config_rootfs_ro_paths, }, + { "lxc.isulad.umask", set_config_umask, get_config_umask, clr_config_umask, }, - /*isulad add end*/ + #endif }; -@@ -2371,6 +2373,27 @@ on_error: - +@@ -6273,4 +6275,40 @@ static inline int clr_config_populate_device(const char *key, struct lxc_conf *c + return lxc_clear_populate_devices(c); } +/* isulad: set config for umask */ @@ -109,13 +111,6 @@ index f66d01b..3940b32 100644 + } +} + - struct parse_line_conf { - struct lxc_conf *conf; - bool from_include; -@@ -3141,6 +3164,13 @@ static int get_config_tty_max(const char *key, char *retv, int inlen, - return lxc_get_conf_size_t(c, retv, inlen, c->ttys.max); - } - +/* isulad add: get umask value*/ +static int get_config_umask(const char *key, char *retv, int inlen, + struct lxc_conf *c, void *data) @@ -123,13 +118,6 @@ index f66d01b..3940b32 100644 + return lxc_get_conf_size_t(c, retv, inlen, c->umask); +} + - static int get_config_tty_dir(const char *key, char *retv, int inlen, - struct lxc_conf *c, void *data) - { -@@ -4396,6 +4426,14 @@ static int clr_config_namespace_share(const char *key, - return 0; - } - +/* isulad add: clear umask value */ +static inline int clr_config_umask(const char *key, struct lxc_conf *c, + void *data) @@ -138,9 +126,7 @@ index f66d01b..3940b32 100644 + return 0; +} + - static int get_config_includefiles(const char *key, char *retv, int inlen, - struct lxc_conf *c, void *data) - { + #endif -- 1.8.3.1 diff --git a/0004-support-isulad-fifo-log.patch b/0004-support-isulad-fifo-log.patch deleted file mode 100644 index 9dbb2cce17639de7c28489a8fc7031eae78653bd..0000000000000000000000000000000000000000 --- a/0004-support-isulad-fifo-log.patch +++ /dev/null @@ -1,96 +0,0 @@ -From f83ae83808419f6742265b8bafc3441fdca65cbb Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Fri, 11 Jan 2019 16:11:34 +0800 -Subject: [PATCH 004/140] support isulad fifo log - -support isulad fifo log in lxc3.0 - -Signed-off-by: LiFeng ---- - src/lxc/log.c | 42 ++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 40 insertions(+), 2 deletions(-) - -diff --git a/src/lxc/log.c b/src/lxc/log.c -index 1e0cc6a..4e74459 100644 ---- a/src/lxc/log.c -+++ b/src/lxc/log.c -@@ -68,6 +68,7 @@ static int syslog_enable = 0; - int lxc_quiet_specified; - int lxc_log_use_global_fd; - static int lxc_loglevel_specified; -+static bool isulad_use_log_fifo_flag = false; - - static char log_prefix[LXC_LOG_PREFIX_SIZE] = "lxc"; - static char *log_fname = NULL; -@@ -138,6 +139,37 @@ static char *lxc_log_get_va_msg(struct lxc_log_event *event) - return msg; - } - -+static const char *isulad_use_log_fifo(const char *file) -+{ -+#define ISULAD_FIFO_PREFIX "fifo:" -+ -+ if (strncmp(file, ISULAD_FIFO_PREFIX, strlen(ISULAD_FIFO_PREFIX)) == 0) { -+ isulad_use_log_fifo_flag = true; -+ return (file + strlen(ISULAD_FIFO_PREFIX)); -+ } -+ return file; -+} -+ -+static int isulad_open_fifo(const char *file_path) -+{ -+#define LOG_FIFO_SIZE (1024 * 1024) -+ int fd = -1; -+ -+ fd = lxc_unpriv(open(file_path, O_RDWR | O_NONBLOCK | O_CLOEXEC, 0640)); -+ if (fd == -1) { -+ fprintf(stderr, "Open fifo %s failed: %s\n", file_path, strerror(errno)); -+ return -1; -+ } -+ -+ if (fcntl(fd, F_SETPIPE_SZ, LOG_FIFO_SIZE) == -1) { -+ printf("Set fifo buffer size failed: %s", strerror(errno)); -+ close(fd); -+ return -1; -+ } -+ -+ return fd; -+} -+ - /*---------------------------------------------------------------------------*/ - static int log_append_syslog(const struct lxc_log_appender *appender, - struct lxc_log_event *event) -@@ -609,7 +641,11 @@ static int __lxc_log_set_file(const char *fname, int create_dirs) - return -1; - } - -- lxc_log_fd = log_open(fname); -+ if (isulad_use_log_fifo_flag) { -+ lxc_log_fd = isulad_open_fifo(fname); -+ } else { -+ lxc_log_fd = log_open(fname); -+ } - if (lxc_log_fd == -1) - return -1; - -@@ -642,6 +678,7 @@ int lxc_log_init(struct lxc_log *log) - { - int ret; - int lxc_priority = LXC_LOG_LEVEL_ERROR; -+ const char *tmp_log_fname; - - if (!log) - return -1; -@@ -673,7 +710,8 @@ int lxc_log_init(struct lxc_log *log) - if (strcmp(log->file, "none") == 0) - return 0; - -- ret = __lxc_log_set_file(log->file, 1); -+ tmp_log_fname = isulad_use_log_fifo(log->file); -+ ret = __lxc_log_set_file(tmp_log_fname, 1); - if (ret < 0) { - ERROR("Failed to enable logfile"); - return -1; --- -1.8.3.1 - diff --git a/0005-auto-mount-cgroup-sys-and-proc.patch b/0005-auto-mount-cgroup-sys-and-proc.patch deleted file mode 100644 index eee484bb911a732a7c1d8263194a1df4dccc0254..0000000000000000000000000000000000000000 --- a/0005-auto-mount-cgroup-sys-and-proc.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 7cb675179d84838d751312fb675c442325413270 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Thu, 10 Jan 2019 20:40:19 +0800 -Subject: [PATCH 005/140] auto mount cgroup sys and proc - -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgfsng.c | 8 ++++++-- - src/lxc/conf.c | 15 ++++++++++++--- - 2 files changed, 18 insertions(+), 5 deletions(-) - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index acc6c30..aff2b5e 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -1648,6 +1648,10 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, - - /* Mount tmpfs */ - tmpfspath = must_make_path(root, "/sys/fs/cgroup", NULL); -+ if (mkdir_p(tmpfspath, 0755) < 0) { -+ ERROR("Failed to create directory: %s", tmpfspath); -+ goto on_error; -+ } - ret = safe_mount(NULL, tmpfspath, "tmpfs", - MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME, - "size=10240k,mode=755", root); -@@ -1700,8 +1704,8 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, - continue; - } - -- path2 = must_make_path(controllerpath, h->container_base_path, -- ops->container_cgroup, NULL); -+ // Ignore ops->container_cgroup so we will not see directory lxc after /sys/fs/cgroup/xxx in container -+ path2 = must_make_path(controllerpath, h->container_base_path, NULL); - ret = mkdir_p(path2, 0755); - if (ret < 0) { - free(controllerpath); -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 20b7aba..18753d1 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -670,8 +670,8 @@ static int lxc_mount_auto_mounts(struct lxc_conf *conf, int flags, struct lxc_ha - { LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED, "%r/proc/sysrq-trigger", "%r/proc/sysrq-trigger", NULL, MS_BIND, NULL }, - { LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED, NULL, "%r/proc/sysrq-trigger", NULL, MS_REMOUNT|MS_BIND|MS_RDONLY, NULL }, - { LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_RW, "proc", "%r/proc", "proc", MS_NODEV|MS_NOEXEC|MS_NOSUID, NULL }, -- { LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RW, "sysfs", "%r/sys", "sysfs", 0, NULL }, -- { LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RO, "sysfs", "%r/sys", "sysfs", MS_RDONLY, NULL }, -+ { LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RW, "sysfs", "%r/sys", "sysfs", MS_NODEV|MS_NOEXEC|MS_NOSUID, NULL }, -+ { LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RO, "sysfs", "%r/sys", "sysfs", MS_RDONLY|MS_NODEV|MS_NOEXEC|MS_NOSUID, NULL }, - { LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED, "sysfs", "%r/sys", "sysfs", MS_NODEV|MS_NOEXEC|MS_NOSUID, NULL }, - { LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED, NULL, "%r/sys", NULL, MS_REMOUNT|MS_BIND|MS_RDONLY, NULL }, - { LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED, "sysfs", "%r/sys/devices/virtual/net", "sysfs", 0, NULL }, -@@ -710,6 +710,15 @@ static int lxc_mount_auto_mounts(struct lxc_conf *conf, int flags, struct lxc_ha - return -1; - } - -+ if (mkdir_p(destination, 0755) < 0) { -+ SYSERROR("Failed to create mount target '%s'", destination); -+ saved_errno = errno; -+ free(source); -+ free(destination); -+ errno = saved_errno; -+ return -1; -+ } -+ - mflags = add_required_remount_flags(source, destination, - default_mounts[i].flags); - r = safe_mount(source, destination, default_mounts[i].fstype, -@@ -717,7 +726,7 @@ static int lxc_mount_auto_mounts(struct lxc_conf *conf, int flags, struct lxc_ha - conf->rootfs.path ? conf->rootfs.mount : NULL); - saved_errno = errno; - if (r < 0 && errno == ENOENT) { -- INFO("Mount source or target for \"%s\" on \"%s\" does " -+ INFO("Mount source for \"%s\" on \"%s\" does " - "not exist. Skipping", source, destination); - r = 0; - } else if (r < 0) { --- -1.8.3.1 - diff --git a/0005-cgroup-refact-cgroup-implemt.patch b/0005-cgroup-refact-cgroup-implemt.patch new file mode 100644 index 0000000000000000000000000000000000000000..0f4426e105e80ec50ab6cdaa4cc857288357721f --- /dev/null +++ b/0005-cgroup-refact-cgroup-implemt.patch @@ -0,0 +1,1149 @@ +From 41bc2b03f1c143352b025432a955e6a6dafd0e91 Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Sat, 11 Apr 2020 19:16:42 +0800 +Subject: [PATCH 05/49] cgroup: refact cgroup implemt + +Signed-off-by: LiFeng +--- + src/lxc/cgroups/cgfsng.c | 816 ++++++++++++++++++++++++++++++++++++++++++++++- + src/lxc/cgroups/cgroup.c | 4 +- + src/lxc/cgroups/cgroup.h | 9 +- + src/lxc/conf.c | 12 + + src/lxc/utils.c | 30 +- + src/lxc/utils.h | 4 + + 6 files changed, 869 insertions(+), 6 deletions(-) + +diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c +index d3595bc..881dd39 100644 +--- a/src/lxc/cgroups/cgfsng.c ++++ b/src/lxc/cgroups/cgfsng.c +@@ -1045,6 +1045,13 @@ __cgfsng_ops static void cgfsng_payload_destroy(struct cgroup_ops *ops, + SYSWARN("Failed to destroy cgroups"); + } + ++#ifdef HAVE_ISULAD ++__cgfsng_ops static void cgfsng_monitor_destroy(struct cgroup_ops *ops, ++ struct lxc_handler *handler) ++{ ++ return; ++} ++#else + __cgfsng_ops static void cgfsng_monitor_destroy(struct cgroup_ops *ops, + struct lxc_handler *handler) + { +@@ -1117,6 +1124,7 @@ try_lxc_rm_rf: + WARN("Failed to destroy \"%s\"", h->monitor_full_path); + } + } ++#endif + + static int mkdir_eexist_on_last(const char *dir, mode_t mode) + { +@@ -1202,6 +1210,13 @@ static void cgroup_tree_leaf_remove(struct hierarchy *h, bool payload) + SYSWARN("Failed to rmdir(\"%s\") cgroup", full_path); + } + ++#ifdef HAVE_ISULAD ++__cgfsng_ops static inline bool cgfsng_monitor_create(struct cgroup_ops *ops, ++ struct lxc_handler *handler) ++{ ++ return true; ++} ++#else + __cgfsng_ops static inline bool cgfsng_monitor_create(struct cgroup_ops *ops, + struct lxc_handler *handler) + { +@@ -1276,7 +1291,227 @@ __cgfsng_ops static inline bool cgfsng_monitor_create(struct cgroup_ops *ops, + ops->monitor_cgroup = move_ptr(monitor_cgroup); + return log_info(true, "The monitor process uses \"%s\" as cgroup", ops->monitor_cgroup); + } ++#endif ++ ++#ifdef HAVE_ISULAD ++ ++static bool isulad_copy_parent_file(char *path, char *file) ++{ ++ int ret; ++ int len = 0; ++ char *value = NULL; ++ char *current = NULL; ++ char *fpath = NULL; ++ char *lastslash = NULL; ++ char oldv; ++ ++ fpath = must_make_path(path, file, NULL); ++ current = read_file(fpath); ++ ++ if (current == NULL) { ++ SYSERROR("Failed to read file \"%s\"", fpath); ++ free(fpath); ++ return false; ++ } ++ ++ if (strcmp(current, "\n") != 0) { ++ free(fpath); ++ free(current); ++ return true; ++ } ++ ++ free(fpath); ++ free(current); ++ ++ lastslash = strrchr(path, '/'); ++ if (lastslash == NULL) { ++ ERROR("Failed to detect \"/\" in \"%s\"", path); ++ return false; ++ } ++ oldv = *lastslash; ++ *lastslash = '\0'; ++ fpath = must_make_path(path, file, NULL); ++ *lastslash = oldv; ++ len = lxc_read_from_file(fpath, NULL, 0); ++ if (len <= 0) ++ goto on_error; ++ ++ value = must_realloc(NULL, len + 1); ++ ret = lxc_read_from_file(fpath, value, len); ++ if (ret != len) ++ goto on_error; ++ free(fpath); ++ ++ fpath = must_make_path(path, file, NULL); ++ ret = lxc_write_to_file(fpath, value, len, false, 0666); ++ if (ret < 0) ++ SYSERROR("Failed to write \"%s\" to file \"%s\"", value, fpath); ++ free(fpath); ++ free(value); ++ return ret >= 0; ++ ++on_error: ++ SYSERROR("Failed to read file \"%s\"", fpath); ++ free(fpath); ++ free(value); ++ return false; ++} ++ ++static bool build_sub_cpuset_cgroup_dir(char *cgpath) ++{ ++ int ret; ++ ++ ret = mkdir_p(cgpath, 0755); ++ if (ret < 0) { ++ if (errno != EEXIST) { ++ SYSERROR("Failed to create directory \"%s\"", cgpath); ++ return false; ++ } ++ } ++ ++ /* copy parent's settings */ ++ if (!isulad_copy_parent_file(cgpath, "cpuset.cpus")) { ++ SYSERROR("Failed to copy \"cpuset.cpus\" settings"); ++ return false; ++ } ++ ++ /* copy parent's settings */ ++ if (!isulad_copy_parent_file(cgpath, "cpuset.mems")) { ++ SYSERROR("Failed to copy \"cpuset.mems\" settings"); ++ return false; ++ } ++ ++ return true; ++} ++ ++static bool isulad_cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname) ++{ ++ char *cgpath, *slash; ++ bool sub_mk_success = false; ++ ++ if (!string_in_list(h->controllers, "cpuset")) ++ return true; ++ ++ cgname += strspn(cgname, "/"); ++ ++ slash = strchr(cgname, '/'); ++ ++ if (slash != NULL) { ++ while (slash) { ++ *slash = '\0'; ++ cgpath = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL); ++ sub_mk_success = build_sub_cpuset_cgroup_dir(cgpath); ++ free(cgpath); ++ *slash = '/'; ++ if (!sub_mk_success) { ++ return false; ++ } ++ slash = strchr(slash + 1, '/'); ++ } ++ } ++ ++ cgpath = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL); ++ sub_mk_success = build_sub_cpuset_cgroup_dir(cgpath); ++ free(cgpath); ++ if (!sub_mk_success) { ++ return false; ++ } ++ ++ return true; ++} ++ ++static int isulad_mkdir_eexist_on_last(const char *dir, mode_t mode) ++{ ++ const char *tmp = dir; ++ const char *orig = dir; ++ ++ do { ++ int ret; ++ size_t cur_len; ++ char *makeme; ++ ++ dir = tmp + strspn(tmp, "/"); ++ tmp = dir + strcspn(dir, "/"); ++ ++ errno = ENOMEM; ++ cur_len = dir - orig; ++ makeme = strndup(orig, cur_len); ++ if (!makeme) ++ return -1; ++ ++ ret = mkdir(makeme, mode); ++ if (ret < 0) { ++ if (errno != EEXIST) { ++ SYSERROR("Failed to create directory \"%s\"", makeme); ++ free(makeme); ++ return -1; ++ } ++ } ++ free(makeme); ++ ++ } while (tmp != dir); ++ ++ return 0; ++} ++ ++static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname, int errfd) ++{ ++ int ret; ++ __do_free char *path = NULL; ++ ++ path = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL); ++ ++ if (file_exists(path)) { // it must not already exist ++ ERROR("Cgroup path \"%s\" already exist.", path); ++ lxc_write_error_message(errfd, "%s:%d: Cgroup path \"%s\" already exist.", ++ __FILE__, __LINE__, path); ++ return false; ++ } ++ ++ if (!isulad_cg_legacy_handle_cpuset_hierarchy(h, cgname)) { ++ ERROR("Failed to handle legacy cpuset controller"); ++ return false; ++ } ++ ++ ret = isulad_mkdir_eexist_on_last(path, 0755); ++ if (ret < 0) { ++ ERROR("Failed to create cgroup \"%s\"", path); ++ return false; ++ } ++ ++ h->cgfd_con = lxc_open_dirfd(path); ++ if (h->cgfd_con < 0) ++ return log_error_errno(false, errno, "Failed to open %s", path); ++ ++ if (h->container_full_path == NULL) { ++ h->container_full_path = move_ptr(path); ++ } ++ ++ return true; ++} + ++/* isulad: create hierarchies path, if fail, return the error */ ++__cgfsng_ops static inline bool cgfsng_payload_create(struct cgroup_ops *ops, ++ struct lxc_handler *handler) ++{ ++ int i; ++ char *container_cgroup = ops->container_cgroup; ++ ++ if (!container_cgroup) { ++ ERROR("cgfsng_create container_cgroup is invalid"); ++ return false; ++ } ++ ++ for (i = 0; ops->hierarchies[i]; i++) { ++ if (!create_path_for_hierarchy(ops->hierarchies[i], container_cgroup, ops->errfd)) { ++ SYSERROR("Failed to create %s", ops->hierarchies[i]->container_full_path); ++ return false; ++ } ++ } ++ ++ return true; ++} ++#else + /* + * Try to create the same cgroup in all hierarchies. Start with cgroup_pattern; + * next cgroup_pattern-1, -2, ..., -999. +@@ -1356,7 +1591,15 @@ __cgfsng_ops static inline bool cgfsng_payload_create(struct cgroup_ops *ops, + INFO("The container process uses \"%s\" as cgroup", ops->container_cgroup); + return true; + } ++#endif + ++#ifdef HAVE_ISULAD ++__cgfsng_ops static bool cgfsng_monitor_enter(struct cgroup_ops *ops, ++ struct lxc_handler *handler) ++{ ++ return true; ++} ++#else + __cgfsng_ops static bool cgfsng_monitor_enter(struct cgroup_ops *ops, + struct lxc_handler *handler) + { +@@ -1408,7 +1651,58 @@ __cgfsng_ops static bool cgfsng_monitor_enter(struct cgroup_ops *ops, + + return true; + } ++#endif ++ ++#ifdef HAVE_ISULAD ++__cgfsng_ops static bool cgfsng_payload_enter(struct cgroup_ops *ops, ++ struct lxc_handler *handler) ++{ ++ int len; ++ char pidstr[INTTYPE_TO_STRLEN(pid_t)]; ++ ++ if (!ops) ++ return ret_set_errno(false, ENOENT); ++ ++ if (!ops->hierarchies) ++ return true; ++ ++ if (!ops->container_cgroup) ++ return ret_set_errno(false, ENOENT); ++ ++ if (!handler || !handler->conf) ++ return ret_set_errno(false, EINVAL); ++ ++ len = snprintf(pidstr, sizeof(pidstr), "%d", handler->pid); ++ ++ for (int i = 0; ops->hierarchies[i]; i++) { ++ int ret; ++ char *fullpath; ++ int retry_count = 0; ++ int max_retry = 10; + ++ fullpath = must_make_path(ops->hierarchies[i]->container_full_path, ++ "cgroup.procs", NULL); ++retry: ++ ret = lxc_write_to_file(fullpath, pidstr, len, false, 0666); ++ if (ret != 0) { ++ if (retry_count < max_retry) { ++ SYSERROR("Failed to enter cgroup \"%s\" with retry count:%d", fullpath, retry_count); ++ (void)isulad_cg_legacy_handle_cpuset_hierarchy(ops->hierarchies[i], ops->container_cgroup); ++ (void)isulad_mkdir_eexist_on_last(ops->hierarchies[i]->container_full_path, 0755); ++ usleep(100 * 1000); /* 100 millisecond */ ++ retry_count++; ++ goto retry; ++ } ++ SYSERROR("Failed to enter cgroup \"%s\"", fullpath); ++ free(fullpath); ++ return false; ++ } ++ free(fullpath); ++ } ++ ++ return true; ++} ++#else + __cgfsng_ops static bool cgfsng_payload_enter(struct cgroup_ops *ops, + struct lxc_handler *handler) + { +@@ -1440,6 +1734,7 @@ __cgfsng_ops static bool cgfsng_payload_enter(struct cgroup_ops *ops, + + return true; + } ++#endif + + static int fchowmodat(int dirfd, const char *path, uid_t chown_uid, + gid_t chown_gid, mode_t chmod_mode) +@@ -1687,6 +1982,167 @@ static inline int cg_mount_cgroup_full(int type, struct hierarchy *h, + return __cg_mount_direct(type, h, controllerpath); + } + ++#ifdef HAVE_ISULAD ++__cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, ++ struct lxc_handler *handler, ++ const char *root, int type) ++{ ++ int i, ret; ++ char *tmpfspath = NULL; ++ bool has_cgns = false, retval = false, wants_force_mount = false; ++ char **merged = NULL; ++ ++ if ((type & LXC_AUTO_CGROUP_MASK) == 0) ++ return true; ++ ++ if (type & LXC_AUTO_CGROUP_FORCE) { ++ type &= ~LXC_AUTO_CGROUP_FORCE; ++ wants_force_mount = true; ++ } ++ ++ if (!wants_force_mount) { ++ if (!lxc_list_empty(&handler->conf->keepcaps)) ++ wants_force_mount = !in_caplist(CAP_SYS_ADMIN, &handler->conf->keepcaps); ++ else ++ wants_force_mount = in_caplist(CAP_SYS_ADMIN, &handler->conf->caps); ++ } ++ ++ has_cgns = cgns_supported(); ++ if (has_cgns && !wants_force_mount) ++ return true; ++ ++ if (type == LXC_AUTO_CGROUP_NOSPEC) ++ type = LXC_AUTO_CGROUP_MIXED; ++ else if (type == LXC_AUTO_CGROUP_FULL_NOSPEC) ++ type = LXC_AUTO_CGROUP_FULL_MIXED; ++ ++ /* Mount tmpfs */ ++ tmpfspath = must_make_path(root, "/sys/fs/cgroup", NULL); ++ if (mkdir_p(tmpfspath, 0755) < 0) { ++ ERROR("Failed to create directory: %s", tmpfspath); ++ goto on_error; ++ } ++ ret = safe_mount(NULL, tmpfspath, "tmpfs", ++ MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME, ++ "size=10240k,mode=755", root); ++ if (ret < 0) ++ goto on_error; ++ ++ for (i = 0; ops->hierarchies[i]; i++) { ++ char *controllerpath = NULL; ++ char *path2 = NULL; ++ struct hierarchy *h = ops->hierarchies[i]; ++ char *controller = strrchr(h->mountpoint, '/'); ++ ++ if (!controller) ++ continue; ++ controller++; ++ ++ // isulad: symlink subcgroup ++ if (strchr(controller, ',') != NULL) { ++ int pret; ++ pret = lxc_append_string(&merged, controller); ++ if (pret < 0) ++ goto on_error; ++ } ++ ++ controllerpath = must_make_path(tmpfspath, controller, NULL); ++ if (dir_exists(controllerpath)) { ++ free(controllerpath); ++ continue; ++ } ++ ++ ret = mkdir(controllerpath, 0755); ++ if (ret < 0) { ++ SYSERROR("Error creating cgroup path: %s", controllerpath); ++ free(controllerpath); ++ goto on_error; ++ } ++ ++ if (has_cgns && wants_force_mount) { ++ /* If cgroup namespaces are supported but the container ++ * will not have CAP_SYS_ADMIN after it has started we ++ * need to mount the cgroups manually. ++ */ ++ ret = cg_mount_in_cgroup_namespace(type, h, controllerpath); ++ free(controllerpath); ++ if (ret < 0) ++ goto on_error; ++ ++ continue; ++ } ++ ++ ret = cg_mount_cgroup_full(type, h, controllerpath); ++ if (ret < 0) { ++ free(controllerpath); ++ goto on_error; ++ } ++ ++ if (!cg_mount_needs_subdirs(type)) { ++ free(controllerpath); ++ continue; ++ } ++ ++ // isulad: ignore ops->container_cgroup so we will not see directory lxc after /sys/fs/cgroup/xxx in container, ++ // isulad: ignore h->container_base_path so we will not see subgroup of /sys/fs/cgroup/xxx/subgroup in container ++ path2 = must_make_path(controllerpath, NULL); ++ ret = mkdir_p(path2, 0755); ++ if (ret < 0) { ++ free(controllerpath); ++ free(path2); ++ goto on_error; ++ } ++ ++ ret = cg_legacy_mount_controllers(type, h, controllerpath, ++ path2, ops->container_cgroup); ++ free(controllerpath); ++ free(path2); ++ if (ret < 0) ++ goto on_error; ++ } ++ ++ // isulad: symlink subcgroup ++ if (merged) { ++ char **mc = NULL; ++ for (mc = merged; *mc; mc++) { ++ char *token = NULL; ++ char *copy = must_copy_string(*mc); ++ lxc_iterate_parts(token, copy, ",") { ++ int mret; ++ char *link; ++ link = must_make_path(tmpfspath, token, NULL); ++ mret = symlink(*mc, link); ++ if (mret < 0 && errno != EEXIST) { ++ SYSERROR("Failed to create link %s for target %s", link, *mc); ++ free(copy); ++ free(link); ++ goto on_error; ++ } ++ free(link); ++ } ++ free(copy); ++ } ++ } ++ ++ ++ // isulad: remount /sys/fs/cgroup to readonly ++ if (type == LXC_AUTO_CGROUP_FULL_RO || type == LXC_AUTO_CGROUP_RO) { ++ ret = mount(tmpfspath, tmpfspath, "bind", ++ MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_RELATIME|MS_RDONLY|MS_BIND|MS_REMOUNT, NULL); ++ if (ret < 0) { ++ SYSERROR("Failed to remount /sys/fs/cgroup."); ++ goto on_error; ++ } ++ } ++ ++ retval = true; ++ ++on_error: ++ free(tmpfspath); ++ lxc_free_array((void **)merged, free); ++ return retval; ++} ++#else + __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, + struct lxc_handler *handler, + const char *root, int type) +@@ -1799,6 +2255,7 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, + + return true; + } ++#endif + + /* Only root needs to escape to the cgroup of its init. */ + __cgfsng_ops static bool cgfsng_escape(const struct cgroup_ops *ops, +@@ -2054,6 +2511,24 @@ __cgfsng_ops static const char *cgfsng_get_cgroup(struct cgroup_ops *ops, + : NULL; + } + ++#ifdef HAVE_ISULAD ++__cgfsng_ops static const char *cgfsng_get_cgroup_full_path(struct cgroup_ops *ops, ++ const char *controller) ++{ ++ struct hierarchy *h; ++ ++ h = get_hierarchy(ops, controller); ++ if (!h) ++ return log_warn_errno(NULL, ENOENT, "Failed to find hierarchy for controller \"%s\"", ++ controller ? controller : "(null)"); ++ ++ if (!h->container_full_path) ++ h->container_full_path = must_make_path(h->mountpoint, h->container_base_path, ops->container_cgroup, NULL); ++ ++ return h->container_full_path; ++} ++#endif ++ + /* Given a cgroup path returned from lxc_cmd_get_cgroup_path, build a full path, + * which must be freed by the caller. + */ +@@ -2360,6 +2835,44 @@ __cgfsng_ops static bool cgfsng_attach(struct cgroup_ops *ops, + return true; + } + ++#ifdef HAVE_ISULAD ++__cgfsng_ops static int cgfsng_get(struct cgroup_ops *ops, const char *filename, ++ char *value, size_t len, const char *name, ++ const char *lxcpath) ++{ ++ int ret = -1; ++ size_t controller_len; ++ char *controller, *p, *path; ++ struct hierarchy *h; ++ ++ controller_len = strlen(filename); ++ controller = alloca(controller_len + 1); ++ (void)strlcpy(controller, filename, controller_len + 1); ++ ++ p = strchr(controller, '.'); ++ if (p) ++ *p = '\0'; ++ ++ const char *ori_path = ops->get_cgroup(ops, controller); ++ if (ori_path == NULL) { ++ ERROR("Failed to get cgroup path:%s", controller); ++ return -1; ++ } ++ path = safe_strdup(ori_path); ++ ++ h = get_hierarchy(ops, controller); ++ if (h) { ++ char *fullpath; ++ ++ fullpath = build_full_cgpath_from_monitorpath(h, path, filename); ++ ret = lxc_read_from_file(fullpath, value, len); ++ free(fullpath); ++ } ++ free(path); ++ ++ return ret; ++} ++#else + /* Called externally (i.e. from 'lxc-cgroup') to query cgroup limits. Here we + * don't have a cgroup_data set up, so we ask the running container through the + * commands API for the cgroup path. +@@ -2397,6 +2910,7 @@ __cgfsng_ops static int cgfsng_get(struct cgroup_ops *ops, const char *filename, + + return ret; + } ++#endif + + static int device_cgroup_parse_access(struct device_item *device, const char *val) + { +@@ -2510,6 +3024,44 @@ static int device_cgroup_rule_parse(struct device_item *device, const char *key, + return device_cgroup_parse_access(device, ++val); + } + ++#ifdef HAVE_ISULAD ++__cgfsng_ops static int cgfsng_set(struct cgroup_ops *ops, ++ const char *filename, const char *value, ++ const char *name, const char *lxcpath) ++{ ++ int ret = -1; ++ size_t controller_len; ++ char *controller, *p, *path; ++ struct hierarchy *h; ++ ++ controller_len = strlen(filename); ++ controller = alloca(controller_len + 1); ++ (void)strlcpy(controller, filename, controller_len + 1); ++ ++ p = strchr(controller, '.'); ++ if (p) ++ *p = '\0'; ++ ++ const char *ori_path = ops->get_cgroup(ops, controller); ++ if (ori_path == NULL) { ++ ERROR("Failed to get cgroup path:%s", controller); ++ return -1; ++ } ++ path = safe_strdup(ori_path); ++ ++ h = get_hierarchy(ops, controller); ++ if (h) { ++ char *fullpath; ++ ++ fullpath = build_full_cgpath_from_monitorpath(h, path, filename); ++ ret = lxc_write_to_file(fullpath, value, strlen(value), false, 0666); ++ free(fullpath); ++ } ++ free(path); ++ ++ return ret; ++} ++#else + /* Called externally (i.e. from 'lxc-cgroup') to set new cgroup limits. Here we + * don't have a cgroup_data set up, so we ask the running container through the + * commands API for the cgroup path. +@@ -2562,6 +3114,7 @@ __cgfsng_ops static int cgfsng_set(struct cgroup_ops *ops, + + return ret; + } ++#endif + + /* take devices cgroup line + * /dev/foo rwx +@@ -2686,6 +3239,199 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, + return lxc_write_openat(h->container_full_path, filename, value, strlen(value)); + } + ++#ifdef HAVE_ISULAD ++/* Called from setup_limits - here we have the container's cgroup_data because ++ * we created the cgroups. ++ */ ++static int isulad_cg_legacy_get_data(struct cgroup_ops *ops, const char *filename, ++ char *value, size_t len) ++{ ++ char *fullpath = NULL; ++ char *p = NULL; ++ struct hierarchy *h = NULL; ++ int ret = 0; ++ char *controller = NULL; ++ ++ len = strlen(filename); ++ if (SIZE_MAX - 1 < len) { ++ errno = EINVAL; ++ return -1; ++ } ++ controller = calloc(1, len + 1); ++ if (controller == NULL) { ++ errno = ENOMEM; ++ return -1; ++ } ++ (void)strlcpy(controller, filename, len + 1); ++ ++ p = strchr(controller, '.'); ++ if (p) ++ *p = '\0'; ++ ++ ++ h = get_hierarchy(ops, controller); ++ if (!h) { ++ ERROR("Failed to setup limits for the \"%s\" controller. " ++ "The controller seems to be unused by \"cgfsng\" cgroup " ++ "driver or not enabled on the cgroup hierarchy", ++ controller); ++ errno = ENOENT; ++ free(controller); ++ return -ENOENT; ++ } ++ ++ fullpath = must_make_path(h->container_full_path, filename, NULL); ++ ret = lxc_read_from_file(fullpath, value, len); ++ free(fullpath); ++ free(controller); ++ return ret; ++} ++ ++static int isulad_cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, ++ const char *value) ++{ ++ size_t len; ++ char *fullpath, *p; ++ /* "b|c <2^64-1>:<2^64-1> r|w|m" = 47 chars max */ ++ char converted_value[50]; ++ struct hierarchy *h; ++ int ret = 0; ++ char *controller = NULL; ++ int retry_count = 0; ++ int max_retry = 10; ++ char *container_cgroup = ops->container_cgroup; ++ ++ len = strlen(filename); ++ controller = alloca(len + 1); ++ (void)strlcpy(controller, filename, len + 1); ++ ++ p = strchr(controller, '.'); ++ if (p) ++ *p = '\0'; ++ ++ if (strcmp("devices.allow", filename) == 0 && value[0] == '/') { ++ ret = convert_devpath(value, converted_value); ++ if (ret < 0) ++ return ret; ++ value = converted_value; ++ } ++ ++ h = get_hierarchy(ops, controller); ++ if (!h) { ++ ERROR("Failed to setup limits for the \"%s\" controller. " ++ "The controller seems to be unused by \"cgfsng\" cgroup " ++ "driver or not enabled on the cgroup hierarchy", ++ controller); ++ errno = ENOENT; ++ return -ENOENT; ++ } ++ ++ fullpath = must_make_path(h->container_full_path, filename, NULL); ++ ++retry: ++ ret = lxc_write_to_file(fullpath, value, strlen(value), false, 0666); ++ if (ret != 0) { ++ if (retry_count < max_retry) { ++ SYSERROR("setting cgroup config for ready process caused \"failed to write %s to %s\".", value, fullpath); ++ (void)isulad_cg_legacy_handle_cpuset_hierarchy(h, container_cgroup); ++ (void)isulad_mkdir_eexist_on_last(h->container_full_path, 0755); ++ usleep(100 * 1000); /* 100 millisecond */ ++ retry_count++; ++ goto retry; ++ } ++ lxc_write_error_message(ops->errfd, ++ "%s:%d: setting cgroup config for ready process caused \"failed to write %s to %s: %s\".", ++ __FILE__, __LINE__, value, fullpath, strerror(errno)); ++ } ++ free(fullpath); ++ return ret; ++} ++ ++__cgfsng_ops static bool cgfsng_setup_limits_legacy(struct cgroup_ops *ops, ++ struct lxc_conf *conf, ++ bool do_devices) ++{ ++ __do_free struct lxc_list *sorted_cgroup_settings = NULL; ++ struct lxc_list *cgroup_settings = &conf->cgroup; ++ struct lxc_list *iterator, *next; ++ struct lxc_cgroup *cg; ++ bool ret = false; ++ char value[21 + 1] = { 0 }; ++ long long int readvalue, setvalue; ++ ++ if (!ops) ++ return ret_set_errno(false, ENOENT); ++ ++ if (!conf) ++ return ret_set_errno(false, EINVAL); ++ ++ cgroup_settings = &conf->cgroup; ++ if (lxc_list_empty(cgroup_settings)) ++ return true; ++ ++ if (!ops->hierarchies) ++ return ret_set_errno(false, EINVAL); ++ ++ sorted_cgroup_settings = sort_cgroup_settings(cgroup_settings); ++ if (!sorted_cgroup_settings) ++ return false; ++ ++ lxc_list_for_each(iterator, sorted_cgroup_settings) { ++ cg = iterator->elem; ++ ++ if (do_devices == !strncmp("devices", cg->subsystem, 7)) { ++ if (isulad_cg_legacy_set_data(ops, cg->subsystem, cg->value)) { ++ if (do_devices && (errno == EACCES || errno == EPERM)) { ++ SYSWARN("Failed to set \"%s\" to \"%s\"", cg->subsystem, cg->value); ++ continue; ++ } ++ SYSERROR("Failed to set \"%s\" to \"%s\"", cg->subsystem, cg->value); ++ goto out; ++ } ++ DEBUG("Set controller \"%s\" set to \"%s\"", cg->subsystem, cg->value); ++ } ++ // isulad: check cpu shares ++ if (strcmp(cg->subsystem, "cpu.shares") == 0) { ++ if (isulad_cg_legacy_get_data(ops, cg->subsystem, value, sizeof(value) - 1) < 0) { ++ SYSERROR("Error get %s", cg->subsystem); ++ goto out; ++ } ++ trim(value); ++ if (lxc_safe_long_long(cg->value, &setvalue) != 0) { ++ SYSERROR("Invalid value %s", cg->value); ++ goto out; ++ } ++ if (lxc_safe_long_long(value, &readvalue) != 0) { ++ SYSERROR("Invalid value %s", value); ++ goto out; ++ } ++ if (setvalue > readvalue) { ++ ERROR("The maximum allowed cpu-shares is %s", value); ++ lxc_write_error_message(ops->errfd, ++ "%s:%d: setting cgroup config for ready process caused \"The maximum allowed cpu-shares is %s\".", ++ __FILE__, __LINE__, value); ++ goto out; ++ } else if (setvalue < readvalue) { ++ ERROR("The minimum allowed cpu-shares is %s", value); ++ lxc_write_error_message(ops->errfd, ++ "%s:%d: setting cgroup config for ready process caused \"The minimum allowed cpu-shares is %s\".", ++ __FILE__, __LINE__, value); ++ goto out; ++ } ++ } ++ } ++ ++ ret = true; ++ INFO("Limits for the legacy cgroup hierarchies have been setup"); ++out: ++ lxc_list_for_each_safe(iterator, sorted_cgroup_settings, next) { ++ lxc_list_del(iterator); ++ free(iterator); ++ } ++ ++ return ret; ++} ++#else + __cgfsng_ops static bool cgfsng_setup_limits_legacy(struct cgroup_ops *ops, + struct lxc_conf *conf, + bool do_devices) +@@ -2739,6 +3485,7 @@ out: + + return ret; + } ++#endif + + /* + * Some of the parsing logic comes from the original cgroup device v1 +@@ -2950,6 +3697,12 @@ bool __cgfsng_delegate_controllers(struct cgroup_ops *ops, const char *cgroup) + return true; + } + ++#ifdef HAVE_ISULAD ++__cgfsng_ops bool cgfsng_monitor_delegate_controllers(struct cgroup_ops *ops) ++{ ++ return true; ++} ++#else + __cgfsng_ops bool cgfsng_monitor_delegate_controllers(struct cgroup_ops *ops) + { + if (!ops) +@@ -2957,6 +3710,7 @@ __cgfsng_ops bool cgfsng_monitor_delegate_controllers(struct cgroup_ops *ops) + + return __cgfsng_delegate_controllers(ops, ops->monitor_cgroup); + } ++#endif + + __cgfsng_ops bool cgfsng_payload_delegate_controllers(struct cgroup_ops *ops) + { +@@ -3107,6 +3861,22 @@ static int cg_hybrid_init(struct cgroup_ops *ops, bool relative, bool unprivileg + + trim(base_cgroup); + prune_init_scope(base_cgroup); ++#ifdef HAVE_ISULAD ++ /* isulad: do not test writeable, if we run isulad in docker without cgroup namespace. ++ * the base_cgroup will be docker/XXX.., mountpoint+base_cgroup may be not exist */ ++ ++ /* ++ * reason:base cgroup may be started with /system.slice when cg_hybrid_init ++ * read /proc/1/cgroup on host, and cgroup init will set all containers ++ * cgroup path under /sys/fs/cgroup//system.slice/xxx/lxc ++ * directory, this is not consistent with docker. The default cgroup path ++ * should be under /sys/fs/cgroup//lxc directory. ++ */ ++ ++ if (strlen(base_cgroup) > 1 && base_cgroup[0] == '/') { ++ base_cgroup[1] = '\0'; ++ } ++#else + if (type == CGROUP2_SUPER_MAGIC) + writeable = test_writeable_v2(mountpoint, base_cgroup); + else +@@ -3115,7 +3885,7 @@ static int cg_hybrid_init(struct cgroup_ops *ops, bool relative, bool unprivileg + TRACE("The %s group is not writeable", base_cgroup); + continue; + } +- ++#endif + if (type == CGROUP2_SUPER_MAGIC) { + char *cgv2_ctrl_path; + +@@ -3268,7 +4038,45 @@ static int cg_init(struct cgroup_ops *ops, struct lxc_conf *conf) + return cg_hybrid_init(ops, relative, !lxc_list_empty(&conf->id_map)); + } + +-__cgfsng_ops static int cgfsng_data_init(struct cgroup_ops *ops) ++#ifdef HAVE_ISULAD ++__cgfsng_ops static int cgfsng_data_init(struct cgroup_ops *ops, struct lxc_conf *conf) ++{ ++ const char *cgroup_pattern; ++ const char *cgroup_tree; ++ __do_free char *container_cgroup = NULL, *__cgroup_tree = NULL; ++ size_t len; ++ ++ if (!ops) ++ return ret_set_errno(-1, ENOENT); ++ ++ /* copy system-wide cgroup information */ ++ cgroup_pattern = lxc_global_config_value("lxc.cgroup.pattern"); ++ if (cgroup_pattern && strcmp(cgroup_pattern, "") != 0) ++ ops->cgroup_pattern = must_copy_string(cgroup_pattern); ++ ++ if (conf->cgroup_meta.dir) { ++ cgroup_tree = conf->cgroup_meta.dir; ++ container_cgroup = must_concat(&len, cgroup_tree, "/", conf->name, NULL); ++ } else if (ops->cgroup_pattern) { ++ __cgroup_tree = lxc_string_replace("%n", conf->name, ops->cgroup_pattern); ++ if (!__cgroup_tree) ++ return ret_set_errno(-1, ENOMEM); ++ ++ cgroup_tree = __cgroup_tree; ++ container_cgroup = must_concat(&len, cgroup_tree, NULL); ++ } else { ++ cgroup_tree = NULL; ++ container_cgroup = must_concat(&len, conf->name, NULL); ++ } ++ if (!container_cgroup) ++ return ret_set_errno(-1, ENOMEM); ++ ++ ops->container_cgroup = move_ptr(container_cgroup); ++ ++ return 0; ++} ++#else ++__cgfsng_ops static int cgfsng_data_init(struct cgroup_ops *ops, struct lxc_conf *conf) + { + const char *cgroup_pattern; + +@@ -3282,6 +4090,7 @@ __cgfsng_ops static int cgfsng_data_init(struct cgroup_ops *ops) + + return 0; + } ++#endif + + struct cgroup_ops *cgfsng_ops_init(struct lxc_conf *conf) + { +@@ -3311,6 +4120,9 @@ struct cgroup_ops *cgfsng_ops_init(struct lxc_conf *conf) + cgfsng_ops->num_hierarchies = cgfsng_num_hierarchies; + cgfsng_ops->get_hierarchies = cgfsng_get_hierarchies; + cgfsng_ops->get_cgroup = cgfsng_get_cgroup; ++#ifdef HAVE_ISULAD ++ cgfsng_ops->get_cgroup_full_path = cgfsng_get_cgroup_full_path; ++#endif + cgfsng_ops->get = cgfsng_get; + cgfsng_ops->set = cgfsng_set; + cgfsng_ops->freeze = cgfsng_freeze; +diff --git a/src/lxc/cgroups/cgroup.c b/src/lxc/cgroups/cgroup.c +index 37fd0e3..ad46d5c 100644 +--- a/src/lxc/cgroups/cgroup.c ++++ b/src/lxc/cgroups/cgroup.c +@@ -31,7 +31,7 @@ struct cgroup_ops *cgroup_init(struct lxc_conf *conf) + if (!cgroup_ops) + return log_error_errno(NULL, errno, "Failed to initialize cgroup driver"); + +- if (cgroup_ops->data_init(cgroup_ops)) { ++ if (cgroup_ops->data_init(cgroup_ops, conf)) { + cgroup_exit(cgroup_ops); + return log_error_errno(NULL, errno, + "Failed to initialize cgroup data"); +@@ -79,7 +79,7 @@ void cgroup_exit(struct cgroup_ops *ops) + free((*it)->container_base_path); + free((*it)->container_full_path); + free((*it)->monitor_full_path); +- if ((*it)->cgfd_mon >= 0) ++ if ((*it)->cgfd_con >= 0) + close((*it)->cgfd_con); + if ((*it)->cgfd_mon >= 0) + close((*it)->cgfd_mon); +diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h +index 1e08a01..dcdc76b 100644 +--- a/src/lxc/cgroups/cgroup.h ++++ b/src/lxc/cgroups/cgroup.h +@@ -102,6 +102,10 @@ struct cgroup_ops { + char *container_cgroup; + char *monitor_cgroup; + ++#ifdef HAVE_ISULAD ++ int errfd; ++#endif ++ + /* @hierarchies + * - A NULL-terminated array of struct hierarchy, one per legacy + * hierarchy. No duplicates. First sufficient, writeable mounted +@@ -139,7 +143,7 @@ struct cgroup_ops { + */ + cgroup_layout_t cgroup_layout; + +- int (*data_init)(struct cgroup_ops *ops); ++ int (*data_init)(struct cgroup_ops *ops, struct lxc_conf *conf); + void (*payload_destroy)(struct cgroup_ops *ops, struct lxc_handler *handler); + void (*monitor_destroy)(struct cgroup_ops *ops, struct lxc_handler *handler); + bool (*monitor_create)(struct cgroup_ops *ops, struct lxc_handler *handler); +@@ -147,6 +151,9 @@ struct cgroup_ops { + bool (*payload_create)(struct cgroup_ops *ops, struct lxc_handler *handler); + bool (*payload_enter)(struct cgroup_ops *ops, struct lxc_handler *handler); + const char *(*get_cgroup)(struct cgroup_ops *ops, const char *controller); ++#ifdef HAVE_ISULAD ++ const char *(*get_cgroup_full_path)(struct cgroup_ops *ops, const char *controller); ++#endif + bool (*escape)(const struct cgroup_ops *ops, struct lxc_conf *conf); + int (*num_hierarchies)(struct cgroup_ops *ops); + bool (*get_hierarchies)(struct cgroup_ops *ops, int n, char ***out); +diff --git a/src/lxc/conf.c b/src/lxc/conf.c +index e3fce51..e806605 100644 +--- a/src/lxc/conf.c ++++ b/src/lxc/conf.c +@@ -637,8 +637,13 @@ static int lxc_mount_auto_mounts(struct lxc_conf *conf, int flags, struct lxc_ha + { LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED, "%r/proc/sysrq-trigger", "%r/proc/sysrq-trigger", NULL, MS_BIND, NULL }, + { LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED, NULL, "%r/proc/sysrq-trigger", NULL, MS_REMOUNT|MS_BIND|MS_RDONLY, NULL }, + { LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_RW, "proc", "%r/proc", "proc", MS_NODEV|MS_NOEXEC|MS_NOSUID, NULL }, ++ #ifdef HAVE_ISULAD ++ { LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RW, "sysfs", "%r/sys", "sysfs", MS_NODEV|MS_NOEXEC|MS_NOSUID, NULL }, ++ { LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RO, "sysfs", "%r/sys", "sysfs", MS_RDONLY|MS_NODEV|MS_NOEXEC|MS_NOSUID, NULL }, ++ #else + { LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RW, "sysfs", "%r/sys", "sysfs", 0, NULL }, + { LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RO, "sysfs", "%r/sys", "sysfs", MS_RDONLY, NULL }, ++ #endif + { LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED, "sysfs", "%r/sys", "sysfs", MS_NODEV|MS_NOEXEC|MS_NOSUID, NULL }, + { LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED, "%r/sys", "%r/sys", NULL, MS_BIND, NULL }, + { LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED, NULL, "%r/sys", NULL, MS_REMOUNT|MS_BIND|MS_RDONLY, NULL }, +@@ -670,6 +675,13 @@ static int lxc_mount_auto_mounts(struct lxc_conf *conf, int flags, struct lxc_ha + if (!destination) + return -1; + ++#ifdef HAVE_ISULAD ++ if (mkdir_p(destination, 0755) < 0) { ++ SYSERROR("Failed to create mount target '%s'", destination); ++ return log_error(-1, "Failed to mkdir destination %s", destination); ++ } ++#endif ++ + mflags = add_required_remount_flags(source, destination, + default_mounts[i].flags); + r = safe_mount(source, destination, default_mounts[i].fstype, +diff --git a/src/lxc/utils.c b/src/lxc/utils.c +index 2cf9994..160b3db 100644 +--- a/src/lxc/utils.c ++++ b/src/lxc/utils.c +@@ -1755,8 +1755,13 @@ int lxc_rm_rf(const char *dirname) + struct dirent *direntp; + + dir = opendir(dirname); +- if (!dir) ++ if (!dir) { ++ if (errno == ENOENT) { ++ WARN("Destroy path: \"%s\" do not exist", dirname); ++ return 0; ++ } + return log_error_errno(-1, errno, "Failed to open dir \"%s\"", dirname); ++ } + + while ((direntp = readdir(dir))) { + __do_free char *pathname = NULL; +@@ -1904,3 +1909,26 @@ int fix_stdio_permissions(uid_t uid) + + return fret; + } ++ ++#ifdef HAVE_ISULAD ++/* isulad: write error message */ ++void lxc_write_error_message(int errfd, const char *format, ...) ++{ ++ int ret; ++ char errbuf[BUFSIZ + 1] = {0}; ++ ssize_t sret; ++ va_list argp; ++ ++ if (errfd <= 0) ++ return; ++ ++ va_start(argp, format); ++ ret = vsnprintf(errbuf, BUFSIZ, format, argp); ++ va_end(argp); ++ if (ret < 0 || ret >= BUFSIZ) ++ SYSERROR("Failed to call vsnprintf"); ++ sret = write(errfd, errbuf, strlen(errbuf)); ++ if (sret < 0) ++ SYSERROR("Write errbuf failed"); ++} ++#endif +diff --git a/src/lxc/utils.h b/src/lxc/utils.h +index 7b36133..3c30565 100644 +--- a/src/lxc/utils.h ++++ b/src/lxc/utils.h +@@ -244,4 +244,8 @@ extern bool lxc_can_use_pidfd(int pidfd); + + extern int fix_stdio_permissions(uid_t uid); + ++#ifdef HAVE_ISULAD ++extern void lxc_write_error_message(int errfd, const char *format, ...); ++#endif ++ + #endif /* __LXC_UTILS_H */ +-- +1.8.3.1 + diff --git a/0006-conf.c-fix-bug-when-set-no-ro-mount-mount-propagatio.patch b/0006-conf.c-fix-bug-when-set-no-ro-mount-mount-propagatio.patch deleted file mode 100644 index b64419df990f3980b868576f83e4d5c1e641092e..0000000000000000000000000000000000000000 --- a/0006-conf.c-fix-bug-when-set-no-ro-mount-mount-propagatio.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 80fcf03d746825fcf809f7b415782a410d9d87d3 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Fri, 11 Jan 2019 16:55:01 +0800 -Subject: [PATCH 006/140] conf.c: fix bug when set no ro mount, mount - propagation will be skipped - -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 18753d1..37a5ff7 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -2087,6 +2087,9 @@ static int mount_entry(const char *fsname, const char *target, - } - } - -+#ifdef HAVE_STATVFS -+ skipremount: -+#endif - if (pflags) { - ret = mount(NULL, target, NULL, pflags, NULL); - if (ret < 0) { -@@ -2103,10 +2106,6 @@ static int mount_entry(const char *fsname, const char *target, - DEBUG("Changed mount propagation for \"%s\"", target); - } - -- --#ifdef HAVE_STATVFS --skipremount: --#endif - DEBUG("Mounted \"%s\" on \"%s\" with filesystem type \"%s\"", - srcpath ? srcpath : "(null)", target, fstype); - --- -1.8.3.1 - diff --git a/0008-isulad-modify-exit-code-and-stop-signal.patch b/0006-modify-container-exit-code-and-stop-signal.patch similarity index 39% rename from 0008-isulad-modify-exit-code-and-stop-signal.patch rename to 0006-modify-container-exit-code-and-stop-signal.patch index a565d186e235fd56f7cdb4c408b58a8c81744063..5e109433313a0382d62a9eeb0e8ac40d191669b3 100644 --- a/0008-isulad-modify-exit-code-and-stop-signal.patch +++ b/0006-modify-container-exit-code-and-stop-signal.patch @@ -1,87 +1,80 @@ -From 98dbcb7dacbf18393295a9dcf054a65f9033ea5d Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Fri, 11 Jan 2019 17:44:53 +0800 -Subject: [PATCH 008/140] isulad: modify exit code and stop signal +From ef7c687828efd488369ff860523aa15a42c72587 Mon Sep 17 00:00:00 2001 +From: wujing +Date: Mon, 13 Apr 2020 04:58:46 -0400 +Subject: [PATCH 06/49] modify container exit code and stop signal -1. modify default stop signal and disable reboot by signal. -2. send '128 + signal' if container is killed by signal. - -Signed-off-by: LiFeng +Signed-off-by: wujing --- - src/lxc/lxccontainer.c | 6 ++---- - src/lxc/start.c | 33 ++++++++++++++++----------------- - 2 files changed, 18 insertions(+), 21 deletions(-) + src/lxc/lxccontainer.c | 10 ++++++++-- + src/lxc/start.c | 28 ++++++++++++++++++++++++++++ + 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index b4cacce..1d7f5be 100644 +index f4462fd..a617172 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c -@@ -2069,7 +2069,8 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout) +@@ -2101,7 +2101,12 @@ WRAP_API_1(bool, lxcapi_reboot2, int) + static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout) { - int killret, ret; - pid_t pid; -- int haltsignal = SIGPWR, state_client_fd = -EBADF; -+ // isulad: keep default signal the same as docker -+ int haltsignal = SIGTERM, state_client_fd = -EBADF; + __do_close int pidfd = -EBADF, state_client_fd = -EBADF; ++#ifdef HAVE_ISULAD ++ // isulad: keep default signal the same as docker ++ int haltsignal = SIGTERM; ++#else + int haltsignal = SIGPWR; ++#endif + pid_t pid = -1; lxc_state_t states[MAX_STATE] = {0}; - - if (!c) -@@ -2082,11 +2083,8 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout) + int killret, ret; +@@ -2117,12 +2122,13 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout) if (pid <= 0) return true; - /* Detect whether we should send SIGRTMIN + 3 (e.g. systemd). */ if (c->lxc_conf && c->lxc_conf->haltsignal) haltsignal = c->lxc_conf->haltsignal; -- else if (task_blocks_signal(pid, (SIGRTMIN + 3))) -- haltsignal = (SIGRTMIN + 3); ++#ifndef HAVE_ISULAD ++ /* Detect whether we should send SIGRTMIN + 3 (e.g. systemd). */ + else if (task_blocks_signal(pid, (SIGRTMIN + 3))) + haltsignal = (SIGRTMIN + 3); +- ++#endif - /* Add a new state client before sending the shutdown signal so that we - * don't miss a state. + /* + * Add a new state client before sending the shutdown signal so diff --git a/src/lxc/start.c b/src/lxc/start.c -index 72e2de2..d64bdac 100644 +index a25bd04..5dcf828 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c -@@ -1893,11 +1893,14 @@ out_abort: +@@ -1886,10 +1886,18 @@ out_sync_fini: return -1; } ++#ifdef HAVE_ISULAD +// isulad: send '128 + signal' if container is killed by signal. -+#define ExitSignalOffset 128 ++#define EXIT_SIGNAL_OFFSET 128 ++#endif + - int __lxc_start(const char *name, struct lxc_handler *handler, - struct lxc_operations* ops, void *data, const char *lxcpath, - bool daemonize, int *error_num) + int __lxc_start(struct lxc_handler *handler, struct lxc_operations *ops, + void *data, const char *lxcpath, bool daemonize, int *error_num) { -- int ret, status; -+ int ret, status, exit_code; + int ret, status; ++#ifdef HAVE_ISULAD ++ int exit_code; ++#endif + const char *name = handler->name; struct lxc_conf *conf = handler->conf; - - ret = lxc_init(name, handler); -@@ -1966,22 +1969,18 @@ int __lxc_start(const char *name, struct lxc_handler *handler, + struct cgroup_ops *cgroup_ops; +@@ -1976,6 +1984,21 @@ int __lxc_start(struct lxc_handler *handler, struct lxc_operations *ops, * reboot. This should mean it was an lxc-execute which simply exited. * In any case, treat it as a 'halt'. */ ++#ifdef HAVE_ISULAD + // isulad: recored log for container init exit - if (WIFSIGNALED(status)) { -- switch(WTERMSIG(status)) { -- case SIGINT: /* halt */ -- DEBUG("Container \"%s\" is halting", name); -- break; -- case SIGHUP: /* reboot */ -- DEBUG("Container \"%s\" is rebooting", name); -- handler->conf->reboot = REBOOT_REQ; -- break; -- case SIGSYS: /* seccomp */ -- DEBUG("Container \"%s\" violated its seccomp policy", name); -- break; -- default: -- DEBUG("Unknown exit status for container \"%s\" init %d", name, WTERMSIG(status)); -- break; -- } ++ if (WIFSIGNALED(status)) { + int signal = WTERMSIG(status); + signal = WTERMSIG(status); -+ exit_code = ExitSignalOffset + signal; ++ exit_code = EXIT_SIGNAL_OFFSET + signal; + ERROR("Container \"%s\" init exited with signal %d", name, signal); + } else if (WIFEXITED(status)) { + exit_code = WEXITSTATUS(status); @@ -89,15 +82,28 @@ index 72e2de2..d64bdac 100644 + } else { + exit_code = -1; + ERROR("Container \"%s\" init exited with unknown status", name); ++ } ++#else + if (WIFSIGNALED(status)) { + switch(WTERMSIG(status)) { + case SIGINT: /* halt */ +@@ -1993,6 +2016,7 @@ int __lxc_start(struct lxc_handler *handler, struct lxc_operations *ops, + break; + } } ++#endif ret = lxc_restore_phys_nics_to_netns(handler); -@@ -1994,7 +1993,7 @@ int __lxc_start(const char *name, struct lxc_handler *handler, - handler->pinfd = -1; - } + if (ret < 0) +@@ -2000,7 +2024,11 @@ int __lxc_start(struct lxc_handler *handler, struct lxc_operations *ops, + + close_prot_errno_disarm(handler->pinfd); -- lxc_monitor_send_exit_code(name, status, handler->lxcpath); ++#ifdef HAVE_ISULAD + lxc_monitor_send_exit_code(name, exit_code, handler->lxcpath); ++#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; diff --git a/0010-Save-pid-ppid-info-into-file-for-isulad.patch b/0007-check-and-save-pid-info-file.patch similarity index 34% rename from 0010-Save-pid-ppid-info-into-file-for-isulad.patch rename to 0007-check-and-save-pid-info-file.patch index 2e021ef5dad3bbb9db81db0b79e9bdd50f9d2748..3eaa02f07c2b727b582025bf4af2e5ebce7d0dc1 100644 --- a/0010-Save-pid-ppid-info-into-file-for-isulad.patch +++ b/0007-check-and-save-pid-info-file.patch @@ -1,58 +1,59 @@ -From 523b705fb269a9463b9412aa3a814a9c71a743cc Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Fri, 11 Jan 2019 22:53:56 -0500 -Subject: [PATCH 010/140] Save pid/ppid info into file for isulad +From 0d54daf204fd2bc41c45c7c159af6436d66b272c Mon Sep 17 00:00:00 2001 +From: wujing +Date: Mon, 13 Apr 2020 05:48:03 -0400 +Subject: [PATCH 07/49] check and save pid info file -Signed-off-by: LiFeng +Signed-off-by: wujing --- src/lxc/conf.c | 1 + src/lxc/conf.h | 2 + - src/lxc/lxccontainer.c | 24 ++++++++++ - src/lxc/lxccontainer.h | 10 ++++ - src/lxc/start.c | 41 +++++++++++++++++ - src/lxc/tools/arguments.h | 2 + - src/lxc/tools/lxc_start.c | 20 ++++++++ - src/lxc/utils.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++ - src/lxc/utils.h | 66 +++++++++++++++++++++++++++ - 9 files changed, 280 insertions(+) + src/lxc/lxccontainer.c | 29 +++++++++++- + src/lxc/lxccontainer.h | 12 +++++ + src/lxc/start.c | 98 ++++++++++++++++++++++++++++++++++++++ + src/lxc/tools/arguments.h | 16 +++++++ + src/lxc/tools/lxc_start.c | 28 +++++++++++ + src/lxc/utils.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++ + src/lxc/utils.h | 69 +++++++++++++++++++++++++++ + 9 files changed, 371 insertions(+), 1 deletion(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 7b7f95b..0b4b63b 100644 +index e806605..43437af 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c -@@ -4194,6 +4194,7 @@ void lxc_conf_free(struct lxc_conf *conf) - /* isulad add begin */ +@@ -3961,6 +3961,7 @@ void lxc_conf_free(struct lxc_conf *conf) + free(conf->shmount.path_host); + free(conf->shmount.path_cont); + #ifdef HAVE_ISULAD ++ free(conf->container_info_file); lxc_clear_init_args(conf); lxc_clear_populate_devices(conf); -+ free(conf->container_info_file); - /* isulad add end */ - free(conf); - } + #endif diff --git a/src/lxc/conf.h b/src/lxc/conf.h -index cced868..e0954f9 100644 +index 7ed3cd0..23942ac 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h -@@ -403,6 +403,8 @@ struct lxc_conf { - size_t init_argc; +@@ -428,6 +428,8 @@ struct lxc_conf { /* populate devices*/ struct lxc_list populate_devs; + mode_t umask; //umask value + + char *container_info_file; - /* isulad add end */ - }; + #endif + }; diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index 318c71e..5679b9b 100644 +index a617172..33bb3ec 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c -@@ -4988,6 +4988,29 @@ static bool do_lxcapi_set_terminal_default_fifos(struct lxc_container *c, const +@@ -5293,6 +5293,31 @@ static int do_lxcapi_seccomp_notify_fd(struct lxc_container *c) - WRAP_API_2(bool, lxcapi_set_terminal_default_fifos, const char *, const char *) + WRAP_API(int, lxcapi_seccomp_notify_fd) ++#ifdef HAVE_ISULAD +/* isulad add set info file path */ +static bool do_lxcapi_set_container_info_file(struct lxc_container *c, const char *info_file) +{ -+ struct lxc_conf *conf; ++ struct lxc_conf *conf = NULL; + + if (!c || !c->lxc_conf || !info_file) + return false; @@ -64,34 +65,39 @@ index 318c71e..5679b9b 100644 + conf = c->lxc_conf; + if (conf->container_info_file) + free(conf->container_info_file); -+ conf->container_info_file = strdup(info_file); ++ conf->container_info_file = safe_strdup(info_file); + + container_mem_unlock(c); + return true; +} + +WRAP_API_1(bool, lxcapi_set_container_info_file, const char *) ++#endif + struct lxc_container *lxc_container_new(const char *name, const char *configpath) { struct lxc_container *c; -@@ -5113,6 +5136,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath - - /* isulad add begin */ - c->set_terminal_init_fifos = lxcapi_set_terminal_default_fifos; +@@ -5434,7 +5459,9 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath + c->mount = lxcapi_mount; + c->umount = lxcapi_umount; + c->seccomp_notify_fd = lxcapi_seccomp_notify_fd; +- ++#ifdef HAVE_ISULAD + c->set_container_info_file = lxcapi_set_container_info_file; - /* isulad add end */ ++#endif return c; + err: diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h -index 486531e..3c845fe 100644 +index 4577de7..edfff32 100644 --- a/src/lxc/lxccontainer.h +++ b/src/lxc/lxccontainer.h -@@ -857,6 +857,16 @@ struct lxc_container { - * \return \c true on success, else \c false. +@@ -865,6 +865,18 @@ struct lxc_container { + * \return pidfd of init process of the container. */ - bool (*set_terminal_init_fifos)(struct lxc_container *c, const char *in, const char *out); + int (*init_pidfd)(struct lxc_container *c); + ++#ifdef HAVE_ISULAD + /*! isulad add + * \brief An API call to set the path of info file + * @@ -101,38 +107,32 @@ index 486531e..3c845fe 100644 + * \return \c true on success, else \c false. + */ + bool (*set_container_info_file) (struct lxc_container *c, const char *info_file); ++#endif }; /*! diff --git a/src/lxc/start.c b/src/lxc/start.c -index d64bdac..9d71dd7 100644 +index 5dcf828..f5f9565 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c -@@ -1553,6 +1553,39 @@ static inline int do_share_ns(void *arg) +@@ -1537,6 +1537,94 @@ static inline int do_share_ns(void *arg) return 0; } -+/* isuald: save pid/ppid info */ -+static int lxc_save_container_info(char *filename, pid_t pid) ++#ifdef HAVE_ISULAD ++static int lxc_write_container_info(char *filename, pid_t pid, pid_t p_pid, ++ unsigned long long start_at, unsigned long long p_start_at) +{ + FILE *pid_fp = NULL; + int ret = 0; -+ pid_t p_pid = 0; -+ unsigned long long start_at = 0; -+ unsigned long long p_start_at = 0; + -+ pid_fp = fopen(filename, "w"); ++ pid_fp = lxc_fopen(filename, "w"); + if (pid_fp == NULL) { + SYSERROR("Failed to create pidfile '%s'",filename); + ret = -1; + goto out; + } + -+ start_at = lxc_get_process_startat(pid); -+ -+ p_pid = getpid(); -+ p_start_at = lxc_get_process_startat(p_pid); -+ + if (fprintf(pid_fp, "%d %llu %d %llu\n", pid, start_at, p_pid, p_start_at) < 0) { + SYSERROR("Failed to write '%s'", filename); + ret = -1; @@ -144,83 +144,164 @@ index d64bdac..9d71dd7 100644 + pid_fp = NULL; + return ret; +} ++ ++static int lxc_check_container_info(char *filename, pid_t pid, pid_t p_pid, ++ unsigned long long start_at, unsigned long long p_start_at) ++{ ++ int ret = 0; ++ int num; ++ char sbuf[1024] = {0}; /* bufs for stat */ ++ int saved_pid; /* process id */ ++ int saved_ppid; /* pid of parent process */ ++ unsigned long long saved_start_time; /* start time of process -- seconds since 1-1-70 */ ++ unsigned long long saved_pstart_time; /* start time of parent process -- seconds since 1-1-70 */ ++ ++ if ((lxc_file2str(filename, sbuf, sizeof(sbuf))) == -1) { ++ SYSERROR("Failed to read pidfile %s", filename); ++ ret = -1; ++ goto out; ++ } ++ ++ num = sscanf(sbuf, "%d %Lu %d %Lu", &saved_pid, &saved_start_time, &saved_ppid, &saved_pstart_time); ++ if (num != 4) { ++ SYSERROR("Call sscanf error"); ++ ret = -1; ++ goto out; ++ } ++ ++ if (pid != saved_pid || p_pid != saved_ppid ++ || start_at != saved_start_time || p_start_at != saved_pstart_time) { ++ ERROR("Check container info failed"); ++ ret = -1; ++ goto out; ++ } ++ ++out: ++ return ret; ++} ++ ++/* isuald: save pid/ppid info */ ++static int lxc_save_container_info(char *filename, pid_t pid) ++{ ++ int ret = 0; ++ pid_t p_pid = 0; ++ unsigned long long start_at = 0; ++ unsigned long long p_start_at = 0; ++ ++ start_at = lxc_get_process_startat(pid); ++ p_pid = getpid(); ++ p_start_at = lxc_get_process_startat(p_pid); ++ ++ ret = lxc_write_container_info(filename, pid, p_pid, start_at, p_start_at); ++ if (ret != 0) { ++ goto out; ++ } ++ ++ ret = lxc_check_container_info(filename, pid, p_pid, start_at, p_start_at); ++ if (ret != 0) { ++ goto out; ++ } ++ ++out: ++ return ret; ++} ++#endif + /* lxc_spawn() performs crucial setup tasks and clone()s the new process which * exec()s the requested container binary. * Note that lxc_spawn() runs in the parent namespaces. Any operations performed -@@ -1683,6 +1716,14 @@ static int lxc_spawn(struct lxc_handler *handler) +@@ -1648,6 +1736,16 @@ static int lxc_spawn(struct lxc_handler *handler) } TRACE("Cloned child process %d", handler->pid); -+ /* isulad: save pid/ppid info into file*/ -+ if (handler->conf->container_info_file) { -+ if (lxc_save_container_info(handler->conf->container_info_file, handler->pid)) { -+ ERROR("Failed to save cloned container pid"); -+ goto out_delete_net; -+ } -+ } -+ - for (i = 0; i < LXC_NS_MAX; i++) - if (handler->ns_on_clone_flags & ns_info[i].clone_flag) - INFO("Cloned %s", ns_info[i].flag_name); ++#ifdef HAVE_ISULAD ++ /* isulad: save pid/ppid info into file*/ ++ if (handler->conf->container_info_file) { ++ if (lxc_save_container_info(handler->conf->container_info_file, handler->pid)) { ++ ERROR("Failed to save cloned container pid"); ++ goto out_delete_net; ++ } ++ } ++#endif ++ + /* Verify that we can actually make use of pidfds. */ + if (!lxc_can_use_pidfd(handler->pidfd)) + close_prot_errno_disarm(handler->pidfd); diff --git a/src/lxc/tools/arguments.h b/src/lxc/tools/arguments.h -index b7af2b5..b6df23f 100644 +index cb0ba74..91f4e9a 100644 --- a/src/lxc/tools/arguments.h +++ b/src/lxc/tools/arguments.h -@@ -63,6 +63,7 @@ struct lxc_arguments { +@@ -40,6 +40,9 @@ struct lxc_arguments { + /* for lxc-start */ const char *share_ns[32]; /* size must be greater than LXC_NS_MAX */ - const char *terminal_fifos[2]; /* isulad add, fifos used to redirct stdin/out/err */ ++#ifdef HAVE_ISULAD + const char *container_info; /* isulad: file used to store pid and ppid info of container */ ++#endif /* for lxc-console */ unsigned int ttynum; -@@ -176,6 +177,7 @@ struct lxc_arguments { - /* isulad add begin */ - #define OPT_INPUT_FIFO OPT_USAGE - 7 - #define OPT_OUTPUT_FIFO OPT_USAGE - 8 -+#define OPT_CONTAINER_INFO OPT_USAGE - 9 - /* isulad add end*/ +@@ -152,6 +155,19 @@ struct lxc_arguments { + #define OPT_SHARE_UTS OPT_USAGE - 5 + #define OPT_SHARE_PID OPT_USAGE - 6 ++#ifdef HAVE_ISULAD ++#define OPT_INPUT_FIFO OPT_USAGE - 7 ++#define OPT_OUTPUT_FIFO OPT_USAGE - 8 ++#define OPT_STDERR_FIFO OPT_USAGE - 9 ++#define OPT_CONTAINER_INFO OPT_USAGE - 10 ++#define OPT_EXIT_FIFO OPT_USAGE - 11 ++#define OPT_START_TIMEOUT OPT_USAGE - 12 ++#define OPT_DISABLE_PTY OPT_USAGE - 13 ++#define OPT_OPEN_STDIN OPT_USAGE - 14 ++#define OPT_ATTACH_TIMEOUT OPT_USAGE - 15 ++#define OPT_ATTACH_SUFFIX OPT_USAGE - 16 ++#endif ++ extern int lxc_arguments_parse(struct lxc_arguments *args, int argc, + char *const argv[]); + diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c -index 8f03f11..2f94d67 100644 +index 459b867..83ee75a 100644 --- a/src/lxc/tools/lxc_start.c +++ b/src/lxc/tools/lxc_start.c -@@ -69,8 +69,11 @@ static const struct option my_longopts[] = { +@@ -48,6 +48,9 @@ static const struct option my_longopts[] = { {"share-ipc", required_argument, 0, OPT_SHARE_IPC}, {"share-uts", required_argument, 0, OPT_SHARE_UTS}, {"share-pid", required_argument, 0, OPT_SHARE_PID}, -+ /* isulad add begin */ - {"in-fifo", required_argument, 0, OPT_INPUT_FIFO}, - {"out-fifo", required_argument, 0, OPT_OUTPUT_FIFO}, ++#ifdef HAVE_ISULAD + {"container-pidfile", required_argument, 0, OPT_CONTAINER_INFO}, -+ /* isulad add end */ ++#endif LXC_COMMON_OPTIONS }; -@@ -148,6 +151,9 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) - case OPT_OUTPUT_FIFO: - args->terminal_fifos[1] = arg; +@@ -118,6 +121,11 @@ 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; + break; ++#endif } return 0; } -@@ -189,6 +195,7 @@ int main(int argc, char *argv[]) - struct lxc_log log; - int err = EXIT_FAILURE; - char *rcfile = NULL; -+ char *container_info_file = NULL; /* isulad: info file*/ - char *const default_args[] = { +@@ -163,6 +171,9 @@ int main(int argc, char *argv[]) "/sbin/init", NULL, -@@ -313,6 +320,18 @@ int main(int argc, char *argv[]) + }; ++#ifdef HAVE_ISULAD ++ char *container_info_file = NULL; ++#endif + + lxc_list_init(&defines); + +@@ -283,6 +294,20 @@ int main(int argc, char *argv[]) goto out; } ++#ifdef HAVE_ISULAD + /* isulad: container info file used to store pid and ppid info of container*/ + if (my_args.container_info != NULL) { + if (ensure_path(&container_info_file, my_args.container_info) < 0) { @@ -232,40 +313,43 @@ index 8f03f11..2f94d67 100644 + goto out; + } + } ++#endif + if (my_args.console) if (!c->set_config_item(c, "lxc.console.path", my_args.console)) goto out; -@@ -353,5 +372,6 @@ int main(int argc, char *argv[]) +@@ -320,5 +345,8 @@ int main(int argc, char *argv[]) out: lxc_container_put(c); ++#ifdef HAVE_ISULAD + free(container_info_file); ++#endif exit(err); } diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index 67c3b3e..4728284 100644 +index 160b3db..ebcdae0 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c -@@ -1828,3 +1828,117 @@ int lxc_setup_keyring(void) - - return ret; +@@ -1931,4 +1931,121 @@ void lxc_write_error_message(int errfd, const char *format, ...) + if (sret < 0) + SYSERROR("Write errbuf failed"); } + +/* isulad: read file to buffer */ -+static int lxc_file2str(const char *filename, char ret[], int cap) ++int lxc_file2str(const char *filename, char ret[], int cap) +{ -+ int fd, num_read; ++ int fd, num_read; + -+ if ((fd = open(filename, O_RDONLY | O_CLOEXEC)) == -1) -+ return -1;/*lint !e960*/ -+ if ((num_read = read(fd, ret, cap - 1)) <= 0) -+ num_read = -1;/*lint !e960*/ -+ else -+ ret[num_read] = 0;/*lint !e613*//*lint !e960*/ -+ close(fd); ++ if ((fd = lxc_open(filename, O_RDONLY | O_CLOEXEC, 0)) == -1) ++ return -1; ++ if ((num_read = read(fd, ret, cap - 1)) <= 0) ++ num_read = -1; ++ else ++ ret[num_read] = 0; ++ close(fd); + -+ return num_read; ++ return num_read; +} + +/* isuald: lxc_stat2proc() makes sure it can handle arbitrary executable file basenames @@ -273,114 +357,119 @@ index 67c3b3e..4728284 100644 + * Such names confuse %s (see scanf(3)), so the string is split and %39c + * is used instead. (except for embedded ')' "(%[^)]c)" would work. + */ -+static proc_t *lxc_stat2proc(char *S) ++static proc_t *lxc_stat2proc(const char *S) +{ -+ int num; -+ proc_t *P = NULL; -+ char *tmp = NULL; -+ -+ if (!S) -+ return NULL;/*lint !e960*/ -+ -+ tmp = strrchr(S, ')'); /* split into "PID (cmd" and "" *//*lint !e586*/ -+ if (!tmp) -+ return NULL;/*lint !e960*/ -+ *tmp = '\0'; /* replace trailing ')' with NUL */ -+ -+ P = malloc(sizeof(proc_t)); -+ if (!P) -+ return NULL;/*lint !e960*/ -+ memset(P, 0x00, sizeof(proc_t)); -+ -+ /* parse these two strings separately, skipping the leading "(". */ -+ num = sscanf(S, "%d (%15c", &P->pid, P->cmd); /* comm[16] in kernel */ -+ if (num < 0 && errno) { -+ ERROR("Call sscanf error: %s", strerror(errno)); -+ free(P); -+ return NULL; -+ } -+ num = sscanf(tmp + 2, /* skip space after ')' too */ -+ "%c " -+ "%d %d %d %d %d " -+ "%lu %lu %lu %lu %lu " -+ "%Lu %Lu %Lu %Lu " /* utime stime cutime cstime *//*lint !e566*/ -+ "%ld %ld %ld %ld " -+ "%Lu " /* start_time *//*lint !e566*/ -+ "%lu " -+ "%ld " -+ "%lu %lu %lu %lu %lu %lu " -+ "%*s %*s %*s %*s " /* discard, no RT signals & Linux 2.1 used hex */ -+ "%lu %lu %lu " -+ "%d %d " -+ "%lu %lu", -+ &P->state, -+ &P->ppid, &P->pgrp, &P->session, &P->tty, &P->tpgid, -+ &P->flags, &P->min_flt, &P->cmin_flt, &P->maj_flt, &P->cmaj_flt, -+ &P->utime, &P->stime, &P->cutime, &P->cstime,/*lint !e561*/ -+ &P->priority, &P->nice, &P->timeout, &P->it_real_value, -+ &P->start_time,/*lint !e561*/ -+ &P->vsize, -+ &P->rss, -+ &P->rss_rlim, &P->start_code, &P->end_code, &P->start_stack, &P->kstk_esp, -+ &P->kstk_eip, -+ &P->wchan, &P->nswap, &P->cnswap, -+ &P->exit_signal, &P->processor, /* 2.2.1 ends with "exit_signal" */ -+ &P->rtprio, &P->sched /* both added to 2.5.18 */ -+ ); -+ -+ if (P->tty == 0) -+ P->tty = -1; /* the old notty val, update elsewhere bef. moving to 0 *//*lint !e960*/ -+ return P; ++ int num; ++ proc_t *P = NULL; ++ char *tmp = NULL; ++ ++ if (!S) ++ return NULL; ++ ++ tmp = strrchr(S, ')'); /* split into "PID (cmd" and "" */ ++ if (!tmp) ++ return NULL; ++ *tmp = '\0'; /* replace trailing ')' with NUL */ ++ ++ P = malloc(sizeof(proc_t)); ++ if (P == NULL) ++ return NULL; ++ (void)memset(P, 0x00, sizeof(proc_t)); ++ ++ /* parse these two strings separately, skipping the leading "(". */ ++ num = sscanf(S, "%d (%15c", &P->pid, P->cmd); /* comm[16] in kernel */ ++ if (num != 2) { ++ ERROR("Call sscanf error: %s", errno ? strerror(errno) : ""); ++ free(P); ++ return NULL; ++ } ++ num = sscanf(tmp + 2, /* skip space after ')' too */ ++ "%c " ++ "%d %d %d %d %d " ++ "%lu %lu %lu %lu %lu " ++ "%Lu %Lu %Lu %Lu " /* utime stime cutime cstime */ ++ "%ld %ld %ld %ld " ++ "%Lu " /* start_time */ ++ "%lu " ++ "%ld " ++ "%lu %lu %lu %lu %lu %lu " ++ "%*s %*s %*s %*s " /* discard, no RT signals & Linux 2.1 used hex */ ++ "%lu %lu %lu " ++ "%d %d " ++ "%lu %lu", ++ &P->state, ++ &P->ppid, &P->pgrp, &P->session, &P->tty, &P->tpgid, ++ &P->flags, &P->min_flt, &P->cmin_flt, &P->maj_flt, &P->cmaj_flt, ++ &P->utime, &P->stime, &P->cutime, &P->cstime, ++ &P->priority, &P->nice, &P->timeout, &P->it_real_value, ++ &P->start_time, ++ &P->vsize, ++ &P->rss, ++ &P->rss_rlim, &P->start_code, &P->end_code, &P->start_stack, &P->kstk_esp, ++ &P->kstk_eip, ++ &P->wchan, &P->nswap, &P->cnswap, ++ &P->exit_signal, &P->processor, /* 2.2.1 ends with "exit_signal" */ ++ &P->rtprio, &P->sched /* both added to 2.5.18 */ ++ ); ++ if (num != 35) { ++ ERROR("Call sscanf error: %s", errno ? strerror(errno) : ""); ++ free(P); ++ return NULL; ++ } ++ if (P->tty == 0) ++ P->tty = -1; /* the old notty val, update elsewhere bef. moving to 0 */ ++ return P; +} + +/* isulad: get starttime of process pid */ +unsigned long long lxc_get_process_startat(pid_t pid) +{ -+ int sret = 0; -+ unsigned long long startat = 0; -+ proc_t *pid_info = NULL; -+ char filename[PATH_MAX] = {0}; -+ char sbuf[1024] = {0}; /* bufs for stat */ -+ -+ sret = snprintf(filename, sizeof(filename), "/proc/%d/stat", pid); -+ if (sret < 0 || sret >= sizeof(filename)) {/*lint !e574*/ -+ ERROR("Failed to sprintf filename"); -+ goto out; -+ } -+ -+ if ((lxc_file2str(filename, sbuf, sizeof(sbuf))) == -1) { -+ SYSERROR("Failed to read pidfile %s", filename); -+ goto out; -+ } -+ -+ pid_info = lxc_stat2proc(sbuf); -+ if (!pid_info) {/*lint !e574*/ -+ ERROR("Failed to get proc stat info"); -+ goto out; -+ } -+ -+ startat = pid_info->start_time; ++ int sret = 0; ++ unsigned long long startat = 0; ++ proc_t *pid_info = NULL; ++ char filename[PATH_MAX] = {0}; ++ char sbuf[1024] = {0}; /* bufs for stat */ ++ ++ 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) { ++ SYSERROR("Failed to read pidfile %s", filename); ++ goto out; ++ } ++ ++ pid_info = lxc_stat2proc(sbuf); ++ if (!pid_info) { ++ ERROR("Failed to get proc stat info"); ++ goto out; ++ } ++ ++ startat = pid_info->start_time; +out: -+ free(pid_info); -+ return startat; ++ free(pid_info); ++ return startat; +} -+ + #endif diff --git a/src/lxc/utils.h b/src/lxc/utils.h -index 2d38178..8e4ed89 100644 +index 3c30565..11d6548 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h -@@ -56,6 +56,71 @@ extern char *get_rundir(void); +@@ -44,6 +44,73 @@ extern char *get_rundir(void); #endif #endif -+/* isuald: -+ ld cutime, cstime, priority, nice, timeout, it_real_value, rss, -+ c state, -+ d ppid, pgrp, session, tty, tpgid, -+ s signal, blocked, sigignore, sigcatch, -+ lu flags, min_flt, cmin_flt, maj_flt, cmaj_flt, utime, stime, -+ lu rss_rlim, start_code, end_code, start_stack, kstk_esp, kstk_eip, -+ lu start_time, vsize, wchan, nswap, cnswap, ++#ifdef HAVE_ISULAD ++/* isulad: ++ ld cutime, cstime, priority, nice, timeout, it_real_value, rss, ++ c state, ++ d ppid, pgrp, session, tty, tpgid, ++ s signal, blocked, sigignore, sigcatch, ++ lu flags, min_flt, cmin_flt, maj_flt, cmaj_flt, utime, stime, ++ lu rss_rlim, start_code, end_code, start_stack, kstk_esp, kstk_eip, ++ lu start_time, vsize, wchan, nswap, cnswap, +*/ + +/* Basic data structure which holds all information we can get about a process. @@ -389,63 +478,66 @@ index 2d38178..8e4ed89 100644 + * Most of it comes from task_struct in linux/sched.h + */ +typedef struct proc_t { -+ // 1st 16 bytes -+ int pid; /* process id */ -+ int ppid; /* pid of parent process */ -+ -+ char state; /* single-char code for process state (S=sleeping) */ -+ -+ unsigned long long -+ utime, /* user-mode CPU time accumulated by process */ -+ stime, /* kernel-mode CPU time accumulated by process */ -+ // and so on... -+ cutime, /* cumulative utime of process and reaped children */ -+ cstime, /* cumulative stime of process and reaped children */ -+ start_time; /* start time of process -- seconds since 1-1-70 */ -+ -+ long -+ priority, /* kernel scheduling priority */ -+ timeout, /* ? */ -+ nice, /* standard unix nice level of process */ -+ rss, /* resident set size from /proc/#/stat (pages) */ -+ it_real_value; /* ? */ -+ unsigned long -+ rtprio, /* real-time priority */ -+ sched, /* scheduling class */ -+ vsize, /* number of pages of virtual memory ... */ -+ rss_rlim, /* resident set size limit? */ -+ flags, /* kernel flags for the process */ -+ min_flt, /* number of minor page faults since process start */ -+ maj_flt, /* number of major page faults since process start */ -+ cmin_flt, /* cumulative min_flt of process and child processes */ -+ cmaj_flt, /* cumulative maj_flt of process and child processes */ -+ nswap, /* ? */ -+ cnswap, /* cumulative nswap ? */ -+ start_code, /* address of beginning of code segment */ -+ end_code, /* address of end of code segment */ -+ start_stack, /* address of the bottom of stack for the process */ -+ kstk_esp, /* kernel stack pointer */ -+ kstk_eip, /* kernel instruction pointer */ -+ wchan; /* address of kernel wait channel proc is sleeping in */ -+ -+ char cmd[16]; /* basename of executable file in call to exec(2) */ -+ int -+ pgrp, /* process group id */ -+ session, /* session id */ -+ tty, /* full device number of controlling terminal */ -+ tpgid, /* terminal process group id */ -+ exit_signal, /* might not be SIGCHLD */ -+ processor; /* current (or most recent?) CPU */ ++ // 1st 16 bytes ++ int pid; /* process id */ ++ int ppid; /* pid of parent process */ ++ ++ char state; /* single-char code for process state (S=sleeping) */ ++ ++ unsigned long long ++ utime, /* user-mode CPU time accumulated by process */ ++ stime, /* kernel-mode CPU time accumulated by process */ ++ // and so on... ++ cutime, /* cumulative utime of process and reaped children */ ++ cstime, /* cumulative stime of process and reaped children */ ++ start_time; /* start time of process -- seconds since 1-1-70 */ ++ ++ long ++ priority, /* kernel scheduling priority */ ++ timeout, /* ? */ ++ nice, /* standard unix nice level of process */ ++ rss, /* resident set size from /proc/#/stat (pages) */ ++ it_real_value; /* ? */ ++ unsigned long ++ rtprio, /* real-time priority */ ++ sched, /* scheduling class */ ++ vsize, /* number of pages of virtual memory ... */ ++ rss_rlim, /* resident set size limit? */ ++ flags, /* kernel flags for the process */ ++ min_flt, /* number of minor page faults since process start */ ++ maj_flt, /* number of major page faults since process start */ ++ cmin_flt, /* cumulative min_flt of process and child processes */ ++ cmaj_flt, /* cumulative maj_flt of process and child processes */ ++ nswap, /* ? */ ++ cnswap, /* cumulative nswap ? */ ++ start_code, /* address of beginning of code segment */ ++ end_code, /* address of end of code segment */ ++ start_stack, /* address of the bottom of stack for the process */ ++ kstk_esp, /* kernel stack pointer */ ++ kstk_eip, /* kernel instruction pointer */ ++ wchan; /* address of kernel wait channel proc is sleeping in */ ++ ++ char cmd[16]; /* basename of executable file in call to exec(2) */ ++ int ++ pgrp, /* process group id */ ++ session, /* session id */ ++ tty, /* full device number of controlling terminal */ ++ tpgid, /* terminal process group id */ ++ exit_signal, /* might not be SIGCHLD */ ++ processor; /* current (or most recent?) CPU */ +} proc_t; ++#endif + static inline int lxc_set_cloexec(int fd) { return fcntl(fd, F_SETFD, FD_CLOEXEC); -@@ -245,5 +310,6 @@ extern int recursive_destroy(char *dirname); - extern int lxc_setup_keyring(void); +@@ -246,6 +313,8 @@ extern int fix_stdio_permissions(uid_t uid); - extern int fd_nonblock(int fd); + #ifdef HAVE_ISULAD + extern void lxc_write_error_message(int errfd, const char *format, ...); ++extern int lxc_file2str(const char *filename, char ret[], int cap); +extern int unsigned long long lxc_get_process_startat(pid_t pid); + #endif #endif /* __LXC_UTILS_H */ -- diff --git a/0007-use-isulad-log-format.patch b/0007-use-isulad-log-format.patch deleted file mode 100644 index a16ee90f73e0da2a0b21b2d10c797e342520ae77..0000000000000000000000000000000000000000 --- a/0007-use-isulad-log-format.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 371dc5d5822cd629b86313c6b6cb39f02e7164e8 Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Fri, 11 Jan 2019 17:00:48 +0800 -Subject: [PATCH 007/140] use isulad log format - -use isulad log format - -Signed-off-by: LiFeng ---- - src/lxc/log.c | 19 ++++++++++++++----- - 1 file changed, 14 insertions(+), 5 deletions(-) - -diff --git a/src/lxc/log.c b/src/lxc/log.c -index 4e74459..91fb7ef 100644 ---- a/src/lxc/log.c -+++ b/src/lxc/log.c -@@ -139,6 +139,7 @@ static char *lxc_log_get_va_msg(struct lxc_log_event *event) - return msg; - } - -+/* use fifo to save log */ - static const char *isulad_use_log_fifo(const char *file) - { - #define ISULAD_FIFO_PREFIX "fifo:" -@@ -150,6 +151,7 @@ static const char *isulad_use_log_fifo(const char *file) - return file; - } - -+/* open isulad fifo */ - static int isulad_open_fifo(const char *file_path) - { - #define LOG_FIFO_SIZE (1024 * 1024) -@@ -349,6 +351,8 @@ static int log_append_logfile(const struct lxc_log_appender *appender, - ssize_t ret; - int fd_to_use = -1; - const char *log_container_name; -+ const char *isulad_prefix; -+ size_t isulad_len = 0; - - #ifndef NO_LXC_CONF - if (current_config) -@@ -367,11 +371,14 @@ static int log_append_logfile(const struct lxc_log_appender *appender, - if (lxc_unix_epoch_to_utc(date_time, LXC_LOG_TIME_SIZE, &event->timestamp) < 0) - return -1; - -+ /* use isulad log format */ -+ if (log_container_name && strlen(log_container_name) > 15) { -+ isulad_len = strlen(log_container_name) - 15; -+ } -+ isulad_prefix = log_container_name ? (log_container_name + isulad_len) : log_prefix; - n = snprintf(buffer, sizeof(buffer), -- "%s%s%s %s %-8s %s - %s:%s:%d - ", -- log_prefix, -- log_container_name ? " " : "", -- log_container_name ? log_container_name : "", -+ "%15s %s %-8s %s - %s:%s:%d - ", -+ isulad_prefix, - date_time, - lxc_log_priority_to_string(event->priority), - event->category, -@@ -752,7 +759,9 @@ int lxc_log_init(struct lxc_log *log) - - if (lxc_log_fd != -1) { - lxc_log_category_lxc.appender = &log_appender_logfile; -- lxc_log_category_lxc.appender->next = &log_appender_stderr; -+ if (!lxc_quiet_specified) -+ if (!log->quiet) -+ lxc_log_category_lxc.appender->next = &log_appender_stderr; - } - - return ret; --- -1.8.3.1 - diff --git a/0030-support-block-device-as-rootfs.patch b/0008-support-block-device-as-rootfs.patch similarity index 67% rename from 0030-support-block-device-as-rootfs.patch rename to 0008-support-block-device-as-rootfs.patch index 1e548d0f01020c6ddbf2701110a6256102589713..6d84a302980b418e6a66e7ae49e80d985e30dd0f 100644 --- a/0030-support-block-device-as-rootfs.patch +++ b/0008-support-block-device-as-rootfs.patch @@ -1,26 +1,27 @@ -From c1b8d03c8911964c8323e4878ecfeca8162a7e08 Mon Sep 17 00:00:00 2001 +From 6792a7f76d9084734d94e815b462ed2977fe107e Mon Sep 17 00:00:00 2001 From: tanyifeng Date: Tue, 15 Jan 2019 16:00:30 +0800 -Subject: [PATCH 030/140] support block device as rootfs +Subject: [PATCH 08/49] support block device as rootfs Signed-off-by: LiFeng +Signed-off-by: WangFengTu --- src/lxc/Makefile.am | 1 + - src/lxc/conf.c | 10 ++--- + src/lxc/conf.c | 36 +++++++++++++++++ src/lxc/storage/block.c | 86 +++++++++++++++++++++++++++++++++++++++++ src/lxc/storage/block.h | 41 ++++++++++++++++++++ - src/lxc/storage/dir.c | 10 +---- - src/lxc/storage/storage.c | 18 +++++++++ - src/lxc/storage/storage_utils.c | 2 +- - 7 files changed, 153 insertions(+), 15 deletions(-) + src/lxc/storage/dir.c | 14 ++++++- + src/lxc/storage/storage.c | 21 ++++++++++ + src/lxc/storage/storage_utils.c | 4 ++ + 7 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 src/lxc/storage/block.c create mode 100644 src/lxc/storage/block.h diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am -index 5678b8d..260a7eb 100644 +index 21441c0..d8c2492 100644 --- a/src/lxc/Makefile.am +++ b/src/lxc/Makefile.am -@@ -130,6 +130,7 @@ liblxc_la_SOURCES = af_unix.c af_unix.h \ +@@ -139,6 +139,7 @@ liblxc_la_SOURCES = af_unix.c af_unix.h \ start.c start.h \ storage/btrfs.c storage/btrfs.h \ storage/dir.c storage/dir.h \ @@ -29,36 +30,59 @@ index 5678b8d..260a7eb 100644 storage/lvm.c storage/lvm.h \ storage/nbd.c storage/nbd.h \ diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 439353b..88763ee 100644 +index 43437af..35488e0 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c -@@ -3865,13 +3865,10 @@ static int setup_populate_devs(const struct lxc_rootfs *rootfs, struct lxc_list - // isulad: setup rootfs mountopts - static int setup_rootfs_mountopts(const struct lxc_rootfs *rootfs) - { -- unsigned long mntflags, pflags; +@@ -3383,6 +3383,36 @@ reset_umask: + INFO("Populated devices into container /dev"); + return ret; + } ++ ++// isulad: setup rootfs mountopts ++static int setup_rootfs_mountopts(const struct lxc_rootfs *rootfs) ++{ + unsigned long mflags, mntflags, pflags; - char *mntdata; - -- // only remount / when container shares rootfs with host. -- if(!rootfs || !rootfs->path || strcmp(rootfs->path, "/")) -- return 0; -- if (!rootfs->options) ++ char *mntdata; ++ + if(!rootfs || !rootfs->options) - return 0; ++ return 0; ++ ++ if (parse_propagationopts(rootfs->options, &pflags) < 0) { ++ return -1; ++ } ++ ++ if (parse_mntopts(rootfs->options, &mntflags, &mntdata) < 0) { ++ free(mntdata); ++ return -1; ++ } ++ free(mntdata); ++ ++ if (mntflags & MS_RDONLY) { ++ mflags = add_required_remount_flags("/", NULL, MS_BIND | MS_REC | mntflags | pflags | MS_REMOUNT); ++ DEBUG("remounting /"); ++ if (mount("/", "/", NULL, mflags, 0) < 0) { ++ SYSERROR("Failed to remount /"); ++ return -1; ++ } ++ } ++ return 0; ++} + #endif - if (parse_mntopts(rootfs->options, &mntflags, &pflags, &mntdata) < 0) { -@@ -3881,8 +3878,9 @@ static int setup_rootfs_mountopts(const struct lxc_rootfs *rootfs) - free(mntdata); + int lxc_setup(struct lxc_handler *handler) +@@ -3531,6 +3561,12 @@ int lxc_setup(struct lxc_handler *handler) + if (ret < 0) + return log_error(-1, "Failed to setup new devpts instance"); - if (mntflags & MS_RDONLY) { -+ mflags = add_required_remount_flags("/", NULL, MS_BIND | MS_REC | mntflags | pflags | MS_REMOUNT); - DEBUG("remounting / as readonly"); -- if (mount("/", "/", NULL, MS_BIND |MS_REMOUNT| MS_RDONLY, 0)) { -+ if (mount("/", "/", NULL, MS_BIND | MS_REMOUNT | MS_RDONLY, 0) < 0) { - SYSERROR("Failed to make / readonly."); - return -1; - } ++#ifdef HAVE_ISULAD ++ if (setup_rootfs_mountopts(&lxc_conf->rootfs)) { ++ return log_error(-1, "failed to set rootfs for '%s'", name); ++ } ++#endif ++ + ret = lxc_create_ttys(handler); + if (ret < 0) + return -1; diff --git a/src/lxc/storage/block.c b/src/lxc/storage/block.c new file mode 100644 index 0000000..eb75e70 @@ -199,38 +223,52 @@ index 0000000..2fa7565 + +#endif /* __LXC_BLK_H */ diff --git a/src/lxc/storage/dir.c b/src/lxc/storage/dir.c -index deeecec..2b548d0 100644 +index 18a10a4..b3dbbd0 100644 --- a/src/lxc/storage/dir.c +++ b/src/lxc/storage/dir.c -@@ -150,7 +150,7 @@ bool dir_detect(const char *path) +@@ -127,7 +127,11 @@ bool dir_detect(const char *path) int dir_mount(struct lxc_storage *bdev) { - int ret; -- unsigned long mflags = 0, mntflags = 0, pflags = 0; + __do_free char *mntdata = NULL; ++#ifdef HAVE_ISULAD + unsigned long mntflags = 0, pflags = 0; - char *mntdata; ++#else + unsigned long mflags = 0, mntflags = 0, pflags = 0; ++#endif + int ret; const char *src; -@@ -169,13 +169,7 @@ int dir_mount(struct lxc_storage *bdev) +@@ -147,6 +151,13 @@ int dir_mount(struct lxc_storage *bdev) src = lxc_storage_get_path(bdev->src, bdev->type); -- ret = mount(src, bdev->dest, "bind", MS_BIND | MS_REC | mntflags | pflags, mntdata); -- if ((0 == ret) && (mntflags & MS_RDONLY)) { -- DEBUG("Remounting \"%s\" on \"%s\" readonly", -- src ? src : "(none)", bdev->dest ? bdev->dest : "(none)"); -- mflags = add_required_remount_flags(src, bdev->dest, MS_BIND | MS_REC | mntflags | pflags | MS_REMOUNT); -- ret = mount(src, bdev->dest, "bind", mflags, mntdata); -- } ++#ifdef HAVE_ISULAD + ret = mount(src, bdev->dest, "bind", MS_BIND | MS_REC | (mntflags & ~MS_RDONLY) | pflags, mntdata); ++ if (ret < 0) { ++ return log_error_errno(-errno, errno, "Failed to mount \"%s\" on \"%s\"", src, bdev->dest); ++ } ++ TRACE("Mounted \"%s\" on \"%s\"", src, bdev->dest); ++#else + ret = mount(src, bdev->dest, "bind", MS_BIND | MS_REC | mntflags | pflags, mntdata); + if (ret < 0) + return log_error_errno(-errno, errno, "Failed to mount \"%s\" on \"%s\"", src, bdev->dest); +@@ -161,9 +172,10 @@ int dir_mount(struct lxc_storage *bdev) + DEBUG("Remounted \"%s\" on \"%s\" read-only with options \"%s\", mount flags \"%lu\", and propagation flags \"%lu\"", + src ? src : "(none)", bdev->dest ? bdev->dest : "(none)", mntdata, mflags, pflags); + } +- + TRACE("Mounted \"%s\" on \"%s\" with options \"%s\", mount flags \"%lu\", and propagation flags \"%lu\"", + src ? src : "(none)", bdev->dest ? bdev->dest : "(none)", mntdata, mflags, pflags); ++#endif ++ + return 0; + } - if (ret < 0) { - SYSERROR("Failed to mount \"%s\" on \"%s\"", src, bdev->dest); diff --git a/src/lxc/storage/storage.c b/src/lxc/storage/storage.c -index c4f4c2e..18f754a 100644 +index 3f1b713..876311a 100644 --- a/src/lxc/storage/storage.c +++ b/src/lxc/storage/storage.c -@@ -61,6 +61,7 @@ +@@ -41,6 +41,7 @@ #include "storage_utils.h" #include "utils.h" #include "zfs.h" @@ -238,10 +276,11 @@ index c4f4c2e..18f754a 100644 #ifndef HAVE_STRLCPY #include "include/strlcpy.h" -@@ -114,6 +115,21 @@ static const struct lxc_storage_ops loop_ops = { +@@ -94,6 +95,22 @@ static const struct lxc_storage_ops loop_ops = { .can_backup = true, }; ++#ifdef HAVE_ISULAD +/* block */ +static const struct lxc_storage_ops blk_ops = { + .detect = &blk_detect, @@ -255,30 +294,35 @@ index c4f4c2e..18f754a 100644 + .can_snapshot = false, + .can_backup = true, +}; -+ ++#endif + /* lvm */ static const struct lxc_storage_ops lvm_ops = { .detect = &lvm_detect, -@@ -199,6 +215,8 @@ static const struct lxc_storage_type bdevs[] = { +@@ -179,6 +196,10 @@ static const struct lxc_storage_type bdevs[] = { { .name = "overlayfs", .ops = &ovl_ops, }, { .name = "loop", .ops = &loop_ops, }, { .name = "nbd", .ops = &nbd_ops, }, ++#ifdef HAVE_ISULAD + //isulad: block device + { .name = "blk", .ops = &blk_ops, } ++#endif }; static const size_t numbdevs = sizeof(bdevs) / sizeof(struct lxc_storage_type); diff --git a/src/lxc/storage/storage_utils.c b/src/lxc/storage/storage_utils.c -index 46e08a3..b4dcb57 100644 +index a3ee353..bfbb782 100644 --- a/src/lxc/storage/storage_utils.c +++ b/src/lxc/storage/storage_utils.c -@@ -416,7 +416,7 @@ int find_fstype_cb(char *buffer, void *data) +@@ -335,7 +335,11 @@ int find_fstype_cb(char *buffer, void *data) return 0; } -- if (mount(cbarg->rootfs, cbarg->target, fstype, mntflags, mntdata)) { ++#ifdef HAVE_ISULAD + if (mount(cbarg->rootfs, cbarg->target, fstype, (mntflags & ~MS_RDONLY), mntdata)) { ++#else + if (mount(cbarg->rootfs, cbarg->target, fstype, mntflags, mntdata)) { ++#endif SYSDEBUG("Failed to mount"); free(mntdata); return 0; diff --git a/0009-lxc_start-add-default-terminal-fifos.patch b/0009-lxc_start-add-default-terminal-fifos.patch deleted file mode 100644 index d52551ccbee8736ac89f1b49bab170a20c142329..0000000000000000000000000000000000000000 --- a/0009-lxc_start-add-default-terminal-fifos.patch +++ /dev/null @@ -1,538 +0,0 @@ -From 3adac5cde53927f37a666fa8bda4ff06489ec694 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Fri, 11 Jan 2019 21:52:11 -0500 -Subject: [PATCH 009/140] lxc_start: add default terminal fifos - -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 4 + - src/lxc/lxccontainer.c | 30 +++++++ - src/lxc/lxccontainer.h | 10 +++ - src/lxc/terminal.c | 194 +++++++++++++++++++++++++++++++++++++++++++++- - src/lxc/terminal.h | 16 ++++ - src/lxc/tools/arguments.h | 5 ++ - src/lxc/tools/lxc_start.c | 11 +++ - src/lxc/utils.c | 23 ++++++ - src/lxc/utils.h | 4 + - 9 files changed, 294 insertions(+), 3 deletions(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 37a5ff7..7b7f95b 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -2714,6 +2714,10 @@ struct lxc_conf *lxc_conf_init(void) - new->console.slave = -1; - new->console.name[0] = '\0'; - memset(&new->console.ringbuf, 0, sizeof(struct lxc_ringbuf)); -+ /* isulad init console fifos */ -+ new->console.init_fifo[0] = NULL; -+ new->console.init_fifo[1] = NULL; -+ lxc_list_init(&new->console.fifos); - new->maincmd_fd = -1; - new->nbd_idx = -1; - new->rootfs.mount = strdup(default_rootfs_mount); -diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index 1d7f5be..318c71e 100644 ---- a/src/lxc/lxccontainer.c -+++ b/src/lxc/lxccontainer.c -@@ -4961,6 +4961,33 @@ out: - return ret; - } - -+/* isulad add set console fifos*/ -+static bool do_lxcapi_set_terminal_default_fifos(struct lxc_container *c, const char *in, const char *out) -+{ -+ struct lxc_conf *conf; -+ -+ if (!c || !c->lxc_conf || !in || !out) -+ return false; -+ if (container_mem_lock(c)) { -+ ERROR("Error getting mem lock"); -+ return false; -+ } -+ -+ conf = c->lxc_conf; -+ if (conf->console.init_fifo[0]) -+ free(conf->console.init_fifo[0]); -+ conf->console.init_fifo[0] = strdup(in); -+ -+ if (conf->console.init_fifo[1]) -+ free(conf->console.init_fifo[1]); -+ conf->console.init_fifo[1] = strdup(out); -+ -+ container_mem_unlock(c); -+ return true; -+} -+ -+WRAP_API_2(bool, lxcapi_set_terminal_default_fifos, const char *, const char *) -+ - struct lxc_container *lxc_container_new(const char *name, const char *configpath) - { - struct lxc_container *c; -@@ -5084,6 +5111,9 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath - c->migrate = lxcapi_migrate; - c->console_log = lxcapi_console_log; - -+ /* isulad add begin */ -+ c->set_terminal_init_fifos = lxcapi_set_terminal_default_fifos; -+ /* isulad add end */ - return c; - - err: -diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h -index 9e06215..486531e 100644 ---- a/src/lxc/lxccontainer.h -+++ b/src/lxc/lxccontainer.h -@@ -847,6 +847,16 @@ struct lxc_container { - * \return \c true if the container was rebooted successfully, else \c false. - */ - bool (*reboot2)(struct lxc_container *c, int timeout); -+ -+ /*! isulad add -+ * \brief An API call to change the path of the console default fifos -+ * -+ * \param c Container. -+ * \param path Value of the console path. -+ * -+ * \return \c true on success, else \c false. -+ */ -+ bool (*set_terminal_init_fifos)(struct lxc_container *c, const char *in, const char *out); - }; - - /*! -diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index 4060e7f..c507712 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -364,6 +364,20 @@ static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf, - return bytes_read; - } - -+/* isulad: forward data to all fifos */ -+static void lxc_forward_data_to_fifo(struct lxc_list *list, char *buf, int r) -+{ -+ struct lxc_list *it,*next; -+ struct lxc_fifos_fd *elem = NULL; -+ -+ lxc_list_for_each_safe(it, list, next) { -+ elem = it->elem; -+ lxc_write_nointr(elem->out_fd, buf, r); -+ } -+ -+ return; -+} -+ - int lxc_terminal_io_cb(int fd, uint32_t events, void *data, - struct lxc_epoll_descr *descr) - { -@@ -384,7 +398,13 @@ int lxc_terminal_io_cb(int fd, uint32_t events, void *data, - terminal->tty_state = NULL; - } - terminal->peer = -EBADF; -- } else { -+ close(fd); -+ return LXC_MAINLOOP_CONTINUE; /* isulad: do not close mainloop when peer close*/ -+ } else if (lxc_terminal_is_fifo(fd, &terminal->fifos)) { -+ /* isulad: delete fifos when the client close */ -+ lxc_terminal_delete_fifo(fd, &terminal->fifos); -+ return LXC_MAINLOOP_CONTINUE; -+ } else { - ERROR("Handler received unexpected file descriptor"); - } - close(fd); -@@ -392,7 +412,7 @@ int lxc_terminal_io_cb(int fd, uint32_t events, void *data, - return LXC_MAINLOOP_CLOSE; - } - -- if (fd == terminal->peer) -+ if (fd == terminal->peer || lxc_terminal_is_fifo(fd, &terminal->fifos)) - w = lxc_write_nointr(terminal->master, buf, r); - - w_rbuf = w_log = 0; -@@ -401,6 +421,9 @@ int lxc_terminal_io_cb(int fd, uint32_t events, void *data, - if (terminal->peer >= 0) - w = lxc_write_nointr(terminal->peer, buf, r); - -+ /* isulad: forward data to fifos */ -+ lxc_forward_data_to_fifo(&terminal->fifos, buf, r); -+ - /* write to terminal ringbuffer */ - if (terminal->buffer_size > 0) - w_rbuf = lxc_ringbuf_write(&terminal->ringbuf, buf, r); -@@ -450,6 +473,27 @@ static int lxc_terminal_mainloop_add_peer(struct lxc_terminal *terminal) - return 0; - } - -+/* isulad add fifo to mainloop */ -+static int lxc_console_mainloop_add_fifo(struct lxc_terminal *terminal) -+{ -+ int ret = 0; -+ struct lxc_list *it,*next; -+ struct lxc_fifos_fd *elem = NULL; -+ -+ lxc_list_for_each_safe(it, &terminal->fifos, next) { -+ elem = it->elem; -+ if (elem->in_fd >= 0) { -+ ret = lxc_mainloop_add_handler(terminal->descr, elem->in_fd, -+ lxc_terminal_io_cb, terminal); -+ if (ret) { -+ ERROR("console fifo %s not added to mainloop", elem->in_fifo); -+ return -1; -+ } -+ } -+ } -+ return ret; -+} -+ - int lxc_terminal_mainloop_add(struct lxc_epoll_descr *descr, - struct lxc_terminal *terminal) - { -@@ -473,7 +517,20 @@ int lxc_terminal_mainloop_add(struct lxc_epoll_descr *descr, - */ - terminal->descr = descr; - -- return lxc_terminal_mainloop_add_peer(terminal); -+ ret = lxc_terminal_mainloop_add_peer(terminal); -+ if (ret < 0) { -+ ERROR("Failed to add handler for terminal peer to mainloop"); -+ return -1; -+ } -+ -+ /* isulad add fifo to mainloop */ -+ ret = lxc_console_mainloop_add_fifo(terminal); -+ if (ret < 0) { -+ ERROR("Failed to add handler for terminal fifos to mainloop"); -+ return -1; -+ } -+ -+ return 0; - } - - int lxc_setup_tios(int fd, struct termios *oldtios) -@@ -812,6 +869,9 @@ void lxc_terminal_delete(struct lxc_terminal *terminal) - if (terminal->log_fd >= 0) - close(terminal->log_fd); - terminal->log_fd = -1; -+ -+ /* isulad: delete all fifos */ -+ lxc_terminal_delete_fifo(-1, &terminal->fifos); - } - - /** -@@ -880,6 +940,77 @@ int lxc_terminal_create_log_file(struct lxc_terminal *terminal) - return 0; - } - -+/* isulad: open terminal fifos */ -+static int terminal_fifo_open(const char *fifo_path, int flags) -+{ -+ int fd = -1; -+ -+ fd = open(fifo_path, flags); -+ if (fd < 0) { -+ WARN("Failed to open fifo %s to send message: %s.", fifo_path, -+ strerror(errno)); -+ return -1; -+ } -+ -+ return fd; -+} -+ -+/* isulad: set terminal fifos */ -+static int lxc_terminal_set_fifo(struct lxc_terminal *console, const char *in, const char *out) -+{ -+ int fifofd_in = -1, fifofd_out = -1; -+ struct lxc_fifos_fd *fifo_elem = NULL; -+ -+ if (!in || !out) -+ return -1; -+ -+ if (!fifo_exists(in) || !fifo_exists(out)) { -+ ERROR("File %s or %s does not refer to a FIFO", in, out); -+ return -1; -+ } -+ -+ fifofd_in = terminal_fifo_open(in, O_RDONLY | O_NONBLOCK | O_CLOEXEC); -+ if (fifofd_in < 0) { -+ ERROR("Failed to open FIFO: %s", in); -+ return -1; -+ } -+ -+ fifofd_out = terminal_fifo_open(out, O_WRONLY | O_NONBLOCK | O_CLOEXEC); -+ if (fifofd_out < 0) { -+ ERROR("Failed to open FIFO: %s", out); -+ close(fifofd_in); -+ return -1; -+ } -+ -+ fifo_elem = malloc(sizeof(*fifo_elem)); -+ if (!fifo_elem) { -+ close(fifofd_in); -+ close(fifofd_out); -+ return -1; -+ } -+ memset(fifo_elem, 0, sizeof(*fifo_elem)); -+ -+ fifo_elem->in_fifo = strdup(in); -+ fifo_elem->out_fifo = strdup(out); -+ fifo_elem->in_fd = fifofd_in; -+ fifo_elem->out_fd = fifofd_out; -+ lxc_list_add_elem(&fifo_elem->node, fifo_elem); -+ lxc_list_add_tail(&console->fifos, &fifo_elem->node); -+ -+ return fifofd_in; -+} -+ -+/* isulad: add default fifos */ -+static int lxc_terminal_fifo_default(struct lxc_terminal *terminal) -+{ -+ if (!terminal->init_fifo[0] || !terminal->init_fifo[1]) { -+ ERROR("Invalid default terminal fifos"); -+ return -1; -+ } -+ -+ return lxc_terminal_set_fifo(terminal, terminal->init_fifo[0], terminal->init_fifo[1]); -+} -+ - int lxc_terminal_create(struct lxc_terminal *terminal) - { - int ret; -@@ -902,6 +1033,13 @@ int lxc_terminal_create(struct lxc_terminal *terminal) - goto err; - } - -+ /* isulad: make master NONBLOCK */ -+ ret = fd_nonblock(terminal->master); -+ if (ret < 0) { -+ SYSERROR("Failed to set O_NONBLOCK flag on terminal master"); -+ goto err; -+ } -+ - ret = fd_cloexec(terminal->slave, true); - if (ret < 0) { - SYSERROR("Failed to set FD_CLOEXEC flag on terminal slave"); -@@ -914,6 +1052,13 @@ int lxc_terminal_create(struct lxc_terminal *terminal) - goto err; - } - -+ /* isulad: open fifos */ -+ ret = lxc_terminal_fifo_default(terminal); -+ if (ret < 0) { -+ ERROR("Failed to allocate fifo terminal"); -+ goto err; -+ } -+ - return 0; - - err: -@@ -1198,12 +1343,55 @@ void lxc_terminal_init(struct lxc_terminal *terminal) - lxc_terminal_info_init(&terminal->proxy); - } - -+/* isulad: judge the fd whether is fifo */ -+static bool lxc_terminal_is_fifo(int fd, struct lxc_list *list) -+{ -+ struct lxc_list *it,*next; -+ struct lxc_fifos_fd *elem = NULL; -+ -+ lxc_list_for_each_safe(it, list, next) { -+ elem = it->elem; -+ if (elem->in_fd == fd) -+ return true; -+ } -+ -+ return false; -+} -+ -+/* isulad: if fd == -1, means delete all the fifos*/ -+int lxc_terminal_delete_fifo(int fd, struct lxc_list *list) -+{ -+ struct lxc_list *it,*next; -+ struct lxc_fifos_fd *elem = NULL; -+ -+ lxc_list_for_each_safe(it, list, next) { -+ elem = it->elem; -+ if (elem->in_fd == fd || -1 == fd) { -+ INFO("Delete fifo fd %d", fd); -+ lxc_list_del(it); -+ if (elem->in_fifo) -+ free(elem->in_fifo); -+ if (elem->out_fifo) -+ free(elem->out_fifo); -+ close(elem->in_fd); -+ close(elem->out_fd); -+ free(elem); -+ } -+ } -+ -+ return 0; -+} -+ - void lxc_terminal_conf_free(struct lxc_terminal *terminal) - { - free(terminal->log_path); - free(terminal->path); - if (terminal->buffer_size > 0 && terminal->ringbuf.addr) - lxc_ringbuf_release(&terminal->ringbuf); -+ /*isulad: free console fifos */ -+ free(terminal->init_fifo[0]); -+ free(terminal->init_fifo[1]); -+ lxc_terminal_delete_fifo(-1, &terminal->fifos); - } - - int lxc_terminal_map_ids(struct lxc_conf *c, struct lxc_terminal *terminal) -diff --git a/src/lxc/terminal.h b/src/lxc/terminal.h -index bfd271f..d25da65 100644 ---- a/src/lxc/terminal.h -+++ b/src/lxc/terminal.h -@@ -115,6 +115,17 @@ struct lxc_terminal { - /* the in-memory ringbuffer */ - struct lxc_ringbuf ringbuf; - }; -+ char *init_fifo[2]; /* isulad: default fifos for the start */ -+ struct lxc_list fifos; /* isulad: fifos used to forward teminal */ -+}; -+ -+/* isulad: fifo struct */ -+struct lxc_fifos_fd { -+ char *in_fifo; -+ char *out_fifo; -+ int in_fd; -+ int out_fd; -+ struct lxc_list node; - }; - - /** -@@ -295,4 +306,9 @@ extern void lxc_terminal_init(struct lxc_terminal *terminal); - extern int lxc_terminal_map_ids(struct lxc_conf *c, - struct lxc_terminal *terminal); - -+/* isulad: judge the fd whether is fifo*/ -+static bool lxc_terminal_is_fifo(int fd, struct lxc_list *list); -+/* isulad: if fd == -1, means delete all the fifos*/ -+int lxc_terminal_delete_fifo(int fd, struct lxc_list *list); -+ - #endif /* __LXC_TERMINAL_H */ -diff --git a/src/lxc/tools/arguments.h b/src/lxc/tools/arguments.h -index 810050a..b7af2b5 100644 ---- a/src/lxc/tools/arguments.h -+++ b/src/lxc/tools/arguments.h -@@ -62,6 +62,7 @@ struct lxc_arguments { - - /* for lxc-start */ - const char *share_ns[32]; /* size must be greater than LXC_NS_MAX */ -+ const char *terminal_fifos[2]; /* isulad add, fifos used to redirct stdin/out/err */ - - /* for lxc-console */ - unsigned int ttynum; -@@ -172,6 +173,10 @@ struct lxc_arguments { - #define OPT_SHARE_IPC OPT_USAGE - 4 - #define OPT_SHARE_UTS OPT_USAGE - 5 - #define OPT_SHARE_PID OPT_USAGE - 6 -+/* isulad add begin */ -+#define OPT_INPUT_FIFO OPT_USAGE - 7 -+#define OPT_OUTPUT_FIFO OPT_USAGE - 8 -+/* isulad add end*/ - - extern int lxc_arguments_parse(struct lxc_arguments *args, int argc, - char *const argv[]); -diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c -index 4553cb5..8f03f11 100644 ---- a/src/lxc/tools/lxc_start.c -+++ b/src/lxc/tools/lxc_start.c -@@ -69,6 +69,8 @@ static const struct option my_longopts[] = { - {"share-ipc", required_argument, 0, OPT_SHARE_IPC}, - {"share-uts", required_argument, 0, OPT_SHARE_UTS}, - {"share-pid", required_argument, 0, OPT_SHARE_PID}, -+ {"in-fifo", required_argument, 0, OPT_INPUT_FIFO}, -+ {"out-fifo", required_argument, 0, OPT_OUTPUT_FIFO}, - LXC_COMMON_OPTIONS - }; - -@@ -140,6 +142,12 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) - case OPT_SHARE_PID: - args->share_ns[LXC_NS_PID] = arg; - break; -+ case OPT_INPUT_FIFO: -+ args->terminal_fifos[0] = arg; -+ break; -+ case OPT_OUTPUT_FIFO: -+ args->terminal_fifos[1] = arg; -+ break; - } - return 0; - } -@@ -322,6 +330,9 @@ int main(int argc, char *argv[]) - if (my_args.close_all_fds) - c->want_close_all_fds(c, true); - -+ if (my_args.terminal_fifos[0] && my_args.terminal_fifos[1]) -+ c->set_terminal_init_fifos(c, my_args.terminal_fifos[0], my_args.terminal_fifos[1]); -+ - if (args == default_args) - err = c->start(c, 0, NULL) ? EXIT_SUCCESS : EXIT_FAILURE; - else -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index 6e9165a..67c3b3e 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -611,6 +611,19 @@ bool dir_exists(const char *path) - return S_ISDIR(sb.st_mode); - } - -+bool fifo_exists(const char *path) -+{ -+ struct stat sb; -+ int ret; -+ -+ ret = stat(path, &sb); -+ if (ret < 0) -+ // could be something other than eexist, just say no -+ return false; -+ return S_ISFIFO(sb.st_mode); -+} -+ -+ - /* Note we don't use SHA-1 here as we don't want to depend on HAVE_GNUTLS. - * FNV has good anti collision properties and we're not worried - * about pre-image resistance or one-way-ness, we're just trying to make -@@ -1715,6 +1728,16 @@ int fd_cloexec(int fd, bool cloexec) - return 0; - } - -+/* isulad: fd_nonblock */ -+int fd_nonblock(int fd) -+{ -+ long flags; -+ -+ flags = fcntl(fd, F_GETFL); -+ -+ return fcntl(fd, F_SETFL, flags | O_NONBLOCK); -+} -+ - int recursive_destroy(char *dirname) - { - int ret; -diff --git a/src/lxc/utils.h b/src/lxc/utils.h -index 94196d0..2d38178 100644 ---- a/src/lxc/utils.h -+++ b/src/lxc/utils.h -@@ -147,6 +147,8 @@ extern gid_t get_ns_gid(gid_t orig); - - extern bool dir_exists(const char *path); - -+extern bool fifo_exists(const char *path); -+ - #define FNV1A_64_INIT ((uint64_t)0xcbf29ce484222325ULL) - extern uint64_t fnv_64a_buf(void *buf, size_t len, uint64_t hval); - -@@ -242,4 +244,6 @@ extern int fd_cloexec(int fd, bool cloexec); - extern int recursive_destroy(char *dirname); - extern int lxc_setup_keyring(void); - -+extern int fd_nonblock(int fd); -+ - #endif /* __LXC_UTILS_H */ --- -1.8.3.1 - diff --git a/0033-support-mount-squashfs-in-mount-entry.patch b/0009-support-mount-squashfs-in-mount-entry.patch similarity index 74% rename from 0033-support-mount-squashfs-in-mount-entry.patch rename to 0009-support-mount-squashfs-in-mount-entry.patch index d0384e1f1e5fd051bbcf07c4baedffb5625a63f4..99bbb8af7c7b8d86b76c504a555b4341afea3ee0 100644 --- a/0033-support-mount-squashfs-in-mount-entry.patch +++ b/0009-support-mount-squashfs-in-mount-entry.patch @@ -1,33 +1,35 @@ -From 572633fe6deaea6b8e4d423225aab452c6f0b7c0 Mon Sep 17 00:00:00 2001 +From 6124835dde5abfeeb8ac796813f2f18803b96117 Mon Sep 17 00:00:00 2001 From: tanyifeng Date: Tue, 15 Jan 2019 19:54:13 +0800 -Subject: [PATCH 033/140] support mount squashfs in mount entry +Subject: [PATCH 09/49] support mount squashfs in mount entry Signed-off-by: LiFeng +Signed-off-by: WangFengTu --- - src/lxc/conf.c | 88 +++++++++++++++++++++++++++++++++++++++-- - src/lxc/storage/loop.c | 36 ++++++++++++++--- - src/lxc/storage/storage_utils.c | 36 ++++++++++++++++- - src/lxc/utils.c | 33 ++++++++++++++-- + src/lxc/conf.c | 95 +++++++++++++++++++++++++++++++++++++++-- + src/lxc/storage/loop.c | 36 +++++++++++++--- + src/lxc/storage/storage_utils.c | 36 +++++++++++++++- + src/lxc/utils.c | 35 ++++++++++++++- src/lxc/utils.h | 1 + - 5 files changed, 181 insertions(+), 13 deletions(-) + 5 files changed, 191 insertions(+), 12 deletions(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 54b967b..fea0f59 100644 +index 35488e0..1f779b9 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c -@@ -78,6 +78,7 @@ +@@ -58,6 +58,7 @@ #include "storage/overlay.h" #include "syscall_wrappers.h" #include "terminal.h" +#include "loop.h" - #include "path.h" #include "utils.h" + #include "uuid.h" -@@ -2444,6 +2445,82 @@ static int mount_entry_create_dir_file(const struct mntent *mntent, +@@ -2013,6 +2014,84 @@ static int mount_entry_create_dir_file(const struct mntent *mntent, return 0; } ++#ifdef HAVE_ISULAD +static int mount_entry_with_loop_dev(const char *src, const char *dest, const char *fstype, + char *mnt_opts, const char *rootfs) +{ @@ -103,48 +105,54 @@ index 54b967b..fea0f59 100644 + + return 0; +} ++#endif + /* rootfs, lxc_name, and lxc_path can be NULL when the container is created * without a rootfs. */ static inline int mount_entry_on_generic(struct mntent *mntent, -@@ -2502,8 +2579,14 @@ static inline int mount_entry_on_generic(struct mntent *mntent, - return -1; - } +@@ -2026,6 +2105,7 @@ static inline int mount_entry_on_generic(struct mntent *mntent, + char *rootfs_path = NULL; + int ret; + bool dev, optional, relative; ++ const char *dest = path; -- ret = mount_entry(mntent->mnt_fsname, dest, mntent->mnt_type, mntflags, + optional = hasmntopt(mntent, "optional") != NULL; + dev = hasmntopt(mntent, "dev") != NULL; +@@ -2052,9 +2132,18 @@ static inline int mount_entry_on_generic(struct mntent *mntent, + if (ret < 0) + return ret; + +- ret = mount_entry(mntent->mnt_fsname, path, mntent->mnt_type, mntflags, - pflags, mntdata, optional, dev, relative, rootfs_path); +- ++#ifdef HAVE_ISULAD + // isulad: support squashfs + if (strcmp(mntent->mnt_type, "squashfs") == 0) { + ret = mount_entry_with_loop_dev(mntent->mnt_fsname, dest, mntent->mnt_type, + mntent->mnt_opts, rootfs_path); -+ } else { -+ ret = mount_entry(mntent->mnt_fsname, dest, mntent->mnt_type, mntflags, -+ pflags, mntdata, optional, dev, relative, rootfs_path); -+ } - - free(mntdata); - free(rpath); -@@ -3897,7 +3980,6 @@ static int setup_rootfs_mountopts(const struct lxc_rootfs *rootfs) - return 0; ++ } else { ++#endif ++ ret = mount_entry(mntent->mnt_fsname, dest, mntent->mnt_type, mntflags, ++ pflags, mntdata, optional, dev, relative, rootfs_path); ++#ifdef HAVE_ISULAD ++ } ++#endif + return ret; } -- - int lxc_setup(struct lxc_handler *handler) - { - int ret; diff --git a/src/lxc/storage/loop.c b/src/lxc/storage/loop.c -index 35cb13e..760def8 100644 +index eebc1b6..345be50 100644 --- a/src/lxc/storage/loop.c +++ b/src/lxc/storage/loop.c -@@ -41,6 +41,7 @@ - #include "loop.h" +@@ -21,6 +21,7 @@ + #include "memory_utils.h" #include "storage.h" #include "storage_utils.h" +#include "lxclock.h" #include "utils.h" lxc_log_define(loop, lxc); -@@ -236,9 +237,11 @@ bool loop_detect(const char *path) +@@ -216,9 +217,11 @@ bool loop_detect(const char *path) int loop_mount(struct lxc_storage *bdev) { @@ -157,7 +165,7 @@ index 35cb13e..760def8 100644 if (strcmp(bdev->type, "loop")) return -22; -@@ -246,13 +249,29 @@ int loop_mount(struct lxc_storage *bdev) +@@ -226,13 +229,29 @@ int loop_mount(struct lxc_storage *bdev) if (!bdev->src || !bdev->dest) return -22; @@ -188,7 +196,7 @@ index 35cb13e..760def8 100644 } DEBUG("Prepared loop device \"%s\"", loname); -@@ -261,14 +280,21 @@ int loop_mount(struct lxc_storage *bdev) +@@ -241,14 +260,21 @@ int loop_mount(struct lxc_storage *bdev) ERROR("Failed to mount rootfs \"%s\" on \"%s\" via loop device \"%s\"", bdev->src, bdev->dest, loname); close(loopfd); @@ -214,10 +222,10 @@ index 35cb13e..760def8 100644 int loop_umount(struct lxc_storage *bdev) diff --git a/src/lxc/storage/storage_utils.c b/src/lxc/storage/storage_utils.c -index b4dcb57..0a87778 100644 +index bfbb782..07eee22 100644 --- a/src/lxc/storage/storage_utils.c +++ b/src/lxc/storage/storage_utils.c -@@ -339,10 +339,14 @@ int is_blktype(struct lxc_storage *b) +@@ -259,10 +259,14 @@ int is_blktype(struct lxc_storage *b) return 0; } @@ -232,7 +240,7 @@ index b4dcb57..0a87778 100644 int ret; struct cbarg { const char *rootfs; -@@ -371,15 +375,30 @@ int mount_unknown_fs(const char *rootfs, const char *target, +@@ -291,15 +295,30 @@ int mount_unknown_fs(const char *rootfs, const char *target, ret = lxc_file_for_each_line(fsfile[i], find_fstype_cb, &cbarg); if (ret < 0) { ERROR("Failed to parse \"%s\"", fsfile[i]); @@ -265,17 +273,17 @@ index b4dcb57..0a87778 100644 return -1; } -@@ -399,6 +418,8 @@ int find_fstype_cb(char *buffer, void *data) - unsigned long mntflags, pflags; - char *mntdata; +@@ -318,6 +337,8 @@ int find_fstype_cb(char *buffer, void *data) + unsigned long mntflags = 0; + char *mntdata = NULL; char *fstype; + char mount_err[BUFSIZ] = {0}; + int ret; /* we don't try 'nodev' entries */ if (strstr(buffer, "nodev")) -@@ -419,6 +440,17 @@ int find_fstype_cb(char *buffer, void *data) - if (mount(cbarg->rootfs, cbarg->target, fstype, (mntflags & ~MS_RDONLY), mntdata)) { +@@ -342,6 +363,17 @@ int find_fstype_cb(char *buffer, void *data) + #endif SYSDEBUG("Failed to mount"); free(mntdata); + // isulad: recored error @@ -293,10 +301,18 @@ index b4dcb57..0a87778 100644 } diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index d1a22f7..120a13d 100644 +index ebcdae0..90113e0 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c -@@ -1053,7 +1053,7 @@ static int open_if_safe(int dirfd, const char *nextpath) +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + #include "config.h" + #include "log.h" +@@ -1008,7 +1009,7 @@ static int open_if_safe(int dirfd, const char *nextpath) * * Return an open fd for the path, or <0 on error. */ @@ -305,7 +321,7 @@ index d1a22f7..120a13d 100644 { int curlen = 0, dirfd, fulllen, i; char *dup; -@@ -1473,6 +1473,9 @@ static int lxc_get_unused_loop_dev(char *name_loop) +@@ -1425,6 +1426,9 @@ static int lxc_get_unused_loop_dev(char *name_loop) { int loop_nr, ret; int fd_ctl = -1, fd_tmp = -1; @@ -315,15 +331,15 @@ index d1a22f7..120a13d 100644 fd_ctl = open("/dev/loop-control", O_RDWR | O_CLOEXEC); if (fd_ctl < 0) { -@@ -1489,10 +1492,34 @@ static int lxc_get_unused_loop_dev(char *name_loop) +@@ -1441,9 +1445,35 @@ static int lxc_get_unused_loop_dev(char *name_loop) ret = snprintf(name_loop, LO_NAME_SIZE, "/dev/loop%d", loop_nr); if (ret < 0 || ret >= LO_NAME_SIZE) goto on_error; - +retry: fd_tmp = open(name_loop, O_RDWR | O_CLOEXEC); -- if (fd_tmp < 0) -+ if (fd_tmp < 0) { + if (fd_tmp < 0) { ++#if HAVE_ISULAD + /* Success of LOOP_CTL_GET_FREE doesn't mean /dev/loop$i is ready, + * we try to make node by ourself to avoid wait. */ + if (try_mknod) { @@ -346,17 +362,25 @@ index d1a22f7..120a13d 100644 + usleep(5000); /* 5 millisecond */ + goto retry; + } - SYSERROR("Failed to open loop \"%s\"", name_loop); ++ SYSERROR("Failed to open loop \"%s\"", name_loop); + goto on_error; -+ } ++#else + /* on Android loop devices are moved under /dev/block, give it a shot */ + ret = snprintf(name_loop, LO_NAME_SIZE, "/dev/block/loop%d", loop_nr); + if (ret < 0 || ret >= LO_NAME_SIZE) +@@ -1452,6 +1482,7 @@ static int lxc_get_unused_loop_dev(char *name_loop) + fd_tmp = open(name_loop, O_RDWR | O_CLOEXEC); + if (fd_tmp < 0) + SYSERROR("Failed to open loop \"%s\"", name_loop); ++#endif + } on_error: - close(fd_ctl); diff --git a/src/lxc/utils.h b/src/lxc/utils.h -index abc88ca..4313942 100644 +index 11d6548..fbb0d55 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h -@@ -224,6 +224,7 @@ extern bool cgns_supported(void); +@@ -215,6 +215,7 @@ extern bool cgns_supported(void); extern char *choose_init(const char *rootfs); extern bool switch_to_ns(pid_t pid, const char *ns); extern char *get_template_path(const char *t); diff --git a/0010-IO-refact-terminal-progress.patch b/0010-IO-refact-terminal-progress.patch new file mode 100644 index 0000000000000000000000000000000000000000..4e413863bb4313079f2fc6d06f0337820389a06f --- /dev/null +++ b/0010-IO-refact-terminal-progress.patch @@ -0,0 +1,3568 @@ +From 1dce19b2ce4d01c12f3f4eda0666457f2fd3c42c Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Mon, 13 Apr 2020 18:11:59 +0800 +Subject: [PATCH 10/49] IO: refact terminal progress + +Signed-off-by: LiFeng +--- + configure.ac | 3 + + src/lxc/Makefile.am | 24 +- + src/lxc/attach.c | 20 +- + src/lxc/attach_options.h | 5 + + src/lxc/conf.c | 10 + + src/lxc/json/defs.c | 205 +++++++ + src/lxc/json/defs.h | 37 ++ + src/lxc/json/json_common.c | 1153 ++++++++++++++++++++++++++++++++++++++ + src/lxc/json/json_common.h | 185 ++++++ + src/lxc/json/logger_json_file.c | 246 ++++++++ + src/lxc/json/logger_json_file.h | 45 ++ + src/lxc/json/oci_runtime_hooks.c | 52 ++ + src/lxc/json/oci_runtime_hooks.h | 15 + + src/lxc/json/oci_runtime_spec.c | 195 +++++++ + src/lxc/json/oci_runtime_spec.h | 37 ++ + src/lxc/json/read-file.c | 95 ++++ + src/lxc/json/read-file.h | 11 + + src/lxc/lxccontainer.c | 36 ++ + src/lxc/lxccontainer.h | 24 + + src/lxc/terminal.c | 783 ++++++++++++++++++++++++++ + src/lxc/terminal.h | 20 + + src/lxc/tools/arguments.h | 1 + + src/lxc/tools/lxc_start.c | 12 + + 23 files changed, 3208 insertions(+), 6 deletions(-) + create mode 100644 src/lxc/json/defs.c + create mode 100644 src/lxc/json/defs.h + create mode 100755 src/lxc/json/json_common.c + create mode 100755 src/lxc/json/json_common.h + create mode 100644 src/lxc/json/logger_json_file.c + create mode 100644 src/lxc/json/logger_json_file.h + create mode 100644 src/lxc/json/oci_runtime_hooks.c + create mode 100644 src/lxc/json/oci_runtime_hooks.h + create mode 100644 src/lxc/json/oci_runtime_spec.c + create mode 100644 src/lxc/json/oci_runtime_spec.h + create mode 100644 src/lxc/json/read-file.c + create mode 100644 src/lxc/json/read-file.h + +diff --git a/configure.ac b/configure.ac +index 5f386d9..56d0cb7 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -119,6 +119,9 @@ AM_CONDITIONAL([DISTRO_UBUNTU], [test "x$with_distro" = "xubuntu"]) + + AC_CONFIG_LINKS([config/etc/default.conf:config/etc/${distroconf}]) + ++# Check yajl ++PKG_CHECK_MODULES([YAJL], [yajl >= 2],[],[AC_MSG_ERROR([You must install yajl >= 2])]) ++ + # Check for init system type + AC_MSG_CHECKING([for init system type]) + AC_ARG_WITH([init-script], +diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am +index d8c2492..23935e5 100644 +--- a/src/lxc/Makefile.am ++++ b/src/lxc/Makefile.am +@@ -53,7 +53,12 @@ noinst_HEADERS = api_extensions.h \ + uuid.h + + #if HAVE_ISULAD +-noinst_HEADERS += isulad_utils.h path.h ++noinst_HEADERS += isulad_utils.h path.h \ ++ json/json_common.h json/defs.h \ ++ json/oci_runtime_hooks.h \ ++ json/logger_json_file.h \ ++ json/oci_runtime_spec.h \ ++ json/read-file.h + #endif + + if IS_BIONIC +@@ -159,10 +164,16 @@ liblxc_la_SOURCES = af_unix.c af_unix.h \ + version.h \ + $(LSM_SOURCES) + +-#if HAVE_ISULAD ++if HAVE_ISULAD + liblxc_la_SOURCES += isulad_utils.c isulad_utils.h \ +- path.c path.h +-#endif ++ path.c path.h \ ++ json/json_common.c json/json_common.h \ ++ json/defs.h json/defs.c \ ++ json/oci_runtime_hooks.c json/oci_runtime_hooks.h \ ++ json/logger_json_file.c json/logger_json_file.h \ ++ json/oci_runtime_spec.c json/oci_runtime_spec.h \ ++ json/read-file.c json/read-file.h ++endif + + if IS_BIONIC + liblxc_la_SOURCES += ../include/fexecve.c ../include/fexecve.h \ +@@ -223,6 +234,7 @@ AM_CFLAGS = -DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \ + -I $(top_srcdir)/src/lxc/cgroups + + if HAVE_ISULAD ++AM_CFLAGS += -I $(top_srcdir)/src/lxc/json + AM_CFLAGS += -DHAVE_ISULAD + endif + if ENABLE_APPARMOR +@@ -271,6 +283,10 @@ liblxc_la_LDFLAGS = -pthread \ + -Wl,-soname,liblxc.so.$(firstword $(subst ., ,@LXC_ABI@)) \ + -version-info @LXC_ABI_MAJOR@ + ++if HAVE_ISULAD ++liblxc_la_LDFLAGS += @YAJL_LIBS@ ++endif ++ + liblxc_la_LIBADD = $(CAP_LIBS) \ + $(OPENSSL_LIBS) \ + $(SELINUX_LIBS) \ +diff --git a/src/lxc/attach.c b/src/lxc/attach.c +index 56d62ed..78b4700 100644 +--- a/src/lxc/attach.c ++++ b/src/lxc/attach.c +@@ -898,12 +898,28 @@ on_error: + } + + static int lxc_attach_terminal(struct lxc_conf *conf, +- struct lxc_terminal *terminal) ++ struct lxc_terminal *terminal, lxc_attach_options_t *options) + { + int ret; + + lxc_terminal_init(terminal); + ++#ifdef HAVE_ISULAD ++ /* isulad: if we pass fifo in option, use them as init fifos */ ++ if (options->init_fifo[0]) { ++ free(terminal->init_fifo[0]); ++ terminal->init_fifo[0] = safe_strdup(options->init_fifo[0]); ++ } ++ if (options->init_fifo[1]) { ++ free(terminal->init_fifo[1]); ++ terminal->init_fifo[1] = safe_strdup(options->init_fifo[1]); ++ } ++ if (options->init_fifo[2]) { ++ free(terminal->init_fifo[2]); ++ terminal->init_fifo[2] = safe_strdup(options->init_fifo[2]); ++ } ++#endif ++ + ret = lxc_terminal_create(terminal); + if (ret < 0) + return log_error(-1, "Failed to create terminal"); +@@ -1097,7 +1113,7 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + } + + if (options->attach_flags & LXC_ATTACH_TERMINAL) { +- ret = lxc_attach_terminal(conf, &terminal); ++ ret = lxc_attach_terminal(conf, &terminal, options); + if (ret < 0) { + ERROR("Failed to setup new terminal"); + free(cwd); +diff --git a/src/lxc/attach_options.h b/src/lxc/attach_options.h +index ec8bea1..3a02ee5 100644 +--- a/src/lxc/attach_options.h ++++ b/src/lxc/attach_options.h +@@ -113,6 +113,11 @@ typedef struct lxc_attach_options_t { + + /*! File descriptor to log output. */ + int log_fd; ++#ifdef HAVE_ISULAD ++ char *init_fifo[3]; /* isulad: default fifos for the start */ ++ int64_t timeout;/* isulad: Seconds for waiting on a container to attach/exec before it is killed*/ ++#endif ++ + } lxc_attach_options_t; + + /*! Default attach options to use */ +diff --git a/src/lxc/conf.c b/src/lxc/conf.c +index 1f779b9..1487b73 100644 +--- a/src/lxc/conf.c ++++ b/src/lxc/conf.c +@@ -2669,6 +2669,16 @@ struct lxc_conf *lxc_conf_init(void) + /* isulad add begin */ + lxc_list_init(&new->populate_devs); + new->umask = 0027; /*default umask 0027*/ ++ new->console.init_fifo[0] = NULL; ++ new->console.init_fifo[1] = NULL; ++ new->console.init_fifo[2] = NULL; ++ new->console.pipes[0][0] = -1; ++ new->console.pipes[0][1] = -1; ++ new->console.pipes[1][0] = -1; ++ new->console.pipes[1][1] = -1; ++ new->console.pipes[2][0] = -1; ++ new->console.pipes[2][1] = -1; ++ lxc_list_init(&new->console.fifos); + #endif + + return new; +diff --git a/src/lxc/json/defs.c b/src/lxc/json/defs.c +new file mode 100644 +index 0000000..4bf569a +--- /dev/null ++++ b/src/lxc/json/defs.c +@@ -0,0 +1,205 @@ ++// Generated from defs.json. Do not edit! ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE ++#endif ++#include ++#include ++#include "defs.h" ++ ++defs_hook *make_defs_hook(yajl_val tree, struct parser_context *ctx, parser_error *err) { ++ defs_hook *ret = NULL; ++ *err = 0; ++ if (tree == NULL) ++ return ret; ++ ret = safe_malloc(sizeof(*ret)); ++ { ++ yajl_val val = get_val(tree, "path", yajl_t_string); ++ if (val != NULL) { ++ char *str = YAJL_GET_STRING(val); ++ ret->path = safe_strdup(str ? str : ""); ++ } ++ } ++ { ++ yajl_val tmp = get_val(tree, "args", yajl_t_array); ++ if (tmp != NULL && YAJL_GET_ARRAY(tmp) != NULL && YAJL_GET_ARRAY(tmp)->len > 0) { ++ size_t i; ++ ret->args_len = YAJL_GET_ARRAY(tmp)->len; ++ if (YAJL_GET_ARRAY(tmp)->len > SIZE_MAX / sizeof(*ret->args) - 1) { ++ free_defs_hook(ret); ++ return NULL; ++ } ++ ret->args = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->args)); ++ for (i = 0; i < YAJL_GET_ARRAY(tmp)->len; i++) { ++ yajl_val val = YAJL_GET_ARRAY(tmp)->values[i]; ++ if (val != NULL) { ++ char *str = YAJL_GET_STRING(val); ++ ret->args[i] = safe_strdup(str ? str : ""); ++ } ++ } ++ } ++ } ++ { ++ yajl_val tmp = get_val(tree, "env", yajl_t_array); ++ if (tmp != NULL && YAJL_GET_ARRAY(tmp) != NULL && YAJL_GET_ARRAY(tmp)->len > 0) { ++ size_t i; ++ ret->env_len = YAJL_GET_ARRAY(tmp)->len; ++ if (YAJL_GET_ARRAY(tmp)->len > SIZE_MAX / sizeof(*ret->env) - 1) { ++ free_defs_hook(ret); ++ return NULL; ++ } ++ ret->env = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->env)); ++ for (i = 0; i < YAJL_GET_ARRAY(tmp)->len; i++) { ++ yajl_val val = YAJL_GET_ARRAY(tmp)->values[i]; ++ if (val != NULL) { ++ char *str = YAJL_GET_STRING(val); ++ ret->env[i] = safe_strdup(str ? str : ""); ++ } ++ } ++ } ++ } ++ { ++ yajl_val val = get_val(tree, "timeout", yajl_t_number); ++ if (val != NULL) { ++ int invalid = common_safe_int(YAJL_GET_NUMBER(val), (int *)&ret->timeout); ++ if (invalid) { ++ if (asprintf(err, "Invalid value '%s' with type 'integer' for key 'timeout': %s", YAJL_GET_NUMBER(val), strerror(-invalid)) < 0) ++ *err = safe_strdup("error allocating memory"); ++ free_defs_hook(ret); ++ return NULL; ++ } ++ } ++ } ++ if (ret->path == NULL) { ++ if (asprintf(err, "Required field '%s' not present", "path") < 0) ++ *err = safe_strdup("error allocating memory"); ++ free_defs_hook(ret); ++ return NULL; ++ } ++ ++ if (tree->type == yajl_t_object && (ctx->options & PARSE_OPTIONS_STRICT)) { ++ int i; ++ for (i = 0; i < tree->u.object.len; i++) ++ if (strcmp(tree->u.object.keys[i], "path") && ++ strcmp(tree->u.object.keys[i], "args") && ++ strcmp(tree->u.object.keys[i], "env") && ++ strcmp(tree->u.object.keys[i], "timeout")) { ++ if (ctx->stderr > 0) ++ fprintf(ctx->stderr, "WARNING: unknown key found: %s\n", tree->u.object.keys[i]); ++ } ++ } ++ return ret; ++} ++ ++void free_defs_hook(defs_hook *ptr) { ++ if (ptr == NULL) ++ return; ++ free(ptr->path); ++ ptr->path = NULL; ++ if (ptr->args != NULL) { ++ size_t i; ++ for (i = 0; i < ptr->args_len; i++) { ++ if (ptr->args[i] != NULL) { ++ free(ptr->args[i]); ++ ptr->args[i] = NULL; ++ } ++ } ++ free(ptr->args); ++ ptr->args = NULL; ++ } ++ if (ptr->env != NULL) { ++ size_t i; ++ for (i = 0; i < ptr->env_len; i++) { ++ if (ptr->env[i] != NULL) { ++ free(ptr->env[i]); ++ ptr->env[i] = NULL; ++ } ++ } ++ free(ptr->env); ++ ptr->env = NULL; ++ } ++ free(ptr); ++} ++ ++yajl_gen_status gen_defs_hook(yajl_gen g, defs_hook *ptr, struct parser_context *ctx, parser_error *err) { ++ yajl_gen_status stat = yajl_gen_status_ok; ++ *err = 0; ++ stat = reformat_start_map(g); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->path != NULL)) { ++ char *str = ""; ++ stat = reformat_map_key(g, "path", strlen("path")); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ if (ptr != NULL && ptr->path != NULL) { ++ str = ptr->path; ++ } ++ stat = reformat_string(g, str, strlen(str)); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) || (ptr != NULL && ptr->args != NULL)) { ++ size_t len = 0, i; ++ stat = reformat_map_key(g, "args", strlen("args")); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ if (ptr != NULL && ptr->args != NULL) { ++ len = ptr->args_len; ++ } ++ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) ++ yajl_gen_config(g, yajl_gen_beautify, 0); ++ stat = reformat_start_array(g); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ for (i = 0; i < len; i++) { ++ stat = reformat_string(g, ptr->args[i], strlen(ptr->args[i])); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ stat = reformat_end_array(g); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) ++ yajl_gen_config(g, yajl_gen_beautify, 1); ++ } ++ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) || (ptr != NULL && ptr->env != NULL)) { ++ size_t len = 0, i; ++ stat = reformat_map_key(g, "env", strlen("env")); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ if (ptr != NULL && ptr->env != NULL) { ++ len = ptr->env_len; ++ } ++ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) ++ yajl_gen_config(g, yajl_gen_beautify, 0); ++ stat = reformat_start_array(g); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ for (i = 0; i < len; i++) { ++ stat = reformat_string(g, ptr->env[i], strlen(ptr->env[i])); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ stat = reformat_end_array(g); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) ++ yajl_gen_config(g, yajl_gen_beautify, 1); ++ } ++ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->timeout)) { ++ long long int num = 0; ++ stat = reformat_map_key(g, "timeout", strlen("timeout")); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ if (ptr != NULL && ptr->timeout) { ++ num = (long long int)ptr->timeout; ++ } ++ stat = reformat_int(g, num); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ stat = reformat_end_map(g); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ return yajl_gen_status_ok; ++} +diff --git a/src/lxc/json/defs.h b/src/lxc/json/defs.h +new file mode 100644 +index 0000000..0bbd8ac +--- /dev/null ++++ b/src/lxc/json/defs.h +@@ -0,0 +1,37 @@ ++// Generated from defs.json. Do not edit! ++#ifndef DEFS_SCHEMA_H ++#define DEFS_SCHEMA_H ++ ++#include ++#include ++#include "json_common.h" ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++typedef struct { ++ char *path; ++ ++ char **args; ++ size_t args_len; ++ ++ char **env; ++ size_t env_len; ++ ++ int timeout; ++ ++} ++defs_hook; ++ ++void free_defs_hook(defs_hook *ptr); ++ ++defs_hook *make_defs_hook(yajl_val tree, struct parser_context *ctx, parser_error *err); ++ ++yajl_gen_status gen_defs_hook(yajl_gen g, defs_hook *ptr, struct parser_context *ctx, parser_error *err); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif +diff --git a/src/lxc/json/json_common.c b/src/lxc/json/json_common.c +new file mode 100755 +index 0000000..ec20c59 +--- /dev/null ++++ b/src/lxc/json/json_common.c +@@ -0,0 +1,1153 @@ ++// Auto generated file. Do not edit! ++#define _GNU_SOURCE ++#include ++#include ++#include ++#include "json_common.h" ++ ++#define MAX_NUM_STR_LEN 21 ++ ++yajl_gen_status reformat_number(void *ctx, const char *str, size_t len) { ++ yajl_gen g = (yajl_gen) ctx; ++ return yajl_gen_number(g, str, len); ++} ++ ++yajl_gen_status reformat_uint(void *ctx, long long unsigned int num) { ++ char numstr[MAX_NUM_STR_LEN]; ++ int ret; ++ ++ ret = snprintf(numstr, MAX_NUM_STR_LEN, "%llu", num); ++ if (ret < 0 || ret >= MAX_NUM_STR_LEN) { ++ return yajl_gen_in_error_state; ++ } ++ return reformat_number(ctx, (const char *)numstr, strlen(numstr)); ++} ++ ++yajl_gen_status reformat_int(void *ctx, long long int num) { ++ char numstr[MAX_NUM_STR_LEN]; ++ int ret; ++ ++ ret = snprintf(numstr, MAX_NUM_STR_LEN, "%lld", num); ++ if (ret < 0 || ret >= MAX_NUM_STR_LEN) { ++ return yajl_gen_in_error_state; ++ } ++ return reformat_number(ctx, (const char *)numstr, strlen(numstr)); ++} ++ ++yajl_gen_status reformat_double(void *ctx, double num) { ++ yajl_gen g = (yajl_gen) ctx; ++ return yajl_gen_double(g, num); ++} ++ ++yajl_gen_status reformat_string(void *ctx, const char *str, size_t len) { ++ yajl_gen g = (yajl_gen) ctx; ++ return yajl_gen_string(g, (const unsigned char *)str, len); ++} ++ ++yajl_gen_status reformat_null(void *ctx) { ++ yajl_gen g = (yajl_gen) ctx; ++ return yajl_gen_null(g); ++} ++ ++yajl_gen_status reformat_bool(void *ctx, int boolean) { ++ yajl_gen g = (yajl_gen) ctx; ++ return yajl_gen_bool(g, boolean); ++} ++ ++yajl_gen_status reformat_map_key(void *ctx, const char *str, size_t len) { ++ yajl_gen g = (yajl_gen) ctx; ++ return yajl_gen_string(g, (const unsigned char *)str, len); ++} ++ ++yajl_gen_status reformat_start_map(void *ctx) { ++ yajl_gen g = (yajl_gen) ctx; ++ return yajl_gen_map_open(g); ++} ++ ++yajl_gen_status reformat_end_map(void *ctx) { ++ yajl_gen g = (yajl_gen) ctx; ++ return yajl_gen_map_close(g); ++} ++ ++yajl_gen_status reformat_start_array(void *ctx) { ++ yajl_gen g = (yajl_gen) ctx; ++ return yajl_gen_array_open(g); ++} ++ ++yajl_gen_status reformat_end_array(void *ctx) { ++ yajl_gen g = (yajl_gen) ctx; ++ return yajl_gen_array_close(g); ++} ++ ++bool json_gen_init(yajl_gen *g, struct parser_context *ctx) { ++ *g = yajl_gen_alloc(NULL); ++ if (NULL == *g) { ++ return false; ++ ++ } ++ yajl_gen_config(*g, yajl_gen_beautify, !(ctx->options & GEN_OPTIONS_SIMPLIFY)); ++ yajl_gen_config(*g, yajl_gen_validate_utf8, !(ctx->options & GEN_OPTIONS_NOT_VALIDATE_UTF8)); ++ return true; ++} ++ ++yajl_val get_val(yajl_val tree, const char *name, yajl_type type) { ++ const char *path[] = { name, NULL }; ++ return yajl_tree_get(tree, path, type); ++} ++ ++void *safe_malloc(size_t size) { ++ void *ret = NULL; ++ if (size == 0) { ++ abort(); ++ } ++ ret = calloc(1, size); ++ if (ret == NULL) { ++ abort(); ++ } ++ return ret; ++} ++ ++int common_safe_double(const char *numstr, double *converted) { ++ char *err_str = NULL; ++ double d; ++ ++ if (numstr == NULL) { ++ return -EINVAL; ++ } ++ ++ errno = 0; ++ d = strtod(numstr, &err_str); ++ if (errno > 0) { ++ return -errno; ++ } ++ ++ if (err_str == NULL || err_str == numstr || *err_str != '\0') { ++ return -EINVAL; ++ } ++ ++ *converted = d; ++ return 0; ++} ++ ++int common_safe_uint8(const char *numstr, uint8_t *converted) { ++ char *err = NULL; ++ unsigned long int uli; ++ ++ if (numstr == NULL) { ++ return -EINVAL; ++ } ++ ++ errno = 0; ++ uli = strtoul(numstr, &err, 0); ++ if (errno > 0) { ++ return -errno; ++ } ++ ++ if (err == NULL || err == numstr || *err != '\0') { ++ return -EINVAL; ++ } ++ ++ if (uli > UINT8_MAX) { ++ return -ERANGE; ++ } ++ ++ *converted = (uint8_t)uli; ++ return 0; ++} ++ ++int common_safe_uint16(const char *numstr, uint16_t *converted) { ++ char *err = NULL; ++ unsigned long int uli; ++ ++ if (numstr == NULL) { ++ return -EINVAL; ++ } ++ ++ errno = 0; ++ uli = strtoul(numstr, &err, 0); ++ if (errno > 0) { ++ return -errno; ++ } ++ ++ if (err == NULL || err == numstr || *err != '\0') { ++ return -EINVAL; ++ } ++ ++ if (uli > UINT16_MAX) { ++ return -ERANGE; ++ } ++ ++ *converted = (uint16_t)uli; ++ return 0; ++} ++ ++int common_safe_uint32(const char *numstr, uint32_t *converted) { ++ char *err = NULL; ++ unsigned long long int ull; ++ ++ if (numstr == NULL) { ++ return -EINVAL; ++ } ++ ++ errno = 0; ++ ull = strtoull(numstr, &err, 0); ++ if (errno > 0) { ++ return -errno; ++ } ++ ++ if (err == NULL || err == numstr || *err != '\0') { ++ return -EINVAL; ++ } ++ ++ if (ull > UINT32_MAX) { ++ return -ERANGE; ++ } ++ ++ *converted = (uint32_t)ull; ++ return 0; ++} ++ ++int common_safe_uint64(const char *numstr, uint64_t *converted) { ++ char *err = NULL; ++ unsigned long long int ull; ++ ++ if (numstr == NULL) { ++ return -EINVAL; ++ } ++ ++ errno = 0; ++ ull = strtoull(numstr, &err, 0); ++ if (errno > 0) { ++ return -errno; ++ } ++ ++ if (err == NULL || err == numstr || *err != '\0') { ++ return -EINVAL; ++ } ++ ++ *converted = (uint64_t)ull; ++ return 0; ++} ++ ++int common_safe_uint(const char *numstr, unsigned int *converted) { ++ char *err = NULL; ++ unsigned long long int ull; ++ ++ if (numstr == NULL) { ++ return -EINVAL; ++ } ++ ++ errno = 0; ++ ull = strtoull(numstr, &err, 0); ++ if (errno > 0) { ++ return -errno; ++ } ++ ++ if (err == NULL || err == numstr || *err != '\0') { ++ return -EINVAL; ++ } ++ ++ if (ull > UINT_MAX) { ++ return -ERANGE; ++ } ++ ++ *converted = (unsigned int)ull; ++ return 0; ++} ++ ++int common_safe_int8(const char *numstr, int8_t *converted) { ++ char *err = NULL; ++ long int li; ++ ++ if (numstr == NULL) { ++ return -EINVAL; ++ } ++ ++ errno = 0; ++ li = strtol(numstr, &err, 0); ++ if (errno > 0) { ++ return -errno; ++ } ++ ++ if (err == NULL || err == numstr || *err != '\0') { ++ return -EINVAL; ++ } ++ ++ if (li > INT8_MAX || li < INT8_MIN) { ++ return -ERANGE; ++ } ++ ++ *converted = (int8_t)li; ++ return 0; ++} ++ ++int common_safe_int16(const char *numstr, int16_t *converted) { ++ char *err = NULL; ++ long int li; ++ ++ if (numstr == NULL) { ++ return -EINVAL; ++ } ++ ++ errno = 0; ++ li = strtol(numstr, &err, 0); ++ if (errno > 0) { ++ return -errno; ++ } ++ ++ if (err == NULL || err == numstr || *err != '\0') { ++ return -EINVAL; ++ } ++ ++ if (li > INT16_MAX || li < INT16_MIN) { ++ return -ERANGE; ++ } ++ ++ *converted = (int16_t)li; ++ return 0; ++} ++ ++int common_safe_int32(const char *numstr, int32_t *converted) { ++ char *err = NULL; ++ long long int lli; ++ ++ if (numstr == NULL) { ++ return -EINVAL; ++ } ++ ++ errno = 0; ++ lli = strtol(numstr, &err, 0); ++ if (errno > 0) { ++ return -errno; ++ } ++ ++ if (err == NULL || err == numstr || *err != '\0') { ++ return -EINVAL; ++ } ++ ++ if (lli > INT32_MAX || lli < INT32_MIN) { ++ return -ERANGE; ++ } ++ ++ *converted = (int32_t)lli; ++ return 0; ++} ++ ++int common_safe_int64(const char *numstr, int64_t *converted) { ++ char *err = NULL; ++ long long int lli; ++ ++ if (numstr == NULL) { ++ return -EINVAL; ++ } ++ ++ errno = 0; ++ lli = strtoll(numstr, &err, 0); ++ if (errno > 0) { ++ return -errno; ++ } ++ ++ if (err == NULL || err == numstr || *err != '\0') { ++ return -EINVAL; ++ } ++ ++ *converted = (int64_t)lli; ++ return 0; ++} ++ ++int common_safe_int(const char *numstr, int *converted) { ++ char *err = NULL; ++ long long int lli; ++ ++ if (numstr == NULL) { ++ return -EINVAL; ++ } ++ ++ errno = 0; ++ lli = strtol(numstr, &err, 0); ++ if (errno > 0) { ++ return -errno; ++ } ++ ++ if (err == NULL || err == numstr || *err != '\0') { ++ return -EINVAL; ++ } ++ ++ if (lli > INT_MAX || lli < INT_MIN) { ++ return -ERANGE; ++ } ++ ++ *converted = (int)lli; ++ return 0; ++} ++ ++yajl_gen_status gen_json_map_int_int(void *ctx, json_map_int_int *map, struct parser_context *ptx, parser_error *err) { ++ yajl_gen_status stat = yajl_gen_status_ok; ++ yajl_gen g = (yajl_gen) ctx; ++ size_t len = 0, i = 0; ++ if (map != NULL) { ++ len = map->len; ++ } ++ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { ++ yajl_gen_config(g, yajl_gen_beautify, 0); ++ } ++ stat = reformat_start_map(g); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ ++ } ++ for (i = 0; i < len; i++) { ++ char numstr[MAX_NUM_STR_LEN]; ++ int nret; ++ nret = snprintf(numstr, MAX_NUM_STR_LEN, "%lld", (long long int)map->keys[i]); ++ if (nret < 0 || nret >= MAX_NUM_STR_LEN) { ++ if (!*err && asprintf(err, "Error to print string") < 0) { ++ *(err) = safe_strdup("error allocating memory"); ++ } ++ return yajl_gen_in_error_state; ++ } ++ stat = reformat_string(g, numstr, strlen(numstr)); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ stat = reformat_int(g, map->values[i]); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ } ++ ++ stat = reformat_end_map(g); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { ++ yajl_gen_config(g, yajl_gen_beautify, 1); ++ } ++ return yajl_gen_status_ok; ++} ++ ++void free_json_map_int_int(json_map_int_int *map) { ++ if (map != NULL) { ++ size_t i; ++ for (i = 0; i < map->len; i++) { ++ // No need to free key for type int ++ // No need to free value for type int ++ } ++ free(map->keys); ++ map->keys = NULL; ++ free(map->values); ++ map->values = NULL; ++ free(map); ++ } ++} ++json_map_int_int *make_json_map_int_int(yajl_val src, struct parser_context *ctx, parser_error *err) { ++ json_map_int_int *ret = NULL; ++ if (src != NULL && YAJL_GET_OBJECT(src) != NULL) { ++ size_t i; ++ size_t len = YAJL_GET_OBJECT(src)->len; ++ if (len > SIZE_MAX / sizeof(int) - 1) { ++ return NULL; ++ } ++ ret = safe_malloc(sizeof(*ret)); ++ ret->len = len; ++ ret->keys = safe_malloc((len + 1) * sizeof(int)); ++ ret->values = safe_malloc((len + 1) * sizeof(int)); ++ for (i = 0; i < len; i++) { ++ const char *srckey = YAJL_GET_OBJECT(src)->keys[i]; ++ yajl_val srcval = YAJL_GET_OBJECT(src)->values[i]; ++ ++ if (srckey != NULL) { ++ int invalid; ++ invalid = common_safe_int(srckey, &(ret->keys[i])); ++ if (invalid) { ++ if (*err == NULL && asprintf(err, "Invalid key '%s' with type 'int': %s", srckey, strerror(-invalid)) < 0) { ++ *(err) = safe_strdup("error allocating memory"); ++ } ++ free_json_map_int_int(ret); ++ return NULL; ++ } ++ } ++ ++ if (srcval != NULL) { ++ int invalid; ++ if (!YAJL_IS_NUMBER(srcval)) { ++ if (*err == NULL && asprintf(err, "Invalid value with type 'int' for key '%s'", srckey) < 0) { ++ *(err) = safe_strdup("error allocating memory"); ++ } ++ free_json_map_int_int(ret); ++ return NULL; ++ } ++ invalid = common_safe_int(YAJL_GET_NUMBER(srcval), &(ret->values[i])); ++ if (invalid) { ++ if (*err == NULL && asprintf(err, "Invalid value with type 'int' for key '%s': %s", srckey, strerror(-invalid)) < 0) { ++ *(err) = safe_strdup("error allocating memory"); ++ } ++ free_json_map_int_int(ret); ++ return NULL; ++ } ++ } ++ } ++ } ++ return ret; ++} ++int append_json_map_int_int(json_map_int_int *map, int key, int val) { ++ size_t len; ++ int *keys = NULL; ++ int *vals = NULL; ++ ++ if (map == NULL) { ++ return -1; ++ } ++ ++ if ((SIZE_MAX / sizeof(int) - 1) < map->len) { ++ return -1; ++ } ++ ++ len = map->len + 1; ++ keys = safe_malloc(len * sizeof(int)); ++ vals = safe_malloc(len * sizeof(int)); ++ ++ if (map->len) { ++ (void)memcpy(keys, map->keys, map->len * sizeof(int)); ++ (void)memcpy(vals, map->values, map->len * sizeof(int)); ++ } ++ free(map->keys); ++ map->keys = keys; ++ free(map->values); ++ map->values = vals; ++ map->keys[map->len] = key; ++ map->values[map->len] = val; ++ ++ map->len++; ++ return 0; ++} ++ ++yajl_gen_status gen_json_map_int_bool(void *ctx, json_map_int_bool *map, struct parser_context *ptx, parser_error *err) { ++ yajl_gen_status stat = yajl_gen_status_ok; ++ yajl_gen g = (yajl_gen) ctx; ++ size_t len = 0, i = 0; ++ if (map != NULL) { ++ len = map->len; ++ } ++ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { ++ yajl_gen_config(g, yajl_gen_beautify, 0); ++ } ++ stat = reformat_start_map(g); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ ++ } ++ for (i = 0; i < len; i++) { ++ char numstr[MAX_NUM_STR_LEN]; ++ int nret; ++ nret = snprintf(numstr, MAX_NUM_STR_LEN, "%lld", (long long int)map->keys[i]); ++ if (nret < 0 || nret >= MAX_NUM_STR_LEN) { ++ if (!*err && asprintf(err, "Error to print string") < 0) { ++ *(err) = safe_strdup("error allocating memory"); ++ } ++ return yajl_gen_in_error_state; ++ } ++ stat = reformat_string(g, numstr, strlen(numstr)); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ stat = reformat_bool(g, map->values[i]); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ } ++ ++ stat = reformat_end_map(g); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { ++ yajl_gen_config(g, yajl_gen_beautify, 1); ++ } ++ return yajl_gen_status_ok; ++} ++ ++void free_json_map_int_bool(json_map_int_bool *map) { ++ if (map != NULL) { ++ free(map->keys); ++ map->keys = NULL; ++ free(map->values); ++ map->values = NULL; ++ free(map); ++ } ++} ++json_map_int_bool *make_json_map_int_bool(yajl_val src, struct parser_context *ctx, parser_error *err) { ++ json_map_int_bool *ret = NULL; ++ if (src != NULL && YAJL_GET_OBJECT(src) != NULL) { ++ size_t i; ++ size_t len = YAJL_GET_OBJECT(src)->len; ++ if (len > SIZE_MAX / sizeof(int) - 1) { ++ return NULL; ++ } ++ ret = safe_malloc(sizeof(*ret)); ++ ret->len = len; ++ ret->keys = safe_malloc((len + 1) * sizeof(int)); ++ ret->values = safe_malloc((len + 1) * sizeof(bool)); ++ for (i = 0; i < len; i++) { ++ const char *srckey = YAJL_GET_OBJECT(src)->keys[i]; ++ yajl_val srcval = YAJL_GET_OBJECT(src)->values[i]; ++ ++ if (srckey != NULL) { ++ int invalid; ++ invalid = common_safe_int(srckey, &(ret->keys[i])); ++ if (invalid) { ++ if (*err == NULL && asprintf(err, "Invalid key '%s' with type 'int': %s", srckey, strerror(-invalid)) < 0) { ++ *(err) = safe_strdup("error allocating memory"); ++ } ++ free_json_map_int_bool(ret); ++ return NULL; ++ } ++ } ++ ++ if (srcval != NULL) { ++ if (YAJL_IS_TRUE(srcval)) { ++ ret->values[i] = true; ++ } else if (YAJL_IS_FALSE(srcval)) { ++ ret->values[i] = false; ++ } else { ++ if (*err == NULL && asprintf(err, "Invalid value with type 'bool' for key '%s'", srckey) < 0) { ++ *(err) = safe_strdup("error allocating memory"); ++ } ++ free_json_map_int_bool(ret); ++ return NULL; ++ } ++ } ++ } ++ } ++ return ret; ++} ++int append_json_map_int_bool(json_map_int_bool *map, int key, bool val) { ++ size_t len; ++ int *keys = NULL; ++ bool *vals = NULL; ++ ++ if (map == NULL) { ++ return -1; ++ } ++ ++ if ((SIZE_MAX / sizeof(int) - 1) < map->len || (SIZE_MAX / sizeof(bool) - 1) < map->len) { ++ return -1; ++ } ++ ++ len = map->len + 1; ++ keys = safe_malloc(len * sizeof(int)); ++ vals = safe_malloc(len * sizeof(bool)); ++ ++ if (map->len) { ++ (void)memcpy(keys, map->keys, map->len * sizeof(int)); ++ (void)memcpy(vals, map->values, map->len * sizeof(bool)); ++ } ++ free(map->keys); ++ map->keys = keys; ++ free(map->values); ++ map->values = vals; ++ map->keys[map->len] = key; ++ map->values[map->len] = val; ++ ++ map->len++; ++ return 0; ++} ++ ++yajl_gen_status gen_json_map_int_string(void *ctx, json_map_int_string *map, struct parser_context *ptx, parser_error *err) { ++ yajl_gen_status stat = yajl_gen_status_ok; ++ yajl_gen g = (yajl_gen) ctx; ++ size_t len = 0, i = 0; ++ if (map != NULL) { ++ len = map->len; ++ } ++ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { ++ yajl_gen_config(g, yajl_gen_beautify, 0); ++ } ++ stat = reformat_start_map(g); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ ++ } ++ for (i = 0; i < len; i++) { ++ char numstr[MAX_NUM_STR_LEN]; ++ int nret; ++ nret = snprintf(numstr, MAX_NUM_STR_LEN, "%lld", (long long int)map->keys[i]); ++ if (nret < 0 || nret >= MAX_NUM_STR_LEN) { ++ if (!*err && asprintf(err, "Error to print string") < 0) { ++ *(err) = safe_strdup("error allocating memory"); ++ } ++ return yajl_gen_in_error_state; ++ } ++ stat = reformat_string(g, numstr, strlen(numstr)); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ stat = reformat_string(g, map->values[i], strlen(map->values[i]));; ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ } ++ ++ stat = reformat_end_map(g); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { ++ yajl_gen_config(g, yajl_gen_beautify, 1); ++ } ++ return yajl_gen_status_ok; ++} ++ ++void free_json_map_int_string(json_map_int_string *map) { ++ if (map != NULL) { ++ size_t i; ++ for (i = 0; i < map->len; i++) { ++ // No need to free key for type int ++ free(map->values[i]); ++ map->values[i] = NULL; ++ } ++ free(map->keys); ++ map->keys = NULL; ++ free(map->values); ++ map->values = NULL; ++ free(map); ++ } ++} ++json_map_int_string *make_json_map_int_string(yajl_val src, struct parser_context *ctx, parser_error *err) { ++ json_map_int_string *ret = NULL; ++ if (src != NULL && YAJL_GET_OBJECT(src) != NULL) { ++ size_t i; ++ size_t len = YAJL_GET_OBJECT(src)->len; ++ if (len > SIZE_MAX / sizeof(char *) - 1) { ++ return NULL; ++ } ++ ret = safe_malloc(sizeof(*ret)); ++ ret->len = len; ++ ret->keys = safe_malloc((len + 1) * sizeof(int)); ++ ret->values = safe_malloc((len + 1) * sizeof(char *)); ++ for (i = 0; i < len; i++) { ++ const char *srckey = YAJL_GET_OBJECT(src)->keys[i]; ++ yajl_val srcval = YAJL_GET_OBJECT(src)->values[i]; ++ ++ if (srckey != NULL) { ++ int invalid; ++ invalid = common_safe_int(srckey, &(ret->keys[i])); ++ if (invalid) { ++ if (*err == NULL && asprintf(err, "Invalid key '%s' with type 'int': %s", srckey, strerror(-invalid)) < 0) { ++ *(err) = safe_strdup("error allocating memory"); ++ } ++ free_json_map_int_string(ret); ++ return NULL; ++ } ++ } ++ ++ if (srcval != NULL) { ++ if (!YAJL_IS_STRING(srcval)) { ++ if (*err == NULL && asprintf(err, "Invalid value with type 'string' for key '%s'", srckey) < 0) { ++ *(err) = safe_strdup("error allocating memory"); ++ } ++ free_json_map_int_string(ret); ++ return NULL; ++ } ++ char *str = YAJL_GET_STRING(srcval); ++ ret->values[i] = safe_strdup(str ? str : ""); ++ } ++ } ++ } ++ return ret; ++} ++int append_json_map_int_string(json_map_int_string *map, int key, const char *val) { ++ size_t len; ++ int *keys = NULL; ++ char **vals = NULL; ++ ++ if (map == NULL) { ++ return -1; ++ } ++ ++ if ((SIZE_MAX / sizeof(int) - 1) < map->len || (SIZE_MAX / sizeof(char *) - 1) < map->len) { ++ return -1; ++ } ++ ++ len = map->len + 1; ++ keys = safe_malloc(len * sizeof(int)); ++ vals = safe_malloc(len * sizeof(char *)); ++ ++ if (map->len) { ++ (void)memcpy(keys, map->keys, map->len * sizeof(int)); ++ (void)memcpy(vals, map->values, map->len * sizeof(char *)); ++ } ++ free(map->keys); ++ map->keys = keys; ++ free(map->values); ++ map->values = vals; ++ map->keys[map->len] = key; ++ map->values[map->len] = safe_strdup(val ? val : ""); ++ ++ map->len++; ++ return 0; ++} ++ ++yajl_gen_status gen_json_map_string_int(void *ctx, json_map_string_int *map, struct parser_context *ptx, parser_error *err) { ++ yajl_gen_status stat = yajl_gen_status_ok; ++ yajl_gen g = (yajl_gen) ctx; ++ size_t len = 0, i = 0; ++ if (map != NULL) { ++ len = map->len; ++ } ++ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { ++ yajl_gen_config(g, yajl_gen_beautify, 0); ++ } ++ stat = reformat_start_map(g); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ ++ } ++ for (i = 0; i < len; i++) { ++ stat = reformat_string(g, map->keys[i], strlen(map->keys[i])); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ stat = reformat_int(g, map->values[i]); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ } ++ ++ stat = reformat_end_map(g); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { ++ yajl_gen_config(g, yajl_gen_beautify, 1); ++ } ++ return yajl_gen_status_ok; ++} ++ ++void free_json_map_string_int(json_map_string_int *map) { ++ if (map != NULL) { ++ size_t i; ++ for (i = 0; i < map->len; i++) { ++ free(map->keys[i]); ++ map->keys[i] = NULL; ++ // No need to free value for type int ++ } ++ free(map->keys); ++ map->keys = NULL; ++ free(map->values); ++ map->values = NULL; ++ free(map); ++ } ++} ++json_map_string_int *make_json_map_string_int(yajl_val src, struct parser_context *ctx, parser_error *err) { ++ json_map_string_int *ret = NULL; ++ if (src != NULL && YAJL_GET_OBJECT(src) != NULL) { ++ size_t i; ++ size_t len = YAJL_GET_OBJECT(src)->len; ++ if (len > SIZE_MAX / sizeof(char *) - 1) { ++ return NULL; ++ } ++ ret = safe_malloc(sizeof(*ret)); ++ ret->len = len; ++ ret->keys = safe_malloc((len + 1) * sizeof(char *)); ++ ret->values = safe_malloc((len + 1) * sizeof(int)); ++ for (i = 0; i < len; i++) { ++ const char *srckey = YAJL_GET_OBJECT(src)->keys[i]; ++ yajl_val srcval = YAJL_GET_OBJECT(src)->values[i]; ++ ret->keys[i] = safe_strdup(srckey ? srckey : ""); ++ ++ if (srcval != NULL) { ++ int invalid; ++ if (!YAJL_IS_NUMBER(srcval)) { ++ if (*err == NULL && asprintf(err, "Invalid value with type 'int' for key '%s'", srckey) < 0) { ++ *(err) = safe_strdup("error allocating memory"); ++ } ++ free_json_map_string_int(ret); ++ return NULL; ++ } ++ invalid = common_safe_int(YAJL_GET_NUMBER(srcval), &(ret->values[i])); ++ if (invalid) { ++ if (*err == NULL && asprintf(err, "Invalid value with type 'int' for key '%s': %s", srckey, strerror(-invalid)) < 0) { ++ *(err) = safe_strdup("error allocating memory"); ++ } ++ free_json_map_string_int(ret); ++ return NULL; ++ } ++ } ++ } ++ } ++ return ret; ++} ++int append_json_map_string_int(json_map_string_int *map, const char *key, int val) { ++ size_t len; ++ char **keys = NULL; ++ int *vals = NULL; ++ ++ if (map == NULL) { ++ return -1; ++ } ++ ++ if ((SIZE_MAX / sizeof(char *) - 1) < map->len || (SIZE_MAX / sizeof(int) - 1) < map->len) { ++ return -1; ++ } ++ ++ len = map->len + 1; ++ keys = safe_malloc(len * sizeof(char *)); ++ vals = safe_malloc(len * sizeof(int)); ++ ++ if (map->len) { ++ (void)memcpy(keys, map->keys, map->len * sizeof(char *)); ++ (void)memcpy(vals, map->values, map->len * sizeof(int)); ++ } ++ free(map->keys); ++ map->keys = keys; ++ free(map->values); ++ map->values = vals; ++ map->keys[map->len] = safe_strdup(key ? key : ""); ++ map->values[map->len] = val; ++ ++ map->len++; ++ return 0; ++} ++ ++yajl_gen_status gen_json_map_string_bool(void *ctx, json_map_string_bool *map, struct parser_context *ptx, parser_error *err) { ++ yajl_gen_status stat = yajl_gen_status_ok; ++ yajl_gen g = (yajl_gen) ctx; ++ size_t len = 0, i = 0; ++ if (map != NULL) { ++ len = map->len; ++ } ++ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { ++ yajl_gen_config(g, yajl_gen_beautify, 0); ++ } ++ stat = reformat_start_map(g); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ ++ } ++ for (i = 0; i < len; i++) { ++ stat = reformat_string(g, map->keys[i], strlen(map->keys[i])); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ stat = reformat_bool(g, map->values[i]); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ } ++ ++ stat = reformat_end_map(g); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { ++ yajl_gen_config(g, yajl_gen_beautify, 1); ++ } ++ return yajl_gen_status_ok; ++} ++ ++void free_json_map_string_bool(json_map_string_bool *map) { ++ if (map != NULL) { ++ size_t i; ++ for (i = 0; i < map->len; i++) { ++ free(map->keys[i]); ++ map->keys[i] = NULL; ++ // No need to free value for type bool ++ } ++ free(map->keys); ++ map->keys = NULL; ++ free(map->values); ++ map->values = NULL; ++ free(map); ++ } ++} ++json_map_string_bool *make_json_map_string_bool(yajl_val src, struct parser_context *ctx, parser_error *err) { ++ json_map_string_bool *ret = NULL; ++ if (src != NULL && YAJL_GET_OBJECT(src) != NULL) { ++ size_t i; ++ size_t len = YAJL_GET_OBJECT(src)->len; ++ if (len > SIZE_MAX / sizeof(char *) - 1) { ++ return NULL; ++ } ++ ret = safe_malloc(sizeof(*ret)); ++ ret->len = len; ++ ret->keys = safe_malloc((len + 1) * sizeof(char *)); ++ ret->values = safe_malloc((len + 1) * sizeof(bool)); ++ for (i = 0; i < len; i++) { ++ const char *srckey = YAJL_GET_OBJECT(src)->keys[i]; ++ yajl_val srcval = YAJL_GET_OBJECT(src)->values[i]; ++ ret->keys[i] = safe_strdup(srckey ? srckey : ""); ++ ++ if (srcval != NULL) { ++ if (YAJL_IS_TRUE(srcval)) { ++ ret->values[i] = true; ++ } else if (YAJL_IS_FALSE(srcval)) { ++ ret->values[i] = false; ++ } else { ++ if (*err == NULL && asprintf(err, "Invalid value with type 'bool' for key '%s'", srckey) < 0) { ++ *(err) = safe_strdup("error allocating memory"); ++ } ++ free_json_map_string_bool(ret); ++ return NULL; ++ } ++ } ++ } ++ } ++ return ret; ++} ++ ++int append_json_map_string_bool(json_map_string_bool *map, const char *key, bool val) { ++ size_t len; ++ char **keys = NULL; ++ bool *vals = NULL; ++ ++ if (map == NULL) { ++ return -1; ++ } ++ ++ if ((SIZE_MAX / sizeof(char *) - 1) < map->len || (SIZE_MAX / sizeof(bool) - 1) < map->len) { ++ return -1; ++ } ++ ++ len = map->len + 1; ++ keys = safe_malloc(len * sizeof(char *)); ++ vals = safe_malloc(len * sizeof(bool)); ++ ++ if (map->len) { ++ (void)memcpy(keys, map->keys, map->len * sizeof(char *)); ++ (void)memcpy(vals, map->values, map->len * sizeof(bool)); ++ } ++ free(map->keys); ++ map->keys = keys; ++ free(map->values); ++ map->values = vals; ++ map->keys[map->len] = safe_strdup(key ? key : ""); ++ map->values[map->len] = val; ++ ++ map->len++; ++ return 0; ++} ++ ++yajl_gen_status gen_json_map_string_string(void *ctx, json_map_string_string *map, struct parser_context *ptx, parser_error *err) { ++ yajl_gen_status stat = yajl_gen_status_ok; ++ yajl_gen g = (yajl_gen) ctx; ++ size_t len = 0, i = 0; ++ if (map != NULL) { ++ len = map->len; ++ } ++ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { ++ yajl_gen_config(g, yajl_gen_beautify, 0); ++ } ++ stat = reformat_start_map(g); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ ++ } ++ for (i = 0; i < len; i++) { ++ stat = reformat_string(g, map->keys[i], strlen(map->keys[i])); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ stat = reformat_string(g, map->values[i], strlen(map->values[i]));; ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ } ++ ++ stat = reformat_end_map(g); ++ if (yajl_gen_status_ok != stat) { ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { ++ yajl_gen_config(g, yajl_gen_beautify, 1); ++ } ++ return yajl_gen_status_ok; ++} ++ ++void free_json_map_string_string(json_map_string_string *map) { ++ if (map != NULL) { ++ size_t i; ++ for (i = 0; i < map->len; i++) { ++ free(map->keys[i]); ++ map->keys[i] = NULL; ++ free(map->values[i]); ++ map->values[i] = NULL; ++ } ++ free(map->keys); ++ map->keys = NULL; ++ free(map->values); ++ map->values = NULL; ++ free(map); ++ } ++} ++json_map_string_string *make_json_map_string_string(yajl_val src, struct parser_context *ctx, parser_error *err) { ++ json_map_string_string *ret = NULL; ++ if (src != NULL && YAJL_GET_OBJECT(src) != NULL) { ++ size_t i; ++ size_t len = YAJL_GET_OBJECT(src)->len; ++ if (len > SIZE_MAX / sizeof(char *) - 1) { ++ return NULL; ++ } ++ ret = safe_malloc(sizeof(*ret)); ++ ret->len = len; ++ ret->keys = safe_malloc((len + 1) * sizeof(char *)); ++ ret->values = safe_malloc((len + 1) * sizeof(char *)); ++ for (i = 0; i < len; i++) { ++ const char *srckey = YAJL_GET_OBJECT(src)->keys[i]; ++ yajl_val srcval = YAJL_GET_OBJECT(src)->values[i]; ++ ret->keys[i] = safe_strdup(srckey ? srckey : ""); ++ ++ if (srcval != NULL) { ++ if (!YAJL_IS_STRING(srcval)) { ++ if (*err == NULL && asprintf(err, "Invalid value with type 'string' for key '%s'", srckey) < 0) { ++ *(err) = safe_strdup("error allocating memory"); ++ } ++ free_json_map_string_string(ret); ++ return NULL; ++ } ++ char *str = YAJL_GET_STRING(srcval); ++ ret->values[i] = safe_strdup(str ? str : ""); ++ } ++ } ++ } ++ return ret; ++} ++int append_json_map_string_string(json_map_string_string *map, const char *key, const char *val) { ++ size_t len, i; ++ char **keys = NULL; ++ char **vals = NULL; ++ ++ if (map == NULL) { ++ return -1; ++ } ++ ++ for (i = 0; i < map->len; i++) { ++ if (strcmp(map->keys[i], key) == 0) { ++ free(map->values[i]); ++ map->values[i] = safe_strdup(val ? val : ""); ++ return 0; ++ } ++ } ++ ++ if ((SIZE_MAX / sizeof(char *) - 1) < map->len) { ++ return -1; ++ } ++ ++ len = map->len + 1; ++ keys = safe_malloc(len * sizeof(char *)); ++ vals = safe_malloc(len * sizeof(char *)); ++ ++ if (map->len) { ++ (void)memcpy(keys, map->keys, map->len * sizeof(char *)); ++ (void)memcpy(vals, map->values, map->len * sizeof(char *)); ++ } ++ free(map->keys); ++ map->keys = keys; ++ free(map->values); ++ map->values = vals; ++ map->keys[map->len] = safe_strdup(key ? key : ""); ++ map->values[map->len] = safe_strdup(val ? val : ""); ++ ++ map->len++; ++ return 0; ++} +diff --git a/src/lxc/json/json_common.h b/src/lxc/json/json_common.h +new file mode 100755 +index 0000000..60aa5fd +--- /dev/null ++++ b/src/lxc/json/json_common.h +@@ -0,0 +1,185 @@ ++// Auto generated file. Do not edit! ++#ifndef _JSON_COMMON_H ++#define _JSON_COMMON_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "utils.h" ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++# undef linux ++ ++//options to report error if there is unknown key found in json ++# define PARSE_OPTIONS_STRICT 0x01 ++//options to generate all key and value ++# define GEN_OPTIONS_ALLKEYVALUE 0x02 ++//options to generate simplify(no indent) json string ++# define GEN_OPTIONS_SIMPLIFY 0x04 ++//options not to validate utf8 data ++# define GEN_OPTIONS_NOT_VALIDATE_UTF8 0x08 ++ ++#define GEN_SET_ERROR_AND_RETURN(stat, err) { \ ++ if (*(err) == NULL) {\ ++ if (asprintf(err, "%s: %s: %d: error generating json, errcode: %d", __FILE__, __func__, __LINE__, stat) < 0) { \ ++ *(err) = safe_strdup("error allocating memory"); \ ++ } \ ++ }\ ++ return stat; \ ++ } ++ ++typedef char *parser_error; ++ ++struct parser_context { ++ unsigned int options; ++ FILE *stderr; ++}; ++ ++yajl_gen_status reformat_number(void *ctx, const char *str, size_t len); ++ ++yajl_gen_status reformat_uint(void *ctx, long long unsigned int num); ++ ++yajl_gen_status reformat_int(void *ctx, long long int num); ++ ++yajl_gen_status reformat_double(void *ctx, double num); ++ ++yajl_gen_status reformat_string(void *ctx, const char *str, size_t len); ++ ++yajl_gen_status reformat_null(void *ctx); ++ ++yajl_gen_status reformat_bool(void *ctx, int boolean); ++ ++yajl_gen_status reformat_map_key(void *ctx, const char *str, size_t len); ++ ++yajl_gen_status reformat_start_map(void *ctx); ++ ++yajl_gen_status reformat_end_map(void *ctx); ++ ++yajl_gen_status reformat_start_array(void *ctx); ++ ++yajl_gen_status reformat_end_array(void *ctx); ++ ++bool json_gen_init(yajl_gen *g, struct parser_context *ctx); ++ ++yajl_val get_val(yajl_val tree, const char *name, yajl_type type); ++ ++void *safe_malloc(size_t size); ++ ++int common_safe_double(const char *numstr, double *converted); ++ ++int common_safe_uint8(const char *numstr, uint8_t *converted); ++ ++int common_safe_uint16(const char *numstr, uint16_t *converted); ++ ++int common_safe_uint32(const char *numstr, uint32_t *converted); ++ ++int common_safe_uint64(const char *numstr, uint64_t *converted); ++ ++int common_safe_uint(const char *numstr, unsigned int *converted); ++ ++int common_safe_int8(const char *numstr, int8_t *converted); ++ ++int common_safe_int16(const char *numstr, int16_t *converted); ++ ++int common_safe_int32(const char *numstr, int32_t *converted); ++ ++int common_safe_int64(const char *numstr, int64_t *converted); ++ ++int common_safe_int(const char *numstr, int *converted); ++ ++typedef struct { ++ int *keys; ++ int *values; ++ size_t len; ++} json_map_int_int; ++ ++void free_json_map_int_int(json_map_int_int *map); ++ ++json_map_int_int *make_json_map_int_int(yajl_val src, struct parser_context *ctx, parser_error *err); ++ ++yajl_gen_status gen_json_map_int_int(void *ctx, json_map_int_int *map, struct parser_context *ptx, parser_error *err); ++ ++int append_json_map_int_int(json_map_int_int *map, int key, int val); ++ ++typedef struct { ++ int *keys; ++ bool *values; ++ size_t len; ++} json_map_int_bool; ++ ++void free_json_map_int_bool(json_map_int_bool *map); ++ ++json_map_int_bool *make_json_map_int_bool(yajl_val src, struct parser_context *ctx, parser_error *err); ++ ++yajl_gen_status gen_json_map_int_bool(void *ctx, json_map_int_bool *map, struct parser_context *ptx, parser_error *err); ++ ++int append_json_map_int_bool(json_map_int_bool *map, int key, bool val); ++ ++typedef struct { ++ int *keys; ++ char **values; ++ size_t len; ++} json_map_int_string; ++ ++void free_json_map_int_string(json_map_int_string *map); ++ ++json_map_int_string *make_json_map_int_string(yajl_val src, struct parser_context *ctx, parser_error *err); ++ ++yajl_gen_status gen_json_map_int_string(void *ctx, json_map_int_string *map, struct parser_context *ptx, parser_error *err); ++ ++int append_json_map_int_string(json_map_int_string *map, int key, const char *val); ++ ++typedef struct { ++ char **keys; ++ int *values; ++ size_t len; ++} json_map_string_int; ++ ++void free_json_map_string_int(json_map_string_int *map); ++ ++json_map_string_int *make_json_map_string_int(yajl_val src, struct parser_context *ctx, parser_error *err); ++ ++yajl_gen_status gen_json_map_string_int(void *ctx, json_map_string_int *map, struct parser_context *ptx, parser_error *err); ++ ++int append_json_map_string_int(json_map_string_int *map, const char *key, int val); ++ ++typedef struct { ++ char **keys; ++ bool *values; ++ size_t len; ++} json_map_string_bool; ++ ++void free_json_map_string_bool(json_map_string_bool *map); ++ ++json_map_string_bool *make_json_map_string_bool(yajl_val src, struct parser_context *ctx, parser_error *err); ++ ++yajl_gen_status gen_json_map_string_bool(void *ctx, json_map_string_bool *map, struct parser_context *ptx, parser_error *err); ++ ++int append_json_map_string_bool(json_map_string_bool *map, const char *key, bool val); ++ ++typedef struct { ++ char **keys; ++ char **values; ++ size_t len; ++} json_map_string_string; ++ ++void free_json_map_string_string(json_map_string_string *map); ++ ++json_map_string_string *make_json_map_string_string(yajl_val src, struct parser_context *ctx, parser_error *err); ++ ++yajl_gen_status gen_json_map_string_string(void *ctx, json_map_string_string *map, struct parser_context *ptx, parser_error *err); ++ ++int append_json_map_string_string(json_map_string_string *map, const char *key, const char *val); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif +\ No newline at end of file +diff --git a/src/lxc/json/logger_json_file.c b/src/lxc/json/logger_json_file.c +new file mode 100644 +index 0000000..6abeef4 +--- /dev/null ++++ b/src/lxc/json/logger_json_file.c +@@ -0,0 +1,246 @@ ++// Generated from json-file.json. Do not edit! ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE ++#endif ++#include ++#include ++#include "logger_json_file.h" ++ ++logger_json_file *make_logger_json_file(yajl_val tree, struct parser_context *ctx, parser_error *err) { ++ logger_json_file *ret = NULL; ++ *err = 0; ++ if (tree == NULL) ++ return ret; ++ ret = safe_malloc(sizeof(*ret)); ++ { ++ yajl_val tmp = get_val(tree, "log", yajl_t_string); ++ if (tmp != NULL) { ++ char *str = YAJL_GET_STRING(tmp); ++ ret->log = (uint8_t *)safe_strdup(str ? str : ""); ++ ret->log_len = str != NULL ? strlen(str) : 0; ++ } ++ } ++ { ++ yajl_val val = get_val(tree, "stream", yajl_t_string); ++ if (val != NULL) { ++ char *str = YAJL_GET_STRING(val); ++ ret->stream = safe_strdup(str ? str : ""); ++ } ++ } ++ { ++ yajl_val val = get_val(tree, "time", yajl_t_string); ++ if (val != NULL) { ++ char *str = YAJL_GET_STRING(val); ++ ret->time = safe_strdup(str ? str : ""); ++ } ++ } ++ { ++ yajl_val tmp = get_val(tree, "attrs", yajl_t_string); ++ if (tmp != NULL) { ++ char *str = YAJL_GET_STRING(tmp); ++ ret->attrs = (uint8_t *)safe_strdup(str ? str : ""); ++ ret->attrs_len = str != NULL ? strlen(str) : 0; ++ } ++ } ++ ++ if (tree->type == yajl_t_object && (ctx->options & PARSE_OPTIONS_STRICT)) { ++ int i; ++ for (i = 0; i < tree->u.object.len; i++) ++ if (strcmp(tree->u.object.keys[i], "log") && ++ strcmp(tree->u.object.keys[i], "stream") && ++ strcmp(tree->u.object.keys[i], "time") && ++ strcmp(tree->u.object.keys[i], "attrs")) { ++ if (ctx->stderr > 0) ++ fprintf(ctx->stderr, "WARNING: unknown key found: %s\n", tree->u.object.keys[i]); ++ } ++ } ++ return ret; ++} ++ ++void free_logger_json_file(logger_json_file *ptr) { ++ if (ptr == NULL) ++ return; ++ free(ptr->log); ++ ptr->log = NULL; ++ free(ptr->stream); ++ ptr->stream = NULL; ++ free(ptr->time); ++ ptr->time = NULL; ++ free(ptr->attrs); ++ ptr->attrs = NULL; ++ free(ptr); ++} ++ ++yajl_gen_status gen_logger_json_file(yajl_gen g, logger_json_file *ptr, struct parser_context *ctx, parser_error *err) { ++ yajl_gen_status stat = yajl_gen_status_ok; ++ *err = 0; ++ stat = reformat_start_map(g); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) || (ptr != NULL && ptr->log != NULL && ptr->log_len)) { ++ const char *str = ""; ++ size_t len = 0; ++ stat = reformat_map_key(g, "log", strlen("log")); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ if (ptr != NULL && ptr->log != NULL) { ++ str = (const char *)ptr->log; ++ len = ptr->log_len; ++ } ++ stat = reformat_string(g, str, len); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->stream != NULL)) { ++ char *str = ""; ++ stat = reformat_map_key(g, "stream", strlen("stream")); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ if (ptr != NULL && ptr->stream != NULL) { ++ str = ptr->stream; ++ } ++ stat = reformat_string(g, str, strlen(str)); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->time != NULL)) { ++ char *str = ""; ++ stat = reformat_map_key(g, "time", strlen("time")); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ if (ptr != NULL && ptr->time != NULL) { ++ str = ptr->time; ++ } ++ stat = reformat_string(g, str, strlen(str)); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) || (ptr != NULL && ptr->attrs != NULL && ptr->attrs_len)) { ++ const char *str = ""; ++ size_t len = 0; ++ stat = reformat_map_key(g, "attrs", strlen("attrs")); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ if (ptr != NULL && ptr->attrs != NULL) { ++ str = (const char *)ptr->attrs; ++ len = ptr->attrs_len; ++ } ++ stat = reformat_string(g, str, len); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ stat = reformat_end_map(g); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ return yajl_gen_status_ok; ++} ++ ++ ++logger_json_file *logger_json_file_parse_file(const char *filename, struct parser_context *ctx, parser_error *err) { ++ logger_json_file *ptr = NULL; ++ size_t filesize; ++ char *content = NULL; ++ ++ if (filename == NULL || err == NULL) ++ return NULL; ++ ++ *err = NULL; ++ content = read_file(filename, &filesize); ++ if (content == NULL) { ++ if (asprintf(err, "cannot read the file: %s", filename) < 0) ++ *err = safe_strdup("error allocating memory"); ++ return NULL; ++ } ++ ptr = logger_json_file_parse_data(content, ctx, err); ++ free(content); ++ return ptr; ++} ++ ++logger_json_file *logger_json_file_parse_file_stream(FILE *stream, struct parser_context *ctx, parser_error *err) { ++ logger_json_file *ptr = NULL; ++ size_t filesize; ++ char *content = NULL ; ++ ++ if (stream == NULL || err == NULL) ++ return NULL; ++ ++ *err = NULL; ++ content = fread_file(stream, &filesize); ++ if (content == NULL) { ++ *err = safe_strdup("cannot read the file"); ++ return NULL; ++ } ++ ptr = logger_json_file_parse_data(content, ctx, err); ++ free(content); ++ return ptr; ++} ++ ++logger_json_file *logger_json_file_parse_data(const char *jsondata, struct parser_context *ctx, parser_error *err) { ++ logger_json_file *ptr = NULL; ++ yajl_val tree; ++ char errbuf[1024]; ++ struct parser_context tmp_ctx; ++ ++ if (jsondata == NULL || err == NULL) ++ return NULL; ++ ++ *err = NULL; ++ if (ctx == NULL) { ++ ctx = &tmp_ctx; ++ memset(&tmp_ctx, 0, sizeof(tmp_ctx)); ++ } ++ tree = yajl_tree_parse(jsondata, errbuf, sizeof(errbuf)); ++ if (tree == NULL) { ++ if (asprintf(err, "cannot parse the data: %s", errbuf) < 0) ++ *err = safe_strdup("error allocating memory"); ++ return NULL; ++ } ++ ptr = make_logger_json_file(tree, ctx, err); ++ yajl_tree_free(tree); ++ return ptr; ++} ++char *logger_json_file_generate_json(logger_json_file *ptr, struct parser_context *ctx, parser_error *err) { ++ yajl_gen g = NULL; ++ struct parser_context tmp_ctx; ++ const unsigned char *gen_buf = NULL; ++ char *json_buf = NULL; ++ size_t gen_len = 0; ++ ++ if (ptr == NULL || err == NULL) ++ return NULL; ++ ++ *err = NULL; ++ if (ctx == NULL) { ++ ctx = &tmp_ctx; ++ memset(&tmp_ctx, 0, sizeof(tmp_ctx)); ++ } ++ ++ if (!json_gen_init(&g, ctx)) { ++ *err = safe_strdup("Json_gen init failed"); ++ goto out; ++ } ++ if (yajl_gen_status_ok != gen_logger_json_file(g, ptr, ctx, err)) { ++ if (*err == NULL) ++ *err = safe_strdup("Failed to generate json"); ++ goto free_out; ++ } ++ yajl_gen_get_buf(g, &gen_buf, &gen_len); ++ if (gen_buf == NULL) { ++ *err = safe_strdup("Error to get generated json"); ++ goto free_out; ++ } ++ ++ if (gen_len == SIZE_MAX) { ++ *err = safe_strdup("Invalid buffer length"); ++ goto free_out; ++ } ++ json_buf = safe_malloc(gen_len + 1); ++ (void)memcpy(json_buf, gen_buf, gen_len); ++ json_buf[gen_len] = '\0'; ++ ++free_out: ++ yajl_gen_clear(g); ++ yajl_gen_free(g); ++out: ++ return json_buf; ++} +diff --git a/src/lxc/json/logger_json_file.h b/src/lxc/json/logger_json_file.h +new file mode 100644 +index 0000000..ad5af7b +--- /dev/null ++++ b/src/lxc/json/logger_json_file.h +@@ -0,0 +1,45 @@ ++// Generated from json-file.json. Do not edit! ++#ifndef LOGGER_JSON_FILE_SCHEMA_H ++#define LOGGER_JSON_FILE_SCHEMA_H ++ ++#include ++#include ++#include "json_common.h" ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++typedef struct { ++ uint8_t *log; ++ size_t log_len; ++ ++ char *stream; ++ ++ char *time; ++ ++ uint8_t *attrs; ++ size_t attrs_len; ++ ++} ++logger_json_file; ++ ++void free_logger_json_file(logger_json_file *ptr); ++ ++logger_json_file *make_logger_json_file(yajl_val tree, struct parser_context *ctx, parser_error *err); ++ ++yajl_gen_status gen_logger_json_file(yajl_gen g, logger_json_file *ptr, struct parser_context *ctx, parser_error *err); ++ ++logger_json_file *logger_json_file_parse_file(const char *filename, struct parser_context *ctx, parser_error *err); ++ ++logger_json_file *logger_json_file_parse_file_stream(FILE *stream, struct parser_context *ctx, parser_error *err); ++ ++logger_json_file *logger_json_file_parse_data(const char *jsondata, struct parser_context *ctx, parser_error *err); ++ ++char *logger_json_file_generate_json(logger_json_file *ptr, struct parser_context *ctx, parser_error *err); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif +diff --git a/src/lxc/json/oci_runtime_hooks.c b/src/lxc/json/oci_runtime_hooks.c +new file mode 100644 +index 0000000..41ddb67 +--- /dev/null ++++ b/src/lxc/json/oci_runtime_hooks.c +@@ -0,0 +1,52 @@ ++/****************************************************************************** ++ * Copyright (C), 1988-1999, Huawei Tech. Co., Ltd. ++ * FileName: oci_runtime_hooks.c ++ * Author: maoweiyong Version: 0.1 Date: 2018-11-07 ++ * Explanation: provide oci runtime hooks functions ++ ******************************************************************************/ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE ++#endif ++#include ++#include "oci_runtime_hooks.h" ++ ++#include "log.h" ++#include "utils.h" ++ ++#define PARSE_ERR_BUFFER_SIZE 1024 ++ ++oci_runtime_spec_hooks *oci_runtime_spec_hooks_parse_file(const char *filename, ++ struct parser_context *ctx, parser_error *err) ++{ ++ yajl_val tree; ++ size_t filesize; ++ ++ if (!filename || !err) { ++ return NULL; ++ } ++ *err = NULL; ++ struct parser_context tmp_ctx; ++ if (!ctx) { ++ ctx = &tmp_ctx; ++ memset(&tmp_ctx, 0, sizeof(tmp_ctx)); ++ } ++ char *content = read_file(filename, &filesize); ++ char errbuf[PARSE_ERR_BUFFER_SIZE]; ++ if (content == NULL) { ++ if (asprintf(err, "cannot read the file: %s", filename) < 0) { ++ *err = safe_strdup("error allocating memory"); ++ } ++ return NULL; ++ } ++ tree = yajl_tree_parse(content, errbuf, sizeof(errbuf)); ++ free(content); ++ if (tree == NULL) { ++ if (asprintf(err, "cannot parse the file: %s", errbuf) < 0) { ++ *err = safe_strdup("error allocating memory"); ++ } ++ return NULL; ++ } ++ oci_runtime_spec_hooks *ptr = make_oci_runtime_spec_hooks(tree, ctx, err); ++ yajl_tree_free(tree); ++ return ptr; ++} +diff --git a/src/lxc/json/oci_runtime_hooks.h b/src/lxc/json/oci_runtime_hooks.h +new file mode 100644 +index 0000000..bf570c9 +--- /dev/null ++++ b/src/lxc/json/oci_runtime_hooks.h +@@ -0,0 +1,15 @@ ++/****************************************************************************** ++ * Copyright (C), 1988-1999, Huawei Tech. Co., Ltd. ++ * FileName: oci_runtime_hooks.h ++ * Author: tanyifeng Version: 0.1 Date: 2018-11-08 ++ * Explanation: provide container oci runtime hooks function definition ++ ******************************************************************************/ ++#ifndef _CONTAINER_HOOKS_H ++# define _CONTAINER_HOOKS_H ++ ++# include "oci_runtime_spec.h" ++ ++oci_runtime_spec_hooks *oci_runtime_spec_hooks_parse_file(const char *filename, ++ struct parser_context *ctx, parser_error *err); ++ ++#endif +diff --git a/src/lxc/json/oci_runtime_spec.c b/src/lxc/json/oci_runtime_spec.c +new file mode 100644 +index 0000000..fd342de +--- /dev/null ++++ b/src/lxc/json/oci_runtime_spec.c +@@ -0,0 +1,195 @@ ++// Generated from spec.json. Do not edit! ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE ++#endif ++#include ++#include ++#include "oci_runtime_spec.h" ++ ++oci_runtime_spec_hooks *make_oci_runtime_spec_hooks(yajl_val tree, struct parser_context *ctx, parser_error *err) { ++ oci_runtime_spec_hooks *ret = NULL; ++ *err = 0; ++ if (tree == NULL) ++ return ret; ++ ret = safe_malloc(sizeof(*ret)); ++ { ++ yajl_val tmp = get_val(tree, "prestart", yajl_t_array); ++ if (tmp != NULL && YAJL_GET_ARRAY(tmp) != NULL && YAJL_GET_ARRAY(tmp)->len > 0) { ++ size_t i; ++ ret->prestart_len = YAJL_GET_ARRAY(tmp)->len; ++ ret->prestart = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->prestart)); ++ for (i = 0; i < YAJL_GET_ARRAY(tmp)->len; i++) { ++ yajl_val val = YAJL_GET_ARRAY(tmp)->values[i]; ++ ret->prestart[i] = make_defs_hook(val, ctx, err); ++ if (ret->prestart[i] == NULL) { ++ free_oci_runtime_spec_hooks(ret); ++ return NULL; ++ } ++ } ++ } ++ } ++ { ++ yajl_val tmp = get_val(tree, "poststart", yajl_t_array); ++ if (tmp != NULL && YAJL_GET_ARRAY(tmp) != NULL && YAJL_GET_ARRAY(tmp)->len > 0) { ++ size_t i; ++ ret->poststart_len = YAJL_GET_ARRAY(tmp)->len; ++ ret->poststart = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->poststart)); ++ for (i = 0; i < YAJL_GET_ARRAY(tmp)->len; i++) { ++ yajl_val val = YAJL_GET_ARRAY(tmp)->values[i]; ++ ret->poststart[i] = make_defs_hook(val, ctx, err); ++ if (ret->poststart[i] == NULL) { ++ free_oci_runtime_spec_hooks(ret); ++ return NULL; ++ } ++ } ++ } ++ } ++ { ++ yajl_val tmp = get_val(tree, "poststop", yajl_t_array); ++ if (tmp != NULL && YAJL_GET_ARRAY(tmp) != NULL && YAJL_GET_ARRAY(tmp)->len > 0) { ++ size_t i; ++ ret->poststop_len = YAJL_GET_ARRAY(tmp)->len; ++ ret->poststop = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->poststop)); ++ for (i = 0; i < YAJL_GET_ARRAY(tmp)->len; i++) { ++ yajl_val val = YAJL_GET_ARRAY(tmp)->values[i]; ++ ret->poststop[i] = make_defs_hook(val, ctx, err); ++ if (ret->poststop[i] == NULL) { ++ free_oci_runtime_spec_hooks(ret); ++ return NULL; ++ } ++ } ++ } ++ } ++ ++ if (tree->type == yajl_t_object && (ctx->options & PARSE_OPTIONS_STRICT)) { ++ int i; ++ for (i = 0; i < tree->u.object.len; i++) ++ if (strcmp(tree->u.object.keys[i], "prestart") && ++ strcmp(tree->u.object.keys[i], "poststart") && ++ strcmp(tree->u.object.keys[i], "poststop")) { ++ if (ctx->stderr > 0) ++ fprintf(ctx->stderr, "WARNING: unknown key found: %s\n", tree->u.object.keys[i]); ++ } ++ } ++ return ret; ++} ++ ++void free_oci_runtime_spec_hooks(oci_runtime_spec_hooks *ptr) { ++ if (ptr == NULL) ++ return; ++ if (ptr->prestart != NULL) { ++ size_t i; ++ for (i = 0; i < ptr->prestart_len; i++) ++ if (ptr->prestart[i] != NULL) { ++ free_defs_hook(ptr->prestart[i]); ++ ptr->prestart[i] = NULL; ++ } ++ free(ptr->prestart); ++ ptr->prestart = NULL; ++ } ++ if (ptr->poststart != NULL) { ++ size_t i; ++ for (i = 0; i < ptr->poststart_len; i++) ++ if (ptr->poststart[i] != NULL) { ++ free_defs_hook(ptr->poststart[i]); ++ ptr->poststart[i] = NULL; ++ } ++ free(ptr->poststart); ++ ptr->poststart = NULL; ++ } ++ if (ptr->poststop != NULL) { ++ size_t i; ++ for (i = 0; i < ptr->poststop_len; i++) ++ if (ptr->poststop[i] != NULL) { ++ free_defs_hook(ptr->poststop[i]); ++ ptr->poststop[i] = NULL; ++ } ++ free(ptr->poststop); ++ ptr->poststop = NULL; ++ } ++ free(ptr); ++} ++ ++yajl_gen_status gen_oci_runtime_spec_hooks(yajl_gen g, oci_runtime_spec_hooks *ptr, struct parser_context *ctx, parser_error *err) { ++ yajl_gen_status stat = yajl_gen_status_ok; ++ *err = 0; ++ stat = reformat_start_map(g); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->prestart != NULL)) { ++ size_t len = 0, i; ++ stat = reformat_map_key(g, "prestart", strlen("prestart")); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ if (ptr != NULL && ptr->prestart != NULL) { ++ len = ptr->prestart_len; ++ } ++ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) ++ yajl_gen_config(g, yajl_gen_beautify, 0); ++ stat = reformat_start_array(g); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ for (i = 0; i < len; i++) { ++ stat = gen_defs_hook(g, ptr->prestart[i], ctx, err); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ stat = reformat_end_array(g); ++ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) ++ yajl_gen_config(g, yajl_gen_beautify, 1); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->poststart != NULL)) { ++ size_t len = 0, i; ++ stat = reformat_map_key(g, "poststart", strlen("poststart")); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ if (ptr != NULL && ptr->poststart != NULL) { ++ len = ptr->poststart_len; ++ } ++ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) ++ yajl_gen_config(g, yajl_gen_beautify, 0); ++ stat = reformat_start_array(g); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ for (i = 0; i < len; i++) { ++ stat = gen_defs_hook(g, ptr->poststart[i], ctx, err); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ stat = reformat_end_array(g); ++ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) ++ yajl_gen_config(g, yajl_gen_beautify, 1); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->poststop != NULL)) { ++ size_t len = 0, i; ++ stat = reformat_map_key(g, "poststop", strlen("poststop")); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ if (ptr != NULL && ptr->poststop != NULL) { ++ len = ptr->poststop_len; ++ } ++ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) ++ yajl_gen_config(g, yajl_gen_beautify, 0); ++ stat = reformat_start_array(g); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ for (i = 0; i < len; i++) { ++ stat = gen_defs_hook(g, ptr->poststop[i], ctx, err); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ stat = reformat_end_array(g); ++ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) ++ yajl_gen_config(g, yajl_gen_beautify, 1); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ } ++ stat = reformat_end_map(g); ++ if (yajl_gen_status_ok != stat) ++ GEN_SET_ERROR_AND_RETURN(stat, err); ++ return yajl_gen_status_ok; ++} +diff --git a/src/lxc/json/oci_runtime_spec.h b/src/lxc/json/oci_runtime_spec.h +new file mode 100644 +index 0000000..ef3f161 +--- /dev/null ++++ b/src/lxc/json/oci_runtime_spec.h +@@ -0,0 +1,37 @@ ++// Generated from spec.json. Do not edit! ++#ifndef OCI_RUNTIME_SPEC_SCHEMA_H ++#define OCI_RUNTIME_SPEC_SCHEMA_H ++ ++#include ++#include ++#include "json_common.h" ++#include "defs.h" ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++typedef struct { ++ defs_hook **prestart; ++ size_t prestart_len; ++ ++ defs_hook **poststart; ++ size_t poststart_len; ++ ++ defs_hook **poststop; ++ size_t poststop_len; ++ ++} ++oci_runtime_spec_hooks; ++ ++void free_oci_runtime_spec_hooks(oci_runtime_spec_hooks *ptr); ++ ++oci_runtime_spec_hooks *make_oci_runtime_spec_hooks(yajl_val tree, struct parser_context *ctx, parser_error *err); ++ ++yajl_gen_status gen_oci_runtime_spec_hooks(yajl_gen g, oci_runtime_spec_hooks *ptr, struct parser_context *ctx, parser_error *err); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif +diff --git a/src/lxc/json/read-file.c b/src/lxc/json/read-file.c +new file mode 100644 +index 0000000..70e73e5 +--- /dev/null ++++ b/src/lxc/json/read-file.c +@@ -0,0 +1,95 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include "read-file.h" ++ ++#ifndef O_CLOEXEC ++#define O_CLOEXEC 02000000 ++#endif ++ ++char *fread_file(FILE *stream, size_t *length) ++{ ++ char *buf = NULL, *tmpbuf = NULL; ++ size_t off = 0; ++ ++ while (1) { ++ size_t ret, newsize; ++ ++ newsize = off + BUFSIZ + 1; ++ tmpbuf = (char *)calloc(1, newsize); ++ if (tmpbuf == NULL) { ++ goto out; ++ } ++ ++ if (buf) { ++ memcpy(tmpbuf, buf, off); ++ ++ memset(buf, 0, off); ++ ++ free(buf); ++ } ++ ++ buf = tmpbuf; ++ ret = fread(buf + off, 1, BUFSIZ, stream); ++ if (!ret && ferror(stream)) { ++ tmpbuf = NULL; ++ goto out; ++ } ++ if (ret < BUFSIZ || feof(stream)) { ++ *length = off + ret + 1; ++ buf[*length - 1] = '\0'; ++ return buf; ++ } ++ off += BUFSIZ; ++ } ++out: ++ if (buf) { ++ free(buf); ++ } ++ if (tmpbuf) { ++ free(tmpbuf); ++ } ++ return NULL; ++ ++} ++ ++char *read_file(const char *path, size_t *length) ++{ ++ char *buf = NULL; ++ char rpath[PATH_MAX + 1] = {0}; ++ int fd = -1; ++ int tmperrno; ++ FILE *fp = NULL; ++ ++ if (!path || !length) { ++ return NULL; ++ } ++ ++ if (strlen(path) > PATH_MAX || NULL == realpath(path, rpath)) { ++ return NULL; ++ } ++ ++ fd = open(rpath, O_RDONLY | O_CLOEXEC, 0640); ++ if (fd < 0) { ++ return NULL; ++ } ++ ++ fp = fdopen(fd, "r"); ++ tmperrno = errno; ++ if (!fp) { ++ close(fd); ++ errno = tmperrno; ++ return NULL; ++ } ++ ++ buf = fread_file(fp, length); ++ fclose(fp); ++ return buf; ++} +diff --git a/src/lxc/json/read-file.h b/src/lxc/json/read-file.h +new file mode 100644 +index 0000000..5d6e0eb +--- /dev/null ++++ b/src/lxc/json/read-file.h +@@ -0,0 +1,11 @@ ++#ifndef READ_FILE_H ++#define READ_FILE_H ++ ++#include ++#include ++ ++extern char *fread_file(FILE *stream, size_t *length); ++ ++extern char *read_file(const char *path, size_t *length); ++ ++#endif +diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c +index 33bb3ec..891fc62 100644 +--- a/src/lxc/lxccontainer.c ++++ b/src/lxc/lxccontainer.c +@@ -5294,6 +5294,41 @@ static int do_lxcapi_seccomp_notify_fd(struct lxc_container *c) + WRAP_API(int, lxcapi_seccomp_notify_fd) + + #ifdef HAVE_ISULAD ++/* isulad add set console fifos*/ ++static bool do_lxcapi_set_terminal_default_fifos(struct lxc_container *c, const char *in, const char *out, const char *err) ++{ ++ struct lxc_conf *conf = NULL; ++ ++ if (!c || !c->lxc_conf) ++ return false; ++ if (container_mem_lock(c)) { ++ ERROR("Error getting mem lock"); ++ return false; ++ } ++ ++ conf = c->lxc_conf; ++ if (in) { ++ if (conf->console.init_fifo[0]) ++ free(conf->console.init_fifo[0]); ++ conf->console.init_fifo[0] = safe_strdup(in); ++ } ++ if (out) { ++ if (conf->console.init_fifo[1]) ++ free(conf->console.init_fifo[1]); ++ conf->console.init_fifo[1] = safe_strdup(out); ++ } ++ if (err) { ++ if (conf->console.init_fifo[2]) ++ free(conf->console.init_fifo[2]); ++ conf->console.init_fifo[2] = safe_strdup(err); ++ } ++ ++ container_mem_unlock(c); ++ return true; ++} ++ ++WRAP_API_3(bool, lxcapi_set_terminal_default_fifos, const char *, const char *, const char *) ++ + /* isulad add set info file path */ + static bool do_lxcapi_set_container_info_file(struct lxc_container *c, const char *info_file) + { +@@ -5461,6 +5496,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath + c->seccomp_notify_fd = lxcapi_seccomp_notify_fd; + #ifdef HAVE_ISULAD + c->set_container_info_file = lxcapi_set_container_info_file; ++ c->set_terminal_init_fifos = lxcapi_set_terminal_default_fifos; + #endif + return c; + +diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h +index edfff32..4a9ba13 100644 +--- a/src/lxc/lxccontainer.h ++++ b/src/lxc/lxccontainer.h +@@ -876,6 +876,30 @@ struct lxc_container { + * \return \c true on success, else \c false. + */ + bool (*set_container_info_file) (struct lxc_container *c, const char *info_file); ++ ++ /*! isulad add ++ * \brief An API call to change the path of the console default fifos ++ * ++ * \param c Container. ++ * \param path Value of the console path. ++ * ++ * \return \c true on success, else \c false. ++ */ ++ bool (*set_terminal_init_fifos)(struct lxc_container *c, const char *in, const char *out, const char *err); ++ ++ /*! isulad add ++ * \brief An API call to add the path of terminal fifos ++ * ++ * \param c Container. ++ * \param path Value of the console path.. ++ * ++ * \return \c true on success, else \c false. ++ */ ++ bool (*add_terminal_fifos)(struct lxc_container *c, const char *in, const char *out, const char *err); ++ ++ bool (*set_terminal_winch)(struct lxc_container *c, unsigned int height, unsigned int width); ++ ++ bool (*set_exec_terminal_winch)(struct lxc_container *c, const char *suffix, unsigned int height, unsigned int width); + #endif + }; + +diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c +index 1b170ca..c8cd83f 100644 +--- a/src/lxc/terminal.c ++++ b/src/lxc/terminal.c +@@ -28,6 +28,9 @@ + #include "syscall_wrappers.h" + #include "terminal.h" + #include "utils.h" ++#ifdef HAVE_ISULAD ++#include "logger_json_file.h" ++#endif + + #if HAVE_PTY_H + #include +@@ -318,6 +321,426 @@ static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf, + return bytes_read; + } + ++#ifdef HAVE_ISULAD ++/* get time buffer */ ++static bool get_time_buffer(struct timespec *timestamp, char *timebuffer, ++ size_t maxsize) ++{ ++ struct tm tm_utc = { 0 }; ++ int32_t nanos = 0; ++ time_t seconds; ++ size_t len = 0; ++ int ret = 0; ++ ++ if (!timebuffer || !maxsize) { ++ return false; ++ } ++ ++ seconds = (time_t)timestamp->tv_sec; ++ gmtime_r(&seconds, &tm_utc); ++ strftime(timebuffer, maxsize, "%Y-%m-%dT%H:%M:%S", &tm_utc); ++ ++ nanos = (int32_t)timestamp->tv_nsec; ++ len = strlen(timebuffer); ++ ret = snprintf(timebuffer + len, (maxsize - len), ".%09dZ", nanos); ++ if (ret < 0 || ret >= (maxsize - len)) { ++ return false; ++ } ++ ++ return true; ++} ++ ++/* get now time buffer */ ++static bool get_now_time_buffer(char *timebuffer, size_t maxsize) ++{ ++ int err = 0; ++ struct timespec ts; ++ ++ err = clock_gettime(CLOCK_REALTIME, &ts); ++ if (err != 0) { ++ ERROR("failed to get time"); ++ return false; ++ } ++ ++ return get_time_buffer(&ts, timebuffer, maxsize); ++} ++ ++static int isulad_lxc_terminal_rotate_write_data(struct lxc_terminal *terminal, const char *buf, ++ int bytes_read) ++{ ++ int ret; ++ struct stat st; ++ int64_t space_left = -1; ++ ++ if (terminal->log_fd < 0) ++ return 0; ++ ++ /* A log size <= 0 means that there's no limit on the size of the log ++ * file at which point we simply ignore whether the log is supposed to ++ * be rotated or not. ++ */ ++ if (terminal->log_size <= 0) ++ return lxc_write_nointr(terminal->log_fd, buf, bytes_read); ++ ++ /* Get current size of the log file. */ ++ ret = fstat(terminal->log_fd, &st); ++ if (ret < 0) { ++ SYSERROR("Failed to stat the terminal log file descriptor"); ++ return -1; ++ } ++ ++ /* handle non-regular files */ ++ if ((st.st_mode & S_IFMT) != S_IFREG) { ++ /* This isn't a regular file. so rotating the file seems a ++ * dangerous thing to do, size limits are also very ++ * questionable. Let's not risk anything and tell the user that ++ * he's requesting us to do weird stuff. ++ */ ++ if (terminal->log_rotate > 0 || terminal->log_size > 0) ++ return -EINVAL; ++ ++ /* I mean, sure log wherever you want to. */ ++ return lxc_write_nointr(terminal->log_fd, buf, bytes_read); ++ } ++ ++ space_left = terminal->log_size - st.st_size; ++ ++ /* User doesn't want to rotate the log file and there's no more space ++ * left so simply truncate it. ++ */ ++ if (space_left <= 0 && terminal->log_rotate <= 0) { ++ ret = lxc_terminal_truncate_log_file(terminal); ++ if (ret < 0) ++ return ret; ++ ++ if (bytes_read <= terminal->log_size) ++ return lxc_write_nointr(terminal->log_fd, buf, bytes_read); ++ ++ /* Write as much as we can into the buffer and loose the rest. */ ++ return lxc_write_nointr(terminal->log_fd, buf, terminal->log_size); ++ } ++ ++ /* There's enough space left. */ ++ if (bytes_read <= space_left) ++ return lxc_write_nointr(terminal->log_fd, buf, bytes_read); ++ ++ /* There'd be more to write but we aren't instructed to rotate the log ++ * file so simply return. There's no error on our side here. ++ */ ++ if (terminal->log_rotate > 0) ++ ret = lxc_terminal_rotate_log_file(terminal); ++ else ++ ret = lxc_terminal_truncate_log_file(terminal); ++ if (ret < 0) ++ return ret; ++ ++ if (terminal->log_size < bytes_read) { ++ /* Well, this is unfortunate because it means that there is more ++ * to write than the user has granted us space. There are ++ * multiple ways to handle this but let's use the simplest one: ++ * write as much as we can, tell the user that there was more ++ * stuff to write and move on. ++ * Note that this scenario shouldn't actually happen with the ++ * standard pty-based terminal that LXC allocates since it will ++ * be switched into raw mode. In raw mode only 1 byte at a time ++ * should be read and written. ++ */ ++ WARN("Size of terminal log file is smaller than the bytes to write"); ++ ret = lxc_write_nointr(terminal->log_fd, buf, terminal->log_size); ++ if (ret < 0) ++ return -1; ++ bytes_read -= ret; ++ return bytes_read; ++ } ++ ++ /* Yay, we made it. */ ++ ret = lxc_write_nointr(terminal->log_fd, buf, bytes_read); ++ if (ret < 0) ++ return -1; ++ bytes_read -= ret; ++ return bytes_read; ++} ++ ++static ssize_t isulad_logger_write(struct lxc_terminal *terminal, const char *type, const char *buf, ++ int bytes_read) ++{ ++ logger_json_file *msg = NULL; ++ ssize_t ret = -1; ++ size_t len; ++ char *json = NULL; ++ char timebuffer[64] = { 0 }; ++ parser_error err = NULL; ++ struct parser_context ctx = { GEN_OPTIONS_SIMPLIFY | GEN_OPTIONS_NOT_VALIDATE_UTF8, stderr }; ++ ++ if (bytes_read < 0 || bytes_read >= INT_MAX) { ++ return -1; ++ } ++ msg = calloc(sizeof(logger_json_file), 1); ++ if (msg == NULL) { ++ return -errno; ++ } ++ msg->log = calloc(bytes_read, 1); ++ if (!msg->log) { ++ goto cleanup; ++ } ++ memcpy(msg->log, buf, bytes_read); ++ msg->log_len = bytes_read; ++ msg->stream = type ? safe_strdup(type) : safe_strdup("stdout"); ++ ++ get_now_time_buffer(timebuffer, sizeof(timebuffer)); ++ msg->time = safe_strdup(timebuffer); ++ ++ json = logger_json_file_generate_json(msg, &ctx, &err); ++ if (!json) { ++ ERROR("Failed to generate json: %s", err); ++ goto cleanup; ++ } ++ len = strlen(json); ++ json[len] = '\n'; ++ ret = isulad_lxc_terminal_rotate_write_data(terminal, json, len + 1); ++cleanup: ++ free(json); ++ free_logger_json_file(msg); ++ free(err); ++ return ret; ++} ++ ++static int isulad_lxc_terminal_write_log_file(struct lxc_terminal *terminal, const char *type, char *buf, ++ int bytes_read) ++{ ++#define __BUF_CACHE_SIZE (16 * LXC_TERMINAL_BUFFER_SIZE) ++ static char cache[__BUF_CACHE_SIZE]; ++ static int size = 0; ++ int upto, index; ++ int begin = 0, buf_readed = 0, buf_left = 0; ++ int ret; ++ ++ if (buf != NULL && bytes_read > 0) { ++ /* Work out how much more data we are okay with reading this time. */ ++ upto = size + bytes_read; ++ if (upto > __BUF_CACHE_SIZE) { ++ upto = __BUF_CACHE_SIZE; ++ } ++ ++ if (upto > size) { ++ buf_readed = upto - size; ++ memcpy(cache + size, buf, buf_readed); ++ buf_left = bytes_read - buf_readed; ++ size += buf_readed; ++ } ++ } ++ ++ // If we have no data to log, and there's no more coming, we're done. ++ if (size == 0) ++ return 0; ++ ++ // Break up the data that we've buffered up into lines, and log each in turn. ++ for (index = 0; index < size; index++) { ++ if (cache[index] == '\n') { ++ ret = isulad_logger_write(terminal, type, cache + begin, index - begin + 1); ++ if (ret < 0) { ++ WARN("Failed to log msg"); ++ } ++ begin = index + 1; ++ } ++ } ++ /* If there's no more coming, or the buffer is full but ++ * has no newlines, log whatever we haven't logged yet, ++ * noting that it's a partial log line. */ ++ if (buf == NULL || (begin == 0 && size == __BUF_CACHE_SIZE)) { ++ if (begin < size) { ++ ret = isulad_logger_write(terminal, type, cache + begin, size - begin); ++ if (ret < 0) { ++ WARN("Failed to log msg"); ++ } ++ begin = 0; ++ size = 0; ++ } ++ if (buf == NULL) { ++ return 0; ++ } ++ } ++ /* Move any unlogged data to the front of the buffer in preparation for another read. */ ++ if (begin > 0) { ++ memcpy(cache, cache + begin, size - begin); ++ size -= begin; ++ } ++ /* Move left data to cache buffer */ ++ if (buf_left > 0) { ++ memcpy(cache + size, buf + buf_readed, buf_left); ++ size += buf_left; ++ } ++ return 0; ++} ++ ++/* isulad: forward data to all fifos */ ++static void lxc_forward_data_to_fifo(struct lxc_list *list, bool is_err, const char *buf, int r) ++{ ++ struct lxc_list *it = NULL; ++ struct lxc_list *next = NULL; ++ struct lxc_fifos_fd *elem = NULL; ++ ++ lxc_list_for_each_safe(it, list, next) { ++ elem = it->elem; ++ if (is_err) { ++ if (elem->err_fd >= 0) ++ lxc_write_nointr(elem->err_fd, buf, r); ++ } else { ++ if (elem->out_fd >= 0) ++ lxc_write_nointr(elem->out_fd, buf, r); ++ } ++ } ++ ++ return; ++} ++ ++/* isulad: judge the fd whether is fifo */ ++static bool lxc_terminal_is_fifo(int fd, struct lxc_list *list) ++{ ++ struct lxc_list *it = NULL; ++ struct lxc_list *next = NULL; ++ struct lxc_fifos_fd *elem = NULL; ++ ++ lxc_list_for_each_safe(it, list, next) { ++ elem = it->elem; ++ if (elem->in_fd == fd) ++ return true; ++ } ++ ++ return false; ++} ++ ++/* isulad: if fd == -1, means delete all the fifos*/ ++int lxc_terminal_delete_fifo(int fd, struct lxc_list *list) ++{ ++ struct lxc_list *it = NULL; ++ struct lxc_list *next = NULL; ++ struct lxc_fifos_fd *elem = NULL; ++ ++ lxc_list_for_each_safe(it, list, next) { ++ elem = it->elem; ++ if (elem->in_fd == fd || -1 == fd) { ++ INFO("Delete fifo fd %d", fd); ++ lxc_list_del(it); ++ if (elem->in_fifo) ++ free(elem->in_fifo); ++ if (elem->out_fifo) ++ free(elem->out_fifo); ++ if (elem->err_fifo) ++ free(elem->err_fifo); ++ if (elem->in_fd >= 0) ++ close(elem->in_fd); ++ if (elem->out_fd >= 0) ++ close(elem->out_fd); ++ if (elem->err_fd >= 0) ++ close(elem->err_fd); ++ free(elem); ++ } ++ } ++ ++ return 0; ++} ++ ++int lxc_terminal_io_cb(int fd, uint32_t events, void *data, ++ struct lxc_epoll_descr *descr) ++{ ++ struct lxc_terminal *terminal = data; ++ char buf[2 * LXC_TERMINAL_BUFFER_SIZE]; ++ int r, w, w_log, w_rbuf; ++ ++ w = r = lxc_read_nointr(fd, buf, sizeof(buf)); ++ if (r <= 0) { ++ INFO("Terminal client on fd %d has exited", fd); ++ lxc_mainloop_del_handler(descr, fd); ++ ++ if (fd == terminal->master) { ++ terminal->master = -EBADF; ++ /* write remained buffer to terminal log */ ++ if (terminal->log_fd >= 0) { ++ w_log = isulad_lxc_terminal_write_log_file(terminal, "stdout", NULL, 0); ++ if (w_log < 0) ++ TRACE("Failed to write %d bytes to terminal log", r); ++ } ++ /* notes: do not close the master fd due to if we close the fd, the process may ++ * recive SIGHUP and the exit code will be 129 (128 + 1) ++ */ ++ return LXC_MAINLOOP_CLOSE; ++ } else if (fd == terminal->peer) { ++ lxc_terminal_signal_fini(terminal); ++ terminal->peer = -EBADF; ++ close(fd); ++ return LXC_MAINLOOP_CONTINUE; /* isulad: do not close mainloop when peer close*/ ++ } else if (lxc_terminal_is_fifo(fd, &terminal->fifos)) { ++ /* isulad: delete fifos when the client close */ ++ lxc_terminal_delete_fifo(fd, &terminal->fifos); ++ return LXC_MAINLOOP_CONTINUE; ++ } else if (fd == terminal->pipes[1][0] || fd == terminal->pipes[2][0]) { ++ if (fd == terminal->pipes[1][0]) { ++ w_log = isulad_lxc_terminal_write_log_file(terminal, "stdout", NULL, 0); ++ terminal->pipes[1][0] = -EBADF; ++ } else if (fd == terminal->pipes[2][0]) { ++ w_log = isulad_lxc_terminal_write_log_file(terminal, "stderr", NULL, 0); ++ terminal->pipes[2][0] = -EBADF; ++ } ++ if (w_log < 0) ++ TRACE("Failed to write %d bytes to terminal log", r); ++ close(fd); ++ return LXC_MAINLOOP_CONTINUE; ++ } else if (fd == terminal->pipes[0][1]) { ++ TRACE("closed stdin pipe of container stdin"); ++ terminal->pipes[0][1] = -EBADF; ++ close(fd); ++ return LXC_MAINLOOP_CONTINUE; ++ } else { ++ ERROR("Handler received unexpected file descriptor"); ++ } ++ close(fd); ++ return LXC_MAINLOOP_CLOSE; ++ } ++ ++ if (fd == terminal->peer || lxc_terminal_is_fifo(fd, &terminal->fifos)) { ++ if (terminal->master > 0) ++ w = lxc_write_nointr(terminal->master, buf, r); ++ if (terminal->pipes[0][1] > 0) ++ w = lxc_write_nointr(terminal->pipes[0][1], buf, r); ++ } ++ ++ w_rbuf = w_log = 0; ++ if (fd == terminal->master || fd == terminal->pipes[1][0] || fd == terminal->pipes[2][0]) { ++ /* write to peer first */ ++ if (terminal->peer >= 0) ++ w = lxc_write_nointr(terminal->peer, buf, r); ++ ++ /* isulad: forward data to fifos */ ++ lxc_forward_data_to_fifo(&terminal->fifos, fd == terminal->pipes[2][0], buf, r); ++ ++ /* write to terminal ringbuffer */ ++ if (terminal->buffer_size > 0) ++ w_rbuf = lxc_ringbuf_write(&terminal->ringbuf, buf, r); ++ ++ /* write to terminal log */ ++ if (terminal->log_fd >= 0) { ++ if (fd == terminal->master || fd == terminal->pipes[1][0]) ++ w_log = isulad_lxc_terminal_write_log_file(terminal, "stdout", buf, r); ++ else if (fd == terminal->pipes[2][0]) ++ w_log = isulad_lxc_terminal_write_log_file(terminal, "stderr", buf, r); ++ } ++ } ++ ++ if (w != r) ++ WARN("Short write on terminal r:%d != w:%d", r, w); ++ ++ if (w_rbuf < 0) { ++ errno = -w_rbuf; ++ SYSTRACE("Failed to write %d bytes to terminal ringbuffer", r); ++ } ++ ++ if (w_log < 0) ++ TRACE("Failed to write %d bytes to terminal log", r); ++ ++ return LXC_MAINLOOP_CONTINUE; ++} ++#else + int lxc_terminal_io_cb(int fd, uint32_t events, void *data, + struct lxc_epoll_descr *descr) + { +@@ -374,6 +797,7 @@ int lxc_terminal_io_cb(int fd, uint32_t events, void *data, + + return LXC_MAINLOOP_CONTINUE; + } ++#endif + + static int lxc_terminal_mainloop_add_peer(struct lxc_terminal *terminal) + { +@@ -401,6 +825,110 @@ static int lxc_terminal_mainloop_add_peer(struct lxc_terminal *terminal) + return 0; + } + ++#ifdef HAVE_ISULAD ++/* isulad add pipes to mainloop */ ++static int lxc_terminal_mainloop_add_pipes(struct lxc_terminal *terminal) ++{ ++ int ret = 0; ++ ++ // parent read data from fifo, and send to stdin of container ++ if (terminal->pipes[0][1] > 0) { ++ ret = lxc_mainloop_add_handler(terminal->descr, terminal->pipes[0][1], ++ lxc_terminal_io_cb, terminal); ++ if (ret) { ++ ERROR("pipe fd %d not added to mainloop", terminal->pipes[0][1]); ++ return -1; ++ } ++ } ++ // parent read data from stdout of container, and send to fifo ++ if (terminal->pipes[1][0] > 0) { ++ ret = lxc_mainloop_add_handler(terminal->descr, terminal->pipes[1][0], ++ lxc_terminal_io_cb, terminal); ++ if (ret) { ++ ERROR("pipe fd %d not added to mainloop", terminal->pipes[1][0]); ++ return -1; ++ } ++ } ++ // parent read data from stderr of container, and send to fifo ++ if (terminal->pipes[2][0] > 0) { ++ ret = lxc_mainloop_add_handler(terminal->descr, terminal->pipes[2][0], ++ lxc_terminal_io_cb, terminal); ++ if (ret) { ++ ERROR("pipe fd %d not added to mainloop", terminal->pipes[2][0]); ++ return -1; ++ } ++ } ++ return ret; ++} ++ ++/* isulad add fifo to mainloop */ ++static int lxc_terminal_mainloop_add_fifo(struct lxc_terminal *terminal) ++{ ++ int ret = 0; ++ struct lxc_list *it = NULL; ++ struct lxc_list *next = NULL; ++ struct lxc_fifos_fd *elem = NULL; ++ ++ lxc_list_for_each_safe(it, &terminal->fifos, next) { ++ elem = it->elem; ++ if (elem->in_fd >= 0) { ++ ret = lxc_mainloop_add_handler(terminal->descr, elem->in_fd, ++ lxc_terminal_io_cb, terminal); ++ if (ret) { ++ ERROR("console fifo %s not added to mainloop", elem->in_fifo); ++ return -1; ++ } ++ } ++ } ++ return ret; ++} ++ ++int lxc_terminal_mainloop_add(struct lxc_epoll_descr *descr, ++ struct lxc_terminal *terminal) ++{ ++ int ret; ++ ++ /* We cache the descr so that we can add an fd to it when someone ++ * does attach to it in lxc_terminal_allocate(). ++ */ ++ terminal->descr = descr; ++ ++ ret = lxc_terminal_mainloop_add_peer(terminal); ++ if (ret < 0) { ++ ERROR("Failed to add handler for terminal peer to mainloop"); ++ return -1; ++ } ++ ++ /* isulad add pipes to mainloop */ ++ ret = lxc_terminal_mainloop_add_pipes(terminal); ++ if (ret < 0) { ++ ERROR("Failed to add handler for terminal fifos to mainloop"); ++ return -1; ++ } ++ ++ /* isulad add fifo to mainloop */ ++ ret = lxc_terminal_mainloop_add_fifo(terminal); ++ if (ret < 0) { ++ ERROR("Failed to add handler for terminal fifos to mainloop"); ++ return -1; ++ } ++ ++ if (terminal->master < 0) { ++ INFO("Terminal is not initialized"); ++ return 0; ++ } ++ ++ ret = lxc_mainloop_add_handler(descr, terminal->master, ++ lxc_terminal_io_cb, terminal); ++ if (ret < 0) { ++ ERROR("Failed to add handler for terminal master fd %d to " ++ "mainloop", terminal->master); ++ return -1; ++ } ++ ++ return 0; ++} ++#else + int lxc_terminal_mainloop_add(struct lxc_epoll_descr *descr, + struct lxc_terminal *terminal) + { +@@ -426,6 +954,7 @@ int lxc_terminal_mainloop_add(struct lxc_epoll_descr *descr, + + return lxc_terminal_mainloop_add_peer(terminal); + } ++#endif + + int lxc_setup_tios(int fd, struct termios *oldtios) + { +@@ -760,6 +1289,31 @@ void lxc_terminal_delete(struct lxc_terminal *terminal) + if (terminal->log_fd >= 0) + close(terminal->log_fd); + terminal->log_fd = -1; ++ ++#ifdef HAVE_ISULAD ++ /* isulad: close all pipes */ ++ if (terminal->pipes[0][0] >= 0) ++ close(terminal->pipes[0][0]); ++ terminal->pipes[0][0] = -1; ++ if (terminal->pipes[0][1] >= 0) ++ close(terminal->pipes[0][1]); ++ terminal->pipes[0][1] = -1; ++ if (terminal->pipes[1][0] >= 0) ++ close(terminal->pipes[1][0]); ++ terminal->pipes[1][0] = -1; ++ if (terminal->pipes[1][1] >= 0) ++ close(terminal->pipes[1][1]); ++ terminal->pipes[1][1] = -1; ++ if (terminal->pipes[2][0] >= 0) ++ close(terminal->pipes[2][0]); ++ terminal->pipes[2][0] = -1; ++ if (terminal->pipes[2][1] >= 0) ++ close(terminal->pipes[2][1]); ++ terminal->pipes[2][1] = -1; ++ ++ /* isulad: delete all fifos */ ++ lxc_terminal_delete_fifo(-1, &terminal->fifos); ++#endif + } + + /** +@@ -828,6 +1382,215 @@ int lxc_terminal_create_log_file(struct lxc_terminal *terminal) + return 0; + } + ++#ifdef HAVE_ISULAD ++/* isulad: fd_nonblock */ ++static int fd_nonblock(int fd) ++{ ++ int flags; ++ ++ flags = fcntl(fd, F_GETFL); ++ ++ return fcntl(fd, F_SETFL, (int)((unsigned int)flags | O_NONBLOCK)); ++} ++ ++static int terminal_fifo_open(const char *fifo_path, int flags) ++{ ++ int fd = -1; ++ ++ fd = lxc_open(fifo_path, flags, 0); ++ if (fd < 0) { ++ WARN("Failed to open fifo %s to send message: %s.", fifo_path, ++ strerror(errno)); ++ return -1; ++ } ++ ++ return fd; ++} ++ ++bool fifo_exists(const char *path) ++{ ++ struct stat sb; ++ int ret; ++ ++ ret = stat(path, &sb); ++ if (ret < 0) ++ // could be something other than eexist, just say no ++ return false; ++ return S_ISFIFO(sb.st_mode); ++} ++ ++/* isulad: set terminal fifos */ ++static int lxc_terminal_set_fifo(struct lxc_terminal *console, const char *in, const char *out, const char *err, int *input_fd) ++{ ++ int fifofd_in = -1, fifofd_out = -1, fifofd_err = -1; ++ struct lxc_fifos_fd *fifo_elem = NULL; ++ ++ if ((in && !fifo_exists(in)) || (out && !fifo_exists(out)) || (err && !fifo_exists(err))) { ++ ERROR("File %s or %s or %s does not refer to a FIFO", in, out, err); ++ return -1; ++ } ++ ++ if (in) { ++ fifofd_in = terminal_fifo_open(in, O_RDONLY | O_NONBLOCK | O_CLOEXEC); ++ if (fifofd_in < 0) { ++ SYSERROR("Failed to open FIFO: %s", in); ++ return -1; ++ } ++ } ++ ++ if (out) { ++ fifofd_out = terminal_fifo_open(out, O_WRONLY | O_NONBLOCK | O_CLOEXEC); ++ if (fifofd_out < 0) { ++ SYSERROR("Failed to open FIFO: %s", out); ++ if (fifofd_in >= 0) ++ close(fifofd_in); ++ return -1; ++ } ++ } ++ ++ if (err) { ++ fifofd_err = terminal_fifo_open(err, O_WRONLY | O_NONBLOCK | O_CLOEXEC); ++ if (fifofd_err < 0) { ++ SYSERROR("Failed to open FIFO: %s", err); ++ if (fifofd_in >= 0) ++ close(fifofd_in); ++ if (fifofd_out >= 0) ++ close(fifofd_out); ++ return -1; ++ } ++ } ++ ++ fifo_elem = malloc(sizeof(*fifo_elem)); ++ if (fifo_elem == NULL) { ++ if (fifofd_in >= 0) ++ close(fifofd_in); ++ if (fifofd_out >= 0) ++ close(fifofd_out); ++ if (fifofd_err >= 0) ++ close(fifofd_err); ++ return -1; ++ } ++ memset(fifo_elem, 0, sizeof(*fifo_elem)); ++ ++ fifo_elem->in_fifo = safe_strdup(in ? in : ""); ++ fifo_elem->out_fifo = safe_strdup(out ? out : ""); ++ fifo_elem->err_fifo = safe_strdup(err ? err : ""); ++ fifo_elem->in_fd = fifofd_in; ++ fifo_elem->out_fd = fifofd_out; ++ fifo_elem->err_fd = fifofd_err; ++ lxc_list_add_elem(&fifo_elem->node, fifo_elem); ++ lxc_list_add_tail(&console->fifos, &fifo_elem->node); ++ ++ if (input_fd) ++ *input_fd = fifofd_in; ++ ++ return 0; ++} ++ ++/* isulad: add default fifos */ ++static int lxc_terminal_fifo_default(struct lxc_terminal *terminal) ++{ ++ if (terminal->init_fifo[0] || terminal->init_fifo[1] || terminal->init_fifo[2]) ++ return lxc_terminal_set_fifo(terminal, terminal->init_fifo[0], terminal->init_fifo[1], terminal->init_fifo[2], NULL); ++ return 0; ++} ++ ++static int use_unix_newline(int master_fd) ++{ ++ struct termios oldtios; ++ int ret; ++ ++ ret = tcgetattr(master_fd, &oldtios); ++ if (ret < 0) ++ return -1; ++ oldtios.c_oflag &= ~ONLCR; ++ ret = tcsetattr(master_fd, TCSAFLUSH, &oldtios); ++ if (ret < 0) ++ return -1; ++ return 0; ++} ++ ++int lxc_terminal_create(struct lxc_terminal *terminal) ++{ ++ int ret; ++ ++ if (!terminal->disable_pty) { ++ ret = openpty(&terminal->master, &terminal->slave, NULL, NULL, NULL); ++ if (ret < 0) { ++ SYSERROR("Failed to open terminal"); ++ return -1; ++ } ++ ++ ret = ttyname_r(terminal->slave, terminal->name, sizeof(terminal->name)); ++ if (ret < 0) { ++ SYSERROR("Failed to retrieve name of terminal slave"); ++ goto err; ++ } ++ ++ /* isulad: clear ONLCR flag */ ++ ret = use_unix_newline(terminal->master); ++ if (ret < 0) { ++ SYSERROR("Failed to clear ONLCR flag on terminal master"); ++ goto err; ++ } ++ ++ ret = fd_cloexec(terminal->master, true); ++ if (ret < 0) { ++ SYSERROR("Failed to set FD_CLOEXEC flag on terminal master"); ++ goto err; ++ } ++ ++ /* isulad: make master NONBLOCK */ ++ ret = fd_nonblock(terminal->master); ++ if (ret < 0) { ++ SYSERROR("Failed to set O_NONBLOCK flag on terminal master"); ++ goto err; ++ } ++ ++ ret = fd_cloexec(terminal->slave, true); ++ if (ret < 0) { ++ SYSERROR("Failed to set FD_CLOEXEC flag on terminal slave"); ++ goto err; ++ } ++ ++ ret = lxc_terminal_peer_default(terminal); ++ if (ret < 0) { ++ ERROR("Failed to allocate proxy terminal"); ++ goto err; ++ } ++ } else { ++ /* isulad: create 3 pipes */ ++ /* for stdin */ ++ if (pipe2(terminal->pipes[0], O_CLOEXEC)) { ++ ERROR("Failed to create stdin pipe"); ++ goto err; ++ } ++ /* for stdout */ ++ if (pipe2(terminal->pipes[1], O_NONBLOCK | O_CLOEXEC)) { ++ ERROR("Failed to create stdout pipe"); ++ goto err; ++ } ++ /* for stderr */ ++ if (pipe2(terminal->pipes[2], O_NONBLOCK | O_CLOEXEC)) { ++ ERROR("Failed to create stderr pipe"); ++ goto err; ++ } ++ } ++ ++ /* isulad: open fifos */ ++ ret = lxc_terminal_fifo_default(terminal); ++ if (ret < 0) { ++ ERROR("Failed to allocate fifo terminal"); ++ goto err; ++ } ++ ++ return 0; ++ ++err: ++ lxc_terminal_delete(terminal); ++ return -ENODEV; ++} ++#else + int lxc_terminal_create(struct lxc_terminal *terminal) + { + int ret; +@@ -868,6 +1631,7 @@ err: + lxc_terminal_delete(terminal); + return -ENODEV; + } ++#endif + + int lxc_terminal_setup(struct lxc_conf *conf) + { +@@ -1146,6 +1910,18 @@ void lxc_terminal_init(struct lxc_terminal *terminal) + terminal->peer = -EBADF; + terminal->log_fd = -EBADF; + lxc_terminal_info_init(&terminal->proxy); ++#ifdef HAVE_ISULAD ++ terminal->init_fifo[0] = NULL; ++ terminal->init_fifo[1] = NULL; ++ terminal->init_fifo[2] = NULL; ++ terminal->pipes[0][0] = -1; ++ terminal->pipes[0][1] = -1; ++ terminal->pipes[1][0] = -1; ++ terminal->pipes[1][1] = -1; ++ terminal->pipes[2][0] = -1; ++ terminal->pipes[2][1] = -1; ++ lxc_list_init(&terminal->fifos); ++#endif + } + + void lxc_terminal_conf_free(struct lxc_terminal *terminal) +@@ -1155,6 +1931,13 @@ void lxc_terminal_conf_free(struct lxc_terminal *terminal) + if (terminal->buffer_size > 0 && terminal->ringbuf.addr) + lxc_ringbuf_release(&terminal->ringbuf); + lxc_terminal_signal_fini(terminal); ++#ifdef HAVE_ISULAD ++ /*isulad: free console fifos */ ++ free(terminal->init_fifo[0]); ++ free(terminal->init_fifo[1]); ++ free(terminal->init_fifo[2]); ++ lxc_terminal_delete_fifo(-1, &terminal->fifos); ++#endif + } + + int lxc_terminal_map_ids(struct lxc_conf *c, struct lxc_terminal *terminal) +diff --git a/src/lxc/terminal.h b/src/lxc/terminal.h +index 1283cb3..dfc03c6 100644 +--- a/src/lxc/terminal.h ++++ b/src/lxc/terminal.h +@@ -88,8 +88,28 @@ struct lxc_terminal { + /* the in-memory ringbuffer */ + struct lxc_ringbuf ringbuf; + }; ++#ifdef HAVE_ISULAD ++ char *init_fifo[3]; /* isulad: default fifos for the start */ ++ struct lxc_list fifos; /* isulad: fifos used to forward teminal */ ++ bool disable_pty; ++ bool open_stdin; ++ int pipes[3][2]; /* isulad: pipes for dup to container fds of stdin,stdout,stderr on daemonize mode*/ ++#endif + }; + ++#ifdef HAVE_ISULAD ++/* isulad: fifo struct */ ++struct lxc_fifos_fd { ++ char *in_fifo; ++ char *out_fifo; ++ char *err_fifo; ++ int in_fd; ++ int out_fd; ++ int err_fd; ++ struct lxc_list node; ++}; ++#endif ++ + /** + * lxc_terminal_allocate: allocate the console or a tty + * +diff --git a/src/lxc/tools/arguments.h b/src/lxc/tools/arguments.h +index 91f4e9a..214949b 100644 +--- a/src/lxc/tools/arguments.h ++++ b/src/lxc/tools/arguments.h +@@ -42,6 +42,7 @@ struct lxc_arguments { + const char *share_ns[32]; /* size must be greater than LXC_NS_MAX */ + #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 */ + #endif + + /* for lxc-console */ +diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c +index 83ee75a..4c4c820 100644 +--- a/src/lxc/tools/lxc_start.c ++++ b/src/lxc/tools/lxc_start.c +@@ -125,6 +125,15 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) + case OPT_CONTAINER_INFO: + args->container_info = arg; + break; ++ case OPT_INPUT_FIFO: ++ args->terminal_fifos[0] = arg; ++ break; ++ case OPT_OUTPUT_FIFO: ++ args->terminal_fifos[1] = arg; ++ break; ++ case OPT_STDERR_FIFO: ++ args->terminal_fifos[2] = arg; ++ break; + #endif + } + return 0; +@@ -306,6 +315,9 @@ 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]); ++ } + #endif + + if (my_args.console) +-- +1.8.3.1 + diff --git a/0011-Add-exit-FIFO-to-monitor-state-of-lxc-monitor.patch b/0011-add-exit-fifo-to-monitor-state-of-lxc-monitor.patch similarity index 40% rename from 0011-Add-exit-FIFO-to-monitor-state-of-lxc-monitor.patch rename to 0011-add-exit-fifo-to-monitor-state-of-lxc-monitor.patch index f2e4b7c4508e7628ee914148653b4566012cf12e..3f83889b0feac2ed76b24499f0bfd58f06a7c37e 100644 --- a/0011-Add-exit-FIFO-to-monitor-state-of-lxc-monitor.patch +++ b/0011-add-exit-fifo-to-monitor-state-of-lxc-monitor.patch @@ -1,261 +1,271 @@ -From 70b6cb3c2a07f49af1f7dd251eac39e20c539f7e Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Sat, 12 Jan 2019 02:07:15 -0500 -Subject: [PATCH 011/140] Add exit FIFO to monitor state of [lxc monitor] +From 5aee93396a979771f59d8accc4f4c168fd31b584 Mon Sep 17 00:00:00 2001 +From: wujing +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: LiFeng +Signed-off-by: wujing --- - src/lxc/conf.c | 3 +++ + src/lxc/conf.c | 4 ++++ src/lxc/conf.h | 2 ++ - src/lxc/confile.c | 8 ++++---- - src/lxc/lxccontainer.c | 20 +++++++++++++++++++- - src/lxc/lxccontainer.h | 6 ++++++ - src/lxc/start.c | 10 ++++++++++ - src/lxc/start.h | 2 ++ - src/lxc/terminal.c | 4 ++-- - src/lxc/tools/arguments.h | 2 ++ - src/lxc/tools/lxc_start.c | 9 +++++++++ - 10 files changed, 59 insertions(+), 7 deletions(-) + 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 0b4b63b..bc45e44 100644 +index 1487b73..a904348 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c -@@ -2759,6 +2759,7 @@ struct lxc_conf *lxc_conf_init(void) - +@@ -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; - /* isulad add end */ - - return new; -@@ -4195,6 +4196,8 @@ void lxc_conf_free(struct lxc_conf *conf) - lxc_clear_init_args(conf); - lxc_clear_populate_devices(conf); + 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) ++ if (conf->exit_fd != -1) { + close(conf->exit_fd); - /* isulad add end */ - free(conf); - } ++ } + lxc_clear_init_args(conf); + lxc_clear_populate_devices(conf); + #endif diff --git a/src/lxc/conf.h b/src/lxc/conf.h -index e0954f9..2d939cd 100644 +index 23942ac..c5b70e1 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h -@@ -405,6 +405,8 @@ struct lxc_conf { - struct lxc_list populate_devs; +@@ -430,6 +430,8 @@ struct lxc_conf { + mode_t umask; //umask value char *container_info_file; + + int exit_fd; /* exit fifo fd*/ - /* isulad add end */ - }; - -diff --git a/src/lxc/confile.c b/src/lxc/confile.c -index e3212d3..cbef2e2 100644 ---- a/src/lxc/confile.c -+++ b/src/lxc/confile.c -@@ -240,10 +240,10 @@ static struct lxc_config_t config_jump_table[] = { - { "lxc.sysctl", set_config_sysctl, get_config_sysctl, clr_config_sysctl, }, - { "lxc.proc", set_config_proc, get_config_proc, clr_config_proc, }, + #endif -- /*isulad add begin*/ -- { "lxc.isulad.init.args", set_config_init_args, get_config_init_args, clr_config_init_args, }, -- { "lxc.isulad.populate.device", set_config_populate_device, get_config_populate_device, clr_config_populate_device, }, -- /*isulad add end*/ -+ /*isulad add begin*/ -+ { "lxc.isulad.init.args", set_config_init_args, get_config_init_args, clr_config_init_args, }, -+ { "lxc.isulad.populate.device", set_config_populate_device, get_config_populate_device, clr_config_populate_device, }, -+ /*isulad add end*/ }; - - static const size_t config_jump_table_size = sizeof(config_jump_table) / sizeof(struct lxc_config_t); diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index 5679b9b..8029f33 100644 +index 891fc62..64cde99 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c -@@ -295,6 +295,10 @@ static void lxc_container_free(struct lxc_container *c) +@@ -281,6 +281,11 @@ static void lxc_container_free(struct lxc_container *c) free(c->config_path); c->config_path = NULL; -+ /* isulad: free exit fifo */ ++#ifdef HAVE_ISULAD + free(c->exit_fifo); + c->exit_fifo = NULL; ++#endif + free(c); } -@@ -882,7 +886,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a +@@ -894,7 +899,11 @@ 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[4] = {-1, -1, -1, -1}; ++#ifdef HAVE_ISULAD ++ int keepfds[] = {-1, -1, -1, -1, -1}; ++#else + int keepfds[3] = {-1, -1, -1}; ++#endif /* container does exist */ if (!c) -@@ -1077,6 +1081,16 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a +@@ -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 = open(c->exit_fifo, O_WRONLY | O_NONBLOCK | O_CLOEXEC); ++ 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 */ -@@ -1111,6 +1125,10 @@ reboot: +@@ -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]; -+ /* isulad: keep exit fifo fd */ ++ ++#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 3c845fe..503038a 100644 +index 4a9ba13..fa9bd5e 100644 --- a/src/lxc/lxccontainer.h +++ b/src/lxc/lxccontainer.h -@@ -81,6 +81,12 @@ struct lxc_container { - */ - char *pidfile; +@@ -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 + /*! - * \private - * Container semaphore lock. + * \brief Determine if \c /var/lib/lxc/$name/config exists. + * diff --git a/src/lxc/start.c b/src/lxc/start.c -index 9d71dd7..9365d11 100644 +index f5f9565..70e8282 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c -@@ -730,6 +730,7 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf, - handler->nsfd[i] = -1; +@@ -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 */ - - if (daemonize && handler->conf->reboot == REBOOT_NONE) { - /* Create socketpair() to synchronize on daemonized startup. -@@ -1005,6 +1006,14 @@ void lxc_fini(const char *name, struct lxc_handler *handler) ++#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)) ++ 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. */ -@@ -2038,6 +2047,7 @@ int __lxc_start(const char *name, struct lxc_handler *handler, +@@ -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; -+ handler->exit_code = exit_code; /* isuald: record exit code*/ - out_fini: ++#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 df987dc..f59bf54 100644 +index 7e2371c..1368d0e 100644 --- a/src/lxc/start.h +++ b/src/lxc/start.h -@@ -133,6 +133,8 @@ struct lxc_handler { +@@ -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/terminal.c b/src/lxc/terminal.c -index c507712..508e2e6 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -1004,8 +1004,8 @@ static int lxc_terminal_set_fifo(struct lxc_terminal *console, const char *in, c - static int lxc_terminal_fifo_default(struct lxc_terminal *terminal) - { - if (!terminal->init_fifo[0] || !terminal->init_fifo[1]) { -- ERROR("Invalid default terminal fifos"); -- return -1; -+ DEBUG("Invalid default terminal fifos"); -+ return 0; - } - - return lxc_terminal_set_fifo(terminal, terminal->init_fifo[0], terminal->init_fifo[1]); diff --git a/src/lxc/tools/arguments.h b/src/lxc/tools/arguments.h -index b6df23f..61f4a0a 100644 +index 214949b..ea5f938 100644 --- a/src/lxc/tools/arguments.h +++ b/src/lxc/tools/arguments.h -@@ -64,6 +64,7 @@ struct lxc_arguments { - const char *share_ns[32]; /* size must be greater than LXC_NS_MAX */ - const char *terminal_fifos[2]; /* isulad add, fifos used to redirct stdin/out/err */ +@@ -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 */ - unsigned int ttynum; -@@ -178,6 +179,7 @@ struct lxc_arguments { - #define OPT_INPUT_FIFO OPT_USAGE - 7 - #define OPT_OUTPUT_FIFO OPT_USAGE - 8 - #define OPT_CONTAINER_INFO OPT_USAGE - 9 -+#define OPT_EXIT_FIFO OPT_USAGE - 10 - /* isulad add end*/ - - extern int lxc_arguments_parse(struct lxc_arguments *args, int argc, diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c -index 2f94d67..60c7d70 100644 +index 4c4c820..8041f02 100644 --- a/src/lxc/tools/lxc_start.c +++ b/src/lxc/tools/lxc_start.c -@@ -73,6 +73,7 @@ static const struct option my_longopts[] = { - {"in-fifo", required_argument, 0, OPT_INPUT_FIFO}, - {"out-fifo", required_argument, 0, OPT_OUTPUT_FIFO}, +@@ -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}, - /* isulad add end */ + #endif LXC_COMMON_OPTIONS }; -@@ -154,6 +155,9 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) +@@ -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; + break; + #endif ++ } return 0; } -@@ -332,6 +336,11 @@ int main(int argc, char *argv[]) +@@ -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 = strdup(my_args.exit_monitor_fifo); -+ } -+ - if (my_args.console) - if (!c->set_config_item(c, "lxc.console.path", my_args.console)) - goto out; ++ c->exit_fifo = safe_strdup(my_args.exit_monitor_fifo); + } + #endif + -- 1.8.3.1 diff --git a/0012-Adapt-to-isulad-log.patch b/0012-Adapt-to-isulad-log.patch new file mode 100644 index 0000000000000000000000000000000000000000..3b8e380a0352a188de8fae31e3b4c51ac91cc337 --- /dev/null +++ b/0012-Adapt-to-isulad-log.patch @@ -0,0 +1,142 @@ +From 74612254660138c0fe96290a6f1ae3c8e46295b8 Mon Sep 17 00:00:00 2001 +From: haozi007 +Date: Mon, 13 Apr 2020 16:44:17 +0800 +Subject: [PATCH 12/49] Adapt to isulad log + +Signed-off-by: haozi007 +--- + src/lxc/log.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++- + src/lxc/tools/lxc_start.c | 2 ++ + 2 files changed, 59 insertions(+), 1 deletion(-) + +diff --git a/src/lxc/log.c b/src/lxc/log.c +index 30d6773..9794582 100644 +--- a/src/lxc/log.c ++++ b/src/lxc/log.c +@@ -55,6 +55,38 @@ static char *log_vmname = NULL; + + lxc_log_define(log, lxc); + ++#ifdef HAVE_ISULAD ++static inline const char *isulad_get_fifo_path(const char *file) ++{ ++#define ISULAD_FIFO_PREFIX "fifo:" ++ ++ if (strncmp(file, ISULAD_FIFO_PREFIX, strlen(ISULAD_FIFO_PREFIX)) == 0) { ++ return (file + strlen(ISULAD_FIFO_PREFIX)); ++ } ++ return NULL; ++} ++ ++static int isulad_open_fifo(const char *file_path) ++{ ++#define LOG_FIFO_SIZE (1024 * 1024) ++ int fd; ++ ++ fd = lxc_unpriv(open(file_path, O_RDWR | O_NONBLOCK | O_CLOEXEC, 0640)); ++ if (fd == -1) { ++ fprintf(stderr, "Open fifo %s failed: %s\n", file_path, strerror(errno)); ++ return -1; ++ } ++ ++ if (fcntl(fd, F_SETPIPE_SZ, LOG_FIFO_SIZE) == -1) { ++ printf("Set fifo buffer size failed: %s", strerror(errno)); ++ close(fd); ++ return -1; ++ } ++ ++ return fd; ++} ++#endif ++ + static int lxc_log_priority_to_syslog(int priority) + { + switch (priority) { +@@ -321,6 +353,12 @@ static int log_append_logfile(const struct lxc_log_appender *appender, + #endif + + log_container_name = lxc_log_get_container_name(); ++#ifdef HAVE_ISULAD ++ /* use isulad log format */ ++ if (log_container_name != NULL && strlen(log_container_name) > 15) { ++ log_container_name = log_container_name + (strlen(log_container_name) - 15); ++ } ++#endif + + if (fd_to_use < 0) + fd_to_use = lxc_log_fd; +@@ -333,9 +371,13 @@ static int log_append_logfile(const struct lxc_log_appender *appender, + return ret; + + n = snprintf(buffer, sizeof(buffer), ++#if HAVE_ISULAD ++ "%15s %s %-8s %s - %s:%s:%d -", ++#else + "%s%s%s %s %-8s %s - %s:%s:%d - ", + log_prefix, + log_container_name ? " " : "", ++#endif + log_container_name ? log_container_name : "", + date_time, + lxc_log_priority_to_string(event->priority), +@@ -590,6 +632,13 @@ static int __lxc_log_set_file(const char *fname, int create_dirs) + return ret_errno(EINVAL); + } + ++#ifdef HAVE_ISULAD ++ fname = isulad_get_fifo_path(fname); ++ if (fname == NULL) { ++ return ret_errno(EINVAL); ++ } ++#endif ++ + #if USE_CONFIGPATH_LOGS + /* We don't build_dir for the default if the default is i.e. + * /var/lib/lxc/$container/$container.log. +@@ -599,7 +648,11 @@ static int __lxc_log_set_file(const char *fname, int create_dirs) + if (build_dir(fname)) + return log_error_errno(-errno, errno, "Failed to create dir for log file \"%s\"", fname); + ++#if HAVE_ISULAD ++ lxc_log_fd = isulad_open_fifo(fname); ++#else + lxc_log_fd = log_open(fname); ++#endif + if (lxc_log_fd < 0) + return lxc_log_fd; + +@@ -695,7 +748,10 @@ int lxc_log_init(struct lxc_log *log) + + if (lxc_log_fd >= 0) { + lxc_log_category_lxc.appender = &log_appender_logfile; +- lxc_log_category_lxc.appender->next = &log_appender_stderr; ++#ifdef HAVE_ISULAD ++ if (!lxc_quiet_specified && !log->quiet) ++#endif ++ lxc_log_category_lxc.appender->next = &log_appender_stderr; + } + + return ret; +diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c +index 8041f02..11ff15b 100644 +--- a/src/lxc/tools/lxc_start.c ++++ b/src/lxc/tools/lxc_start.c +@@ -139,6 +139,7 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) + break; + case OPT_STDERR_FIFO: + args->terminal_fifos[2] = arg; ++ break; + case OPT_EXIT_FIFO: + args->exit_monitor_fifo = arg; + break; +@@ -327,6 +328,7 @@ int main(int argc, char *argv[]) + + 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) { +-- +1.8.3.1 + diff --git a/0012-Init-fifos-in-lxc_attach_terminal.patch b/0012-Init-fifos-in-lxc_attach_terminal.patch deleted file mode 100644 index 1353b2fed8bfaa02ec738acfc31b7180b785c4c7..0000000000000000000000000000000000000000 --- a/0012-Init-fifos-in-lxc_attach_terminal.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0c5c03e94eb4beb4d55275bef52b14f1eef09d66 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Sat, 12 Jan 2019 03:23:53 -0500 -Subject: [PATCH 012/140] Init fifos in lxc_attach_terminal - -Signed-off-by: LiFeng ---- - src/lxc/terminal.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index 508e2e6..410f643 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -1341,6 +1341,10 @@ void lxc_terminal_init(struct lxc_terminal *terminal) - terminal->peer = -EBADF; - terminal->log_fd = -EBADF; - lxc_terminal_info_init(&terminal->proxy); -+ /* isulad init console fifos */ -+ terminal->init_fifo[0] = NULL; -+ terminal->init_fifo[1] = NULL; -+ lxc_list_init(&terminal->fifos); - } - - /* isulad: judge the fd whether is fifo */ --- -1.8.3.1 - diff --git a/0013-isulad-set-env-home-in-container.patch b/0013-set-env-in-container.patch similarity index 31% rename from 0013-isulad-set-env-home-in-container.patch rename to 0013-set-env-in-container.patch index d99a5155c49d20224f034759dc79c7d9ea734e95..5ee528d650de175c838c530272cf3f43922a8306 100644 --- a/0013-isulad-set-env-home-in-container.patch +++ b/0013-set-env-in-container.patch @@ -1,111 +1,119 @@ -From 3e630813a53666d5cdb8db81addcb86e9fe3c341 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Sat, 12 Jan 2019 14:42:27 +0800 -Subject: [PATCH 013/140] isulad: set env home in container +From 01d666e795a2cce1d4968202a38c73e673c42e88 Mon Sep 17 00:00:00 2001 +From: wujing +Date: Mon, 13 Apr 2020 07:04:20 -0400 +Subject: [PATCH 13/49] set env in container -Signed-off-by: LiFeng +Signed-off-by: wujing --- - src/lxc/attach.c | 5 +++++ - src/lxc/cgroups/cgfsng.c | 5 +++-- - src/lxc/conf.c | 2 +- - src/lxc/start.c | 4 ++++ - src/lxc/utils.c | 29 +++++++++++++++++++++++++++++ - src/lxc/utils.h | 3 +++ - 6 files changed, 45 insertions(+), 3 deletions(-) + src/lxc/attach.c | 7 +++++++ + src/lxc/start.c | 7 +++++++ + src/lxc/tools/lxc_start.c | 4 ++-- + src/lxc/utils.c | 39 +++++++++++++++++++++++++++++++++++++++ + src/lxc/utils.h | 2 ++ + 5 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/lxc/attach.c b/src/lxc/attach.c -index e7ba705..2bbf1eb 100644 +index 78b4700..801dc27 100644 --- a/src/lxc/attach.c +++ b/src/lxc/attach.c -@@ -876,6 +876,11 @@ static int attach_child_main(struct attach_clone_payload *payload) +@@ -779,6 +779,13 @@ static int attach_child_main(struct attach_clone_payload *payload) else new_gid = ns_root_gid; ++#ifdef HAVE_ISULAD + // isulad: set env home in container + if (lxc_setup_env_home(new_uid) < 0) { + goto on_error; + } ++#endif + if ((init_ctx->container && init_ctx->container->lxc_conf && init_ctx->container->lxc_conf->no_new_privs) || (options->attach_flags & LXC_ATTACH_NO_NEW_PRIVS)) { -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index aff2b5e..3e702b3 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -1704,8 +1704,9 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, - continue; - } - -- // Ignore ops->container_cgroup so we will not see directory lxc after /sys/fs/cgroup/xxx in container -- path2 = must_make_path(controllerpath, h->container_base_path, NULL); -+ // isulad: ignore ops->container_cgroup so we will not see directory lxc after /sys/fs/cgroup/xxx in container, -+ // isulad: ignore h->container_base_path so we will not see subgroup of /sys/fs/cgroup/xxx/subgroup in container -+ path2 = must_make_path(controllerpath, NULL); - ret = mkdir_p(path2, 0755); - if (ret < 0) { - free(controllerpath); -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index bc45e44..5065e69 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -3680,7 +3680,7 @@ int lxc_setup(struct lxc_handler *handler) - return -1; - } - -- /*isulad: move mount entrues here, before we do lxc_fill_autodev and populate devices */ -+ /*isulad: move mount entries here, before we do lxc_fill_autodev and populate devices */ - if (!lxc_list_empty(&lxc_conf->mount_list)) { - ret = setup_mount_entries(lxc_conf, &lxc_conf->rootfs, - &lxc_conf->mount_list, name, lxcpath); diff --git a/src/lxc/start.c b/src/lxc/start.c -index 9365d11..b13326c 100644 +index 70e8282..17766bc 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c -@@ -1398,6 +1398,10 @@ static int do_start(void *data) - new_uid = handler->conf->init_uid; - new_gid = handler->conf->init_gid; +@@ -1381,6 +1381,13 @@ static int do_start(void *data) + if (new_gid == nsgid) + new_gid = LXC_INVALID_GID; ++#ifdef HAVE_ISULAD + // isulad: set env home in container -+ if (lxc_setup_env_home(new_uid) < 0) ++ if (lxc_setup_env_home(new_uid) < 0) { + goto out_warn_father; ++ } ++#endif + - /* Avoid unnecessary syscalls. */ - if (new_uid == nsuid) - new_uid = LXC_INVALID_UID; + /* Make sure that the processes STDIO is correctly owned by the user that we are switching to */ + ret = fix_stdio_permissions(new_uid); + if (ret) +diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c +index 11ff15b..76802df6 100644 +--- a/src/lxc/tools/lxc_start.c ++++ b/src/lxc/tools/lxc_start.c +@@ -139,7 +139,7 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) + break; + case OPT_STDERR_FIFO: + args->terminal_fifos[2] = arg; +- break; ++ break; + case OPT_EXIT_FIFO: + args->exit_monitor_fifo = arg; + break; +@@ -328,7 +328,7 @@ int main(int argc, char *argv[]) + + 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) { diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index 4728284..74e74a1 100644 +index 90113e0..5b04fa4 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c -@@ -45,6 +45,7 @@ - #include +@@ -28,6 +28,7 @@ #include #include + #include +#include #include "config.h" #include "log.h" -@@ -1829,6 +1830,34 @@ int lxc_setup_keyring(void) - return ret; +@@ -2079,4 +2080,42 @@ out: + free(pid_info); + return startat; } - ++ +// isulad: set env home in container +int lxc_setup_env_home(uid_t uid) +{ -+#define __DEFAULT_HOMEDIR__ "/" -+ int ret = 0; -+ char *homedir; -+ struct passwd pwd, *result = NULL; ++#define __PASSWD_FILE__ "/etc/passwd" ++ char *homedir = "/"; // default home dir is / ++ FILE *stream = NULL; ++ struct passwd pw, *pwbufp = NULL; + char buf[BUFSIZ]; + -+ ret = getpwuid_r(uid, &pwd, buf, BUFSIZ, &result); -+ if (ret || !result || !result->pw_dir) { -+ WARN("User invalid, can not find user '%u'", uid); -+ homedir = __DEFAULT_HOMEDIR__; -+ } else { -+ homedir = result->pw_dir; ++ stream = fopen_cloexec(__PASSWD_FILE__, "r"); ++ if (stream == NULL) { ++ SYSWARN("Failed to open %s", __PASSWD_FILE__); ++ goto set_env; + } + ++ while (fgetpwent_r(stream, &pw, buf, sizeof(buf), &pwbufp) == 0 && pwbufp != NULL) { ++ if (pwbufp->pw_uid == uid) { ++ homedir = pwbufp->pw_dir; ++ goto set_env; ++ } ++ } ++ WARN("User invalid, can not find user '%u'", uid); ++ ++set_env: ++ if (stream) ++ fclose(stream); ++ + // if we didn't configure HOME, set it based on uid + if (setenv("HOME", homedir, 0) < 0) { + SYSERROR("Unable to set env 'HOME'"); @@ -116,24 +124,20 @@ index 4728284..74e74a1 100644 + return 0; +} + -+ - /* isulad: read file to buffer */ - static int lxc_file2str(const char *filename, char ret[], int cap) - { + #endif diff --git a/src/lxc/utils.h b/src/lxc/utils.h -index 8e4ed89..364bf67 100644 +index fbb0d55..677f632 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h -@@ -309,6 +309,9 @@ extern int fd_cloexec(int fd, bool cloexec); - extern int recursive_destroy(char *dirname); - extern int lxc_setup_keyring(void); - -+// isulad: set env home in container -+extern int lxc_setup_env_home(uid_t uid); -+ - extern int fd_nonblock(int fd); +@@ -316,6 +316,8 @@ extern int fix_stdio_permissions(uid_t uid); + extern void lxc_write_error_message(int errfd, const char *format, ...); + extern int lxc_file2str(const char *filename, char ret[], int cap); extern int unsigned long long lxc_get_process_startat(pid_t pid); ++// set env home in container ++extern int lxc_setup_env_home(uid_t uid); + #endif + #endif /* __LXC_UTILS_H */ -- 1.8.3.1 diff --git a/0018-lxc-attach-add-support-terminal-fifos.patch b/0014-exec-refact-attach-progress.patch similarity index 47% rename from 0018-lxc-attach-add-support-terminal-fifos.patch rename to 0014-exec-refact-attach-progress.patch index 8f2aacea021e92104c3f00d7801ab6048d3c14e3..5753672278afaee48ba50561c2892ee34383e345 100644 --- a/0018-lxc-attach-add-support-terminal-fifos.patch +++ b/0014-exec-refact-attach-progress.patch @@ -1,59 +1,23 @@ -From 0c11550c088cca12b6900623240799dc911da458 Mon Sep 17 00:00:00 2001 +From 61b64be9ac4e5d46e9363bb605c7b2e14d0cd2a2 Mon Sep 17 00:00:00 2001 From: LiFeng -Date: Mon, 14 Jan 2019 02:18:26 -0500 -Subject: [PATCH 018/140] lxc-attach: add support terminal fifos - -1. support terminal fifos to redirect terminal -2. support lxc-attach run in background +Date: Mon, 13 Apr 2020 20:41:03 +0800 +Subject: [PATCH 14/49] exec: refact attach progress Signed-off-by: LiFeng --- - src/lxc/attach.c | 18 ++++- - src/lxc/attach_options.h | 3 + - src/lxc/terminal.c | 27 +++++-- - src/lxc/tools/arguments.h | 2 +- - src/lxc/tools/lxc_attach.c | 181 +++++++++++++++++++++++++++++++++++++++++---- - 5 files changed, 204 insertions(+), 27 deletions(-) + src/lxc/attach.c | 2 +- + src/lxc/attach_options.h | 23 +++- + src/lxc/conf.h | 2 + + src/lxc/terminal.c | 27 ++++- + src/lxc/tools/arguments.h | 1 + + src/lxc/tools/lxc_attach.c | 273 +++++++++++++++++++++++++++++++++++++++++++++ + 6 files changed, 324 insertions(+), 4 deletions(-) diff --git a/src/lxc/attach.c b/src/lxc/attach.c -index 2bbf1eb..1886bde 100644 +index 801dc27..e66ca1c 100644 --- a/src/lxc/attach.c +++ b/src/lxc/attach.c -@@ -988,12 +988,23 @@ on_error: - } - - static int lxc_attach_terminal(struct lxc_conf *conf, -- struct lxc_terminal *terminal) -+ struct lxc_terminal *terminal, lxc_attach_options_t *options) - { - int ret; - - lxc_terminal_init(terminal); - -+ /* isulad: if we pass fifo in option, use them as init fifos */ -+ if (options->init_fifo[0] && options->init_fifo[1]) { -+ if (terminal->init_fifo[0]) -+ free(terminal->init_fifo[0]); -+ terminal->init_fifo[0] = strdup(options->init_fifo[0]); -+ -+ if (terminal->init_fifo[1]) -+ free(terminal->init_fifo[1]); -+ terminal->init_fifo[1] = strdup(options->init_fifo[1]); -+ } -+ - ret = lxc_terminal_create(terminal); - if (ret < 0) { - ERROR("Failed to create terminal"); -@@ -1203,7 +1214,7 @@ int lxc_attach(const char *name, const char *lxcpath, - } - - if (options->attach_flags & LXC_ATTACH_TERMINAL) { -- ret = lxc_attach_terminal(conf, &terminal); -+ ret = lxc_attach_terminal(conf, &terminal, options); - if (ret < 0) { - ERROR("Failed to setup new terminal"); - free(cwd); -@@ -1489,7 +1500,7 @@ int lxc_attach(const char *name, const char *lxcpath, +@@ -1420,7 +1420,7 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, } if (pid == 0) { @@ -62,70 +26,77 @@ index 2bbf1eb..1886bde 100644 ret = pthread_sigmask(SIG_SETMASK, &terminal.tty_state->oldmask, NULL); if (ret < 0) { -@@ -1497,7 +1508,6 @@ int lxc_attach(const char *name, const char *lxcpath, - _exit(EXIT_FAILURE); - } - } -- - ret = attach_child_main(&payload); - if (ret < 0) - ERROR("Failed to exec"); diff --git a/src/lxc/attach_options.h b/src/lxc/attach_options.h -index 193fd7e..081618c 100644 +index 3a02ee5..7b0ea5e 100644 --- a/src/lxc/attach_options.h +++ b/src/lxc/attach_options.h -@@ -135,6 +135,8 @@ typedef struct lxc_attach_options_t { +@@ -116,10 +116,12 @@ typedef struct lxc_attach_options_t { + #ifdef HAVE_ISULAD + char *init_fifo[3]; /* isulad: default fifos for the start */ + int64_t timeout;/* isulad: Seconds for waiting on a container to attach/exec before it is killed*/ ++ const char *suffix; + #endif - /*! File descriptor to log output. */ - int log_fd; -+ -+ char *init_fifo[2]; /* isulad: default fifos for the start */ } lxc_attach_options_t; ++#ifdef HAVE_ISULAD /*! Default attach options to use */ -@@ -153,6 +155,7 @@ typedef struct lxc_attach_options_t { + #define LXC_ATTACH_OPTIONS_DEFAULT \ + { \ +@@ -136,8 +138,27 @@ typedef struct lxc_attach_options_t { /* .stdout_fd = */ 1, \ /* .stderr_fd = */ 2, \ /* .log_fd = */ -EBADF, \ -+ /* .init_fifo = */ {NULL, NULL}, \ ++ /* .init_fifo = */ {NULL, NULL, NULL}, \ } - +- ++#else ++/*! Default attach options to use */ ++#define LXC_ATTACH_OPTIONS_DEFAULT \ ++ { \ ++ /* .attach_flags = */ LXC_ATTACH_DEFAULT, \ ++ /* .namespaces = */ -1, \ ++ /* .personality = */ -1, \ ++ /* .initial_cwd = */ NULL, \ ++ /* .uid = */ (uid_t)-1, \ ++ /* .gid = */ (gid_t)-1, \ ++ /* .env_policy = */ LXC_ATTACH_KEEP_ENV, \ ++ /* .extra_env_vars = */ NULL, \ ++ /* .extra_keep_env = */ NULL, \ ++ /* .stdin_fd = */ 0, \ ++ /* .stdout_fd = */ 1, \ ++ /* .stderr_fd = */ 2, \ ++ /* .log_fd = */ -EBADF, \ ++ } ++#endif /*! + * Representation of a command to run in a container. + */ +diff --git a/src/lxc/conf.h b/src/lxc/conf.h +index c5b70e1..52460a3 100644 +--- a/src/lxc/conf.h ++++ b/src/lxc/conf.h +@@ -432,6 +432,8 @@ struct lxc_conf { + char *container_info_file; + + int exit_fd; /* exit fifo fd*/ ++ ++ char *errmsg; /* record error messages */ + #endif + + }; diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index 7aa4730..ee3aef2 100644 +index c8cd83f..775743d 100644 --- a/src/lxc/terminal.c +++ b/src/lxc/terminal.c -@@ -514,7 +514,7 @@ static int lxc_terminal_mainloop_add_peer(struct lxc_terminal *terminal) - } - - /* isulad add fifo to mainloop */ --static int lxc_console_mainloop_add_fifo(struct lxc_terminal *terminal) -+static int lxc_terminal_mainloop_add_fifo(struct lxc_terminal *terminal) - { - int ret = 0; - struct lxc_list *it,*next; -@@ -564,7 +564,7 @@ int lxc_terminal_mainloop_add(struct lxc_epoll_descr *descr, - } - - /* isulad add fifo to mainloop */ -- ret = lxc_console_mainloop_add_fifo(terminal); -+ ret = lxc_terminal_mainloop_add_fifo(terminal); - if (ret < 0) { - ERROR("Failed to add handler for terminal fifos to mainloop"); - return -1; -@@ -789,13 +789,28 @@ void lxc_terminal_free(struct lxc_conf *conf, int fd) - static int lxc_terminal_peer_default(struct lxc_terminal *terminal) - { - struct lxc_terminal_state *ts; -- const char *path; -+ const char *path = NULL; - int ret = 0; +@@ -1174,8 +1174,25 @@ static int lxc_terminal_peer_default(struct lxc_terminal *terminal) if (terminal->path) path = terminal->path; - else - path = "/dev/tty"; + ++#ifdef HAVE_ISULAD + /* isulad: if no console was given, try current controlling terminal, there + * won't be one if we were started as a daemon (-d) + */ @@ -142,71 +113,84 @@ index 7aa4730..ee3aef2 100644 + DEBUG("Not have a controlling terminal"); + return 0; + } ++#endif terminal->peer = lxc_unpriv(open(path, O_RDWR | O_CLOEXEC)); if (terminal->peer < 0) { -@@ -1355,7 +1370,7 @@ int lxc_terminal_prepare_login(int fd) +@@ -1884,9 +1901,15 @@ int lxc_terminal_prepare_login(int fd) if (ret < 0) return -1; -- ret = lxc_terminal_set_stdfds(fd); ++#ifdef HAVE_ISULAD + ret = set_stdfds(fd); ++ if (ret < 0) ++ return -1; ++#else + ret = lxc_terminal_set_stdfds(fd); if (ret < 0) return -1; ++#endif + if (fd > STDERR_FILENO) + close(fd); diff --git a/src/lxc/tools/arguments.h b/src/lxc/tools/arguments.h -index 61f4a0a..047e9f1 100644 +index ea5f938..e0866d6 100644 --- a/src/lxc/tools/arguments.h +++ b/src/lxc/tools/arguments.h -@@ -62,7 +62,7 @@ struct lxc_arguments { - - /* for lxc-start */ - const char *share_ns[32]; /* size must be greater than LXC_NS_MAX */ -- const char *terminal_fifos[2]; /* isulad add, fifos used to redirct stdin/out/err */ -+ char *terminal_fifos[2]; /* isulad add, fifos used to redirct stdin/out/err */ +@@ -44,6 +44,7 @@ struct lxc_arguments { 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 */ ++ const char *suffix; /* isulad add, suffix used for connect with parent of execed process*/ + #endif + /* for lxc-console */ diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c -index 8c8e7d3..6d0ffe5 100644 +index a8f493a..47ac2f2 100644 --- a/src/lxc/tools/lxc_attach.c +++ b/src/lxc/tools/lxc_attach.c -@@ -75,6 +75,8 @@ static const struct option my_longopts[] = { - {"set-var", required_argument, 0, 'v'}, - {"pty-log", required_argument, 0, 'L'}, +@@ -74,6 +74,12 @@ static const struct option my_longopts[] = { {"rcfile", required_argument, 0, 'f'}, + {"uid", required_argument, 0, 'u'}, + {"gid", required_argument, 0, 'g'}, ++#ifdef HAVE_ISULAD + {"in-fifo", required_argument, 0, OPT_INPUT_FIFO}, /* isulad add terminal fifos*/ + {"out-fifo", required_argument, 0, OPT_OUTPUT_FIFO}, ++ {"err-fifo", required_argument, 0, OPT_STDERR_FIFO}, ++ {"suffix", required_argument, 0, OPT_ATTACH_SUFFIX}, ++#endif LXC_COMMON_OPTIONS }; -@@ -133,6 +135,9 @@ Options :\n\ - .log_file = "none", - }; - -+// isulad: send '128 + signal' if container is killed by signal. -+#define ExitSignalOffset 128 -+ - static int my_parser(struct lxc_arguments *args, int c, char *arg) - { - int ret; -@@ -190,6 +195,12 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) - case 'f': - args->rcfile = arg; +@@ -201,6 +207,20 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) + if (lxc_safe_uint(arg, &args->gid) < 0) + return -1; break; ++#ifdef HAVE_ISULAD + case OPT_INPUT_FIFO: + args->terminal_fifos[0] = arg; + break; + case OPT_OUTPUT_FIFO: + args->terminal_fifos[1] = arg; + break; ++ case OPT_STDERR_FIFO: ++ args->terminal_fifos[2] = arg; ++ break; ++ case OPT_ATTACH_SUFFIX: ++ args->suffix = arg; ++ break; ++#endif } return 0; -@@ -253,10 +264,143 @@ static int lxc_attach_create_log_file(const char *log_file) +@@ -264,6 +284,258 @@ static int lxc_attach_create_log_file(const char *log_file) return fd; } ++#ifdef HAVE_ISULAD ++// isulad: send '128 + signal' if container is killed by signal. ++#define ExitSignalOffset 128 ++ +/*isulad: attach with terminal*/ +static int do_attach_foreground(struct lxc_container *c, lxc_attach_command_t *command, + lxc_attach_options_t *attach_options, @@ -238,8 +222,8 @@ index 8c8e7d3..6d0ffe5 100644 + wexit = ExitSignalOffset + signal; + } +out: -+ //if (c->lxc_conf->errmsg) -+ // *errmsg = strdup(c->lxc_conf->errmsg); ++ if (c->lxc_conf->errmsg) ++ *errmsg = safe_strdup(c->lxc_conf->errmsg); + return wexit; +} + @@ -283,7 +267,7 @@ index 8c8e7d3..6d0ffe5 100644 + msgpipe[1] = -1; + size_read = read(msgpipe[0], msgbuf, BUFSIZ); + if (size_read > 0) { -+ *errmsg = strdup(msgbuf); ++ *errmsg = safe_strdup(msgbuf); + ret = -1; + } + @@ -319,8 +303,10 @@ index 8c8e7d3..6d0ffe5 100644 + else + ret = c->attach(c, lxc_attach_run_shell, NULL, attach_options, &pid); + if (ret < 0) { -+ //if (c->lxc_conf->errmsg) -+ // lxc_write_error_message(msgpipe[1], "%s", c->lxc_conf->errmsg); ++ if (c->lxc_conf->errmsg) ++ lxc_write_error_message(msgpipe[1], "%s", c->lxc_conf->errmsg); ++ else ++ lxc_write_error_message(msgpipe[1], "Failed to attach container"); + close(msgpipe[1]); + msgpipe[1] = -1; + ret = -1; @@ -339,72 +325,128 @@ index 8c8e7d3..6d0ffe5 100644 + exit(0); +} + - int main(int argc, char *argv[]) - { - int ret = -1; - int wexit = 0; ++int main(int argc, char *argv[]) ++{ ++ int ret = -1; ++ int wexit = 0; ++ struct lxc_log log; + char *errmsg = NULL; - struct lxc_log log; - pid_t pid; - lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT; -@@ -316,8 +460,13 @@ int main(int argc, char *argv[]) - if (elevated_privileges) - attach_options.attach_flags &= ~(elevated_privileges); - -- if (stdfd_is_pty()) -+ if (my_args.terminal_fifos[0] && my_args.terminal_fifos[1]) { ++ pid_t pid; ++ lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT; ++ lxc_attach_command_t command = (lxc_attach_command_t){.program = NULL}; ++ ++ if (lxc_caps_init()) ++ exit(EXIT_FAILURE); ++ ++ if (lxc_arguments_parse(&my_args, argc, argv)) ++ exit(EXIT_FAILURE); ++ ++ log.name = my_args.name; ++ log.file = my_args.log_file; ++ log.level = my_args.log_priority; ++ log.prefix = my_args.progname; ++ log.quiet = my_args.quiet; ++ log.lxcpath = my_args.lxcpath[0]; ++ ++ if (lxc_log_init(&log)) ++ exit(EXIT_FAILURE); ++ ++ if (geteuid()) ++ if (access(my_args.lxcpath[0], O_RDONLY) < 0) { ++ ERROR("You lack access to %s", my_args.lxcpath[0]); ++ exit(EXIT_FAILURE); ++ } ++ ++ struct lxc_container *c = lxc_container_new(my_args.name, my_args.lxcpath[0]); ++ if (!c) ++ exit(EXIT_FAILURE); ++ ++ 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); ++ } ++ ++ c->configfile = strdup(my_args.rcfile); ++ if (!c->configfile) { ++ ERROR("Out of memory setting new config filename"); ++ lxc_container_put(c); ++ exit(EXIT_FAILURE); ++ } ++ } ++ ++ if (!c->may_control(c)) { ++ ERROR("Insufficent privileges to control %s", c->name); ++ lxc_container_put(c); ++ exit(EXIT_FAILURE); ++ } ++ ++ if (remount_sys_proc) ++ attach_options.attach_flags |= LXC_ATTACH_REMOUNT_PROC_SYS; ++ ++ if (elevated_privileges) ++ attach_options.attach_flags &= ~(elevated_privileges); ++ ++ if (my_args.terminal_fifos[0] || my_args.terminal_fifos[1] || my_args.terminal_fifos[2]) { + attach_options.init_fifo[0] = my_args.terminal_fifos[0]; + attach_options.init_fifo[1] = my_args.terminal_fifos[1]; ++ attach_options.init_fifo[2] = my_args.terminal_fifos[2]; + attach_options.attach_flags |= LXC_ATTACH_TERMINAL; + } else if (stdfd_is_pty()) { - attach_options.attach_flags |= LXC_ATTACH_TERMINAL; ++ attach_options.attach_flags |= LXC_ATTACH_TERMINAL; + } - - attach_options.namespaces = namespace_flags; - attach_options.personality = new_personality; -@@ -332,27 +481,27 @@ int main(int argc, char *argv[]) - - if (my_args.console_log) { - attach_options.log_fd = lxc_attach_create_log_file(my_args.console_log); -- if (attach_options.log_fd < 0) -- goto out; ++ ++ attach_options.namespaces = namespace_flags; ++ attach_options.personality = new_personality; ++ attach_options.env_policy = env_policy; ++ attach_options.extra_env_vars = extra_env; ++ attach_options.extra_keep_env = extra_keep; ++ ++ if (my_args.argc > 0) { ++ command.program = my_args.argv[0]; ++ command.argv = (char**)my_args.argv; ++ } ++ ++ if (my_args.console_log) { ++ attach_options.log_fd = lxc_attach_create_log_file(my_args.console_log); + if (attach_options.log_fd < 0) { + ERROR("Failed to create log file for %s", c->name); + lxc_container_put(c); + exit(EXIT_FAILURE); + } - } - -- if (command.program) -- ret = c->attach(c, lxc_attach_run_command, &command, &attach_options, &pid); ++ } ++ ++ attach_options.suffix = my_args.suffix; ++ + /* isulad: add do attach background */ + if (attach_options.attach_flags & LXC_ATTACH_TERMINAL) + wexit = do_attach_foreground(c, &command, &attach_options, &errmsg); - else -- ret = c->attach(c, lxc_attach_run_shell, NULL, &attach_options, &pid); -- if (ret < 0) -- goto out; ++ else + wexit = do_attach_background(c, &command, &attach_options, &errmsg); - -- ret = lxc_wait_for_pid_status(pid); -- if (ret < 0) -- goto out; -- -- if (WIFEXITED(ret)) -- wexit = WEXITSTATUS(ret); ++ + if (errmsg) { + fprintf(stderr, "%s:%s:%s:%d starting container process caused \"%s\"", c->name, + __FILE__, __func__, __LINE__, errmsg); + free(errmsg); + } - --out: - lxc_container_put(c); -- if (ret >= 0) ++ ++ lxc_container_put(c); + if (wexit >= 0) - exit(wexit); ++ exit(wexit); ++ ++ exit(EXIT_FAILURE); ++} ++#else + int main(int argc, char *argv[]) + { + int ret = -1; +@@ -377,3 +649,4 @@ out: exit(EXIT_FAILURE); + } ++#endif -- 1.8.3.1 diff --git a/0014-support-rotate-for-container-log-file.patch b/0014-support-rotate-for-container-log-file.patch deleted file mode 100644 index 55e075bdf037eb128a95bce671b0d12a23538dac..0000000000000000000000000000000000000000 --- a/0014-support-rotate-for-container-log-file.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 42efaa5362d755d9f9bf028c283ca24bc6a03cbb Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Sat, 12 Jan 2019 15:29:56 +0800 -Subject: [PATCH 014/140] support rotate for container log file - -support rotate for container log file - -Signed-off-by: LiFeng ---- - src/lxc/confile.c | 3 +++ - src/lxc/terminal.c | 40 ++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 43 insertions(+) - -diff --git a/src/lxc/confile.c b/src/lxc/confile.c -index cbef2e2..e782211 100644 ---- a/src/lxc/confile.c -+++ b/src/lxc/confile.c -@@ -1802,11 +1802,14 @@ static int set_config_console_rotate(const char *key, const char *value, - if (lxc_safe_uint(value, &lxc_conf->console.log_rotate) < 0) - return -1; - -+ /* -+ * isulad: support rotate muti-files - if (lxc_conf->console.log_rotate > 1) { - ERROR("The \"lxc.console.rotate\" config key can only be set " - "to 0 or 1"); - return -1; - } -+ */ - - return 0; - } -diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index 410f643..3bb3a52 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -229,6 +229,39 @@ static int lxc_terminal_truncate_log_file(struct lxc_terminal *terminal) - return lxc_unpriv(ftruncate(terminal->log_fd, 0)); - } - -+/* -+ * isuald: support mult-logfiles -+ * */ -+static int lxc_terminal_rename_old_log_file(struct lxc_terminal *terminal) -+{ -+ int ret; -+ size_t i; -+ char tmp[PATH_MAX] = {0}; -+ char *rename_fname = NULL; -+ -+ for (i = terminal->log_rotate - 1; i > 1; i--) { -+ ret = sprintf(tmp, "%s.%d", terminal->log_path, i); -+ if (ret < 0) -+ return -EFBIG; -+ if (rename_fname) -+ free(rename_fname); -+ rename_fname = strdup(tmp); -+ ret = sprintf(tmp, "%s.%d", terminal->log_path, (i - 1)); -+ if (ret < 0) { -+ free(rename_fname); -+ return -EFBIG; -+ } -+ ret = lxc_unpriv(rename(tmp, rename_fname)); -+ if (ret < 0 && errno != ENOENT) -+ return ret; -+ } -+ -+ if (rename_fname) -+ free(rename_fname); -+ -+ return 0; -+} -+ - static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal) - { - int ret; -@@ -242,6 +275,13 @@ static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal) - if (terminal->log_fd < 0) - return -EBADF; - -+ /* isuald: rotate old log file first */ -+ ret = lxc_terminal_rename_old_log_file(terminal); -+ if(ret != 0) { -+ ERROR("Rename old log file failed"); -+ return ret; -+ } -+ - len = strlen(terminal->log_path) + sizeof(".1"); - tmp = alloca(len); - --- -1.8.3.1 - diff --git a/0016-add-masked-paths-and-ro-paths.patch b/0015-add-masked-paths-and-readonly-paths.patch similarity index 63% rename from 0016-add-masked-paths-and-ro-paths.patch rename to 0015-add-masked-paths-and-readonly-paths.patch index 7cf8cadf6e62cc078b0a6d9811014f24430d88a5..bfe5a18e4905d02a9b96eb6fd77c48f482873b09 100644 --- a/0016-add-masked-paths-and-ro-paths.patch +++ b/0015-add-masked-paths-and-readonly-paths.patch @@ -1,24 +1,24 @@ -From 6abc6c02684ec9d48033969399352050789da2d6 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Sat, 12 Jan 2019 15:55:52 +0800 -Subject: [PATCH 016/140] add masked paths and ro paths +From c5ea37649d728630df34e1af22908b8e8124f772 Mon Sep 17 00:00:00 2001 +From: wujing +Date: Mon, 13 Apr 2020 09:11:21 -0400 +Subject: [PATCH 15/49] add masked paths and readonly paths -Signed-off-by: LiFeng +Signed-off-by: wujing --- - src/lxc/conf.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ - src/lxc/conf.h | 8 ++++ - src/lxc/confile.c | 113 ++++++++++++++++++++++++++++++++++++++++++++- - 3 files changed, 255 insertions(+), 1 deletion(-) + src/lxc/conf.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++- + src/lxc/conf.h | 12 +++++ + src/lxc/confile.c | 106 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 256 insertions(+), 1 deletion(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 5065e69..537f956 100644 +index a904348..fce241b 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c -@@ -1343,6 +1343,95 @@ static int lxc_mount_rootfs(struct lxc_conf *conf) +@@ -1275,6 +1275,96 @@ static int lxc_mount_rootfs(struct lxc_conf *conf) return 0; } -+ ++#ifdef HAVE_ISULAD +// maskPath masks the top of the specified path inside a container to avoid +// security issues from processes reading information from non-namespace aware +// mounts ( proc/kcore ). @@ -49,7 +49,7 @@ index 5065e69..537f956 100644 +// remount_readonly will bind over the top of an existing path and ensure that it is read-only. +static bool remount_readonly(const char *path) +{ -+ int ret, savederrno, i; ++ int ret, i; + + if (!path) + return true; @@ -63,7 +63,7 @@ index 5065e69..537f956 100644 + if (ret < 0) + goto on_error; + ret = mount(path, path, "", MS_BIND | MS_REMOUNT | MS_RDONLY | MS_REC | \ -+ MS_NOEXEC | MS_NOSUID | MS_NODEV, ""); ++ MS_NOEXEC | MS_NOSUID | MS_NODEV, ""); + if (ret < 0) + goto on_error; + } else if (errno == EBUSY) { @@ -88,8 +88,8 @@ index 5065e69..537f956 100644 + struct lxc_list *it; + + lxc_list_for_each(it, maskedpaths) { -+ if (!mask_path((char *)it->elem)) -+ return -1; ++ if (!mask_path((char *)it->elem)) ++ return -1; + } + + return 0; @@ -100,56 +100,69 @@ index 5065e69..537f956 100644 + struct lxc_list *it; + + lxc_list_for_each(it, ropaths) { -+ if (!remount_readonly((char *)it->elem)) -+ return -1; ++ if (!remount_readonly((char *)it->elem)) ++ return -1; + } + + return 0; +} ++#endif + int lxc_chroot(const struct lxc_rootfs *rootfs) { - int i, ret; -@@ -2759,6 +2848,8 @@ struct lxc_conf *lxc_conf_init(void) + __do_free char *nroot = NULL; +@@ -2666,8 +2756,9 @@ struct lxc_conf *lxc_conf_init(void) + seccomp_conf_init(new); - /* isulad add begin */ + #ifdef HAVE_ISULAD +- /* isulad add begin */ lxc_list_init(&new->populate_devs); + lxc_list_init(&new->rootfs.maskedpaths); + lxc_list_init(&new->rootfs.ropaths); new->exit_fd = -1; - /* isulad add end */ + new->umask = 0027; /*default umask 0027*/ + new->console.init_fifo[0] = NULL; +@@ -3690,6 +3781,22 @@ int lxc_setup(struct lxc_handler *handler) + return log_error(-1, "Failed to setup sysctl parameters"); + } -@@ -3759,6 +3850,22 @@ int lxc_setup(struct lxc_handler *handler) - if (ret < 0) - return -1; - -+ //isulad: setup rootfs masked paths ++#ifdef HAVE_ISULAD ++ // isulad: setup rootfs masked paths + if (!lxc_list_empty(&lxc_conf->rootfs.maskedpaths)) { + if (setup_rootfs_maskedpaths(&lxc_conf->rootfs.maskedpaths)) { -+ ERROR("failed to setup maskedpaths"); -+ return -1; ++ return log_error(-1, "failed to setup maskedpaths"); + } + } + + // isulad: setup rootfs ro paths + if (!lxc_list_empty(&lxc_conf->rootfs.ropaths)) { + if (setup_rootfs_ropaths(&lxc_conf->rootfs.ropaths)) { -+ ERROR("failed to setup readonlypaths"); -+ return -1; ++ return log_error(-1, "failed to setup readonlypaths"); + } + } ++#endif + - ret = setup_personality(lxc_conf->personality); - if (ret < 0) { - ERROR("Failed to set personality"); -@@ -4147,6 +4254,32 @@ int lxc_clear_populate_devices(struct lxc_conf *c) + if (!lxc_list_empty(&lxc_conf->keepcaps)) { + if (!lxc_list_empty(&lxc_conf->caps)) + return log_error(-1, "Container requests lxc.cap.drop and lxc.cap.keep: either use lxc.cap.drop or lxc.cap.keep, not both"); +@@ -4103,6 +4210,8 @@ void lxc_conf_free(struct lxc_conf *conf) + } + lxc_clear_init_args(conf); + lxc_clear_populate_devices(conf); ++ lxc_clear_rootfs_masked_paths(conf); ++ lxc_clear_rootfs_ro_paths(conf); + #endif + free(conf); + } +@@ -4945,4 +5054,32 @@ int lxc_clear_populate_devices(struct lxc_conf *c) return 0; } +/*isulad: clear rootfs masked paths*/ +int lxc_clear_rootfs_masked_paths(struct lxc_conf *c) +{ -+ struct lxc_list *it,*next; ++ struct lxc_list *it = NULL; ++ struct lxc_list *next = NULL; + + lxc_list_for_each_safe(it, &c->rootfs.maskedpaths, next) { + lxc_list_del(it); @@ -162,7 +175,8 @@ index 5065e69..537f956 100644 +/*isulad: clear rootfs ro paths*/ +int lxc_clear_rootfs_ro_paths(struct lxc_conf *c) +{ -+ struct lxc_list *it,*next; ++ struct lxc_list *it = NULL; ++ struct lxc_list *next = NULL; + + lxc_list_for_each_safe(it, &c->rootfs.ropaths, next) { + lxc_list_del(it); @@ -172,91 +186,72 @@ index 5065e69..537f956 100644 + return 0; +} + - void lxc_conf_free(struct lxc_conf *conf) - { - if (!conf) -@@ -4195,6 +4328,8 @@ void lxc_conf_free(struct lxc_conf *conf) - /* isulad add begin */ - lxc_clear_init_args(conf); - lxc_clear_populate_devices(conf); -+ lxc_clear_rootfs_masked_paths(conf); -+ lxc_clear_rootfs_ro_paths(conf); - free(conf->container_info_file); - if (conf->exit_fd != -1) - close(conf->exit_fd); + #endif diff --git a/src/lxc/conf.h b/src/lxc/conf.h -index 2d939cd..7927812 100644 +index 52460a3..482fe0d 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h -@@ -160,6 +160,8 @@ struct lxc_tty_info { - * @options : mount options +@@ -143,6 +143,8 @@ struct lxc_tty_info { * @mountflags : the portion of @options that are flags * @data : the portion of @options that are not flags + * @managed : whether it is managed by LXC + * @maskedpaths: A list of paths to be msked over inside the container + * @ropaths : A list of paths to be remounted with readonly inside the container */ struct lxc_rootfs { char *path; -@@ -168,6 +170,10 @@ struct lxc_rootfs { - char *options; +@@ -152,6 +154,14 @@ struct lxc_rootfs { unsigned long mountflags; char *data; -+ /* isulad: maskedpaths */ -+ struct lxc_list maskedpaths; -+ /* isulad: ropaths */ -+ struct lxc_list ropaths; + bool managed; ++ ++#ifdef HAVE_ISULAD ++ /* isulad: maskedpaths */ ++ struct lxc_list maskedpaths; ++ /* isulad: ropaths */ ++ struct lxc_list ropaths; ++#endif ++ }; /* -@@ -477,6 +483,8 @@ extern int lxc_clear_procs(struct lxc_conf *c, const char *key); - /* isulad add begin */ +@@ -511,5 +521,7 @@ extern int userns_exec_minimal(const struct lxc_conf *conf, + #ifdef HAVE_ISULAD 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); - - /* isulad add end */ - + #endif + #endif /* __LXC_CONF_H */ diff --git a/src/lxc/confile.c b/src/lxc/confile.c -index e782211..e199965 100644 +index 2df269a..bf0fdf0 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c -@@ -139,6 +139,8 @@ lxc_config_define(pty_max); - lxc_config_define(rootfs_mount); - lxc_config_define(rootfs_options); - lxc_config_define(rootfs_path); +@@ -151,6 +151,8 @@ lxc_config_define(proc); + lxc_config_define(init_args); + lxc_config_define(populate_device); + lxc_config_define(umask); +lxc_config_define(rootfs_masked_paths); +lxc_config_define(rootfs_ro_paths); - lxc_config_define(seccomp_profile); - lxc_config_define(selinux_context); - lxc_config_define(signal_halt); -@@ -243,6 +245,8 @@ static struct lxc_config_t config_jump_table[] = { - /*isulad add begin*/ + #endif + + /* +@@ -268,6 +270,8 @@ static struct lxc_config_t config_jump_table[] = { { "lxc.isulad.init.args", set_config_init_args, get_config_init_args, clr_config_init_args, }, { "lxc.isulad.populate.device", set_config_populate_device, get_config_populate_device, clr_config_populate_device, }, + { "lxc.isulad.umask", set_config_umask, get_config_umask, clr_config_umask, }, + { "lxc.isulad.rootfs.maskedpaths", set_config_rootfs_masked_paths, get_config_rootfs_masked_paths, clr_config_rootfs_masked_paths, }, + { "lxc.isulad.rootfs.ropaths", set_config_rootfs_ro_paths, get_config_rootfs_ro_paths, clr_config_rootfs_ro_paths, }, - /*isulad add end*/ + #endif }; -@@ -2224,7 +2228,7 @@ static int set_config_init_args(const char *key, const char *value, +@@ -6311,4 +6315,106 @@ static inline int clr_config_umask(const char *key, struct lxc_conf *c, return 0; } --/* isulad: set config for init args */ -+/* isulad: set config for populate device */ - static int set_config_populate_device(const char *key, const char *value, - struct lxc_conf *lxc_conf, void *data) - { -@@ -2308,6 +2312,62 @@ on_error: - free(dev_elem); - } - return -1; -+} -+ +/* isulad: set config for rootfs masked paths */ +static int set_config_rootfs_masked_paths(const char *key, const char *value, -+ struct lxc_conf *lxc_conf, void *data) ++ struct lxc_conf *lxc_conf, void *data) +{ + struct lxc_list *list_item = NULL; + @@ -264,13 +259,10 @@ index e782211..e199965 100644 + return lxc_clear_rootfs_masked_paths(lxc_conf); + + list_item = malloc(sizeof(*list_item)); -+ if (!list_item) ++ if (list_item == NULL) + goto on_error; + -+ list_item->elem = strdup(value); -+ -+ if (!list_item->elem) -+ goto on_error; ++ list_item->elem = safe_strdup(value); + + lxc_list_add_tail(&lxc_conf->rootfs.maskedpaths, list_item); + @@ -282,9 +274,28 @@ index e782211..e199965 100644 + return -1; +} + ++// isulad: get config rootfs masked paths ++static int get_config_rootfs_masked_paths(const char *key, char *retv, int inlen, ++ struct lxc_conf *c, void *data) ++{ ++ int len, fulllen = 0; ++ struct lxc_list *it = NULL; ++ ++ if (!retv) ++ inlen = 0; ++ else ++ memset(retv, 0, inlen); ++ ++ lxc_list_for_each(it, &c->rootfs.maskedpaths) { ++ strprint(retv, inlen, "%s\n", (char *)it->elem); ++ } ++ ++ return fulllen; ++} ++ +/* isulad: set config for rootfs ro paths */ +static int set_config_rootfs_ro_paths(const char *key, const char *value, -+ struct lxc_conf *lxc_conf, void *data) ++ struct lxc_conf *lxc_conf, void *data) +{ + struct lxc_list *list_item = NULL; + @@ -292,13 +303,10 @@ index e782211..e199965 100644 + return lxc_clear_rootfs_ro_paths(lxc_conf); + + list_item = malloc(sizeof(*list_item)); -+ if (!list_item) ++ if (list_item == NULL) + goto on_error; + -+ list_item->elem = strdup(value); -+ -+ if (!list_item->elem) -+ goto on_error; ++ list_item->elem = safe_strdup(value); + + lxc_list_add_tail(&lxc_conf->rootfs.ropaths, list_item); + @@ -308,38 +316,14 @@ index e782211..e199965 100644 + free(list_item); + + return -1; - - } - -@@ -3889,6 +3949,43 @@ static int get_config_populate_device(const char *key, char *retv, int inlen, - return fulllen; - } - -+// isulad: get config rootfs masked paths -+static int get_config_rootfs_masked_paths(const char *key, char *retv, int inlen, -+ struct lxc_conf *c, void *data) -+{ -+ int len, fulllen = 0; -+ struct lxc_list *it; -+ -+ if (!retv) -+ inlen = 0; -+ else -+ memset(retv, 0, inlen); -+ -+ lxc_list_for_each(it, &c->rootfs.maskedpaths) { -+ strprint(retv, inlen, "%s\n", (char *)it->elem); -+ } -+ -+ return fulllen; +} + +// isulad: get config rootfs ro paths +static int get_config_rootfs_ro_paths(const char *key, char *retv, int inlen, -+ struct lxc_conf *c, void *data) ++ struct lxc_conf *c, void *data) +{ + int len, fulllen = 0; -+ struct lxc_list *it; ++ struct lxc_list *it = NULL; + + if (!retv) + inlen = 0; @@ -352,30 +336,22 @@ index e782211..e199965 100644 + + return fulllen; +} - - /* Callbacks to clear config items. */ - static inline int clr_config_personality(const char *key, struct lxc_conf *c, -@@ -4708,6 +4805,20 @@ static inline int clr_config_populate_device(const char *key, struct lxc_conf *c - return lxc_clear_populate_devices(c); - } - ++ +/* isulad: clr config rootfs masked paths */ +static inline int clr_config_rootfs_masked_paths(const char *key, struct lxc_conf *c, -+ void *data) ++ void *data) +{ + return lxc_clear_rootfs_masked_paths(c); +} + +/* isulad: clr config rootfs ro paths */ +static inline int clr_config_rootfs_ro_paths(const char *key, struct lxc_conf *c, -+ void *data) ++ void *data) +{ + return lxc_clear_rootfs_ro_paths(c); +} + - static int get_config_net_nic(const char *key, char *retv, int inlen, - struct lxc_conf *c, void *data) - { + #endif -- 1.8.3.1 diff --git a/0015-fix-high-gcc-compile-bug.patch b/0015-fix-high-gcc-compile-bug.patch deleted file mode 100644 index 5d79915348d25d3acc247fb30b6854ba95b65e36..0000000000000000000000000000000000000000 --- a/0015-fix-high-gcc-compile-bug.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 5b07aee14b1c49e11cdf42fb2b9c8887751cedb7 Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Sat, 12 Jan 2019 16:28:41 +0800 -Subject: [PATCH 015/140] fix high gcc compile bug - -fix high gcc compile bug - -Signed-off-by: LiFeng ---- - src/lxc/terminal.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index 3bb3a52..7aa4730 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -235,18 +235,18 @@ static int lxc_terminal_truncate_log_file(struct lxc_terminal *terminal) - static int lxc_terminal_rename_old_log_file(struct lxc_terminal *terminal) - { - int ret; -- size_t i; -+ unsigned int i; - char tmp[PATH_MAX] = {0}; - char *rename_fname = NULL; - - for (i = terminal->log_rotate - 1; i > 1; i--) { -- ret = sprintf(tmp, "%s.%d", terminal->log_path, i); -+ ret = sprintf(tmp, "%s.%u", terminal->log_path, i); - if (ret < 0) - return -EFBIG; - if (rename_fname) - free(rename_fname); - rename_fname = strdup(tmp); -- ret = sprintf(tmp, "%s.%d", terminal->log_path, (i - 1)); -+ ret = sprintf(tmp, "%s.%u", terminal->log_path, (i - 1)); - if (ret < 0) { - free(rename_fname); - return -EFBIG; --- -1.8.3.1 - diff --git a/0016-start-separate-i-and-t.patch b/0016-start-separate-i-and-t.patch new file mode 100644 index 0000000000000000000000000000000000000000..65a0e4a36fb194cfa88df2af7162cbcae3635dd5 --- /dev/null +++ b/0016-start-separate-i-and-t.patch @@ -0,0 +1,369 @@ +From 204008167f00ddda3f5f2b0121bcf29b3d55c689 Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Mon, 13 Apr 2020 21:17:15 +0800 +Subject: [PATCH 16/49] start: separate -i and -t + +Signed-off-by: LiFeng +--- + src/lxc/lxccontainer.c | 44 +++++++++++++++++- + src/lxc/lxccontainer.h | 27 +++++++++++ + src/lxc/start.c | 111 +++++++++++++++++++++++++++++++++++++++++++++- + src/lxc/start.h | 4 ++ + src/lxc/tools/arguments.h | 2 + + src/lxc/tools/lxc_start.c | 14 ++++++ + 6 files changed, 198 insertions(+), 4 deletions(-) + +diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c +index 64cde99..e27b63b 100644 +--- a/src/lxc/lxccontainer.c ++++ b/src/lxc/lxccontainer.c +@@ -1163,12 +1163,18 @@ reboot: + goto on_error; + } + +- if (useinit) ++ if (useinit) { + ret = lxc_execute(c->name, argv, 1, handler, c->config_path, + c->daemonize, &c->error_num); +- else ++ } ++ else { ++#ifdef HAVE_ISULAD ++ handler->disable_pty = c->disable_pty; ++ handler->open_stdin = c->open_stdin; ++#endif + ret = lxc_start(argv, handler, c->config_path, c->daemonize, + &c->error_num); ++ } + + if (conf->reboot == REBOOT_REQ) { + INFO("Container requested reboot"); +@@ -5381,6 +5387,40 @@ static bool do_lxcapi_set_container_info_file(struct lxc_container *c, const cha + } + + WRAP_API_1(bool, lxcapi_set_container_info_file, const char *) ++ ++static bool do_lxcapi_want_disable_pty(struct lxc_container *c, bool state) ++{ ++ if (!c || !c->lxc_conf) ++ return false; ++ ++ if (container_mem_lock(c)) ++ return false; ++ ++ c->disable_pty = state; ++ ++ container_mem_unlock(c); ++ ++ return true; ++} ++ ++WRAP_API_1(bool, lxcapi_want_disable_pty, bool) ++ ++static bool do_lxcapi_want_open_stdin(struct lxc_container *c, bool state) ++{ ++ if (!c || !c->lxc_conf) ++ return false; ++ ++ if (container_mem_lock(c)) ++ return false; ++ ++ c->open_stdin = state; ++ ++ container_mem_unlock(c); ++ ++ return true; ++} ++ ++WRAP_API_1(bool, lxcapi_want_open_stdin, bool) + #endif + + struct lxc_container *lxc_container_new(const char *name, const char *configpath) +diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h +index fa9bd5e..de2ee46 100644 +--- a/src/lxc/lxccontainer.h ++++ b/src/lxc/lxccontainer.h +@@ -113,6 +113,11 @@ struct lxc_container { + * exit FIFO File to open used monitor the state of lxc monitor process. + */ + char *exit_fifo; ++ /*! Whether container wishes to create pty or pipes for console log */ ++ bool disable_pty; ++ ++ /*! Whether container wishes to keep stdin active */ ++ bool open_stdin; + #endif + + /*! +@@ -908,6 +913,28 @@ struct lxc_container { + bool (*set_terminal_winch)(struct lxc_container *c, unsigned int height, unsigned int width); + + bool (*set_exec_terminal_winch)(struct lxc_container *c, const char *suffix, unsigned int height, unsigned int width); ++ ++ /*! ++ * \brief Change whether the container wants to create pty or pipes ++ * from the console log. ++ * ++ * \param c Container. ++ * \param state Value for the disable pty bit (0 or 1). ++ * ++ * \return \c true on success, else \c false. ++ */ ++ bool (*want_disable_pty)(struct lxc_container *c, bool state); ++ ++ /*! ++ * \brief Change whether the container wants to keep stdin active ++ * for parent process of container ++ * ++ * \param c Container. ++ * \param state Value for the open_stdin bit (0 or 1). ++ * ++ * \return \c true on success, else \c false. ++ */ ++ bool (*want_open_stdin)(struct lxc_container *c, bool state); + #endif + }; + +diff --git a/src/lxc/start.c b/src/lxc/start.c +index 17766bc..145b015 100644 +--- a/src/lxc/start.c ++++ b/src/lxc/start.c +@@ -580,6 +580,16 @@ int lxc_poll(const char *name, struct lxc_handler *handler) + + TRACE("Mainloop is ready"); + ++#ifdef HAVE_ISULAD ++ // iSulad: close stdin pipe if we do not want open_stdin with container stdin ++ if (!handler->conf->console.open_stdin) { ++ if (handler->conf->console.pipes[0][1] > 0) { ++ close(handler->conf->console.pipes[0][1]); ++ handler->conf->console.pipes[0][1] = -1; ++ } ++ } ++#endif ++ + ret = lxc_mainloop(&descr, -1); + close_prot_errno_disarm(descr.epfd); + if (ret < 0 || !handler->init_died) +@@ -733,6 +743,10 @@ int lxc_init(const char *name, struct lxc_handler *handler) + int ret; + const char *loglevel; + struct lxc_conf *conf = handler->conf; ++#ifdef HAVE_ISULAD ++ conf->console.disable_pty = handler->disable_pty; ++ conf->console.open_stdin = handler->open_stdin; ++#endif + + handler->monitor_pid = lxc_raw_getpid(); + status_fd = open("/proc/self/status", O_RDONLY | O_CLOEXEC); +@@ -1178,6 +1192,25 @@ static int do_start(void *data) + * means that migration won't work, but at least we won't spew output + * where it isn't wanted. + */ ++#ifdef HAVE_ISULAD ++ if (!handler->disable_pty && handler->daemonize && !handler->conf->autodev) { ++ char path[PATH_MAX]; ++ ++ ret = snprintf(path, sizeof(path), "%s/dev/null", ++ handler->conf->rootfs.mount); ++ if (ret < 0 || ret >= sizeof(path)) ++ goto out_warn_father; ++ ++ ret = access(path, F_OK); ++ if (ret != 0) { ++ devnull_fd = open_devnull(); ++ ++ if (devnull_fd < 0) ++ goto out_warn_father; ++ WARN("Using /dev/null from the host for container init's standard file descriptors. Migration will not work"); ++ } ++ } ++#else + if (handler->daemonize && !handler->conf->autodev) { + char path[PATH_MAX]; + +@@ -1195,6 +1228,7 @@ static int do_start(void *data) + WARN("Using /dev/null from the host for container init's standard file descriptors. Migration will not work"); + } + } ++#endif + + /* Ask father to setup cgroups and wait for him to finish. */ + ret = lxc_sync_barrier_parent(handler, LXC_SYNC_CGROUP); +@@ -1266,12 +1300,70 @@ static int do_start(void *data) + DEBUG("Set PR_SET_NO_NEW_PRIVS to block execve() gainable privileges"); + } + ++#ifdef HAVE_ISULAD ++ /* isulad: dup2 pipe[0][0] to container stdin, pipe[1][1] to container stdout, pipe[2][1] to container stderr */ ++ if (handler->disable_pty) { ++ if (handler->conf->console.pipes[0][1] >= 0) { ++ close(handler->conf->console.pipes[0][1]); ++ handler->conf->console.pipes[0][1] = -1; ++ } ++ ++ if (handler->conf->console.pipes[0][0] >= 0) { ++ ret = dup2(handler->conf->console.pipes[0][0], STDIN_FILENO); ++ if (ret < 0) ++ goto out_warn_father; ++ } ++ ++ if (handler->conf->console.pipes[1][0] >= 0) { ++ close(handler->conf->console.pipes[1][0]); ++ handler->conf->console.pipes[1][0] = -1; ++ } ++ ++ if (handler->conf->console.pipes[1][1] >= 0) { ++ ret = dup2(handler->conf->console.pipes[1][1], STDOUT_FILENO); ++ if (ret < 0) ++ goto out_warn_father; ++ } ++ if (handler->conf->console.pipes[2][0] >= 0) { ++ close(handler->conf->console.pipes[2][0]); ++ handler->conf->console.pipes[2][0] = -1; ++ } ++ ++ if (handler->conf->console.pipes[2][1] >= 0) { ++ ret = dup2(handler->conf->console.pipes[2][1], STDERR_FILENO); ++ if (ret < 0) ++ goto out_warn_father; ++ } ++ } ++#endif ++ + /* Some init's such as busybox will set sane tty settings on stdin, + * stdout, stderr which it thinks is the console. We already set them + * the way we wanted on the real terminal, and we want init to do its + * setup on its console ie. the pty allocated in lxc_terminal_setup() so + * make sure that that pty is stdin,stdout,stderr. + */ ++ setsid(); ++#ifdef HAVE_ISULAD ++ if (!handler->disable_pty && handler->conf->console.slave >= 0) { ++ /* isulad:make the given terminal as controlling terminal to avoid warning ++ * sh: cannot set terminal process group (-1): Inappropriate ioctl for device ++ * sh: no job control in this shell */ ++ if (ioctl(handler->conf->console.slave, TIOCSCTTY, NULL) < 0) { ++ ERROR("Faild to make the given terminal the controlling terminal of the calling process"); ++ goto out_warn_father; ++ } ++ if (handler->daemonize || !handler->conf->is_execute) ++ ret = set_stdfds(handler->conf->console.slave); ++ else ++ ret = lxc_terminal_set_stdfds(handler->conf->console.slave); ++ if (ret < 0) { ++ ERROR("Failed to redirect std{in,out,err} to pty file " ++ "descriptor %d", handler->conf->console.slave); ++ goto out_warn_father; ++ } ++ } ++#else + if (handler->conf->console.slave >= 0) { + if (handler->daemonize || !handler->conf->is_execute) + ret = set_stdfds(handler->conf->console.slave); +@@ -1283,6 +1375,7 @@ static int do_start(void *data) + goto out_warn_father; + } + } ++#endif + + /* If we mounted a temporary proc, then unmount it now. */ + tmp_proc_unmount(handler->conf); +@@ -1306,6 +1399,21 @@ static int do_start(void *data) + + close_prot_errno_disarm(handler->sigfd); + ++ #ifdef HAVE_ISULAD ++ if (!handler->disable_pty && handler->conf->console.slave < 0 && handler->daemonize) { ++ if (devnull_fd < 0) { ++ devnull_fd = open_devnull(); ++ if (devnull_fd < 0) ++ goto out_warn_father; ++ } ++ ++ ret = set_stdfds(devnull_fd); ++ if (ret < 0) { ++ ERROR("Failed to redirect std{in,out,err} to \"/dev/null\""); ++ goto out_warn_father; ++ } ++ } ++ #else + if (handler->conf->console.slave < 0 && handler->daemonize) { + if (devnull_fd < 0) { + devnull_fd = open_devnull(); +@@ -1319,11 +1427,10 @@ static int do_start(void *data) + goto out_warn_father; + } + } ++ #endif + + close_prot_errno_disarm(devnull_fd); + +- setsid(); +- + if (handler->conf->init_cwd) { + ret = chdir(handler->conf->init_cwd); + if (ret < 0) { +diff --git a/src/lxc/start.h b/src/lxc/start.h +index 1368d0e..5ea5fe2 100644 +--- a/src/lxc/start.h ++++ b/src/lxc/start.h +@@ -125,6 +125,10 @@ struct lxc_handler { + + #ifdef HAVE_ISULAD + int exit_code;/* isulad: record the exit code of container */ ++ /* Indicates whether should we using pipes or pty dup to std{in,out,err} for console log. */ ++ bool disable_pty; ++ /* Indicates whether should we keep stdin active. */ ++ bool open_stdin; + #endif + + }; +diff --git a/src/lxc/tools/arguments.h b/src/lxc/tools/arguments.h +index e0866d6..a6d9967 100644 +--- a/src/lxc/tools/arguments.h ++++ b/src/lxc/tools/arguments.h +@@ -45,6 +45,8 @@ struct lxc_arguments { + 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 */ + const char *suffix; /* isulad add, suffix used for connect with parent of execed process*/ ++ int disable_pty; ++ int open_stdin; + #endif + + /* for lxc-console */ +diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c +index 76802df6..321c847 100644 +--- a/src/lxc/tools/lxc_start.c ++++ b/src/lxc/tools/lxc_start.c +@@ -143,6 +143,12 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) + case OPT_EXIT_FIFO: + args->exit_monitor_fifo = arg; + break; ++ case OPT_DISABLE_PTY: ++ args->disable_pty = 1; ++ break; ++ case OPT_OPEN_STDIN: ++ args->open_stdin = 1; ++ break; + #endif + + } +@@ -334,6 +340,14 @@ int main(int argc, char *argv[]) + if (my_args.exit_monitor_fifo != NULL) { + c->exit_fifo = safe_strdup(my_args.exit_monitor_fifo); + } ++ ++ if (my_args.disable_pty) { ++ c->want_disable_pty(c, true); ++ } ++ ++ if (my_args.open_stdin) { ++ c->want_open_stdin(c, true); ++ } + #endif + + if (my_args.console) +-- +1.8.3.1 + diff --git a/0045-add_terminal_fifos-Add-terminal-fifos-dynamically.patch b/0017-attach-add_terminal_fifos-Add-terminal-fifos-dynamic.patch similarity index 37% rename from 0045-add_terminal_fifos-Add-terminal-fifos-dynamically.patch rename to 0017-attach-add_terminal_fifos-Add-terminal-fifos-dynamic.patch index af7465ef4f8cff624dd4478fab7bc885a9812f4a..30c1b774eb45c0317676eca5e1695ea79831b84f 100644 --- a/0045-add_terminal_fifos-Add-terminal-fifos-dynamically.patch +++ b/0017-attach-add_terminal_fifos-Add-terminal-fifos-dynamic.patch @@ -1,34 +1,51 @@ -From 934f4937ec177e9c95445b800ca11adbb7c3a0ef Mon Sep 17 00:00:00 2001 +From 29c1823334219c03b1ef4d6b4965529b73ff071b Mon Sep 17 00:00:00 2001 From: LiFeng -Date: Thu, 17 Jan 2019 02:18:14 -0500 -Subject: [PATCH 045/140] add_terminal_fifos: Add terminal fifos dynamically +Date: Mon, 13 Apr 2020 21:39:35 +0800 +Subject: [PATCH 17/49] attach: add_terminal_fifos: Add terminal fifos + dynamically Signed-off-by: LiFeng --- - src/lxc/commands.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ - src/lxc/commands.h | 4 ++++ - src/lxc/lxccontainer.c | 24 +++++++++++++++++++ - src/lxc/lxccontainer.h | 10 ++++++++ - src/lxc/terminal.c | 47 ++++++++++++++++++++++++++++++++++++++ - src/lxc/terminal.h | 1 + - 6 files changed, 148 insertions(+) + src/lxc/commands.c | 94 +++++++++++++++++++++++++++++++++++++++++++++----- + src/lxc/commands.h | 8 +++++ + src/lxc/lxccontainer.c | 24 +++++++++++++ + src/lxc/terminal.c | 57 ++++++++++++++++++++++++++++++ + src/lxc/terminal.h | 4 +++ + 5 files changed, 178 insertions(+), 9 deletions(-) diff --git a/src/lxc/commands.c b/src/lxc/commands.c -index 47a824a..46b2805 100644 +index 991bca2..0ffc5c7 100644 --- a/src/lxc/commands.c +++ b/src/lxc/commands.c -@@ -96,6 +96,7 @@ static const char *lxc_cmd_str(lxc_cmd_t cmd) - [LXC_CMD_ADD_STATE_CLIENT] = "add_state_client", - [LXC_CMD_CONSOLE_LOG] = "console_log", - [LXC_CMD_SERVE_STATE_CLIENTS] = "serve_state_clients", -+ [LXC_CMD_SET_TERMINAL_FIFOS] = "set_terminal_fifos", +@@ -75,15 +75,18 @@ static const char *lxc_cmd_str(lxc_cmd_t cmd) + [LXC_CMD_GET_CONFIG_ITEM] = "get_config_item", + [LXC_CMD_GET_NAME] = "get_name", + [LXC_CMD_GET_LXCPATH] = "get_lxcpath", +- [LXC_CMD_ADD_STATE_CLIENT] = "add_state_client", +- [LXC_CMD_CONSOLE_LOG] = "console_log", ++ [LXC_CMD_ADD_STATE_CLIENT] = "add_state_client", ++ [LXC_CMD_CONSOLE_LOG] = "console_log", + [LXC_CMD_SERVE_STATE_CLIENTS] = "serve_state_clients", + [LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER] = "seccomp_notify_add_listener", + [LXC_CMD_ADD_BPF_DEVICE_CGROUP] = "add_bpf_device_cgroup", +- [LXC_CMD_FREEZE] = "freeze", +- [LXC_CMD_UNFREEZE] = "unfreeze", +- [LXC_CMD_GET_CGROUP2_FD] = "get_cgroup2_fd", ++ [LXC_CMD_FREEZE] = "freeze", ++ [LXC_CMD_UNFREEZE] = "unfreeze", ++ [LXC_CMD_GET_CGROUP2_FD] = "get_cgroup2_fd", + [LXC_CMD_GET_INIT_PIDFD] = "get_init_pidfd", ++#ifdef HAVE_ISULAD ++ [LXC_CMD_SET_TERMINAL_FIFOS] = "set_terminal_fifos", ++#endif }; if (cmd >= LXC_CMD_MAX) -@@ -1056,6 +1057,66 @@ reap_client_fd: - return 1; +@@ -1388,6 +1391,76 @@ static int lxc_cmd_get_cgroup2_fd_callback(int fd, struct lxc_cmd_req *req, + return 0; } ++#ifdef HAVE_ISULAD +/* + * isulad: lxc_cmd_set_terminal_fifos: Set the fifos used for the container as terminal input/output + * @@ -36,21 +53,30 @@ index 47a824a..46b2805 100644 + * + * Returns 0 when success, else when fail. + */ -+int lxc_cmd_set_terminal_fifos(const char *name, const char *lxcpath, const char *in_fifo, const char *out_fifo) ++int lxc_cmd_set_terminal_fifos(const char *name, const char *lxcpath, const char *in_fifo, ++ const char *out_fifo, const char *err_fifo) +{ + int ret = 0, stopped = 0; + int len = 0; + char *tmp = NULL; ++ const char *split = "&&&&", *none_fifo_name = "none"; ++ const char *cmd_in_fifo = in_fifo ? in_fifo : none_fifo_name; ++ const char *cmd_out_fifo = out_fifo ? out_fifo : none_fifo_name; ++ const char *cmd_err_fifo = err_fifo ? err_fifo : none_fifo_name; + -+ if (!in_fifo || !out_fifo) { ++ if (len + strlen(cmd_in_fifo) + strlen(split) + strlen(cmd_out_fifo) + ++ strlen(split) + strlen(cmd_err_fifo) == SIZE_MAX) + return -1; -+ } -+ -+ len = strlen(in_fifo) + strlen("&&&&") + strlen(out_fifo) + 1; ++ len += strlen(cmd_in_fifo) + strlen(split) + strlen(cmd_out_fifo) + strlen(split) + strlen(cmd_err_fifo) + 1; + tmp = malloc(len); -+ if (!tmp) ++ if (tmp == NULL) ++ return -1; ++ ret = snprintf(tmp, len, "%s%s%s%s%s", cmd_in_fifo, split, cmd_out_fifo, split, cmd_err_fifo); ++ if (ret < 0 || ret >= len) { ++ ERROR("Failed to snprintf in fifo of command"); ++ free(tmp); + return -1; -+ snprintf(tmp, len, "%s%s%s", in_fifo, "&&&&", out_fifo); ++ } + + struct lxc_cmd_rr cmd = { + .req = { @@ -78,7 +104,7 @@ index 47a824a..46b2805 100644 +} + +static int lxc_cmd_set_terminal_fifos_callback(int fd, struct lxc_cmd_req *req, -+ struct lxc_handler *handler) ++ struct lxc_handler *handler, struct lxc_epoll_descr *descr) +{ + struct lxc_cmd_rsp rsp; + memset(&rsp, 0, sizeof(rsp)); @@ -86,61 +112,77 @@ index 47a824a..46b2805 100644 + rsp.ret = lxc_terminal_add_fifos(handler->conf, req->data);; + + return lxc_cmd_rsp_send(fd, &rsp); -+ +} ++#endif + static int lxc_cmd_process(int fd, struct lxc_cmd_req *req, - struct lxc_handler *handler) - { -@@ -1075,6 +1136,7 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req, - [LXC_CMD_ADD_STATE_CLIENT] = lxc_cmd_add_state_client_callback, - [LXC_CMD_CONSOLE_LOG] = lxc_cmd_console_log_callback, - [LXC_CMD_SERVE_STATE_CLIENTS] = lxc_cmd_serve_state_clients_callback, -+ [LXC_CMD_SET_TERMINAL_FIFOS] = lxc_cmd_set_terminal_fifos_callback, + struct lxc_handler *handler, + struct lxc_epoll_descr *descr) +@@ -1410,11 +1483,14 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req, + [LXC_CMD_CONSOLE_LOG] = lxc_cmd_console_log_callback, + [LXC_CMD_SERVE_STATE_CLIENTS] = lxc_cmd_serve_state_clients_callback, + [LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER] = lxc_cmd_seccomp_notify_add_listener_callback, +- [LXC_CMD_ADD_BPF_DEVICE_CGROUP] = lxc_cmd_add_bpf_device_cgroup_callback, +- [LXC_CMD_FREEZE] = lxc_cmd_freeze_callback, +- [LXC_CMD_UNFREEZE] = lxc_cmd_unfreeze_callback, +- [LXC_CMD_GET_CGROUP2_FD] = lxc_cmd_get_cgroup2_fd_callback, ++ [LXC_CMD_ADD_BPF_DEVICE_CGROUP] = lxc_cmd_add_bpf_device_cgroup_callback, ++ [LXC_CMD_FREEZE] = lxc_cmd_freeze_callback, ++ [LXC_CMD_UNFREEZE] = lxc_cmd_unfreeze_callback, ++ [LXC_CMD_GET_CGROUP2_FD] = lxc_cmd_get_cgroup2_fd_callback, + [LXC_CMD_GET_INIT_PIDFD] = lxc_cmd_get_init_pidfd_callback, ++#ifdef HAVE_ISULAD ++ [LXC_CMD_SET_TERMINAL_FIFOS] = lxc_cmd_set_terminal_fifos_callback, ++#endif }; - if (req->cmd >= LXC_CMD_MAX) { + if (req->cmd >= LXC_CMD_MAX) diff --git a/src/lxc/commands.h b/src/lxc/commands.h -index 2c024b6..0c64544 100644 +index 9e52484..95815e6 100644 --- a/src/lxc/commands.h +++ b/src/lxc/commands.h -@@ -46,6 +46,7 @@ typedef enum { - LXC_CMD_ADD_STATE_CLIENT, - LXC_CMD_CONSOLE_LOG, - LXC_CMD_SERVE_STATE_CLIENTS, +@@ -38,6 +38,9 @@ typedef enum { + LXC_CMD_UNFREEZE, + LXC_CMD_GET_CGROUP2_FD, + LXC_CMD_GET_INIT_PIDFD, ++#ifdef HAVE_ISULAD + LXC_CMD_SET_TERMINAL_FIFOS, ++#endif LXC_CMD_MAX, } lxc_cmd_t; -@@ -125,4 +126,7 @@ extern int lxc_try_cmd(const char *name, const char *lxcpath); - extern int lxc_cmd_console_log(const char *name, const char *lxcpath, - struct lxc_console_log *log); +@@ -130,4 +133,9 @@ extern int lxc_cmd_freeze(const char *name, const char *lxcpath, int timeout); + extern int lxc_cmd_unfreeze(const char *name, const char *lxcpath, int timeout); + extern int lxc_cmd_get_cgroup2_fd(const char *name, const char *lxcpath); ++#ifdef HAVE_ISULAD +extern int lxc_cmd_set_terminal_fifos(const char *name, const char *lxcpath, -+ const char *in_fifo, const char *out_fifo); ++ const char *in_fifo, const char *out_fifo, const char *err_fifo); ++#endif + #endif /* __commands_h */ diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index d641851..bfbf223 100644 +index e27b63b..d0e6e2b 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c -@@ -5164,6 +5164,29 @@ static bool do_lxcapi_clean_container_resource(struct lxc_container *c, pid_t pi - - WRAP_API_1(bool, lxcapi_clean_container_resource, pid_t) +@@ -5421,6 +5421,29 @@ static bool do_lxcapi_want_open_stdin(struct lxc_container *c, bool state) + } + WRAP_API_1(bool, lxcapi_want_open_stdin, bool) ++ +/* isulad add clean resources */ -+static bool do_lxcapi_add_terminal_fifo(struct lxc_container *c, const char *in_fifo, const char *out_fifo) ++static bool do_lxcapi_add_terminal_fifo(struct lxc_container *c, const char *in_fifo, const char *out_fifo, const char *err_fifo) +{ + bool ret = true; + -+ if (!c || !c->lxc_conf || !in_fifo || !out_fifo) ++ if (!c || !c->lxc_conf) + return false; + if (container_mem_lock(c)) { + ERROR("Error getting mem lock"); + return false; + } + -+ if (lxc_cmd_set_terminal_fifos(c->name, c->config_path, in_fifo, out_fifo)) { ++ if (lxc_cmd_set_terminal_fifos(c->name, c->config_path, in_fifo, out_fifo, err_fifo)) { + ERROR("Error set console fifos"); + ret = false; + } @@ -149,47 +191,25 @@ index d641851..bfbf223 100644 + return ret; +} + -+WRAP_API_2(bool, lxcapi_add_terminal_fifo, const char *, const char *) -+ - static struct lxc_container *do_lxc_container_new(const char *name, const char *configpath, bool load_config) - { - struct lxc_container *c; -@@ -5299,6 +5322,7 @@ static struct lxc_container *do_lxc_container_new(const char *name, const char * ++WRAP_API_3(bool, lxcapi_add_terminal_fifo, const char *, const char *, const char *) + #endif + + struct lxc_container *lxc_container_new(const char *name, const char *configpath) +@@ -5567,6 +5590,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath + #ifdef HAVE_ISULAD c->set_container_info_file = lxcapi_set_container_info_file; - c->set_start_timeout = lxcapi_set_start_timeout; - c->clean_container_resource = lxcapi_clean_container_resource; + c->set_terminal_init_fifos = lxcapi_set_terminal_default_fifos; + c->add_terminal_fifos = lxcapi_add_terminal_fifo; - /* isulad add end */ + #endif return c; -diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h -index a00e0ec..c1d83ba 100644 ---- a/src/lxc/lxccontainer.h -+++ b/src/lxc/lxccontainer.h -@@ -878,6 +878,16 @@ struct lxc_container { - bool (*set_terminal_init_fifos)(struct lxc_container *c, const char *in, const char *out); - - /*! isulad add -+ * \brief An API call to add the path of terminal fifos -+ * -+ * \param c Container. -+ * \param path Value of the console path.. -+ * -+ * \return \c true on success, else \c false. -+ */ -+ bool (*add_terminal_fifos)(struct lxc_container *c, const char *in, const char *out); -+ -+ /*! isulad add - * \brief An API call to set the path of info file - * - * \param c Container. diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index ee3aef2..a33830d 100644 +index 775743d..4d7c2cd 100644 --- a/src/lxc/terminal.c +++ b/src/lxc/terminal.c -@@ -1473,3 +1473,50 @@ int lxc_terminal_map_ids(struct lxc_conf *c, struct lxc_terminal *terminal) - - return 0; +@@ -1607,6 +1607,63 @@ err: + lxc_terminal_delete(terminal); + return -ENODEV; } + +/* isulad: add fifos dynamic*/ @@ -198,34 +218,44 @@ index ee3aef2..a33830d 100644 + int ret = 0; + struct lxc_terminal *terminal = &conf->console; + int fifofd_in = -1; -+ char *tmp = NULL, *saveptr = NULL, *in = NULL, *out = NULL; ++ char *tmp = NULL, *saveptr = NULL, *in = NULL, *out = NULL, *err = NULL; ++ const char *none_fifo_name = "none"; + -+ tmp = strdup(fifonames); -+ if (!tmp) { -+ ret = -1; -+ goto free_out; -+ } ++ tmp = safe_strdup(fifonames); + + in = strtok_r(tmp, "&&&&", &saveptr); + if (!in) { + ret = -1; + goto free_out; + } ++ if (strcmp(in, none_fifo_name) == 0) ++ in = NULL; ++ + out = strtok_r(NULL, "&&&&", &saveptr); + if (!out) { + ret = -1; + goto free_out; + } ++ if (strcmp(out, none_fifo_name) == 0) ++ out = NULL; + -+ fifofd_in = lxc_terminal_set_fifo(terminal, in, out); -+ if (fifofd_in < 0) { ++ err = strtok_r(NULL, "&&&&", &saveptr); ++ if (!err) { ++ ret = -1; ++ goto free_out; ++ } ++ if (strcmp(err, none_fifo_name) == 0) ++ err = NULL; ++ ++ ret = lxc_terminal_set_fifo(terminal, in, out, err, &fifofd_in); ++ if (ret < 0) { + ERROR("Faild to set fifos to console config"); + ret = -1; + goto free_out; + } + + if (lxc_mainloop_add_handler(terminal->descr, fifofd_in, -+ lxc_terminal_io_cb, terminal)) { ++ lxc_terminal_io_cb, terminal)) { + ERROR("console fifo not added to mainloop"); + lxc_terminal_delete_fifo(fifofd_in, &terminal->fifos); + ret = -1; @@ -238,16 +268,21 @@ index ee3aef2..a33830d 100644 + return ret; +} + + #else + int lxc_terminal_create(struct lxc_terminal *terminal) + { diff --git a/src/lxc/terminal.h b/src/lxc/terminal.h -index d25da65..d006b80 100644 +index dfc03c6..b4160b3 100644 --- a/src/lxc/terminal.h +++ b/src/lxc/terminal.h -@@ -310,5 +310,6 @@ extern int lxc_terminal_map_ids(struct lxc_conf *c, - static bool lxc_terminal_is_fifo(int fd, struct lxc_list *list); - /* isulad: if fd == -1, means delete all the fifos*/ - int lxc_terminal_delete_fifo(int fd, struct lxc_list *list); -+int lxc_terminal_add_fifos(struct lxc_conf *conf, const char *fifonames); +@@ -274,4 +274,8 @@ extern void lxc_terminal_init(struct lxc_terminal *terminal); + extern int lxc_terminal_map_ids(struct lxc_conf *c, + struct lxc_terminal *terminal); ++#ifdef HAVE_ISULAD ++int lxc_terminal_add_fifos(struct lxc_conf *conf, const char *fifonames); ++#endif ++ #endif /* __LXC_TERMINAL_H */ -- 1.8.3.1 diff --git a/0017-isulad-check-cgroup-cpu.shares-after-setted.patch b/0017-isulad-check-cgroup-cpu.shares-after-setted.patch deleted file mode 100644 index 51f9f67e4ff2906524847957d1ff9eac680fb1c3..0000000000000000000000000000000000000000 --- a/0017-isulad-check-cgroup-cpu.shares-after-setted.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 068331c965f3011f03e31b67d9791b2f81fd69b0 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Mon, 14 Jan 2019 11:03:03 +0800 -Subject: [PATCH 017/140] isulad: check cgroup cpu.shares after setted - -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgfsng.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 61 insertions(+) - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index 3e702b3..ab5732b 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -2204,6 +2204,42 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, - return ret; - } - -+/* Called from setup_limits - here we have the container's cgroup_data because -+ * we created the cgroups. -+ */ -+static int cg_legacy_get_data(struct cgroup_ops *ops, const char *filename, -+ char *value, size_t len) -+{ -+ char *fullpath, *p; -+ struct hierarchy *h; -+ int ret = 0; -+ char *controller = NULL; -+ -+ len = strlen(filename); -+ controller = alloca(len + 1); -+ (void)strlcpy(controller, filename, len + 1); -+ -+ p = strchr(controller, '.'); -+ if (p) -+ *p = '\0'; -+ -+ -+ h = get_hierarchy(ops, controller); -+ if (!h) { -+ ERROR("Failed to setup limits for the \"%s\" controller. " -+ "The controller seems to be unused by \"cgfsng\" cgroup " -+ "driver or not enabled on the cgroup hierarchy", -+ controller); -+ errno = ENOENT; -+ return -ENOENT; -+ } -+ -+ fullpath = must_make_path(h->container_full_path, filename, NULL); -+ ret = lxc_read_from_file(fullpath, value, len); -+ free(fullpath); -+ return ret; -+} -+ - static bool __cg_legacy_setup_limits(struct cgroup_ops *ops, - struct lxc_list *cgroup_settings, - bool do_devices) -@@ -2211,6 +2247,8 @@ static bool __cg_legacy_setup_limits(struct cgroup_ops *ops, - struct lxc_list *iterator, *next, *sorted_cgroup_settings; - struct lxc_cgroup *cg; - bool ret = false; -+ char value[21]; -+ long long int readvalue, setvalue; - - if (lxc_list_empty(cgroup_settings)) - return true; -@@ -2236,6 +2274,29 @@ static bool __cg_legacy_setup_limits(struct cgroup_ops *ops, - DEBUG("Set controller \"%s\" set to \"%s\"", - cg->subsystem, cg->value); - } -+ // isulad: check cpu shares -+ if (strcmp(cg->subsystem, "cpu.shares") == 0) { -+ if (cg_legacy_get_data(ops, cg->subsystem, value, sizeof(value)) < 0) { -+ SYSERROR("Error get %s", cg->subsystem); -+ goto out; -+ } -+ trim(value); -+ if (lxc_safe_long_long(cg->value, &setvalue) != 0) { -+ SYSERROR("Invalid value %s", cg->value); -+ goto out; -+ } -+ if (lxc_safe_long_long(value, &readvalue) != 0) { -+ SYSERROR("Invalid value %s", value); -+ goto out; -+ } -+ if (setvalue > readvalue) { -+ ERROR("The maximum allowed cpu-shares is %s", value); -+ goto out; -+ } else if (setvalue < readvalue) { -+ ERROR("The minimum allowed cpu-shares is %s", value); -+ goto out; -+ } -+ } - } - - ret = true; --- -1.8.3.1 - diff --git a/0018-pty-setup-pty-after-setup-rootfs-mount-options.patch b/0018-pty-setup-pty-after-setup-rootfs-mount-options.patch new file mode 100644 index 0000000000000000000000000000000000000000..1612fe7f12aaa7d41f1d250781f1ab4f21c8cb2d --- /dev/null +++ b/0018-pty-setup-pty-after-setup-rootfs-mount-options.patch @@ -0,0 +1,157 @@ +From 8d2f80168d89abc317affee358120dcf25b8af19 Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Tue, 14 Apr 2020 12:50:55 +0800 +Subject: [PATCH 18/49] pty: setup pty after setup rootfs mount options + +Signed-off-by: LiFeng +--- + src/lxc/conf.c | 16 +++++++++---- + src/lxc/start.c | 2 +- + src/lxc/terminal.c | 67 ++++++++++++++++++++++++++++++++++++------------------ + 3 files changed, 57 insertions(+), 28 deletions(-) + +diff --git a/src/lxc/conf.c b/src/lxc/conf.c +index fce241b..2e93227 100644 +--- a/src/lxc/conf.c ++++ b/src/lxc/conf.c +@@ -3748,14 +3748,20 @@ int lxc_setup(struct lxc_handler *handler) + if (lxc_conf->autodev > 0) + (void)lxc_setup_boot_id(); + ++#ifdef HAVE_ISULAD ++ if (setup_rootfs_mountopts(&lxc_conf->rootfs)) { ++ return log_error(-1, "failed to set rootfs for '%s'", name); ++ } ++ if (lxc_conf->rootfs.path) { ++ ret = lxc_setup_devpts(lxc_conf); ++ if (ret < 0) { ++ return log_error(-1, "Failed to setup new devpts instance for '%s'", name); ++ } ++ } ++#else + ret = lxc_setup_devpts(lxc_conf); + if (ret < 0) + return log_error(-1, "Failed to setup new devpts instance"); +- +-#ifdef HAVE_ISULAD +- if (setup_rootfs_mountopts(&lxc_conf->rootfs)) { +- return log_error(-1, "failed to set rootfs for '%s'", name); +- } + #endif + + ret = lxc_create_ttys(handler); +diff --git a/src/lxc/start.c b/src/lxc/start.c +index 145b015..800f884 100644 +--- a/src/lxc/start.c ++++ b/src/lxc/start.c +@@ -596,7 +596,7 @@ int lxc_poll(const char *name, struct lxc_handler *handler) + goto out_mainloop_console; + + if (has_console) +- ret = lxc_mainloop(&descr_console, 0); ++ ret = lxc_mainloop(&descr_console, 100); + + out_mainloop_console: + if (has_console) { +diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c +index 4d7c2cd..1f46d49 100644 +--- a/src/lxc/terminal.c ++++ b/src/lxc/terminal.c +@@ -186,6 +186,42 @@ static int lxc_terminal_truncate_log_file(struct lxc_terminal *terminal) + return lxc_unpriv(ftruncate(terminal->log_fd, 0)); + } + ++#ifdef HAVE_ISULAD ++/* ++ * isulad: support mult-logfiles ++ * */ ++static int lxc_terminal_rename_old_log_file(struct lxc_terminal *terminal) ++{ ++ int ret; ++ unsigned int i; ++ char tmp[PATH_MAX] = {0}; ++ char *rename_fname = NULL; ++ ++ for (i = terminal->log_rotate - 1; i > 1; i--) { ++ ret = snprintf(tmp, PATH_MAX, "%s.%u", terminal->log_path, i); ++ if (ret < 0 || ret >= PATH_MAX) { ++ free(rename_fname); ++ return -EFBIG; ++ } ++ free(rename_fname); ++ rename_fname = safe_strdup(tmp); ++ ret = snprintf(tmp, PATH_MAX, "%s.%u", terminal->log_path, (i - 1)); ++ if (ret < 0 || ret >= PATH_MAX) { ++ free(rename_fname); ++ return -EFBIG; ++ } ++ ret = lxc_unpriv(rename(tmp, rename_fname)); ++ if (ret < 0 && errno != ENOENT) { ++ free(rename_fname); ++ return ret; ++ } ++ } ++ ++ free(rename_fname); ++ return 0; ++} ++#endif ++ + static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal) + { + __do_free char *tmp = NULL; +@@ -199,6 +235,15 @@ static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal) + if (terminal->log_fd < 0) + return -EBADF; + ++#ifdef HAVE_ISULAD ++ /* isuald: rotate old log file first */ ++ ret = lxc_terminal_rename_old_log_file(terminal); ++ if(ret != 0) { ++ ERROR("Rename old log file failed"); ++ return ret; ++ } ++#endif ++ + len = strlen(terminal->log_path) + sizeof(".1"); + tmp = must_realloc(NULL, len); + +@@ -1512,21 +1557,6 @@ static int lxc_terminal_fifo_default(struct lxc_terminal *terminal) + return 0; + } + +-static int use_unix_newline(int master_fd) +-{ +- struct termios oldtios; +- int ret; +- +- ret = tcgetattr(master_fd, &oldtios); +- if (ret < 0) +- return -1; +- oldtios.c_oflag &= ~ONLCR; +- ret = tcsetattr(master_fd, TCSAFLUSH, &oldtios); +- if (ret < 0) +- return -1; +- return 0; +-} +- + int lxc_terminal_create(struct lxc_terminal *terminal) + { + int ret; +@@ -1544,13 +1574,6 @@ int lxc_terminal_create(struct lxc_terminal *terminal) + goto err; + } + +- /* isulad: clear ONLCR flag */ +- ret = use_unix_newline(terminal->master); +- if (ret < 0) { +- SYSERROR("Failed to clear ONLCR flag on terminal master"); +- goto err; +- } +- + ret = fd_cloexec(terminal->master, true); + if (ret < 0) { + SYSERROR("Failed to set FD_CLOEXEC flag on terminal master"); +-- +1.8.3.1 + diff --git a/0019-remount-cgroup-readonly-and-make-soft-link-of-subcgr.patch b/0019-remount-cgroup-readonly-and-make-soft-link-of-subcgr.patch deleted file mode 100644 index f5de1fbbd713cc30f947290f29d00cd93b835da2..0000000000000000000000000000000000000000 --- a/0019-remount-cgroup-readonly-and-make-soft-link-of-subcgr.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 16616f224d5577594548b2ce1ee50f51a449e20d Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Mon, 14 Jan 2019 13:51:01 +0800 -Subject: [PATCH 019/140] remount cgroup readonly and make soft link of - subcgroup - -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgfsng.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 44 insertions(+) - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index ab5732b..705985f 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -1621,6 +1621,7 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, - int i, ret; - char *tmpfspath = NULL; - bool has_cgns = false, retval = false, wants_force_mount = false; -+ char **merged = NULL; - - if ((type & LXC_AUTO_CGROUP_MASK) == 0) - return true; -@@ -1667,6 +1668,14 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, - continue; - controller++; - -+ // isulad: symlink subcgroup -+ if (strchr(controller, ',') != NULL) { -+ int pret; -+ pret = lxc_append_string(&merged, controller); -+ if (pret < 0) -+ goto on_error; -+ } -+ - controllerpath = must_make_path(tmpfspath, controller, NULL); - if (dir_exists(controllerpath)) { - free(controllerpath); -@@ -1721,10 +1730,45 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, - if (ret < 0) - goto on_error; - } -+ -+ // isulad: symlink subcgroup -+ if (merged) { -+ char **mc; -+ for (mc = merged; *mc; mc++) { -+ char *token; -+ char *merge = must_copy_string(*mc); -+ lxc_iterate_parts(token, merge, ",") { -+ int mret; -+ char *link; -+ link = must_make_path(tmpfspath, token, NULL); -+ mret = symlink(*mc, link); -+ if (mret < 0 && errno != EEXIST) { -+ SYSERROR("Failed to create link %s for target %s", link, merge); -+ free(merge); -+ free(link); -+ goto on_error; -+ } -+ free(link); -+ } -+ free(merge); -+ } -+ } -+ -+ -+ // isulad: remount /sys/fs/cgroup to readonly -+ if (type == LXC_AUTO_CGROUP_FULL_RO || type == LXC_AUTO_CGROUP_RO) { -+ ret = mount(tmpfspath, tmpfspath, "bind", -+ MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_RELATIME|MS_RDONLY|MS_BIND|MS_REMOUNT, NULL); -+ if (ret < 0) { -+ SYSERROR("Failed to remount /sys/fs/cgroup."); -+ goto on_error; -+ } -+ } - retval = true; - - on_error: - free(tmpfspath); -+ lxc_free_array((void **)merged, free); - return retval; - } - --- -1.8.3.1 - diff --git a/0138-resize-implement-resize-function-in-exec-start.patch b/0019-resize-implement-resize-function-in-exec-start.patch similarity index 56% rename from 0138-resize-implement-resize-function-in-exec-start.patch rename to 0019-resize-implement-resize-function-in-exec-start.patch index 62011cbe36068016fa616fb4a793e60231b8aadd..cb278967eff27f1bf00a87ff6dfbabba9a41a1c4 100644 --- a/0138-resize-implement-resize-function-in-exec-start.patch +++ b/0019-resize-implement-resize-function-in-exec-start.patch @@ -1,88 +1,178 @@ -From d51a587ee6a9ba82e52f5f1a61191e257865041d Mon Sep 17 00:00:00 2001 +From f690df5983011dd3b61f0e139c3e939f3fecf37a Mon Sep 17 00:00:00 2001 From: LiFeng -Date: Fri, 29 Nov 2019 22:12:10 -0500 -Subject: [PATCH 138/140] resize: implement resize function in exec/start +Date: Tue, 14 Apr 2020 16:04:15 +0800 +Subject: [PATCH 19/49] resize: implement resize function in exec/start Signed-off-by: LiFeng --- - src/lxc/Makefile.am | 1 + - src/lxc/attach.c | 45 ++++- - src/lxc/attach.h | 2 +- - src/lxc/commands.c | 44 +++++ - src/lxc/commands.h | 9 + - src/lxc/exec_commands.c | 416 +++++++++++++++++++++++++++++++++++++++++++++ - src/lxc/exec_commands.h | 73 ++++++++ - src/lxc/lxccontainer.c | 64 ++++++- - src/lxc/lxccontainer.h | 15 +- - src/lxc/terminal.c | 26 +++ - src/lxc/terminal.h | 1 + - src/lxc/tools/arguments.h | 3 +- - src/lxc/tools/lxc_attach.c | 20 ++- - src/lxc/tools/lxc_copy.c | 2 +- - src/lxc/tools/lxc_ls.c | 2 +- - 15 files changed, 698 insertions(+), 25 deletions(-) + src/lxc/Makefile.am | 10 +- + src/lxc/af_unix.c | 33 +++- + src/lxc/af_unix.h | 5 +- + src/lxc/attach.c | 51 +++++- + src/lxc/commands.c | 50 ++++++ + src/lxc/commands.h | 2 + + src/lxc/exec_commands.c | 416 ++++++++++++++++++++++++++++++++++++++++++++++++ + src/lxc/exec_commands.h | 73 +++++++++ + src/lxc/lxccontainer.c | 50 ++++++ + src/lxc/terminal.c | 27 ++++ + src/lxc/terminal.h | 1 + + 11 files changed, 710 insertions(+), 8 deletions(-) create mode 100644 src/lxc/exec_commands.c create mode 100644 src/lxc/exec_commands.h diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am -index 27240cc..c21eb85 100644 +index 23935e5..c288c51 100644 --- a/src/lxc/Makefile.am +++ b/src/lxc/Makefile.am -@@ -101,6 +101,7 @@ liblxc_la_SOURCES = af_unix.c af_unix.h \ - cgroups/cgroup_utils.c cgroups/cgroup_utils.h \ - compiler.h \ - commands.c commands.h \ -+ exec_commands.c exec_commands.h \ - commands_utils.c commands_utils.h \ - conf.c conf.h \ - confile.c confile.h \ +@@ -52,14 +52,15 @@ noinst_HEADERS = api_extensions.h \ + utils.h \ + uuid.h + +-#if HAVE_ISULAD ++if HAVE_ISULAD + noinst_HEADERS += isulad_utils.h path.h \ + json/json_common.h json/defs.h \ + json/oci_runtime_hooks.h \ + json/logger_json_file.h \ + json/oci_runtime_spec.h \ +- json/read-file.h +-#endif ++ json/read-file.h \ ++ exec_commands.h ++endif + + if IS_BIONIC + noinst_HEADERS += ../include/fexecve.h \ +@@ -172,7 +173,8 @@ liblxc_la_SOURCES += isulad_utils.c isulad_utils.h \ + json/oci_runtime_hooks.c json/oci_runtime_hooks.h \ + json/logger_json_file.c json/logger_json_file.h \ + json/oci_runtime_spec.c json/oci_runtime_spec.h \ +- json/read-file.c json/read-file.h ++ json/read-file.c json/read-file.h \ ++ exec_commands.c exec_commands.h + endif + + if IS_BIONIC +diff --git a/src/lxc/af_unix.c b/src/lxc/af_unix.c +index e172088..9f268be 100644 +--- a/src/lxc/af_unix.c ++++ b/src/lxc/af_unix.c +@@ -168,7 +168,7 @@ int lxc_unix_send_fds(int fd, int *sendfds, int num_sendfds, void *data, + } + + static int lxc_abstract_unix_recv_fds_iov(int fd, int *recvfds, int num_recvfds, +- struct iovec *iov, size_t iovlen) ++ struct iovec *iov, size_t iovlen, unsigned int timeout) + { + __do_free char *cmsgbuf = NULL; + int ret; +@@ -188,6 +188,22 @@ static int lxc_abstract_unix_recv_fds_iov(int fd, int *recvfds, int num_recvfds, + msg.msg_iov = iov; + msg.msg_iovlen = iovlen; + ++#ifdef HAVE_ISULAD ++ struct timeval out; ++ if (timeout > 0) { ++ memset(&out, 0, sizeof(out)); ++ out.tv_sec = timeout / 1000000; ++ out.tv_usec = timeout % 1000000; ++ ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, ++ (const void *)&out, sizeof(out)); ++ if (ret < 0) { ++ ERROR("Failed to set %u timeout on containter " ++ "state socket", timeout); ++ return ret; ++ } ++ } ++#endif ++ + do { + ret = recvmsg(fd, &msg, 0); + } while (ret < 0 && errno == EINTR); +@@ -220,8 +236,21 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds, + .iov_base = data ? data : buf, + .iov_len = data ? size : sizeof(buf), + }; +- return lxc_abstract_unix_recv_fds_iov(fd, recvfds, num_recvfds, &iov, 1); ++ return lxc_abstract_unix_recv_fds_iov(fd, recvfds, num_recvfds, &iov, 1, 0); ++} ++ ++#ifdef HAVE_ISULAD ++int lxc_abstract_unix_recv_fds_timeout(int fd, int *recvfds, int num_recvfds, ++ void *data, size_t size, unsigned int timeout) ++{ ++ char buf[1] = {0}; ++ struct iovec iov = { ++ .iov_base = data ? data : buf, ++ .iov_len = data ? size : sizeof(buf), ++ }; ++ return lxc_abstract_unix_recv_fds_iov(fd, recvfds, num_recvfds, &iov, 1, timeout); + } ++#endif + + int lxc_abstract_unix_send_credential(int fd, void *data, size_t size) + { +diff --git a/src/lxc/af_unix.h b/src/lxc/af_unix.h +index 2531b0b..6943a61 100644 +--- a/src/lxc/af_unix.h ++++ b/src/lxc/af_unix.h +@@ -27,5 +27,8 @@ extern int lxc_unix_sockaddr(struct sockaddr_un *ret, const char *path); + extern int lxc_unix_connect(struct sockaddr_un *addr); + extern int lxc_unix_connect_type(struct sockaddr_un *addr, int type); + extern int lxc_socket_set_timeout(int fd, int rcv_timeout, int snd_timeout); +- ++#ifdef HAVE_ISULAD ++int lxc_abstract_unix_recv_fds_timeout(int fd, int *recvfds, int num_recvfds, ++ void *data, size_t size, unsigned int timeout); ++#endif + #endif /* __LXC_AF_UNIX_H */ diff --git a/src/lxc/attach.c b/src/lxc/attach.c -index 1f14eb4..03a7646 100644 +index e66ca1c..33946bb 100644 --- a/src/lxc/attach.c +++ b/src/lxc/attach.c -@@ -64,6 +64,7 @@ - #include "syscall_wrappers.h" +@@ -45,6 +45,10 @@ #include "terminal.h" #include "utils.h" -+#include "exec_commands.h" ++#ifdef HAVE_ISULAD ++#include "exec_commands.h" ++#endif ++ #if HAVE_SYS_PERSONALITY_H #include -@@ -1208,7 +1209,7 @@ out: - return ret; - } - --int lxc_attach(const char *name, const char *lxcpath, -+int lxc_attach(const char *name, const char *lxcpath, const char *suffix, - lxc_attach_exec_t exec_function, void *exec_payload, - lxc_attach_options_t *options, pid_t *attached_process, char **err_msg) - { -@@ -1221,6 +1222,10 @@ int lxc_attach(const char *name, const char *lxcpath, - struct lxc_terminal terminal; + #endif +@@ -998,6 +1002,13 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, struct lxc_conf *conf; + char *name, *lxcpath; struct attach_clone_payload payload = {0}; ++#ifdef HAVE_ISULAD + struct lxc_exec_command_handler exec_command; ++ const char *suffix = options->suffix; + + exec_command.maincmd_fd = -1; + exec_command.terminal = &terminal; ++#endif ret = access("/proc/self/ns", X_OK); - if (ret) { -@@ -1354,6 +1359,10 @@ int lxc_attach(const char *name, const char *lxcpath, + if (ret) +@@ -1129,6 +1140,12 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, } terminal.log_fd = options->log_fd; ++#ifdef HAVE_ISULAD + if (suffix != NULL) { + exec_command.maincmd_fd = lxc_exec_cmd_init(name, lxcpath, suffix); + exec_command.terminal = &terminal; + } ++#endif } else { lxc_terminal_init(&terminal); } -@@ -1394,15 +1403,30 @@ int lxc_attach(const char *name, const char *lxcpath, +@@ -1169,6 +1186,15 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, ret = socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets); if (ret < 0) { SYSERROR("Could not set up required IPC mechanism for attaching"); ++#ifdef HAVE_ISULAD + if (options->attach_flags & LXC_ATTACH_TERMINAL) { + lxc_terminal_delete(&terminal); + lxc_terminal_conf_free(&terminal); @@ -90,31 +180,15 @@ index 1f14eb4..03a7646 100644 + close(exec_command.maincmd_fd); + } + } ++#endif free(cwd); lxc_proc_put_context_info(init_ctx); return -1; - } - -- - /* isulad: pipdfd for get error message of child or grandchild process. */ - if (pipe2(conf->errpipe, O_CLOEXEC) != 0) { - SYSERROR("Failed to init errpipe"); -+ if (options->attach_flags & LXC_ATTACH_TERMINAL) { -+ lxc_terminal_delete(&terminal); -+ lxc_terminal_conf_free(&terminal); -+ if (exec_command.maincmd_fd != -1) { -+ close(exec_command.maincmd_fd); -+ } -+ } -+ close(ipc_sockets[0]); -+ close(ipc_sockets[1]); - free(cwd); - lxc_proc_put_context_info(init_ctx); - return -1; -@@ -1418,6 +1442,15 @@ int lxc_attach(const char *name, const char *lxcpath, +@@ -1184,6 +1210,17 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, pid = fork(); if (pid < 0) { SYSERROR("Failed to create first subprocess"); ++#ifdef HAVE_ISULAD + if (options->attach_flags & LXC_ATTACH_TERMINAL) { + lxc_terminal_delete(&terminal); + lxc_terminal_conf_free(&terminal); @@ -124,67 +198,67 @@ index 1f14eb4..03a7646 100644 + } + close(ipc_sockets[0]); + close(ipc_sockets[1]); ++#endif free(cwd); lxc_proc_put_context_info(init_ctx); return -1; -@@ -1474,6 +1507,8 @@ int lxc_attach(const char *name, const char *lxcpath, +@@ -1239,7 +1276,9 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + ret = lxc_attach_terminal_mainloop_init(&terminal, &descr); if (ret < 0) goto on_error; - +- ++#ifdef HAVE_ISULAD + (void)lxc_exec_cmd_mainloop_add(&descr, &exec_command); -+ ++#endif TRACE("Initialized terminal mainloop"); } -@@ -1597,6 +1632,9 @@ int lxc_attach(const char *name, const char *lxcpath, +@@ -1352,6 +1391,11 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, if (options->attach_flags & LXC_ATTACH_TERMINAL) { lxc_terminal_delete(&terminal); lxc_terminal_conf_free(&terminal); ++#ifdef HAVE_ISULAD + if (exec_command.maincmd_fd != -1) { + close(exec_command.maincmd_fd); + } ++#endif } lxc_proc_put_context_info(init_ctx); -@@ -1615,6 +1653,9 @@ int lxc_attach(const char *name, const char *lxcpath, +@@ -1365,6 +1409,11 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, lxc_attach_terminal_close_master(&terminal); lxc_attach_terminal_close_peer(&terminal); lxc_attach_terminal_close_log(&terminal); ++#ifdef HAVE_ISULAD + if (exec_command.maincmd_fd != -1) { + close(exec_command.maincmd_fd); + } ++#endif } /* Wait for the parent to have setup cgroups. */ -diff --git a/src/lxc/attach.h b/src/lxc/attach.h -index e62b98b..8626a8e 100644 ---- a/src/lxc/attach.h -+++ b/src/lxc/attach.h -@@ -41,7 +41,7 @@ struct lxc_proc_context_info { - int ns_fd[LXC_NS_MAX]; - }; - --extern int lxc_attach(const char *name, const char *lxcpath, -+extern int lxc_attach(const char *name, const char *lxcpath, const char *suffix, - lxc_attach_exec_t exec_function, void *exec_payload, - lxc_attach_options_t *options, pid_t *attached_process, char **err_msg); - diff --git a/src/lxc/commands.c b/src/lxc/commands.c -index b70564f..8fd929d 100644 +index 0ffc5c7..184a219 100644 --- a/src/lxc/commands.c +++ b/src/lxc/commands.c -@@ -97,6 +97,7 @@ static const char *lxc_cmd_str(lxc_cmd_t cmd) - [LXC_CMD_CONSOLE_LOG] = "console_log", - [LXC_CMD_SERVE_STATE_CLIENTS] = "serve_state_clients", - [LXC_CMD_SET_TERMINAL_FIFOS] = "set_terminal_fifos", -+ [LXC_CMD_SET_TERMINAL_WINCH] = "set_terminal_winch", +@@ -86,6 +86,7 @@ static const char *lxc_cmd_str(lxc_cmd_t cmd) + [LXC_CMD_GET_INIT_PIDFD] = "get_init_pidfd", + #ifdef HAVE_ISULAD + [LXC_CMD_SET_TERMINAL_FIFOS] = "set_terminal_fifos", ++ [LXC_CMD_SET_TERMINAL_WINCH] = "set_terminal_winch", + #endif }; - if (cmd >= LXC_CMD_MAX) -@@ -1126,6 +1127,48 @@ static int lxc_cmd_set_terminal_fifos_callback(int fd, struct lxc_cmd_req *req, +@@ -1459,6 +1460,54 @@ static int lxc_cmd_set_terminal_fifos_callback(int fd, struct lxc_cmd_req *req, + return lxc_cmd_rsp_send(fd, &rsp); } - ++ ++struct lxc_cmd_set_terminal_winch_request { ++ unsigned int height; ++ unsigned int width; ++}; ++ +int lxc_cmd_set_terminal_winch(const char *name, const char *lxcpath, unsigned int height, unsigned int width) +{ + int ret = 0, stopped = 0; @@ -215,7 +289,7 @@ index b70564f..8fd929d 100644 +} + +static int lxc_cmd_set_terminal_winch_callback(int fd, struct lxc_cmd_req *req, -+ struct lxc_handler *handler) ++ struct lxc_handler *handler, struct lxc_epoll_descr *descr) +{ + struct lxc_cmd_rsp rsp; + struct lxc_cmd_set_terminal_winch_request *data = (struct lxc_cmd_set_terminal_winch_request *)(req->data); @@ -227,48 +301,36 @@ index b70564f..8fd929d 100644 + +} + + #endif + static int lxc_cmd_process(int fd, struct lxc_cmd_req *req, - struct lxc_handler *handler) - { -@@ -1146,6 +1189,7 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req, - [LXC_CMD_CONSOLE_LOG] = lxc_cmd_console_log_callback, - [LXC_CMD_SERVE_STATE_CLIENTS] = lxc_cmd_serve_state_clients_callback, - [LXC_CMD_SET_TERMINAL_FIFOS] = lxc_cmd_set_terminal_fifos_callback, -+ [LXC_CMD_SET_TERMINAL_WINCH] = lxc_cmd_set_terminal_winch_callback, +@@ -1490,6 +1539,7 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req, + [LXC_CMD_GET_INIT_PIDFD] = lxc_cmd_get_init_pidfd_callback, + #ifdef HAVE_ISULAD + [LXC_CMD_SET_TERMINAL_FIFOS] = lxc_cmd_set_terminal_fifos_callback, ++ [LXC_CMD_SET_TERMINAL_WINCH] = lxc_cmd_set_terminal_winch_callback, + #endif }; - if (req->cmd >= LXC_CMD_MAX) { diff --git a/src/lxc/commands.h b/src/lxc/commands.h -index 6b64849..c8cc8cd 100644 +index 95815e6..aa8289d 100644 --- a/src/lxc/commands.h +++ b/src/lxc/commands.h -@@ -47,6 +47,7 @@ typedef enum { - LXC_CMD_CONSOLE_LOG, - LXC_CMD_SERVE_STATE_CLIENTS, +@@ -40,6 +40,7 @@ typedef enum { + LXC_CMD_GET_INIT_PIDFD, + #ifdef HAVE_ISULAD LXC_CMD_SET_TERMINAL_FIFOS, + LXC_CMD_SET_TERMINAL_WINCH, + #endif LXC_CMD_MAX, } lxc_cmd_t; - -@@ -80,6 +81,11 @@ struct lxc_cmd_console_log { - - }; - -+struct lxc_cmd_set_terminal_winch_request { -+ unsigned int height; -+ unsigned int width; -+}; -+ - extern int lxc_cmd_terminal_winch(const char *name, const char *lxcpath); - extern int lxc_cmd_console(const char *name, int *ttynum, int *fd, - const char *lxcpath); -@@ -129,4 +135,7 @@ extern int lxc_cmd_console_log(const char *name, const char *lxcpath, +@@ -136,6 +137,7 @@ extern int lxc_cmd_get_cgroup2_fd(const char *name, const char *lxcpath); + #ifdef HAVE_ISULAD extern int lxc_cmd_set_terminal_fifos(const char *name, const char *lxcpath, const char *in_fifo, const char *out_fifo, const char *err_fifo); - +extern int lxc_cmd_set_terminal_winch(const char *name, const char *lxcpath, unsigned int height, unsigned int width); -+ -+ + #endif + #endif /* __commands_h */ diff --git a/src/lxc/exec_commands.c b/src/lxc/exec_commands.c new file mode 100644 @@ -772,87 +834,25 @@ index 0000000..2581ee9 + +#endif /* __exec_commands_h */ diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index 9f9cbfc..7ef57f0 100644 +index d0e6e2b..75c1bbc 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c -@@ -47,6 +47,7 @@ - #include "cgroup.h" - #include "commands.h" - #include "commands_utils.h" -+#include "exec_commands.h" - #include "conf.h" - #include "config.h" - #include "confile.h" -@@ -4214,7 +4215,7 @@ static bool do_lxcapi_rename(struct lxc_container *c, const char *newname) - - WRAP_API_1(bool, lxcapi_rename, const char *) - --static int lxcapi_attach(struct lxc_container *c, lxc_attach_exec_t exec_function, void *exec_payload, lxc_attach_options_t *options, pid_t *attached_process) -+static int lxcapi_attach(struct lxc_container *c, const char *suffix, lxc_attach_exec_t exec_function, void *exec_payload, lxc_attach_options_t *options, pid_t *attached_process) - { - int ret; - -@@ -4223,12 +4224,12 @@ static int lxcapi_attach(struct lxc_container *c, lxc_attach_exec_t exec_functio - - current_config = c->lxc_conf; - -- ret = lxc_attach(c->name, c->config_path, exec_function, exec_payload, options, attached_process, &c->lxc_conf->errmsg); -+ ret = lxc_attach(c->name, c->config_path, suffix, exec_function, exec_payload, options, attached_process, &c->lxc_conf->errmsg); - current_config = NULL; - return ret; - } - --static int do_lxcapi_attach_run_wait(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char * const argv[]) -+static int do_lxcapi_attach_run_wait(struct lxc_container *c, const char *suffix, lxc_attach_options_t *options, const char *program, const char * const argv[]) - { - lxc_attach_command_t command; - pid_t pid; -@@ -4240,7 +4241,7 @@ static int do_lxcapi_attach_run_wait(struct lxc_container *c, lxc_attach_options - command.program = (char*)program; - command.argv = (char**)argv; +@@ -62,6 +62,10 @@ + #include "utils.h" + #include "version.h" -- r = lxc_attach(c->name, c->config_path, lxc_attach_run_command, &command, options, &pid, NULL); -+ r = lxc_attach(c->name, c->config_path, suffix, lxc_attach_run_command, &command, options, &pid, NULL); - if (r < 0) { - ERROR("ups"); - return r; -@@ -4249,12 +4250,12 @@ static int do_lxcapi_attach_run_wait(struct lxc_container *c, lxc_attach_options - return lxc_wait_for_pid_status(pid); ++#ifdef HAVE_ISULAD ++#include "exec_commands.h" ++#endif ++ + #if HAVE_OPENSSL + #include + #endif +@@ -5444,6 +5448,50 @@ static bool do_lxcapi_add_terminal_fifo(struct lxc_container *c, const char *in_ } --static int lxcapi_attach_run_wait(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char * const argv[]) -+static int lxcapi_attach_run_wait(struct lxc_container *c, const char *suffix, lxc_attach_options_t *options, const char *program, const char * const argv[]) - { - int ret; - - current_config = c ? c->lxc_conf : NULL; -- ret = do_lxcapi_attach_run_wait(c, options, program, argv); -+ ret = do_lxcapi_attach_run_wait(c, suffix, options, program, argv); - current_config = NULL; - - return ret; -@@ -5109,7 +5110,7 @@ static bool do_lxcapi_restore(struct lxc_container *c, char *directory, bool ver - - WRAP_API_2(bool, lxcapi_restore, char *, bool) - --static int lxcapi_attach_run_waitl(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char *arg, ...) -+static int lxcapi_attach_run_waitl(struct lxc_container *c, const char *suffix, lxc_attach_options_t *options, const char *program, const char *arg, ...) - { - va_list ap; - const char **argv; -@@ -5131,7 +5132,7 @@ static int lxcapi_attach_run_waitl(struct lxc_container *c, lxc_attach_options_t - } - argv[0] = arg; - -- ret = do_lxcapi_attach_run_wait(c, options, program, (const char * const *)argv); -+ ret = do_lxcapi_attach_run_wait(c, suffix, options, program, (const char * const *)argv); - free((void*)argv); - - out: -@@ -5230,6 +5231,51 @@ static bool do_lxcapi_clean_container_resource(struct lxc_container *c, pid_t pi - - WRAP_API_1(bool, lxcapi_clean_container_resource, pid_t) - + WRAP_API_3(bool, lxcapi_add_terminal_fifo, const char *, const char *, const char *) ++ +static bool do_lxcapi_set_terminal_winch(struct lxc_container *c, unsigned int height, unsigned int width) +{ + bool ret = true; @@ -896,75 +896,27 @@ index 9f9cbfc..7ef57f0 100644 +} + +WRAP_API_3(bool, lxcapi_set_exec_terminal_winch, const char *, unsigned int, unsigned int) -+ -+ - /* isulad get coantainer pids */ - static bool do_lxcapi_get_container_pids(struct lxc_container *c, pid_t **pids,size_t *pids_len) - { -@@ -5484,6 +5530,8 @@ static struct lxc_container *do_lxc_container_new(const char *name, const char * - c->clean_container_resource = lxcapi_clean_container_resource; + #endif + + struct lxc_container *lxc_container_new(const char *name, const char *configpath) +@@ -5591,6 +5639,8 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath + c->set_container_info_file = lxcapi_set_container_info_file; + c->set_terminal_init_fifos = lxcapi_set_terminal_default_fifos; c->add_terminal_fifos = lxcapi_add_terminal_fifo; - c->get_container_pids = lxcapi_get_container_pids; + c->set_terminal_winch = lxcapi_set_terminal_winch; + c->set_exec_terminal_winch = lxcapi_set_exec_terminal_winch; - /* isulad add end */ + #endif return c; -diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h -index 608f815..976acf4 100644 ---- a/src/lxc/lxccontainer.h -+++ b/src/lxc/lxccontainer.h -@@ -674,7 +674,7 @@ struct lxc_container { - * - * \return \c 0 on success, \c -1 on error. - */ -- int (*attach)(struct lxc_container *c, lxc_attach_exec_t exec_function, -+ int (*attach)(struct lxc_container *c, const char *suffix, lxc_attach_exec_t exec_function, - void *exec_payload, lxc_attach_options_t *options, pid_t *attached_process); - - /*! -@@ -688,7 +688,7 @@ struct lxc_container { - * \return \c waitpid(2) status of exited process that ran \p - * program, or \c -1 on error. - */ -- int (*attach_run_wait)(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char * const argv[]); -+ int (*attach_run_wait)(struct lxc_container *c, const char *suffix, lxc_attach_options_t *options, const char *program, const char * const argv[]); - - /*! - * \brief Run a program inside a container and wait for it to exit (list variant). -@@ -701,7 +701,7 @@ struct lxc_container { - * \return \c waitpid(2) status of exited process that ran \p - * program, or \c -1 on error. - */ -- int (*attach_run_waitl)(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char *arg, ...); -+ int (*attach_run_waitl)(struct lxc_container *c, const char *suffix, lxc_attach_options_t *options, const char *program, const char *arg, ...); - - /*! - * \brief Create a container snapshot. -@@ -958,6 +958,15 @@ struct lxc_container { - * \return \c true on success, else \c false. - */ - bool (*get_container_pids)(struct lxc_container *c,pid_t **pids,size_t *pids_len); -+ /*! isulad add -+ * \brief An API call to set terminal winch -+ * -+ * \param c Container. -+ * \return \c true on success, else \c false. -+ */ -+ bool (*set_terminal_winch)(struct lxc_container *c, unsigned int height, unsigned int width); -+ -+ bool (*set_exec_terminal_winch)(struct lxc_container *c, const char *suffix, unsigned int height, unsigned int width); - }; - - /*! diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index bccc23d..535f374 100644 +index 1f46d49..39a6718 100644 --- a/src/lxc/terminal.c +++ b/src/lxc/terminal.c -@@ -69,6 +69,32 @@ __attribute__((constructor)) void lxc_terminal_init_global(void) - lxc_list_init(&lxc_ttys); +@@ -187,6 +187,33 @@ static int lxc_terminal_truncate_log_file(struct lxc_terminal *terminal) } + #ifdef HAVE_ISULAD ++ +int lxc_set_terminal_winsz(struct lxc_terminal *terminal, unsigned int height, unsigned int width) +{ + int ret = 0; @@ -991,143 +943,21 @@ index bccc23d..535f374 100644 + return ret; +} + - void lxc_terminal_winsz(int srcfd, int dstfd) - { - int ret; + /* + * isulad: support mult-logfiles + * */ diff --git a/src/lxc/terminal.h b/src/lxc/terminal.h -index 9bb341f..4b5c70e 100644 +index b4160b3..f49142d 100644 --- a/src/lxc/terminal.h +++ b/src/lxc/terminal.h -@@ -313,5 +313,6 @@ extern int lxc_terminal_map_ids(struct lxc_conf *c, - /* isulad: if fd == -1, means delete all the fifos*/ - int lxc_terminal_delete_fifo(int fd, struct lxc_list *list); +@@ -276,6 +276,7 @@ extern int lxc_terminal_map_ids(struct lxc_conf *c, + + #ifdef HAVE_ISULAD int lxc_terminal_add_fifos(struct lxc_conf *conf, const char *fifonames); +int lxc_set_terminal_winsz(struct lxc_terminal *terminal, unsigned int height, unsigned int width); + #endif #endif /* __LXC_TERMINAL_H */ -diff --git a/src/lxc/tools/arguments.h b/src/lxc/tools/arguments.h -index de02aeb..cb7f776 100644 ---- a/src/lxc/tools/arguments.h -+++ b/src/lxc/tools/arguments.h -@@ -71,6 +71,7 @@ struct lxc_arguments { - - /* for lxc-attach */ - int64_t attach_timeout; -+ const char *suffix; /* isulad add, suffix used for connect with parent of execed process*/ - - /* for lxc-console */ - unsigned int ttynum; -@@ -191,7 +192,7 @@ struct lxc_arguments { - #define OPT_DISABLE_PTY OPT_USAGE - 13 - #define OPT_OPEN_STDIN OPT_USAGE - 14 - #define OPT_ATTACH_TIMEOUT OPT_USAGE - 15 -- -+#define OPT_ATTACH_SUFFIX OPT_USAGE - 16 - /* isulad add end*/ - - extern int lxc_arguments_parse(struct lxc_arguments *args, int argc, -diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c -index 0d40155..56684e7 100644 ---- a/src/lxc/tools/lxc_attach.c -+++ b/src/lxc/tools/lxc_attach.c -@@ -82,6 +82,7 @@ static const struct option my_longopts[] = { - {"out-fifo", required_argument, 0, OPT_OUTPUT_FIFO}, - {"err-fifo", required_argument, 0, OPT_STDERR_FIFO}, - {"timeout", required_argument, 0, OPT_ATTACH_TIMEOUT}, -+ {"suffix", required_argument, 0, OPT_ATTACH_SUFFIX}, - LXC_COMMON_OPTIONS - }; - -@@ -287,6 +288,9 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) - } - args->attach_timeout = (unsigned int)atoll(arg); - break; -+ case OPT_ATTACH_SUFFIX: -+ args->suffix = arg; -+ break; - } - - return 0; -@@ -351,7 +355,7 @@ static int lxc_attach_create_log_file(const char *log_file) - } - - /*isulad: attach with terminal*/ --static int do_attach_foreground(struct lxc_container *c, lxc_attach_command_t *command, -+static int do_attach_foreground(struct lxc_container *c, const char *suffix, lxc_attach_command_t *command, - lxc_attach_options_t *attach_options, - char **errmsg) - { -@@ -361,9 +365,9 @@ static int do_attach_foreground(struct lxc_container *c, lxc_attach_command_t *c - int signal; - - if (command->program) -- ret = c->attach(c, lxc_attach_run_command, command, attach_options, &pid); -+ ret = c->attach(c, suffix, lxc_attach_run_command, command, attach_options, &pid); - else -- ret = c->attach(c, lxc_attach_run_shell, NULL, attach_options, &pid); -+ ret = c->attach(c, suffix, lxc_attach_run_shell, NULL, attach_options, &pid); - if (ret < 0) - goto out; - -@@ -399,7 +403,7 @@ static void close_msg_pipe(int *errpipe) - } - - /*isulad: attach without terminal in background */ --static int do_attach_background(struct lxc_container *c, lxc_attach_command_t *command, -+static int do_attach_background(struct lxc_container *c, const char *suffix, lxc_attach_command_t *command, - lxc_attach_options_t *attach_options, - char **errmsg) - { -@@ -458,9 +462,9 @@ static int do_attach_background(struct lxc_container *c, lxc_attach_command_t *c - setsid(); - - if (command->program) -- ret = c->attach(c, lxc_attach_run_command, command, attach_options, &pid); -+ ret = c->attach(c, suffix, lxc_attach_run_command, command, attach_options, &pid); - else -- ret = c->attach(c, lxc_attach_run_shell, NULL, attach_options, &pid); -+ ret = c->attach(c, suffix, lxc_attach_run_shell, NULL, attach_options, &pid); - if (ret < 0) { - if (c->lxc_conf->errmsg) - lxc_write_error_message(msgpipe[1], "%s", c->lxc_conf->errmsg); -@@ -580,9 +584,9 @@ int main(int argc, char *argv[]) - - /* isulad: add do attach background */ - if (attach_options.attach_flags & LXC_ATTACH_TERMINAL) -- wexit = do_attach_foreground(c, &command, &attach_options, &errmsg); -+ wexit = do_attach_foreground(c, my_args.suffix, &command, &attach_options, &errmsg); - else -- wexit = do_attach_background(c, &command, &attach_options, &errmsg); -+ wexit = do_attach_background(c, my_args.suffix, &command, &attach_options, &errmsg); - - if (errmsg) { - fprintf(stderr, "%s:%s:%s:%d starting container process caused \"%s\"", c->name, -diff --git a/src/lxc/tools/lxc_copy.c b/src/lxc/tools/lxc_copy.c -index 954f1dd..b4e2b8f 100644 ---- a/src/lxc/tools/lxc_copy.c -+++ b/src/lxc/tools/lxc_copy.c -@@ -467,7 +467,7 @@ static int do_clone_ephemeral(struct lxc_container *c, - goto destroy_and_put; - - if (arg->daemonize && arg->argc) { -- ret = clone->attach_run_wait(clone, &attach_options, arg->argv[0], (const char *const *)arg->argv); -+ ret = clone->attach_run_wait(clone, NULL, &attach_options, arg->argv[0], (const char *const *)arg->argv); - if (ret < 0) - goto destroy_and_put; - clone->shutdown(clone, -1); -diff --git a/src/lxc/tools/lxc_ls.c b/src/lxc/tools/lxc_ls.c -index e261c7b..9fd1bf3 100644 ---- a/src/lxc/tools/lxc_ls.c -+++ b/src/lxc/tools/lxc_ls.c -@@ -544,7 +544,7 @@ static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args, - - /* fork(): Attach to the namespace of the container and - * run ls_get() in it which is called in ls_get_wrapper(). */ -- check = c->attach(c, ls_get_wrapper, &wargs, &aopt, &out); -+ check = c->attach(c, NULL, ls_get_wrapper, &wargs, &aopt, &out); - /* close the socket */ - close(wargs.pipefd[1]); - -- 1.8.3.1 diff --git a/0020-confile-decode-escape-charactors-in-config.patch b/0020-confile-decode-escape-charactors-in-config.patch new file mode 100644 index 0000000000000000000000000000000000000000..e0c786ee005f62b120654c6cece0041de6b32c3d --- /dev/null +++ b/0020-confile-decode-escape-charactors-in-config.patch @@ -0,0 +1,104 @@ +From 200cc2a1e95c0c0f17cf14f16d8ceb60ca3628c0 Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Tue, 14 Apr 2020 16:16:14 +0800 +Subject: [PATCH 20/49] confile: decode escape charactors in config + +Signed-off-by: LiFeng +--- + src/lxc/confile.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 62 insertions(+) + +diff --git a/src/lxc/confile.c b/src/lxc/confile.c +index bf0fdf0..a28c5da 100644 +--- a/src/lxc/confile.c ++++ b/src/lxc/confile.c +@@ -2732,6 +2732,54 @@ struct parse_line_conf { + bool from_include; + }; + ++#ifdef HAVE_ISULAD ++// escape_string_decode compress some escape characters ++static char *escape_string_decode(const char *src) ++{ ++ size_t src_end = 0; ++ size_t dst_end = 0; ++ size_t len = 0; ++ char *dst = NULL; ++ ++ if (src == NULL) { ++ return NULL; ++ } ++ ++ len = strlen(src); ++ if (len == 0) { ++ return NULL; ++ } ++ ++ dst = calloc(1, len + 1); ++ if (dst == NULL) { ++ ERROR("Out of memory"); ++ return NULL; ++ } ++ ++ while(src_end < len) { ++ if (src[src_end] == '\\') { ++ switch (src[++src_end]) ++ { ++ case 'r': dst[dst_end] = '\r'; break; ++ case 'n': dst[dst_end] = '\n'; break; ++ case 'f': dst[dst_end] = '\f'; break; ++ case 'b': dst[dst_end] = '\b'; break; ++ case 't': dst[dst_end] = '\t'; break; ++ case '\\': dst[dst_end] = '\\'; break; ++ // default do not decode ++ default: dst[dst_end++] = '\\'; dst[dst_end] = src[src_end]; break; ++ } ++ } else { ++ dst[dst_end] = src[src_end]; ++ } ++ dst_end++; ++ src_end++; ++ } ++ ++ return dst; ++} ++#endif ++ + static int parse_line(char *buffer, void *data) + { + char *dot, *key, *line, *linep, *value; +@@ -2740,6 +2788,9 @@ static int parse_line(char *buffer, void *data) + int ret = 0; + char *dup = buffer; + struct parse_line_conf *plc = data; ++#ifdef HAVE_ISULAD ++ char *value_decode = NULL; ++#endif + + /* If there are newlines in the config file we should keep them. */ + empty_line = lxc_is_line_empty(dup); +@@ -2806,10 +2857,21 @@ static int parse_line(char *buffer, void *data) + goto on_error; + } + ++#ifdef HAVE_ISULAD ++ value_decode = escape_string_decode(value); ++ if (value_decode == NULL) { ++ ERROR("Value %s decode failed", value); ++ } ++ ret = config->set(key, value_decode ? value_decode: value, plc->conf, NULL); ++#else + ret = config->set(key, value, plc->conf, NULL); ++#endif + + on_error: + free(linep); ++#ifdef HAVE_ISULAD ++ free(value_decode); ++#endif + + return ret; + } +-- +1.8.3.1 + diff --git a/0020-fix-log-error-when-symlink-subcgroup.patch b/0020-fix-log-error-when-symlink-subcgroup.patch deleted file mode 100644 index 86350fe8b55c34b7b487c1d163f3d1191e92b844..0000000000000000000000000000000000000000 --- a/0020-fix-log-error-when-symlink-subcgroup.patch +++ /dev/null @@ -1,44 +0,0 @@ -From a4a3b0c8f6a33676c62729ab7fc1e7d6f54536b8 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Mon, 14 Jan 2019 15:33:12 +0800 -Subject: [PATCH 020/140] fix log error when symlink subcgroup - -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgfsng.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index 705985f..7f2a200 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -1736,21 +1736,21 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, - char **mc; - for (mc = merged; *mc; mc++) { - char *token; -- char *merge = must_copy_string(*mc); -- lxc_iterate_parts(token, merge, ",") { -+ char *copy = must_copy_string(*mc); -+ lxc_iterate_parts(token, copy, ",") { - int mret; - char *link; - link = must_make_path(tmpfspath, token, NULL); - mret = symlink(*mc, link); - if (mret < 0 && errno != EEXIST) { -- SYSERROR("Failed to create link %s for target %s", link, merge); -- free(merge); -+ SYSERROR("Failed to create link %s for target %s", link, *mc); -+ free(copy); - free(link); - goto on_error; - } - free(link); - } -- free(merge); -+ free(copy); - } - } - --- -1.8.3.1 - diff --git a/0070-lxc-signal-all-process-for-shared-container-when-con.patch b/0021-cgroup-add-retry-for-destory-cgroups.patch similarity index 33% rename from 0070-lxc-signal-all-process-for-shared-container-when-con.patch rename to 0021-cgroup-add-retry-for-destory-cgroups.patch index 89aa437b834df667851d18bb1dfde9c639b8cbcd..0302337d28a9818a9da0495fdb0c7ea65a5264b4 100644 --- a/0070-lxc-signal-all-process-for-shared-container-when-con.patch +++ b/0021-cgroup-add-retry-for-destory-cgroups.patch @@ -1,37 +1,171 @@ -From 38b34aa2e20484616c40dba507f1c7a36afb56c2 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Thu, 21 Mar 2019 17:21:44 +0800 -Subject: [PATCH 070/140] lxc: signal all process for shared container when - container init exited +From 4814d02fd3d364b599707b3cb298a8cc945033f9 Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Tue, 14 Apr 2020 17:07:24 +0800 +Subject: [PATCH 21/49] cgroup: add retry for destory cgroups -Signed-off-by: tanyifeng Signed-off-by: LiFeng --- - src/lxc/cgroups/cgfsng.c | 2 +- - src/lxc/start.c | 332 +++++++++++++++++++++++++---------------------- - 2 files changed, 175 insertions(+), 159 deletions(-) + src/lxc/cgroups/cgfsng.c | 105 +++++++++++++++++++++++++ + src/lxc/cgroups/cgroup.h | 4 + + src/lxc/start.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++- + 3 files changed, 303 insertions(+), 1 deletion(-) diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index ab7ca35..5ceb06b 100644 +index 881dd39..00270ab 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c -@@ -1056,7 +1056,7 @@ static int cgroup_rmdir(struct hierarchy **hierarchies, +@@ -1000,6 +1000,106 @@ static int cgroup_tree_remove_wrapper(void *data) + return cgroup_tree_remove(arg->hierarchies, arg->container_cgroup); + } - ret = recursive_destroy(h->container_full_path); - if (ret < 0) { -- SYSERROR("Failed to destroy \"%s\"", h->container_full_path); -+ SYSWARN("Failed to destroy \"%s\"", h->container_full_path); - return -1; - } ++#ifdef HAVE_ISULAD ++ ++static int isulad_cgroup_tree_remove(struct hierarchy **hierarchies, ++ const char *container_cgroup) ++{ ++ if (!container_cgroup || !hierarchies) ++ return 0; ++ ++ for (int i = 0; hierarchies[i]; i++) { ++ struct hierarchy *h = hierarchies[i]; ++ int ret; ++ ++ if (!h->container_full_path) ++ continue; ++ ++ ret = lxc_rm_rf(h->container_full_path); ++ if (ret < 0) { ++ SYSERROR("Failed to destroy \"%s\"", h->container_full_path); ++ return -1; ++ } ++ ++ free_disarm(h->container_full_path); ++ } ++ ++ return 0; ++} ++ ++static int isulad_cgroup_tree_remove_wrapper(void *data) ++{ ++ struct generic_userns_exec_data *arg = data; ++ uid_t nsuid = (arg->conf->root_nsuid_map != NULL) ? 0 : arg->conf->init_uid; ++ gid_t nsgid = (arg->conf->root_nsgid_map != NULL) ? 0 : arg->conf->init_gid; ++ int ret; ++ ++ if (!lxc_setgroups(0, NULL) && errno != EPERM) ++ return log_error_errno(-1, errno, "Failed to setgroups(0, NULL)"); ++ ++ ret = setresgid(nsgid, nsgid, nsgid); ++ if (ret < 0) ++ return log_error_errno(-1, errno, "Failed to setresgid(%d, %d, %d)", ++ (int)nsgid, (int)nsgid, (int)nsgid); ++ ++ ret = setresuid(nsuid, nsuid, nsuid); ++ if (ret < 0) ++ return log_error_errno(-1, errno, "Failed to setresuid(%d, %d, %d)", ++ (int)nsuid, (int)nsuid, (int)nsuid); ++ ++ return isulad_cgroup_tree_remove(arg->hierarchies, arg->container_cgroup); ++} ++ ++__cgfsng_ops static bool isulad_cgfsng_payload_destroy(struct cgroup_ops *ops, ++ struct lxc_handler *handler) ++{ ++ int ret; ++ ++ if (!ops) { ++ ERROR("Called with uninitialized cgroup operations"); ++ return false; ++ } ++ ++ if (!ops->hierarchies) { ++ return false; ++ } ++ ++ if (!handler) { ++ ERROR("Called with uninitialized handler"); ++ return false; ++ } ++ ++ if (!handler->conf) { ++ ERROR("Called with uninitialized conf"); ++ return false; ++ } ++ ++#ifdef HAVE_STRUCT_BPF_CGROUP_DEV_CTX ++ ret = bpf_program_cgroup_detach(handler->conf->cgroup2_devices); ++ if (ret < 0) ++ WARN("Failed to detach bpf program from cgroup"); ++#endif ++ ++ if (handler->conf && !lxc_list_empty(&handler->conf->id_map)) { ++ struct generic_userns_exec_data wrap = { ++ .conf = handler->conf, ++ .container_cgroup = ops->container_cgroup, ++ .hierarchies = ops->hierarchies, ++ .origuid = 0, ++ }; ++ ret = userns_exec_1(handler->conf, isulad_cgroup_tree_remove_wrapper, ++ &wrap, "cgroup_tree_remove_wrapper"); ++ } else { ++ ret = isulad_cgroup_tree_remove(ops->hierarchies, ops->container_cgroup); ++ } ++ if (ret < 0) { ++ SYSWARN("Failed to destroy cgroups"); ++ return false; ++ } ++ ++ return true; ++} ++#else + __cgfsng_ops static void cgfsng_payload_destroy(struct cgroup_ops *ops, + struct lxc_handler *handler) + { +@@ -1044,6 +1144,7 @@ __cgfsng_ops static void cgfsng_payload_destroy(struct cgroup_ops *ops, + if (ret < 0) + SYSWARN("Failed to destroy cgroups"); + } ++#endif + + #ifdef HAVE_ISULAD + __cgfsng_ops static void cgfsng_monitor_destroy(struct cgroup_ops *ops, +@@ -4107,7 +4208,11 @@ struct cgroup_ops *cgfsng_ops_init(struct lxc_conf *conf) + return NULL; + cgfsng_ops->data_init = cgfsng_data_init; ++#ifdef HAVE_ISULAD ++ cgfsng_ops->payload_destroy = isulad_cgfsng_payload_destroy; ++#else + cgfsng_ops->payload_destroy = cgfsng_payload_destroy; ++#endif + cgfsng_ops->monitor_destroy = cgfsng_monitor_destroy; + cgfsng_ops->monitor_create = cgfsng_monitor_create; + cgfsng_ops->monitor_enter = cgfsng_monitor_enter; +diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h +index dcdc76b..a9048c4 100644 +--- a/src/lxc/cgroups/cgroup.h ++++ b/src/lxc/cgroups/cgroup.h +@@ -144,7 +144,11 @@ struct cgroup_ops { + cgroup_layout_t cgroup_layout; + + int (*data_init)(struct cgroup_ops *ops, struct lxc_conf *conf); ++#ifdef HAVE_ISULAD ++ bool (*payload_destroy)(struct cgroup_ops *ops, struct lxc_handler *handler); ++#else + void (*payload_destroy)(struct cgroup_ops *ops, struct lxc_handler *handler); ++#endif + void (*monitor_destroy)(struct cgroup_ops *ops, struct lxc_handler *handler); + bool (*monitor_create)(struct cgroup_ops *ops, struct lxc_handler *handler); + bool (*monitor_enter)(struct cgroup_ops *ops, struct lxc_handler *handler); diff --git a/src/lxc/start.c b/src/lxc/start.c -index 1c9eb0a..b14e46f 100644 +index 800f884..0942c31 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c -@@ -941,6 +941,162 @@ out_close_maincmd_fd: +@@ -879,6 +879,170 @@ out_restore_sigmask: return -1; } ++#ifdef HAVE_ISULAD +void trim_line(char *s) +{ + size_t len; @@ -46,6 +180,7 @@ index 1c9eb0a..b14e46f 100644 + FILE *f; + char *line = NULL; + size_t sz = 0; ++ pid_t *tmp_pids = NULL; + + f = fopen_cloexec(path, "r"); + if (!f) @@ -55,7 +190,16 @@ index 1c9eb0a..b14e46f 100644 + pid_t pid; + trim_line(line); + pid = (pid_t)atoll(line); -+ *pids = realloc(*pids, sizeof(pid_t) * (*len + 1)); ++ if (lxc_mem_realloc((void **)&tmp_pids, sizeof(pid_t) * (*len + 1), *pids, sizeof(pid_t) * (*len)) != 0) { ++ free(*pids); ++ *pids = NULL; ++ ERROR("out of memory"); ++ free(line); ++ fclose(f); ++ return -1; ++ } ++ *pids = tmp_pids; ++ + (*pids)[*len] = pid; + (*len)++; + } @@ -67,13 +211,13 @@ index 1c9eb0a..b14e46f 100644 + +static int _recursive_read_cgroup_procs(const char *dirpath, pid_t **pids, size_t *len) +{ -+ struct dirent *direntp; -+ DIR *dir; ++ struct dirent *direntp = NULL; ++ DIR *dir = NULL; + int ret, failed = 0; + char pathname[PATH_MAX]; + + dir = opendir(dirpath); -+ if (!dir && errno != ENOENT) { ++ if (dir == NULL) { + WARN("Failed to open \"%s\"", dirpath); + return 0; + } @@ -83,7 +227,7 @@ index 1c9eb0a..b14e46f 100644 + int rc; + + if (!strcmp(direntp->d_name, ".") || -+ !strcmp(direntp->d_name, "..")) ++ !strcmp(direntp->d_name, "..")) + continue; + + rc = snprintf(pathname, PATH_MAX, "%s/%s", dirpath, direntp->d_name); @@ -123,18 +267,14 @@ index 1c9eb0a..b14e46f 100644 + +int get_all_pids(struct cgroup_ops *cg_ops, pid_t **pids, size_t *len) +{ -+ char *devices_path = NULL; -+ int ret; ++ const char *devices_path = NULL; + -+ devices_path = must_make_path("/sys/fs/cgroup", "devices", cg_ops->container_cgroup, NULL); ++ devices_path = cg_ops->get_cgroup_full_path(cg_ops, "devices"); + if (!file_exists(devices_path)) { -+ free(devices_path); + return 0; + } + -+ ret = _recursive_read_cgroup_procs(devices_path, pids, len); -+ free(devices_path); -+ return ret; ++ return _recursive_read_cgroup_procs(devices_path, pids, len); +} + +static int set_cgroup_freezer(struct cgroup_ops *cg_ops, const char *value) @@ -142,7 +282,7 @@ index 1c9eb0a..b14e46f 100644 + char *fullpath; + int ret; + -+ fullpath = must_make_path("/sys/fs/cgroup", "freezer", cg_ops->container_cgroup, "freezer.state", NULL); ++ fullpath = must_make_path(cg_ops->get_cgroup_full_path(cg_ops, "freezer"), "freezer.state", NULL); + ret = lxc_write_to_file(fullpath, value, strlen(value), false, 0666); + free(fullpath); + return ret; @@ -187,214 +327,61 @@ index 1c9eb0a..b14e46f 100644 + + free(pids); +} ++#endif + - void lxc_fini(const char *name, struct lxc_handler *handler) + void lxc_end(struct lxc_handler *handler) { - int i, ret; -@@ -949,6 +1105,8 @@ void lxc_fini(const char *name, struct lxc_handler *handler) - char *namespaces[LXC_NS_MAX + 1]; - size_t namespace_count = 0; - struct cgroup_ops *cgroup_ops = handler->cgroup_ops; -+ int retry_count = 0; -+ int max_retry = 10; + int ret; +@@ -952,11 +1116,37 @@ void lxc_end(struct lxc_handler *handler) - /* The STOPPING state is there for future cleanup code which can take - * awhile. -@@ -1013,7 +1171,21 @@ void lxc_fini(const char *name, struct lxc_handler *handler) - while (namespace_count--) - free(namespaces[namespace_count]); + lsm_process_cleanup(handler->conf, handler->lxcpath); -- cgroup_ops->destroy(cgroup_ops, handler); -+ // if we shared pid namespace with others, should kill all processes within container cgroup -+ if (handler->conf->ns_share[LXC_NS_PID] != NULL) { -+ TRACE("Trying to kill all subprocess"); -+ signal_all_processes(handler); -+ TRACE("Finished kill all subprocess"); ++#ifdef HAVE_ISULAD ++ // close maincmd fd before destroy cgroup for isulad ++ if (handler->conf->reboot == REBOOT_NONE) { ++ /* For all new state clients simply close the command socket. ++ * This will inform all state clients that the container is ++ * STOPPED and also prevents a race between a open()/close() on ++ * the command socket causing a new process to get ECONNREFUSED ++ * because we haven't yet closed the command socket. ++ */ ++ close_prot_errno_disarm(handler->conf->maincmd_fd); ++ TRACE("Closed command socket"); + } ++ int retry_count = 0; ++ int max_retry = 10; +retry: -+ if (!cgroup_ops->destroy(cgroup_ops, handler)) { -+ if (retry_count < max_retry) { -+ usleep(100 * 1000); /* 100 millisecond */ -+ retry_count++; -+ goto retry; ++ if (cgroup_ops != NULL && !cgroup_ops->payload_destroy(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); + } - ++#else + if (cgroup_ops) { + cgroup_ops->payload_destroy(cgroup_ops, handler); + cgroup_ops->monitor_destroy(cgroup_ops, handler); + } +- if (handler->conf->reboot == REBOOT_NONE) { /* For all new state clients simply close the command socket. -@@ -2494,162 +2666,6 @@ static void clean_resource_set_env(struct lxc_handler *handler) - /* End of environment variable setup for hooks. */ - } - --void trim_line(char *s) --{ -- size_t len; -- -- len = strlen(s); -- while ((len > 1) && (s[len - 1] == '\n')) -- s[--len] = '\0'; --} -- --static int _read_procs_file(const char *path, pid_t **pids, size_t *len) --{ -- FILE *f; -- char *line = NULL; -- size_t sz = 0; -- -- f = fopen_cloexec(path, "r"); -- if (!f) -- return -1; -- -- while (getline(&line, &sz, f) != -1) { -- pid_t pid; -- trim_line(line); -- pid = (pid_t)atoll(line); -- *pids = realloc(*pids, sizeof(pid_t) * (*len + 1)); -- (*pids)[*len] = pid; -- (*len)++; -- } -- -- free(line); -- fclose(f); -- return 0; --} -- --static int _recursive_read_cgroup_procs(const char *dirpath, pid_t **pids, size_t *len) --{ -- struct dirent *direntp; -- DIR *dir; -- int ret, failed = 0; -- char pathname[PATH_MAX]; -- -- dir = opendir(dirpath); -- if (!dir && errno != ENOENT) { -- WARN("Failed to open \"%s\"", dirpath); -- return 0; -- } -- -- while ((direntp = readdir(dir))) { -- struct stat mystat; -- int rc; -- -- if (!strcmp(direntp->d_name, ".") || -- !strcmp(direntp->d_name, "..")) -- continue; -- -- rc = snprintf(pathname, PATH_MAX, "%s/%s", dirpath, direntp->d_name); -- if (rc < 0 || rc >= PATH_MAX) { -- failed = 1; -- continue; -- } -- -- if (strcmp(direntp->d_name, "cgroup.procs") == 0) { -- if (_read_procs_file(pathname, pids, len)) { -- failed = 1; -- -- } -- continue; -- } -- -- ret = lstat(pathname, &mystat); -- if (ret) { -- failed = 1; -- continue; -- } -- -- if (S_ISDIR(mystat.st_mode)) { -- if (_recursive_read_cgroup_procs(pathname, pids, len) < 0) -- failed = 1; -- } -- } -- -- ret = closedir(dir); -- if (ret) { -- WARN("Failed to close directory \"%s\"", dirpath); -- failed = 1; -- } -- -- return failed ? -1 : 0; --} -- --int get_all_pids(struct cgroup_ops *cg_ops, pid_t **pids, size_t *len) --{ -- char *devices_path = NULL; -- int ret; -- -- devices_path = must_make_path("/sys/fs/cgroup", "devices", cg_ops->container_cgroup, NULL); -- if (!file_exists(devices_path)) { -- free(devices_path); -- return 0; -- } -- -- ret = _recursive_read_cgroup_procs(devices_path, pids, len); -- free(devices_path); -- return ret; --} -- --static int set_cgroup_freezer(struct cgroup_ops *cg_ops, const char *value) --{ -- char *fullpath; -- int ret; -- -- fullpath = must_make_path("/sys/fs/cgroup", "freezer", cg_ops->container_cgroup, "freezer.state", NULL); -- ret = lxc_write_to_file(fullpath, value, strlen(value), false, 0666); -- free(fullpath); -- return ret; --} -- --/* isulad: kill all process in container cgroup path */ --static void signal_all_processes(struct lxc_handler *handler) --{ -- int ret; -- struct cgroup_ops *cg_ops = handler->cgroup_ops; -- pid_t *pids = NULL; -- size_t len = 0, i; -- -- ret = set_cgroup_freezer(cg_ops, "FROZEN"); -- if (ret < 0 && errno != ENOENT) { -- WARN("cgroup_set frozen failed"); -- } -- -- ret = get_all_pids(cg_ops, &pids, &len); -- if (ret < 0) { -- WARN("failed to get all pids"); -- } -- -- for (i = 0; i < len; i++) { -- ret = kill(pids[i], SIGKILL); -- if (ret < 0 && errno != ESRCH) { -- WARN("Can not kill process (pid=%d) with SIGKILL for container %s", pids[i], handler->name); -- } -- } -- -- ret = set_cgroup_freezer(cg_ops, "THAWED"); -- if (ret < 0 && errno != ENOENT) { -- WARN("cgroup_set thawed failed"); -- } -- -- for (i = 0; i < len; i++) { -- ret = lxc_wait_for_pid_status(pids[i]); -- if (ret < 0 && errno != ECHILD) { -- WARN("Failed to wait pid %d for container %s: %s", pids[i], handler->name, strerror(errno)); -- } -- } -- -- free(pids); --} -- - /*isulad: do_lxcapi_clean_resource */ - int do_lxcapi_clean_resource(char *name, char *lxcpath, struct lxc_conf *conf, pid_t pid) - { -@@ -2687,7 +2703,7 @@ retry: - retry_count++; - goto retry; - } -- ERROR("Failed to destroy cgroup for container \"%s\".", handler->name); -+ SYSERROR("Failed to destroy cgroup path for container: \"%s\"", handler->name); - ret = -1; - } + * This will inform all state clients that the container is +@@ -966,7 +1156,10 @@ void lxc_end(struct lxc_handler *handler) + */ + close_prot_errno_disarm(handler->conf->maincmd_fd); + TRACE("Closed command socket"); ++ } ++#endif ++ if (handler->conf->reboot == REBOOT_NONE) { + /* This function will try to connect to the legacy lxc-monitord + * state server and only exists for backwards compatibility. + */ -- 1.8.3.1 diff --git a/0021-lxc-attch-add-error-message.patch b/0021-lxc-attch-add-error-message.patch deleted file mode 100644 index 7c0b13194ea7f080559bfa4c6c549e14ec7149a8..0000000000000000000000000000000000000000 --- a/0021-lxc-attch-add-error-message.patch +++ /dev/null @@ -1,374 +0,0 @@ -From c26c254376f73d9b43dd1747746a2bc265a85bb3 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Mon, 14 Jan 2019 04:29:40 -0500 -Subject: [PATCH 021/140] lxc-attch: add error message - -Signed-off-by: LiFeng ---- - src/lxc/attach.c | 49 +++++++++++++++++++++++++++++++++++++++++----- - src/lxc/attach.h | 4 ++-- - src/lxc/attach_options.h | 6 +++--- - src/lxc/conf.c | 27 +++++++++++++++++++++---- - src/lxc/conf.h | 3 +++ - src/lxc/lxccontainer.c | 4 ++-- - src/lxc/tools/lxc_attach.c | 8 ++++---- - src/lxc/tools/lxc_ls.c | 4 ++-- - src/lxc/utils.c | 21 ++++++++++++++++++++ - src/lxc/utils.h | 1 + - 10 files changed, 105 insertions(+), 22 deletions(-) - -diff --git a/src/lxc/attach.c b/src/lxc/attach.c -index 1886bde..570b9d0 100644 ---- a/src/lxc/attach.c -+++ b/src/lxc/attach.c -@@ -757,10 +757,15 @@ static int attach_child_main(struct attach_clone_payload *payload) - gid_t ns_root_gid = 0; - lxc_attach_options_t* options = payload->options; - struct lxc_proc_context_info* init_ctx = payload->init_ctx; -+ int msg_fd = -1; - bool needs_lsm = (options->namespaces & CLONE_NEWNS) && - (options->attach_flags & LXC_ATTACH_LSM) && - init_ctx->lsm_label; - -+ /*isulad: record errpipe fd*/ -+ msg_fd = init_ctx->container->lxc_conf->errpipe[1]; -+ init_ctx->container->lxc_conf->errpipe[1] = -1; -+ - /* A description of the purpose of this functionality is provided in the - * lxc-attach(1) manual page. We have to remount here and not in the - * parent process, otherwise /proc may not properly reflect the new pid -@@ -980,7 +985,7 @@ static int attach_child_main(struct attach_clone_payload *payload) - goto on_error; - - /* We're done, so we can now do whatever the user intended us to do. */ -- _exit(payload->exec_function(payload->exec_payload)); -+ _exit(payload->exec_function(payload->exec_payload, msg_fd)); - - on_error: - lxc_put_attach_clone_payload(payload); -@@ -1085,7 +1090,7 @@ static inline void lxc_attach_terminal_close_log(struct lxc_terminal *terminal) - - int lxc_attach(const char *name, const char *lxcpath, - lxc_attach_exec_t exec_function, void *exec_payload, -- lxc_attach_options_t *options, pid_t *attached_process) -+ lxc_attach_options_t *options, pid_t *attached_process, char **err_msg) - { - int i, ret, status; - int ipc_sockets[2]; -@@ -1268,6 +1273,15 @@ int lxc_attach(const char *name, const char *lxcpath, - return -1; - } - -+ -+ /* isulad: pipdfd for get error message of child or grandchild process. */ -+ if (pipe2(conf->errpipe, O_CLOEXEC) != 0) { -+ SYSERROR("Failed to init errpipe"); -+ free(cwd); -+ lxc_proc_put_context_info(init_ctx); -+ return -1; -+ } -+ - /* Create intermediate subprocess, two reasons: - * 1. We can't setns() in the child itself, since we want to make - * sure we are properly attached to the pidns. -@@ -1291,6 +1305,11 @@ int lxc_attach(const char *name, const char *lxcpath, - /* close unneeded file descriptors */ - close(ipc_sockets[1]); - free(cwd); -+ -+ /* isulad: close errpipe */ -+ close(conf->errpipe[1]); -+ conf->errpipe[1] = -1; -+ - lxc_proc_close_ns_fd(init_ctx); - if (options->attach_flags & LXC_ATTACH_TERMINAL) - lxc_attach_terminal_close_slave(&terminal); -@@ -1399,6 +1418,19 @@ int lxc_attach(const char *name, const char *lxcpath, - - *attached_process = attached_pid; - -+ /* isulad: read error msg from pipe */ -+ ssize_t size_read; -+ char errbuf[BUFSIZ + 1] = {0}; -+ -+ size_read = read(conf->errpipe[0], errbuf, BUFSIZ); -+ if (size_read > 0) { -+ if (err_msg) -+ *err_msg = strdup(errbuf); -+ if (!(*err_msg)) -+ ERROR("Out of memory"); -+ goto close_mainloop; -+ } -+ - /* Now shut down communication with child, we're done. */ - shutdown(ipc_sockets[0], SHUT_RDWR); - close(ipc_sockets[0]); -@@ -1439,7 +1471,11 @@ int lxc_attach(const char *name, const char *lxcpath, - - /* close unneeded file descriptors */ - close(ipc_sockets[0]); -- ipc_sockets[0] = -EBADF; -+ ipc_sockets[0] = -EBADF;\ -+ -+ /* isulad: close errpipe */ -+ close(conf->errpipe[0]); -+ conf->errpipe[0] = -1; - - if (options->attach_flags & LXC_ATTACH_TERMINAL) { - lxc_attach_terminal_close_master(&terminal); -@@ -1539,7 +1575,7 @@ int lxc_attach(const char *name, const char *lxcpath, - _exit(0); - } - --int lxc_attach_run_command(void *payload) -+int lxc_attach_run_command(void *payload, int msg_fd) - { - int ret = -1; - lxc_attach_command_t *cmd = payload; -@@ -1556,11 +1592,14 @@ int lxc_attach_run_command(void *payload) - } - } - -+ /* isulad: write errorm messages */ -+ lxc_write_error_message(msg_fd, "exec: \"%s\": %s", cmd->program, strerror(errno)); -+ - SYSERROR("Failed to exec \"%s\"", cmd->program); - return ret; - } - --int lxc_attach_run_shell(void* payload) -+int lxc_attach_run_shell(void* payload, int msg_fd) - { - uid_t uid; - struct passwd pwent; -diff --git a/src/lxc/attach.h b/src/lxc/attach.h -index 4bf9578..e62b98b 100644 ---- a/src/lxc/attach.h -+++ b/src/lxc/attach.h -@@ -42,7 +42,7 @@ struct lxc_proc_context_info { - }; - - extern int lxc_attach(const char *name, const char *lxcpath, -- lxc_attach_exec_t exec_function, void *exec_payload, -- lxc_attach_options_t *options, pid_t *attached_process); -+ lxc_attach_exec_t exec_function, void *exec_payload, -+ lxc_attach_options_t *options, pid_t *attached_process, char **err_msg); - - #endif /* __LXC_ATTACH_H */ -diff --git a/src/lxc/attach_options.h b/src/lxc/attach_options.h -index 081618c..7b0a8cb 100644 ---- a/src/lxc/attach_options.h -+++ b/src/lxc/attach_options.h -@@ -71,7 +71,7 @@ enum { - * - * \return Function should return \c 0 on success, and any other value to denote failure. - */ --typedef int (*lxc_attach_exec_t)(void* payload); -+typedef int (*lxc_attach_exec_t)(void* payload, int msg_fd); - - /*! - * LXC attach options for \ref lxc_container \c attach(). -@@ -173,7 +173,7 @@ typedef struct lxc_attach_command_t { - * - * \return \c -1 on error, exit code of lxc_attach_command_t program on success. - */ --extern int lxc_attach_run_command(void* payload); -+extern int lxc_attach_run_command(void* payload, int msg_fd); - - /*! - * \brief Run a shell command in the container. -@@ -182,7 +182,7 @@ extern int lxc_attach_run_command(void* payload); - * - * \return Exit code of shell. - */ --extern int lxc_attach_run_shell(void* payload); -+extern int lxc_attach_run_shell(void* payload, int msg_fd); - - #ifdef __cplusplus - } -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 537f956..8d8230f 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -2803,10 +2803,6 @@ struct lxc_conf *lxc_conf_init(void) - new->console.slave = -1; - new->console.name[0] = '\0'; - memset(&new->console.ringbuf, 0, sizeof(struct lxc_ringbuf)); -- /* isulad init console fifos */ -- new->console.init_fifo[0] = NULL; -- new->console.init_fifo[1] = NULL; -- lxc_list_init(&new->console.fifos); - new->maincmd_fd = -1; - new->nbd_idx = -1; - new->rootfs.mount = strdup(default_rootfs_mount); -@@ -2851,6 +2847,14 @@ struct lxc_conf *lxc_conf_init(void) - lxc_list_init(&new->rootfs.maskedpaths); - lxc_list_init(&new->rootfs.ropaths); - new->exit_fd = -1; -+ /* isulad init console fifos */ -+ new->console.init_fifo[0] = NULL; -+ new->console.init_fifo[1] = NULL; -+ lxc_list_init(&new->console.fifos); -+ -+ new->errmsg = NULL; -+ new->errpipe[0] = -1; -+ new->errpipe[1] = -1; - /* isulad add end */ - - return new; -@@ -4280,6 +4284,19 @@ int lxc_clear_rootfs_ro_paths(struct lxc_conf *c) - return 0; - } - -+/*isulad: close error pipe */ -+void lxc_close_error_pipe(int *errpipe) -+{ -+ if (errpipe[0] >= 0) { -+ close(errpipe[0]); -+ errpipe[0] = -1; -+ } -+ if (errpipe[1] >= 0) { -+ close(errpipe[1]); -+ errpipe[1] = -1; -+ } -+} -+ - void lxc_conf_free(struct lxc_conf *conf) - { - if (!conf) -@@ -4333,6 +4350,8 @@ void lxc_conf_free(struct lxc_conf *conf) - free(conf->container_info_file); - if (conf->exit_fd != -1) - close(conf->exit_fd); -+ free(conf->errmsg); -+ lxc_close_error_pipe(conf->errpipe); - /* isulad add end */ - free(conf); - } -diff --git a/src/lxc/conf.h b/src/lxc/conf.h -index 7927812..db474e1 100644 ---- a/src/lxc/conf.h -+++ b/src/lxc/conf.h -@@ -413,6 +413,9 @@ struct lxc_conf { - char *container_info_file; - - int exit_fd; /* exit fifo fd*/ -+ -+ char *errmsg; /* record error messages */ -+ int errpipe[2];//pipdfd for get error message of child or grandchild process. - /* isulad add end */ - }; - -diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index 8029f33..31f4819 100644 ---- a/src/lxc/lxccontainer.c -+++ b/src/lxc/lxccontainer.c -@@ -4063,7 +4063,7 @@ static int lxcapi_attach(struct lxc_container *c, lxc_attach_exec_t exec_functio - - current_config = c->lxc_conf; - -- ret = lxc_attach(c->name, c->config_path, exec_function, exec_payload, options, attached_process); -+ ret = lxc_attach(c->name, c->config_path, exec_function, exec_payload, options, attached_process, &c->lxc_conf->errmsg); - current_config = NULL; - return ret; - } -@@ -4080,7 +4080,7 @@ static int do_lxcapi_attach_run_wait(struct lxc_container *c, lxc_attach_options - command.program = (char*)program; - command.argv = (char**)argv; - -- r = lxc_attach(c->name, c->config_path, lxc_attach_run_command, &command, options, &pid); -+ r = lxc_attach(c->name, c->config_path, lxc_attach_run_command, &command, options, &pid, NULL); - if (r < 0) { - ERROR("ups"); - return r; -diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c -index 6d0ffe5..a590fd1 100644 ---- a/src/lxc/tools/lxc_attach.c -+++ b/src/lxc/tools/lxc_attach.c -@@ -295,8 +295,8 @@ static int do_attach_foreground(struct lxc_container *c, lxc_attach_command_t *c - wexit = ExitSignalOffset + signal; - } - out: -- //if (c->lxc_conf->errmsg) -- // *errmsg = strdup(c->lxc_conf->errmsg); -+ if (c->lxc_conf->errmsg) -+ *errmsg = strdup(c->lxc_conf->errmsg); - return wexit; - } - -@@ -376,8 +376,8 @@ static int do_attach_background(struct lxc_container *c, lxc_attach_command_t *c - else - ret = c->attach(c, lxc_attach_run_shell, NULL, attach_options, &pid); - if (ret < 0) { -- //if (c->lxc_conf->errmsg) -- // lxc_write_error_message(msgpipe[1], "%s", c->lxc_conf->errmsg); -+ if (c->lxc_conf->errmsg) -+ lxc_write_error_message(msgpipe[1], "%s", c->lxc_conf->errmsg); - close(msgpipe[1]); - msgpipe[1] = -1; - ret = -1; -diff --git a/src/lxc/tools/lxc_ls.c b/src/lxc/tools/lxc_ls.c -index cb3eb1e..e261c7b 100644 ---- a/src/lxc/tools/lxc_ls.c -+++ b/src/lxc/tools/lxc_ls.c -@@ -122,7 +122,7 @@ struct wrapargs { - /* - * Takes struct wrapargs as argument. - */ --static int ls_get_wrapper(void *wrap); -+static int ls_get_wrapper(void *wrap, int msgfd); - - /* - * To calculate swap usage we should not simply check memory.usage_in_bytes and -@@ -1023,7 +1023,7 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) - return 0; - } - --static int ls_get_wrapper(void *wrap) -+static int ls_get_wrapper(void *wrap, int msgfd) - { - int ret = -1; - size_t len = 0; -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index 74e74a1..8ec9f46 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -1971,3 +1971,24 @@ out: - return startat; - } - -+/* isulad: write error message */ -+void lxc_write_error_message(int errfd, const char *format, ...) -+{ -+ int ret; -+ char errbuf[BUFSIZ + 1] = {0}; -+ ssize_t sret; -+ va_list argp; -+ -+ if (errfd <= 0) -+ return; -+ -+ va_start(argp, format); -+ ret = vsnprintf(errbuf, BUFSIZ, format, argp); -+ va_end(argp); -+ if (ret < 0) -+ SYSERROR("Failed to call vsnprintf"); -+ sret = write(errfd, errbuf, strlen(errbuf)); -+ if (sret < 0) -+ SYSERROR("Write errbuf failed"); -+} -+ -diff --git a/src/lxc/utils.h b/src/lxc/utils.h -index 364bf67..3d56fd9 100644 ---- a/src/lxc/utils.h -+++ b/src/lxc/utils.h -@@ -314,5 +314,6 @@ extern int lxc_setup_env_home(uid_t uid); - - extern int fd_nonblock(int fd); - extern int unsigned long long lxc_get_process_startat(pid_t pid); -+extern void lxc_write_error_message(int errfd, const char *format, ...); - - #endif /* __LXC_UTILS_H */ --- -1.8.3.1 - diff --git a/0022-support-terminal-log.patch b/0022-support-terminal-log.patch new file mode 100644 index 0000000000000000000000000000000000000000..4935f670be4683e2fb7e7a22612d9e3238e5374c --- /dev/null +++ b/0022-support-terminal-log.patch @@ -0,0 +1,313 @@ +From cd19f650d43fdae95e7e72bebe207f4ddc9deb85 Mon Sep 17 00:00:00 2001 +From: haozi007 +Date: Mon, 13 Apr 2020 19:18:26 +0800 +Subject: [PATCH 22/49] support terminal log + +Signed-off-by: haozi007 +--- + src/lxc/commands.c | 14 ++++++------ + src/lxc/conf.c | 6 ++++++ + src/lxc/confile.c | 3 +++ + src/lxc/log.c | 54 +++++++++++++++++++++++------------------------ + src/lxc/lxccontainer.c | 2 ++ + src/lxc/start.c | 48 ++++++++++++++++++++--------------------- + src/lxc/terminal.c | 1 + + src/lxc/tools/lxc_start.c | 6 ++++++ + 8 files changed, 76 insertions(+), 58 deletions(-) + +diff --git a/src/lxc/commands.c b/src/lxc/commands.c +index 184a219..b21c12b 100644 +--- a/src/lxc/commands.c ++++ b/src/lxc/commands.c +@@ -80,9 +80,9 @@ static const char *lxc_cmd_str(lxc_cmd_t cmd) + [LXC_CMD_SERVE_STATE_CLIENTS] = "serve_state_clients", + [LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER] = "seccomp_notify_add_listener", + [LXC_CMD_ADD_BPF_DEVICE_CGROUP] = "add_bpf_device_cgroup", +- [LXC_CMD_FREEZE] = "freeze", +- [LXC_CMD_UNFREEZE] = "unfreeze", +- [LXC_CMD_GET_CGROUP2_FD] = "get_cgroup2_fd", ++ [LXC_CMD_FREEZE] = "freeze", ++ [LXC_CMD_UNFREEZE] = "unfreeze", ++ [LXC_CMD_GET_CGROUP2_FD] = "get_cgroup2_fd", + [LXC_CMD_GET_INIT_PIDFD] = "get_init_pidfd", + #ifdef HAVE_ISULAD + [LXC_CMD_SET_TERMINAL_FIFOS] = "set_terminal_fifos", +@@ -1532,10 +1532,10 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req, + [LXC_CMD_CONSOLE_LOG] = lxc_cmd_console_log_callback, + [LXC_CMD_SERVE_STATE_CLIENTS] = lxc_cmd_serve_state_clients_callback, + [LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER] = lxc_cmd_seccomp_notify_add_listener_callback, +- [LXC_CMD_ADD_BPF_DEVICE_CGROUP] = lxc_cmd_add_bpf_device_cgroup_callback, +- [LXC_CMD_FREEZE] = lxc_cmd_freeze_callback, +- [LXC_CMD_UNFREEZE] = lxc_cmd_unfreeze_callback, +- [LXC_CMD_GET_CGROUP2_FD] = lxc_cmd_get_cgroup2_fd_callback, ++ [LXC_CMD_ADD_BPF_DEVICE_CGROUP] = lxc_cmd_add_bpf_device_cgroup_callback, ++ [LXC_CMD_FREEZE] = lxc_cmd_freeze_callback, ++ [LXC_CMD_UNFREEZE] = lxc_cmd_unfreeze_callback, ++ [LXC_CMD_GET_CGROUP2_FD] = lxc_cmd_get_cgroup2_fd_callback, + [LXC_CMD_GET_INIT_PIDFD] = lxc_cmd_get_init_pidfd_callback, + #ifdef HAVE_ISULAD + [LXC_CMD_SET_TERMINAL_FIFOS] = lxc_cmd_set_terminal_fifos_callback, +diff --git a/src/lxc/conf.c b/src/lxc/conf.c +index 2e93227..4088363 100644 +--- a/src/lxc/conf.c ++++ b/src/lxc/conf.c +@@ -1767,6 +1767,9 @@ static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs, + if (ret < 0 && errno != EEXIST) + return log_error_errno(-errno, errno, "Failed to create console"); + ++#ifdef HAVE_ISULAD ++ if (console->slave > 0) { ++#endif + ret = fchmod(console->slave, S_IXUSR | S_IXGRP); + if (ret < 0) + return log_error_errno(-errno, errno, "Failed to set mode \"0%o\" to \"%s\"", S_IXUSR | S_IXGRP, console->name); +@@ -1776,6 +1779,9 @@ static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs, + if (ret < 0) + return log_error_errno(-1, errno, "Failed to mount \"%s\" on \"%s\"", console->name, lxcpath); + DEBUG("Mounted \"%s\" onto \"%s\"", console->name, lxcpath); ++#ifdef HAVE_ISULAD ++ } ++#endif + + /* bind mount '/dev//console' to '/dev/console' */ + ret = safe_mount(lxcpath, path, "none", MS_BIND, 0, rootfs_path); +diff --git a/src/lxc/confile.c b/src/lxc/confile.c +index a28c5da..0fcebd4 100644 +--- a/src/lxc/confile.c ++++ b/src/lxc/confile.c +@@ -2301,11 +2301,14 @@ static int set_config_console_rotate(const char *key, const char *value, + if (lxc_safe_uint(value, &lxc_conf->console.log_rotate) < 0) + return -1; + ++#ifndef HAVE_ISULAD ++ /* isulad: support rotate muti-files */ + if (lxc_conf->console.log_rotate > 1) { + ERROR("The \"lxc.console.rotate\" config key can only be set " + "to 0 or 1"); + return -1; + } ++#endif + + return 0; + } +diff --git a/src/lxc/log.c b/src/lxc/log.c +index 9794582..79caa2c 100644 +--- a/src/lxc/log.c ++++ b/src/lxc/log.c +@@ -60,30 +60,30 @@ static inline const char *isulad_get_fifo_path(const char *file) + { + #define ISULAD_FIFO_PREFIX "fifo:" + +- if (strncmp(file, ISULAD_FIFO_PREFIX, strlen(ISULAD_FIFO_PREFIX)) == 0) { +- return (file + strlen(ISULAD_FIFO_PREFIX)); +- } +- return NULL; ++ if (strncmp(file, ISULAD_FIFO_PREFIX, strlen(ISULAD_FIFO_PREFIX)) == 0) { ++ return (file + strlen(ISULAD_FIFO_PREFIX)); ++ } ++ return NULL; + } + + static int isulad_open_fifo(const char *file_path) + { + #define LOG_FIFO_SIZE (1024 * 1024) +- int fd; ++ int fd; + +- fd = lxc_unpriv(open(file_path, O_RDWR | O_NONBLOCK | O_CLOEXEC, 0640)); +- if (fd == -1) { +- fprintf(stderr, "Open fifo %s failed: %s\n", file_path, strerror(errno)); +- return -1; +- } ++ fd = lxc_unpriv(open(file_path, O_RDWR | O_NONBLOCK | O_CLOEXEC, 0640)); ++ if (fd == -1) { ++ fprintf(stderr, "Open fifo %s failed: %s\n", file_path, strerror(errno)); ++ return -1; ++ } + +- if (fcntl(fd, F_SETPIPE_SZ, LOG_FIFO_SIZE) == -1) { +- printf("Set fifo buffer size failed: %s", strerror(errno)); +- close(fd); +- return -1; +- } ++ if (fcntl(fd, F_SETPIPE_SZ, LOG_FIFO_SIZE) == -1) { ++ printf("Set fifo buffer size failed: %s", strerror(errno)); ++ close(fd); ++ return -1; ++ } + +- return fd; ++ return fd; + } + #endif + +@@ -354,10 +354,10 @@ static int log_append_logfile(const struct lxc_log_appender *appender, + + log_container_name = lxc_log_get_container_name(); + #ifdef HAVE_ISULAD +- /* use isulad log format */ +- if (log_container_name != NULL && strlen(log_container_name) > 15) { +- log_container_name = log_container_name + (strlen(log_container_name) - 15); +- } ++ /* use isulad log format */ ++ if (log_container_name != NULL && strlen(log_container_name) > 15) { ++ log_container_name = log_container_name + (strlen(log_container_name) - 15); ++ } + #endif + + if (fd_to_use < 0) +@@ -633,10 +633,10 @@ static int __lxc_log_set_file(const char *fname, int create_dirs) + } + + #ifdef HAVE_ISULAD +- fname = isulad_get_fifo_path(fname); +- if (fname == NULL) { +- return ret_errno(EINVAL); +- } ++ fname = isulad_get_fifo_path(fname); ++ if (fname == NULL) { ++ return ret_errno(EINVAL); ++ } + #endif + + #if USE_CONFIGPATH_LOGS +@@ -649,7 +649,7 @@ static int __lxc_log_set_file(const char *fname, int create_dirs) + return log_error_errno(-errno, errno, "Failed to create dir for log file \"%s\"", fname); + + #if HAVE_ISULAD +- lxc_log_fd = isulad_open_fifo(fname); ++ lxc_log_fd = isulad_open_fifo(fname); + #else + lxc_log_fd = log_open(fname); + #endif +@@ -749,9 +749,9 @@ int lxc_log_init(struct lxc_log *log) + if (lxc_log_fd >= 0) { + lxc_log_category_lxc.appender = &log_appender_logfile; + #ifdef HAVE_ISULAD +- if (!lxc_quiet_specified && !log->quiet) ++ if (!lxc_quiet_specified && !log->quiet) + #endif +- lxc_log_category_lxc.appender->next = &log_appender_stderr; ++ lxc_log_category_lxc.appender->next = &log_appender_stderr; + } + + return ret; +diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c +index 75c1bbc..821cfa1 100644 +--- a/src/lxc/lxccontainer.c ++++ b/src/lxc/lxccontainer.c +@@ -5641,6 +5641,8 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath + c->add_terminal_fifos = lxcapi_add_terminal_fifo; + c->set_terminal_winch = lxcapi_set_terminal_winch; + 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; + #endif + return c; + +diff --git a/src/lxc/start.c b/src/lxc/start.c +index 0942c31..f6a96b4 100644 +--- a/src/lxc/start.c ++++ b/src/lxc/start.c +@@ -1387,24 +1387,9 @@ static int do_start(void *data) + */ + #ifdef HAVE_ISULAD + if (!handler->disable_pty && handler->daemonize && !handler->conf->autodev) { +- char path[PATH_MAX]; +- +- ret = snprintf(path, sizeof(path), "%s/dev/null", +- handler->conf->rootfs.mount); +- if (ret < 0 || ret >= sizeof(path)) +- goto out_warn_father; +- +- ret = access(path, F_OK); +- if (ret != 0) { +- devnull_fd = open_devnull(); +- +- if (devnull_fd < 0) +- goto out_warn_father; +- WARN("Using /dev/null from the host for container init's standard file descriptors. Migration will not work"); +- } +- } + #else + if (handler->daemonize && !handler->conf->autodev) { ++#endif + char path[PATH_MAX]; + + ret = snprintf(path, sizeof(path), "%s/dev/null", +@@ -1421,7 +1406,6 @@ static int do_start(void *data) + WARN("Using /dev/null from the host for container init's standard file descriptors. Migration will not work"); + } + } +-#endif + + /* Ask father to setup cgroups and wait for him to finish. */ + ret = lxc_sync_barrier_parent(handler, LXC_SYNC_CGROUP); +@@ -2059,13 +2043,29 @@ static int lxc_spawn(struct lxc_handler *handler) + TRACE("Cloned child process %d", handler->pid); + + #ifdef HAVE_ISULAD +- /* isulad: save pid/ppid info into file*/ +- if (handler->conf->container_info_file) { +- if (lxc_save_container_info(handler->conf->container_info_file, handler->pid)) { +- ERROR("Failed to save cloned container pid"); +- goto out_delete_net; +- } +- } ++ /* isulad: close pipe after clone */ ++ if (handler->conf->console.pipes[0][0] >= 0) { ++ close(handler->conf->console.pipes[0][0]); ++ handler->conf->console.pipes[0][0] = -1; ++ } ++ ++ if (handler->conf->console.pipes[1][1] >= 0) { ++ close(handler->conf->console.pipes[1][1]); ++ handler->conf->console.pipes[1][1] = -1; ++ } ++ ++ if (handler->conf->console.pipes[2][1] >= 0) { ++ close(handler->conf->console.pipes[2][1]); ++ handler->conf->console.pipes[2][1] = -1; ++ } ++ ++ /* isulad: save pid/ppid info into file*/ ++ if (handler->conf->container_info_file) { ++ if (lxc_save_container_info(handler->conf->container_info_file, handler->pid)) { ++ ERROR("Failed to save cloned container pid"); ++ goto out_delete_net; ++ } ++ } + #endif + + /* Verify that we can actually make use of pidfds. */ +diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c +index 39a6718..14686fc 100644 +--- a/src/lxc/terminal.c ++++ b/src/lxc/terminal.c +@@ -2090,3 +2090,4 @@ int lxc_terminal_map_ids(struct lxc_conf *c, struct lxc_terminal *terminal) + + return 0; + } ++ +diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c +index 321c847..72a4494 100644 +--- a/src/lxc/tools/lxc_start.c ++++ b/src/lxc/tools/lxc_start.c +@@ -53,8 +53,14 @@ static const struct option my_longopts[] = { + {"share-uts", required_argument, 0, OPT_SHARE_UTS}, + {"share-pid", required_argument, 0, OPT_SHARE_PID}, + #ifdef HAVE_ISULAD ++ {"in-fifo", required_argument, 0, OPT_INPUT_FIFO}, ++ {"out-fifo", required_argument, 0, OPT_OUTPUT_FIFO}, ++ {"err-fifo", required_argument, 0, OPT_STDERR_FIFO}, + {"container-pidfile", required_argument, 0, OPT_CONTAINER_INFO}, + {"exit-fifo", required_argument, 0, OPT_EXIT_FIFO}, ++ {"start-timeout", required_argument, 0, OPT_START_TIMEOUT}, ++ {"disable-pty", no_argument, 0, OPT_DISABLE_PTY}, ++ {"open-stdin", no_argument, 0, OPT_OPEN_STDIN}, + #endif + LXC_COMMON_OPTIONS + }; +-- +1.8.3.1 + diff --git a/0022-support-rootfs-mount-propagation.patch b/0023-Supporting-rootfs-mount-propagation.patch similarity index 30% rename from 0022-support-rootfs-mount-propagation.patch rename to 0023-Supporting-rootfs-mount-propagation.patch index bcee5831a6a75c8ef2bca92a3c24c4b6b362b102..d0477e75e481e17208aeb49f36480a5166685384 100644 --- a/0022-support-rootfs-mount-propagation.patch +++ b/0023-Supporting-rootfs-mount-propagation.patch @@ -1,26 +1,36 @@ -From 26046eb2a18d2a7668dc213c86806efeca7d87a8 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Mon, 14 Jan 2019 17:02:02 +0800 -Subject: [PATCH 022/140] support rootfs mount propagation +From 0f756bece17253aadfe72e8f2eafe8a61d969f87 Mon Sep 17 00:00:00 2001 +From: wujing +Date: Tue, 14 Apr 2020 04:53:05 -0400 +Subject: [PATCH 23/49] Supporting rootfs mount propagation -Signed-off-by: LiFeng +Signed-off-by: wujing --- - src/lxc/conf.c | 230 ++++++++++++++++++++++++++-------------- - src/lxc/conf.h | 2 +- - src/lxc/confile.c | 8 +- - src/lxc/criu.c | 4 +- - src/lxc/storage/btrfs.c | 4 +- - src/lxc/storage/dir.c | 9 +- - src/lxc/storage/overlay.c | 4 +- - src/lxc/storage/storage_utils.c | 4 +- - src/lxc/storage/zfs.c | 4 +- - 9 files changed, 165 insertions(+), 104 deletions(-) + src/lxc/conf.c | 429 +++++++++++++++++++++++++++++++++++----- + src/lxc/conf.h | 24 ++- + src/lxc/confile.c | 19 ++ + src/lxc/criu.c | 7 + + src/lxc/storage/btrfs.c | 11 ++ + src/lxc/storage/dir.c | 38 +++- + src/lxc/storage/overlay.c | 8 + + src/lxc/storage/storage_utils.c | 13 +- + src/lxc/storage/zfs.c | 9 + + src/lxc/utils.h | 4 + + 10 files changed, 498 insertions(+), 64 deletions(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 8d8230f..55d1e45 100644 +index 4088363..e0a6f98 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c -@@ -1296,11 +1296,102 @@ static int lxc_fill_autodev(const struct lxc_rootfs *rootfs) +@@ -61,6 +61,8 @@ + #include "loop.h" + #include "utils.h" + #include "uuid.h" ++#include "path.h" ++#include "utils.h" + + #ifdef MAJOR_IN_MKDEV + #include +@@ -1236,12 +1238,106 @@ static int lxc_fill_autodev(const struct lxc_rootfs *rootfs) return 0; } @@ -50,6 +60,7 @@ index 8d8230f..55d1e45 100644 + return p; +} + ++#ifdef HAVE_ISULAD +static int rootfs_parent_mount_private(char *rootfs) +{ + /* walk /proc/self/mountinfo and change parent of rootfs to private */ @@ -65,13 +76,13 @@ index 8d8230f..55d1e45 100644 + } + + while (getline(&line, &len, f) != -1) { -+ char *target, *opts, *tmptarget; ++ char *target = NULL; ++ char *opts = NULL; ++ char *tmptarget = NULL; + target = get_field(line, 4); + if (!target) + continue; -+ tmptarget = strdup(target); -+ if (!tmptarget) -+ continue; ++ tmptarget = safe_strdup(target); + null_endofword(tmptarget); + if (!strstr(rootfs, tmptarget)) { + free(tmptarget); @@ -89,9 +100,7 @@ index 8d8230f..55d1e45 100644 + continue; + null_endofword(opts); + free(options); -+ options = strdup(opts); -+ if (!options) -+ continue; ++ options = safe_strdup(opts); + } + + if (!parent || !options) { @@ -112,23 +121,29 @@ index 8d8230f..55d1e45 100644 + free(line); + return ret; +} ++#endif + static int lxc_mount_rootfs(struct lxc_conf *conf) { int ret; struct lxc_storage *bdev; const struct lxc_rootfs *rootfs = &conf->rootfs; -+ unsigned long flags, mntflags, pflags; -+ char *mntdata; ++#ifdef HAVE_ISULAD ++ unsigned long flags, mntflags, pflags; ++ char *mntdata = NULL; ++#endif ++ if (!rootfs->path) { ret = mount("", "/", NULL, MS_SLAVE | MS_REC, 0); -@@ -1319,6 +1410,44 @@ static int lxc_mount_rootfs(struct lxc_conf *conf) - return -1; - } - -+ // isulad-start: support mount propagations of rootfs -+ //Get rootfs mnt propagation options, such as slave or shared + if (ret < 0) +@@ -1255,6 +1351,44 @@ static int lxc_mount_rootfs(struct lxc_conf *conf) + return log_error_errno(-1, errno, "Failed to access to \"%s\". Check it is present", + rootfs->mount); + ++#ifdef HAVE_ISULAD ++ // Support mount propagations of rootfs ++ // Get rootfs mnt propagation options, such as slave or shared + if (parse_mntopts(conf->rootfs.options, &mntflags, &pflags, &mntdata) < 0) { + free(mntdata); + return -1; @@ -145,8 +160,7 @@ index 8d8230f..55d1e45 100644 + */ + ret = mount("", "/", NULL, flags, NULL); + if (ret < 0) { -+ SYSERROR("Failed to make / to propagation flags %lu.", flags); -+ return -1; ++ return log_error_errno(-1, errno, "Failed to make / to propagation flags %lu.", flags); + } + + /* Make parent mount private to make sure following bind mount does @@ -155,41 +169,41 @@ index 8d8230f..55d1e45 100644 + */ + ret = rootfs_parent_mount_private(conf->rootfs.mount); + if (ret != 0) { -+ ERROR("Failed to make parent of rootfs %s to private.", conf->rootfs.mount); -+ return -1; ++ return log_error(-1, "Failed to make parent of rootfs %s to private.", conf->rootfs.mount); + } + + ret = mount(conf->rootfs.mount, conf->rootfs.mount, "bind", MS_BIND | MS_REC, NULL); + if (ret < 0) { + SYSERROR("Failed to mount rootfs %s", conf->rootfs.mount); + return -1; -+ }// isulad-end: support mount propagations of rootfs ++ } ++#endif + bdev = storage_init(conf); - if (!bdev) { - ERROR("Failed to mount rootfs \"%s\" onto \"%s\" with options \"%s\"", -@@ -1960,7 +2089,7 @@ static int lxc_setup_console(const struct lxc_rootfs *rootfs, + if (!bdev) + return log_error(-1, "Failed to mount rootfs \"%s\" onto \"%s\" with options \"%s\"", +@@ -1802,7 +1936,43 @@ static int lxc_setup_console(const struct lxc_rootfs *rootfs, + return lxc_setup_ttydir_console(rootfs, console, ttydir); } - --static void parse_mntopt(char *opt, unsigned long *flags, char **data, size_t size) ++#ifdef HAVE_ISULAD +static void parse_mntopt(char *opt, unsigned long *mflags, unsigned long *pflags, char **data, size_t size) - { - struct mount_opt *mo; - -@@ -1970,26 +2099,40 @@ static void parse_mntopt(char *opt, unsigned long *flags, char **data, size_t si - for (mo = &mount_opt[0]; mo->name != NULL; mo++) { - if (strncmp(opt, mo->name, strlen(mo->name)) == 0) { - if (mo->clear) -- *flags &= ~mo->flag; ++{ ++ struct mount_opt *mo; ++ ++ /* If opt is found in mount_opt, set or clear flags. ++ * Otherwise append it to data. */ ++ ++ for (mo = &mount_opt[0]; mo->name != NULL; mo++) { ++ if (strncmp(opt, mo->name, strlen(mo->name)) == 0) { ++ if (mo->clear) + *mflags &= ~mo->flag; - else -- *flags |= mo->flag; ++ else + *mflags |= mo->flag; - return; - } - } - ++ return; ++ } ++ } ++ + /* If opt is found in propagation_opt, set or clear flags. */ + for (mo = &propagation_opt[0]; mo->name != NULL; mo++) { + if (strncmp(opt, mo->name, strlen(mo->name)) != 0) @@ -202,77 +216,72 @@ index 8d8230f..55d1e45 100644 + + return; + } + ++ if (strlen(*data)) ++ (void)strlcat(*data, ",", size); + - if (strlen(*data)) - (void)strlcat(*data, ",", size); ++ (void)strlcat(*data, opt, size); ++} ++#else + static int parse_mntopt(char *opt, unsigned long *flags, char **data, size_t size) + { + ssize_t ret; +@@ -1839,7 +2009,43 @@ static int parse_mntopt(char *opt, unsigned long *flags, char **data, size_t siz - (void)strlcat(*data, opt, size); + return 0; } - --int parse_mntopts(const char *mntopts, unsigned long *mntflags, char **mntdata) ++#endif ++ ++#ifdef HAVE_ISULAD +int parse_mntopts(const char *mntopts, unsigned long *mntflags, unsigned long *pflags, char **mntdata) - { - char *data, *p, *s; - size_t size; - - *mntdata = NULL; - *mntflags = 0L; ++{ ++ char *data, *p, *s; ++ size_t size; ++ ++ *mntdata = NULL; ++ *mntflags = 0L; + *pflags = 0L; ++ ++ if (!mntopts) ++ return 0; ++ ++ s = safe_strdup(mntopts); - if (!mntopts) - return 0; -@@ -2007,7 +2150,7 @@ int parse_mntopts(const char *mntopts, unsigned long *mntflags, char **mntdata) - *data = 0; ++ size = strlen(s) + 1; ++ data = malloc(size); ++ if (!data) { ++ free(s); ++ return -1; ++ } ++ *data = 0; ++ ++ lxc_iterate_parts(p, s, ",") ++ parse_mntopt(p, mntflags, pflags, &data, size); ++ ++ if (*data) ++ *mntdata = data; ++ else ++ free(data); ++ free(s); ++ ++ return 0; ++} ++#else + int parse_mntopts(const char *mntopts, unsigned long *mntflags, char **mntdata) + { + __do_free char *mntopts_new = NULL, *mntopts_dup = NULL; +@@ -1870,6 +2076,7 @@ int parse_mntopts(const char *mntopts, unsigned long *mntflags, char **mntdata) - lxc_iterate_parts(p, s, ",") -- parse_mntopt(p, mntflags, &data, size); -+ parse_mntopt(p, mntflags, pflags, &data, size); + return 0; + } ++#endif - if (*data) - *mntdata = data; -@@ -2018,71 +2161,6 @@ int parse_mntopts(const char *mntopts, unsigned long *mntflags, char **mntdata) + static void parse_propagationopt(char *opt, unsigned long *flags) + { +@@ -1908,32 +2115,6 @@ int parse_propagationopts(const char *mntopts, unsigned long *pflags) return 0; } --static void parse_propagationopt(char *opt, unsigned long *flags) --{ -- struct mount_opt *mo; -- -- /* If opt is found in propagation_opt, set or clear flags. */ -- for (mo = &propagation_opt[0]; mo->name != NULL; mo++) { -- if (strncmp(opt, mo->name, strlen(mo->name)) != 0) -- continue; -- -- if (mo->clear) -- *flags &= ~mo->flag; -- else -- *flags |= mo->flag; -- -- return; -- } --} -- --int parse_propagationopts(const char *mntopts, unsigned long *pflags) --{ -- char *p, *s; -- -- if (!mntopts) -- return 0; -- -- s = strdup(mntopts); -- if (!s) { -- SYSERROR("Failed to allocate memory"); -- return -ENOMEM; -- } -- -- *pflags = 0L; -- lxc_iterate_parts(p, s, ",") -- parse_propagationopt(p, pflags); -- free(s); -- -- return 0; --} -- -static void null_endofword(char *word) -{ - while (*word && *word != ' ' && *word != '\t') @@ -302,206 +311,623 @@ index 8d8230f..55d1e45 100644 static int mount_entry(const char *fsname, const char *target, const char *fstype, unsigned long mountflags, unsigned long pflags, const char *data, bool optional, -@@ -2289,10 +2367,9 @@ static inline int mount_entry_on_generic(struct mntent *mntent, - const char *lxc_path) - { +@@ -2186,6 +2367,82 @@ retry: + + return 0; + } ++ ++/* isulad: checkMountDestination checks to ensure that the mount destination is not over the top of /proc. ++ * dest is required to be an abs path and have any symlinks resolved before calling this function. */ ++static int check_mount_destination(const char *rootfs, const char *dest) ++{ ++ const char *invalid_destinations[] = { ++ "/proc", ++ NULL ++ }; ++ // White list, it should be sub directories of invalid destinations ++ const char *valid_destinations[] = { ++ // These entries can be bind mounted by files emulated by fuse, ++ // so commands like top, free displays stats in container. ++ "/proc/cpuinfo", ++ "/proc/diskstats", ++ "/proc/meminfo", ++ "/proc/stat", ++ "/proc/swaps", ++ "/proc/uptime", ++ "/proc/net/dev", ++ NULL ++ }; ++ const char **valid = NULL; ++ const char **invalid = NULL; ++ ++ for(valid = valid_destinations; *valid != NULL; valid++) { ++ char *fullpath = NULL; ++ char *relpath = NULL; ++ const char *parts[3] = { ++ rootfs, ++ *valid, ++ NULL ++ }; ++ fullpath = lxc_string_join("/", parts, false); ++ if (!fullpath) { ++ ERROR("Out of memory"); ++ return -1; ++ } ++ relpath = path_relative(fullpath, dest); ++ free(fullpath); ++ if (!relpath) ++ return -1; ++ if (!strcmp(relpath, ".")) { ++ free(relpath); ++ return 0; ++ } ++ free(relpath); ++ } ++ ++ for(invalid = invalid_destinations; *invalid != NULL; invalid++) { ++ char *fullpath = NULL; ++ char *relpath = NULL; ++ const char *parts[3] = { ++ rootfs, ++ *invalid, ++ NULL ++ }; ++ fullpath = lxc_string_join("/", parts, false); ++ if (!fullpath) { ++ ERROR("Out of memory"); ++ return -1; ++ } ++ relpath = path_relative(fullpath, dest); ++ free(fullpath); ++ if (!relpath) ++ return -1; ++ if (!strcmp(relpath, ".") || strncmp(relpath, "..", 2)) { ++ ERROR("%s cannot be mounted because it is located inside %s", dest, *invalid); ++ free(relpath); ++ return -1; ++ } ++ free(relpath); ++ } ++ ++ return 0; ++} + #endif + + /* rootfs, lxc_name, and lxc_path can be NULL when the container is created +@@ -2201,18 +2458,51 @@ static inline int mount_entry_on_generic(struct mntent *mntent, + char *rootfs_path = NULL; int ret; -- unsigned long mntflags; -+ unsigned long mntflags, pflags; - char *mntdata; bool dev, optional, relative; -- unsigned long pflags = 0; - char *rootfs_path = NULL; +- const char *dest = path; ++ const char *dest = path; ++ ++#ifdef HAVE_ISULAD ++ char *rpath = NULL; ++#endif optional = hasmntopt(mntent, "optional") != NULL; -@@ -2312,11 +2389,7 @@ static inline int mount_entry_on_generic(struct mntent *mntent, + dev = hasmntopt(mntent, "dev") != NULL; + relative = hasmntopt(mntent, "relative") != NULL; + ++#ifdef HAVE_ISULAD ++ // isulad: ensure that the destination of the bind mount is resolved of symlinks at mount time because ++ // any previous mounts can invalidate the next mount's destination. ++ // this can happen when a user specifies mounts within other mounts to cause breakouts or other ++ // evil stuff to try to escape the container's rootfs. ++ if (rootfs_path) { ++ rpath = follow_symlink_in_scope(path, rootfs_path); ++ if (!rpath) { ++ ERROR("Failed to get real path of '%s' in scope '%s'.", path, rootfs_path); ++ lxc_write_error_message(rootfs->errfd, "%s:%d: failed to get real path of '%s' in scope '%s'.", ++ __FILE__, __LINE__, path, rootfs_path); ++ return -1; ++ } ++ dest = rpath; ++ ++ ret = check_mount_destination(rootfs_path, dest); ++ if (ret) { ++ ERROR("Mount destination is invalid: '%s'", dest); ++ lxc_write_error_message(rootfs->errfd, "%s:%d: mount destination is invalid: '%s'.", ++ __FILE__, __LINE__, dest); ++ free(rpath); ++ return -1; ++ } ++ } ++#else + if (rootfs && rootfs->path) + rootfs_path = rootfs->mount; ++#endif + + ret = mount_entry_create_dir_file(mntent, path, rootfs, lxc_name, + lxc_path); + if (ret < 0) { ++#ifdef HAVE_ISULAD ++ free(rpath); ++#endif + if (optional) + return 0; + +@@ -2220,6 +2510,29 @@ static inline int mount_entry_on_generic(struct mntent *mntent, } cull_mntent_opt(mntent); -- ret = parse_propagationopts(mntent->mnt_opts, &pflags); -- if (ret < 0) -- return -1; -- -- ret = parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata); ++#ifdef HAVE_ISULAD + ret = parse_mntopts(mntent->mnt_opts, &mntflags, &pflags, &mntdata); ++ if (ret < 0) { ++ free(rpath); ++ return -1; ++ } ++ ++ // support squashfs ++ if (strcmp(mntent->mnt_type, "squashfs") == 0) { ++ ret = mount_entry_with_loop_dev(mntent->mnt_fsname, dest, mntent->mnt_type, ++ mntent->mnt_opts, rootfs_path); ++ } else { ++ ret = mount_entry(mntent->mnt_fsname, dest, mntent->mnt_type, mntflags, ++ pflags, mntdata, optional, dev, relative, rootfs_path); ++ } ++ ++ if (ret < 0) { ++ lxc_write_error_message(rootfs->errfd, "%s:%d: failed to mount %s as type %s.", ++ __FILE__, __LINE__, mntent->mnt_fsname, mntent->mnt_type); ++ } ++ ++ free(rpath); ++#else + ret = parse_propagationopts(mntent->mnt_opts, &pflags); if (ret < 0) return -1; +@@ -2228,18 +2541,10 @@ static inline int mount_entry_on_generic(struct mntent *mntent, + if (ret < 0) + return ret; + +-#ifdef HAVE_ISULAD +- // isulad: support squashfs +- if (strcmp(mntent->mnt_type, "squashfs") == 0) { +- ret = mount_entry_with_loop_dev(mntent->mnt_fsname, dest, mntent->mnt_type, +- mntent->mnt_opts, rootfs_path); +- } else { +-#endif +- ret = mount_entry(mntent->mnt_fsname, dest, mntent->mnt_type, mntflags, +- pflags, mntdata, optional, dev, relative, rootfs_path); +-#ifdef HAVE_ISULAD +- } ++ ret = mount_entry(mntent->mnt_fsname, dest, mntent->mnt_type, mntflags, ++ pflags, mntdata, optional, dev, relative, rootfs_path); + #endif ++ + return ret; + } -@@ -3544,7 +3617,8 @@ int lxc_setup_rootfs_prepare_root(struct lxc_conf *conf, const char *name, - return 0; +@@ -2329,6 +2634,28 @@ static int mount_file_entries(const struct lxc_conf *conf, + while (getmntent_r(file, &mntent, buf, sizeof(buf))) { + int ret; + ++#ifdef HAVE_ISULAD ++ //isulad, system contaienr, skip "proc/sys/xxx" path ++ if (conf->systemd != NULL && strcmp(conf->systemd, "true") == 0) { ++ if (strstr(mntent.mnt_dir, "proc/sys") != NULL) { ++ continue; ++ } ++ } ++ ++ /* Note: Workaround for volume file path with space*/ ++ mntent.mnt_fsname = lxc_string_replace(SPACE_MAGIC_STR, " ", mntent.mnt_fsname); ++ if(!mntent.mnt_fsname) { ++ SYSERROR("memory allocation error"); ++ return -1; ++ } ++ mntent.mnt_dir = lxc_string_replace(SPACE_MAGIC_STR, " ", mntent.mnt_dir); ++ if(!mntent.mnt_dir) { ++ SYSERROR("memory allocation error"); ++ free(mntent.mnt_fsname); ++ return -1; ++ } ++#endif ++ + if (!rootfs->path) + ret = mount_entry_on_systemfs(&mntent); + else if (mntent.mnt_dir[0] != '/') +@@ -2337,6 +2664,14 @@ static int mount_file_entries(const struct lxc_conf *conf, + else + ret = mount_entry_on_absolute_rootfs(&mntent, rootfs, + lxc_name, lxc_path); ++ ++#ifdef HAVE_ISULAD ++ free(mntent.mnt_fsname); ++ mntent.mnt_fsname = NULL; ++ free(mntent.mnt_dir); ++ mntent.mnt_dir = NULL; ++#endif ++ + if (ret < 0) + return -1; + } +@@ -3391,7 +3726,13 @@ int lxc_setup_rootfs_prepare_root(struct lxc_conf *conf, const char *name, + return log_trace(0, "Bind mounted container / onto itself"); } -- remount_all_slave(); -+ if (!conf->rootfs.options) ++#ifdef HAVE_ISULAD ++ if (!conf->rootfs.options) { + remount_all_slave(); ++ } ++#else + remount_all_slave(); ++#endif ret = run_lxc_hooks(name, "pre-mount", conf, NULL); - if (ret < 0) { + if (ret < 0) +@@ -3585,16 +3926,12 @@ reset_umask: + static int setup_rootfs_mountopts(const struct lxc_rootfs *rootfs) + { + unsigned long mflags, mntflags, pflags; +- char *mntdata; ++ char *mntdata = NULL; + + if(!rootfs || !rootfs->options) + return 0; + +- if (parse_propagationopts(rootfs->options, &pflags) < 0) { +- return -1; +- } +- +- if (parse_mntopts(rootfs->options, &mntflags, &mntdata) < 0) { ++ if (parse_mntopts(rootfs->options, &mntflags, &pflags, &mntdata) < 0) { + free(mntdata); + return -1; + } +@@ -3602,9 +3939,9 @@ static int setup_rootfs_mountopts(const struct lxc_rootfs *rootfs) + + if (mntflags & MS_RDONLY) { + mflags = add_required_remount_flags("/", NULL, MS_BIND | MS_REC | mntflags | pflags | MS_REMOUNT); +- DEBUG("remounting /"); ++ DEBUG("remounting / as readonly"); + if (mount("/", "/", NULL, mflags, 0) < 0) { +- SYSERROR("Failed to remount /"); ++ SYSERROR("Failed to make / readonly."); + return -1; + } + } diff --git a/src/lxc/conf.h b/src/lxc/conf.h -index db474e1..7393dbf 100644 +index 482fe0d..22c554d 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h -@@ -463,7 +463,7 @@ extern int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data, +@@ -156,10 +156,12 @@ struct lxc_rootfs { + bool managed; + + #ifdef HAVE_ISULAD +- /* isulad: maskedpaths */ +- struct lxc_list maskedpaths; +- /* isulad: ropaths */ +- struct lxc_list ropaths; ++ /* isulad: maskedpaths */ ++ struct lxc_list maskedpaths; ++ /* isulad: ropaths */ ++ struct lxc_list ropaths; ++ /* isulad: errfd */ ++ int errfd; + #endif + + }; +@@ -444,6 +446,8 @@ struct lxc_conf { + int exit_fd; /* exit fifo fd*/ + + char *errmsg; /* record error messages */ ++ ++ char *systemd; //systemd value + #endif + + }; +@@ -492,8 +496,6 @@ extern int userns_exec_1(const struct lxc_conf *conf, int (*fn)(void *), + void *data, const char *fn_name); extern int userns_exec_full(struct lxc_conf *conf, int (*fn)(void *), void *data, const char *fn_name); - extern int parse_mntopts(const char *mntopts, unsigned long *mntflags, +-extern int parse_mntopts(const char *mntopts, unsigned long *mntflags, - char **mntdata); -+ unsigned long *pflags, char **mntdata); extern int parse_propagationopts(const char *mntopts, unsigned long *pflags); extern void tmp_proc_unmount(struct lxc_conf *lxc_conf); extern void remount_all_slave(void); +@@ -519,6 +521,16 @@ extern int userns_exec_minimal(const struct lxc_conf *conf, + int (*fn_parent)(void *), void *fn_parent_data, + int (*fn_child)(void *), void *fn_child_data); + #ifdef HAVE_ISULAD ++// isulad modify ++extern int parse_mntopts(const char *mntopts, unsigned long *mntflags, ++ unsigned long *pflags, char **mntdata); ++#else ++extern int parse_mntopts(const char *mntopts, unsigned long *mntflags, ++ char **mntdata); ++#endif ++ ++#ifdef HAVE_ISULAD ++// isulad add + 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); diff --git a/src/lxc/confile.c b/src/lxc/confile.c -index e199965..db63b55 100644 +index 0fcebd4..9ba3c7c 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c -@@ -2065,16 +2065,10 @@ static int set_config_rootfs_options(const char *key, const char *value, - char *mdata = NULL, *opts = NULL; +@@ -1358,6 +1358,10 @@ static int set_config_environment(const char *key, const char *value, + { + struct lxc_list *list_item = NULL; + ++#ifdef HAVE_ISULAD ++ char *replaced = NULL; ++#endif ++ + if (lxc_config_value_empty(value)) + return lxc_clear_environment(lxc_conf); + +@@ -1378,7 +1382,16 @@ static int set_config_environment(const char *key, const char *value, + env_var[1] = env_val; + list_item->elem = lxc_string_join("=", env_var, false); + } else { ++#ifdef HAVE_ISULAD ++ /* isulad: recover space replaced by SPACE_MAGIC_STR */ ++ replaced = lxc_string_replace(SPACE_MAGIC_STR, " ", value); ++ if(!replaced) ++ goto on_error; ++ ++ list_item->elem = replaced; ++#else + list_item->elem = strdup(value); ++#endif + } + + if (!list_item->elem) +@@ -2594,6 +2607,11 @@ static int set_config_rootfs_options(const char *key, const char *value, + int ret; struct lxc_rootfs *rootfs = &lxc_conf->rootfs; -- ret = parse_mntopts(value, &mflags, &mdata); ++#ifdef HAVE_ISULAD + ret = parse_mntopts(value, &mflags, &pflags, &mdata); ++ if (ret < 0) ++ return -EINVAL; ++#else + ret = parse_mntopts(value, &mflags, &mdata); if (ret < 0) return -EINVAL; +@@ -2603,6 +2621,7 @@ static int set_config_rootfs_options(const char *key, const char *value, + free(mdata); + return -EINVAL; + } ++#endif -- ret = parse_propagationopts(value, &pflags); -- if (ret < 0) { -- free(mdata); -- return -EINVAL; -- } -- ret = set_config_string_item(&opts, value); if (ret < 0) { - free(mdata); diff --git a/src/lxc/criu.c b/src/lxc/criu.c -index 31c1940..bb97859 100644 +index 1a909bb..14a8aae 100644 --- a/src/lxc/criu.c +++ b/src/lxc/criu.c -@@ -389,9 +389,9 @@ static void exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf, - while (getmntent_r(mnts, &mntent, buf, sizeof(buf))) { - char *fmt, *key, *val, *mntdata; +@@ -371,8 +371,15 @@ static void exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf, + char *mntdata = NULL; char arg[2 * PATH_MAX + 2]; -- unsigned long flags; -+ unsigned long flags, pflags; -- if (parse_mntopts(mntent.mnt_opts, &flags, &mntdata) < 0) ++#ifdef HAVE_ISULAD ++ unsigned long pflags; ++ + if (parse_mntopts(mntent.mnt_opts, &flags, &pflags, &mntdata) < 0) ++ goto err; ++#else + if (parse_mntopts(mntent.mnt_opts, &flags, &mntdata) < 0) goto err; ++#endif free(mntdata); + diff --git a/src/lxc/storage/btrfs.c b/src/lxc/storage/btrfs.c -index bbfce61..a02c215 100644 +index 92a4a6d..069a9dd 100644 --- a/src/lxc/storage/btrfs.c +++ b/src/lxc/storage/btrfs.c -@@ -212,7 +212,7 @@ bool btrfs_detect(const char *path) - - int btrfs_mount(struct lxc_storage *bdev) - { -- unsigned long mntflags; -+ unsigned long mntflags, pflags; - char *mntdata; +@@ -197,16 +197,27 @@ int btrfs_mount(struct lxc_storage *bdev) const char *src; int ret; -@@ -223,7 +223,7 @@ int btrfs_mount(struct lxc_storage *bdev) + ++#ifdef HAVE_ISULAD ++ unsigned long pflags = 0; ++#endif ++ + if (strcmp(bdev->type, "btrfs")) + return -22; + if (!bdev->src || !bdev->dest) return -22; -- if (parse_mntopts(bdev->mntopts, &mntflags, &mntdata) < 0) { -+ if (parse_mntopts(bdev->mntopts, &mntflags, &pflags, &mntdata) < 0) { ++#ifdef HAVE_ISULAD ++ if (parse_mntopts(bdev->mntopts, &mntflags, &pflags, &mntdata) < 0) { ++ free(mntdata); ++ return -22; ++ } ++#else + if (parse_mntopts(bdev->mntopts, &mntflags, &mntdata) < 0) { free(mntdata); return -22; } ++#endif + + src = lxc_storage_get_path(bdev->src, "btrfs"); + diff --git a/src/lxc/storage/dir.c b/src/lxc/storage/dir.c -index 79b6469..c7b5ee2 100644 +index b3dbbd0..1dc95f1 100644 --- a/src/lxc/storage/dir.c +++ b/src/lxc/storage/dir.c -@@ -170,20 +170,13 @@ int dir_mount(struct lxc_storage *bdev) - if (!bdev->src || !bdev->dest) - return -22; +@@ -124,14 +124,39 @@ bool dir_detect(const char *path) + return false; + } -- ret = parse_mntopts(bdev->mntopts, &mntflags, &mntdata); ++#ifdef HAVE_ISULAD + int dir_mount(struct lxc_storage *bdev) + { + __do_free char *mntdata = NULL; +-#ifdef HAVE_ISULAD + unsigned long mntflags = 0, pflags = 0; ++ int ret; ++ const char *src; ++ ++ if (strcmp(bdev->type, "dir")) ++ return -22; ++ ++ if (!bdev->src || !bdev->dest) ++ return -22; ++ + ret = parse_mntopts(bdev->mntopts, &mntflags, &pflags, &mntdata); - if (ret < 0) { - ERROR("Failed to parse mount options \"%s\"", bdev->mntopts); - free(mntdata); - return -EINVAL; - } ++ if (ret < 0) ++ return log_error_errno(ret, errno, "Failed to parse mount options \"%s\"", bdev->mntopts); ++ ++ src = lxc_storage_get_path(bdev->src, bdev->type); ++ ++ ret = mount(src, bdev->dest, "bind", MS_BIND | MS_REC | (mntflags & ~MS_RDONLY) | pflags, mntdata); ++ if (ret < 0) { ++ return log_error_errno(-errno, errno, "Failed to mount \"%s\" on \"%s\"", src, bdev->dest); ++ } ++ TRACE("Mounted \"%s\" on \"%s\"", src, bdev->dest); ++ ++ return 0; ++} + #else ++int dir_mount(struct lxc_storage *bdev) ++{ ++ __do_free char *mntdata = NULL; + unsigned long mflags = 0, mntflags = 0, pflags = 0; +-#endif + int ret; + const char *src; + +@@ -151,13 +176,6 @@ int dir_mount(struct lxc_storage *bdev) -- ret = parse_propagationopts(bdev->mntopts, &pflags); -- if (ret < 0) { -- ERROR("Failed to parse propagation options \"%s\"", bdev->mntopts); -- free(mntdata); -- return -EINVAL; -- } -- src = lxc_storage_get_path(bdev->src, bdev->type); +-#ifdef HAVE_ISULAD +- ret = mount(src, bdev->dest, "bind", MS_BIND | MS_REC | (mntflags & ~MS_RDONLY) | pflags, mntdata); +- if (ret < 0) { +- return log_error_errno(-errno, errno, "Failed to mount \"%s\" on \"%s\"", src, bdev->dest); +- } +- TRACE("Mounted \"%s\" on \"%s\"", src, bdev->dest); +-#else ret = mount(src, bdev->dest, "bind", MS_BIND | MS_REC | mntflags | pflags, mntdata); + if (ret < 0) + return log_error_errno(-errno, errno, "Failed to mount \"%s\" on \"%s\"", src, bdev->dest); +@@ -174,10 +192,10 @@ int dir_mount(struct lxc_storage *bdev) + } + TRACE("Mounted \"%s\" on \"%s\" with options \"%s\", mount flags \"%lu\", and propagation flags \"%lu\"", + src ? src : "(none)", bdev->dest ? bdev->dest : "(none)", mntdata, mflags, pflags); +-#endif + + return 0; + } ++#endif + + int dir_umount(struct lxc_storage *bdev) + { diff --git a/src/lxc/storage/overlay.c b/src/lxc/storage/overlay.c -index 01546b1..90408a3 100644 +index 770785c..75a81de 100644 --- a/src/lxc/storage/overlay.c +++ b/src/lxc/storage/overlay.c -@@ -495,7 +495,7 @@ int ovl_mount(struct lxc_storage *bdev) - char *options_work, *work, *lastslash; - int lastslashidx; +@@ -349,6 +349,9 @@ int ovl_mount(struct lxc_storage *bdev) + char *work, *lastslash; size_t len, len2; -- unsigned long mntflags; -+ unsigned long mntflags, pflags; - char *mntdata; int ret, ret2; ++#ifdef HAVE_ISULAD ++ unsigned long pflags = 0; ++#endif -@@ -575,7 +575,7 @@ int ovl_mount(struct lxc_storage *bdev) - memcpy(work + lastslashidx, "olwork", STRLITERALLEN("olwork")); - work[lastslashidx + STRLITERALLEN("olwork")] = '\0'; + if (strcmp(bdev->type, "overlay") && strcmp(bdev->type, "overlayfs")) + return -22; +@@ -414,7 +417,12 @@ int ovl_mount(struct lxc_storage *bdev) + work = must_make_path(upper, LXC_OVERLAY_WORK_DIR, NULL); + upper[lastslash - upper] = '/'; -- ret = parse_mntopts(bdev->mntopts, &mntflags, &mntdata); ++#ifdef HAVE_ISULAD + ret = parse_mntopts(bdev->mntopts, &mntflags, &pflags, &mntdata); ++#else + ret = parse_mntopts(bdev->mntopts, &mntflags, &mntdata); ++#endif ++ if (ret < 0) { ERROR("Failed to parse mount options"); free(mntdata); diff --git a/src/lxc/storage/storage_utils.c b/src/lxc/storage/storage_utils.c -index fa4e727..46e08a3 100644 +index 07eee22..6fec638 100644 --- a/src/lxc/storage/storage_utils.c +++ b/src/lxc/storage/storage_utils.c -@@ -396,7 +396,7 @@ int find_fstype_cb(char *buffer, void *data) - const char *options; - } *cbarg = data; - -- unsigned long mntflags; -+ unsigned long mntflags, pflags; - char *mntdata; - char *fstype; +@@ -340,6 +340,10 @@ int find_fstype_cb(char *buffer, void *data) + char mount_err[BUFSIZ] = {0}; + int ret; -@@ -411,7 +411,7 @@ int find_fstype_cb(char *buffer, void *data) ++#ifdef HAVE_ISULAD ++ unsigned long pflags = 0; ++#endif ++ + /* we don't try 'nodev' entries */ + if (strstr(buffer, "nodev")) + return 0; +@@ -351,14 +355,19 @@ int find_fstype_cb(char *buffer, void *data) DEBUG("Trying to mount \"%s\"->\"%s\" with FSType \"%s\"", cbarg->rootfs, cbarg->target, fstype); - if (parse_mntopts(cbarg->options, &mntflags, &mntdata) < 0) { ++#ifdef HAVE_ISULAD + if (parse_mntopts(cbarg->options, &mntflags, &pflags, &mntdata) < 0) { free(mntdata); return 0; } + +-#ifdef HAVE_ISULAD + if (mount(cbarg->rootfs, cbarg->target, fstype, (mntflags & ~MS_RDONLY), mntdata)) { + #else ++ if (parse_mntopts(cbarg->options, &mntflags, &mntdata) < 0) { ++ free(mntdata); ++ return 0; ++ } ++ + if (mount(cbarg->rootfs, cbarg->target, fstype, mntflags, mntdata)) { + #endif + SYSDEBUG("Failed to mount"); diff --git a/src/lxc/storage/zfs.c b/src/lxc/storage/zfs.c -index ba104da..752b0c5 100644 +index 4cc171f..025cf95 100644 --- a/src/lxc/storage/zfs.c +++ b/src/lxc/storage/zfs.c -@@ -184,7 +184,7 @@ int zfs_mount(struct lxc_storage *bdev) - size_t oldlen, newlen, totallen; - char *mntdata, *tmp; +@@ -167,13 +167,22 @@ int zfs_mount(struct lxc_storage *bdev) const char *src; -- unsigned long mntflags; -+ unsigned long mntflags, pflags; char cmd_output[PATH_MAX] = {0}; ++#ifdef HAVE_ISULAD ++ unsigned long pflags = 0; ++#endif ++ if (strcmp(bdev->type, "zfs")) -@@ -193,7 +193,7 @@ int zfs_mount(struct lxc_storage *bdev) + return -22; + if (!bdev->src || !bdev->dest) return -22; -- ret = parse_mntopts(bdev->mntopts, &mntflags, &mntdata); ++#ifdef HAVE_ISULAD + ret = parse_mntopts(bdev->mntopts, &mntflags, &pflags, &mntdata); ++#else + ret = parse_mntopts(bdev->mntopts, &mntflags, &mntdata); ++#endif ++ if (ret < 0) { ERROR("Failed to parse mount options"); free(mntdata); +diff --git a/src/lxc/utils.h b/src/lxc/utils.h +index 677f632..36c458e 100644 +--- a/src/lxc/utils.h ++++ b/src/lxc/utils.h +@@ -27,8 +27,12 @@ + #include "memory_utils.h" + #include "raw_syscalls.h" + #include "string_utils.h" ++ + #ifdef HAVE_ISULAD + #include "isulad_utils.h" ++ ++/* isulad: replace space with SPACE_MAGIC_STR */ ++#define SPACE_MAGIC_STR "[#)" + #endif + + /* returns 1 on success, 0 if there were any failures */ -- 1.8.3.1 diff --git a/0023-attach.c-change-uid-and-gid-from-lxc-container-confi.patch b/0023-attach.c-change-uid-and-gid-from-lxc-container-confi.patch deleted file mode 100644 index b2163dec593ab7a9bd1078633cebfde9a91de760..0000000000000000000000000000000000000000 --- a/0023-attach.c-change-uid-and-gid-from-lxc-container-confi.patch +++ /dev/null @@ -1,31 +0,0 @@ -From ecd40a856d039f7bc67ac076041a07cb369eaa77 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Mon, 14 Jan 2019 17:09:57 +0800 -Subject: [PATCH 023/140] attach.c: change uid and gid from lxc container - config - -Signed-off-by: LiFeng ---- - src/lxc/attach.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/src/lxc/attach.c b/src/lxc/attach.c -index 570b9d0..e6e4b0d 100644 ---- a/src/lxc/attach.c -+++ b/src/lxc/attach.c -@@ -1146,6 +1146,12 @@ int lxc_attach(const char *name, const char *lxcpath, - } - conf = init_ctx->container->lxc_conf; - -+ // isulad: always switch uid and gid for attach -+ if (options->uid == -1) -+ options->uid = init_ctx->container->lxc_conf->init_uid; -+ if (options->gid == -1) -+ options->gid = init_ctx->container->lxc_conf->init_gid; -+ - if (!fetch_seccomp(init_ctx->container, options)) - WARN("Failed to get seccomp policy"); - --- -1.8.3.1 - diff --git a/0024-isulad-support-symlink-in-mount-entry-and-not-permit.patch b/0024-isulad-support-symlink-in-mount-entry-and-not-permit.patch deleted file mode 100644 index a46a07d58c30c2df8556e35dc333d437edbe432e..0000000000000000000000000000000000000000 --- a/0024-isulad-support-symlink-in-mount-entry-and-not-permit.patch +++ /dev/null @@ -1,821 +0,0 @@ -From cf669a5cfd241dc8ec9ce2571e73fc13d4266bce Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Mon, 14 Jan 2019 20:12:06 +0800 -Subject: [PATCH 024/140] isulad: support symlink in mount entry, and not - permit mount to /proc - -Signed-off-by: LiFeng ---- - src/lxc/Makefile.am | 2 + - src/lxc/conf.c | 108 ++++++++++- - src/lxc/path.c | 546 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - src/lxc/path.h | 70 +++++++ - 4 files changed, 721 insertions(+), 5 deletions(-) - create mode 100644 src/lxc/path.c - create mode 100644 src/lxc/path.h - -diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am -index 08e2fab..f2928b7 100644 ---- a/src/lxc/Makefile.am -+++ b/src/lxc/Makefile.am -@@ -12,6 +12,7 @@ noinst_HEADERS = attach.h \ - confile_utils.h \ - criu.h \ - error.h \ -+ path.h \ - file_utils.h \ - ../include/netns_ifaddrs.h \ - initutils.h \ -@@ -95,6 +96,7 @@ liblxc_la_SOURCES = af_unix.c af_unix.h \ - commands_utils.c commands_utils.h \ - conf.c conf.h \ - confile.c confile.h \ -+ path.c path.h \ - confile_utils.c confile_utils.h \ - criu.c criu.h \ - error.c error.h \ -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 55d1e45..800573a 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -77,6 +77,7 @@ - #include "storage/overlay.h" - #include "syscall_wrappers.h" - #include "terminal.h" -+#include "path.h" - #include "utils.h" - - #ifdef MAJOR_IN_MKDEV -@@ -2309,6 +2310,79 @@ static void cull_mntent_opt(struct mntent *mntent) - } - } - -+/* isulad: checkMountDestination checks to ensure that the mount destination is not over the top of /proc. -+ * dest is required to be an abs path and have any symlinks resolved before calling this function. */ -+static int check_mount_destination(const char *rootfs, const char *dest) -+{ -+ const char *invalid_destinations[] = { -+ "/proc", -+ NULL -+ }; -+ // White list, it should be sub directories of invalid destinations -+ const char *valid_destinations[] = { -+ // These entries can be bind mounted by files emulated by fuse, -+ // so commands like top, free displays stats in container. -+ "/proc/cpuinfo", -+ "/proc/diskstats", -+ "/proc/meminfo", -+ "/proc/stat", -+ "/proc/swaps", -+ "/proc/uptime", -+ "/proc/net/dev", -+ NULL -+ }; -+ const char **valid, **invalid; -+ -+ for(valid = valid_destinations; *valid != NULL; valid++) { -+ char *fullpath, *relpath; -+ const char *parts[3] = { -+ rootfs, -+ *valid, -+ NULL -+ }; -+ fullpath = lxc_string_join("/", parts, false); -+ if (!fullpath) { -+ ERROR("Out of memory"); -+ return -1; -+ } -+ relpath = path_relative(fullpath, dest); -+ free(fullpath); -+ if (!relpath) -+ return -1; -+ if (!strcmp(relpath, ".")) { -+ free(relpath); -+ return 0; -+ } -+ free(relpath); -+ } -+ -+ for(invalid = invalid_destinations; *invalid != NULL; invalid++) { -+ char *fullpath, *relpath; -+ const char *parts[3] = { -+ rootfs, -+ *invalid, -+ NULL -+ }; -+ fullpath = lxc_string_join("/", parts, false); -+ if (!fullpath) { -+ ERROR("Out of memory"); -+ return -1; -+ } -+ relpath = path_relative(fullpath, dest); -+ free(fullpath); -+ if (!relpath) -+ return -1; -+ if (!strcmp(relpath, ".") || strncmp(relpath, "..", 2)) { -+ ERROR("%s cannot be mounted because it is located inside %s", dest, *invalid); -+ free(relpath); -+ return -1; -+ } -+ free(relpath); -+ } -+ -+ return 0; -+} -+ - static int mount_entry_create_dir_file(const struct mntent *mntent, - const char *path, - const struct lxc_rootfs *rootfs, -@@ -2370,7 +2444,8 @@ static inline int mount_entry_on_generic(struct mntent *mntent, - unsigned long mntflags, pflags; - char *mntdata; - bool dev, optional, relative; -- char *rootfs_path = NULL; -+ char *rootfs_path = NULL, *rpath = NULL; -+ const char *dest = path; - - optional = hasmntopt(mntent, "optional") != NULL; - dev = hasmntopt(mntent, "dev") != NULL; -@@ -2379,9 +2454,29 @@ static inline int mount_entry_on_generic(struct mntent *mntent, - if (rootfs && rootfs->path) - rootfs_path = rootfs->mount; - -- ret = mount_entry_create_dir_file(mntent, path, rootfs, lxc_name, -- lxc_path); -+ // isulad: ensure that the destination of the bind mount is resolved of symlinks at mount time because -+ // any previous mounts can invalidate the next mount's destination. -+ // this can happen when a user specifies mounts within other mounts to cause breakouts or other -+ // evil stuff to try to escape the container's rootfs. -+ if (rootfs_path) { -+ rpath = follow_symlink_in_scope(path, rootfs_path); -+ if (!rpath) { -+ ERROR("Failed to get real path for '%s'", path); -+ return -1; -+ } -+ dest = rpath; -+ -+ ret = check_mount_destination(rootfs_path, dest); -+ if (ret) { -+ ERROR("Mount destination is invalid: '%s'", dest); -+ free(rpath); -+ return -1; -+ } -+ } -+ -+ ret = mount_entry_create_dir_file(mntent, dest, rootfs, lxc_name, lxc_path); - if (ret < 0) { -+ free(rpath); - if (optional) - return 0; - -@@ -2390,13 +2485,16 @@ static inline int mount_entry_on_generic(struct mntent *mntent, - cull_mntent_opt(mntent); - - ret = parse_mntopts(mntent->mnt_opts, &mntflags, &pflags, &mntdata); -- if (ret < 0) -+ if (ret < 0) { -+ free(rpath); - return -1; -+ } - -- ret = mount_entry(mntent->mnt_fsname, path, mntent->mnt_type, mntflags, -+ ret = mount_entry(mntent->mnt_fsname, dest, mntent->mnt_type, mntflags, - pflags, mntdata, optional, dev, relative, rootfs_path); - - free(mntdata); -+ free(rpath); - return ret; - } - -diff --git a/src/lxc/path.c b/src/lxc/path.c -new file mode 100644 -index 0000000..e917dcb ---- /dev/null -+++ b/src/lxc/path.c -@@ -0,0 +1,546 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "path.h" -+#include "log.h" -+ -+lxc_log_define(lxc_path_ui, lxc); -+ -+#define ISSLASH(C) ((C) == '/') -+#define IS_ABSOLUTE_FILE_NAME(F) (ISSLASH ((F)[0])) -+#define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F)) -+ -+bool specify_current_dir(const char *path) -+{ -+ char *basec = NULL, *bname = NULL; -+ bool res = false; -+ -+ basec = strdup(path); -+ if (!basec) { -+ ERROR("Out of memory"); -+ return false; -+ } -+ -+ bname = basename(basec); -+ res = !strcmp(bname, "."); -+ free(basec); -+ return res; -+} -+ -+bool has_traling_path_separator(const char *path) -+{ -+ return path && strlen(path) && (path[strlen(path) - 1] == '/'); -+} -+ -+// PreserveTrailingDotOrSeparator returns the given cleaned path -+// and appends a trailing `/.` or `/` if its corresponding original -+// path ends with a trailing `/.` or `/`. If the cleaned -+// path already ends in a `.` path segment, then another is not added. If the -+// clean path already ends in a path separator, then another is not added. -+char *preserve_trailing_dot_or_separator(const char *cleanedpath, -+ const char *originalpath) -+{ -+ char *respath = NULL; -+ size_t len; -+ -+ len = strlen(cleanedpath) + 3; -+ respath = malloc(len); -+ if (!respath) { -+ ERROR("Out of memory"); -+ return NULL; -+ } -+ memset(respath, 0x00, len); -+ strcat(respath, cleanedpath); -+ -+ if (!specify_current_dir(cleanedpath) && specify_current_dir(originalpath)) { -+ if (!has_traling_path_separator(respath)) -+ strcat(respath, "/"); -+ strcat(respath, "."); -+ } -+ -+ if (!has_traling_path_separator(respath) && -+ has_traling_path_separator(originalpath)) -+ strcat(respath, "/"); -+ -+ return respath; -+} -+ -+ -+// Split splits path immediately following the final Separator, -+// separating it into a directory and file name component. -+// If there is no Separator in path, Split returns an empty dir -+// and file set to path. -+// The returned values have the property that path = dir+file. -+bool filepath_split(const char *path, char **dir, char **base) -+{ -+ ssize_t i; -+ size_t len; -+ -+ len = strlen(path); -+ i = len - 1; -+ while (i >= 0 && path[i] != '/') -+ i--; -+ -+ *dir = malloc(i + 2); -+ if (!*dir) { -+ ERROR("Out of memory"); -+ return false; -+ } -+ memcpy(*dir, path, i + 1); -+ *(*dir + i + 1) = '\0'; -+ -+ *base = strdup(path + i + 1); -+ if (!*base) { -+ ERROR("Out of memory"); -+ free(*dir); -+ *dir = NULL; -+ return false; -+ } -+ -+ return true; -+} -+ -+/* -+ * cleanpath is similar to realpath of glibc, but not expands symbolic links, -+ * and not check the existence of components of the path. -+ */ -+char *cleanpath(const char *path, char *resolved) -+{ -+ char *rpath, *dest; -+ const char *start, *end, *rpath_limit; -+ -+ if (path == NULL || path[0] == '\0') -+ return NULL; -+ -+ if (resolved == NULL) { -+ rpath = malloc(PATH_MAX); -+ if (rpath == NULL) { -+ ERROR("Out of memory"); -+ return NULL; -+ } -+ } else { -+ rpath = resolved; -+ } -+ rpath_limit = rpath + PATH_MAX; -+ -+ if (!IS_ABSOLUTE_FILE_NAME(path)) { -+ if (!getcwd(rpath, PATH_MAX)) { -+ ERROR("Failed to getcwd"); -+ rpath[0] = '\0'; -+ goto error; -+ } -+ dest = strchr(rpath, '\0'); -+ start = path; -+ } else { -+ dest = rpath; -+ *dest++ = '/'; -+ start = path; -+ } -+ -+ for (end = start; *start; start = end) { -+ /* Skip sequence of multiple path-separators. */ -+ while (ISSLASH(*start)) -+ ++start; -+ -+ /* Find end of path component. */ -+ for (end = start; *end && !ISSLASH(*end); ++end) -+ /* Nothing. */; -+ -+ if (end - start == 0) { -+ break; -+ } else if (end - start == 1 && start[0] == '.') { -+ /* nothing */; -+ } else if (end - start == 2 && start[0] == '.' && start[1] == '.') { -+ /* Back up to previous component, ignore if at root already. */ -+ if (dest > rpath + 1) -+ for (--dest; dest > rpath && !ISSLASH(dest[-1]); --dest) -+ continue; -+ } else { -+ size_t new_size; -+ -+ if (!ISSLASH(dest[-1])) -+ *dest++ = '/'; -+ -+ if (dest + (end - start) >= rpath_limit) { -+ long long dest_offset = dest - rpath; -+ char *new_rpath; -+ -+ if (resolved) { -+ printf("Path is to long"); -+ if (dest > rpath + 1) -+ dest--; -+ *dest = '\0'; -+ goto error; -+ } -+ -+ new_size = rpath_limit - rpath; -+ if (end - start + 1 > PATH_MAX) -+ new_size += end - start + 1; -+ else -+ new_size += PATH_MAX; -+ new_rpath = (char *) realloc(rpath, new_size); -+ if (new_rpath == NULL) { -+ ERROR("Out of memory"); -+ goto error; -+ } -+ rpath = new_rpath; -+ rpath_limit = rpath + new_size; -+ -+ dest = rpath + dest_offset; -+ } -+ -+ memcpy(dest, start, end - start); -+ dest += end - start; -+ *dest = '\0'; -+ } -+ } -+ if (dest > rpath + 1 && ISSLASH(dest[-1])) -+ --dest; -+ *dest = '\0'; -+ -+ return rpath; -+ -+error: -+ if (resolved == NULL) -+ free(rpath); -+ return NULL; -+} -+ -+// evalSymlinksInScope will evaluate symlinks in `path` within a scope `root` and return -+// a result guaranteed to be contained within the scope `root`, at the time of the call. -+// Symlinks in `root` are not evaluated and left as-is. -+// Errors encountered while attempting to evaluate symlinks in path will be returned. -+// Non-existing paths are valid and do not constitute an error. -+// `path` has to contain `root` as a prefix, or else an error will be returned. -+// Trying to break out from `root` does not constitute an error. -+// -+// Example: -+// If /foo/bar -> /outside, -+// FollowSymlinkInScope("/foo/bar", "/foo") == "/foo/outside" instead of "/oustide" -+char *eval_symlinks_in_scope(const char *fullpath, const char *rootpath) -+{ -+ char resroot[PATH_MAX] = {0}, *root = NULL; -+ char *rpath, *dest, *prefix, *extra_buf = NULL; -+ const char *start, *end, *rpath_limit; -+ int num_links = 0; -+ size_t prefix_len; -+ -+ if (!fullpath || !rootpath) -+ return NULL; -+ -+ root = cleanpath(rootpath, resroot); -+ if (!root) { -+ ERROR("Failed to get cleaned path"); -+ return NULL; -+ } -+ -+ if (!strcmp(fullpath, root)) -+ return strdup(fullpath); -+ -+ if (!strstr(fullpath, root)) { -+ ERROR("Path '%s' is not in '%s'", fullpath, root); -+ return NULL; -+ } -+ -+ rpath = malloc(PATH_MAX); -+ if (rpath == NULL) { -+ ERROR("Out of memory"); -+ goto error; -+ return NULL; -+ } -+ rpath_limit = rpath + PATH_MAX; -+ -+ prefix = root; -+ prefix_len = strlen(prefix); -+ if (!strcmp(prefix, "/")) -+ prefix_len = 0; -+ -+ dest = rpath; -+ if (prefix_len) { -+ memcpy(rpath, prefix, prefix_len); -+ dest += prefix_len; -+ } -+ *dest++ = '/'; -+ start = fullpath + prefix_len; -+ -+ for (end = start; *start; start = end) { -+ struct stat st; -+ int n; -+ -+ /* Skip sequence of multiple path-separators. */ -+ while (ISSLASH(*start)) -+ ++start; -+ -+ /* Find end of path component. */ -+ for (end = start; *end && !ISSLASH(*end); ++end) -+ /* Nothing. */; -+ -+ if (end - start == 0) { -+ break; -+ } else if (end - start == 1 && start[0] == '.') { -+ /* nothing */; -+ } else if (end - start == 2 && start[0] == '.' && start[1] == '.') { -+ /* Back up to previous component, ignore if at root already. */ -+ if (dest > rpath + prefix_len + 1) -+ for (--dest; dest > rpath && !ISSLASH(dest[-1]); --dest) -+ continue; -+ } else { -+ size_t new_size; -+ -+ if (!ISSLASH(dest[-1])) -+ *dest++ = '/'; -+ -+ if (dest + (end - start) >= rpath_limit) { -+ long long dest_offset = dest - rpath; -+ char *new_rpath; -+ -+ new_size = rpath_limit - rpath; -+ if (end - start + 1 > PATH_MAX) -+ new_size += end - start + 1; -+ else -+ new_size += PATH_MAX; -+ new_rpath = (char *) realloc(rpath, new_size); -+ if (new_rpath == NULL) { -+ ERROR("Out of memory"); -+ goto error; -+ } -+ rpath = new_rpath; -+ rpath_limit = rpath + new_size; -+ -+ dest = rpath + dest_offset; -+ } -+ -+ memcpy(dest, start, end - start); -+ dest += end - start; -+ *dest = '\0'; -+ -+ if (lstat(rpath, &st) < 0) { -+ // if rpath does not exist, accept it -+ continue; -+ } -+ -+ if (S_ISLNK(st.st_mode)) { -+ char *buf; -+ size_t len; -+ -+ if (++num_links > MAXSYMLINKS) { -+ ERROR("Too many links in '%s'", fullpath); -+ goto error; -+ } -+ -+ buf = malloc(PATH_MAX); -+ if (!buf) { -+ ERROR("Out of memory"); -+ goto error; -+ } -+ -+ n = readlink(rpath, buf, PATH_MAX - 1); -+ if (n < 0) { -+ free(buf); -+ goto error; -+ } -+ buf[n] = '\0'; -+ -+ if (!extra_buf) { -+ extra_buf = malloc(PATH_MAX); -+ if (!extra_buf) { -+ ERROR("Out of memory"); -+ free(buf); -+ goto error; -+ } -+ } -+ -+ len = strlen(end); -+ if ((long int)(n + len) >= PATH_MAX) { -+ free(buf); -+ ERROR("Path is too long"); -+ goto error; -+ } -+ -+ /* Careful here, end may be a pointer into extra_buf... */ -+ memmove(&extra_buf[n], end, len + 1); -+ fullpath = end = memcpy(extra_buf, buf, n); -+ -+ if (IS_ABSOLUTE_FILE_NAME(buf)) { -+ if (prefix_len) -+ memcpy(rpath, prefix, prefix_len); -+ dest = rpath + prefix_len; -+ *dest++ = '/'; /* It's an absolute symlink */ -+ } else { -+ /* Back up to previous component, ignore if at root -+ already: */ -+ if (dest > rpath + prefix_len + 1) -+ for (--dest; dest > rpath && !ISSLASH(dest[-1]); --dest) -+ continue; -+ } -+ } -+ } -+ } -+ if (dest > rpath + prefix_len + 1 && ISSLASH(dest[-1])) -+ --dest; -+ *dest = '\0'; -+ -+ if (extra_buf) -+ free(extra_buf); -+ -+ return rpath; -+ -+error: -+ if (extra_buf) -+ free(extra_buf); -+ free(rpath); -+ return NULL; -+} -+ -+// FollowSymlinkInScope is a wrapper around evalSymlinksInScope that returns an -+// absolute path. This function handles paths in a platform-agnostic manner. -+char *follow_symlink_in_scope(const char *fullpath, const char *rootpath) -+{ -+ char resfull[PATH_MAX] = {0}, *full = NULL; -+ char resroot[PATH_MAX] = {0}, *root = NULL; -+ -+ full = cleanpath(fullpath, resfull); -+ if (!full) { -+ ERROR("Failed to get cleaned path"); -+ return NULL; -+ } -+ -+ root = cleanpath(rootpath, resroot); -+ if (!root) { -+ ERROR("Failed to get cleaned path"); -+ return NULL; -+ } -+ -+ return eval_symlinks_in_scope(full, root); -+} -+ -+// GetResourcePath evaluates `path` in the scope of the container's rootpath, with proper path -+// sanitisation. Symlinks are all scoped to the rootpath of the container, as -+// though the container's rootpath was `/`. -+// -+// The BaseFS of a container is the host-facing path which is bind-mounted as -+// `/` inside the container. This method is essentially used to access a -+// particular path inside the container as though you were a process in that -+// container. -+int get_resource_path(const char *rootpath, const char *path, -+ char **scopepath) -+{ -+ char resolved[PATH_MAX] = {0}, *cleanedpath = NULL; -+ char *fullpath = NULL; -+ size_t len; -+ -+ if (!rootpath || !path || !scopepath) -+ return -1; -+ -+ *scopepath = NULL; -+ -+ cleanedpath = cleanpath(path, resolved); -+ if (!cleanedpath) { -+ ERROR("Failed to get cleaned path"); -+ return -1; -+ } -+ -+ len = strlen(rootpath) + strlen(cleanedpath) + 1; -+ fullpath = malloc(len); -+ if (!fullpath) { -+ ERROR("Out of memory"); -+ return -1; -+ } -+ snprintf(fullpath, len, "%s%s", rootpath, cleanedpath); -+ -+ *scopepath = follow_symlink_in_scope(fullpath, rootpath); -+ -+ free(fullpath); -+ return 0; -+} -+ -+// Rel returns a relative path that is lexically equivalent to targpath when -+// joined to basepath with an intervening separator. That is, -+// Join(basepath, Rel(basepath, targpath)) is equivalent to targpath itself. -+// On success, the returned path will always be relative to basepath, -+// even if basepath and targpath share no elements. -+// An error is returned if targpath can't be made relative to basepath or if -+// knowing the current working directory would be necessary to compute it. -+// Rel calls Clean on the result. -+char *path_relative(const char *basepath, const char *targpath) -+{ -+ char resbase[PATH_MAX] = {0}, *base = NULL; -+ char restarg[PATH_MAX] = {0}, *targ = NULL; -+ size_t bl = 0, tl = 0, b0 = 0, bi = 0, t0 = 0, ti = 0; -+ -+ base = cleanpath(basepath, resbase); -+ if (!base) { -+ ERROR("Failed to get cleaned path"); -+ return NULL; -+ } -+ -+ targ = cleanpath(targpath, restarg); -+ if (!targ) { -+ ERROR("Failed to get cleaned path"); -+ return NULL; -+ } -+ -+ if (strcmp(base, targ) == 0) -+ return strdup("."); -+ -+ bl = strlen(base); -+ tl = strlen(targ); -+ while(true) { -+ while(bi < bl && !ISSLASH(base[bi])) -+ bi++; -+ while(ti < tl && !ISSLASH(targ[ti])) -+ ti++; -+ //not the same string -+ if (((bi - b0) != (ti - t0)) || strncmp(base + b0, targ + t0, bi - b0)) -+ break; -+ if (bi < bl) -+ bi++; -+ if (ti < tl) -+ ti++; -+ b0 = bi; -+ t0 = ti; -+ } -+ -+ if (b0 != bl) { -+ // Base elements left. Must go up before going down. -+ int seps = 0, i; -+ size_t ncopyed = 0, seps_size; -+ char *buf; -+ -+ for (bi = b0; bi < bl; bi++) { -+ if (ISSLASH(base[bi])) -+ seps++; -+ } -+ //strlen(..) + strlen(/..) + '\0' -+ seps_size = 2 + seps * 3 + 1; -+ if (t0 != tl) -+ seps_size += 1 + tl - t0; -+ -+ buf = calloc(seps_size, 1); -+ if (!buf) { -+ ERROR("Out of memory"); -+ return NULL; -+ } -+ buf[ncopyed++] = '.'; -+ buf[ncopyed++] = '.'; -+ for (i = 0; i < seps; i++) { -+ buf[ncopyed++] = '/'; -+ buf[ncopyed++] = '.'; -+ buf[ncopyed++] = '.'; -+ } -+ if (t0 != tl) { -+ buf[ncopyed++] = '/'; -+ memcpy(buf + ncopyed, targ + t0, tl - t0 + 1); -+ } -+ return buf; -+ } -+ -+ return strdup(targ + t0); -+} -\ No newline at end of file -diff --git a/src/lxc/path.h b/src/lxc/path.h -new file mode 100644 -index 0000000..e3a04cc ---- /dev/null -+++ b/src/lxc/path.h -@@ -0,0 +1,70 @@ -+#ifndef __LCRD_PATH_H_ -+#define __LCRD_PATH_H_ -+ -+#include -+ -+bool specify_current_dir(const char *path); -+ -+bool has_traling_path_separator(const char *path); -+ -+// PreserveTrailingDotOrSeparator returns the given cleaned path -+// and appends a trailing `/.` or `/` if its corresponding original -+// path ends with a trailing `/.` or `/`. If the cleaned -+// path already ends in a `.` path segment, then another is not added. If the -+// clean path already ends in a path separator, then another is not added. -+char *preserve_trailing_dot_or_separator(const char *cleanedpath, -+ const char *originalpath); -+ -+ -+// Split splits path immediately following the final Separator, -+// separating it into a directory and file name component. -+// If there is no Separator in path, Split returns an empty dir -+// and file set to path. -+// The returned values have the property that path = dir+file. -+bool filepath_split(const char *path, char **dir, char **base); -+ -+/* -+ * cleanpath is similar to realpath of glibc, but not expands symbolic links, -+ * and not check the existence of components of the path. -+ */ -+char *cleanpath(const char *path, char *resolved); -+ -+// evalSymlinksInScope will evaluate symlinks in `path` within a scope `root` and return -+// a result guaranteed to be contained within the scope `root`, at the time of the call. -+// Symlinks in `root` are not evaluated and left as-is. -+// Errors encountered while attempting to evaluate symlinks in path will be returned. -+// Non-existing paths are valid and do not constitute an error. -+// `path` has to contain `root` as a prefix, or else an error will be returned. -+// Trying to break out from `root` does not constitute an error. -+// -+// Example: -+// If /foo/bar -> /outside, -+// FollowSymlinkInScope("/foo/bar", "/foo") == "/foo/outside" instead of "/oustide" -+char *eval_symlinks_in_scope(const char *fullpath, const char *rootpath); -+ -+// FollowSymlinkInScope is a wrapper around evalSymlinksInScope that returns an -+// absolute path. This function handles paths in a platform-agnostic manner. -+char *follow_symlink_in_scope(const char *fullpath, const char *rootpath); -+ -+// GetResourcePath evaluates `path` in the scope of the container's rootpath, with proper path -+// sanitisation. Symlinks are all scoped to the rootpath of the container, as -+// though the container's rootpath was `/`. -+// -+// The BaseFS of a container is the host-facing path which is bind-mounted as -+// `/` inside the container. This method is essentially used to access a -+// particular path inside the container as though you were a process in that -+// container. -+int get_resource_path(const char *rootpath, const char *path, -+ char **scopepath); -+ -+// Rel returns a relative path that is lexically equivalent to targpath when -+// joined to basepath with an intervening separator. That is, -+// Join(basepath, Rel(basepath, targpath)) is equivalent to targpath itself. -+// On success, the returned path will always be relative to basepath, -+// even if basepath and targpath share no elements. -+// An error is returned if targpath can't be made relative to basepath or if -+// knowing the current working directory would be necessary to compute it. -+// Rel calls Clean on the result. -+char *path_relative(const char *basepath, const char *targpath); -+ -+#endif --- -1.8.3.1 - diff --git a/0024-start-do-not-check-ppid-when-set-death-signal.patch b/0024-start-do-not-check-ppid-when-set-death-signal.patch new file mode 100644 index 0000000000000000000000000000000000000000..64e62af805e440a134cff52430abb8009df21b9e --- /dev/null +++ b/0024-start-do-not-check-ppid-when-set-death-signal.patch @@ -0,0 +1,40 @@ +From 52b97324185142285f78143509244d88c6962826 Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Tue, 14 Apr 2020 17:38:44 +0800 +Subject: [PATCH 24/49] start: do not check ppid when set death signal + +Signed-off-by: LiFeng +--- + src/lxc/utils.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/lxc/utils.c b/src/lxc/utils.c +index 5b04fa4..27078e2 100644 +--- a/src/lxc/utils.c ++++ b/src/lxc/utils.c +@@ -1734,11 +1734,14 @@ static int process_dead(/* takes */ int status_fd) + int lxc_set_death_signal(int signal, pid_t parent, int parent_status_fd) + { + int ret; ++#ifndef HAVE_ISULAD + pid_t ppid; ++#endif + + ret = prctl(PR_SET_PDEATHSIG, prctl_arg(signal), prctl_arg(0), + prctl_arg(0), prctl_arg(0)); + ++#ifndef HAVE_ISULAD + /* verify that we haven't been orphaned in the meantime */ + ppid = (pid_t)syscall(SYS_getppid); + if (ppid == 0) { /* parent outside our pidns */ +@@ -1750,6 +1753,7 @@ int lxc_set_death_signal(int signal, pid_t parent, int parent_status_fd) + } else if (ppid != parent) { + return raise(SIGKILL); + } ++#endif + + if (ret < 0) + return -1; +-- +1.8.3.1 + diff --git a/0025-support-oci-hooks.patch b/0025-support-oci-hooks.patch index b2fe665eeeadc115798166c96dea2ac6df07e610..a2acd2446db7a8fd536ff9289db981a94c94c63f 100644 --- a/0025-support-oci-hooks.patch +++ b/0025-support-oci-hooks.patch @@ -1,130 +1,57 @@ -From 38eef3f6000e2c4219007cf0f3638ef101fc67fb Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Mon, 14 Jan 2019 17:47:17 +0800 -Subject: [PATCH 025/140] support oci hooks +From 52aa8985248200041b2a093634a8c36cb4bb8414 Mon Sep 17 00:00:00 2001 +From: haozi007 +Date: Tue, 14 Apr 2020 18:33:53 +0800 +Subject: [PATCH 25/49] support oci hooks -support oci hooks - -Signed-off-by: LiFeng +Signed-off-by: haozi007 --- - configure.ac | 3 + - src/lxc/Makefile.am | 13 +- - src/lxc/conf.c | 528 ++++++++++++++++- - src/lxc/conf.h | 9 + - src/lxc/json/defs.c | 198 +++++++ - src/lxc/json/defs.h | 37 ++ - src/lxc/json/json_common.c | 1196 ++++++++++++++++++++++++++++++++++++++ - src/lxc/json/json_common.h | 185 ++++++ - src/lxc/json/oci_runtime_hooks.c | 53 ++ - src/lxc/json/oci_runtime_hooks.h | 15 + - src/lxc/json/oci_runtime_spec.c | 196 +++++++ - src/lxc/json/oci_runtime_spec.h | 37 ++ - src/lxc/json/read-file.c | 94 +++ - src/lxc/json/read-file.h | 11 + - src/lxc/lxccontainer.c | 66 +++ - src/lxc/lxccontainer.h | 7 + - src/lxc/start.c | 17 + - src/lxc/utils.c | 66 ++- - src/lxc/utils.h | 2 + - 19 files changed, 2716 insertions(+), 17 deletions(-) - create mode 100644 src/lxc/json/defs.c - create mode 100644 src/lxc/json/defs.h - create mode 100755 src/lxc/json/json_common.c - create mode 100755 src/lxc/json/json_common.h - create mode 100644 src/lxc/json/oci_runtime_hooks.c - create mode 100644 src/lxc/json/oci_runtime_hooks.h - create mode 100644 src/lxc/json/oci_runtime_spec.c - create mode 100644 src/lxc/json/oci_runtime_spec.h - create mode 100644 src/lxc/json/read-file.c - create mode 100644 src/lxc/json/read-file.h + 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(+) -diff --git a/configure.ac b/configure.ac -index 950c8dd..4da52a2 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -120,6 +120,9 @@ AM_CONDITIONAL([DISTRO_UBUNTU], [test "x$with_distro" = "xubuntu"]) - - AC_CONFIG_LINKS([config/etc/default.conf:config/etc/${distroconf}]) - -+# Check yajl -+PKG_CHECK_MODULES([YAJL], [yajl >= 2],[],[AC_MSG_ERROR([You must install yajl >= 2])]) -+ - # Check for init system type - AC_MSG_CHECKING([for init system type]) - AC_ARG_WITH([init-script], -diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am -index f2928b7..5678b8d 100644 ---- a/src/lxc/Makefile.am -+++ b/src/lxc/Makefile.am -@@ -43,6 +43,11 @@ noinst_HEADERS = attach.h \ - ../tests/lxctest.h \ - tools/arguments.h \ - storage/storage_utils.h \ -+ json/defs.h \ -+ json/json_common.h \ -+ json/oci_runtime_hooks.h \ -+ json/oci_runtime_spec.h \ -+ json/read-file.h \ - utils.h - - if IS_BIONIC -@@ -140,6 +145,11 @@ liblxc_la_SOURCES = af_unix.c af_unix.h \ - terminal.c \ - utils.c utils.h \ - version.h \ -+ json/json_common.c json/json_common.h \ -+ json/defs.h json/defs.c \ -+ json/oci_runtime_hooks.c json/oci_runtime_hooks.h \ -+ json/oci_runtime_spec.c json/oci_runtime_spec.h \ -+ json/read-file.c json/read-file.h \ - $(LSM_SOURCES) - - if IS_BIONIC -@@ -192,6 +202,7 @@ AM_CFLAGS = -DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \ - -I $(top_srcdir)/src \ - -I $(top_srcdir)/src/lxc \ - -I $(top_srcdir)/src/lxc/storage \ -+ -I $(top_srcdir)/src/lxc/json \ - -I $(top_srcdir)/src/lxc/cgroups - - if ENABLE_APPARMOR -@@ -224,7 +235,7 @@ liblxc_la_CFLAGS = -fPIC \ - liblxc_la_LDFLAGS = -pthread \ - -Wl,-no-undefined \ - -Wl,-soname,liblxc.so.$(firstword $(subst ., ,@LXC_ABI@)) \ -- -version-info @LXC_ABI_MAJOR@ -+ -version-info @LXC_ABI_MAJOR@ @YAJL_LIBS@ - - liblxc_la_LIBADD = $(CAP_LIBS) \ - $(GNUTLS_LIBS) \ diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 800573a..6a14de1 100644 +index e0a6f98..71fd6f9 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c -@@ -53,6 +53,7 @@ - #include +@@ -33,6 +33,11 @@ #include #include -+#include ++#ifdef HAVE_ISULAD ++#include ++#include "sync.h" ++#endif ++ #include "af_unix.h" #include "caps.h" -@@ -137,7 +138,10 @@ char *lxchook_names[NUM_LXC_HOOKS] = { + #include "cgroup.h" +@@ -121,7 +126,14 @@ char *lxchook_names[NUM_LXC_HOOKS] = { "post-stop", "clone", "destroy", -- "start-host" ++#ifdef HAVE_ISULAD + "start-host", + "oci-prestart", + "oci-poststart", + "oci-poststop" ++#else + "start-host" ++#endif }; struct mount_opt { -@@ -4082,13 +4086,530 @@ int lxc_setup(struct lxc_handler *handler) +@@ -3947,6 +3959,530 @@ static int setup_rootfs_mountopts(const struct lxc_rootfs *rootfs) + } return 0; } - ++ +struct oci_hook_conf { + defs_hook *ocihook; + @@ -156,18 +83,26 @@ index 800573a..6a14de1 100644 + ERROR("Get container %s pid failed: %s", name, strerror(errno)); + cpid = "-1"; + } -+ // {"ociVersion":"","id":"xxx","pid":777,"root":"xxx","bundlePath":"xxx"} -+ size = 1 + 16 + 5 + strlen(name) + 3 + 6 + strlen(cpid) + 1 -+ + 7 + strlen(rootfs) + 3 + 13 + strlen(lxcpath) + 1 + strlen(name) + 3 + 1; ++ ++ 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; + inmsg = malloc(size); -+ if (!inmsg) { ++ if (inmsg == NULL) { + ERROR("Out of memory"); + ret = -1; + goto out_free; + } + rc = snprintf(inmsg, size, -+ "{\"ociVersion\":\"\",\"id\":\"%s\",\"pid\":%s,\"root\":\"%s\",\"bundlePath\":\"%s/%s\"}", -+ name, cpid, rootfs, lxcpath, name); ++ "{\"ociVersion\":\"\",\"id\":\"%s\",\"pid\":%s,\"root\":\"%s\",\"bundle\":\"%s/%s\"}", ++ name, cpid, rootfs, lxcpath, name); + if (rc < 0 || rc >= size) { + ERROR("Create json string failed"); + ret = -1; @@ -183,34 +118,43 @@ index 800573a..6a14de1 100644 + +static char **merge_ocihook_env(char **oldenvs, size_t env_len, size_t *merge_env_len) +{ -+ char **result; ++ char **result = NULL; + size_t result_len = env_len; + size_t i, j; -+ char *tmpenv; -+ char *lxc_envs[] = {"LXC_CGNS_AWARE", "LXC_PID", "LXC_ROOTFS_MOUNT", -+ "LXC_CONFIG_FILE", "LXC_CGROUP_PATH", "LXC_ROOTFS_PATH", "LXC_NAME"}; -+ char *lxcenv_buf; ++ 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; + ++ if (result_len > SIZE_MAX - (sizeof(lxc_envs) / sizeof(char *)) - 1) ++ return NULL; + result_len += (sizeof(lxc_envs) / sizeof(char *)) + 1; + result = malloc(sizeof(char *) * result_len); -+ if (!result) ++ if (result == NULL) + return NULL; + memset(result, 0, sizeof(char *) * result_len); + + for(i = 0; i < env_len; i++) { + if (oldenvs[i]) -+ result[i] = strdup(oldenvs[i]); ++ result[i] = safe_strdup(oldenvs[i]); + } + + for(j = 0; j < (sizeof(lxc_envs) / sizeof(char *)); j++) { ++ size_t env_buf_len = 0; + tmpenv = getenv(lxc_envs[j]); + if (tmpenv && i < (result_len - 1)) { -+ lxcenv_buf = malloc(strlen(tmpenv) + 1 + strlen(lxc_envs[j]) + 1); -+ if (!lxcenv_buf) { ++ 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) { + lxc_free_array((void **)result, free); + return NULL; + } -+ if (sprintf(lxcenv_buf, "%s=%s", lxc_envs[j], tmpenv) < 0) { ++ if (snprintf(lxcenv_buf, env_buf_len, "%s=%s", lxc_envs[j], tmpenv) < 0) { + free(lxcenv_buf); + continue; + } @@ -223,8 +167,8 @@ index 800573a..6a14de1 100644 + return result; +} + -+static struct lxc_popen_FILE *lxc_popen_ocihook(char *commandpath, char **args, int args_len, -+ char **envs, int env_len, const char *instr) ++static struct lxc_popen_FILE *lxc_popen_ocihook(const char *commandpath, char **args, int args_len, ++ char **envs, int env_len, const char *instr) +{ + int ret; + struct lxc_popen_FILE *fp = NULL; @@ -249,17 +193,12 @@ index 800573a..6a14de1 100644 + goto on_error; + + if (child_pid == 0) { -+ /* child */ -+ size_t result_capacity; -+ int r; -+ char **real_args; -+ + 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) { -+ SYSERROR("Failed to remove FD_CLOEXEC from fd."); ++ fprintf(stderr, "Failed to remove FD_CLOEXEC from fd."); + exit(127); + } + } @@ -286,6 +225,11 @@ index 800573a..6a14de1 100644 + if (ret < 0) + _exit(EXIT_FAILURE); + ++ if (lxc_check_inherited(NULL, true, NULL, 0) != 0) { ++ fprintf(stderr, "check inherited fd failed"); ++ exit(127); ++ } ++ + /* + * Unblock signals. + * This is the main/only reason @@ -297,20 +241,11 @@ index 800573a..6a14de1 100644 + sigprocmask(SIG_UNBLOCK, &mask, NULL); + } + -+ result_capacity = args_len; -+ real_args = malloc(sizeof(char *) * (result_capacity + 2 + 1)); -+ if (!real_args) -+ _exit(EXIT_FAILURE); -+ memset(real_args, 0, sizeof(char *) * (result_capacity + 2 + 1)); -+ real_args[0] = strdup("sh"); -+ real_args[1] = strdup(commandpath); -+ for(r = 2; r < (args_len + 1); r++) -+ real_args[r] = strdup(args[r-1]); -+ + if (env_len > 0) -+ execvpe("/bin/sh", real_args, envs); ++ execvpe(commandpath, args, envs); + else -+ execvp("/bin/sh", real_args); ++ execvp(commandpath, args); ++ fprintf(stderr, "fork/exec %s: %s", commandpath, strerror(errno)); + exit(127); + } + @@ -375,16 +310,12 @@ index 800573a..6a14de1 100644 + + if (alive) { + ERROR("%s:%d: running %s hook caused \"hook ran past specified timeout of %.1fs\"", -+ __FILE__, __LINE__, -+ (conf->which == LXCHOOK_START_HOST) ? "prestart" : lxchook_names[conf->which], -+ (double)conf->timeout); -+ -+ if (conf->errfd >= 0) { -+ lxc_write_error_message(conf->errfd, "%s:%d: running %s hook caused \"hook ran past specified timeout of %.1fs\"", -+ __FILE__, __LINE__, -+ (conf->which == LXCHOOK_START_HOST) ? "prestart" : lxchook_names[conf->which], -+ (double)conf->timeout); -+ } ++ __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); + + if (kill(conf->pid, SIGKILL) && errno != ESRCH) { + ERROR("Send kill signal failed"); @@ -397,7 +328,7 @@ index 800573a..6a14de1 100644 + return ((void *)0); +} + -+static int run_ocihook_buffer(struct oci_hook_conf *oconf, char *inmsg) ++static int run_ocihook_buffer(struct oci_hook_conf *oconf, const char *inmsg) +{ + struct lxc_popen_FILE *f; + char output[LXC_LOG_BUFFER_SIZE] = {0}; @@ -426,7 +357,7 @@ index 800573a..6a14de1 100644 + } + + conf = malloc(sizeof(struct wait_conf)); -+ if (!conf) { ++ if (conf == NULL) { + SYSERROR("Failed to malloc."); + goto on_error; + } @@ -451,6 +382,7 @@ index 800573a..6a14de1 100644 + err = pthread_create(&ptid, &attr, wait_ocihook_timeout, conf); + if (err != 0) { + ERROR("Create wait timeout thread failed"); ++ free(conf); + goto on_error; + } + @@ -464,23 +396,19 @@ index 800573a..6a14de1 100644 + SYSERROR("Script exited with error."); + goto print_hook; + } else if (WIFEXITED(ret) && WEXITSTATUS(ret) != 0) { -+ ERROR("Script exited with status %d. output:%s", WEXITSTATUS(ret), output); -+ if (conf->errfd >= 0) { -+ lxc_write_error_message(conf->errfd, "%s:%d: running %s hook caused \"error running hook: exit status %d, output:%s\"", -+ __FILE__, __LINE__, -+ (conf->which >= NUM_LXC_HOOKS) ? "invalid type" : lxchook_names[conf->which], -+ WEXITSTATUS(ret), output); -+ } ++ 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); + + goto print_hook; + } else if (WIFSIGNALED(ret)) { + ERROR("Script terminated by signal %d.", WTERMSIG(ret)); -+ if (conf->errfd >= 0) { -+ lxc_write_error_message(conf->errfd, "%s:%d: running %s hook caused \"error running hook: Script terminated by signal %d\"", -+ __FILE__, __LINE__, -+ (conf->which >= NUM_LXC_HOOKS) ? "invalid type" : lxchook_names[conf->which], -+ WTERMSIG(ret)); -+ } ++ 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)); + + goto print_hook; + } @@ -500,8 +428,8 @@ index 800573a..6a14de1 100644 + 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.", -+ buffer, err_args_msg ? err_args_msg : "", -+ err_envs_msg ? err_envs_msg : "", conf->timeout); ++ buffer, err_args_msg ? err_args_msg : "", ++ err_envs_msg ? err_envs_msg : "", oconf->ocihook->timeout); + + free(err_args_msg); + free(err_envs_msg); @@ -509,12 +437,12 @@ index 800573a..6a14de1 100644 +} + +static int run_ocihook_script_argv(const char *name, const char *section, -+ struct oci_hook_conf *oconf, -+ const char *lxcpath, const char *rootfs) ++ struct oci_hook_conf *oconf, ++ const char *lxcpath, const char *rootfs) +{ + int ret; + const char *script = oconf->ocihook->path; -+ char *inmsg; ++ char *inmsg = NULL; + + INFO("Executing script \"%s\" for container \"%s\", config section \"%s\".", + script, name, section); @@ -536,7 +464,7 @@ index 800573a..6a14de1 100644 + char *tmp = NULL; + + if (!path) { -+ ret = strdup("/"); ++ ret = safe_strdup("/"); + return ret; + } + if (!backend) { @@ -544,38 +472,37 @@ index 800573a..6a14de1 100644 + } + + if (strcmp(backend, "aufs") == 0 || -+ strcmp(backend, "overlayfs") == 0 || -+ strcmp(backend, "loop") == 0) { ++ strcmp(backend, "overlayfs") == 0 || ++ strcmp(backend, "loop") == 0) { + tmp = strrchr(path, ':'); -+ tmp++; -+ ret = strdup(tmp); -+ if (!ret) { -+ ERROR("Out of memory"); ++ if (tmp == NULL) { ++ ERROR("Invalid root path format"); + return NULL; + } ++ tmp++; ++ ret = safe_strdup(tmp); + return ret; + } + +default_out: -+ ret = strdup(path); -+ if (!ret) { -+ ERROR("Out of memory"); -+ return NULL; -+ } ++ ret = safe_strdup(path); + return ret; +} + -+static int run_oci_hooks(const char *name, const char *lxcpath, struct lxc_conf *lc, int which, int errfd) ++static int do_run_oci_hooks(const char *name, const char *lxcpath, struct lxc_conf *lc, int which, int errfd) +{ + struct oci_hook_conf work_conf = {0}; -+ oci_runtime_spec_hooks *ocihooks = NULL; + size_t i; + int ret = 0; -+ char *rootpath; ++ int nret = 0; ++ char *rootpath = NULL; + -+ if (!lc || !lc->ocihooks) { ++ if (!lc) { + return -1; + } ++ if (!lc->ocihooks) { ++ return 0; ++ } + + rootpath = get_root_path(lc->rootfs.path, lc->rootfs.bdev_type); + if (!rootpath) { @@ -586,2456 +513,682 @@ index 800573a..6a14de1 100644 + work_conf.errfd = errfd; + work_conf.which = which; + switch (which) { -+ 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]; -+ ret = run_ocihook_script_argv(name, "lxc", &work_conf, lxcpath, rootpath); -+ if (ret != 0) -+ break; -+ } -+ break; -+ case OCI_HOOK_POSTSTOP: -+ for (i = 0; i < lc->ocihooks->poststop_len; i++) { -+ work_conf.ocihook = lc->ocihooks->poststop[i]; -+ ret = run_ocihook_script_argv(name, "lxc", &work_conf, lxcpath, rootpath); -+ if (ret != 0) -+ break; -+ } -+ break; -+ default: -+ ret = -1; ++ 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; + } + if (rootpath) + free(rootpath); + return ret; +} + - int run_lxc_hooks(const char *name, char *hookname, struct lxc_conf *conf, - char *argv[]) - { - struct lxc_list *it; - int which = -1; - -- if (strcmp(hookname, "pre-start") == 0) ++int run_oci_hooks(const char *name, const char *hookname, struct lxc_conf *conf, const char *lxcpath) ++{ ++ int which = -1; ++ + if (strcmp(hookname, "oci-prestart") == 0) { -+ int ret; + which = OCI_HOOK_PRESTART; -+ if (!argv || !argv[0]) { ++ if (!lxcpath) { + ERROR("oci hook require lxcpath"); + return -1; + } -+ return run_oci_hooks(name, argv[0], conf, which, conf->errpipe[1]); ++ return do_run_oci_hooks(name, lxcpath, conf, which, conf->errpipe[1]); + } else if (strcmp(hookname, "oci-poststart") == 0) { -+ int ret; + which = OCI_HOOK_POSTSTART; -+ if (!argv || !argv[0]) { ++ if (!lxcpath) { + ERROR("oci hook require lxcpath"); + return -1; + } -+ return run_oci_hooks(name, argv[0], conf, which, conf->errpipe[1]); ++ return do_run_oci_hooks(name, lxcpath, conf, which, conf->errpipe[1]); + } else if (strcmp(hookname, "oci-poststop") == 0) { -+ int ret; + which = OCI_HOOK_POSTSTOP; -+ if (!argv || !argv[0]) { ++ if (!lxcpath) { + ERROR("oci hook require lxcpath"); + return -1; + } -+ return run_oci_hooks(name, argv[0], conf, which, conf->errpipe[1]); -+ } else if (strcmp(hookname, "pre-start") == 0) - which = LXCHOOK_PRESTART; - else if (strcmp(hookname, "start-host") == 0) - which = LXCHOOK_START_HOST; -@@ -4476,6 +4997,9 @@ void lxc_conf_free(struct lxc_conf *conf) ++ 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"); - if (current_config == conf) - current_config = NULL; -+ // isulad: free oci hooks -+ if (conf->ocihooks) -+ free_oci_runtime_spec_hooks(conf->ocihooks); - lxc_terminal_conf_free(&conf->console); - free(conf->rootfs.mount); - free(conf->rootfs.bdev_type); ++#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"); diff --git a/src/lxc/conf.h b/src/lxc/conf.h -index 7393dbf..2263e47 100644 +index 22c554d..61c3383 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h -@@ -35,6 +35,7 @@ - #include - #include +@@ -23,6 +23,10 @@ + #include "start.h" + #include "terminal.h" ++#ifdef HAVE_ISULAD +#include "oci_runtime_hooks.h" - #include "compiler.h" - #include "config.h" - #include "list.h" -@@ -239,6 +240,9 @@ enum lxchooks { ++#endif ++ + #if HAVE_SYS_RESOURCE_H + #include + #endif +@@ -212,6 +216,11 @@ enum lxchooks { LXCHOOK_CLONE, LXCHOOK_DESTROY, LXCHOOK_START_HOST, ++#ifdef HAVE_ISULAD + OCI_HOOK_PRESTART, + OCI_HOOK_POSTSTART, + OCI_HOOK_POSTSTOP, ++#endif NUM_LXC_HOOKS }; -@@ -307,6 +311,11 @@ struct lxc_conf { - struct lxc_list hooks[NUM_LXC_HOOKS]; - }; +@@ -433,6 +442,11 @@ struct lxc_conf { + } shmount; + #ifdef HAVE_ISULAD + /* + * isulad: support oci hook + * */ + oci_runtime_spec_hooks *ocihooks; + - char *lsm_aa_profile; - unsigned int lsm_aa_allow_incomplete; - char *lsm_se_context; -diff --git a/src/lxc/json/defs.c b/src/lxc/json/defs.c -new file mode 100644 -index 0000000..38df2f7 ---- /dev/null -+++ b/src/lxc/json/defs.c -@@ -0,0 +1,198 @@ -+// Generated from defs.json. Do not edit! -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE -+#endif -+#include -+#include -+#include "securec.h" -+#include "defs.h" -+ -+defs_hook *make_defs_hook(yajl_val tree, struct parser_context *ctx, parser_error *err) { -+ defs_hook *ret = NULL; -+ *err = 0; -+ if (tree == NULL) -+ return ret; -+ ret = safe_malloc(sizeof(*ret)); -+ { -+ yajl_val val = get_val(tree, "path", yajl_t_string); -+ if (val) { -+ char *str = YAJL_GET_STRING(val); -+ ret->path = safe_strdup(str ? str : ""); -+ } -+ } -+ { -+ yajl_val tmp = get_val(tree, "args", yajl_t_array); -+ if (tmp && YAJL_GET_ARRAY(tmp)) { -+ size_t i; -+ ret->args_len = YAJL_GET_ARRAY(tmp)->len; -+ ret->args = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->args)); -+ for (i = 0; i < YAJL_GET_ARRAY(tmp)->len; i++) { -+ yajl_val val = YAJL_GET_ARRAY(tmp)->values[i]; -+ if (val) { -+ char *str = YAJL_GET_STRING(val); -+ ret->args[i] = safe_strdup(str ? str : ""); -+ } -+ } -+ } -+ } -+ { -+ yajl_val tmp = get_val(tree, "env", yajl_t_array); -+ if (tmp && YAJL_GET_ARRAY(tmp)) { -+ size_t i; -+ ret->env_len = YAJL_GET_ARRAY(tmp)->len; -+ ret->env = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->env)); -+ for (i = 0; i < YAJL_GET_ARRAY(tmp)->len; i++) { -+ yajl_val val = YAJL_GET_ARRAY(tmp)->values[i]; -+ if (val) { -+ char *str = YAJL_GET_STRING(val); -+ ret->env[i] = safe_strdup(str ? str : ""); -+ } -+ } -+ } -+ } -+ { -+ yajl_val val = get_val(tree, "timeout", yajl_t_number); -+ if (val) { -+ int invalid = common_safe_int(YAJL_GET_NUMBER(val), (int *)&ret->timeout); -+ if (invalid) { -+ if (asprintf(err, "Invalid value '%s' with type 'integer' for key 'timeout': %s", YAJL_GET_NUMBER(val), strerror(-invalid)) < 0) -+ *err = safe_strdup("error allocating memory"); -+ free_defs_hook(ret); -+ return NULL; -+ } -+ } -+ } -+ if (ret->path == NULL) { -+ if (asprintf(err, "Required field '%s' not present", "path") < 0) -+ *err = safe_strdup("error allocating memory"); -+ free_defs_hook(ret); -+ return NULL; -+ } -+ -+ if (tree->type == yajl_t_object && (ctx->options & PARSE_OPTIONS_STRICT)) { -+ int i; -+ for (i = 0; i < tree->u.object.len; i++) -+ if (strcmp(tree->u.object.keys[i], "path") && -+ strcmp(tree->u.object.keys[i], "args") && -+ strcmp(tree->u.object.keys[i], "env") && -+ strcmp(tree->u.object.keys[i], "timeout")) { -+ if (ctx->stderr > 0) -+ fprintf(ctx->stderr, "WARNING: unknown key found: %s\n", tree->u.object.keys[i]); -+ } -+ } -+ return ret; -+} -+ -+void free_defs_hook(defs_hook *ptr) { -+ if (!ptr) -+ return; -+ free(ptr->path); -+ ptr->path = NULL; -+ if (ptr->args) { -+ size_t i; -+ for (i = 0; i < ptr->args_len; i++) { -+ if (ptr->args[i]) { -+ free(ptr->args[i]); -+ ptr->args[i] = NULL; -+ } -+ } -+ free(ptr->args); -+ ptr->args = NULL; -+ } -+ if (ptr->env) { -+ size_t i; -+ for (i = 0; i < ptr->env_len; i++) { -+ if (ptr->env[i]) { -+ free(ptr->env[i]); -+ ptr->env[i] = NULL; -+ } -+ } -+ free(ptr->env); -+ ptr->env = NULL; -+ } -+ free(ptr); -+} -+ -+yajl_gen_status gen_defs_hook(yajl_gen g, defs_hook *ptr, struct parser_context *ctx, parser_error *err) { -+ yajl_gen_status stat = yajl_gen_status_ok; -+ *err = 0; -+ stat = reformat_start_map(g); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr && ptr->path)) { -+ char *str = ""; -+ stat = reformat_map_key(g, "path", strlen("path")); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (ptr && ptr->path) { -+ str = ptr->path; -+ } -+ stat = reformat_string(g, str, strlen(str)); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr && ptr->args)) { -+ size_t len = 0, i; -+ stat = reformat_map_key(g, "args", strlen("args")); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (ptr && ptr->args) { -+ len = ptr->args_len; -+ } -+ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) -+ yajl_gen_config(g, yajl_gen_beautify, 0); -+ stat = reformat_start_array(g); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ for (i = 0; i < len; i++) { -+ stat = reformat_string(g, ptr->args[i], strlen(ptr->args[i])); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ stat = reformat_end_array(g); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) -+ yajl_gen_config(g, yajl_gen_beautify, 1); -+ } -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr && ptr->env)) { -+ size_t len = 0, i; -+ stat = reformat_map_key(g, "env", strlen("env")); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (ptr && ptr->env) { -+ len = ptr->env_len; -+ } -+ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) -+ yajl_gen_config(g, yajl_gen_beautify, 0); -+ stat = reformat_start_array(g); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ for (i = 0; i < len; i++) { -+ stat = reformat_string(g, ptr->env[i], strlen(ptr->env[i])); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ stat = reformat_end_array(g); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) -+ yajl_gen_config(g, yajl_gen_beautify, 1); -+ } -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr && ptr->timeout)) { -+ long long int num = 0; -+ stat = reformat_map_key(g, "timeout", strlen("timeout")); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (ptr && ptr->timeout) { -+ num = (long long int)ptr->timeout; -+ } -+ stat = reformat_int(g, num); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ stat = reformat_end_map(g); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ return yajl_gen_status_ok; -+} -diff --git a/src/lxc/json/defs.h b/src/lxc/json/defs.h -new file mode 100644 -index 0000000..0bbd8ac ---- /dev/null -+++ b/src/lxc/json/defs.h -@@ -0,0 +1,37 @@ -+// Generated from defs.json. Do not edit! -+#ifndef DEFS_SCHEMA_H -+#define DEFS_SCHEMA_H -+ -+#include -+#include -+#include "json_common.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif + /* 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. + -+typedef struct { -+ char *path; + 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; + -+ char **args; -+ size_t args_len; ++ if (!c->lxc_conf) ++ c->lxc_conf = lxc_conf_init(); + -+ char **env; -+ size_t env_len; ++ if (!c->lxc_conf) ++ return false; + -+ int timeout; ++ 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; + ++ if (err) ++ free(err); ++ return true; +} -+defs_hook; + -+void free_defs_hook(defs_hook *ptr); ++/* ++ * 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; + -+defs_hook *make_defs_hook(yajl_val tree, struct parser_context *ctx, parser_error *err); ++ if (!c->config_path) ++ return false; + -+yajl_gen_status gen_defs_hook(yajl_gen g, defs_hook *ptr, struct parser_context *ctx, parser_error *err); ++ /* $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; + -+#ifdef __cplusplus -+} -+#endif ++ newpath = malloc(len); ++ if (newpath == NULL) ++ return false; + -+#endif -diff --git a/src/lxc/json/json_common.c b/src/lxc/json/json_common.c -new file mode 100755 -index 0000000..8b91844 ---- /dev/null -+++ b/src/lxc/json/json_common.c -@@ -0,0 +1,1196 @@ -+// Auto generated file. Do not edit! -+#define _GNU_SOURCE -+#include -+#include -+#include -+#include "json_common.h" -+ -+#define MAX_NUM_STR_LEN 21 -+ -+yajl_gen_status reformat_number(void *ctx, const char *str, size_t len) { -+ yajl_gen g = (yajl_gen) ctx; -+ return yajl_gen_number(g, str, len); -+} ++ 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; ++ } + -+yajl_gen_status reformat_uint(void *ctx, long long unsigned int num) { -+ char numstr[MAX_NUM_STR_LEN]; -+ int ret; ++ free(c->ocihookfile); ++ c->ocihookfile = newpath; + -+ ret = sprintf(numstr, "%llu", num); -+ if (ret < 0) { -+ return yajl_gen_in_error_state; -+ } -+ return reformat_number(ctx, (const char *)numstr, strlen(numstr)); ++ return true; +} ++#endif + -+yajl_gen_status reformat_int(void *ctx, long long int num) { -+ char numstr[MAX_NUM_STR_LEN]; -+ int ret; + 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 + -+ ret = sprintf(numstr, "%lld", num); -+ if (ret < 0) { -+ return yajl_gen_in_error_state; -+ } -+ return reformat_number(ctx, (const char *)numstr, strlen(numstr)); -+} + 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) + -+yajl_gen_status reformat_double(void *ctx, double num) { -+ yajl_gen g = (yajl_gen) ctx; -+ return yajl_gen_double(g, num); -+} ++/* isulad add clean resources */ ++static bool do_lxcapi_clean_container_resource(struct lxc_container *c, pid_t pid) ++{ ++ int ret; + -+yajl_gen_status reformat_string(void *ctx, const char *str, size_t len) { -+ yajl_gen g = (yajl_gen) ctx; -+ return yajl_gen_string(g, (const unsigned char *)str, len); -+} ++ if (!c) ++ return false; + -+yajl_gen_status reformat_null(void *ctx) { -+ yajl_gen g = (yajl_gen) ctx; -+ return yajl_gen_null(g); -+} ++ 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; + -+yajl_gen_status reformat_bool(void *ctx, int boolean) { -+ yajl_gen g = (yajl_gen) ctx; -+ return yajl_gen_bool(g, boolean); +} + -+yajl_gen_status reformat_map_key(void *ctx, const char *str, size_t len) { -+ yajl_gen g = (yajl_gen) ctx; -+ return yajl_gen_string(g, (const unsigned char *)str, len); -+} ++WRAP_API_1(bool, lxcapi_clean_container_resource, pid_t) + -+yajl_gen_status reformat_start_map(void *ctx) { -+ yajl_gen g = (yajl_gen) ctx; -+ return yajl_gen_map_open(g); -+} ++/* isulad get coantainer pids */ ++static bool do_lxcapi_get_container_pids(struct lxc_container *c, pid_t **pids,size_t *pids_len) ++{ ++ int ret; + -+yajl_gen_status reformat_end_map(void *ctx) { -+ yajl_gen g = (yajl_gen) ctx; -+ return yajl_gen_map_close(g); -+} ++ if (!c) ++ return false; + -+yajl_gen_status reformat_start_array(void *ctx) { -+ yajl_gen g = (yajl_gen) ctx; -+ return yajl_gen_array_open(g); -+} ++ 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; + -+yajl_gen_status reformat_end_array(void *ctx) { -+ yajl_gen g = (yajl_gen) ctx; -+ return yajl_gen_array_close(g); +} + -+bool json_gen_init(yajl_gen *g, struct parser_context *ctx) { -+ *g = yajl_gen_alloc(NULL); -+ if (NULL == *g) { -+ return false; ++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 + -+ } -+ yajl_gen_config(*g, yajl_gen_beautify, !(ctx->options & GEN_OPTIONS_SIMPLIFY)); -+ yajl_gen_config(*g, yajl_gen_validate_utf8, 1); -+ return true; -+} + 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; + -+yajl_val get_val(yajl_val tree, const char *name, yajl_type type) { -+ const char *path[] = { name, NULL }; -+ return yajl_tree_get(tree, path, type); -+} ++ /*! ++ * \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; ++ } + -+void *safe_malloc(size_t size) { -+ void *ret = NULL; -+ if (size == 0) { -+ abort(); -+ } -+ ret = calloc(1, size); -+ if (ret == NULL) { -+ abort(); -+ } -+ return ret; -+} ++ /* 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 + -+int common_safe_double(const char *numstr, double *converted) { -+ char *err_str = NULL; -+ double d; + 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); + } + -+ if (!numstr) { -+ return -EINVAL; -+ } ++#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; ++ } + -+ errno = 0; -+ d = strtod(numstr, &err_str); -+ if (errno > 0) { -+ return -errno; -+ } ++ 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++; ++ } + -+ if (!err_str || err_str == numstr || *err_str != '\0') { -+ return -EINVAL; -+ } ++ 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"); + -+ *converted = d; -+ return 0; ++ 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; +} + -+int common_safe_uint8(const char *numstr, uint8_t *converted) { -+ char *err = NULL; -+ unsigned long int uli; -+ -+ if (!numstr) { -+ return -EINVAL; -+ } -+ -+ errno = 0; -+ uli = strtoul(numstr, &err, 0); -+ if (errno > 0) { -+ return -errno; -+ } -+ -+ if (!err || err == numstr || *err != '\0') { -+ return -EINVAL; -+ } -+ -+ if (uli > UINT8_MAX) { -+ return -ERANGE; -+ } -+ -+ *converted = (uint8_t)uli; -+ return 0; -+} ++/*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; + -+int common_safe_uint16(const char *numstr, uint16_t *converted) { -+ char *err = NULL; -+ unsigned long int uli; ++ handler = malloc(sizeof(*handler)); ++ if (handler == NULL) ++ return NULL; + -+ if (!numstr) { -+ return -EINVAL; -+ } ++ 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; ++ } + -+ errno = 0; -+ uli = strtoul(numstr, &err, 0); -+ if (errno > 0) { -+ return -errno; -+ } ++ INFO("Container \"%s\" 's clean handler is initialized.", name); + -+ if (!err || err == numstr || *err != '\0') { -+ return -EINVAL; -+ } ++ return handler; + -+ if (uli > UINT16_MAX) { -+ return -ERANGE; -+ } ++on_error: ++ lxc_free_handler(handler); + -+ *converted = (uint16_t)uli; -+ return 0; ++ return NULL; +} + -+int common_safe_uint32(const char *numstr, uint32_t *converted) { -+ char *err = NULL; -+ unsigned long long int ull; ++/*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; + -+ if (!numstr) { -+ return -EINVAL; -+ } ++ 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; ++ } + -+ errno = 0; -+ ull = strtoull(numstr, &err, 0); -+ if (errno > 0) { -+ return -errno; -+ } ++ INFO("Container \"%s\" 's clean handler is initialized.", name); + -+ if (!err || err == numstr || *err != '\0') { -+ return -EINVAL; -+ } ++ return handler; + -+ if (ull > UINT32_MAX) { -+ return -ERANGE; -+ } ++on_error: ++ lxc_free_handler(handler); + -+ *converted = (uint32_t)ull; -+ return 0; ++ return NULL; +} + -+int common_safe_uint64(const char *numstr, uint64_t *converted) { -+ char *err = NULL; -+ unsigned long long int ull; ++/*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; + -+ if (!numstr) { -+ return -EINVAL; -+ } -+ -+ errno = 0; -+ ull = strtoull(numstr, &err, 0); -+ if (errno > 0) { -+ return -errno; -+ } -+ -+ if (!err || err == numstr || *err != '\0') { -+ return -EINVAL; -+ } -+ -+ *converted = (uint64_t)ull; -+ return 0; -+} -+ -+int common_safe_uint(const char *numstr, unsigned int *converted) { -+ char *err = NULL; -+ unsigned long long int ull; -+ -+ if (!numstr) { -+ return -EINVAL; -+ } -+ -+ errno = 0; -+ ull = strtoull(numstr, &err, 0); -+ if (errno > 0) { -+ return -errno; -+ } -+ -+ if (!err || err == numstr || *err != '\0') { -+ return -EINVAL; -+ } -+ -+ if (ull > UINT_MAX) { -+ return -ERANGE; -+ } -+ -+ *converted = (unsigned int)ull; -+ return 0; -+} -+ -+int common_safe_int8(const char *numstr, int8_t *converted) { -+ char *err = NULL; -+ long int li; -+ -+ if (!numstr) { -+ return -EINVAL; -+ } -+ -+ errno = 0; -+ li = strtol(numstr, &err, 0); -+ if (errno > 0) { -+ return -errno; -+ } -+ -+ if (!err || err == numstr || *err != '\0') { -+ return -EINVAL; -+ } -+ -+ if (li > INT8_MAX || li < INT8_MIN) { -+ return -ERANGE; -+ } -+ -+ *converted = (int8_t)li; -+ return 0; -+} -+ -+int common_safe_int16(const char *numstr, int16_t *converted) { -+ char *err = NULL; -+ long int li; -+ -+ if (!numstr) { -+ return -EINVAL; -+ } -+ -+ errno = 0; -+ li = strtol(numstr, &err, 0); -+ if (errno > 0) { -+ return -errno; -+ } -+ -+ if (!err || err == numstr || *err != '\0') { -+ return -EINVAL; -+ } -+ -+ if (li > INT16_MAX || li < INT16_MIN) { -+ return -ERANGE; -+ } -+ -+ *converted = (int16_t)li; -+ return 0; -+} -+ -+int common_safe_int32(const char *numstr, int32_t *converted) { -+ char *err = NULL; -+ long long int lli; -+ -+ if (!numstr) { -+ return -EINVAL; -+ } -+ -+ errno = 0; -+ lli = strtol(numstr, &err, 0); -+ if (errno > 0) { -+ return -errno; -+ } -+ -+ if (!err || err == numstr || *err != '\0') { -+ return -EINVAL; -+ } -+ -+ if (lli > INT32_MAX || lli < INT32_MIN) { -+ return -ERANGE; -+ } -+ -+ *converted = (int32_t)lli; -+ return 0; -+} -+ -+int common_safe_int64(const char *numstr, int64_t *converted) { -+ char *err = NULL; -+ long long int lli; -+ -+ if (!numstr) { -+ return -EINVAL; -+ } -+ -+ errno = 0; -+ lli = strtoll(numstr, &err, 0); -+ if (errno > 0) { -+ return -errno; -+ } -+ -+ if (!err || err == numstr || *err != '\0') { -+ return -EINVAL; -+ } -+ -+ *converted = (int64_t)lli; -+ return 0; -+} -+ -+int common_safe_int(const char *numstr, int *converted) { -+ char *err = NULL; -+ long long int lli; -+ -+ if (!numstr) { -+ return -EINVAL; -+ } -+ -+ errno = 0; -+ lli = strtol(numstr, &err, 0); -+ if (errno > 0) { -+ return -errno; -+ } -+ -+ if (!err || err == numstr || *err != '\0') { -+ return -EINVAL; -+ } -+ -+ if (lli > INT_MAX || lli < INT_MIN) { -+ return -ERANGE; -+ } -+ -+ *converted = (int)lli; -+ return 0; -+} -+ -+char *safe_strdup(const char *src) -+{ -+ char *dst = NULL; -+ -+ if (!src) { -+ return NULL; -+ } -+ -+ dst = strdup(src); -+ if (!dst) { -+ abort(); -+ } -+ -+ return dst; -+} -+ -+ -+yajl_gen_status gen_json_map_int_int(void *ctx, json_map_int_int *map, struct parser_context *ptx, parser_error *err) { -+ yajl_gen_status stat = yajl_gen_status_ok; -+ yajl_gen g = (yajl_gen) ctx; -+ size_t len = 0, i = 0; -+ if (map) { -+ len = map->len; -+ } -+ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { -+ yajl_gen_config(g, yajl_gen_beautify, 0); -+ } -+ stat = reformat_start_map(g); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ -+ } -+ for (i = 0; i < len; i++) { -+ char numstr[MAX_NUM_STR_LEN]; -+ int nret; -+ nret = sprintf(numstr, "%lld", (long long int)map->keys[i]); -+ if (nret < 0) { -+ if (!*err && asprintf(err, "Error to print string") < 0) { -+ *(err) = safe_strdup("error allocating memory"); -+ } -+ return yajl_gen_in_error_state; -+ } -+ stat = reformat_string(g, numstr, strlen(numstr)); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ stat = reformat_int(g, map->values[i]); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ } -+ -+ stat = reformat_end_map(g); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { -+ yajl_gen_config(g, yajl_gen_beautify, 1); -+ } -+ return yajl_gen_status_ok; -+} -+ -+void free_json_map_int_int(json_map_int_int *map) { -+ if (map) { -+ size_t i; -+ for (i = 0; i < map->len; i++) { -+ // No need to free key for type int -+ // No need to free value for type int -+ } -+ free(map->keys); -+ map->keys = NULL; -+ free(map->values); -+ map->values = NULL; -+ free(map); -+ } -+} -+json_map_int_int *make_json_map_int_int(yajl_val src, struct parser_context *ctx, parser_error *err) { -+ json_map_int_int *ret = NULL; -+ if (src && YAJL_GET_OBJECT(src)) { -+ size_t i; -+ size_t len = YAJL_GET_OBJECT(src)->len; -+ ret = safe_malloc(sizeof(*ret)); -+ ret->len = len; -+ ret->keys = safe_malloc((len + 1) * sizeof(int)); -+ ret->values = safe_malloc((len + 1) * sizeof(int)); -+ for (i = 0; i < len; i++) { -+ const char *srckey = YAJL_GET_OBJECT(src)->keys[i]; -+ yajl_val srcval = YAJL_GET_OBJECT(src)->values[i]; -+ -+ if (srckey) { -+ int invalid; -+ invalid = common_safe_int(srckey, &(ret->keys[i])); -+ if (invalid) { -+ if (!*err && asprintf(err, "Invalid key '%s' with type 'int': %s", srckey, strerror(-invalid)) < 0) { -+ *(err) = safe_strdup("error allocating memory"); -+ } -+ free_json_map_int_int(ret); -+ return NULL; -+ } -+ } -+ -+ if (srcval) { -+ int invalid; -+ if (!YAJL_IS_NUMBER(srcval)) { -+ if (!*err && asprintf(err, "Invalid value with type 'int' for key '%s'", srckey) < 0) { -+ *(err) = safe_strdup("error allocating memory"); -+ } -+ free_json_map_int_int(ret); -+ return NULL; -+ } -+ invalid = common_safe_int(YAJL_GET_NUMBER(srcval), &(ret->values[i])); -+ if (invalid) { -+ if (!*err && asprintf(err, "Invalid value with type 'int' for key '%s': %s", srckey, strerror(-invalid)) < 0) { -+ *(err) = safe_strdup("error allocating memory"); -+ } -+ free_json_map_int_int(ret); -+ return NULL; -+ } -+ } -+ } -+ } -+ return ret; -+} -+int append_json_map_int_int(json_map_int_int *map, int key, int val) { -+ size_t len; -+ int *keys; -+ int *vals; -+ -+ if (!map) { -+ return -1; -+ } -+ -+ if ((SIZE_MAX / sizeof(int) - 1) < map->len) { -+ return -1; -+ } -+ -+ len = map->len + 1; -+ keys = safe_malloc(len * sizeof(int)); -+ vals = safe_malloc(len * sizeof(int)); -+ -+ if (map->len) { -+ if (memcpy(keys, map->keys, map->len * sizeof(int)) != EOK) { -+ free(keys); -+ free(vals); -+ return -1; -+ } -+ if (memcpy(vals, map->values, map->len * sizeof(int)) != EOK) { -+ free(keys); -+ free(vals); -+ return -1; -+ } -+ } -+ free(map->keys); -+ map->keys = keys; -+ free(map->values); -+ map->values = vals; -+ map->keys[map->len] = key; -+ map->values[map->len] = val; -+ -+ map->len++; -+ return 0; -+} -+ -+yajl_gen_status gen_json_map_int_bool(void *ctx, json_map_int_bool *map, struct parser_context *ptx, parser_error *err) { -+ yajl_gen_status stat = yajl_gen_status_ok; -+ yajl_gen g = (yajl_gen) ctx; -+ size_t len = 0, i = 0; -+ if (map) { -+ len = map->len; -+ } -+ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { -+ yajl_gen_config(g, yajl_gen_beautify, 0); -+ } -+ stat = reformat_start_map(g); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ -+ } -+ for (i = 0; i < len; i++) { -+ char numstr[MAX_NUM_STR_LEN]; -+ int nret; -+ nret = sprintf(numstr, "%lld", (long long int)map->keys[i]); -+ if (nret < 0) { -+ if (!*err && asprintf(err, "Error to print string") < 0) { -+ *(err) = safe_strdup("error allocating memory"); -+ } -+ return yajl_gen_in_error_state; -+ } -+ stat = reformat_string(g, numstr, strlen(numstr)); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ stat = reformat_bool(g, map->values[i]); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ } -+ -+ stat = reformat_end_map(g); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { -+ yajl_gen_config(g, yajl_gen_beautify, 1); -+ } -+ return yajl_gen_status_ok; -+} -+ -+void free_json_map_int_bool(json_map_int_bool *map) { -+ if (map) { -+ size_t i; -+ for (i = 0; i < map->len; i++) { -+ // No need to free key for type int -+ // No need to free value for type bool -+ } -+ free(map->keys); -+ map->keys = NULL; -+ free(map->values); -+ map->values = NULL; -+ free(map); -+ } -+} -+json_map_int_bool *make_json_map_int_bool(yajl_val src, struct parser_context *ctx, parser_error *err) { -+ json_map_int_bool *ret = NULL; -+ if (src && YAJL_GET_OBJECT(src)) { -+ size_t i; -+ size_t len = YAJL_GET_OBJECT(src)->len; -+ ret = safe_malloc(sizeof(*ret)); -+ ret->len = len; -+ ret->keys = safe_malloc((len + 1) * sizeof(int)); -+ ret->values = safe_malloc((len + 1) * sizeof(bool)); -+ for (i = 0; i < len; i++) { -+ const char *srckey = YAJL_GET_OBJECT(src)->keys[i]; -+ yajl_val srcval = YAJL_GET_OBJECT(src)->values[i]; -+ -+ if (srckey) { -+ int invalid; -+ invalid = common_safe_int(srckey, &(ret->keys[i])); -+ if (invalid) { -+ if (!*err && asprintf(err, "Invalid key '%s' with type 'int': %s", srckey, strerror(-invalid)) < 0) { -+ *(err) = safe_strdup("error allocating memory"); -+ } -+ free_json_map_int_bool(ret); -+ return NULL; -+ } -+ } -+ -+ if (srcval) { -+ if (YAJL_IS_TRUE(srcval)) { -+ ret->values[i] = true; -+ } else if (YAJL_IS_FALSE(srcval)) { -+ ret->values[i] = false; -+ } else { -+ if (!*err && asprintf(err, "Invalid value with type 'bool' for key '%s'", srckey) < 0) { -+ *(err) = safe_strdup("error allocating memory"); -+ } -+ free_json_map_int_bool(ret); -+ return NULL; -+ } -+ } -+ } -+ } -+ return ret; -+} -+int append_json_map_int_bool(json_map_int_bool *map, int key, bool val) { -+ size_t len; -+ int *keys; -+ bool *vals; -+ -+ if (!map) { -+ return -1; -+ } -+ -+ if ((SIZE_MAX / sizeof(int) - 1) < map->len || (SIZE_MAX / sizeof(bool) - 1) < map->len) { -+ return -1; -+ } -+ -+ len = map->len + 1; -+ keys = safe_malloc(len * sizeof(int)); -+ vals = safe_malloc(len * sizeof(bool)); -+ -+ if (map->len) { -+ if (memcpy(keys, map->keys, map->len * sizeof(int)) != EOK) { -+ free(keys); -+ free(vals); -+ return -1; -+ } -+ if (memcpy(vals, map->values, map->len * sizeof(bool)) != EOK) { -+ free(keys); -+ free(vals); -+ return -1; -+ } -+ } -+ free(map->keys); -+ map->keys = keys; -+ free(map->values); -+ map->values = vals; -+ map->keys[map->len] = key; -+ map->values[map->len] = val; -+ -+ map->len++; -+ return 0; -+} -+ -+yajl_gen_status gen_json_map_int_string(void *ctx, json_map_int_string *map, struct parser_context *ptx, parser_error *err) { -+ yajl_gen_status stat = yajl_gen_status_ok; -+ yajl_gen g = (yajl_gen) ctx; -+ size_t len = 0, i = 0; -+ if (map) { -+ len = map->len; -+ } -+ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { -+ yajl_gen_config(g, yajl_gen_beautify, 0); -+ } -+ stat = reformat_start_map(g); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ -+ } -+ for (i = 0; i < len; i++) { -+ char numstr[MAX_NUM_STR_LEN]; -+ int nret; -+ nret = sprintf(numstr, "%lld", (long long int)map->keys[i]); -+ if (nret < 0) { -+ if (!*err && asprintf(err, "Error to print string") < 0) { -+ *(err) = safe_strdup("error allocating memory"); -+ } -+ return yajl_gen_in_error_state; -+ } -+ stat = reformat_string(g, numstr, strlen(numstr)); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ stat = reformat_string(g, map->values[i], strlen(map->values[i]));; -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ } -+ -+ stat = reformat_end_map(g); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { -+ yajl_gen_config(g, yajl_gen_beautify, 1); -+ } -+ return yajl_gen_status_ok; -+} -+ -+void free_json_map_int_string(json_map_int_string *map) { -+ if (map) { -+ size_t i; -+ for (i = 0; i < map->len; i++) { -+ // No need to free key for type int -+ free(map->values[i]); -+ map->values[i] = NULL; -+ } -+ free(map->keys); -+ map->keys = NULL; -+ free(map->values); -+ map->values = NULL; -+ free(map); -+ } -+} -+json_map_int_string *make_json_map_int_string(yajl_val src, struct parser_context *ctx, parser_error *err) { -+ json_map_int_string *ret = NULL; -+ if (src && YAJL_GET_OBJECT(src)) { -+ size_t i; -+ size_t len = YAJL_GET_OBJECT(src)->len; -+ ret = safe_malloc(sizeof(*ret)); -+ ret->len = len; -+ ret->keys = safe_malloc((len + 1) * sizeof(int)); -+ ret->values = safe_malloc((len + 1) * sizeof(char *)); -+ for (i = 0; i < len; i++) { -+ const char *srckey = YAJL_GET_OBJECT(src)->keys[i]; -+ yajl_val srcval = YAJL_GET_OBJECT(src)->values[i]; -+ -+ if (srckey) { -+ int invalid; -+ invalid = common_safe_int(srckey, &(ret->keys[i])); -+ if (invalid) { -+ if (!*err && asprintf(err, "Invalid key '%s' with type 'int': %s", srckey, strerror(-invalid)) < 0) { -+ *(err) = safe_strdup("error allocating memory"); -+ } -+ free_json_map_int_string(ret); -+ return NULL; -+ } -+ } -+ -+ if (srcval) { -+ if (!YAJL_IS_STRING(srcval)) { -+ if (!*err && asprintf(err, "Invalid value with type 'string' for key '%s'", srckey) < 0) { -+ *(err) = safe_strdup("error allocating memory"); -+ } -+ free_json_map_int_string(ret); -+ return NULL; -+ } -+ char *str = YAJL_GET_STRING(srcval); -+ ret->values[i] = safe_strdup(str ? str : ""); -+ } -+ } -+ } -+ return ret; -+} -+int append_json_map_int_string(json_map_int_string *map, int key, const char *val) { -+ size_t len; -+ int *keys; -+ char **vals; -+ -+ if (!map) { -+ return -1; -+ } -+ -+ if ((SIZE_MAX / sizeof(int) - 1) < map->len || (SIZE_MAX / sizeof(char *) - 1) < map->len) { -+ return -1; -+ } -+ -+ len = map->len + 1; -+ keys = safe_malloc(len * sizeof(int)); -+ vals = safe_malloc(len * sizeof(char *)); -+ -+ if (map->len) { -+ if (memcpy(keys, map->keys, map->len * sizeof(int)) != EOK) { -+ free(keys); -+ free(vals); -+ return -1; -+ } -+ if (memcpy(vals, map->values, map->len * sizeof(char *)) != EOK) { -+ free(keys); -+ free(vals); -+ return -1; -+ } -+ } -+ free(map->keys); -+ map->keys = keys; -+ free(map->values); -+ map->values = vals; -+ map->keys[map->len] = key; -+ map->values[map->len] = safe_strdup(val ? val : ""); -+ -+ map->len++; -+ return 0; -+} -+ -+yajl_gen_status gen_json_map_string_int(void *ctx, json_map_string_int *map, struct parser_context *ptx, parser_error *err) { -+ yajl_gen_status stat = yajl_gen_status_ok; -+ yajl_gen g = (yajl_gen) ctx; -+ size_t len = 0, i = 0; -+ if (map) { -+ len = map->len; -+ } -+ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { -+ yajl_gen_config(g, yajl_gen_beautify, 0); -+ } -+ stat = reformat_start_map(g); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ -+ } -+ for (i = 0; i < len; i++) { -+ stat = reformat_string(g, map->keys[i], strlen(map->keys[i])); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ stat = reformat_int(g, map->values[i]); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ } -+ -+ stat = reformat_end_map(g); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { -+ yajl_gen_config(g, yajl_gen_beautify, 1); -+ } -+ return yajl_gen_status_ok; -+} -+ -+void free_json_map_string_int(json_map_string_int *map) { -+ if (map) { -+ size_t i; -+ for (i = 0; i < map->len; i++) { -+ free(map->keys[i]); -+ map->keys[i] = NULL; -+ // No need to free value for type int -+ } -+ free(map->keys); -+ map->keys = NULL; -+ free(map->values); -+ map->values = NULL; -+ free(map); -+ } -+} -+json_map_string_int *make_json_map_string_int(yajl_val src, struct parser_context *ctx, parser_error *err) { -+ json_map_string_int *ret = NULL; -+ if (src && YAJL_GET_OBJECT(src)) { -+ size_t i; -+ size_t len = YAJL_GET_OBJECT(src)->len; -+ ret = safe_malloc(sizeof(*ret)); -+ ret->len = len; -+ ret->keys = safe_malloc((len + 1) * sizeof(char *)); -+ ret->values = safe_malloc((len + 1) * sizeof(int)); -+ for (i = 0; i < len; i++) { -+ const char *srckey = YAJL_GET_OBJECT(src)->keys[i]; -+ yajl_val srcval = YAJL_GET_OBJECT(src)->values[i]; -+ ret->keys[i] = safe_strdup(srckey ? srckey : ""); -+ -+ if (srcval) { -+ int invalid; -+ if (!YAJL_IS_NUMBER(srcval)) { -+ if (!*err && asprintf(err, "Invalid value with type 'int' for key '%s'", srckey) < 0) { -+ *(err) = safe_strdup("error allocating memory"); -+ } -+ free_json_map_string_int(ret); -+ return NULL; -+ } -+ invalid = common_safe_int(YAJL_GET_NUMBER(srcval), &(ret->values[i])); -+ if (invalid) { -+ if (!*err && asprintf(err, "Invalid value with type 'int' for key '%s': %s", srckey, strerror(-invalid)) < 0) { -+ *(err) = safe_strdup("error allocating memory"); -+ } -+ free_json_map_string_int(ret); -+ return NULL; -+ } -+ } -+ } -+ } -+ return ret; -+} -+int append_json_map_string_int(json_map_string_int *map, const char *key, int val) { -+ size_t len; -+ char **keys; -+ int *vals; -+ -+ if (!map) { -+ return -1; -+ } -+ -+ if ((SIZE_MAX / sizeof(char *) - 1) < map->len || (SIZE_MAX / sizeof(int) - 1) < map->len) { -+ return -1; -+ } -+ -+ len = map->len + 1; -+ keys = safe_malloc(len * sizeof(char *)); -+ vals = safe_malloc(len * sizeof(int)); -+ -+ if (map->len) { -+ if (memcpy(keys, map->keys, map->len * sizeof(char *)) != EOK) { -+ free(keys); -+ free(vals); -+ return -1; -+ } -+ if (memcpy(vals, map->values, map->len * sizeof(int)) != EOK) { -+ free(keys); -+ free(vals); -+ return -1; -+ } -+ } -+ free(map->keys); -+ map->keys = keys; -+ free(map->values); -+ map->values = vals; -+ map->keys[map->len] = safe_strdup(key ? key : ""); -+ map->values[map->len] = val; -+ -+ map->len++; -+ return 0; -+} -+ -+yajl_gen_status gen_json_map_string_bool(void *ctx, json_map_string_bool *map, struct parser_context *ptx, parser_error *err) { -+ yajl_gen_status stat = yajl_gen_status_ok; -+ yajl_gen g = (yajl_gen) ctx; -+ size_t len = 0, i = 0; -+ if (map) { -+ len = map->len; -+ } -+ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { -+ yajl_gen_config(g, yajl_gen_beautify, 0); -+ } -+ stat = reformat_start_map(g); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ -+ } -+ for (i = 0; i < len; i++) { -+ stat = reformat_string(g, map->keys[i], strlen(map->keys[i])); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ stat = reformat_bool(g, map->values[i]); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ } -+ -+ stat = reformat_end_map(g); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { -+ yajl_gen_config(g, yajl_gen_beautify, 1); -+ } -+ return yajl_gen_status_ok; -+} -+ -+void free_json_map_string_bool(json_map_string_bool *map) { -+ if (map) { -+ size_t i; -+ for (i = 0; i < map->len; i++) { -+ free(map->keys[i]); -+ map->keys[i] = NULL; -+ // No need to free value for type bool -+ } -+ free(map->keys); -+ map->keys = NULL; -+ free(map->values); -+ map->values = NULL; -+ free(map); -+ } -+} -+json_map_string_bool *make_json_map_string_bool(yajl_val src, struct parser_context *ctx, parser_error *err) { -+ json_map_string_bool *ret = NULL; -+ if (src && YAJL_GET_OBJECT(src)) { -+ size_t i; -+ size_t len = YAJL_GET_OBJECT(src)->len; -+ ret = safe_malloc(sizeof(*ret)); -+ ret->len = len; -+ ret->keys = safe_malloc((len + 1) * sizeof(char *)); -+ ret->values = safe_malloc((len + 1) * sizeof(bool)); -+ for (i = 0; i < len; i++) { -+ const char *srckey = YAJL_GET_OBJECT(src)->keys[i]; -+ yajl_val srcval = YAJL_GET_OBJECT(src)->values[i]; -+ ret->keys[i] = safe_strdup(srckey ? srckey : ""); -+ -+ if (srcval) { -+ if (YAJL_IS_TRUE(srcval)) { -+ ret->values[i] = true; -+ } else if (YAJL_IS_FALSE(srcval)) { -+ ret->values[i] = false; -+ } else { -+ if (!*err && asprintf(err, "Invalid value with type 'bool' for key '%s'", srckey) < 0) { -+ *(err) = safe_strdup("error allocating memory"); -+ } -+ free_json_map_string_bool(ret); -+ return NULL; -+ } -+ } -+ } -+ } -+ return ret; -+} -+int append_json_map_string_bool(json_map_string_bool *map, const char *key, bool val) { -+ size_t len; -+ char **keys; -+ bool *vals; -+ -+ if (!map) { -+ return -1; -+ } -+ -+ if ((SIZE_MAX / sizeof(char *) - 1) < map->len || (SIZE_MAX / sizeof(bool) - 1) < map->len) { -+ return -1; -+ } -+ -+ len = map->len + 1; -+ keys = safe_malloc(len * sizeof(char *)); -+ vals = safe_malloc(len * sizeof(bool)); -+ -+ if (map->len) { -+ if (memcpy(keys, map->keys, map->len * sizeof(char *)) != EOK) { -+ free(keys); -+ free(vals); -+ return -1; -+ } -+ if (memcpy(vals, map->values, map->len * sizeof(bool)) != EOK) { -+ free(keys); -+ free(vals); -+ return -1; -+ } -+ } -+ free(map->keys); -+ map->keys = keys; -+ free(map->values); -+ map->values = vals; -+ map->keys[map->len] = safe_strdup(key ? key : ""); -+ map->values[map->len] = val; -+ -+ map->len++; -+ return 0; -+} -+ -+yajl_gen_status gen_json_map_string_string(void *ctx, json_map_string_string *map, struct parser_context *ptx, parser_error *err) { -+ yajl_gen_status stat = yajl_gen_status_ok; -+ yajl_gen g = (yajl_gen) ctx; -+ size_t len = 0, i = 0; -+ if (map) { -+ len = map->len; -+ } -+ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { -+ yajl_gen_config(g, yajl_gen_beautify, 0); -+ } -+ stat = reformat_start_map(g); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ -+ } -+ for (i = 0; i < len; i++) { -+ stat = reformat_string(g, map->keys[i], strlen(map->keys[i])); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ stat = reformat_string(g, map->values[i], strlen(map->values[i]));; -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ } -+ -+ stat = reformat_end_map(g); -+ if (yajl_gen_status_ok != stat) { -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { -+ yajl_gen_config(g, yajl_gen_beautify, 1); -+ } -+ return yajl_gen_status_ok; -+} -+ -+void free_json_map_string_string(json_map_string_string *map) { -+ if (map) { -+ size_t i; -+ for (i = 0; i < map->len; i++) { -+ free(map->keys[i]); -+ map->keys[i] = NULL; -+ free(map->values[i]); -+ map->values[i] = NULL; -+ } -+ free(map->keys); -+ map->keys = NULL; -+ free(map->values); -+ map->values = NULL; -+ free(map); -+ } -+} -+json_map_string_string *make_json_map_string_string(yajl_val src, struct parser_context *ctx, parser_error *err) { -+ json_map_string_string *ret = NULL; -+ if (src && YAJL_GET_OBJECT(src)) { -+ size_t i; -+ size_t len = YAJL_GET_OBJECT(src)->len; -+ ret = safe_malloc(sizeof(*ret)); -+ ret->len = len; -+ ret->keys = safe_malloc((len + 1) * sizeof(char *)); -+ ret->values = safe_malloc((len + 1) * sizeof(char *)); -+ for (i = 0; i < len; i++) { -+ const char *srckey = YAJL_GET_OBJECT(src)->keys[i]; -+ yajl_val srcval = YAJL_GET_OBJECT(src)->values[i]; -+ ret->keys[i] = safe_strdup(srckey ? srckey : ""); -+ -+ if (srcval) { -+ if (!YAJL_IS_STRING(srcval)) { -+ if (!*err && asprintf(err, "Invalid value with type 'string' for key '%s'", srckey) < 0) { -+ *(err) = safe_strdup("error allocating memory"); -+ } -+ free_json_map_string_string(ret); -+ return NULL; -+ } -+ char *str = YAJL_GET_STRING(srcval); -+ ret->values[i] = safe_strdup(str ? str : ""); -+ } -+ } -+ } -+ return ret; -+} -+int append_json_map_string_string(json_map_string_string *map, const char *key, const char *val) { -+ size_t len; -+ char **keys; -+ char **vals; -+ -+ if (!map) { -+ return -1; -+ } -+ -+ if ((SIZE_MAX / sizeof(char *) - 1) < map->len) { -+ return -1; -+ } -+ -+ len = map->len + 1; -+ keys = safe_malloc(len * sizeof(char *)); -+ vals = safe_malloc(len * sizeof(char *)); -+ -+ if (map->len) { -+ if (memcpy(keys, map->keys, map->len * sizeof(char *)) != EOK) { -+ free(keys); -+ free(vals); -+ return -1; -+ } -+ if (memcpy(vals, map->values, map->len * sizeof(char *)) != EOK) { -+ free(keys); -+ free(vals); -+ return -1; -+ } -+ } -+ free(map->keys); -+ map->keys = keys; -+ free(map->values); -+ map->values = vals; -+ map->keys[map->len] = safe_strdup(key ? key : ""); -+ map->values[map->len] = safe_strdup(val ? val : ""); -+ -+ map->len++; -+ return 0; -+} -diff --git a/src/lxc/json/json_common.h b/src/lxc/json/json_common.h -new file mode 100755 -index 0000000..904fe3c ---- /dev/null -+++ b/src/lxc/json/json_common.h -@@ -0,0 +1,185 @@ -+// Auto generated file. Do not edit! -+#ifndef _JSON_COMMON_H -+#define _JSON_COMMON_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "securec.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+# undef linux -+ -+//options to report error if there is unknown key found in json -+# define PARSE_OPTIONS_STRICT 0x01 -+//options to generate all key and value -+# define GEN_OPTIONS_ALLKEYVALUE 0x02 -+//options to generate simplify(no indent) json string -+# define GEN_OPTIONS_SIMPLIFY 0x04 -+ -+#define GEN_SET_ERROR_AND_RETURN(stat, err) { \ -+ if (!*(err)) {\ -+ if (asprintf(err, "%s: %s: %d: error generating json, errcode: %d", __FILE__, __func__, __LINE__, stat) < 0) { \ -+ *(err) = safe_strdup("error allocating memory"); \ -+ } \ -+ }\ -+ return stat; \ -+ } -+ -+typedef char *parser_error; -+ -+struct parser_context { -+ unsigned int options; -+ FILE *stderr; -+}; -+ -+yajl_gen_status reformat_number(void *ctx, const char *str, size_t len); -+ -+yajl_gen_status reformat_uint(void *ctx, long long unsigned int num); -+ -+yajl_gen_status reformat_int(void *ctx, long long int num); -+ -+yajl_gen_status reformat_double(void *ctx, double num); -+ -+yajl_gen_status reformat_string(void *ctx, const char *str, size_t len); -+ -+yajl_gen_status reformat_null(void *ctx); -+ -+yajl_gen_status reformat_bool(void *ctx, int boolean); -+ -+yajl_gen_status reformat_map_key(void *ctx, const char *str, size_t len); -+ -+yajl_gen_status reformat_start_map(void *ctx); -+ -+yajl_gen_status reformat_end_map(void *ctx); -+ -+yajl_gen_status reformat_start_array(void *ctx); -+ -+yajl_gen_status reformat_end_array(void *ctx); -+ -+bool json_gen_init(yajl_gen *g, struct parser_context *ctx); -+ -+yajl_val get_val(yajl_val tree, const char *name, yajl_type type); -+ -+void *safe_malloc(size_t size); -+ -+int common_safe_double(const char *numstr, double *converted); -+ -+int common_safe_uint8(const char *numstr, uint8_t *converted); -+ -+int common_safe_uint16(const char *numstr, uint16_t *converted); -+ -+int common_safe_uint32(const char *numstr, uint32_t *converted); -+ -+int common_safe_uint64(const char *numstr, uint64_t *converted); -+ -+int common_safe_uint(const char *numstr, unsigned int *converted); -+ -+int common_safe_int8(const char *numstr, int8_t *converted); -+ -+int common_safe_int16(const char *numstr, int16_t *converted); -+ -+int common_safe_int32(const char *numstr, int32_t *converted); -+ -+int common_safe_int64(const char *numstr, int64_t *converted); -+ -+int common_safe_int(const char *numstr, int *converted); -+ -+char *safe_strdup(const char *src); -+ -+typedef struct { -+ int *keys; -+ int *values; -+ size_t len; -+} json_map_int_int; -+ -+void free_json_map_int_int(json_map_int_int *map); -+ -+json_map_int_int *make_json_map_int_int(yajl_val src, struct parser_context *ctx, parser_error *err); -+ -+yajl_gen_status gen_json_map_int_int(void *ctx, json_map_int_int *map, struct parser_context *ptx, parser_error *err); -+ -+int append_json_map_int_int(json_map_int_int *map, int key, int val); -+ -+typedef struct { -+ int *keys; -+ bool *values; -+ size_t len; -+} json_map_int_bool; -+ -+void free_json_map_int_bool(json_map_int_bool *map); -+ -+json_map_int_bool *make_json_map_int_bool(yajl_val src, struct parser_context *ctx, parser_error *err); -+ -+yajl_gen_status gen_json_map_int_bool(void *ctx, json_map_int_bool *map, struct parser_context *ptx, parser_error *err); -+ -+int append_json_map_int_bool(json_map_int_bool *map, int key, bool val); -+ -+typedef struct { -+ int *keys; -+ char **values; -+ size_t len; -+} json_map_int_string; -+ -+void free_json_map_int_string(json_map_int_string *map); -+ -+json_map_int_string *make_json_map_int_string(yajl_val src, struct parser_context *ctx, parser_error *err); -+ -+yajl_gen_status gen_json_map_int_string(void *ctx, json_map_int_string *map, struct parser_context *ptx, parser_error *err); -+ -+int append_json_map_int_string(json_map_int_string *map, int key, const char *val); -+ -+typedef struct { -+ char **keys; -+ int *values; -+ size_t len; -+} json_map_string_int; -+ -+void free_json_map_string_int(json_map_string_int *map); -+ -+json_map_string_int *make_json_map_string_int(yajl_val src, struct parser_context *ctx, parser_error *err); -+ -+yajl_gen_status gen_json_map_string_int(void *ctx, json_map_string_int *map, struct parser_context *ptx, parser_error *err); -+ -+int append_json_map_string_int(json_map_string_int *map, const char *key, int val); -+ -+typedef struct { -+ char **keys; -+ bool *values; -+ size_t len; -+} json_map_string_bool; -+ -+void free_json_map_string_bool(json_map_string_bool *map); -+ -+json_map_string_bool *make_json_map_string_bool(yajl_val src, struct parser_context *ctx, parser_error *err); -+ -+yajl_gen_status gen_json_map_string_bool(void *ctx, json_map_string_bool *map, struct parser_context *ptx, parser_error *err); -+ -+int append_json_map_string_bool(json_map_string_bool *map, const char *key, bool val); -+ -+typedef struct { -+ char **keys; -+ char **values; -+ size_t len; -+} json_map_string_string; -+ -+void free_json_map_string_string(json_map_string_string *map); -+ -+json_map_string_string *make_json_map_string_string(yajl_val src, struct parser_context *ctx, parser_error *err); -+ -+yajl_gen_status gen_json_map_string_string(void *ctx, json_map_string_string *map, struct parser_context *ptx, parser_error *err); -+ -+int append_json_map_string_string(json_map_string_string *map, const char *key, const char *val); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif -\ No newline at end of file -diff --git a/src/lxc/json/oci_runtime_hooks.c b/src/lxc/json/oci_runtime_hooks.c -new file mode 100644 -index 0000000..3aa134e ---- /dev/null -+++ b/src/lxc/json/oci_runtime_hooks.c -@@ -0,0 +1,53 @@ -+/****************************************************************************** -+ * Copyright (C), 1988-1999, Huawei Tech. Co., Ltd. -+ * FileName: oci_runtime_hooks.c -+ * Author: maoweiyong Version: 0.1 Date: 2018-11-07 -+ * Explanation: provide oci runtime hooks functions -+ ******************************************************************************/ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE -+#endif -+#include -+#include "oci_runtime_hooks.h" -+ -+#include "log.h" -+#include "utils.h" -+ -+#define PARSE_ERR_BUFFER_SIZE 1024 -+ -+oci_runtime_spec_hooks *oci_runtime_spec_hooks_parse_file(const char *filename, -+ struct parser_context *ctx, parser_error *err) -+{ -+ yajl_val tree; -+ size_t filesize; -+ -+ if (!filename || !err) { -+ return NULL; -+ } -+ *err = NULL; -+ struct parser_context tmp_ctx; -+ if (!ctx) { -+ ctx = &tmp_ctx; -+ memset(&tmp_ctx, 0, sizeof(tmp_ctx)); -+ } -+ char *content = read_file(filename, &filesize); -+ char errbuf[PARSE_ERR_BUFFER_SIZE]; -+ if (content == NULL) { -+ if (asprintf(err, "cannot read the file: %s", filename) < 0) { -+ *err = strdup("error allocating memory"); -+ } -+ return NULL; -+ } -+ tree = yajl_tree_parse(content, errbuf, sizeof(errbuf)); -+ free(content); -+ if (tree == NULL) { -+ if (asprintf(err, "cannot parse the file: %s", errbuf) < 0) { -+ *err = strdup("error allocating memory"); -+ } -+ return NULL; -+ } -+ oci_runtime_spec_hooks *ptr = make_oci_runtime_spec_hooks(tree, ctx, -+ err); -+ yajl_tree_free(tree); -+ return ptr; -+} -diff --git a/src/lxc/json/oci_runtime_hooks.h b/src/lxc/json/oci_runtime_hooks.h -new file mode 100644 -index 0000000..bf570c9 ---- /dev/null -+++ b/src/lxc/json/oci_runtime_hooks.h -@@ -0,0 +1,15 @@ -+/****************************************************************************** -+ * Copyright (C), 1988-1999, Huawei Tech. Co., Ltd. -+ * FileName: oci_runtime_hooks.h -+ * Author: tanyifeng Version: 0.1 Date: 2018-11-08 -+ * Explanation: provide container oci runtime hooks function definition -+ ******************************************************************************/ -+#ifndef _CONTAINER_HOOKS_H -+# define _CONTAINER_HOOKS_H -+ -+# include "oci_runtime_spec.h" -+ -+oci_runtime_spec_hooks *oci_runtime_spec_hooks_parse_file(const char *filename, -+ struct parser_context *ctx, parser_error *err); -+ -+#endif -diff --git a/src/lxc/json/oci_runtime_spec.c b/src/lxc/json/oci_runtime_spec.c -new file mode 100644 -index 0000000..1f6073c ---- /dev/null -+++ b/src/lxc/json/oci_runtime_spec.c -@@ -0,0 +1,196 @@ -+// Generated from spec.json. Do not edit! -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE -+#endif -+#include -+#include -+#include "securec.h" -+#include "oci_runtime_spec.h" -+ -+oci_runtime_spec_hooks *make_oci_runtime_spec_hooks(yajl_val tree, struct parser_context *ctx, parser_error *err) { -+ oci_runtime_spec_hooks *ret = NULL; -+ *err = 0; -+ if (tree == NULL) -+ return ret; -+ ret = safe_malloc(sizeof(*ret)); -+ { -+ yajl_val tmp = get_val(tree, "prestart", yajl_t_array); -+ if (tmp && YAJL_GET_ARRAY(tmp)) { -+ size_t i; -+ ret->prestart_len = YAJL_GET_ARRAY(tmp)->len; -+ ret->prestart = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->prestart)); -+ for (i = 0; i < YAJL_GET_ARRAY(tmp)->len; i++) { -+ yajl_val val = YAJL_GET_ARRAY(tmp)->values[i]; -+ ret->prestart[i] = make_defs_hook(val, ctx, err); -+ if (ret->prestart[i] == NULL) { -+ free_oci_runtime_spec_hooks(ret); -+ return NULL; -+ } -+ } -+ } -+ } -+ { -+ yajl_val tmp = get_val(tree, "poststart", yajl_t_array); -+ if (tmp && YAJL_GET_ARRAY(tmp)) { -+ size_t i; -+ ret->poststart_len = YAJL_GET_ARRAY(tmp)->len; -+ ret->poststart = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->poststart)); -+ for (i = 0; i < YAJL_GET_ARRAY(tmp)->len; i++) { -+ yajl_val val = YAJL_GET_ARRAY(tmp)->values[i]; -+ ret->poststart[i] = make_defs_hook(val, ctx, err); -+ if (ret->poststart[i] == NULL) { -+ free_oci_runtime_spec_hooks(ret); -+ return NULL; -+ } -+ } -+ } -+ } -+ { -+ yajl_val tmp = get_val(tree, "poststop", yajl_t_array); -+ if (tmp && YAJL_GET_ARRAY(tmp)) { -+ size_t i; -+ ret->poststop_len = YAJL_GET_ARRAY(tmp)->len; -+ ret->poststop = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->poststop)); -+ for (i = 0; i < YAJL_GET_ARRAY(tmp)->len; i++) { -+ yajl_val val = YAJL_GET_ARRAY(tmp)->values[i]; -+ ret->poststop[i] = make_defs_hook(val, ctx, err); -+ if (ret->poststop[i] == NULL) { -+ free_oci_runtime_spec_hooks(ret); -+ return NULL; -+ } -+ } -+ } -+ } -+ -+ if (tree->type == yajl_t_object && (ctx->options & PARSE_OPTIONS_STRICT)) { -+ int i; -+ for (i = 0; i < tree->u.object.len; i++) -+ if (strcmp(tree->u.object.keys[i], "prestart") && -+ strcmp(tree->u.object.keys[i], "poststart") && -+ strcmp(tree->u.object.keys[i], "poststop")) { -+ if (ctx->stderr > 0) -+ fprintf(ctx->stderr, "WARNING: unknown key found: %s\n", tree->u.object.keys[i]); -+ } -+ } -+ return ret; -+} -+ -+void free_oci_runtime_spec_hooks(oci_runtime_spec_hooks *ptr) { -+ if (!ptr) -+ return; -+ if (ptr->prestart) { -+ size_t i; -+ for (i = 0; i < ptr->prestart_len; i++) -+ if (ptr->prestart[i]) { -+ free_defs_hook(ptr->prestart[i]); -+ ptr->prestart[i] = NULL; -+ } -+ free(ptr->prestart); -+ ptr->prestart = NULL; -+ } -+ if (ptr->poststart) { -+ size_t i; -+ for (i = 0; i < ptr->poststart_len; i++) -+ if (ptr->poststart[i]) { -+ free_defs_hook(ptr->poststart[i]); -+ ptr->poststart[i] = NULL; -+ } -+ free(ptr->poststart); -+ ptr->poststart = NULL; -+ } -+ if (ptr->poststop) { -+ size_t i; -+ for (i = 0; i < ptr->poststop_len; i++) -+ if (ptr->poststop[i]) { -+ free_defs_hook(ptr->poststop[i]); -+ ptr->poststop[i] = NULL; -+ } -+ free(ptr->poststop); -+ ptr->poststop = NULL; -+ } -+ free(ptr); -+} -+ -+yajl_gen_status gen_oci_runtime_spec_hooks(yajl_gen g, oci_runtime_spec_hooks *ptr, struct parser_context *ctx, parser_error *err) { -+ yajl_gen_status stat = yajl_gen_status_ok; -+ *err = 0; -+ stat = reformat_start_map(g); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr && ptr->prestart)) { -+ size_t len = 0, i; -+ stat = reformat_map_key(g, "prestart", strlen("prestart")); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (ptr && ptr->prestart) { -+ len = ptr->prestart_len; -+ } -+ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) -+ yajl_gen_config(g, yajl_gen_beautify, 0); -+ stat = reformat_start_array(g); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ for (i = 0; i < len; i++) { -+ stat = gen_defs_hook(g, ptr->prestart[i], ctx, err); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ stat = reformat_end_array(g); -+ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) -+ yajl_gen_config(g, yajl_gen_beautify, 1); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr && ptr->poststart)) { -+ size_t len = 0, i; -+ stat = reformat_map_key(g, "poststart", strlen("poststart")); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (ptr && ptr->poststart) { -+ len = ptr->poststart_len; -+ } -+ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) -+ yajl_gen_config(g, yajl_gen_beautify, 0); -+ stat = reformat_start_array(g); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ for (i = 0; i < len; i++) { -+ stat = gen_defs_hook(g, ptr->poststart[i], ctx, err); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ stat = reformat_end_array(g); -+ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) -+ yajl_gen_config(g, yajl_gen_beautify, 1); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr && ptr->poststop)) { -+ size_t len = 0, i; -+ stat = reformat_map_key(g, "poststop", strlen("poststop")); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (ptr && ptr->poststop) { -+ len = ptr->poststop_len; -+ } -+ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) -+ yajl_gen_config(g, yajl_gen_beautify, 0); -+ stat = reformat_start_array(g); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ for (i = 0; i < len; i++) { -+ stat = gen_defs_hook(g, ptr->poststop[i], ctx, err); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ stat = reformat_end_array(g); -+ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) -+ yajl_gen_config(g, yajl_gen_beautify, 1); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ stat = reformat_end_map(g); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ return yajl_gen_status_ok; -+} -diff --git a/src/lxc/json/oci_runtime_spec.h b/src/lxc/json/oci_runtime_spec.h -new file mode 100644 -index 0000000..ef3f161 ---- /dev/null -+++ b/src/lxc/json/oci_runtime_spec.h -@@ -0,0 +1,37 @@ -+// Generated from spec.json. Do not edit! -+#ifndef OCI_RUNTIME_SPEC_SCHEMA_H -+#define OCI_RUNTIME_SPEC_SCHEMA_H -+ -+#include -+#include -+#include "json_common.h" -+#include "defs.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+typedef struct { -+ defs_hook **prestart; -+ size_t prestart_len; -+ -+ defs_hook **poststart; -+ size_t poststart_len; -+ -+ defs_hook **poststop; -+ size_t poststop_len; -+ -+} -+oci_runtime_spec_hooks; -+ -+void free_oci_runtime_spec_hooks(oci_runtime_spec_hooks *ptr); -+ -+oci_runtime_spec_hooks *make_oci_runtime_spec_hooks(yajl_val tree, struct parser_context *ctx, parser_error *err); ++ handler = lxc_init_clean_handler(name, lxcpath, conf, pid); ++ if (!handler) { ++ ERROR("Failed to init container %s clean handler", name); ++ ret = -1; ++ goto out; ++ } + -+yajl_gen_status gen_oci_runtime_spec_hooks(yajl_gen g, oci_runtime_spec_hooks *ptr, struct parser_context *ctx, parser_error *err); ++ if (clean_resource_set_env(handler) != 0) { ++ ERROR("Failed to set env for poststop hooks"); ++ ret = -1; ++ goto out; ++ } + -+#ifdef __cplusplus -+} -+#endif ++ 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; ++ } + -+#endif -diff --git a/src/lxc/json/read-file.c b/src/lxc/json/read-file.c -new file mode 100644 -index 0000000..ad0eda1 ---- /dev/null -+++ b/src/lxc/json/read-file.c -@@ -0,0 +1,94 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include "read-file.h" -+ -+#ifndef O_CLOEXEC -+#define O_CLOEXEC 02000000 -+#endif ++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; ++ } + -+char *fread_file(FILE *stream, size_t *length) -+{ -+ char *buf = NULL, *tmpbuf = NULL; -+ size_t off = 0; -+ -+ while (1) { -+ size_t ret, newsize; -+ -+ newsize = off + BUFSIZ + 1; -+ tmpbuf = (char *)calloc(1, newsize); -+ if (tmpbuf == NULL) { -+ goto out; -+ } -+ -+ if (buf) { -+ memcpy(tmpbuf, buf, off); -+ -+ memset(buf, 0, off); -+ -+ free(buf); -+ } -+ -+ buf = tmpbuf; -+ ret = fread(buf + off, 1, BUFSIZ, stream); -+ if (!ret && ferror(stream)) { -+ tmpbuf = NULL; -+ goto out; -+ } -+ if (ret < BUFSIZ || feof(stream)) { -+ *length = off + ret + 1; -+ buf[*length - 1] = '\0'; -+ return buf; -+ } -+ off += BUFSIZ; -+ } +out: -+ if (buf) { -+ free(buf); -+ } -+ if (tmpbuf) { -+ free(tmpbuf); -+ } -+ return NULL; -+ ++ lxc_free_handler(handler); ++ return ret; +} + -+char *read_file(const char *path, size_t *length) ++/*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) +{ -+ char *buf = NULL; -+ char rpath[PATH_MAX + 1] = {0}; -+ int fd, tmperrno; -+ FILE *fp; -+ -+ if (!path || !length) { -+ return NULL; -+ } -+ -+ if (strlen(path) > PATH_MAX || NULL == realpath(path, rpath)) { -+ return NULL; -+ } -+ -+ fd = open(rpath, O_RDONLY | O_CLOEXEC, 0640); -+ if (fd < 0) { -+ return NULL; -+ } -+ -+ fp = fdopen(fd, "r"); -+ tmperrno = errno; -+ if (!fp) { -+ close(fd); -+ errno = tmperrno; -+ return NULL; -+ } -+ -+ buf = fread_file(fp, length); -+ fclose(fp); -+ return buf; -+} -diff --git a/src/lxc/json/read-file.h b/src/lxc/json/read-file.h -new file mode 100644 -index 0000000..5d6e0eb ---- /dev/null -+++ b/src/lxc/json/read-file.h -@@ -0,0 +1,11 @@ -+#ifndef READ_FILE_H -+#define READ_FILE_H -+ -+#include -+#include -+ -+extern char *fread_file(FILE *stream, size_t *length); -+ -+extern char *read_file(const char *path, size_t *length); -+ -+#endif -diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index 31f4819..68134d8 100644 ---- a/src/lxc/lxccontainer.c -+++ b/src/lxc/lxccontainer.c -@@ -271,6 +271,9 @@ static void lxc_container_free(struct lxc_container *c) - free(c->configfile); - c->configfile = NULL; - -+ free(c->ocihookfile); -+ c->ocihookfile = NULL; -+ - free(c->error_string); - c->error_string = NULL; - -@@ -612,6 +615,30 @@ static bool load_config_locked(struct lxc_container *c, const char *fname) - return true; - } - -+static bool load_ocihooks_locked(struct lxc_container *c) -+{ -+ parser_error err = NULL; -+ oci_runtime_spec_hooks *hooks; -+ -+ if (!c->lxc_conf) -+ c->lxc_conf = lxc_conf_init(); -+ -+ if (!c->lxc_conf) -+ return false; ++ int ret = 0; ++ struct lxc_handler *handler = NULL; ++ struct cgroup_ops *cg_ops = NULL; + -+ 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; ++ handler = lxc_init_pids_handler(name, lxcpath, conf); ++ if (!handler) { ++ ERROR("Failed to init container %s clean handler", name); ++ ret = -1; ++ goto out; + } -+ c->lxc_conf->ocihooks = hooks; -+ -+ if (err) -+ free(err); -+ return true; -+} -+ - static bool do_lxcapi_load_config(struct lxc_container *c, const char *alt_file) - { - int lret; -@@ -645,6 +672,9 @@ static bool do_lxcapi_load_config(struct lxc_container *c, const char *alt_file) - - ret = load_config_locked(c, fname); - -+ if (ret && file_exists(c->ocihookfile)) -+ ret = load_ocihooks_locked(c); -+ - if (need_disklock) - container_disk_unlock(c); - else -@@ -3242,6 +3272,37 @@ static bool set_config_filename(struct lxc_container *c) - return true; - } - -+/* -+ * 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; -+ int len, ret; -+ -+ if (!c->config_path) -+ return false; + -+ /* $lxc_path + "/" + c->name + "/" + "config" + '\0' */ -+ len = strlen(c->config_path) + strlen(c->name) + strlen(OCI_HOOK_JSON_FILE_NAME) + 3; -+ newpath = malloc(len); -+ if (!newpath) -+ return false; -+ -+ 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; ++ cg_ops = handler->cgroup_ops; ++ ret = get_all_pids(cg_ops, pids, pids_len); ++ if (ret < 0) { ++ WARN("failed to get all pids"); + } + -+ free(c->ocihookfile); -+ c->ocihookfile = newpath; -+ -+ return true; ++out: ++ lxc_free_handler(handler); ++ return ret; +} + - static bool do_lxcapi_set_config_path(struct lxc_container *c, const char *path) - { - char *p; -@@ -5081,6 +5142,11 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath - goto err; - } - -+ if (!set_oci_hook_config_filename(c)) { -+ fprintf(stderr, "Error allocating oci hooks file pathname\n"); -+ goto err; -+ } -+ - if (file_exists(c->configfile) && !lxcapi_load_config(c, NULL)) { - fprintf(stderr, "Failed to load config for %s\n", name); - goto err; -diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h -index 503038a..5d23cc7 100644 ---- a/src/lxc/lxccontainer.h -+++ b/src/lxc/lxccontainer.h -@@ -77,6 +77,13 @@ struct lxc_container { ++#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 *, - /*! - * \private -+ * isulad: support oci hook from json file -+ * full path of json file -+ * */ -+ char *ocihookfile; -+ -+ /*! -+ * \private - * File to store pid. - */ - char *pidfile; -diff --git a/src/lxc/start.c b/src/lxc/start.c -index b13326c..63f5af8 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -1887,6 +1887,16 @@ static int lxc_spawn(struct lxc_handler *handler) - goto out_delete_net; - } + extern int resolve_clone_flags(struct lxc_handler *handler); -+ /* isulad: Run oci prestart hook at here */ -+ char* oci_hook_args[1]; -+ oci_hook_args[0] = alloca(strlen(lxcpath) + 1); -+ (void)strlcpy(oci_hook_args[0], lxcpath, strlen(lxcpath)); -+ ret = run_lxc_hooks(name, "oci-prestart", conf, oci_hook_args); -+ if (ret < 0) { -+ ERROR("Failed to run oci prestart hooks"); -+ goto out_delete_net; -+ } ++#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); + - /* Tell the child to complete its initialization and wait for it to exec - * or return an error. (The child will never return - * LXC_SYNC_READY_START+1. It will either close the sync pipe, causing -@@ -1922,6 +1932,13 @@ static int lxc_spawn(struct lxc_handler *handler) - if (ret < 0) - goto out_abort; - -+ /* isulad: Run oci prestart hook at here */ -+ ret = run_lxc_hooks(name, "oci-poststart", conf, oci_hook_args); -+ if (ret < 0) { -+ ERROR("Failed to run oci poststart hooks"); -+ goto out_delete_net; -+ } ++/*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 + - ret = lxc_set_state(name, handler, RUNNING); - if (ret < 0) { - ERROR("Failed to set state to \"%s\"", lxc_state2str(RUNNING)); + #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, diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index 8ec9f46..d1a22f7 100644 +index 27078e2..39413ee 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c -@@ -1864,11 +1864,11 @@ static int lxc_file2str(const char *filename, char ret[], int cap) - int fd, num_read; - - if ((fd = open(filename, O_RDONLY | O_CLOEXEC)) == -1) -- return -1;/*lint !e960*/ -+ return -1; - if ((num_read = read(fd, ret, cap - 1)) <= 0) -- num_read = -1;/*lint !e960*/ -+ num_read = -1; - else -- ret[num_read] = 0;/*lint !e613*//*lint !e960*/ -+ ret[num_read] = 0; - close(fd); - - return num_read; -@@ -1886,16 +1886,16 @@ static proc_t *lxc_stat2proc(char *S) - char *tmp = NULL; - - if (!S) -- return NULL;/*lint !e960*/ -+ return NULL; - -- tmp = strrchr(S, ')'); /* split into "PID (cmd" and "" *//*lint !e586*/ -+ tmp = strrchr(S, ')'); /* split into "PID (cmd" and "" */ - if (!tmp) -- return NULL;/*lint !e960*/ -+ return NULL; - *tmp = '\0'; /* replace trailing ')' with NUL */ - - P = malloc(sizeof(proc_t)); - if (!P) -- return NULL;/*lint !e960*/ -+ return NULL; - memset(P, 0x00, sizeof(proc_t)); - - /* parse these two strings separately, skipping the leading "(". */ -@@ -1909,9 +1909,9 @@ static proc_t *lxc_stat2proc(char *S) - "%c " - "%d %d %d %d %d " - "%lu %lu %lu %lu %lu " -- "%Lu %Lu %Lu %Lu " /* utime stime cutime cstime *//*lint !e566*/ -+ "%Lu %Lu %Lu %Lu " /* utime stime cutime cstime */ - "%ld %ld %ld %ld " -- "%Lu " /* start_time *//*lint !e566*/ -+ "%Lu " /* start_time */ - "%lu " - "%ld " - "%lu %lu %lu %lu %lu %lu " -@@ -1922,9 +1922,9 @@ static proc_t *lxc_stat2proc(char *S) - &P->state, - &P->ppid, &P->pgrp, &P->session, &P->tty, &P->tpgid, - &P->flags, &P->min_flt, &P->cmin_flt, &P->maj_flt, &P->cmaj_flt, -- &P->utime, &P->stime, &P->cutime, &P->cstime,/*lint !e561*/ -+ &P->utime, &P->stime, &P->cutime, &P->cstime, - &P->priority, &P->nice, &P->timeout, &P->it_real_value, -- &P->start_time,/*lint !e561*/ -+ &P->start_time, - &P->vsize, - &P->rss, - &P->rss_rlim, &P->start_code, &P->end_code, &P->start_stack, &P->kstk_esp, -@@ -1935,7 +1935,7 @@ static proc_t *lxc_stat2proc(char *S) - ); - - if (P->tty == 0) -- P->tty = -1; /* the old notty val, update elsewhere bef. moving to 0 *//*lint !e960*/ -+ P->tty = -1; /* the old notty val, update elsewhere bef. moving to 0 */ - return P; - } - -@@ -1949,7 +1949,7 @@ unsigned long long lxc_get_process_startat(pid_t pid) - char sbuf[1024] = {0}; /* bufs for stat */ - - sret = snprintf(filename, sizeof(filename), "/proc/%d/stat", pid); -- if (sret < 0 || sret >= sizeof(filename)) {/*lint !e574*/ -+ if (sret < 0 || sret >= sizeof(filename)) { - ERROR("Failed to sprintf filename"); - goto out; - } -@@ -1960,7 +1960,7 @@ unsigned long long lxc_get_process_startat(pid_t pid) - } - - pid_info = lxc_stat2proc(sbuf); -- if (!pid_info) {/*lint !e574*/ -+ if (!pid_info) { - ERROR("Failed to get proc stat info"); - goto out; - } -@@ -1992,3 +1992,41 @@ void lxc_write_error_message(int errfd, const char *format, ...) - SYSERROR("Write errbuf failed"); +@@ -2122,4 +2122,42 @@ set_env: + return 0; } +bool lxc_process_alive(pid_t pid, unsigned long long start_time) +{ -+ int ret; + int sret = 0; + bool alive = true; + proc_t *pid_info = NULL; @@ -3071,16 +1224,20 @@ index 8ec9f46..d1a22f7 100644 + free(pid_info); + return alive; +} ++ + #endif diff --git a/src/lxc/utils.h b/src/lxc/utils.h -index 3d56fd9..abc88ca 100644 +index 36c458e..a213ba7 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h -@@ -316,4 +316,6 @@ extern int fd_nonblock(int fd); +@@ -322,6 +322,8 @@ extern int lxc_file2str(const char *filename, char ret[], int cap); extern int unsigned long long lxc_get_process_startat(pid_t pid); - extern void lxc_write_error_message(int errfd, const char *format, ...); - -+extern bool lxc_process_alive(pid_t pid, unsigned long long start_time); + // set env home in container + extern int lxc_setup_env_home(uid_t uid); + ++extern bool lxc_process_alive(pid_t pid, unsigned long long start_time); + #endif + #endif /* __LXC_UTILS_H */ -- 1.8.3.1 diff --git a/0026-Supporting-UID-GID-configuration.patch b/0026-Supporting-UID-GID-configuration.patch new file mode 100644 index 0000000000000000000000000000000000000000..7c721fd67a28752b505d6254f14da427eb1a70db --- /dev/null +++ b/0026-Supporting-UID-GID-configuration.patch @@ -0,0 +1,306 @@ +From 61bfa0ce515288897b93640507e48f09f0d78010 Mon Sep 17 00:00:00 2001 +From: wujing +Date: Tue, 14 Apr 2020 23:17:04 -0400 +Subject: [PATCH 26/49] Supporting UID GID configuration + +Signed-off-by: wujing +--- + src/lxc/attach.c | 16 ++++++++ + src/lxc/conf.c | 19 ++++++++- + src/lxc/conf.h | 4 ++ + src/lxc/start.c | 8 ++++ + src/lxc/tools/lxc_attach.c | 99 +++++++++++++++++++++++++++++++++++++++++++--- + 5 files changed, 139 insertions(+), 7 deletions(-) + +diff --git a/src/lxc/attach.c b/src/lxc/attach.c +index 33946bb..c77b929 100644 +--- a/src/lxc/attach.c ++++ b/src/lxc/attach.c +@@ -749,8 +749,10 @@ static int attach_child_main(struct attach_clone_payload *payload) + goto on_error; + } + ++#ifndef HAVE_ISULAD + if (!lxc_setgroups(0, NULL) && errno != EPERM) + goto on_error; ++#endif + + if (options->namespaces & CLONE_NEWUSER) { + /* Check whether nsuid 0 has a mapping. */ +@@ -892,6 +894,12 @@ static int attach_child_main(struct attach_clone_payload *payload) + if (new_gid == ns_root_gid) + new_gid = LXC_INVALID_GID; + ++#ifdef HAVE_ISULAD ++ if (!lxc_setgroups(init_ctx->container->lxc_conf->init_groups_len, ++ init_ctx->container->lxc_conf->init_groups)) ++ goto on_error; ++#endif ++ + /* Make sure that the processes STDIO is correctly owned by the user that we are switching to */ + ret = fix_stdio_permissions(new_uid); + if (ret) +@@ -1058,6 +1066,14 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + } + conf = init_ctx->container->lxc_conf; + ++#ifdef HAVE_ISULAD ++ // always switch uid and gid for attach ++ if (options->uid == -1) ++ options->uid = init_ctx->container->lxc_conf->init_uid; ++ if (options->gid == -1) ++ options->gid = init_ctx->container->lxc_conf->init_gid; ++#endif ++ + if (!fetch_seccomp(init_ctx->container, options)) + WARN("Failed to get seccomp policy"); + +diff --git a/src/lxc/conf.c b/src/lxc/conf.c +index 71fd6f9..43ef067 100644 +--- a/src/lxc/conf.c ++++ b/src/lxc/conf.c +@@ -5100,6 +5100,7 @@ void lxc_conf_free(struct lxc_conf *conf) + close(conf->exit_fd); + } + lxc_clear_init_args(conf); ++ lxc_clear_init_groups(conf); + lxc_clear_populate_devices(conf); + lxc_clear_rootfs_masked_paths(conf); + lxc_clear_rootfs_ro_paths(conf); +@@ -5919,11 +5920,25 @@ struct lxc_list *sort_cgroup_settings(struct lxc_list *cgroup_settings) + /*isulad clear init args*/ + int lxc_clear_init_args(struct lxc_conf *lxc_conf) + { +- size_t i; ++ int i; + +- for (i = 0; i < lxc_conf->init_argc; i++) ++ for (i = 0; i < lxc_conf->init_argc; i++) { + free(lxc_conf->init_argv[i]); ++ lxc_conf->init_argv[i] = NULL; ++ } + free(lxc_conf->init_argv); ++ lxc_conf->init_argv = NULL; ++ lxc_conf->init_argc = 0; ++ ++ return 0; ++} ++ ++/*isulad clear init groups*/ ++int lxc_clear_init_groups(struct lxc_conf *lxc_conf) ++{ ++ free(lxc_conf->init_groups); ++ lxc_conf->init_groups = NULL; ++ lxc_conf->init_groups_len = 0; + + return 0; + } +diff --git a/src/lxc/conf.h b/src/lxc/conf.h +index 61c3383..879e427 100644 +--- a/src/lxc/conf.h ++++ b/src/lxc/conf.h +@@ -451,6 +451,9 @@ struct lxc_conf { + char **init_argv; + size_t init_argc; + ++ gid_t *init_groups; ++ size_t init_groups_len; ++ + /* populate devices*/ + struct lxc_list populate_devs; + mode_t umask; //umask value +@@ -548,6 +551,7 @@ extern int parse_mntopts(const char *mntopts, unsigned long *mntflags, + #ifdef HAVE_ISULAD + // isulad add + int lxc_clear_init_args(struct lxc_conf *lxc_conf); ++int lxc_clear_init_groups(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); +diff --git a/src/lxc/start.c b/src/lxc/start.c +index 4f45776..e2311ec 100644 +--- a/src/lxc/start.c ++++ b/src/lxc/start.c +@@ -1685,8 +1685,16 @@ static int do_start(void *data) + #if HAVE_LIBCAP + if (lxc_proc_cap_is_set(CAP_SETGID, CAP_EFFECTIVE)) + #endif ++ #ifdef HAVE_ISULAD ++ /* isulad: set groups for init process, and before we set uid and gid */ ++ if (!lxc_setgroups(handler->conf->init_groups_len, handler->conf->init_groups)) { ++ ERROR("Can not set groups"); ++ goto out_warn_father; ++ } ++ #else + if (!lxc_setgroups(0, NULL)) + goto out_warn_father; ++ #endif + + if (!lxc_switch_uid_gid(new_uid, new_gid)) + goto out_warn_father; +diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c +index 47ac2f2..b068c9a 100644 +--- a/src/lxc/tools/lxc_attach.c ++++ b/src/lxc/tools/lxc_attach.c +@@ -72,9 +72,11 @@ static const struct option my_longopts[] = { + {"set-var", required_argument, 0, 'v'}, + {"pty-log", required_argument, 0, 'L'}, + {"rcfile", required_argument, 0, 'f'}, ++#ifndef HAVE_ISULAD + {"uid", required_argument, 0, 'u'}, + {"gid", required_argument, 0, 'g'}, +-#ifdef HAVE_ISULAD ++#else ++ {"user", required_argument, 0, 'u'}, + {"in-fifo", required_argument, 0, OPT_INPUT_FIFO}, /* isulad add terminal fifos*/ + {"out-fifo", required_argument, 0, OPT_OUTPUT_FIFO}, + {"err-fifo", required_argument, 0, OPT_STDERR_FIFO}, +@@ -130,9 +132,18 @@ Options :\n\ + multiple times.\n\ + -f, --rcfile=FILE\n\ + Load configuration file FILE\n\ ++" ++#ifndef HAVE_ISULAD ++"\ + -u, --uid=UID Execute COMMAND with UID inside the container\n\ + -g, --gid=GID Execute COMMAND with GID inside the container\n\ +-", ++" ++#else ++"\ ++ --user User ID (format: UID[:GID])\n\ ++" ++#endif ++, + .options = my_longopts, + .parser = my_parser, + .checker = NULL, +@@ -142,6 +153,71 @@ Options :\n\ + .gid = LXC_INVALID_GID, + }; + ++#ifdef HAVE_ISULAD ++static int parse_user_id(const char *username, char **uid, char **gid, char **tmp_dup) ++{ ++ char *tmp = NULL; ++ char *pdot = NULL; ++ ++ if (uid == NULL || gid == NULL || tmp_dup == NULL) { ++ return -1; ++ } ++ ++ if (username != NULL) { ++ tmp = strdup(username); ++ if (tmp == NULL) { ++ ERROR("Failed to duplicate user name"); ++ return -1; ++ } ++ ++ // for free tmp in caller ++ *tmp_dup = tmp; ++ pdot = strstr(tmp, ":"); ++ if (pdot != NULL) { ++ *pdot = '\0'; ++ if (pdot != tmp) { ++ // uid found ++ *uid = tmp; ++ } ++ ++ if (*(pdot + 1) != '\0') { ++ // gid found ++ *gid = pdot + 1; ++ } ++ } else { ++ // No : found ++ if (*tmp != '\0') { ++ *uid = tmp; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++static int get_attach_uid_gid(const char *username, uid_t *user_id, gid_t *group_id) ++{ ++ char *tmp = NULL; ++ char *uid = NULL; ++ char *gid = NULL; ++ ++ // parse uid and gid by username ++ if (parse_user_id(username, &uid, &gid, &tmp) != 0) { ++ return -1; ++ } ++ ++ if (uid != NULL) { ++ *user_id = (unsigned int)atoll(uid); ++ } ++ if (gid != NULL) { ++ *group_id = (unsigned int)atoll(gid); ++ } ++ ++ free(tmp); ++ return 0; ++} ++#endif ++ + static int my_parser(struct lxc_arguments *args, int c, char *arg) + { + int ret; +@@ -199,6 +275,7 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) + case 'f': + args->rcfile = arg; + break; ++#ifndef HAVE_ISULAD + case 'u': + if (lxc_safe_uint(arg, &args->uid) < 0) + return -1; +@@ -207,7 +284,13 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) + if (lxc_safe_uint(arg, &args->gid) < 0) + return -1; + break; +-#ifdef HAVE_ISULAD ++#else ++ case 'u': ++ if (get_attach_uid_gid(arg, &args->uid, &args->gid) != 0) { ++ ERROR("Failed to get attach user U/GID"); ++ return -1; ++ } ++ break; + case OPT_INPUT_FIFO: + args->terminal_fifos[0] = arg; + break; +@@ -286,7 +369,7 @@ static int lxc_attach_create_log_file(const char *log_file) + + #ifdef HAVE_ISULAD + // isulad: send '128 + signal' if container is killed by signal. +-#define ExitSignalOffset 128 ++#define EXIT_SIGNAL_OFFSET 128 + + /*isulad: attach with terminal*/ + static int do_attach_foreground(struct lxc_container *c, lxc_attach_command_t *command, +@@ -316,7 +399,7 @@ static int do_attach_foreground(struct lxc_container *c, lxc_attach_command_t *c + + if (WIFSIGNALED(ret)) { + signal = WTERMSIG(ret); +- wexit = ExitSignalOffset + signal; ++ wexit = EXIT_SIGNAL_OFFSET + signal; + } + out: + if (c->lxc_conf->errmsg) +@@ -515,6 +598,12 @@ int main(int argc, char *argv[]) + } + } + ++ if (my_args.uid != LXC_INVALID_UID) ++ attach_options.uid = my_args.uid; ++ ++ if (my_args.gid != LXC_INVALID_GID) ++ attach_options.gid = my_args.gid; ++ + attach_options.suffix = my_args.suffix; + + /* isulad: add do attach background */ +-- +1.8.3.1 + diff --git a/0036-drop_caps-add-drop-caps-of-current-process.patch b/0027-Capabilites-security-feature-enhanced.patch similarity index 46% rename from 0036-drop_caps-add-drop-caps-of-current-process.patch rename to 0027-Capabilites-security-feature-enhanced.patch index 64c8b90edfc2ea7d9d02d0dc52918a4b81624be4..60419dc10bd20a3c69cc6532d288289f740f5be6 100644 --- a/0036-drop_caps-add-drop-caps-of-current-process.patch +++ b/0027-Capabilites-security-feature-enhanced.patch @@ -1,52 +1,56 @@ -From 35ef612b75dee5aa2bf313a8ceb24a7636319582 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Tue, 15 Jan 2019 22:55:06 -0500 -Subject: [PATCH 036/140] drop_caps: add drop caps of current process +From e71dabf21ddd2a093ebdfcc6f6c79200415d12b1 Mon Sep 17 00:00:00 2001 +From: wujing +Date: Tue, 14 Apr 2020 23:30:46 -0400 +Subject: [PATCH 27/49] Capabilites security feature enhanced -Signed-off-by: LiFeng +Signed-off-by: wujing --- - src/lxc/attach.c | 26 +++++++++++++--- - src/lxc/cgroups/cgfsng.c | 35 ++++++++++----------- - src/lxc/conf.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++ - src/lxc/conf.h | 1 + - src/lxc/start.c | 16 ++++++++++ - 5 files changed, 135 insertions(+), 22 deletions(-) + src/lxc/attach.c | 24 +++++++++++++ + src/lxc/conf.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + src/lxc/conf.h | 1 + + src/lxc/start.c | 20 +++++++++++ + 4 files changed, 148 insertions(+) diff --git a/src/lxc/attach.c b/src/lxc/attach.c -index 8cbbf96..3f60fe1 100644 +index c77b929..231fa5f 100644 --- a/src/lxc/attach.c +++ b/src/lxc/attach.c -@@ -936,11 +936,6 @@ static int attach_child_main(struct attach_clone_payload *payload) - TRACE("Loaded seccomp profile"); +@@ -832,10 +832,12 @@ static int attach_child_main(struct attach_clone_payload *payload) + goto on_error; } -- close(payload->ipc_socket); -- payload->ipc_socket = -EBADF; -- lxc_proc_put_context_info(init_ctx); -- payload->init_ctx = NULL; -- ++#ifndef HAVE_ISULAD + close(payload->ipc_socket); + payload->ipc_socket = -EBADF; + lxc_proc_put_context_info(init_ctx); + payload->init_ctx = NULL; ++#endif + /* The following is done after the communication socket is shut down. * That way, all errors that might (though unlikely) occur up until this - * point will have their messages printed to the original stderr (if -@@ -997,9 +992,30 @@ static int attach_child_main(struct attach_clone_payload *payload) - if (new_gid == ns_root_gid) +@@ -895,6 +897,11 @@ static int attach_child_main(struct attach_clone_payload *payload) new_gid = LXC_INVALID_GID; + #ifdef HAVE_ISULAD + if (prctl(PR_SET_KEEPCAPS, 1) < 0) { + SYSERROR("Failed to keep permitted capabilities"); + goto on_error; + } + + if (!lxc_setgroups(init_ctx->container->lxc_conf->init_groups_len, + init_ctx->container->lxc_conf->init_groups)) + goto on_error; +@@ -908,6 +915,23 @@ static int attach_child_main(struct attach_clone_payload *payload) if (!lxc_switch_uid_gid(new_uid, new_gid)) goto on_error; ++#ifdef HAVE_ISULAD + if (prctl(PR_SET_KEEPCAPS, 0) < 0) { + SYSERROR("Failed to clear permitted capabilities"); + goto on_error; + } + -+ if (init_ctx->container && init_ctx->container->lxc_conf && -+ lxc_drop_caps(init_ctx->container->lxc_conf) != 0) { ++ if (lxc_drop_caps(init_ctx->container->lxc_conf) != 0) { + ERROR("Failed to drop caps."); + goto on_error; + } @@ -55,84 +59,50 @@ index 8cbbf96..3f60fe1 100644 + payload->ipc_socket = -EBADF; + lxc_proc_put_context_info(init_ctx); + payload->init_ctx = NULL; ++#endif + /* We're done, so we can now do whatever the user intended us to do. */ - _exit(payload->exec_function(payload->exec_payload, msg_fd)); - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index 8b913a6..bc1481d 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -2664,11 +2664,11 @@ __cgfsng_ops static bool cgfsng_data_init(struct cgroup_ops *ops, struct lxc_han - { - const char *cgroup_pattern; - char *container_cgroup, *tmp; -- struct lxc_conf *conf = handler->conf; -+ struct lxc_conf *conf = NULL; - size_t len; - -- if (!conf) -- return false; -+ if (handler) -+ conf = handler->conf; - - /* copy system-wide cgroup information */ - cgroup_pattern = lxc_global_config_value("lxc.cgroup.pattern"); -@@ -2680,21 +2680,22 @@ __cgfsng_ops static bool cgfsng_data_init(struct cgroup_ops *ops, struct lxc_han - ops->cgroup_pattern = must_copy_string(cgroup_pattern); - - /* isulad: init ops->container_cgroup here instead of in cgfsng_payload_create*/ -- if (conf->cgroup_meta.dir) -- tmp = lxc_string_join("/", (const char *[]){conf->cgroup_meta.dir, handler->name, NULL}, false); -- else -- tmp = lxc_string_replace("%n", handler->name, ops->cgroup_pattern); -- if (!tmp) { -- ERROR("Failed expanding cgroup name pattern"); -- return false; -- } -- -- len = strlen(tmp) + 1; -- container_cgroup = must_realloc(NULL, len); -- (void)strlcpy(container_cgroup, tmp, len); -- free(tmp); -- ops->container_cgroup = container_cgroup; -+ if (conf) { -+ if (conf->cgroup_meta.dir) -+ tmp = lxc_string_join("/", (const char *[]){conf->cgroup_meta.dir, handler->name, NULL}, false); -+ else -+ tmp = lxc_string_replace("%n", handler->name, ops->cgroup_pattern); -+ if (!tmp) { -+ ERROR("Failed expanding cgroup name pattern"); -+ return false; -+ } - -+ len = strlen(tmp) + 1; -+ container_cgroup = must_realloc(NULL, len); -+ (void)strlcpy(container_cgroup, tmp, len); -+ free(tmp); -+ ops->container_cgroup = container_cgroup; -+ } - return true; - } + _exit(payload->exec_function(payload->exec_payload)); diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index fea0f59..6134ed3 100644 +index 43ef067..325e0c2 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c -@@ -4220,6 +4220,85 @@ int lxc_setup(struct lxc_handler *handler) +@@ -2902,6 +2902,16 @@ static int dropcaps_except(struct lxc_list *caps) + lxc_list_for_each (iterator, caps) { + keep_entry = iterator->elem; + ++#ifdef HAVE_ISULAD ++ /* Do not keep any cap*/ ++ if (strcmp(keep_entry, "ISULAD_KEEP_NONE") == 0) { ++ DEBUG("Do not keep any capability"); ++ for(i = 0; i < numcaps; i++) { ++ caplist[i] = 0; ++ } ++ break; ++ } ++#endif + capid = parse_cap(keep_entry); + if (capid == -2) + continue; +@@ -4703,6 +4713,99 @@ int lxc_setup(struct lxc_handler *handler) return 0; } ++#ifdef HAVE_ISULAD +/* isulad drop caps for container*/ +int lxc_drop_caps(struct lxc_conf *conf) +{ +#define __DEF_CAP_TO_MASK(x) (1U << ((x) & 31)) +#if HAVE_LIBCAP -+ struct lxc_list *iterator; -+ char *keep_entry; -+ int i, capid; -+ int numcaps = lxc_caps_last_cap() + 1; ++ int ret = 0; ++ struct lxc_list *iterator = NULL; ++ char *keep_entry = NULL; ++ size_t i = 0; ++ int capid; ++ size_t numcaps = (size_t)lxc_caps_last_cap() + 1; + struct lxc_list *caps = NULL; ++ int *caplist = NULL; + + if (lxc_list_empty(&conf->keepcaps)) + return 0; @@ -143,8 +113,12 @@ index fea0f59..6134ed3 100644 + return -1; + + // caplist[i] is 1 if we keep capability i -+ int *caplist = alloca(numcaps * sizeof(int)); -+ memset(caplist, 0, numcaps * sizeof(int)); ++ caplist = malloc(numcaps * sizeof(int)); ++ if (caplist == NULL) { ++ ERROR("Out of memory"); ++ return -1; ++ } ++ (void)memset(caplist, 0, numcaps * sizeof(int)); + + lxc_list_for_each(iterator, caps) { + @@ -163,9 +137,10 @@ index fea0f59..6134ed3 100644 + if (capid == -2) + continue; + -+ if (capid < 0) { ++ if (capid < 0) { + ERROR("unknown capability %s", keep_entry); -+ return -1; ++ ret = -1; ++ goto out; + } + + DEBUG("keep capability '%s' (%d)", keep_entry, capid); @@ -179,64 +154,72 @@ index fea0f59..6134ed3 100644 + cap_user_header_t cap_header = &cap_header_data; + cap_user_data_t cap_data = &cap_data_data[0]; + -+ memset(cap_header, 0 ,sizeof(struct __user_cap_header_struct)); ++ memset(cap_header, 0,sizeof(struct __user_cap_header_struct)); + memset(cap_data, 0, sizeof(struct __user_cap_data_struct) * 2); + + cap_header->pid = 0; -+ cap_header->version = _LINUX_CAPABILITY_VERSION; ++ cap_header->version = _LINUX_CAPABILITY_VERSION_3; + + for (i = 0; i < numcaps; i++) { + if (caplist[i]) { -+ cap_data[CAP_TO_INDEX(i)].effective = cap_data[CAP_TO_INDEX(i)].effective | __DEF_CAP_TO_MASK(i); -+ cap_data[CAP_TO_INDEX(i)].permitted = cap_data[CAP_TO_INDEX(i)].permitted | __DEF_CAP_TO_MASK(i); -+ cap_data[CAP_TO_INDEX(i)].inheritable = cap_data[CAP_TO_INDEX(i)].inheritable | __DEF_CAP_TO_MASK(i); ++ cap_data[CAP_TO_INDEX(i)].effective = cap_data[CAP_TO_INDEX(i)].effective | (i > 31 ? __DEF_CAP_TO_MASK(i % 32) : __DEF_CAP_TO_MASK(i)); ++ cap_data[CAP_TO_INDEX(i)].permitted = cap_data[CAP_TO_INDEX(i)].permitted | (i > 31 ? __DEF_CAP_TO_MASK(i % 32) : __DEF_CAP_TO_MASK(i)); ++ cap_data[CAP_TO_INDEX(i)].inheritable = cap_data[CAP_TO_INDEX(i)].inheritable | (i > 31 ? __DEF_CAP_TO_MASK(i % 32) : __DEF_CAP_TO_MASK(i)); + } + } + + if (capset(cap_header, cap_data)) { -+ SYSERROR("Failed to set capabilitys"); -+ return -1; ++ SYSERROR("Failed to set capabilitys"); ++ ret = -1; ++ goto out; + } + +#endif -+ return 0; ++ ++out: ++ free(caplist); ++ return ret; +} ++#endif + - struct oci_hook_conf { - defs_hook *ocihook; - + int run_lxc_hooks(const char *name, char *hookname, struct lxc_conf *conf, + char *argv[]) + { diff --git a/src/lxc/conf.h b/src/lxc/conf.h -index 44feb98..b92c48e 100644 +index 879e427..7b6fd3b 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h -@@ -498,6 +498,7 @@ int lxc_clear_init_args(struct lxc_conf *lxc_conf); +@@ -555,6 +555,7 @@ int lxc_clear_init_groups(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 lxc_drop_caps(struct lxc_conf *conf); - - /* isulad add end */ - + 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/start.c b/src/lxc/start.c -index 040909c..357e81d 100644 +index e2311ec..bb2e74a 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c -@@ -1411,6 +1411,11 @@ static int do_start(void *data) +@@ -1652,6 +1652,13 @@ static int do_start(void *data) } } ++#ifdef HAVE_ISULAD + if (prctl(PR_SET_KEEPCAPS, 1) < 0) { + SYSERROR("Failed to keep permitted capabilities"); + goto out_warn_father; + } ++#endif + /* The container has been setup. We can now switch to an unprivileged * uid/gid. */ -@@ -1448,6 +1453,17 @@ static int do_start(void *data) +@@ -1705,6 +1712,19 @@ static int do_start(void *data) goto out_warn_father; } ++#ifdef HAVE_ISULAD + /* isulad: drop the cap of current process */ + if (prctl(PR_SET_KEEPCAPS, 0) < 0) { + SYSERROR("Failed to clear permitted capabilities"); @@ -247,10 +230,11 @@ index 040909c..357e81d 100644 + SYSERROR("Failed to drop caps"); + goto out_warn_father; + } ++#endif + - /* After this call, we are in error because this ops should not return - * as it execs. - */ + if (handler->conf->monitor_signal_pdeath != SIGKILL) { + ret = lxc_set_death_signal(handler->conf->monitor_signal_pdeath, + handler->monitor_pid, status_fd); -- 1.8.3.1 diff --git a/0027-fix-bug-of-memory-leak.patch b/0027-fix-bug-of-memory-leak.patch deleted file mode 100644 index a5875cead240c84220e58f944d6f0dd4e83fd4b2..0000000000000000000000000000000000000000 --- a/0027-fix-bug-of-memory-leak.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 9b7c539dec8af7c01abbcba4333b5f14e23c3b3b Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Mon, 14 Jan 2019 21:24:25 +0800 -Subject: [PATCH 027/140] fix bug of memory leak - -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 11 +++++++++++ - src/lxc/conf.h | 1 + - src/lxc/lxccontainer.c | 11 +++++++---- - 3 files changed, 19 insertions(+), 4 deletions(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 6a14de1..e076bf2 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4822,6 +4822,16 @@ int lxc_clear_procs(struct lxc_conf *c, const char *key) - return 0; - } - -+int lxc_clear_namespace(struct lxc_conf *c) -+{ -+ int i; -+ for (i = 0; i < LXC_NS_MAX; i++) { -+ free(c->ns_share[i]); -+ c->ns_share[i] = NULL; -+ } -+ return 0; -+} -+ - int lxc_clear_groups(struct lxc_conf *c) - { - struct lxc_list *it, *next; -@@ -5036,6 +5046,7 @@ void lxc_conf_free(struct lxc_conf *conf) - lxc_clear_limits(conf, "lxc.prlimit"); - lxc_clear_sysctls(conf, "lxc.sysctl"); - lxc_clear_procs(conf, "lxc.proc"); -+ lxc_clear_namespace(conf); - free(conf->cgroup_meta.dir); - free(conf->cgroup_meta.controllers); - /* isulad add begin */ -diff --git a/src/lxc/conf.h b/src/lxc/conf.h -index 2263e47..44feb98 100644 ---- a/src/lxc/conf.h -+++ b/src/lxc/conf.h -@@ -491,6 +491,7 @@ extern int setup_sysctl_parameters(struct lxc_list *sysctls); - extern int lxc_clear_sysctls(struct lxc_conf *c, const char *key); - extern int setup_proc_filesystem(struct lxc_list *procs, pid_t pid); - extern int lxc_clear_procs(struct lxc_conf *c, const char *key); -+extern int lxc_clear_namespace(struct lxc_conf *c); - - /* isulad add begin */ - int lxc_clear_init_args(struct lxc_conf *lxc_conf); -diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index 81c0ec3..e6272fc 100644 ---- a/src/lxc/lxccontainer.c -+++ b/src/lxc/lxccontainer.c -@@ -5418,10 +5418,13 @@ int list_active_containers(const char *lxcpath, char ***nret, - continue; - } - -- if (array_contains(&ct_name, p, ct_name_cnt)) { -- if (is_hashed) -- free(p); -- continue; -+ -+ if (ct_name && ct_name_cnt) { -+ if (array_contains(&ct_name, p, ct_name_cnt)) { -+ if (is_hashed) -+ free(p); -+ continue; -+ } - } - - if (!add_to_array(&ct_name, p, ct_name_cnt)) { --- -1.8.3.1 - diff --git a/0034-some-small-bugfix.patch b/0028-Supporting-workdir-configuration.patch similarity index 54% rename from 0034-some-small-bugfix.patch rename to 0028-Supporting-workdir-configuration.patch index 9db4036777b37658b9b93919756c2467c3e5e008..d681a71ab110c3687e009e3ab8dfbce385dc8490 100644 --- a/0034-some-small-bugfix.patch +++ b/0028-Supporting-workdir-configuration.patch @@ -1,95 +1,106 @@ -From 193bc24b1974e5149cf751ae9c50383b9c1a3999 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Tue, 15 Jan 2019 20:39:11 +0800 -Subject: [PATCH 034/140] some small bugfix +From cbe77bd42528e92d9e3871a36133a2a11f5a3f21 Mon Sep 17 00:00:00 2001 +From: wujing +Date: Wed, 15 Apr 2020 00:28:40 -0400 +Subject: [PATCH 28/49] Supporting workdir configuration -1. support new container without load config to save time -2. try to create workdir if not exist - -Signed-off-by: LiFeng +Signed-off-by: wujing --- - src/lxc/attach.c | 16 ++++++++++++++++ - src/lxc/lxc.h | 5 +++++ - src/lxc/lxccontainer.c | 21 +++++++++++++++++---- - src/lxc/lxccontainer.h | 12 ++++++++++++ - src/lxc/start.c | 12 ++++++++---- - 5 files changed, 58 insertions(+), 8 deletions(-) + src/lxc/attach.c | 18 ++++++++++++++++++ + src/lxc/lxc.h | 7 +++++++ + src/lxc/lxccontainer.c | 26 +++++++++++++++++++++++++- + src/lxc/lxccontainer.h | 14 ++++++++++++++ + src/lxc/start.c | 10 ++++++++++ + 5 files changed, 74 insertions(+), 1 deletion(-) diff --git a/src/lxc/attach.c b/src/lxc/attach.c -index e6e4b0d..8cbbf96 100644 +index 231fa5f..cb480ed 100644 --- a/src/lxc/attach.c +++ b/src/lxc/attach.c -@@ -806,6 +806,22 @@ static int attach_child_main(struct attach_clone_payload *payload) +@@ -708,6 +708,24 @@ static int attach_child_main(struct attach_clone_payload *payload) TRACE("Dropped capabilities"); } ++#ifdef HAVE_ISULAD + /* isulad: set workdir */ -+ if (init_ctx && init_ctx->container && init_ctx->container->lxc_conf && init_ctx->container->lxc_conf->init_cwd) { ++ if (init_ctx->container->lxc_conf->init_cwd) { + char *init_cwd; + init_cwd = init_ctx->container->lxc_conf->init_cwd; -+ /* try to create workdir if not exist */ -+ struct stat st; -+ if (stat(init_cwd, &st) < 0 && mkdir_p(init_cwd, 0750) < 0) { ++ /* try to create workdir if not exist */ ++ struct stat st; ++ if (stat(init_cwd, &st) < 0 && mkdir_p(init_cwd, 0750) < 0) { + SYSERROR("Try to create directory \"%s\" as workdir failed when attach", init_cwd); + goto on_error; -+ } -+ if (chdir(init_cwd)) { ++ } ++ if (chdir(init_cwd)) { + SYSERROR("Could not change directory to \"%s\" when attach", init_cwd); + goto on_error; -+ } ++ } + } ++#endif + /* Always set the environment (specify (LXC_ATTACH_KEEP_ENV, NULL, NULL) * if you want this to be a no-op). */ diff --git a/src/lxc/lxc.h b/src/lxc/lxc.h -index 687b4b2..5df5080 100644 +index 630eff0..99fd422 100644 --- a/src/lxc/lxc.h +++ b/src/lxc/lxc.h -@@ -104,6 +104,11 @@ extern lxc_state_t lxc_state(const char *name, const char *lxcpath); +@@ -83,6 +83,13 @@ extern lxc_state_t lxc_state(const char *name, const char *lxcpath); + */ extern struct lxc_container *lxc_container_new(const char *name, const char *configpath); - /* ++#ifdef HAVE_ISULAD ++/* + * Create a new container without loading config. + */ +extern struct lxc_container *lxc_container_without_config_new(const char *name, const char *configpath); ++#endif + -+/* + /* * Returns 1 on success, 0 on failure. */ - extern int lxc_container_get(struct lxc_container *c); diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index 38059fa..e99c41c 100644 +index 9b3ab75..ce2b2bf 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c -@@ -5133,7 +5133,7 @@ static bool do_lxcapi_clean_container_resource(struct lxc_container *c, pid_t pi +@@ -5595,7 +5595,11 @@ static bool do_lxcapi_get_container_pids(struct lxc_container *c, pid_t **pids,s + WRAP_API_2(bool, lxcapi_get_container_pids, pid_t **,size_t *) + #endif - WRAP_API_1(bool, lxcapi_clean_container_resource, pid_t) - --struct lxc_container *lxc_container_new(const char *name, const char *configpath) ++#ifdef HAVE_ISULAD +static struct lxc_container *do_lxc_container_new(const char *name, const char *configpath, bool load_config) ++#else + struct lxc_container *lxc_container_new(const char *name, const char *configpath) ++#endif { struct lxc_container *c; size_t len; -@@ -5190,9 +5190,11 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath +@@ -5653,12 +5657,19 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath + fprintf(stderr, "Error allocating oci hooks file pathname\n"); goto err; } +-#endif -- if (file_exists(c->configfile) && !lxcapi_load_config(c, NULL)) { -- fprintf(stderr, "Failed to load config for %s\n", name); -- goto err; -+ if (load_config) { -+ if (file_exists(c->configfile) && !lxcapi_load_config(c, NULL)) { ++ if (load_config && file_exists(c->configfile)) { ++ if (!lxcapi_load_config(c, NULL)) { + fprintf(stderr, "Failed to load config for %s\n", name); + goto err; + } ++ } ++#else + if (file_exists(c->configfile) && !lxcapi_load_config(c, NULL)) { + fprintf(stderr, "Failed to load config for %s\n", name); + goto err; } ++#endif - if (ongoing_create(c) == 2) { -@@ -5274,6 +5276,17 @@ err: + rc = ongoing_create(c); + switch (rc) { +@@ -5761,6 +5772,19 @@ err: return NULL; } ++#ifdef HAVE_ISULAD +// isulad: new container without load config to save time +struct lxc_container *lxc_container_without_config_new(const char *name, const char *configpath) +{ @@ -100,18 +111,21 @@ index 38059fa..e99c41c 100644 +{ + return do_lxc_container_new(name, configpath, true); +} ++#endif + int lxc_get_wait_states(const char **states) { int i; diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h -index 679ca42..a00e0ec 100644 +index f1621f9..e69be8f 100644 --- a/src/lxc/lxccontainer.h +++ b/src/lxc/lxccontainer.h -@@ -1040,6 +1040,18 @@ struct lxc_console_log { +@@ -1097,6 +1097,20 @@ struct lxc_console_log { + */ struct lxc_container *lxc_container_new(const char *name, const char *configpath); - /*! ++#ifdef HAVE_ISULAD ++/*! + * \brief Create a new container without loading config. + * + * \param name Name to use for container. @@ -122,34 +136,32 @@ index 679ca42..a00e0ec 100644 + * \note This function can only used for listing container. + */ +struct lxc_container *lxc_container_without_config_new(const char *name, const char *configpath); ++#endif + -+/*! + /*! * \brief Add a reference to the specified container. * - * \param c Container. diff --git a/src/lxc/start.c b/src/lxc/start.c -index 08d753a..040909c 100644 +index bb2e74a..70ce1bd 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c -@@ -1364,10 +1364,14 @@ static int do_start(void *data) - setsid(); +@@ -1609,6 +1609,16 @@ static int do_start(void *data) + close_prot_errno_disarm(devnull_fd); if (handler->conf->init_cwd) { -- ret = chdir(handler->conf->init_cwd); -- if (ret < 0) { -- SYSERROR("Could not change directory to \"%s\"", -- handler->conf->init_cwd); -+ /* isulad: try to craete workdir if not exist */ ++#ifdef HAVE_ISULAD ++ /* try to craete workdir if not exist */ + struct stat st; + if (stat(handler->conf->init_cwd, &st) < 0 && mkdir_p(handler->conf->init_cwd, 0755) < 0) { + SYSERROR("Try to create directory \"%s\" as workdir failed", handler->conf->init_cwd); ++ lxc_write_error_message(handler->conf->errpipe[1], "%s:%d: Failed to create workdir: %s.", ++ __FILE__, __LINE__, strerror(errno)); + goto out_warn_father; + } -+ if (chdir(handler->conf->init_cwd)) { -+ SYSERROR("Could not change directory to \"%s\"", handler->conf->init_cwd); - goto out_warn_father; - } - } ++#endif + ret = chdir(handler->conf->init_cwd); + if (ret < 0) { + SYSERROR("Could not change directory to \"%s\"", -- 1.8.3.1 diff --git a/0028-support-rootfs-for-container.patch b/0028-support-rootfs-for-container.patch deleted file mode 100644 index df255eceb6e50a104f1aa9551bf2dbe1929ce0df..0000000000000000000000000000000000000000 --- a/0028-support-rootfs-for-container.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 0d83272984a667bcd530553ad4fb7ca0805ceb59 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Tue, 15 Jan 2019 09:45:44 +0800 -Subject: [PATCH 028/140] support rootfs / for container - -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++-------- - 1 file changed, 53 insertions(+), 8 deletions(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index e076bf2..f429491 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -888,9 +888,6 @@ static int lxc_setup_ttys(struct lxc_conf *conf) - char *ttydir = ttys->dir; - char path[PATH_MAX], lxcpath[PATH_MAX]; - -- if (!conf->rootfs.path) -- return 0; -- - for (i = 0; i < ttys->max; i++) { - struct lxc_terminal_info *tty = &ttys->tty[i]; - -@@ -1394,7 +1391,7 @@ static int lxc_mount_rootfs(struct lxc_conf *conf) - { - int ret; - struct lxc_storage *bdev; -- const struct lxc_rootfs *rootfs = &conf->rootfs; -+ struct lxc_rootfs *rootfs = &conf->rootfs; - unsigned long flags, mntflags, pflags; - char *mntdata; - -@@ -1405,6 +1402,17 @@ static int lxc_mount_rootfs(struct lxc_conf *conf) - return -1; - } - -+ // isulad: bind mount / to rootfs.mount. then we can do pivot root even if we use / as root. -+ if (!access(rootfs->mount, F_OK)) { -+ rootfs->path = strdup("/"); -+ if (mount("/", rootfs->mount, NULL, MS_BIND, 0)) { -+ SYSERROR("Failed to mount / to %s.", rootfs->mount); -+ return -1; -+ } -+ } else { -+ INFO("Use '/' as container rootfs, but no valid mountpoint provided. Something may go wrong."); -+ } -+ - return 0; - } - -@@ -3854,6 +3862,35 @@ static int setup_populate_devs(const struct lxc_rootfs *rootfs, struct lxc_list - return 0; - } - -+// isulad: setup rootfs mountopts -+static int setup_rootfs_mountopts(const struct lxc_rootfs *rootfs) -+{ -+ unsigned long mntflags, pflags; -+ char *mntdata; -+ -+ // only remount / when container shares rootfs with host. -+ if(!rootfs || !rootfs->path || strcmp(rootfs->path, "/")) -+ return 0; -+ if (!rootfs->options) -+ return 0; -+ -+ if (parse_mntopts(rootfs->options, &mntflags, &pflags, &mntdata) < 0) { -+ free(mntdata); -+ return -1; -+ } -+ free(mntdata); -+ -+ if (mntflags & MS_RDONLY) { -+ DEBUG("remounting / as readonly"); -+ if (mount("/", "/", NULL, MS_BIND |MS_REMOUNT| MS_RDONLY, 0)) { -+ SYSERROR("Failed to make / readonly."); -+ return -1; -+ } -+ } -+ return 0; -+} -+ -+ - int lxc_setup(struct lxc_handler *handler) - { - int ret; -@@ -4020,12 +4057,20 @@ int lxc_setup(struct lxc_handler *handler) - return -1; - } - -- ret = lxc_setup_devpts(lxc_conf); -- if (ret < 0) { -- ERROR("Failed to setup new devpts instance"); -+ /* isulad: remount rootfs readonly if necessary */ -+ if (setup_rootfs_mountopts(&lxc_conf->rootfs)) { -+ ERROR("failed to set rootfs for '%s'", name); - return -1; - } - -+ if (lxc_conf->rootfs.path) { -+ ret = lxc_setup_devpts(lxc_conf); -+ if (ret < 0) { -+ ERROR("Failed to setup new devpts instance"); -+ return -1; -+ } -+ } -+ - ret = lxc_create_ttys(handler); - if (ret < 0) - return -1; -@@ -4184,7 +4229,7 @@ static char **merge_ocihook_env(char **oldenvs, size_t env_len, size_t *merge_en - return result; - } - --static struct lxc_popen_FILE *lxc_popen_ocihook(char *commandpath, char **args, int args_len, -+static struct lxc_popen_FILE *lxc_popen_ocihook(char *commandpath, char **args, int args_len, - char **envs, int env_len, const char *instr) - { - int ret; --- -1.8.3.1 - diff --git a/0029-Supporting-additional-groups-configuration.patch b/0029-Supporting-additional-groups-configuration.patch new file mode 100644 index 0000000000000000000000000000000000000000..e6bb0496450e67a31ef07982bacfd153b9533765 --- /dev/null +++ b/0029-Supporting-additional-groups-configuration.patch @@ -0,0 +1,103 @@ +From f25dd7358ea454e78c41094e79764ea9e09f28e7 Mon Sep 17 00:00:00 2001 +From: wujing +Date: Wed, 15 Apr 2020 03:57:20 -0400 +Subject: [PATCH 29/49] Supporting additional groups configuration + +Signed-off-by: wujing +--- + src/lxc/confile.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 65 insertions(+) + +diff --git a/src/lxc/confile.c b/src/lxc/confile.c +index 9ba3c7c..55cba6d 100644 +--- a/src/lxc/confile.c ++++ b/src/lxc/confile.c +@@ -149,6 +149,7 @@ lxc_config_define(sysctl); + lxc_config_define(proc); + #ifdef HAVE_ISULAD + lxc_config_define(init_args); ++lxc_config_define(init_groups); + lxc_config_define(populate_device); + lxc_config_define(umask); + lxc_config_define(rootfs_masked_paths); +@@ -268,6 +269,7 @@ static struct lxc_config_t config_jump_table[] = { + { "lxc.proc", set_config_proc, get_config_proc, clr_config_proc, }, + #ifdef HAVE_ISULAD + { "lxc.isulad.init.args", set_config_init_args, get_config_init_args, clr_config_init_args, }, ++ { "lxc.isulad.init.groups", set_config_init_groups, get_config_init_groups, clr_config_init_groups, }, + { "lxc.isulad.populate.device", set_config_populate_device, get_config_populate_device, clr_config_populate_device, }, + { "lxc.isulad.umask", set_config_umask, get_config_umask, clr_config_umask, }, + { "lxc.isulad.rootfs.maskedpaths", set_config_rootfs_masked_paths, get_config_rootfs_masked_paths, clr_config_rootfs_masked_paths, }, +@@ -6247,6 +6249,69 @@ static inline int clr_config_init_args(const char *key, struct lxc_conf *c, + return lxc_clear_init_args(c); + } + ++/* isulad: set config for init groups */ ++static int set_config_init_groups(const char *key, const char *value, ++ struct lxc_conf *lxc_conf, void *data) ++{ ++ char *groups = NULL; ++ char *token = NULL; ++ int ret = -1; ++ ++ if (lxc_config_value_empty(value)) ++ return lxc_clear_init_groups(lxc_conf); ++ ++ groups = strdup(value); ++ if (!groups) ++ return -1; ++ ++ /* In case several capability keep is specified in a single line ++ * split these caps in a single element for the list. ++ */ ++ lxc_iterate_parts(token, groups, " \t") { ++ gid_t *tmp = NULL; ++ if (lxc_mem_realloc((void **)&tmp, (lxc_conf->init_groups_len + 1) * sizeof(gid_t), lxc_conf->init_groups, ++ (lxc_conf->init_groups_len) * sizeof(gid_t)) != 0) { ++ ERROR("Out of memory"); ++ goto on_error; ++ } ++ lxc_conf->init_groups = tmp; ++ tmp[lxc_conf->init_groups_len] = atoll(token); ++ lxc_conf->init_groups_len++; ++ } ++ ++ ret = 0; ++ ++on_error: ++ free(groups); ++ ++ return ret; ++} ++ ++/* isulad: get config init groups */ ++static int get_config_init_groups(const char *key, char *retv, int inlen, ++ struct lxc_conf *c, void *data) ++{ ++ int i, len, fulllen = 0; ++ ++ if (!retv) ++ inlen = 0; ++ else ++ memset(retv, 0, inlen); ++ ++ for (i = 0; i < c->init_groups_len; i++) { ++ strprint(retv, inlen, "%u\n", c->init_groups[i]); ++ } ++ ++ return fulllen; ++} ++ ++/* isulad: clr config init args*/ ++static inline int clr_config_init_groups(const char *key, struct lxc_conf *c, ++ void *data) ++{ ++ return lxc_clear_init_groups(c); ++} ++ + /* isulad: set config for populate device */ + static int set_config_populate_device(const char *key, const char *value, + struct lxc_conf *lxc_conf, void *data) +-- +1.8.3.1 + diff --git a/0030-set-negative-files.limit-value-to-max.patch b/0030-set-negative-files.limit-value-to-max.patch new file mode 100644 index 0000000000000000000000000000000000000000..89205c88251ef8a2e78891b455bbaeac97d7b57d --- /dev/null +++ b/0030-set-negative-files.limit-value-to-max.patch @@ -0,0 +1,71 @@ +From eef7e463b7d4bebc305d65c35288c9fab6a5486f Mon Sep 17 00:00:00 2001 +From: wujing +Date: Wed, 15 Apr 2020 05:45:49 -0400 +Subject: [PATCH 30/49] set negative files.limit value to max + +Signed-off-by: wujing +--- + src/lxc/cgroups/cgfsng.c | 19 +++++++++++++++---- + src/lxc/storage/storage.c | 8 +++++++- + 2 files changed, 22 insertions(+), 5 deletions(-) + +diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c +index 00270ab..b6aef12 100644 +--- a/src/lxc/cgroups/cgfsng.c ++++ b/src/lxc/cgroups/cgfsng.c +@@ -3481,16 +3481,27 @@ __cgfsng_ops static bool cgfsng_setup_limits_legacy(struct cgroup_ops *ops, + cg = iterator->elem; + + if (do_devices == !strncmp("devices", cg->subsystem, 7)) { +- if (isulad_cg_legacy_set_data(ops, cg->subsystem, cg->value)) { ++ const char *cgvalue = cg->value; ++ if (strcmp(cg->subsystem, "files.limit") == 0) { ++ if (lxc_safe_long_long(cgvalue, &setvalue) != 0) { ++ SYSERROR("Invalid integer value %s", cgvalue); ++ goto out; ++ } ++ if (setvalue <= 0) { ++ cgvalue = "max"; ++ } ++ } ++ if (isulad_cg_legacy_set_data(ops, cg->subsystem, cgvalue)) { + if (do_devices && (errno == EACCES || errno == EPERM)) { +- SYSWARN("Failed to set \"%s\" to \"%s\"", cg->subsystem, cg->value); ++ SYSWARN("Failed to set \"%s\" to \"%s\"", cg->subsystem, cgvalue); + continue; + } +- SYSERROR("Failed to set \"%s\" to \"%s\"", cg->subsystem, cg->value); ++ SYSERROR("Failed to set \"%s\" to \"%s\"", cg->subsystem, cgvalue); + goto out; + } +- DEBUG("Set controller \"%s\" set to \"%s\"", cg->subsystem, cg->value); ++ DEBUG("Set controller \"%s\" set to \"%s\"", cg->subsystem, cgvalue); + } ++ + // isulad: check cpu shares + if (strcmp(cg->subsystem, "cpu.shares") == 0) { + if (isulad_cg_legacy_get_data(ops, cg->subsystem, value, sizeof(value) - 1) < 0) { +diff --git a/src/lxc/storage/storage.c b/src/lxc/storage/storage.c +index 876311a..5291b24 100644 +--- a/src/lxc/storage/storage.c ++++ b/src/lxc/storage/storage.c +@@ -591,9 +591,15 @@ bool storage_destroy(struct lxc_conf *conf) + int destroy_rv = 0; + + r = storage_init(conf); ++#ifdef HAVE_ISULAD ++ if (r == NULL) { ++ WARN("%s 's storage init failed, the storage may be deleted already", conf->name); ++ return true; ++ } ++#else + if (!r) + return ret; +- ++#endif + destroy_rv = r->ops->destroy(r); + if (destroy_rv == 0) + ret = true; +-- +1.8.3.1 + diff --git a/0031-clean-add-clean-resources-api.patch b/0031-clean-add-clean-resources-api.patch deleted file mode 100644 index b85707df4dd41c188628ce33ecb2ca4232596cd7..0000000000000000000000000000000000000000 --- a/0031-clean-add-clean-resources-api.patch +++ /dev/null @@ -1,488 +0,0 @@ -From 97a9081b91b573df9c381331fde2dc6ec7f257e6 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Tue, 15 Jan 2019 04:20:57 -0500 -Subject: [PATCH 031/140] clean: add clean resources api - -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgfsng.c | 124 +++++++++++++++++------------------------ - src/lxc/cgroups/cgroup.c | 2 +- - src/lxc/cgroups/cgroup.h | 4 +- - src/lxc/lxccontainer.c | 18 ++++++ - src/lxc/lxccontainer.h | 10 ++++ - src/lxc/start.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++ - src/lxc/start.h | 4 ++ - 7 files changed, 228 insertions(+), 75 deletions(-) - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index 7f2a200..8b913a6 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -1050,12 +1050,15 @@ static int cgroup_rmdir(struct hierarchy **hierarchies, - int ret; - struct hierarchy *h = hierarchies[i]; - -- if (!h->container_full_path) -- continue; -+ if (!h->container_full_path) { -+ h->container_full_path = must_make_path(h->mountpoint, h->container_base_path, container_cgroup, NULL); -+ } - - ret = recursive_destroy(h->container_full_path); -- if (ret < 0) -- WARN("Failed to destroy \"%s\"", h->container_full_path); -+ if (ret < 0) { -+ ERROR("Failed to destroy \"%s\"", h->container_full_path); -+ return -1; -+ } - - free(h->container_full_path); - h->container_full_path = NULL; -@@ -1102,7 +1105,8 @@ static int cgroup_rmdir_wrapper(void *data) - return cgroup_rmdir(arg->hierarchies, arg->container_cgroup); - } - --__cgfsng_ops static void cgfsng_payload_destroy(struct cgroup_ops *ops, -+/* isulad: fix return bool instead of void*/ -+__cgfsng_ops static bool cgfsng_payload_destroy(struct cgroup_ops *ops, - struct lxc_handler *handler) - { - int ret; -@@ -1113,6 +1117,8 @@ __cgfsng_ops static void cgfsng_payload_destroy(struct cgroup_ops *ops, - wrap.hierarchies = ops->hierarchies; - wrap.conf = handler->conf; - -+ INFO("cgfsng_payload_destroy.%p, %s", ops->hierarchies, ops->container_cgroup); -+ - if (handler->conf && !lxc_list_empty(&handler->conf->id_map)) - ret = userns_exec_1(handler->conf, cgroup_rmdir_wrapper, &wrap, - "cgroup_rmdir_wrapper"); -@@ -1120,8 +1126,10 @@ __cgfsng_ops static void cgfsng_payload_destroy(struct cgroup_ops *ops, - ret = cgroup_rmdir(ops->hierarchies, ops->container_cgroup); - if (ret < 0) { - WARN("Failed to destroy cgroups"); -- return; -+ return false; - } -+ -+ return true; - } - - static bool cg_unified_create_cgroup(struct hierarchy *h, char *cgname) -@@ -1232,12 +1240,20 @@ static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname) - { - int ret; - -+ h->container_full_path = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL); -+ -+ if (file_exists(h->container_full_path)) { // it must not already exist -+ ERROR("Cgroup path \"%s\" already exist.", h->container_full_path); -+ //lxc_write_error_message(errfd, "%s:%d: Cgroup path \"%s\" already exist.", -+ // __FILE__, __LINE__, h->fullcgpath); -+ return false; -+ } -+ - if (!cg_legacy_handle_cpuset_hierarchy(h, cgname)) { - ERROR("Failed to handle legacy cpuset controller"); - return false; - } - -- h->container_full_path = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL); - ret = mkdir_eexist_on_last(h->container_full_path, 0755); - if (ret < 0) { - ERROR("Failed to create cgroup \"%s\"", h->container_full_path); -@@ -1259,83 +1275,26 @@ static void remove_path_for_hierarchy(struct hierarchy *h, char *cgname) - h->container_full_path = NULL; - } - --/* Try to create the same cgroup in all hierarchies. Start with cgroup_pattern; -- * next cgroup_pattern-1, -2, ..., -999. -- */ -+/* isulad: create hierarchies path, if fail, return the error */ - __cgfsng_ops static bool cgfsng_payload_create(struct cgroup_ops *ops, - struct lxc_handler *handler) - { - int i; -- size_t len; -- char *container_cgroup, *offset, *tmp; -- int idx = 0; -- struct lxc_conf *conf = handler->conf; -- -- if (ops->container_cgroup) { -- WARN("cgfsng_create called a second time: %s", ops->container_cgroup); -- return false; -- } -+ char *container_cgroup = ops->container_cgroup; - -- if (!conf) -- return false; -- -- if (conf->cgroup_meta.dir) -- tmp = lxc_string_join("/", (const char *[]){conf->cgroup_meta.dir, handler->name, NULL}, false); -- else -- tmp = lxc_string_replace("%n", handler->name, ops->cgroup_pattern); -- if (!tmp) { -- ERROR("Failed expanding cgroup name pattern"); -+ if (!container_cgroup) { -+ ERROR("cgfsng_create container_cgroup is invalid"); - return false; - } - -- len = strlen(tmp) + 5; /* leave room for -NNN\0 */ -- container_cgroup = must_realloc(NULL, len); -- (void)strlcpy(container_cgroup, tmp, len); -- free(tmp); -- offset = container_cgroup + len - 5; -- --again: -- if (idx == 1000) { -- ERROR("Too many conflicting cgroup names"); -- goto out_free; -- } -- -- if (idx) { -- int ret; -- -- ret = snprintf(offset, 5, "-%d", idx); -- if (ret < 0 || (size_t)ret >= 5) { -- FILE *f = fopen("/dev/null", "w"); -- if (f) { -- fprintf(f, "Workaround for GCC7 bug: " -- "https://gcc.gnu.org/bugzilla/" -- "show_bug.cgi?id=78969"); -- fclose(f); -- } -- } -- } -- - for (i = 0; ops->hierarchies[i]; i++) { - if (!create_path_for_hierarchy(ops->hierarchies[i], container_cgroup)) { -- int j; -- ERROR("Failed to create cgroup \"%s\"", ops->hierarchies[i]->container_full_path); -- free(ops->hierarchies[i]->container_full_path); -- ops->hierarchies[i]->container_full_path = NULL; -- for (j = 0; j < i; j++) -- remove_path_for_hierarchy(ops->hierarchies[j], container_cgroup); -- idx++; -- goto again; -+ SYSERROR("Failed to create %s", ops->hierarchies[i]->container_full_path); -+ return false; - } - } - -- ops->container_cgroup = container_cgroup; -- - return true; -- --out_free: -- free(container_cgroup); -- -- return false; - } - - __cgfsng_ops static bool cgfsng_payload_enter(struct cgroup_ops *ops, pid_t pid) -@@ -2701,9 +2660,15 @@ static bool cg_init(struct cgroup_ops *ops) - return cg_hybrid_init(ops); - } - --__cgfsng_ops static bool cgfsng_data_init(struct cgroup_ops *ops) -+__cgfsng_ops static bool cgfsng_data_init(struct cgroup_ops *ops, struct lxc_handler *handler) - { - const char *cgroup_pattern; -+ char *container_cgroup, *tmp; -+ struct lxc_conf *conf = handler->conf; -+ size_t len; -+ -+ if (!conf) -+ return false; - - /* copy system-wide cgroup information */ - cgroup_pattern = lxc_global_config_value("lxc.cgroup.pattern"); -@@ -2714,6 +2679,22 @@ __cgfsng_ops static bool cgfsng_data_init(struct cgroup_ops *ops) - } - ops->cgroup_pattern = must_copy_string(cgroup_pattern); - -+ /* isulad: init ops->container_cgroup here instead of in cgfsng_payload_create*/ -+ if (conf->cgroup_meta.dir) -+ tmp = lxc_string_join("/", (const char *[]){conf->cgroup_meta.dir, handler->name, NULL}, false); -+ else -+ tmp = lxc_string_replace("%n", handler->name, ops->cgroup_pattern); -+ if (!tmp) { -+ ERROR("Failed expanding cgroup name pattern"); -+ return false; -+ } -+ -+ len = strlen(tmp) + 1; -+ container_cgroup = must_realloc(NULL, len); -+ (void)strlcpy(container_cgroup, tmp, len); -+ free(tmp); -+ ops->container_cgroup = container_cgroup; -+ - return true; - } - -@@ -2735,7 +2716,6 @@ struct cgroup_ops *cgfsng_ops_init(void) - - cgfsng_ops->data_init = cgfsng_data_init; - cgfsng_ops->destroy = cgfsng_payload_destroy; -- cgfsng_ops->destroy = cgfsng_payload_destroy; - cgfsng_ops->payload_create = cgfsng_payload_create; - cgfsng_ops->payload_enter = cgfsng_payload_enter; - cgfsng_ops->escape = cgfsng_escape; -diff --git a/src/lxc/cgroups/cgroup.c b/src/lxc/cgroups/cgroup.c -index 04e0311..8e7aef9 100644 ---- a/src/lxc/cgroups/cgroup.c -+++ b/src/lxc/cgroups/cgroup.c -@@ -50,7 +50,7 @@ struct cgroup_ops *cgroup_init(struct lxc_handler *handler) - return NULL; - } - -- if (!cgroup_ops->data_init(cgroup_ops)) -+ if (!cgroup_ops->data_init(cgroup_ops, handler)) - return NULL; - - TRACE("Initialized cgroup driver %s", cgroup_ops->driver); -diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h -index ba4c153..fa4871e 100644 ---- a/src/lxc/cgroups/cgroup.h -+++ b/src/lxc/cgroups/cgroup.h -@@ -123,8 +123,8 @@ struct cgroup_ops { - */ - cgroup_layout_t cgroup_layout; - -- bool (*data_init)(struct cgroup_ops *ops); -- void (*destroy)(struct cgroup_ops *ops, struct lxc_handler *handler); -+ bool (*data_init)(struct cgroup_ops *ops, struct lxc_handler *handler); -+ bool (*destroy)(struct cgroup_ops *ops, struct lxc_handler *handler); - bool (*payload_create)(struct cgroup_ops *ops, struct lxc_handler *handler); - bool (*payload_enter)(struct cgroup_ops *ops, pid_t pid); - const char *(*get_cgroup)(struct cgroup_ops *ops, const char *controller); -diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index beae459..38059fa 100644 ---- a/src/lxc/lxccontainer.c -+++ b/src/lxc/lxccontainer.c -@@ -5116,6 +5116,23 @@ static bool do_lxcapi_set_start_timeout(struct lxc_container *c, unsigned int s - - WRAP_API_1(bool, lxcapi_set_start_timeout, unsigned int) - -+/* isulad add clean resources */ -+static bool do_lxcapi_clean_container_resource(struct lxc_container *c, pid_t pid) -+{ -+ int ret; -+ -+ if (!c) -+ return false; -+ -+ 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; -+ -+} -+ -+WRAP_API_1(bool, lxcapi_clean_container_resource, pid_t) -+ - struct lxc_container *lxc_container_new(const char *name, const char *configpath) - { - struct lxc_container *c; -@@ -5248,6 +5265,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath - c->set_terminal_init_fifos = lxcapi_set_terminal_default_fifos; - c->set_container_info_file = lxcapi_set_container_info_file; - c->set_start_timeout = lxcapi_set_start_timeout; -+ c->clean_container_resource = lxcapi_clean_container_resource; - /* isulad add end */ - return c; - -diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h -index 77de704..679ca42 100644 ---- a/src/lxc/lxccontainer.h -+++ b/src/lxc/lxccontainer.h -@@ -896,6 +896,16 @@ struct lxc_container { - * \return \c true on success, else \c false. - */ - bool (*set_start_timeout)(struct lxc_container *c, unsigned int start_timeout); -+ -+ /*! 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); - }; - - /*! -diff --git a/src/lxc/start.c b/src/lxc/start.c -index f7be9e4..08d753a 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -1895,6 +1895,11 @@ static int lxc_spawn(struct lxc_handler *handler) - if (ret < 0) - SYSERROR("Failed to set environment variable: LXC_PID=%s", pidstr); - -+ if (handler->cgroup_ops->container_cgroup) { -+ if (setenv("LXC_CGROUP_PATH", handler->cgroup_ops->container_cgroup, 1)) -+ SYSERROR("Failed to set environment variable: LXC_CGROUP_PATH=%s.", handler->cgroup_ops->container_cgroup); -+ } -+ - /* Run any host-side start hooks */ - ret = run_lxc_hooks(name, "start-host", conf, NULL); - if (ret < 0) { -@@ -2289,3 +2294,139 @@ static bool do_destroy_container(struct lxc_handler *handler) - - return storage_destroy(handler->conf); - } -+ -+/*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; -+ -+ handler = malloc(sizeof(*handler)); -+ 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. -+ */ -+ 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(handler); -+ if (!handler->cgroup_ops) { -+ ERROR("Failed to initialize cgroup driver"); -+ goto on_error; -+ } -+ -+ INFO("Container \"%s\" 's clean handler is initialized.", name); -+ -+ return handler; -+ -+on_error: -+ lxc_free_handler(handler); -+ -+ return NULL; -+} -+ -+/*isulad: set env for clean resources */ -+static void clean_resource_set_env(struct lxc_handler *handler) -+{ -+ const char *name = handler->name; -+ struct lxc_conf *conf = handler->conf; -+ char pidstr[20]; -+ -+ /* Start of environment variable setup for hooks. */ -+ if (name && setenv("LXC_NAME", name, 1)) -+ SYSERROR("Failed to set environment variable: LXC_NAME=%s.", name); -+ -+ if (conf->rcfile && setenv("LXC_CONFIG_FILE", conf->rcfile, 1)) -+ SYSERROR("Failed to set environment variable: LXC_CONFIG_FILE=%s.", conf->rcfile); -+ -+ if (conf->rootfs.mount && setenv("LXC_ROOTFS_MOUNT", conf->rootfs.mount, 1)) -+ SYSERROR("Failed to set environment variable: LXC_ROOTFS_MOUNT=%s.", conf->rootfs.mount); -+ -+ if (conf->rootfs.path && setenv("LXC_ROOTFS_PATH", conf->rootfs.path, 1)) -+ SYSERROR("Failed to set environment variable: LXC_ROOTFS_PATH=%s.", conf->rootfs.path); -+ -+ if (conf->console.path && setenv("LXC_CONSOLE", conf->console.path, 1)) -+ SYSERROR("Failed to set environment variable: LXC_CONSOLE=%s.", conf->console.path); -+ -+ if (conf->console.log_path && setenv("LXC_CONSOLE_LOGPATH", conf->console.log_path, 1)) -+ SYSERROR("Failed to set environment variable: LXC_CONSOLE_LOGPATH=%s.", conf->console.log_path); -+ -+ if (setenv("LXC_CGNS_AWARE", "1", 1)) -+ SYSERROR("Failed to set environment variable LXC_CGNS_AWARE=1."); -+ -+ -+ snprintf(pidstr, 20, "%d", handler->pid); -+ if (setenv("LXC_PID", pidstr, 1)) -+ SYSERROR("Failed to set environment variable: LXC_PID=%s.", pidstr); -+ -+ if (handler->cgroup_ops->container_cgroup) { -+ if (setenv("LXC_CGROUP_PATH", handler->cgroup_ops->container_cgroup, 1)) -+ SYSERROR("Failed to set environment variable: LXC_CGROUP_PATH=%s.", handler->cgroup_ops->container_cgroup); -+ } -+ /* End of environment variable setup for hooks. */ -+} -+ -+/*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; -+ -+ handler = lxc_init_clean_handler(name, lxcpath, conf, pid); -+ if (!handler) { -+ ERROR("Failed to init container %s clean handler", name); -+ ret = -1; -+ goto out; -+ } -+ -+ clean_resource_set_env(handler); -+ -+ char* oci_hook_args[1]; -+ oci_hook_args[0] = alloca(strlen(handler->lxcpath) + 1); -+ (void)strlcpy(oci_hook_args[0], handler->lxcpath, strlen(handler->lxcpath)); -+ -+ if (run_lxc_hooks(handler->name, "oci-poststop", handler->conf, oci_hook_args)) { -+ ERROR("Failed to run lxc.hook.post-stop for container \"%s\".", handler->name); -+ ret = -1; -+ } -+ -+retry: -+ if (!handler->cgroup_ops->destroy(handler->cgroup_ops, handler)) { -+ if (retry_count < max_retry) { -+ usleep(100 * 1000); /* 100 millisecond */ -+ retry_count++; -+ goto retry; -+ } -+ ERROR("Failed to destroy cgroup for container \"%s\".", handler->name); -+ ret = -1; -+ } -+ -+ -+out_fini_handler: -+ lxc_free_handler(handler); -+out: -+ return ret; -+} -+ -diff --git a/src/lxc/start.h b/src/lxc/start.h -index a96f2ae..1d84325 100644 ---- a/src/lxc/start.h -+++ b/src/lxc/start.h -@@ -180,4 +180,8 @@ extern int __lxc_start(const char *name, struct lxc_handler *handler, - - extern int resolve_clone_flags(struct lxc_handler *handler); - -+/*isulad: do_lxcapi_clean_resource */ -+extern int do_lxcapi_clean_resource(char *name, char *lxcpath, struct lxc_conf *conf, pid_t pid); -+ -+ - #endif --- -1.8.3.1 - diff --git a/0031-head-file-remove-macro-HAVE_ISULAD-in-installed-head.patch b/0031-head-file-remove-macro-HAVE_ISULAD-in-installed-head.patch new file mode 100644 index 0000000000000000000000000000000000000000..c211fa2f8dd252d26a58e66a454d9a9b8fb48412 --- /dev/null +++ b/0031-head-file-remove-macro-HAVE_ISULAD-in-installed-head.patch @@ -0,0 +1,115 @@ +From 5065f006a775e345fa80c1250442ff0f5c05383f Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Wed, 15 Apr 2020 17:46:54 +0800 +Subject: [PATCH 31/49] head file: remove macro HAVE_ISULAD in installed head + file + +Signed-off-by: LiFeng +--- + src/lxc/attach_options.h | 25 ++----------------------- + src/lxc/lxccontainer.h | 6 ------ + 2 files changed, 2 insertions(+), 29 deletions(-) + +diff --git a/src/lxc/attach_options.h b/src/lxc/attach_options.h +index 7b0ea5e..5f01739 100644 +--- a/src/lxc/attach_options.h ++++ b/src/lxc/attach_options.h +@@ -113,15 +113,12 @@ typedef struct lxc_attach_options_t { + + /*! File descriptor to log output. */ + int log_fd; +-#ifdef HAVE_ISULAD ++ + char *init_fifo[3]; /* isulad: default fifos for the start */ + int64_t timeout;/* isulad: Seconds for waiting on a container to attach/exec before it is killed*/ + const char *suffix; +-#endif +- + } lxc_attach_options_t; + +-#ifdef HAVE_ISULAD + /*! Default attach options to use */ + #define LXC_ATTACH_OPTIONS_DEFAULT \ + { \ +@@ -140,25 +137,7 @@ typedef struct lxc_attach_options_t { + /* .log_fd = */ -EBADF, \ + /* .init_fifo = */ {NULL, NULL, NULL}, \ + } +-#else +-/*! Default attach options to use */ +-#define LXC_ATTACH_OPTIONS_DEFAULT \ +- { \ +- /* .attach_flags = */ LXC_ATTACH_DEFAULT, \ +- /* .namespaces = */ -1, \ +- /* .personality = */ -1, \ +- /* .initial_cwd = */ NULL, \ +- /* .uid = */ (uid_t)-1, \ +- /* .gid = */ (gid_t)-1, \ +- /* .env_policy = */ LXC_ATTACH_KEEP_ENV, \ +- /* .extra_env_vars = */ NULL, \ +- /* .extra_keep_env = */ NULL, \ +- /* .stdin_fd = */ 0, \ +- /* .stdout_fd = */ 1, \ +- /* .stderr_fd = */ 2, \ +- /* .log_fd = */ -EBADF, \ +- } +-#endif ++ + /*! + * Representation of a command to run in a container. + */ +diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h +index e69be8f..6ede70c 100644 +--- a/src/lxc/lxccontainer.h ++++ b/src/lxc/lxccontainer.h +@@ -107,7 +107,6 @@ 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. +@@ -125,7 +124,6 @@ struct lxc_container { + * full path of json file + * */ + char *ocihookfile; +-#endif + + /*! + * \brief Determine if \c /var/lib/lxc/$name/config exists. +@@ -886,7 +884,6 @@ struct lxc_container { + */ + int (*init_pidfd)(struct lxc_container *c); + +-#ifdef HAVE_ISULAD + /*! isulad add + * \brief An API call to set the path of info file + * +@@ -963,7 +960,6 @@ struct lxc_container { + * \return \c true on success, else \c false. + */ + bool (*get_container_pids)(struct lxc_container *c,pid_t **pids,size_t *pids_len); +-#endif + }; + + /*! +@@ -1097,7 +1093,6 @@ struct lxc_console_log { + */ + struct lxc_container *lxc_container_new(const char *name, const char *configpath); + +-#ifdef HAVE_ISULAD + /*! + * \brief Create a new container without loading config. + * +@@ -1109,7 +1104,6 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath + * \note This function can only used for listing container. + */ + struct lxc_container *lxc_container_without_config_new(const char *name, const char *configpath); +-#endif + + /*! + * \brief Add a reference to the specified container. +-- +1.8.3.1 + diff --git a/0032-Drop-all-caps-when-cap.keep-ISULAD_KEEP_NONE.patch b/0032-Drop-all-caps-when-cap.keep-ISULAD_KEEP_NONE.patch deleted file mode 100644 index d6f35d3a5018b27627a06dfd93e3079796a10ab3..0000000000000000000000000000000000000000 --- a/0032-Drop-all-caps-when-cap.keep-ISULAD_KEEP_NONE.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 9a8aa1961330227da81a6081db7254441afb3031 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Tue, 15 Jan 2019 05:39:39 -0500 -Subject: [PATCH 032/140] Drop all caps when cap.keep=ISULAD_KEEP_NONE - -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 88763ee..54b967b 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -2805,6 +2805,15 @@ static int dropcaps_except(struct lxc_list *caps) - lxc_list_for_each (iterator, caps) { - keep_entry = iterator->elem; - -+ /* isulad: Do not keep any cap*/ -+ if (strcmp(keep_entry, "ISULAD_KEEP_NONE") == 0) { -+ DEBUG("Do not keep any capability"); -+ for(i = 0; i < numcaps; i++) { -+ caplist[i] = 0; -+ } -+ break; -+ } -+ - capid = parse_cap(keep_entry); - if (capid == -2) - continue; --- -1.8.3.1 - diff --git a/0128-link-proc-mounts-to-etc-mtab.patch b/0032-link-proc-mounts-to-etc-mtab.patch similarity index 51% rename from 0128-link-proc-mounts-to-etc-mtab.patch rename to 0032-link-proc-mounts-to-etc-mtab.patch index f6ec56263e04932cdc05de4a80f5efd975baced2..00a0a470d219f72dea10038728c09ca2d1422b3a 100644 --- a/0128-link-proc-mounts-to-etc-mtab.patch +++ b/0032-link-proc-mounts-to-etc-mtab.patch @@ -1,20 +1,20 @@ -From 2bca52aab48cf7337df9dfb64d20f55ceac3a9ff Mon Sep 17 00:00:00 2001 +From e86ebe923f1ecc072d8a99949871b46fe8188ac9 Mon Sep 17 00:00:00 2001 From: wujing -Date: Tue, 10 Dec 2019 21:28:47 +0800 -Subject: [PATCH 128/140] link /proc/mounts to /etc/mtab +Date: Wed, 15 Apr 2020 06:01:36 -0400 +Subject: [PATCH 32/49] link proc mounts to etc mtab Signed-off-by: wujing --- - src/lxc/conf.c | 39 ++++++++++++++++++++++++++++++++++++++- - 1 file changed, 38 insertions(+), 1 deletion(-) + src/lxc/conf.c | 37 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 37 insertions(+) diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 21ec340..b66e7bc 100644 +index 325e0c2..6856b1d 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c -@@ -4101,6 +4101,37 @@ static int setup_rootfs_mountopts(const struct lxc_rootfs *rootfs) - return 0; - } +@@ -3977,6 +3977,37 @@ struct oci_hook_conf { + int which; + }; +static int create_mtab_link() +{ @@ -47,31 +47,22 @@ index 21ec340..b66e7bc 100644 + return 0; +} + - int lxc_setup(struct lxc_handler *handler) - { - int ret; -@@ -4331,7 +4362,7 @@ int lxc_setup(struct lxc_handler *handler) + struct wait_conf { + pid_t pid; + unsigned long long startat; +@@ -4696,6 +4727,12 @@ int lxc_setup(struct lxc_handler *handler) + return log_error(-1, "failed to setup readonlypaths"); } } - -- //isulad: system container, remount /proc/sys/xxx by mount_list -+ // isulad: system container, remount /proc/sys/xxx by mount_list - if (lxc_conf->systemd != NULL && strcmp(lxc_conf->systemd, "true") == 0) { - if (!lxc_list_empty(&lxc_conf->mount_list)) { - if (remount_proc_sys_mount_entries(&lxc_conf->mount_list)) { -@@ -4341,6 +4372,12 @@ int lxc_setup(struct lxc_handler *handler) - } - } - ++ + // isulad: create link /etc/mtab for /proc/mounts + if (create_mtab_link() != 0) { + ERROR("failed to create link /etc/mtab for target /proc/mounts"); + goto on_error; + } -+ + #endif + if (!lxc_list_empty(&lxc_conf->keepcaps)) { - if (!lxc_list_empty(&lxc_conf->caps)) { - ERROR("Container requests lxc.cap.drop and " -- 1.8.3.1 diff --git a/0033-build-add-secure-build-flags.patch b/0033-build-add-secure-build-flags.patch new file mode 100644 index 0000000000000000000000000000000000000000..15e3f3d0697d08e0e38a73e8eb2dacd4d1fca686 --- /dev/null +++ b/0033-build-add-secure-build-flags.patch @@ -0,0 +1,423 @@ +From 2b69f168a6847885233e88be02a1143a4c55b59f Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Wed, 15 Apr 2020 18:58:24 +0800 +Subject: [PATCH 33/49] build: add secure build flags + +Signed-off-by: LiFeng +--- + configure.ac | 14 +++++- + src/lxc/Makefile.am | 8 +++- + src/lxc/cgroups/cgfsng.c | 117 ++++++++++++++++++++++++--------------------- + src/lxc/confile.c | 1 - + src/lxc/terminal.c | 6 ++- + src/lxc/tools/lxc_attach.c | 2 - + src/lxc/utils.c | 7 +++ + 7 files changed, 93 insertions(+), 62 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 56d0cb7..438d292 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -43,6 +43,7 @@ AM_INIT_AUTOMAKE([-Wall -Werror -Wno-portability subdir-objects]) + AC_CANONICAL_HOST + AM_PROG_CC_C_O + AC_USE_SYSTEM_EXTENSIONS ++CFLAGS=`echo "${CFLAGS#\-g}"` + + # Test if we have a new enough compiler. + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +@@ -190,6 +191,11 @@ AC_ARG_ENABLE([werror], + [AS_HELP_STRING([--disable-werror], [do not treat warnings as errors])], + [enable_werror=$enableval], [enable_werror=yes]) + ++AC_ARG_ENABLE([debug], ++ [AC_HELP_STRING([--enable-debug], ++ [set -g into cflags [default=no]])], ++ [], [enable_debug=no]) ++ + # Allow disabling rpath + AC_ARG_ENABLE([rpath], + [AS_HELP_STRING([--enable-rpath], [set rpath in executables [default=no]])], +@@ -732,7 +738,6 @@ AX_CHECK_COMPILE_FLAG([-fno-strict-aliasing], [CFLAGS="$CFLAGS -fno-strict-alias + AX_CHECK_COMPILE_FLAG([-fstack-clash-protection], [CFLAGS="$CFLAGS -fstack-clash-protection"],,[-Werror]) + AX_CHECK_LINK_FLAG([-fstack-protector-strong], [CFLAGS="$CFLAGS -fstack-protector-strong"],,[-Werror]) + AX_CHECK_LINK_FLAG([--param=ssp-buffer-size=4], [CFLAGS="$CFLAGS --param=ssp-buffer-size=4"],,[-Werror]) +-AX_CHECK_COMPILE_FLAG([-g], [CFLAGS="$CFLAGS -g"],,[-Werror]) + AX_CHECK_COMPILE_FLAG([--mcet -fcf-protection], [CFLAGS="$CFLAGS --mcet -fcf-protection"],,[-Werror]) + AX_CHECK_COMPILE_FLAG([-Werror=implicit-function-declaration], [CFLAGS="$CFLAGS -Werror=implicit-function-declaration"],,[-Werror]) + AX_CHECK_COMPILE_FLAG([-Wlogical-op], [CFLAGS="$CFLAGS -Wlogical-op"],,[-Werror]) +@@ -759,12 +764,17 @@ AX_CHECK_COMPILE_FLAG([-fexceptions], [CFLAGS="$CFLAGS -fexceptions"],,[-Werror] + + AX_CHECK_LINK_FLAG([-z relro], [LDFLAGS="$LDFLAGS -z relro"],,[]) + AX_CHECK_LINK_FLAG([-z now], [LDFLAGS="$LDFLAGS -z now"],,[]) ++AX_CHECK_LINK_FLAG([-z noexecstack], [LDFLAGS="$LDFLAGS -z noexecstack"],,[]) + +-CFLAGS="$CFLAGS -Wvla -std=gnu11" ++CFLAGS="$CFLAGS -Wvla -std=gnu11 -D_FORTIFY_SOURCE=2 -Wall -fPIC -fPIE -pie" + if test "x$enable_werror" = "xyes"; then + CFLAGS="$CFLAGS -Werror" + fi + ++if test "x$enable_debug" = "xyes"; then ++ CFLAGS="$CFLAGS -g" ++fi ++ + AC_ARG_ENABLE([thread-safety], + [AS_HELP_STRING([--enable-thread-safety], [enforce thread-safety otherwise fail the build [default=yes]])], + [enable_thread_safety=$enableval], [enable_thread_safety=yes]) +diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am +index c288c51..0e1ba8d 100644 +--- a/src/lxc/Makefile.am ++++ b/src/lxc/Makefile.am +@@ -276,6 +276,10 @@ liblxc_la_CFLAGS += -fsanitize=address \ + -fno-omit-frame-pointer + endif + ++if HAVE_ISULAD ++liblxc_la_CFLAGS += -D_FORTIFY_SOURCE=2 -Wall ++endif ++ + if ENABLE_UBSAN + liblxc_la_CFLAGS += -fsanitize=undefined + endif +@@ -286,7 +290,9 @@ liblxc_la_LDFLAGS = -pthread \ + -version-info @LXC_ABI_MAJOR@ + + if HAVE_ISULAD +-liblxc_la_LDFLAGS += @YAJL_LIBS@ ++liblxc_la_LDFLAGS += @YAJL_LIBS@ -Wl,-z,relro \ ++ -Wl,-z,now \ ++ -Wl,-z,noexecstack + endif + + liblxc_la_LIBADD = $(CAP_LIBS) \ +diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c +index b6aef12..1047c08 100644 +--- a/src/lxc/cgroups/cgfsng.c ++++ b/src/lxc/cgroups/cgfsng.c +@@ -214,6 +214,7 @@ static char *read_file(const char *fnam) + return move_ptr(buf); + } + ++#ifndef HAVE_ISULAD + /* Taken over modified from the kernel sources. */ + #define NBITS 32 /* bits in uint32_t */ + #define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d)) +@@ -476,12 +477,14 @@ static bool copy_parent_file(const char *parent_cgroup, + value, child_cgroup, file); + return true; + } ++#endif + + static inline bool is_unified_hierarchy(const struct hierarchy *h) + { + return h->version == CGROUP2_SUPER_MAGIC; + } + ++#ifndef HAVE_ISULAD + /* + * Initialize the cpuset hierarchy in first directory of @cgroup_leaf and set + * cgroup.clone_children so that children inherit settings. Since the +@@ -561,6 +564,7 @@ static int cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, + + return fret; + } ++#endif + + /* Given two null-terminated lists of strings, return true if any string is in + * both. +@@ -946,29 +950,6 @@ static void lxc_cgfsng_print_basecg_debuginfo(char *basecginfo, char **klist, + TRACE("named subsystem %d: %s", k, *it); + } + +-static int cgroup_tree_remove(struct hierarchy **hierarchies, +- const char *container_cgroup) +-{ +- if (!container_cgroup || !hierarchies) +- return 0; +- +- for (int i = 0; hierarchies[i]; i++) { +- struct hierarchy *h = hierarchies[i]; +- int ret; +- +- if (!h->container_full_path) +- continue; +- +- ret = lxc_rm_rf(h->container_full_path); +- if (ret < 0) +- WARN("Failed to destroy \"%s\"", h->container_full_path); +- +- free_disarm(h->container_full_path); +- } +- +- return 0; +-} +- + struct generic_userns_exec_data { + struct hierarchy **hierarchies; + const char *container_cgroup; +@@ -977,29 +958,6 @@ struct generic_userns_exec_data { + char *path; + }; + +-static int cgroup_tree_remove_wrapper(void *data) +-{ +- struct generic_userns_exec_data *arg = data; +- uid_t nsuid = (arg->conf->root_nsuid_map != NULL) ? 0 : arg->conf->init_uid; +- gid_t nsgid = (arg->conf->root_nsgid_map != NULL) ? 0 : arg->conf->init_gid; +- int ret; +- +- if (!lxc_setgroups(0, NULL) && errno != EPERM) +- return log_error_errno(-1, errno, "Failed to setgroups(0, NULL)"); +- +- ret = setresgid(nsgid, nsgid, nsgid); +- if (ret < 0) +- return log_error_errno(-1, errno, "Failed to setresgid(%d, %d, %d)", +- (int)nsgid, (int)nsgid, (int)nsgid); +- +- ret = setresuid(nsuid, nsuid, nsuid); +- if (ret < 0) +- return log_error_errno(-1, errno, "Failed to setresuid(%d, %d, %d)", +- (int)nsuid, (int)nsuid, (int)nsuid); +- +- return cgroup_tree_remove(arg->hierarchies, arg->container_cgroup); +-} +- + #ifdef HAVE_ISULAD + + static int isulad_cgroup_tree_remove(struct hierarchy **hierarchies, +@@ -1100,6 +1058,52 @@ __cgfsng_ops static bool isulad_cgfsng_payload_destroy(struct cgroup_ops *ops, + return true; + } + #else ++static int cgroup_tree_remove(struct hierarchy **hierarchies, ++ const char *container_cgroup) ++{ ++ if (!container_cgroup || !hierarchies) ++ return 0; ++ ++ for (int i = 0; hierarchies[i]; i++) { ++ struct hierarchy *h = hierarchies[i]; ++ int ret; ++ ++ if (!h->container_full_path) ++ continue; ++ ++ ret = lxc_rm_rf(h->container_full_path); ++ if (ret < 0) ++ WARN("Failed to destroy \"%s\"", h->container_full_path); ++ ++ free_disarm(h->container_full_path); ++ } ++ ++ return 0; ++} ++ ++static int cgroup_tree_remove_wrapper(void *data) ++{ ++ struct generic_userns_exec_data *arg = data; ++ uid_t nsuid = (arg->conf->root_nsuid_map != NULL) ? 0 : arg->conf->init_uid; ++ gid_t nsgid = (arg->conf->root_nsgid_map != NULL) ? 0 : arg->conf->init_gid; ++ int ret; ++ ++ if (!lxc_setgroups(0, NULL) && errno != EPERM) ++ return log_error_errno(-1, errno, "Failed to setgroups(0, NULL)"); ++ ++ ret = setresgid(nsgid, nsgid, nsgid); ++ if (ret < 0) ++ return log_error_errno(-1, errno, "Failed to setresgid(%d, %d, %d)", ++ (int)nsgid, (int)nsgid, (int)nsgid); ++ ++ ret = setresuid(nsuid, nsuid, nsuid); ++ if (ret < 0) ++ return log_error_errno(-1, errno, "Failed to setresuid(%d, %d, %d)", ++ (int)nsuid, (int)nsuid, (int)nsuid); ++ ++ return cgroup_tree_remove(arg->hierarchies, arg->container_cgroup); ++} ++ + __cgfsng_ops static void cgfsng_payload_destroy(struct cgroup_ops *ops, + struct lxc_handler *handler) + { +@@ -1227,6 +1231,14 @@ try_lxc_rm_rf: + } + #endif + ++#ifdef HAVE_ISULAD ++__cgfsng_ops static inline bool cgfsng_monitor_create(struct cgroup_ops *ops, ++ struct lxc_handler *handler) ++{ ++ return true; ++} ++#else ++ + static int mkdir_eexist_on_last(const char *dir, mode_t mode) + { + const char *tmp = dir; +@@ -1311,13 +1323,6 @@ static void cgroup_tree_leaf_remove(struct hierarchy *h, bool payload) + SYSWARN("Failed to rmdir(\"%s\") cgroup", full_path); + } + +-#ifdef HAVE_ISULAD +-__cgfsng_ops static inline bool cgfsng_monitor_create(struct cgroup_ops *ops, +- struct lxc_handler *handler) +-{ +- return true; +-} +-#else + __cgfsng_ops static inline bool cgfsng_monitor_create(struct cgroup_ops *ops, + struct lxc_handler *handler) + { +@@ -3038,6 +3043,7 @@ static int device_cgroup_parse_access(struct device_item *device, const char *va + return 0; + } + ++#ifndef HAVE_ISULAD + static int device_cgroup_rule_parse(struct device_item *device, const char *key, + const char *val) + { +@@ -3124,6 +3130,7 @@ static int device_cgroup_rule_parse(struct device_item *device, const char *key, + + return device_cgroup_parse_access(device, ++val); + } ++#endif + + #ifdef HAVE_ISULAD + __cgfsng_ops static int cgfsng_set(struct cgroup_ops *ops, +@@ -3307,6 +3314,7 @@ static int convert_devpath(const char *invalue, char *dest) + return 0; + } + ++#ifndef HAVE_ISULAD + /* Called from setup_limits - here we have the container's cgroup_data because + * we created the cgroups. + */ +@@ -3339,6 +3347,7 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, + + return lxc_write_openat(h->container_full_path, filename, value, strlen(value)); + } ++#endif + + #ifdef HAVE_ISULAD + /* Called from setup_limits - here we have the container's cgroup_data because +@@ -3923,7 +3932,6 @@ static int cg_hybrid_init(struct cgroup_ops *ops, bool relative, bool unprivileg + __do_free char *base_cgroup = NULL, *mountpoint = NULL; + __do_free_string_list char **controller_list = NULL; + int type; +- bool writeable; + struct hierarchy *new; + + type = get_cgroup_version(line); +@@ -3989,6 +3997,7 @@ static int cg_hybrid_init(struct cgroup_ops *ops, bool relative, bool unprivileg + base_cgroup[1] = '\0'; + } + #else ++ bool writeable; + if (type == CGROUP2_SUPER_MAGIC) + writeable = test_writeable_v2(mountpoint, base_cgroup); + else +diff --git a/src/lxc/confile.c b/src/lxc/confile.c +index 55cba6d..f00afe9 100644 +--- a/src/lxc/confile.c ++++ b/src/lxc/confile.c +@@ -6228,7 +6228,6 @@ static int get_config_init_args(const char *key, char *retv, int inlen, + struct lxc_conf *c, void *data) + { + int i, len, fulllen = 0; +- struct lxc_list *it; + + if (!retv) + inlen = 0; +diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c +index 14686fc..c0a4d1a 100644 +--- a/src/lxc/terminal.c ++++ b/src/lxc/terminal.c +@@ -287,6 +287,7 @@ static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal) + return lxc_terminal_create_log_file(terminal); + } + ++#ifndef HAVE_ISULAD + static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf, + int bytes_read) + { +@@ -392,6 +393,7 @@ static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf, + bytes_read -= ret; + return bytes_read; + } ++#endif + + #ifdef HAVE_ISULAD + /* get time buffer */ +@@ -1240,8 +1242,8 @@ void lxc_terminal_free(struct lxc_conf *conf, int fd) + + static int lxc_terminal_peer_default(struct lxc_terminal *terminal) + { +- struct lxc_terminal_state *ts; +- const char *path; ++ struct lxc_terminal_state *ts = NULL; ++ const char *path = NULL; + int ret = 0; + + if (terminal->path) +diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c +index b068c9a..48e18bb 100644 +--- a/src/lxc/tools/lxc_attach.c ++++ b/src/lxc/tools/lxc_attach.c +@@ -507,11 +507,9 @@ out: + + int main(int argc, char *argv[]) + { +- int ret = -1; + int wexit = 0; + struct lxc_log log; + char *errmsg = NULL; +- pid_t pid; + lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT; + lxc_attach_command_t command = (lxc_attach_command_t){.program = NULL}; + +diff --git a/src/lxc/utils.c b/src/lxc/utils.c +index 39413ee..ba69995 100644 +--- a/src/lxc/utils.c ++++ b/src/lxc/utils.c +@@ -1427,9 +1427,11 @@ static int lxc_get_unused_loop_dev(char *name_loop) + { + int loop_nr, ret; + int fd_ctl = -1, fd_tmp = -1; ++#if HAVE_ISULAD + // isulad: retry and try mknod + int max_retry = 200; + bool try_mknod = true; ++#endif + + fd_ctl = open("/dev/loop-control", O_RDWR | O_CLOEXEC); + if (fd_ctl < 0) { +@@ -1446,7 +1448,10 @@ static int lxc_get_unused_loop_dev(char *name_loop) + ret = snprintf(name_loop, LO_NAME_SIZE, "/dev/loop%d", loop_nr); + if (ret < 0 || ret >= LO_NAME_SIZE) + goto on_error; ++ ++#if HAVE_ISULAD + retry: ++#endif + fd_tmp = open(name_loop, O_RDWR | O_CLOEXEC); + if (fd_tmp < 0) { + #if HAVE_ISULAD +@@ -1693,6 +1698,7 @@ uint64_t lxc_find_next_power2(uint64_t n) + return n; + } + ++#ifndef HAVE_ISULAD + static int process_dead(/* takes */ int status_fd) + { + __do_close int dupfd = -EBADF; +@@ -1730,6 +1736,7 @@ static int process_dead(/* takes */ int status_fd) + + return ret; + } ++#endif + + int lxc_set_death_signal(int signal, pid_t parent, int parent_status_fd) + { +-- +1.8.3.1 + diff --git a/0029-add-start-timeout-to-limit-start-time.patch b/0034-support-timeout.patch similarity index 32% rename from 0029-add-start-timeout-to-limit-start-time.patch rename to 0034-support-timeout.patch index fe5ad412bdb889274ca8cc458cb97e3a004b3de2..442e6e98838f06ede3a31c57eda977fe9e5ef55c 100644 --- a/0029-add-start-timeout-to-limit-start-time.patch +++ b/0034-support-timeout.patch @@ -1,108 +1,336 @@ -From be744bf5f224a4a14790c8f6a37c5335590daaf6 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Mon, 14 Jan 2019 21:38:07 -0500 -Subject: [PATCH 029/140] add start timeout to limit start time +From b13e288b8a46262e2c062ddfc152f10739b1691a Mon Sep 17 00:00:00 2001 +From: haozi007 +Date: Wed, 15 Apr 2020 17:35:53 +0800 +Subject: [PATCH 34/49] support timeout -Signed-off-by: LiFeng +Signed-off-by: haozi007 --- - src/lxc/conf.c | 6 +-- - src/lxc/execute.c | 4 +- - src/lxc/lxc.h | 8 ++-- - src/lxc/lxccontainer.c | 21 ++++++++- - src/lxc/lxccontainer.h | 16 +++++++ - src/lxc/start.c | 106 +++++++++++++++++++++++++++++++++++++++++++--- - src/lxc/start.h | 6 +-- - src/lxc/tools/arguments.h | 2 + - src/lxc/tools/lxc_start.c | 26 ++++++++++++ - 9 files changed, 175 insertions(+), 20 deletions(-) + src/lxc/attach.c | 104 ++++++++++++++++++++++++++++++++++++++-- + src/lxc/attach.h | 6 +++ + src/lxc/commands.c | 5 ++ + src/lxc/execute.c | 12 +++++ + src/lxc/lxc.h | 13 ++++- + src/lxc/lxccontainer.c | 41 ++++++++++++++-- + src/lxc/lxccontainer.h | 16 +++++++ + src/lxc/start.c | 115 +++++++++++++++++++++++++++++++++++++++++++-- + src/lxc/start.h | 6 +++ + src/lxc/tools/arguments.h | 2 + + src/lxc/tools/lxc_attach.c | 10 ++++ + src/lxc/tools/lxc_start.c | 14 ++++++ + src/lxc/utils.c | 11 +++++ + src/lxc/utils.h | 2 + + 14 files changed, 346 insertions(+), 11 deletions(-) -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index f429491..439353b 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4381,14 +4381,12 @@ void* wait_ocihook_timeout(void *arg) - - if (alive) { - ERROR("%s:%d: running %s hook caused \"hook ran past specified timeout of %.1fs\"", -- __FILE__, __LINE__, -- (conf->which == LXCHOOK_START_HOST) ? "prestart" : lxchook_names[conf->which], -+ __FILE__, __LINE__, lxchook_names[conf->which], - (double)conf->timeout); - - if (conf->errfd >= 0) { - lxc_write_error_message(conf->errfd, "%s:%d: running %s hook caused \"hook ran past specified timeout of %.1fs\"", -- __FILE__, __LINE__, -- (conf->which == LXCHOOK_START_HOST) ? "prestart" : lxchook_names[conf->which], -+ __FILE__, __LINE__, lxchook_names[conf->which], - (double)conf->timeout); +diff --git a/src/lxc/attach.c b/src/lxc/attach.c +index cb480ed..510c069 100644 +--- a/src/lxc/attach.c ++++ b/src/lxc/attach.c +@@ -45,12 +45,27 @@ + #include "terminal.h" + #include "utils.h" + ++#if HAVE_SYS_PERSONALITY_H ++#include ++#endif ++ + #ifdef HAVE_ISULAD + #include "exec_commands.h" +-#endif + +-#if HAVE_SYS_PERSONALITY_H +-#include ++typedef enum { ++ ATTACH_INIT, ++ ATTACH_TIMEOUT, ++ ATTACH_MAX, ++} attach_timeout_t; ++ ++static volatile attach_timeout_t g_attach_timeout_state = ATTACH_INIT; ++ ++struct attach_timeout_conf { ++ int64_t timeout; ++ unsigned long long start_time; ++ pid_t pid; ++}; ++ + #endif + + lxc_log_define(attach, lxc); +@@ -1038,9 +1053,67 @@ static inline void lxc_attach_terminal_close_log(struct lxc_terminal *terminal) + close_prot_errno_disarm(terminal->log_fd); + } + ++#ifdef HAVE_ISULAD ++/* isulad: attach timeout thread function */ ++static void* wait_attach_timeout(void *arg) ++{ ++ struct attach_timeout_conf *conf = (struct attach_timeout_conf *)arg; ++ ++ if (!conf || conf->timeout < 1) ++ goto out; ++ sleep(conf->timeout); ++ if (lxc_process_alive(conf->pid, conf->start_time)) { ++ g_attach_timeout_state = ATTACH_TIMEOUT; ++ if (kill(conf->pid, SIGKILL) < 0) { ++ ERROR("Failed to send signal %d to pid %d", SIGKILL, conf->pid); ++ } ++ } ++ ++out: ++ free(conf); ++ return ((void *)0); ++} ++ ++/* isulad: create attach timeout thread */ ++static int create_attach_timeout_thread(int64_t attach_timeout, pid_t pid) ++{ ++ int ret = 0; ++ pthread_t ptid; ++ pthread_attr_t attr; ++ struct attach_timeout_conf *timeout_conf = NULL; ++ ++ timeout_conf = malloc(sizeof(struct attach_timeout_conf)); ++ if (timeout_conf == NULL) { ++ ERROR("Failed to malloc attach timeout conf"); ++ ret = -1; ++ goto out; ++ } ++ ++ memset(timeout_conf, 0, sizeof(struct attach_timeout_conf)); ++ timeout_conf->timeout = attach_timeout; ++ timeout_conf->pid = pid; ++ timeout_conf->start_time = lxc_get_process_startat(pid); ++ ++ pthread_attr_init(&attr); ++ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); ++ ret = pthread_create(&ptid, &attr, wait_attach_timeout, timeout_conf); ++ if (ret != 0) { ++ ERROR("Create attach wait timeout thread failed"); ++ free(timeout_conf); ++ goto out; ++ } ++ ++out: ++ return ret; ++} ++int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, ++ void *exec_payload, lxc_attach_options_t *options, ++ pid_t *attached_process, char **err_msg) ++#else + int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + void *exec_payload, lxc_attach_options_t *options, + pid_t *attached_process) ++#endif + { + int i, ret, status; + int ipc_sockets[2]; +@@ -1417,6 +1490,26 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + + *attached_process = attached_pid; + ++#ifdef HAVE_ISULAD ++ if (options->timeout > 0) { ++ ret = create_attach_timeout_thread(options->timeout, *attached_process); ++ if (ret) { ++ ERROR("Failed to create attach timeout thread for container."); ++ goto close_mainloop; ++ } ++ } ++ /* isulad: read error msg from pipe */ ++ ssize_t size_read; ++ char errbuf[BUFSIZ + 1] = {0}; ++ ++ size_read = read(conf->errpipe[0], errbuf, BUFSIZ); ++ if (size_read > 0) { ++ if (err_msg) ++ *err_msg = safe_strdup(errbuf); ++ goto close_mainloop; ++ } ++#endif ++ + /* Now shut down communication with child, we're done. */ + shutdown(ipc_sockets[0], SHUT_RDWR); + close(ipc_sockets[0]); +@@ -1433,6 +1526,11 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + } } ++#ifdef HAVE_ISULAD ++ if (g_attach_timeout_state == ATTACH_TIMEOUT && err_msg != NULL && *err_msg == NULL) { ++ *err_msg = safe_strdup("Attach exceeded timeout"); ++ } ++#endif + close_mainloop: + if (options->attach_flags & LXC_ATTACH_TERMINAL) + lxc_mainloop_close(&descr); +diff --git a/src/lxc/attach.h b/src/lxc/attach.h +index ef5a6c1..8316344 100644 +--- a/src/lxc/attach.h ++++ b/src/lxc/attach.h +@@ -20,9 +20,15 @@ struct lxc_proc_context_info { + int ns_fd[LXC_NS_MAX]; + }; + ++#ifdef HAVE_ISULAD ++extern int lxc_attach(struct lxc_container *container, ++ lxc_attach_exec_t exec_function, void *exec_payload, ++ lxc_attach_options_t *options, pid_t *attached_process, char **err_msg); ++#else + extern int lxc_attach(struct lxc_container *container, + lxc_attach_exec_t exec_function, void *exec_payload, + lxc_attach_options_t *options, pid_t *attached_process); ++#endif + + extern int lxc_attach_remount_sys_proc(void); + +diff --git a/src/lxc/commands.c b/src/lxc/commands.c +index b21c12b..c32aef1 100644 +--- a/src/lxc/commands.c ++++ b/src/lxc/commands.c +@@ -119,7 +119,12 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd) + int ret; + struct lxc_cmd_rsp *rsp = &cmd->rsp; + ++#ifdef HAVE_ISULAD ++ /*isulad: add timeout 1s to avoid long block due to [lxc monitor] error*/ ++ ret = lxc_abstract_unix_recv_fds_timeout(sock, &fd_rsp, 1, rsp, sizeof(*rsp), 1000 * 1000); ++#else + ret = lxc_abstract_unix_recv_fds(sock, &fd_rsp, 1, rsp, sizeof(*rsp)); ++#endif + if (ret < 0) + return log_warn_errno(-1, + errno, "Failed to receive response for command \"%s\"", diff --git a/src/lxc/execute.c b/src/lxc/execute.c -index 45ca67e..d388e63 100644 +index 7dd8358..59ff604 100644 --- a/src/lxc/execute.c +++ b/src/lxc/execute.c -@@ -111,12 +111,12 @@ static struct lxc_operations execute_start_ops = { +@@ -88,14 +88,26 @@ static struct lxc_operations execute_start_ops = { + .post_start = execute_post_start + }; ++#ifdef HAVE_ISULAD ++int lxc_execute(const char *name, char *const argv[], int quiet, ++ struct lxc_handler *handler, const char *lxcpath, ++ bool daemonize, int *error_num, unsigned int start_timeout) ++#else int lxc_execute(const char *name, char *const argv[], int quiet, struct lxc_handler *handler, const char *lxcpath, -- bool daemonize, int *error_num) -+ bool daemonize, int *error_num, unsigned int start_timeout) + bool daemonize, int *error_num) ++#endif { ++ struct execute_args args = {.argv = argv, .quiet = quiet}; TRACE("Doing lxc_execute"); handler->conf->is_execute = true; - return __lxc_start(name, handler, &execute_start_ops, &args, lxcpath, -- daemonize, error_num); ++#ifdef HAVE_ISULAD ++ return __lxc_start(handler, &execute_start_ops, &args, lxcpath, + daemonize, error_num, start_timeout); ++#else + return __lxc_start(handler, &execute_start_ops, &args, lxcpath, + daemonize, error_num); ++#endif } diff --git a/src/lxc/lxc.h b/src/lxc/lxc.h -index 22e3509..687b4b2 100644 +index 99fd422..ec2feaa 100644 --- a/src/lxc/lxc.h +++ b/src/lxc/lxc.h -@@ -55,7 +55,7 @@ struct lxc_handler; +@@ -32,9 +32,14 @@ struct lxc_handler; + * @daemonize : 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_handler *handler, const char *lxcpath, -- bool daemonize, int *error_num); -+ bool daemonize, int *error_num, unsigned int start_timeout); - ++#ifdef HAVE_ISULAD ++extern int lxc_start(char *const argv[], struct lxc_handler *handler, ++ const char *lxcpath, bool daemonize, int *error_num, ++ unsigned int start_timeout); ++#else + extern int lxc_start(char *const argv[], struct lxc_handler *handler, + const char *lxcpath, bool daemonize, int *error_num); +- ++#endif /* * Start the specified command inside an application container -@@ -66,9 +66,9 @@ extern int lxc_start(const char *name, char *const argv[], + * @name : the name of the container +@@ -44,9 +49,15 @@ extern int lxc_start(char *const argv[], struct lxc_handler *handler, * @daemonize : whether or not the container is daemonized * Returns 0 on success, < 0 otherwise */ --extern int lxc_execute(const char *name, char *const argv[], int quiet, -- struct lxc_handler *handler, const char *lxcpath, -- bool daemonize, int *error_num); -+int lxc_execute(const char *name, char *const argv[], int quiet, -+ struct lxc_handler *handler, const char *lxcpath, -+ bool daemonize, int *error_num, unsigned int start_timeout); ++#ifdef HAVE_ISULAD ++extern int lxc_execute(const char *name, char *const argv[], int quiet, ++ struct lxc_handler *handler, const char *lxcpath, ++ bool daemonize, int *error_num, unsigned int start_timeout); ++#else + extern int lxc_execute(const char *name, char *const argv[], int quiet, + struct lxc_handler *handler, const char *lxcpath, + bool daemonize, int *error_num); ++#endif /* * Close the fd associated with the monitoring diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index e6272fc..beae459 100644 +index ce2b2bf..f622a63 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c -@@ -1169,10 +1169,10 @@ reboot: +@@ -1234,17 +1234,25 @@ reboot: + goto on_error; + } - if (useinit) ++#ifdef HAVE_ISULAD + if (useinit) { ret = lxc_execute(c->name, argv, 1, handler, c->config_path, - c->daemonize, &c->error_num); + c->daemonize, &c->error_num, c->start_timeout); - else - ret = lxc_start(c->name, argv, handler, c->config_path, -- c->daemonize, &c->error_num); -+ c->daemonize, &c->error_num, c->start_timeout); + } + else { +-#ifdef HAVE_ISULAD + handler->disable_pty = c->disable_pty; + handler->open_stdin = c->open_stdin; +-#endif ++ ret = lxc_start(argv, handler, c->config_path, c->daemonize, ++ &c->error_num, c->start_timeout); ++#else ++ if (useinit) { ++ ret = lxc_execute(c->name, argv, 1, handler, c->config_path, ++ c->daemonize, &c->error_num); ++ } ++ else { + ret = lxc_start(argv, handler, c->config_path, c->daemonize, + &c->error_num); ++#endif + } if (conf->reboot == REBOOT_REQ) { - INFO("Container requested reboot"); -@@ -5100,6 +5100,22 @@ static bool do_lxcapi_set_container_info_file(struct lxc_container *c, const cha - - WRAP_API_1(bool, lxcapi_set_container_info_file, const char *) +@@ -4200,8 +4208,13 @@ static int lxcapi_attach(struct lxc_container *c, + + current_config = c->lxc_conf; + ++#ifdef HAVE_ISULAD ++ ret = lxc_attach(c, exec_function, exec_payload, options, ++ attached_process, &c->lxc_conf->errmsg); ++#else + ret = lxc_attach(c, exec_function, exec_payload, options, + attached_process); ++#endif + current_config = NULL; + return ret; + } +@@ -4221,7 +4234,11 @@ static int do_lxcapi_attach_run_wait(struct lxc_container *c, + command.program = (char *)program; + command.argv = (char **)argv; + ++#ifdef HAVE_ISULAD ++ ret = lxc_attach(c, lxc_attach_run_command, &command, options, &pid, NULL); ++#else + ret = lxc_attach(c, lxc_attach_run_command, &command, options, &pid); ++#endif + if (ret < 0) + return ret; + +@@ -5593,6 +5610,23 @@ static bool do_lxcapi_get_container_pids(struct lxc_container *c, pid_t **pids,s + } + WRAP_API_2(bool, lxcapi_get_container_pids, pid_t **,size_t *) ++ +/* isulad add start timeout */ +static bool do_lxcapi_set_start_timeout(struct lxc_container *c, unsigned int start_timeout) +{ @@ -119,24 +347,24 @@ index e6272fc..beae459 100644 + +WRAP_API_1(bool, lxcapi_set_start_timeout, unsigned int) + - struct lxc_container *lxc_container_new(const char *name, const char *configpath) - { - struct lxc_container *c; -@@ -5231,6 +5247,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath - /* isulad add begin */ - c->set_terminal_init_fifos = lxcapi_set_terminal_default_fifos; - c->set_container_info_file = lxcapi_set_container_info_file; + #endif + + #ifdef HAVE_ISULAD +@@ -5764,6 +5798,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath + c->want_open_stdin = lxcapi_want_open_stdin; + c->clean_container_resource = lxcapi_clean_container_resource; + c->get_container_pids = lxcapi_get_container_pids; + c->set_start_timeout = lxcapi_set_start_timeout; - /* isulad add end */ + #endif return c; diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h -index 5d23cc7..77de704 100644 +index 6ede70c..2951ac7 100644 --- a/src/lxc/lxccontainer.h +++ b/src/lxc/lxccontainer.h -@@ -94,6 +94,12 @@ struct lxc_container { - */ - char *exit_fifo; +@@ -125,6 +125,12 @@ struct lxc_container { + * */ + char *ocihookfile; + /*! isulad: + * \private @@ -145,12 +373,12 @@ index 5d23cc7..77de704 100644 + unsigned int start_timeout; + /*! - * \private - * Container semaphore lock. -@@ -880,6 +886,16 @@ struct lxc_container { + * \brief Determine if \c /var/lib/lxc/$name/config exists. + * +@@ -960,6 +966,16 @@ struct lxc_container { * \return \c true on success, else \c false. */ - bool (*set_container_info_file) (struct lxc_container *c, const char *info_file); + bool (*get_container_pids)(struct lxc_container *c,pid_t **pids,size_t *pids_len); + + /*! isulad add + * \brief An API call to set start timeout @@ -165,16 +393,13 @@ index 5d23cc7..77de704 100644 /*! diff --git a/src/lxc/start.c b/src/lxc/start.c -index 63f5af8..f7be9e4 100644 +index 70ce1bd..0bc1143 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c -@@ -93,7 +93,22 @@ extern void mod_all_rdeps(struct lxc_container *c, bool inc); - static bool do_destroy_container(struct lxc_handler *handler); - static int lxc_rmdir_onedev_wrapper(void *data); - static void lxc_destroy_container_on_signal(struct lxc_handler *handler, -- const char *name); -+ const char *name); -+ +@@ -880,6 +880,21 @@ out_restore_sigmask: + } + + #ifdef HAVE_ISULAD +/* isulad: start timeout thread */ +typedef enum { + START_INIT, @@ -189,41 +414,41 @@ index 63f5af8..f7be9e4 100644 + unsigned int timeout; + int errfd; +}; - - static void print_top_failing_dir(const char *path) ++ + void trim_line(char *s) { -@@ -1897,6 +1912,12 @@ static int lxc_spawn(struct lxc_handler *handler) + size_t len; +@@ -2285,6 +2300,12 @@ static int lxc_spawn(struct lxc_handler *handler) goto out_delete_net; } + if (START_TIMEOUT == global_timeout_state) { -+ //lxc_write_error_message(conf->errpipe[1], "Starting the container \"%s\" timeout.", name); ++ lxc_write_error_message(conf->errpipe[1], "Starting the container \"%s\" timeout.", name); + ERROR("Starting the container \"%s\" timeout.", name); + goto out_delete_net; + } + - /* Tell the child to complete its initialization and wait for it to exec - * or return an error. (The child will never return - * LXC_SYNC_READY_START+1. It will either close the sync pipe, causing -@@ -1936,7 +1957,13 @@ static int lxc_spawn(struct lxc_handler *handler) - ret = run_lxc_hooks(name, "oci-poststart", conf, oci_hook_args); - if (ret < 0) { + /* 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. + */ +@@ -2341,6 +2362,13 @@ static int lxc_spawn(struct lxc_handler *handler) ERROR("Failed to run oci poststart hooks"); -- goto out_delete_net; -+ goto out_abort; -+ } + goto out_abort; + } + + if (START_TIMEOUT == global_timeout_state) { -+ //lxc_write_error_message(conf->errpipe[1], "Starting the container \"%s\" timeout.", name); ++ lxc_write_error_message(conf->errpipe[1], "Starting the container \"%s\" timeout.", name); + ERROR("Starting the container \"%s\" timeout.", name); + goto out_abort; - } ++ } ++ + #endif ret = lxc_set_state(name, handler, RUNNING); -@@ -1964,12 +1991,71 @@ out_abort: - return -1; +@@ -2368,17 +2396,82 @@ out_sync_fini: } + #ifdef HAVE_ISULAD +/* isulad: start timeout thread function */ +static void* wait_start_timeout(void *arg) +{ @@ -258,7 +483,7 @@ index 63f5af8..f7be9e4 100644 + } + + timeout_conf = malloc(sizeof(struct start_timeout_conf)); -+ if (!timeout_conf) { ++ if (timeout_conf == NULL) { + ERROR("Failed to malloc start timeout conf"); + ret = -1; + goto out; @@ -284,38 +509,49 @@ index 63f5af8..f7be9e4 100644 +} + // isulad: send '128 + signal' if container is killed by signal. - #define ExitSignalOffset 128 + #define EXIT_SIGNAL_OFFSET 128 + #endif - int __lxc_start(const char *name, struct lxc_handler *handler, - struct lxc_operations* ops, void *data, const char *lxcpath, -- bool daemonize, int *error_num) -+ bool daemonize, int *error_num, unsigned int start_timeout) ++ ++#ifdef HAVE_ISULAD ++int __lxc_start(struct lxc_handler *handler, struct lxc_operations *ops, ++ void *data, const char *lxcpath, bool daemonize, int *error_num, ++ unsigned int start_timeout) ++{ ++ int exit_code; ++#else + int __lxc_start(struct lxc_handler *handler, struct lxc_operations *ops, + void *data, const char *lxcpath, bool daemonize, int *error_num) { - int ret, status, exit_code; +- int ret, status; +-#ifdef HAVE_ISULAD +- int exit_code; + #endif ++ int ret, status; + const char *name = handler->name; struct lxc_conf *conf = handler->conf; -@@ -1983,8 +2069,18 @@ int __lxc_start(const char *name, struct lxc_handler *handler, - handler->data = data; + struct cgroup_ops *cgroup_ops; +@@ -2393,6 +2486,16 @@ int __lxc_start(struct lxc_handler *handler, struct lxc_operations *ops, handler->daemonize = daemonize; + cgroup_ops = handler->cgroup_ops; ++#ifdef HAVE_ISULAD + /* isulad: add start timeout limit */ + if (start_timeout > 0) { + ret = create_start_timeout_thread(conf, start_timeout); + if (ret) { + ERROR("Failed to create start timeout thread for container \"%s\".", name); -+ goto out_fini_nonet; ++ goto out_abort; + } + } -+ ++#endif if (!attach_block_device(handler->conf)) { ERROR("Failed to attach block device"); -+ ret = -1; - goto out_fini_nonet; - } - -@@ -2114,14 +2210,14 @@ static struct lxc_operations start_ops = { + ret = -1; +@@ -2574,14 +2677,18 @@ static struct lxc_operations start_ops = { }; - int lxc_start(const char *name, char *const argv[], struct lxc_handler *handler, + int lxc_start(char *const argv[], struct lxc_handler *handler, - const char *lxcpath, bool daemonize, int *error_num) + const char *lxcpath, bool daemonize, int *error_num, unsigned int start_timeout) { @@ -324,90 +560,111 @@ index 63f5af8..f7be9e4 100644 }; TRACE("Doing lxc_start"); -- return __lxc_start(name, handler, &start_ops, &start_arg, lxcpath, daemonize, error_num); -+ return __lxc_start(name, handler, &start_ops, &start_arg, lxcpath, daemonize, error_num, start_timeout); ++#ifdef HAVE_ISULAD ++ return __lxc_start(handler, &start_ops, &start_arg, lxcpath, daemonize, error_num, start_timeout); ++#else + return __lxc_start(handler, &start_ops, &start_arg, lxcpath, daemonize, error_num); ++#endif } static void lxc_destroy_container_on_signal(struct lxc_handler *handler, diff --git a/src/lxc/start.h b/src/lxc/start.h -index f59bf54..a96f2ae 100644 +index 4fc3ff7..cea37bc 100644 --- a/src/lxc/start.h +++ b/src/lxc/start.h -@@ -174,9 +174,9 @@ extern void lxc_fini(const char *name, struct lxc_handler *handler); +@@ -170,8 +170,14 @@ extern void lxc_end(struct lxc_handler *handler); */ extern int lxc_check_inherited(struct lxc_conf *conf, bool closeall, int *fds_to_ignore, size_t len_fds); --extern int __lxc_start(const char *, struct lxc_handler *, -- struct lxc_operations *, void *, const char *, bool, -- int *); -+extern int __lxc_start(const char *name, struct lxc_handler *handler, ++#ifdef HAVE_ISULAD ++extern int __lxc_start(struct lxc_handler *handler, + struct lxc_operations* ops, void *data, const char *lxcpath, + bool daemonize, int *error_num, unsigned int start_timeout); ++#else + extern int __lxc_start(struct lxc_handler *, struct lxc_operations *, void *, + const char *, bool, int *); ++#endif extern int resolve_clone_flags(struct lxc_handler *handler); diff --git a/src/lxc/tools/arguments.h b/src/lxc/tools/arguments.h -index 047e9f1..afab9f5 100644 +index a6d9967..41ea109 100644 --- a/src/lxc/tools/arguments.h +++ b/src/lxc/tools/arguments.h -@@ -65,6 +65,7 @@ struct lxc_arguments { - char *terminal_fifos[2]; /* isulad add, fifos used to redirct stdin/out/err */ - const char *container_info; /* isulad: file used to store pid and ppid info of container */ - const char *exit_monitor_fifo; /* isulad: fifo used to monitor state of monitor process */ +@@ -47,6 +47,8 @@ struct lxc_arguments { + const char *suffix; /* isulad add, suffix used for connect with parent of execed process*/ + int disable_pty; + int open_stdin; + unsigned int start_timeout; /* isulad: Seconds for waiting on a container to start before it is killed*/ ++ int64_t attach_timeout; /* for lxc-attach */ + #endif /* for lxc-console */ - unsigned int ttynum; -@@ -180,6 +181,7 @@ struct lxc_arguments { - #define OPT_OUTPUT_FIFO OPT_USAGE - 8 - #define OPT_CONTAINER_INFO OPT_USAGE - 9 - #define OPT_EXIT_FIFO OPT_USAGE - 10 -+#define OPT_START_TIMEOUT OPT_USAGE - 11 - /* isulad add end*/ - - extern int lxc_arguments_parse(struct lxc_arguments *args, int argc, +diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c +index 48e18bb..a855a8d 100644 +--- a/src/lxc/tools/lxc_attach.c ++++ b/src/lxc/tools/lxc_attach.c +@@ -81,6 +81,7 @@ static const struct option my_longopts[] = { + {"out-fifo", required_argument, 0, OPT_OUTPUT_FIFO}, + {"err-fifo", required_argument, 0, OPT_STDERR_FIFO}, + {"suffix", required_argument, 0, OPT_ATTACH_SUFFIX}, ++ {"timeout", required_argument, 0, OPT_ATTACH_TIMEOUT}, + #endif + LXC_COMMON_OPTIONS + }; +@@ -141,6 +142,7 @@ Options :\n\ + #else + "\ + --user User ID (format: UID[:GID])\n\ ++ --timeout Timeout in seconds (default: 0)\n\ + " + #endif + , +@@ -303,6 +305,13 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) + case OPT_ATTACH_SUFFIX: + args->suffix = arg; + break; ++ case OPT_ATTACH_TIMEOUT: ++ if(!is_non_negative_num(arg)) { ++ ERROR("Error attach timeout parameter:%s.\n", arg); ++ return -1; ++ } ++ args->attach_timeout = (unsigned int)atoll(arg); ++ break; + #endif + } + +@@ -581,6 +590,7 @@ int main(int argc, char *argv[]) + attach_options.env_policy = env_policy; + attach_options.extra_env_vars = extra_env; + attach_options.extra_keep_env = extra_keep; ++ attach_options.timeout = my_args.attach_timeout; + + if (my_args.argc > 0) { + command.program = my_args.argv[0]; diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c -index 60c7d70..f37f8a6 100644 +index 72a4494..b430a1e 100644 --- a/src/lxc/tools/lxc_start.c +++ b/src/lxc/tools/lxc_start.c -@@ -40,6 +40,7 @@ - #include - #include - #include -+#include +@@ -29,6 +29,7 @@ + #include "log.h" - #include + #ifdef HAVE_ISULAD ++#include + #include "isulad_utils.h" + #endif -@@ -74,6 +75,7 @@ static const struct option my_longopts[] = { - {"out-fifo", required_argument, 0, OPT_OUTPUT_FIFO}, - {"container-pidfile", required_argument, 0, OPT_CONTAINER_INFO}, - {"exit-fifo", required_argument, 0, OPT_EXIT_FIFO}, +@@ -61,6 +62,7 @@ static const struct option my_longopts[] = { + {"start-timeout", required_argument, 0, OPT_START_TIMEOUT}, + {"disable-pty", no_argument, 0, OPT_DISABLE_PTY}, + {"open-stdin", no_argument, 0, OPT_OPEN_STDIN}, + {"start-timeout", required_argument, 0, OPT_START_TIMEOUT}, - /* isulad add end */ + #endif LXC_COMMON_OPTIONS }; -@@ -108,6 +110,18 @@ Options :\n\ - .pidfile = NULL, - }; - -+static bool is_non_negative_num(const char *s) -+{ -+ if (!s || !strcmp(s, "")) -+ return false; -+ while(*s != '\0') { -+ if(!isdigit(*s)) -+ return false; -+ ++s; -+ } -+ return true; -+} -+ - static int my_parser(struct lxc_arguments *args, int c, char *arg) - { - switch (c) { -@@ -158,6 +172,13 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) - case OPT_EXIT_FIFO: - args->exit_monitor_fifo = arg; +@@ -155,6 +157,13 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) + case OPT_OPEN_STDIN: + args->open_stdin = 1; break; + case OPT_START_TIMEOUT: + if(!is_non_negative_num(arg)) { @@ -416,21 +673,54 @@ index 60c7d70..f37f8a6 100644 + } + args->start_timeout = (unsigned int)atoi(arg); + break; + #endif + } - return 0; - } -@@ -341,6 +362,11 @@ int main(int argc, char *argv[]) - c->exit_fifo = strdup(my_args.exit_monitor_fifo); +@@ -354,6 +363,11 @@ int main(int argc, char *argv[]) + if (my_args.open_stdin) { + c->want_open_stdin(c, true); } - ++ + /* isulad: add start timeout */ + if(my_args.start_timeout) { + c->set_start_timeout(c, my_args.start_timeout); + } -+ + #endif + if (my_args.console) - if (!c->set_config_item(c, "lxc.console.path", my_args.console)) - goto out; +diff --git a/src/lxc/utils.c b/src/lxc/utils.c +index ba69995..810b7fe 100644 +--- a/src/lxc/utils.c ++++ b/src/lxc/utils.c +@@ -2167,4 +2167,15 @@ out: + return alive; + } + ++bool is_non_negative_num(const char *s) ++{ ++ if (!s || !strcmp(s, "")) ++ return false; ++ while(*s != '\0') { ++ if(!isdigit(*s)) ++ return false; ++ ++s; ++ } ++ return true; ++} + #endif +diff --git a/src/lxc/utils.h b/src/lxc/utils.h +index a213ba7..39ef579 100644 +--- a/src/lxc/utils.h ++++ b/src/lxc/utils.h +@@ -324,6 +324,8 @@ extern int unsigned long long lxc_get_process_startat(pid_t pid); + extern int lxc_setup_env_home(uid_t uid); + + extern bool lxc_process_alive(pid_t pid, unsigned long long start_time); ++ ++extern bool is_non_negative_num(const char *s); + #endif + + #endif /* __LXC_UTILS_H */ -- 1.8.3.1 diff --git a/0035-Seccomp-security-feature-enhanced.patch b/0035-Seccomp-security-feature-enhanced.patch new file mode 100644 index 0000000000000000000000000000000000000000..20598e13cc0d856f1ee727a205d77a09f3ef4ea4 --- /dev/null +++ b/0035-Seccomp-security-feature-enhanced.patch @@ -0,0 +1,659 @@ +From 327e83ff13bec4bf1fa80ede9515d3f9531d7d1f Mon Sep 17 00:00:00 2001 +From: wujing +Date: Wed, 15 Apr 2020 06:37:43 -0400 +Subject: [PATCH 35/49] Seccomp security feature enhanced + +Signed-off-by: wujing +--- + src/lxc/conf.c | 3 +- + src/lxc/seccomp.c | 548 +++++++++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 548 insertions(+), 3 deletions(-) + +diff --git a/src/lxc/conf.c b/src/lxc/conf.c +index 6856b1d..e8ee749 100644 +--- a/src/lxc/conf.c ++++ b/src/lxc/conf.c +@@ -4730,8 +4730,7 @@ int lxc_setup(struct lxc_handler *handler) + + // isulad: create link /etc/mtab for /proc/mounts + if (create_mtab_link() != 0) { +- ERROR("failed to create link /etc/mtab for target /proc/mounts"); +- goto on_error; ++ return log_error(-1, "failed to create link /etc/mtab for target /proc/mounts"); + } + #endif + +diff --git a/src/lxc/seccomp.c b/src/lxc/seccomp.c +index 081d315..a75adb7 100644 +--- a/src/lxc/seccomp.c ++++ b/src/lxc/seccomp.c +@@ -295,7 +295,11 @@ on_error: + #endif + + #if HAVE_DECL_SECCOMP_SYSCALL_RESOLVE_NAME_ARCH ++#ifdef HAVE_ISULAD ++enum lxc_arch_t { ++#else + enum lxc_hostarch_t { ++#endif + lxc_seccomp_arch_all = 0, + lxc_seccomp_arch_native, + lxc_seccomp_arch_i386, +@@ -351,8 +355,13 @@ int get_hostarch(void) + return lxc_seccomp_arch_unknown; + } + ++#ifdef HAVE_ISULAD ++scmp_filter_ctx get_new_ctx(enum lxc_arch_t n_arch, ++ uint32_t default_policy_action, uint32_t *architectures) ++#else + scmp_filter_ctx get_new_ctx(enum lxc_hostarch_t n_arch, + uint32_t default_policy_action, bool *needs_merge) ++#endif + { + int ret; + uint32_t arch; +@@ -475,10 +484,17 @@ scmp_filter_ctx get_new_ctx(enum lxc_hostarch_t n_arch, + return NULL; + } + TRACE("Removed native arch from main seccomp context"); +- ++#ifdef HAVE_ISULAD ++ *architectures = arch; ++#else + *needs_merge = true; ++#endif + } else { ++#ifdef HAVE_ISULAD ++ *architectures = SCMP_ARCH_NATIVE; ++#else + *needs_merge = false; ++#endif + TRACE("Arch %d already present in main seccomp context", (int)n_arch); + } + +@@ -510,7 +526,11 @@ bool do_resolve_add_rule(uint32_t arch, char *line, scmp_filter_ctx ctx, + if (ret < 0) { + errno = -ret; + SYSERROR("Failed loading rule to reject force umount"); ++#ifdef HAVE_ISULAD ++ return true; ++#else + return false; ++#endif + } + + INFO("Set seccomp rule to reject force umounts"); +@@ -519,14 +539,24 @@ bool do_resolve_add_rule(uint32_t arch, char *line, scmp_filter_ctx ctx, + + nr = seccomp_syscall_resolve_name(line); + if (nr == __NR_SCMP_ERROR) { ++#ifdef HAVE_ISULAD ++ DEBUG("Failed to resolve syscall \"%s\"", line); ++ DEBUG("This syscall will NOT be handled by seccomp"); ++#else + WARN("Failed to resolve syscall \"%s\"", line); + WARN("This syscall will NOT be handled by seccomp"); ++#endif + return true; + } + + if (nr < 0) { ++#ifdef HAVE_ISULAD ++ DEBUG("Got negative return value %d for syscall \"%s\"", nr, line); ++ DEBUG("This syscall will NOT be handled by seccomp"); ++#else + WARN("Got negative return value %d for syscall \"%s\"", nr, line); + WARN("This syscall will NOT be handled by seccomp"); ++#endif + return true; + } + +@@ -553,14 +583,42 @@ bool do_resolve_add_rule(uint32_t arch, char *line, scmp_filter_ctx ctx, + rule->args_num, arg_cmp); + if (ret < 0) { + errno = -ret; ++#ifdef HAVE_ISULAD ++ DEBUG("Failed loading rule for %s (nr %d action %d (%s))", ++ line, nr, rule->action, get_action_name(rule->action)); ++#else + SYSERROR("Failed loading rule for %s (nr %d action %d (%s))", + line, nr, rule->action, get_action_name(rule->action)); ++#endif + return false; + } + + return true; + } + ++#ifdef HAVE_ISULAD ++#define SCMP_ARCH_INDEX_MAX 3 ++ ++struct scmp_ctx_info { ++ uint32_t architectures[SCMP_ARCH_INDEX_MAX]; ++ enum lxc_arch_t lxc_arch[SCMP_ARCH_INDEX_MAX]; ++ scmp_filter_ctx contexts[SCMP_ARCH_INDEX_MAX]; ++ bool needs_merge[SCMP_ARCH_INDEX_MAX]; ++}; ++ ++static int get_arch_index(enum lxc_arch_t arch, struct scmp_ctx_info *ctx) ++{ ++ int i; ++ ++ for (i = 0; i < SCMP_ARCH_INDEX_MAX; i++) { ++ if (ctx->lxc_arch[i] == arch) ++ return i; ++ } ++ ++ return -1; ++} ++#endif ++ + /* + * v2 consists of + * [x86] +@@ -575,6 +633,493 @@ bool do_resolve_add_rule(uint32_t arch, char *line, scmp_filter_ctx ctx, + * write + * close + */ ++#ifdef HAVE_ISULAD ++static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_conf *conf) ++{ ++ int ret; ++ char *p; ++ enum lxc_arch_t cur_rule_arch, native_arch; ++ bool blacklist = false; ++ uint32_t default_policy_action = -1, default_rule_action = -1; ++ struct seccomp_v2_rule rule; ++ struct scmp_ctx_info ctx; ++ ++ if (strncmp(line, "blacklist", 9) == 0) ++ blacklist = true; ++ else if (strncmp(line, "whitelist", 9) != 0) { ++ ERROR("Bad seccomp policy style \"%s\"", line); ++ return -1; ++ } ++ ++ p = strchr(line, ' '); ++ if (p) { ++ default_policy_action = get_v2_default_action(p + 1); ++ if (default_policy_action == -2) ++ return -1; ++ } ++ ++ /* for blacklist, allow any syscall which has no rule */ ++ if (blacklist) { ++ if (default_policy_action == -1) ++ default_policy_action = SCMP_ACT_ALLOW; ++ ++ if (default_rule_action == -1) ++ default_rule_action = SCMP_ACT_KILL; ++ } else { ++ if (default_policy_action == -1) ++ default_policy_action = SCMP_ACT_KILL; ++ ++ if (default_rule_action == -1) ++ default_rule_action = SCMP_ACT_ALLOW; ++ } ++ ++ memset(&ctx, 0, sizeof(ctx)); ++ ctx.architectures[0] = SCMP_ARCH_NATIVE; ++ ctx.architectures[1] = SCMP_ARCH_NATIVE; ++ ctx.architectures[2] = SCMP_ARCH_NATIVE; ++ native_arch = get_hostarch(); ++ cur_rule_arch = native_arch; ++ if (native_arch == lxc_seccomp_arch_amd64) { ++ cur_rule_arch = lxc_seccomp_arch_all; ++ ++ ctx.lxc_arch[0] = lxc_seccomp_arch_i386; ++ ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_i386, ++ default_policy_action, &ctx.architectures[0]); ++ if (!ctx.contexts[0]) ++ goto bad; ++ ++ ctx.lxc_arch[1] = lxc_seccomp_arch_x32; ++ ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_x32, ++ default_policy_action, &ctx.architectures[1]); ++ if (!ctx.contexts[1]) ++ goto bad; ++ ++ ctx.lxc_arch[2] = lxc_seccomp_arch_amd64; ++ ctx.contexts[2] = get_new_ctx(lxc_seccomp_arch_amd64, ++ default_policy_action, &ctx.architectures[2]); ++ if (!ctx.contexts[2]) ++ goto bad; ++#ifdef SCMP_ARCH_PPC ++ } else if (native_arch == lxc_seccomp_arch_ppc64) { ++ cur_rule_arch = lxc_seccomp_arch_all; ++ ++ ctx.lxc_arch[0] = lxc_seccomp_arch_ppc; ++ ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_ppc, ++ default_policy_action, &ctx.architectures[0]); ++ if (!ctx.contexts[0]) ++ goto bad; ++ ++ ctx.lxc_arch[1] = lxc_seccomp_arch_ppc64; ++ ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_ppc64, ++ default_policy_action, &ctx.architectures[1]); ++ if (!ctx.contexts[1]) ++ goto bad; ++#endif ++#ifdef SCMP_ARCH_ARM ++ } else if (native_arch == lxc_seccomp_arch_arm64) { ++ cur_rule_arch = lxc_seccomp_arch_all; ++ ++ ctx.lxc_arch[0] = lxc_seccomp_arch_arm; ++ ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_arm, ++ default_policy_action, &ctx.architectures[0]); ++ if (!ctx.contexts[0]) ++ goto bad; ++ ++#ifdef SCMP_ARCH_AARCH64 ++ ctx.lxc_arch[1] = lxc_seccomp_arch_arm64; ++ ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_arm64, ++ default_policy_action, &ctx.architectures[1]); ++ if (!ctx.contexts[1]) ++ goto bad; ++#endif ++#endif ++#ifdef SCMP_ARCH_MIPS ++ } else if (native_arch == lxc_seccomp_arch_mips64) { ++ cur_rule_arch = lxc_seccomp_arch_all; ++ ++ ctx.lxc_arch[0] = lxc_seccomp_arch_mips; ++ ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_mips, ++ default_policy_action, &ctx.architectures[0]); ++ if (!ctx.contexts[0]) ++ goto bad; ++ ++ ctx.lxc_arch[1] = lxc_seccomp_arch_mips64n32; ++ ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_mips64n32, ++ default_policy_action, &ctx.architectures[1]); ++ if (!ctx.contexts[1]) ++ goto bad; ++ ++ ctx.lxc_arch[2] = lxc_seccomp_arch_mips64; ++ ctx.contexts[2] = get_new_ctx(lxc_seccomp_arch_mips64, ++ default_policy_action, &ctx.architectures[2]); ++ if (!ctx.contexts[2]) ++ goto bad; ++ } else if (native_arch == lxc_seccomp_arch_mipsel64) { ++ cur_rule_arch = lxc_seccomp_arch_all; ++ ctx.lxc_arch[0] = lxc_seccomp_arch_mipsel; ++ ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_mipsel, ++ default_policy_action, &ctx.architectures[0]); ++ if (!ctx.contexts[0]) ++ goto bad; ++ ++ ctx.lxc_arch[1] = lxc_seccomp_arch_mipsel64n32; ++ ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_mipsel64n32, ++ default_policy_action, &ctx.architectures[1]); ++ if (!ctx.contexts[1]) ++ goto bad; ++ ++ ctx.lxc_arch[2] = lxc_seccomp_arch_mipsel64; ++ ctx.contexts[2] = get_new_ctx(lxc_seccomp_arch_mipsel64, ++ default_policy_action, &ctx.architectures[2]); ++ if (!ctx.contexts[2]) ++ goto bad; ++#endif ++ } ++ ++ if (default_policy_action != SCMP_ACT_KILL) { ++ ret = seccomp_reset(conf->seccomp.seccomp_ctx, default_policy_action); ++ if (ret != 0) { ++ ERROR("Error re-initializing Seccomp"); ++ return -1; ++ } ++ ++ ret = seccomp_attr_set(conf->seccomp.seccomp_ctx, SCMP_FLTATR_CTL_NNP, 0); ++ if (ret < 0) { ++ errno = -ret; ++ SYSERROR("Failed to turn off no-new-privs"); ++ return -1; ++ } ++ ++#ifdef SCMP_FLTATR_ATL_TSKIP ++ ret = seccomp_attr_set(conf->seccomp.seccomp_ctx, SCMP_FLTATR_ATL_TSKIP, 1); ++ if (ret < 0) { ++ errno = -ret; ++ SYSWARN("Failed to turn on seccomp nop-skip, continuing"); ++ } ++#endif ++ } ++ ++ while (getline(&line, line_bufsz, f) != -1) { ++ if (line[0] == '#') ++ continue; ++ ++ if (line[0] == '\0') ++ continue; ++ ++ remove_trailing_newlines(line); ++ ++ INFO("Processing \"%s\"", line); ++ if (line[0] == '[') { ++ /* Read the architecture for next set of rules. */ ++ if (strcmp(line, "[x86]") == 0 || ++ strcmp(line, "[X86]") == 0) { ++ if (native_arch != lxc_seccomp_arch_i386 && ++ native_arch != lxc_seccomp_arch_amd64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_i386; ++ } else if (strcmp(line, "[x32]") == 0 || ++ strcmp(line, "[X32]") == 0) { ++ if (native_arch != lxc_seccomp_arch_amd64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_x32; ++ } else if (strcmp(line, "[X86_64]") == 0 || ++ strcmp(line, "[x86_64]") == 0) { ++ if (native_arch != lxc_seccomp_arch_amd64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_amd64; ++ } else if (strcmp(line, "[all]") == 0 || ++ strcmp(line, "[ALL]") == 0) { ++ cur_rule_arch = lxc_seccomp_arch_all; ++ } ++#ifdef SCMP_ARCH_ARM ++ else if (strcmp(line, "[arm]") == 0 || ++ strcmp(line, "[ARM]") == 0) { ++ if (native_arch != lxc_seccomp_arch_arm && ++ native_arch != lxc_seccomp_arch_arm64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_arm; ++ } ++#endif ++#ifdef SCMP_ARCH_AARCH64 ++ else if (strcmp(line, "[arm64]") == 0 || ++ strcmp(line, "[ARM64]") == 0) { ++ if (native_arch != lxc_seccomp_arch_arm64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_arm64; ++ } ++#endif ++#ifdef SCMP_ARCH_PPC64LE ++ else if (strcmp(line, "[ppc64le]") == 0 || ++ strcmp(line, "[PPC64LE]") == 0) { ++ if (native_arch != lxc_seccomp_arch_ppc64le) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_ppc64le; ++ } ++#endif ++#ifdef SCMP_ARCH_PPC64 ++ else if (strcmp(line, "[ppc64]") == 0 || ++ strcmp(line, "[PPC64]") == 0) { ++ if (native_arch != lxc_seccomp_arch_ppc64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_ppc64; ++ } ++#endif ++#ifdef SCMP_ARCH_PPC ++ else if (strcmp(line, "[ppc]") == 0 || ++ strcmp(line, "[PPC]") == 0) { ++ if (native_arch != lxc_seccomp_arch_ppc && ++ native_arch != lxc_seccomp_arch_ppc64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_ppc; ++ } ++#endif ++#ifdef SCMP_ARCH_MIPS ++ else if (strcmp(line, "[mips64]") == 0 || ++ strcmp(line, "[MIPS64]") == 0) { ++ if (native_arch != lxc_seccomp_arch_mips64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_mips64; ++ } else if (strcmp(line, "[mips64n32]") == 0 || ++ strcmp(line, "[MIPS64N32]") == 0) { ++ if (native_arch != lxc_seccomp_arch_mips64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_mips64n32; ++ } else if (strcmp(line, "[mips]") == 0 || ++ strcmp(line, "[MIPS]") == 0) { ++ if (native_arch != lxc_seccomp_arch_mips && ++ native_arch != lxc_seccomp_arch_mips64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_mips; ++ } else if (strcmp(line, "[mipsel64]") == 0 || ++ strcmp(line, "[MIPSEL64]") == 0) { ++ if (native_arch != lxc_seccomp_arch_mipsel64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_mipsel64; ++ } else if (strcmp(line, "[mipsel64n32]") == 0 || ++ strcmp(line, "[MIPSEL64N32]") == 0) { ++ if (native_arch != lxc_seccomp_arch_mipsel64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_mipsel64n32; ++ } else if (strcmp(line, "[mipsel]") == 0 || ++ strcmp(line, "[MIPSEL]") == 0) { ++ if (native_arch != lxc_seccomp_arch_mipsel && ++ native_arch != lxc_seccomp_arch_mipsel64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_mipsel; ++ } ++#endif ++#ifdef SCMP_ARCH_S390X ++ else if (strcmp(line, "[s390x]") == 0 || ++ strcmp(line, "[S390X]") == 0) { ++ if (native_arch != lxc_seccomp_arch_s390x) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_s390x; ++ } ++#endif ++ else { ++ goto bad_arch; ++ } ++ ++ continue; ++ } ++ ++ /* irrelevant arch - i.e. arm on i386 */ ++ if (cur_rule_arch == lxc_seccomp_arch_unknown) ++ continue; ++ ++ memset(&rule, 0, sizeof(rule)); ++ /* read optional action which follows the syscall */ ++ ret = parse_v2_rules(line, default_rule_action, &rule); ++ if (ret != 0) { ++ ERROR("Failed to interpret seccomp rule"); ++ goto bad_rule; ++ } ++ ++ if (cur_rule_arch == native_arch) { ++ /* add for native arch */ ++ if (!do_resolve_add_rule(SCMP_ARCH_NATIVE, line, ++ conf->seccomp.seccomp_ctx, &rule)) ++ goto bad_rule; ++ ++ INFO("Added native rule for arch %d for %s action %d(%s)", ++ SCMP_ARCH_NATIVE, line, rule.action, ++ get_action_name(rule.action)); ++ } else if (cur_rule_arch != lxc_seccomp_arch_all) { ++ /* add for compat specified arch */ ++ int arch_index = get_arch_index(cur_rule_arch, &ctx); ++ if (arch_index < 0) ++ goto bad_arch; ++ ++ if (!do_resolve_add_rule(ctx.architectures[arch_index], line, ++ ctx.contexts[arch_index], &rule)) ++ goto bad_rule; ++ ++ INFO("Added compat rule for arch %d for %s action %d(%s)", ++ ctx.architectures[arch_index], line, rule.action, ++ get_action_name(rule.action)); ++ ctx.needs_merge[arch_index] = true; ++ } else { ++ /* add for all compat archs */ ++ if (!do_resolve_add_rule(SCMP_ARCH_NATIVE, line, ++ conf->seccomp.seccomp_ctx, &rule)) ++ goto bad_rule; ++ ++ INFO("Added native rule for arch %d for %s action %d(%s)", ++ SCMP_ARCH_NATIVE, line, rule.action, ++ get_action_name(rule.action)); ++ ++ if (ctx.architectures[0] != SCMP_ARCH_NATIVE) { ++ if (!do_resolve_add_rule(ctx.architectures[0], line, ++ ctx.contexts[0], &rule)) ++ goto bad_rule; ++ ++ INFO("Added compat rule for arch %d for %s action %d(%s)", ++ ctx.architectures[0], line, rule.action, ++ get_action_name(rule.action)); ++ ctx.needs_merge[0] = true; ++ } ++ ++ if (ctx.architectures[1] != SCMP_ARCH_NATIVE) { ++ if (!do_resolve_add_rule(ctx.architectures[1], line, ++ ctx.contexts[1], &rule)) ++ goto bad_rule; ++ ++ INFO("Added compat rule for arch %d for %s action %d(%s)", ++ ctx.architectures[1], line, rule.action, ++ get_action_name(rule.action)); ++ ctx.needs_merge[1] = true; ++ } ++ ++ if (ctx.architectures[2] != SCMP_ARCH_NATIVE) { ++ if (!do_resolve_add_rule(ctx.architectures[2], line, ++ ctx.contexts[2], &rule)) ++ goto bad_rule; ++ ++ INFO("Added native rule for arch %d for %s action %d(%s)", ++ ctx.architectures[2], line, rule.action, ++ get_action_name(rule.action)); ++ ctx.needs_merge[2] = true; ++ } ++ } ++ ++ } ++ ++ INFO("Merging compat seccomp contexts into main context"); ++ if (ctx.contexts[0]) { ++ if (ctx.needs_merge[0]) { ++ ret = seccomp_merge(conf->seccomp.seccomp_ctx, ctx.contexts[0]); ++ if (ret < 0) { ++ ERROR("%s - Failed to merge first compat seccomp " ++ "context into main context", strerror(-ret)); ++ goto bad; ++ } ++ ++ TRACE("Merged first compat seccomp context into main context"); ++ } else { ++ seccomp_release(ctx.contexts[0]); ++ ctx.contexts[0] = NULL; ++ } ++ } ++ ++ if (ctx.contexts[1]) { ++ if (ctx.needs_merge[1]) { ++ ret = seccomp_merge(conf->seccomp.seccomp_ctx, ctx.contexts[1]); ++ if (ret < 0) { ++ ERROR("%s - Failed to merge second compat seccomp " ++ "context into main context", strerror(-ret)); ++ goto bad; ++ } ++ ++ TRACE("Merged second compat seccomp context into main context"); ++ } else { ++ seccomp_release(ctx.contexts[1]); ++ ctx.contexts[1] = NULL; ++ } ++ } ++ ++ if (ctx.contexts[2]) { ++ if (ctx.needs_merge[2]) { ++ ret = seccomp_merge(conf->seccomp.seccomp_ctx, ctx.contexts[2]); ++ if (ret < 0) { ++ ERROR("%s - Failed to merge third compat seccomp " ++ "context into main context", strerror(-ret)); ++ goto bad; ++ } ++ ++ TRACE("Merged third compat seccomp context into main context"); ++ } else { ++ seccomp_release(ctx.contexts[2]); ++ ctx.contexts[2] = NULL; ++ } ++ } ++ ++ free(line); ++ return 0; ++ ++bad_arch: ++ ERROR("Unsupported architecture \"%s\"", line); ++ ++bad_rule: ++bad: ++ if (ctx.contexts[0]) ++ seccomp_release(ctx.contexts[0]); ++ ++ if (ctx.contexts[1]) ++ seccomp_release(ctx.contexts[1]); ++ ++ if (ctx.contexts[2]) ++ seccomp_release(ctx.contexts[2]); ++ ++ free(line); ++ ++ return -1; ++} ++#else + static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_conf *conf) + { + int ret; +@@ -1067,6 +1612,7 @@ bad: + + return -1; + } ++#endif + #else /* HAVE_DECL_SECCOMP_SYSCALL_RESOLVE_NAME_ARCH */ + static int parse_config_v2(FILE *f, char *line, struct lxc_conf *conf) + { +-- +1.8.3.1 + diff --git a/0035-lxc-fixup-builds-with-newer-glibc.patch b/0035-lxc-fixup-builds-with-newer-glibc.patch deleted file mode 100644 index 37be0c3e573848e33babfbe3453de3f9696141ef..0000000000000000000000000000000000000000 --- a/0035-lxc-fixup-builds-with-newer-glibc.patch +++ /dev/null @@ -1,25 +0,0 @@ -From cf85b9009e0085ec861d9294e6e04f1baa2ba28d Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Wed, 16 Jan 2019 20:53:25 +0800 -Subject: [PATCH 035/140] lxc: fixup builds with newer glibc - -Signed-off-by: LiFeng ---- - src/lxc/utils.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index 120a13d..c8fb993 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -44,6 +44,7 @@ - #include - #include - #include -+#include - #include - #include - --- -1.8.3.1 - diff --git a/0036-Security-coding-modification.patch b/0036-Security-coding-modification.patch new file mode 100644 index 0000000000000000000000000000000000000000..015c05013786cc21f30581e470baff86f5376cfe --- /dev/null +++ b/0036-Security-coding-modification.patch @@ -0,0 +1,99 @@ +From ff35c1cd6118668e13f7ca83d7d704bb9363155a Mon Sep 17 00:00:00 2001 +From: wujing +Date: Wed, 15 Apr 2020 07:19:03 -0400 +Subject: [PATCH 36/49] Security coding modification + +Signed-off-by: wujing +--- + src/lxc/commands_utils.c | 2 +- + src/lxc/confile.c | 22 ++++++++++++++++++++++ + src/lxc/lxccontainer.c | 8 ++++++++ + 3 files changed, 31 insertions(+), 1 deletion(-) + +diff --git a/src/lxc/commands_utils.c b/src/lxc/commands_utils.c +index 2f2670d..c5fc094 100644 +--- a/src/lxc/commands_utils.c ++++ b/src/lxc/commands_utils.c +@@ -114,7 +114,7 @@ int lxc_make_abstract_socket_name(char *path, size_t pathlen, + } + + ret = snprintf(offset, len, "%s/%s/%s", lxcpath, name, suffix); +- if (ret < 0) ++ if (ret < 0 || (size_t)ret >= len) + return log_error_errno(-1, errno, "Failed to create abstract socket name"); + + /* +diff --git a/src/lxc/confile.c b/src/lxc/confile.c +index f00afe9..8790494 100644 +--- a/src/lxc/confile.c ++++ b/src/lxc/confile.c +@@ -4288,7 +4288,12 @@ static int get_config_prlimit(const char *key, char *retv, int inlen, + + lxc_list_for_each(it, &c->limits) { + /* 2 colon separated 64 bit integers or the word 'unlimited' */ ++#ifdef HAVE_ISULAD ++#define MAX_LIMIT_BUF_LEN ((INTTYPE_TO_STRLEN(uint64_t) * 2) + 2) ++ char buf[MAX_LIMIT_BUF_LEN] = { 0 }; ++#else + char buf[INTTYPE_TO_STRLEN(uint64_t) * 2 + 2]; ++#endif + int partlen; + struct lxc_limit *lim = it->elem; + +@@ -4296,17 +4301,34 @@ static int get_config_prlimit(const char *key, char *retv, int inlen, + memcpy(buf, "unlimited", STRLITERALLEN("unlimited") + 1); + partlen = STRLITERALLEN("unlimited"); + } else { ++#ifdef HAVE_ISULAD ++ partlen = snprintf(buf, MAX_LIMIT_BUF_LEN, "%" PRIu64, (uint64_t)lim->limit.rlim_cur); ++ if (partlen < 0 || partlen >= MAX_LIMIT_BUF_LEN) { ++ return -1; ++ } ++#else + partlen = sprintf(buf, "%" PRIu64, + (uint64_t)lim->limit.rlim_cur); ++#endif + } + + if (lim->limit.rlim_cur != lim->limit.rlim_max) { + if (lim->limit.rlim_max == RLIM_INFINITY) + memcpy(buf + partlen, ":unlimited", + STRLITERALLEN(":unlimited") + 1); ++#ifdef HAVE_ISULAD ++ else { ++ int nret = snprintf(buf + partlen, (MAX_LIMIT_BUF_LEN - partlen), ++ ":%" PRIu64, (uint64_t)lim->limit.rlim_max); ++ if (nret < 0 || nret >= (MAX_LIMIT_BUF_LEN - partlen)) { ++ return -1; ++ } ++ } ++#else + else + sprintf(buf + partlen, ":%" PRIu64, + (uint64_t)lim->limit.rlim_max); ++#endif + } + + if (get_all) { +diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c +index f622a63..ab10ac6 100644 +--- a/src/lxc/lxccontainer.c ++++ b/src/lxc/lxccontainer.c +@@ -3243,6 +3243,14 @@ static bool container_destroy(struct lxc_container *c, + if (ret < 0) { + ERROR("Failed to destroy directory \"%s\" for \"%s\"", path, + c->name); ++#ifdef HAVE_ISULAD ++ char msg[BUFSIZ] = { 0 }; ++ ret = snprintf(msg, BUFSIZ, "Failed to destroy directory \"%s\": %s", path, errno ? strerror(errno) : "error"); ++ if (ret < 0 || ret >= BUFSIZ) { ++ ERROR("Sprintf failed"); ++ goto out; ++ } ++#endif + goto out; + } + INFO("Destroyed directory \"%s\" for \"%s\"", path, c->name); +-- +1.8.3.1 + diff --git a/0037-cgfsng-fix-build-error-device_cgroup_rule_parse.patch b/0037-cgfsng-fix-build-error-device_cgroup_rule_parse.patch new file mode 100644 index 0000000000000000000000000000000000000000..77d135051d9133462885372f11f9a0e33bef3023 --- /dev/null +++ b/0037-cgfsng-fix-build-error-device_cgroup_rule_parse.patch @@ -0,0 +1,35 @@ +From 5f8d8bb11c42fbf6bca39438530db88729e50f5e Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Thu, 16 Apr 2020 11:12:28 +0800 +Subject: [PATCH 37/49] cgfsng: fix build error device_cgroup_rule_parse + +Signed-off-by: LiFeng +--- + src/lxc/cgroups/cgfsng.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c +index 1047c08..76576c5 100644 +--- a/src/lxc/cgroups/cgfsng.c ++++ b/src/lxc/cgroups/cgfsng.c +@@ -3043,8 +3043,7 @@ static int device_cgroup_parse_access(struct device_item *device, const char *va + return 0; + } + +-#ifndef HAVE_ISULAD +-static int device_cgroup_rule_parse(struct device_item *device, const char *key, ++int device_cgroup_rule_parse(struct device_item *device, const char *key, + const char *val) + { + int count, ret; +@@ -3130,7 +3129,6 @@ static int device_cgroup_rule_parse(struct device_item *device, const char *key, + + return device_cgroup_parse_access(device, ++val); + } +-#endif + + #ifdef HAVE_ISULAD + __cgfsng_ops static int cgfsng_set(struct cgroup_ops *ops, +-- +1.8.3.1 + diff --git a/0063-lxc-ignore-systemcall-load-failure-error.patch b/0038-Ignore-errors-when-loading-rules-fail.patch similarity index 36% rename from 0063-lxc-ignore-systemcall-load-failure-error.patch rename to 0038-Ignore-errors-when-loading-rules-fail.patch index 368a6907cee00dcfe6c79ec5be1ddd17117fc224..c62a471654714244a12f1d974eed930601abcadd 100644 --- a/0063-lxc-ignore-systemcall-load-failure-error.patch +++ b/0038-Ignore-errors-when-loading-rules-fail.patch @@ -1,24 +1,28 @@ -From 5fb35ffb15082021cfaae7b17d31175a63701514 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Sat, 9 Mar 2019 03:10:06 +0800 -Subject: [PATCH 063/140] lxc: ignore systemcall load failure error +From 06a4fd31155821e4425a94ed0ff0d2353d5d940d Mon Sep 17 00:00:00 2001 +From: wujing +Date: Wed, 15 Apr 2020 23:28:36 -0400 +Subject: [PATCH 38/49] Ignore errors when loading rules fail Signed-off-by: wujing -Signed-off-by: LiFeng --- - src/lxc/seccomp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + src/lxc/seccomp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lxc/seccomp.c b/src/lxc/seccomp.c -index 4a5b3d0..26eac90 100644 +index a75adb7..b7c4de3 100644 --- a/src/lxc/seccomp.c +++ b/src/lxc/seccomp.c -@@ -543,7 +543,7 @@ bool do_resolve_add_rule(uint32_t arch, char *line, scmp_filter_ctx ctx, - errno = -ret; +@@ -586,11 +586,12 @@ bool do_resolve_add_rule(uint32_t arch, char *line, scmp_filter_ctx ctx, + #ifdef HAVE_ISULAD + DEBUG("Failed loading rule for %s (nr %d action %d (%s))", + line, nr, rule->action, get_action_name(rule->action)); ++ return true; + #else SYSERROR("Failed loading rule for %s (nr %d action %d (%s))", line, nr, rule->action, get_action_name(rule->action)); -- return false; -+ return true; +-#endif + return false; ++#endif } return true; diff --git a/0038-make-the-given-terminal-as-controlling-terminal.patch b/0038-make-the-given-terminal-as-controlling-terminal.patch deleted file mode 100644 index 59278b79ba2f71134ba9c9defb94050dc5a81915..0000000000000000000000000000000000000000 --- a/0038-make-the-given-terminal-as-controlling-terminal.patch +++ /dev/null @@ -1,46 +0,0 @@ -From a1f81f063eb08dbf3ca99d298fef016b89d7d0d1 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Tue, 15 Jan 2019 23:24:21 -0500 -Subject: [PATCH 038/140] make the given terminal as controlling terminal - -Avoid warning when start cmd /bin/sh : -sh: cannot set terminal process group (-1): Inappropriate ioctl for device -sh: no job control in this shell - -Signed-off-by: LiFeng ---- - src/lxc/start.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/src/lxc/start.c b/src/lxc/start.c -index 708ab7f..ec61b32 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -1330,7 +1330,15 @@ static int do_start(void *data) - * setup on its console ie. the pty allocated in lxc_terminal_setup() so - * make sure that that pty is stdin,stdout,stderr. - */ -+ setsid(); - if (handler->conf->console.slave >= 0) { -+ /* isulad:make the given terminal as controlling terminal to avoid warning -+ * sh: cannot set terminal process group (-1): Inappropriate ioctl for device -+ * sh: no job control in this shell */ -+ if (ioctl(handler->conf->console.slave, TIOCSCTTY, NULL) < 0) { -+ ERROR("Faild to make the given terminal the controlling terminal of the calling process"); -+ goto out_warn_father; -+ } - if (handler->daemonize || !handler->conf->is_execute) - ret = set_stdfds(handler->conf->console.slave); - else -@@ -1377,8 +1385,6 @@ static int do_start(void *data) - devnull_fd = -1; - } - -- setsid(); -- - if (handler->conf->init_cwd) { - /* isulad: try to craete workdir if not exist */ - struct stat st; --- -1.8.3.1 - diff --git a/0039-net-adapt-to-isulad.patch b/0039-net-adapt-to-isulad.patch new file mode 100644 index 0000000000000000000000000000000000000000..5ffe39d94c761a7431f1e3d5fc282dde655e289b --- /dev/null +++ b/0039-net-adapt-to-isulad.patch @@ -0,0 +1,51 @@ +From c474b4e528e591680c6f9cbbcb27bdfe4e5f94f9 Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Thu, 16 Apr 2020 12:01:39 +0800 +Subject: [PATCH 39/49] net: adapt to isulad + +Signed-off-by: LiFeng +--- + src/lxc/commands_utils.c | 2 +- + src/lxc/network.c | 10 +++++++++- + 2 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/src/lxc/commands_utils.c b/src/lxc/commands_utils.c +index c5fc094..2f2670d 100644 +--- a/src/lxc/commands_utils.c ++++ b/src/lxc/commands_utils.c +@@ -114,7 +114,7 @@ int lxc_make_abstract_socket_name(char *path, size_t pathlen, + } + + ret = snprintf(offset, len, "%s/%s/%s", lxcpath, name, suffix); +- if (ret < 0 || (size_t)ret >= len) ++ if (ret < 0) + return log_error_errno(-1, errno, "Failed to create abstract socket name"); + + /* +diff --git a/src/lxc/network.c b/src/lxc/network.c +index b442ed5..19adb23 100644 +--- a/src/lxc/network.c ++++ b/src/lxc/network.c +@@ -3448,10 +3448,18 @@ static int lxc_network_setup_in_child_namespaces_common(struct lxc_netdev *netde + + /* set the network device up */ + if (netdev->flags & IFF_UP) { ++ ++#ifdef HAVE_ISULAD ++ if (netdev->name[0] != '\0') { ++ err = lxc_netdev_up(netdev->name); ++ if (err) ++ return log_error_errno(-1, -err, "Failed to set network device \"%s\" up", netdev->name); ++ } ++#else + err = lxc_netdev_up(netdev->name); + if (err) + return log_error_errno(-1, -err, "Failed to set network device \"%s\" up", netdev->name); +- ++#endif + /* the network is up, make the loopback up too */ + err = lxc_netdev_up("lo"); + if (err) +-- +1.8.3.1 + diff --git a/0039-print-error-message-when-container-start-failed.patch b/0039-print-error-message-when-container-start-failed.patch deleted file mode 100644 index c631c14ae154d1137a684e3b56cbc9f3391f6b38..0000000000000000000000000000000000000000 --- a/0039-print-error-message-when-container-start-failed.patch +++ /dev/null @@ -1,816 +0,0 @@ -From 24f908199916fc92cb7935bfccc19244d3a8d864 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Wed, 16 Jan 2019 14:38:38 +0800 -Subject: [PATCH 039/140] print error message when container start failed - -Signed-off-by: tanyifeng -Signed-off-by: LiFeng ---- - src/lxc/attach.c | 6 +-- - src/lxc/cgroups/cgfsng.c | 22 +++++++-- - src/lxc/cgroups/cgroup.c | 4 +- - src/lxc/cgroups/cgroup.h | 2 + - src/lxc/conf.c | 122 ++++++++++++++++++++++++++-------------------- - src/lxc/conf.h | 5 +- - src/lxc/execute.c | 3 +- - src/lxc/lxccontainer.c | 37 ++++++++++++-- - src/lxc/start.c | 14 ++++-- - src/lxc/start.h | 2 +- - src/lxc/tools/lxc_start.c | 3 ++ - 11 files changed, 147 insertions(+), 73 deletions(-) - -diff --git a/src/lxc/attach.c b/src/lxc/attach.c -index 4ccdd74..b44ea74 100644 ---- a/src/lxc/attach.c -+++ b/src/lxc/attach.c -@@ -1396,7 +1396,7 @@ int lxc_attach(const char *name, const char *lxcpath, - - /* Setup resource limits */ - if (!lxc_list_empty(&conf->limits)) { -- ret = setup_resource_limits(&conf->limits, pid); -+ ret = setup_resource_limits(&conf->limits, pid, -1); - if (ret < 0) - goto on_error; - } -@@ -1650,8 +1650,8 @@ int lxc_attach_run_command(void *payload, int msg_fd) - } - } - -- /* isulad: write errorm messages */ -- lxc_write_error_message(msg_fd, "exec: \"%s\": %s", cmd->program, strerror(errno)); -+ /* isulad: write error messages */ -+ lxc_write_error_message(msg_fd, "exec: \"%s\": %s.", cmd->program, strerror(errno)); - - SYSERROR("Failed to exec \"%s\"", cmd->program); - return ret; -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index bc1481d..47b12a6 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -1236,7 +1236,7 @@ static int mkdir_eexist_on_last(const char *dir, mode_t mode) - return 0; - } - --static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname) -+static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname, int errfd) - { - int ret; - -@@ -1244,8 +1244,8 @@ static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname) - - if (file_exists(h->container_full_path)) { // it must not already exist - ERROR("Cgroup path \"%s\" already exist.", h->container_full_path); -- //lxc_write_error_message(errfd, "%s:%d: Cgroup path \"%s\" already exist.", -- // __FILE__, __LINE__, h->fullcgpath); -+ lxc_write_error_message(errfd, "%s:%d: Cgroup path \"%s\" already exist.", -+ __FILE__, __LINE__, h->container_full_path); - return false; - } - -@@ -1288,7 +1288,7 @@ __cgfsng_ops static bool cgfsng_payload_create(struct cgroup_ops *ops, - } - - for (i = 0; ops->hierarchies[i]; i++) { -- if (!create_path_for_hierarchy(ops->hierarchies[i], container_cgroup)) { -+ if (!create_path_for_hierarchy(ops->hierarchies[i], container_cgroup, ops->errfd)) { - SYSERROR("Failed to create %s", ops->hierarchies[i]->container_full_path); - return false; - } -@@ -2203,6 +2203,11 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, - - fullpath = must_make_path(h->container_full_path, filename, NULL); - ret = lxc_write_to_file(fullpath, value, strlen(value), false, 0666); -+ if (ret) { -+ lxc_write_error_message(ops->errfd, -+ "%s:%d: setting cgroup config for ready process caused \"failed to write %s to %s: %s\".", -+ __FILE__, __LINE__, value, fullpath, strerror(errno)); -+ } - free(fullpath); - return ret; - } -@@ -2294,9 +2299,15 @@ static bool __cg_legacy_setup_limits(struct cgroup_ops *ops, - } - if (setvalue > readvalue) { - ERROR("The maximum allowed cpu-shares is %s", value); -+ lxc_write_error_message(ops->errfd, -+ "%s:%d: setting cgroup config for ready process caused \"The maximum allowed cpu-shares is %s\".", -+ __FILE__, __LINE__, value); - goto out; - } else if (setvalue < readvalue) { - ERROR("The minimum allowed cpu-shares is %s", value); -+ lxc_write_error_message(ops->errfd, -+ "%s:%d: setting cgroup config for ready process caused \"The minimum allowed cpu-shares is %s\".", -+ __FILE__, __LINE__, value); - goto out; - } - } -@@ -2699,7 +2710,7 @@ __cgfsng_ops static bool cgfsng_data_init(struct cgroup_ops *ops, struct lxc_han - return true; - } - --struct cgroup_ops *cgfsng_ops_init(void) -+struct cgroup_ops *cgfsng_ops_init(int errfd) - { - struct cgroup_ops *cgfsng_ops; - -@@ -2715,6 +2726,7 @@ struct cgroup_ops *cgfsng_ops_init(void) - return NULL; - } - -+ cgfsng_ops->errfd = errfd; - cgfsng_ops->data_init = cgfsng_data_init; - cgfsng_ops->destroy = cgfsng_payload_destroy; - cgfsng_ops->payload_create = cgfsng_payload_create; -diff --git a/src/lxc/cgroups/cgroup.c b/src/lxc/cgroups/cgroup.c -index 8e7aef9..7442c31 100644 ---- a/src/lxc/cgroups/cgroup.c -+++ b/src/lxc/cgroups/cgroup.c -@@ -38,13 +38,13 @@ - - lxc_log_define(cgroup, lxc); - --extern struct cgroup_ops *cgfsng_ops_init(void); -+extern struct cgroup_ops *cgfsng_ops_init(int errfd); - - struct cgroup_ops *cgroup_init(struct lxc_handler *handler) - { - struct cgroup_ops *cgroup_ops; - -- cgroup_ops = cgfsng_ops_init(); -+ cgroup_ops = cgfsng_ops_init(handler->conf->errpipe[1]); - if (!cgroup_ops) { - ERROR("Failed to initialize cgroup driver"); - return NULL; -diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h -index fa4871e..b6116f6 100644 ---- a/src/lxc/cgroups/cgroup.h -+++ b/src/lxc/cgroups/cgroup.h -@@ -92,6 +92,8 @@ struct cgroup_ops { - char **cgroup_use; - char *cgroup_pattern; - char *container_cgroup; -+ /* isulad: errfd */ -+ int errfd; - - /* @hierarchies - * - A NULL-terminated array of struct hierarchy, one per legacy -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 88cebfd..8fa63f7 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -2414,6 +2414,8 @@ static int mount_entry_create_dir_file(const struct mntent *mntent, - ret = mkdir_p(path, 0755); - if (ret < 0 && errno != EEXIST) { - SYSERROR("Failed to create directory \"%s\"", path); -+ lxc_write_error_message(rootfs->errfd, "%s:%d: mkdir %s: %s.", -+ __FILE__, __LINE__, path, strerror(errno)); - return -1; - } - } -@@ -2435,12 +2437,17 @@ static int mount_entry_create_dir_file(const struct mntent *mntent, - free(p1); - if (ret < 0 && errno != EEXIST) { - SYSERROR("Failed to create directory \"%s\"", path); -+ lxc_write_error_message(rootfs->errfd, "%s:%d: mkdir %s: %s.", -+ __FILE__, __LINE__, p2, strerror(errno)); - return -1; - } - - ret = mknod(path, S_IFREG | 0000, 0); -- if (ret < 0 && errno != EEXIST) -+ if (ret < 0 && errno != EEXIST) { -+ lxc_write_error_message(rootfs->errfd, "%s:%d: open %s: %s.", -+ __FILE__, __LINE__, path, strerror(errno)); - return -errno; -+ } - - return 0; - } -@@ -2550,7 +2557,9 @@ static inline int mount_entry_on_generic(struct mntent *mntent, - if (rootfs_path) { - rpath = follow_symlink_in_scope(path, rootfs_path); - if (!rpath) { -- ERROR("Failed to get real path for '%s'", path); -+ ERROR("Failed to get real path of '%s' in scope '%s'.", path, rootfs_path); -+ lxc_write_error_message(rootfs->errfd, "%s:%d: failed to get real path of '%s' in scope '%s'.", -+ __FILE__, __LINE__, path, rootfs_path); - return -1; - } - dest = rpath; -@@ -2558,6 +2567,8 @@ static inline int mount_entry_on_generic(struct mntent *mntent, - ret = check_mount_destination(rootfs_path, dest); - if (ret) { - ERROR("Mount destination is invalid: '%s'", dest); -+ lxc_write_error_message(rootfs->errfd, "%s:%d: mount destination is invalid: '%s'.", -+ __FILE__, __LINE__, dest); - free(rpath); - return -1; - } -@@ -2587,6 +2598,10 @@ static inline int mount_entry_on_generic(struct mntent *mntent, - ret = mount_entry(mntent->mnt_fsname, dest, mntent->mnt_type, mntflags, - pflags, mntdata, optional, dev, relative, rootfs_path); - } -+ if (ret < 0) { -+ lxc_write_error_message(rootfs->errfd, "%s:%d: failed to mount %s as type %s.", -+ __FILE__, __LINE__, mntent->mnt_fsname, mntent->mnt_type); -+ } - - free(mntdata); - free(rpath); -@@ -2949,7 +2964,7 @@ static int parse_resource(const char *res) - return resid; - } - --int setup_resource_limits(struct lxc_list *limits, pid_t pid) -+int setup_resource_limits(struct lxc_list *limits, pid_t pid, int errfd) - { - int resid; - struct lxc_list *it; -@@ -2966,7 +2981,10 @@ int setup_resource_limits(struct lxc_list *limits, pid_t pid) - - #if HAVE_PRLIMIT || HAVE_PRLIMIT64 - if (prlimit(pid, resid, &lim->limit, NULL) != 0) { -- SYSERROR("Failed to set limit %s", lim->resource); -+ SYSERROR("Failed to set limit %s %lu %lu.", lim->resource, lim->limit.rlim_cur, lim->limit.rlim_max); -+ lxc_write_error_message(errfd, "%s:%d: Failed to set limit %s %lu %lu: %s.", -+ __FILE__, __LINE__, lim->resource, -+ lim->limit.rlim_cur, lim->limit.rlim_max, strerror(errno)); - return -1; - } - -@@ -3989,6 +4007,8 @@ int lxc_setup(struct lxc_handler *handler) - ret = lxc_setup_rootfs_prepare_root(lxc_conf, name, lxcpath); - if (ret < 0) { - ERROR("Failed to setup rootfs"); -+ lxc_write_error_message(lxc_conf->errpipe[1], "%s:%d: failed to setup rootfs %s.", -+ __FILE__, __LINE__, lxc_conf->rootfs.path); - return -1; - } - -@@ -3996,31 +4016,31 @@ int lxc_setup(struct lxc_handler *handler) - ret = setup_utsname(lxc_conf->utsname); - if (ret < 0) { - ERROR("Failed to setup the utsname %s", name); -- return -1; -+ goto on_error; - } - } - - ret = lxc_setup_keyring(); - if (ret < 0) -- return -1; -+ goto on_error; - - ret = lxc_setup_network_in_child_namespaces(lxc_conf, &lxc_conf->network); - if (ret < 0) { - ERROR("Failed to setup network"); -- return -1; -+ goto on_error; - } - - ret = lxc_network_send_name_and_ifindex_to_parent(handler); - if (ret < 0) { - ERROR("Failed to send network device names and ifindices to parent"); -- return -1; -+ goto on_error; - } - - if (lxc_conf->autodev > 0) { - ret = mount_autodev(name, &lxc_conf->rootfs, lxcpath); - if (ret < 0) { - ERROR("Failed to mount \"/dev\""); -- return -1; -+ goto on_error; - } - } - -@@ -4030,13 +4050,14 @@ int lxc_setup(struct lxc_handler *handler) - ret = lxc_mount_auto_mounts(lxc_conf, lxc_conf->auto_mounts & ~LXC_AUTO_CGROUP_MASK, handler); - if (ret < 0) { - ERROR("Failed to setup first automatic mounts"); -- return -1; -+ goto on_error; - } - -+ lxc_conf->rootfs.errfd = lxc_conf->errpipe[1]; - ret = setup_mount(lxc_conf, &lxc_conf->rootfs, lxc_conf->fstab, name, lxcpath); - if (ret < 0) { - ERROR("Failed to setup mounts"); -- return -1; -+ goto on_error; - } - - if (lxc_conf->is_execute) { -@@ -4047,13 +4068,13 @@ int lxc_setup(struct lxc_handler *handler) - ret = snprintf(path, PATH_MAX, SBINDIR "/init.lxc.static"); - if (ret < 0 || ret >= PATH_MAX) { - ERROR("Path to init.lxc.static too long"); -- return -1; -+ goto on_error; - } - - fd = open(path, O_PATH | O_CLOEXEC); - if (fd < 0) { - SYSERROR("Unable to open lxc.init.static"); -- return -1; -+ goto on_error; - } - - ((struct execute_args *)handler->data)->init_fd = fd; -@@ -4062,7 +4083,7 @@ int lxc_setup(struct lxc_handler *handler) - ret = lxc_execute_bind_init(handler); - if (ret < 0) { - ERROR("Failed to bind-mount the lxc init system"); -- return -1; -+ goto on_error; - } - } - } -@@ -4074,7 +4095,7 @@ int lxc_setup(struct lxc_handler *handler) - ret = lxc_mount_auto_mounts(lxc_conf, lxc_conf->auto_mounts & LXC_AUTO_CGROUP_MASK, handler); - if (ret < 0) { - ERROR("Failed to setup remaining automatic mounts"); -- return -1; -+ goto on_error; - } - - /*isulad: move mount entries here, before we do lxc_fill_autodev and populate devices */ -@@ -4083,27 +4104,27 @@ int lxc_setup(struct lxc_handler *handler) - &lxc_conf->mount_list, name, lxcpath); - if (ret < 0) { - ERROR("Failed to setup mount entries"); -- return -1; -+ goto on_error; - } - } - - ret = run_lxc_hooks(name, "mount", lxc_conf, NULL); - if (ret < 0) { - ERROR("Failed to run mount hooks"); -- return -1; -+ goto on_error; - } - - if (lxc_conf->autodev > 0) { - ret = run_lxc_hooks(name, "autodev", lxc_conf, NULL); - if (ret < 0) { - ERROR("Failed to run autodev hooks"); -- return -1; -+ goto on_error; - } - - ret = lxc_fill_autodev(&lxc_conf->rootfs); - if (ret < 0) { - ERROR("Failed to populate \"/dev\""); -- return -1; -+ goto on_error; - } - } - -@@ -4111,64 +4132,64 @@ int lxc_setup(struct lxc_handler *handler) - if (!lxc_list_empty(&lxc_conf->populate_devs)) { - if (setup_populate_devs(&lxc_conf->rootfs, &lxc_conf->populate_devs)) { - ERROR("Failed to setup devices in the container"); -- return -1;; -+ goto on_error; - } - } - - /* Make sure any start hooks are in the container */ - if (!verify_start_hooks(lxc_conf)) { - ERROR("Failed to verify start hooks"); -- return -1; -+ goto on_error; - } - - ret = lxc_setup_console(&lxc_conf->rootfs, &lxc_conf->console, - lxc_conf->ttys.dir); - if (ret < 0) { - ERROR("Failed to setup console"); -- return -1; -+ goto on_error; - } - - ret = lxc_setup_dev_symlinks(&lxc_conf->rootfs); - if (ret < 0) { - ERROR("Failed to setup \"/dev\" symlinks"); -- return -1; -+ goto on_error; - } - - ret = lxc_create_tmp_proc_mount(lxc_conf); - if (ret < 0) { - ERROR("Failed to \"/proc\" LSMs"); -- return -1; -+ goto on_error; - } - - ret = lxc_setup_rootfs_switch_root(&lxc_conf->rootfs); - if (ret < 0) { - ERROR("Failed to pivot root into rootfs"); -- return -1; -+ goto on_error; - } - - /* isulad: remount rootfs readonly if necessary */ - if (setup_rootfs_mountopts(&lxc_conf->rootfs)) { - ERROR("failed to set rootfs for '%s'", name); -- return -1; -+ goto on_error; - } - - if (lxc_conf->rootfs.path) { - ret = lxc_setup_devpts(lxc_conf); - if (ret < 0) { - ERROR("Failed to setup new devpts instance"); -- return -1; -+ goto on_error; - } - } - - ret = lxc_create_ttys(handler); - if (ret < 0) -- return -1; -+ goto on_error; - - //isulad: setup rootfs masked paths - if (!lxc_list_empty(&lxc_conf->rootfs.maskedpaths)) { - if (setup_rootfs_maskedpaths(&lxc_conf->rootfs.maskedpaths)) { - ERROR("failed to setup maskedpaths"); -- return -1; -+ goto on_error; - } - } - -@@ -4176,7 +4197,7 @@ int lxc_setup(struct lxc_handler *handler) - if (!lxc_list_empty(&lxc_conf->rootfs.ropaths)) { - if (setup_rootfs_ropaths(&lxc_conf->rootfs.ropaths)) { - ERROR("failed to setup readonlypaths"); -- return -1; -+ goto on_error; - } - } - -@@ -4186,7 +4207,7 @@ int lxc_setup(struct lxc_handler *handler) - ret = setup_personality(lxc_conf->personality); - if (ret < 0) { - ERROR("Failed to set personality"); -- return -1; -+ goto on_error; - } - - /* Set sysctl value to a path under /proc/sys as determined from the -@@ -4197,7 +4218,7 @@ int lxc_setup(struct lxc_handler *handler) - ret = setup_sysctl_parameters(&lxc_conf->sysctls); - if (ret < 0) { - ERROR("Failed to setup sysctl parameters"); -- return -1; -+ goto on_error; - } - } - -@@ -4206,21 +4227,24 @@ int lxc_setup(struct lxc_handler *handler) - ERROR("Container requests lxc.cap.drop and " - "lxc.cap.keep: either use lxc.cap.drop or " - "lxc.cap.keep, not both"); -- return -1; -+ goto on_error; - } - - if (dropcaps_except(&lxc_conf->keepcaps)) { - ERROR("Failed to keep capabilities"); -- return -1; -+ goto on_error; - } - } else if (setup_caps(&lxc_conf->caps)) { - ERROR("Failed to drop capabilities"); -- return -1; -+ goto on_error; - } - - NOTICE("The container \"%s\" is set up", name); - - return 0; -+on_error: -+ lxc_write_error_message(lxc_conf->errpipe[1], "Failed to setup lxc, please check the config file."); -+ return -1; - } - - /* isulad drop caps for container*/ -@@ -4555,11 +4579,9 @@ void* wait_ocihook_timeout(void *arg) - __FILE__, __LINE__, lxchook_names[conf->which], - (double)conf->timeout); - -- if (conf->errfd >= 0) { -- 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); -- } -+ 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); - - if (kill(conf->pid, SIGKILL) && errno != ESRCH) { - ERROR("Send kill signal failed"); -@@ -4640,22 +4662,18 @@ static int run_ocihook_buffer(struct oci_hook_conf *oconf, char *inmsg) - goto print_hook; - } else if (WIFEXITED(ret) && WEXITSTATUS(ret) != 0) { - ERROR("Script exited with status %d. output:%s", WEXITSTATUS(ret), output); -- if (conf->errfd >= 0) { -- lxc_write_error_message(conf->errfd, "%s:%d: running %s hook caused \"error running hook: exit status %d, output:%s\"", -- __FILE__, __LINE__, -- (conf->which >= NUM_LXC_HOOKS) ? "invalid type" : lxchook_names[conf->which], -- WEXITSTATUS(ret), output); -- } -+ lxc_write_error_message(conf->errfd, "%s:%d: running %s hook caused \"error running hook: exit status %d, output:%s\".", -+ __FILE__, __LINE__, -+ (conf->which >= NUM_LXC_HOOKS) ? "invalid type" : lxchook_names[conf->which], -+ WEXITSTATUS(ret), output); - - goto print_hook; - } else if (WIFSIGNALED(ret)) { - ERROR("Script terminated by signal %d.", WTERMSIG(ret)); -- if (conf->errfd >= 0) { -- lxc_write_error_message(conf->errfd, "%s:%d: running %s hook caused \"error running hook: Script terminated by signal %d\"", -- __FILE__, __LINE__, -- (conf->which >= NUM_LXC_HOOKS) ? "invalid type" : lxchook_names[conf->which], -- WTERMSIG(ret)); -- } -+ lxc_write_error_message(conf->errfd, "%s:%d: running %s hook caused \"error running hook: Script terminated by signal %d\".", -+ __FILE__, __LINE__, -+ (conf->which >= NUM_LXC_HOOKS) ? "invalid type" : lxchook_names[conf->which], -+ WTERMSIG(ret)); - - goto print_hook; - } -diff --git a/src/lxc/conf.h b/src/lxc/conf.h -index b92c48e..88f5b41 100644 ---- a/src/lxc/conf.h -+++ b/src/lxc/conf.h -@@ -175,6 +175,8 @@ struct lxc_rootfs { - struct lxc_list maskedpaths; - /* isulad: ropaths */ - struct lxc_list ropaths; -+ /* isulad: errfd */ -+ int errfd; - }; - - /* -@@ -462,7 +464,7 @@ extern int lxc_setup_rootfs_prepare_root(struct lxc_conf *conf, - const char *name, const char *lxcpath); - extern int lxc_setup(struct lxc_handler *handler); - extern int lxc_setup_parent(struct lxc_handler *handler); --extern int setup_resource_limits(struct lxc_list *limits, pid_t pid); -+extern int setup_resource_limits(struct lxc_list *limits, pid_t pid, int errfd); - extern int find_unmapped_nsid(struct lxc_conf *conf, enum idtype idtype); - extern int mapped_hostid(unsigned id, struct lxc_conf *conf, - enum idtype idtype); -@@ -499,6 +501,7 @@ 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 lxc_drop_caps(struct lxc_conf *conf); -+void lxc_close_error_pipe(int *errpipe); - - /* isulad add end */ - -diff --git a/src/lxc/execute.c b/src/lxc/execute.c -index d388e63..3fc46c6 100644 ---- a/src/lxc/execute.c -+++ b/src/lxc/execute.c -@@ -40,7 +40,7 @@ - - lxc_log_define(execute, start); - --static int execute_start(struct lxc_handler *handler, void* data) -+static int execute_start(struct lxc_handler *handler, void* data, int fd) - { - int argc_add, j; - char **argv; -@@ -91,6 +91,7 @@ static int execute_start(struct lxc_handler *handler, void* data) - else - execvp(argv[0], argv); - SYSERROR("Failed to exec %s", argv[0]); -+ lxc_write_error_message(fd, "Failed to exec: \"%s\": %s.", argv[0], strerror(errno)); - - free(argv); - out1: -diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index e99c41c..d641851 100644 ---- a/src/lxc/lxccontainer.c -+++ b/src/lxc/lxccontainer.c -@@ -916,7 +916,9 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a - NULL, - }; - char **init_cmd = NULL; -- int keepfds[4] = {-1, -1, -1, -1}; -+ int keepfds[] = {-1, -1, -1, -1, -1}; -+ ssize_t size_read; -+ char errbuf[BUFSIZ + 1] = {0}; - - /* container does exist */ - if (!c) -@@ -962,7 +964,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a - argv = init_cmd = split_init_cmd(conf->init_cmd); - } - -- /* isulad: use init argv as init cmd */ -+ /* isulad: use init argv as init cmd */ - if (!argv) { - argv = init_cmd = use_init_args(conf->init_argv, conf->init_argc); - } -@@ -986,10 +988,19 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a - char title[2048]; - pid_t pid; - -+ //isulad: pipdfd for get error message of child or grandchild process. -+ if (pipe2(conf->errpipe, O_CLOEXEC) != 0) { -+ SYSERROR("Failed to init errpipe"); -+ free_init_cmd(init_cmd); -+ lxc_free_handler(handler); -+ return false; -+ } -+ - pid = fork(); - if (pid < 0) { - free_init_cmd(init_cmd); - lxc_free_handler(handler); -+ lxc_close_error_pipe(conf->errpipe); - return false; - } - -@@ -999,11 +1010,23 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a - * the PID file, child will do the free and unlink. - */ - c->pidfile = NULL; -+ close(conf->errpipe[1]); -+ conf->errpipe[1] = -1; - - /* Wait for container to tell us whether it started - * successfully. - */ - started = wait_on_daemonized_start(handler, pid); -+ if (!started) { -+ size_read = read(conf->errpipe[0], errbuf, BUFSIZ); -+ if (size_read > 0) { -+ conf->errmsg = strdup(errbuf); -+ if (!conf->errmsg) -+ ERROR("Out of memory"); -+ } -+ } -+ close(conf->errpipe[0]); -+ conf->errpipe[0] = -1; - - free_init_cmd(init_cmd); - lxc_free_handler(handler); -@@ -1039,6 +1062,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a - if (pid != 0) { - free_init_cmd(init_cmd); - lxc_free_handler(handler); -+ lxc_close_error_pipe(conf->errpipe); - _exit(EXIT_SUCCESS); - } - -@@ -1050,10 +1074,12 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a - SYSERROR("Failed to change to \"/\" directory"); - _exit(EXIT_FAILURE); - } -- -+ close(conf->errpipe[0]); -+ conf->errpipe[0] = -1; - keepfds[0] = handler->conf->maincmd_fd; - keepfds[1] = handler->state_socket_pair[0]; - keepfds[2] = handler->state_socket_pair[1]; -+ keepfds[4] = conf->errpipe[1]; - ret = lxc_check_inherited(conf, true, keepfds, - sizeof(keepfds) / sizeof(keepfds[0])); - if (ret < 0) -@@ -1088,6 +1114,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a - if (w < 0 || (size_t)w >= sizeof(pidstr)) { - free_init_cmd(init_cmd); - lxc_free_handler(handler); -+ lxc_close_error_pipe(conf->errpipe); - - SYSERROR("Failed to write monitor pid to \"%s\"", c->pidfile); - -@@ -1101,6 +1128,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a - if (ret < 0) { - free_init_cmd(init_cmd); - lxc_free_handler(handler); -+ lxc_close_error_pipe(conf->errpipe); - - SYSERROR("Failed to write monitor pid to \"%s\"", c->pidfile); - -@@ -1159,6 +1187,9 @@ reboot: - if (conf->exit_fd >= 0) { - keepfds[3] = conf->exit_fd; - } -+ /* isulad: keep errpipe fd */ -+ if (c->daemonize) -+ keepfds[4] = conf->errpipe[1]; - ret = lxc_check_inherited(conf, c->daemonize, keepfds, - sizeof(keepfds) / sizeof(keepfds[0])); - if (ret < 0) { -diff --git a/src/lxc/start.c b/src/lxc/start.c -index ec61b32..3e6854f 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -892,6 +892,7 @@ int lxc_init(const char *name, struct lxc_handler *handler) - ret = lxc_terminal_setup(conf); - if (ret < 0) { - ERROR("Failed to create console"); -+ lxc_write_error_message(conf->errpipe[1], "Failed to create console for container \"%s\".", name); - goto out_restore_sigmask; - } - TRACE("Created console"); -@@ -1390,6 +1391,8 @@ static int do_start(void *data) - struct stat st; - if (stat(handler->conf->init_cwd, &st) < 0 && mkdir_p(handler->conf->init_cwd, 0755) < 0) { - SYSERROR("Try to create directory \"%s\" as workdir failed", handler->conf->init_cwd); -+ lxc_write_error_message(handler->conf->errpipe[1], "%s:%d: Failed to create workdir: %s.", -+ __FILE__, __LINE__, strerror(errno)); - goto out_warn_father; - } - if (chdir(handler->conf->init_cwd)) { -@@ -1489,7 +1492,7 @@ static int do_start(void *data) - /* After this call, we are in error because this ops should not return - * as it execs. - */ -- handler->ops->start(handler, handler->data); -+ handler->ops->start(handler, handler->data, handler->daemonize ? handler->conf->errpipe[1] : -1); - - out_warn_father: - /* We want the parent to know something went wrong, so we return a -@@ -1898,7 +1901,7 @@ static int lxc_spawn(struct lxc_handler *handler) - goto out_delete_net; - - if (!lxc_list_empty(&conf->limits)) { -- ret = setup_resource_limits(&conf->limits, handler->pid); -+ ret = setup_resource_limits(&conf->limits, handler->pid, conf->errpipe[1]); - if (ret < 0) { - ERROR("Failed to setup resource limits"); - goto out_delete_net; -@@ -1960,7 +1963,7 @@ static int lxc_spawn(struct lxc_handler *handler) - } - - if (START_TIMEOUT == global_timeout_state) { -- //lxc_write_error_message(conf->errpipe[1], "Starting the container \"%s\" timeout.", name); -+ lxc_write_error_message(conf->errpipe[1], "Starting the container \"%s\" timeout.", name); - ERROR("Starting the container \"%s\" timeout.", name); - goto out_delete_net; - } -@@ -2008,7 +2011,7 @@ static int lxc_spawn(struct lxc_handler *handler) - } - - if (START_TIMEOUT == global_timeout_state) { -- //lxc_write_error_message(conf->errpipe[1], "Starting the container \"%s\" timeout.", name); -+ lxc_write_error_message(conf->errpipe[1], "Starting the container \"%s\" timeout.", name); - ERROR("Starting the container \"%s\" timeout.", name); - goto out_abort; - } -@@ -2232,7 +2235,7 @@ struct start_args { - char *const *argv; - }; - --static int start(struct lxc_handler *handler, void* data) -+static int start(struct lxc_handler *handler, void* data, int fd) - { - struct start_args *arg = data; - -@@ -2240,6 +2243,7 @@ static int start(struct lxc_handler *handler, void* data) - - execvp(arg->argv[0], arg->argv); - SYSERROR("Failed to exec \"%s\"", arg->argv[0]); -+ lxc_write_error_message(fd, "exec: \"%s\": %s.", arg->argv[0], strerror(errno)); - return 0; - } - -diff --git a/src/lxc/start.h b/src/lxc/start.h -index 1d84325..ab72e6e 100644 ---- a/src/lxc/start.h -+++ b/src/lxc/start.h -@@ -145,7 +145,7 @@ struct execute_args { - }; - - struct lxc_operations { -- int (*start)(struct lxc_handler *, void *); -+ int (*start)(struct lxc_handler *, void *, int); - int (*post_start)(struct lxc_handler *, void *); - }; - -diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c -index f37f8a6..ec48701 100644 ---- a/src/lxc/tools/lxc_start.c -+++ b/src/lxc/tools/lxc_start.c -@@ -392,6 +392,9 @@ int main(int argc, char *argv[]) - else - err = c->start(c, 0, args) ? EXIT_SUCCESS : EXIT_FAILURE; - if (err) { -+ if (c->lxc_conf->errmsg) -+ fprintf(stderr, "%s:%s:%s:%d starting container process caused \"%s\"", c->name, -+ __FILE__, __func__, __LINE__, c->lxc_conf->errmsg); - ERROR("The container failed to start"); - - if (my_args.daemonize) --- -1.8.3.1 - diff --git a/0040-add-timeout-200ms-for-cmds-send-to-lxc-monitor.patch b/0040-add-timeout-200ms-for-cmds-send-to-lxc-monitor.patch deleted file mode 100644 index 81a925eeb168d1ca5f8cfe518d58b79210f916f3..0000000000000000000000000000000000000000 --- a/0040-add-timeout-200ms-for-cmds-send-to-lxc-monitor.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 04512fa5baae9aeff6ac8f120e718f339b56525f Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Wed, 16 Jan 2019 02:22:13 -0500 -Subject: [PATCH 040/140] add timeout(200ms) for cmds send to [lxc monitor] - -Signed-off-by: LiFeng ---- - src/lxc/af_unix.c | 25 +++++++++++++++++++++++-- - src/lxc/af_unix.h | 2 ++ - src/lxc/commands.c | 7 +++++-- - 3 files changed, 30 insertions(+), 4 deletions(-) - -diff --git a/src/lxc/af_unix.c b/src/lxc/af_unix.c -index 02f32c4..24500a8 100644 ---- a/src/lxc/af_unix.c -+++ b/src/lxc/af_unix.c -@@ -194,8 +194,9 @@ int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds, - return ret; - } - --int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds, -- void *data, size_t size) -+/* isulad: add wait timeout Microseconds*/ -+int lxc_abstract_unix_recv_fds_timeout(int fd, int *recvfds, int num_recvfds, -+ void *data, size_t size, unsigned int timeout) - { - int ret; - struct msghdr msg; -@@ -204,6 +205,7 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds, - char buf[1] = {0}; - char *cmsgbuf; - size_t cmsgbufsize = CMSG_SPACE(num_recvfds * sizeof(int)); -+ struct timeval out; - - memset(&msg, 0, sizeof(msg)); - memset(&iov, 0, sizeof(iov)); -@@ -222,6 +224,19 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds, - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - -+ if (timeout > 0) { -+ memset(&out, 0, sizeof(out)); -+ out.tv_sec = timeout / 1000000; -+ out.tv_usec = timeout % 1000000; -+ ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, -+ (const void *)&out, sizeof(out)); -+ if (ret < 0) { -+ ERROR("Failed to set %u timeout on containter " -+ "state socket", timeout); -+ goto out; -+ } -+ } -+ - ret = recvmsg(fd, &msg, 0); - if (ret <= 0) - goto out; -@@ -238,6 +253,12 @@ out: - return ret; - } - -+int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds, -+ void *data, size_t size) -+{ -+ return lxc_abstract_unix_recv_fds_timeout(fd, recvfds, num_recvfds, data, size, 0); -+} -+ - int lxc_abstract_unix_send_credential(int fd, void *data, size_t size) - { - struct msghdr msg = {0}; -diff --git a/src/lxc/af_unix.h b/src/lxc/af_unix.h -index f2c2fdc..74fd77f 100644 ---- a/src/lxc/af_unix.h -+++ b/src/lxc/af_unix.h -@@ -37,5 +37,7 @@ extern int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds, - void *data, size_t size); - extern int lxc_abstract_unix_send_credential(int fd, void *data, size_t size); - extern int lxc_abstract_unix_rcv_credential(int fd, void *data, size_t size); -+extern int lxc_abstract_unix_recv_fds_timeout(int fd, int *recvfds, int num_recvfds, -+ void *data, size_t size, unsigned int timeout); - - #endif /* __LXC_AF_UNIX_H */ -diff --git a/src/lxc/commands.c b/src/lxc/commands.c -index 133384d..47a824a 100644 ---- a/src/lxc/commands.c -+++ b/src/lxc/commands.c -@@ -126,13 +126,16 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd) - int ret, rspfd; - struct lxc_cmd_rsp *rsp = &cmd->rsp; - -- ret = lxc_abstract_unix_recv_fds(sock, &rspfd, 1, rsp, sizeof(*rsp)); -+ /*isulad: add timeout 200ms to avoid long block due to [lxc monitor] error*/ -+ ret = lxc_abstract_unix_recv_fds_timeout(sock, &rspfd, 1, rsp, sizeof(*rsp), 200 * 1000); - if (ret < 0) { - SYSWARN("Failed to receive response for command \"%s\"", - lxc_cmd_str(cmd->req.cmd)); - -- if (errno == ECONNRESET) -+ if (errno == ECONNRESET || errno == EAGAIN || errno == EWOULDBLOCK) { -+ errno = ECONNRESET; /*isulad set errno ECONNRESET when timeout */ - return -1; -+ } - - return -1; - } --- -1.8.3.1 - diff --git a/0040-cgfsng-make-container-full-path-in-cgfsng_get_cgroup.patch b/0040-cgfsng-make-container-full-path-in-cgfsng_get_cgroup.patch new file mode 100644 index 0000000000000000000000000000000000000000..f987eb2e208ac80c8f7464252c942e89fe0cbf78 --- /dev/null +++ b/0040-cgfsng-make-container-full-path-in-cgfsng_get_cgroup.patch @@ -0,0 +1,29 @@ +From beefa97e5dd3daec438b6d8237af167fde1097dd Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Thu, 16 Apr 2020 12:35:45 +0800 +Subject: [PATCH 40/49] cgfsng: make container full path in cgfsng_get_cgroup + +Signed-off-by: LiFeng +--- + src/lxc/cgroups/cgfsng.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c +index 76576c5..e2a8983 100644 +--- a/src/lxc/cgroups/cgfsng.c ++++ b/src/lxc/cgroups/cgfsng.c +@@ -2612,6 +2612,11 @@ __cgfsng_ops static const char *cgfsng_get_cgroup(struct cgroup_ops *ops, + return log_warn_errno(NULL, ENOENT, "Failed to find hierarchy for controller \"%s\"", + controller ? controller : "(null)"); + ++#ifdef HAVE_ISULAD ++ if (!h->container_full_path) ++ h->container_full_path = must_make_path(h->mountpoint, h->container_base_path, ops->container_cgroup, NULL); ++#endif ++ + return h->container_full_path + ? h->container_full_path + strlen(h->mountpoint) + : NULL; +-- +1.8.3.1 + diff --git a/0041-build-fix-some-bug-in-free-memory.patch b/0041-build-fix-some-bug-in-free-memory.patch new file mode 100644 index 0000000000000000000000000000000000000000..e143c7f4e756ac5025a06e5e051ce4bf0b1a49c6 --- /dev/null +++ b/0041-build-fix-some-bug-in-free-memory.patch @@ -0,0 +1,52 @@ +From dcc50d14398f1bfcde7c41e7480928e6c98b52d9 Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Thu, 16 Apr 2020 12:35:45 +0800 +Subject: [PATCH 41/49] build: fix some bug in free memory + +Signed-off-by: LiFeng +--- + src/lxc/lxccontainer.c | 10 ++++++++++ + src/lxc/string_utils.c | 1 + + 2 files changed, 11 insertions(+) + +diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c +index ab10ac6..818848a 100644 +--- a/src/lxc/lxccontainer.c ++++ b/src/lxc/lxccontainer.c +@@ -6006,11 +6006,21 @@ int list_active_containers(const char *lxcpath, char ***nret, + continue; + } + ++#ifdef HAVE_ISULAD ++ if (ct_name && ct_name_cnt) { ++ if (array_contains(&ct_name, p, ct_name_cnt)) { ++ if (is_hashed) ++ free(p); ++ continue; ++ } ++ } ++#else + if (array_contains(&ct_name, p, ct_name_cnt)) { + if (is_hashed) + free(p); + continue; + } ++#endif + + if (!add_to_array(&ct_name, p, ct_name_cnt)) { + if (is_hashed) +diff --git a/src/lxc/string_utils.c b/src/lxc/string_utils.c +index dcb1160..9118add 100644 +--- a/src/lxc/string_utils.c ++++ b/src/lxc/string_utils.c +@@ -501,6 +501,7 @@ int lxc_grow_array(void ***array, size_t *capacity, size_t new_size, size_t capa + /* first time around, catch some trivial mistakes of the user + * only initializing one of these */ + if (!*array || !*capacity) { ++ free(*array); + *array = NULL; + *capacity = 0; + } +-- +1.8.3.1 + diff --git a/0042-cgfsng-make-container-full-path-in-destory-cgroup.patch b/0042-cgfsng-make-container-full-path-in-destory-cgroup.patch new file mode 100644 index 0000000000000000000000000000000000000000..33da326f5f1fa35ea156b840381b9f094c95e52e --- /dev/null +++ b/0042-cgfsng-make-container-full-path-in-destory-cgroup.patch @@ -0,0 +1,29 @@ +From a5cc738c0f322b35a759f83d8d631e657f8bd58b Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Thu, 16 Apr 2020 16:30:34 +0800 +Subject: [PATCH 42/49] cgfsng: make container full path in destory cgroup + +Signed-off-by: LiFeng +--- + src/lxc/cgroups/cgfsng.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c +index e2a8983..1e1df3b 100644 +--- a/src/lxc/cgroups/cgfsng.c ++++ b/src/lxc/cgroups/cgfsng.c +@@ -970,8 +970,9 @@ static int isulad_cgroup_tree_remove(struct hierarchy **hierarchies, + struct hierarchy *h = hierarchies[i]; + int ret; + +- if (!h->container_full_path) +- continue; ++ if (!h->container_full_path) { ++ h->container_full_path = must_make_path(h->mountpoint, h->container_base_path, container_cgroup, NULL); ++ } + + ret = lxc_rm_rf(h->container_full_path); + if (ret < 0) { +-- +1.8.3.1 + diff --git a/0042-lxc-seccomp-adopt-to-lxc3.0.patch b/0042-lxc-seccomp-adopt-to-lxc3.0.patch deleted file mode 100644 index d1002b5561bc6b7a748e0f48b56f262a288fb0b3..0000000000000000000000000000000000000000 --- a/0042-lxc-seccomp-adopt-to-lxc3.0.patch +++ /dev/null @@ -1,169 +0,0 @@ -From cd1cd3c8d36b5f689ceaac00965ab1a3e77c2f33 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Thu, 17 Jan 2019 03:09:00 +0800 -Subject: [PATCH 042/140] lxc: seccomp adopt to lxc3.0 - -Signed-off-by: LiFeng ---- - src/lxc/seccomp.c | 127 ++++++++++++++++++++++++++++-------------------------- - 1 file changed, 65 insertions(+), 62 deletions(-) - -diff --git a/src/lxc/seccomp.c b/src/lxc/seccomp.c -index 1e14be1..27bdc22 100644 ---- a/src/lxc/seccomp.c -+++ b/src/lxc/seccomp.c -@@ -936,86 +936,89 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c - SCMP_ARCH_NATIVE, line, rule.action, - get_action_name(rule.action)); - -- if (ctx.architectures[0] != SCMP_ARCH_NATIVE) { -- if (!do_resolve_add_rule(ctx.architectures[0], line, -- ctx.contexts[0], &rule)) -- goto bad_rule; -- -- INFO("Added compat rule for arch %d for %s action %d(%s)", -- ctx.architectures[0], line, rule.action, -- get_action_name(rule.action)); -- } -+ if (cur_rule_arch == lxc_seccomp_arch_all) { -+ if (ctx.architectures[0] != SCMP_ARCH_NATIVE) { -+ if (!do_resolve_add_rule(ctx.architectures[0], line, -+ ctx.contexts[0], &rule)) -+ goto bad_rule; -+ -+ INFO("Added compat rule for arch %d for %s action %d(%s)", -+ ctx.architectures[0], line, rule.action, -+ get_action_name(rule.action)); -+ } - -- if (ctx.architectures[1] != SCMP_ARCH_NATIVE) { -- if (!do_resolve_add_rule(ctx.architectures[1], line, -- ctx.contexts[1], &rule)) -- goto bad_rule; -+ if (ctx.architectures[1] != SCMP_ARCH_NATIVE) { -+ if (!do_resolve_add_rule(ctx.architectures[1], line, -+ ctx.contexts[1], &rule)) -+ goto bad_rule; - -- INFO("Added compat rule for arch %d for %s action %d(%s)", -- ctx.architectures[1], line, rule.action, -- get_action_name(rule.action)); -- } -+ INFO("Added compat rule for arch %d for %s action %d(%s)", -+ ctx.architectures[1], line, rule.action, -+ get_action_name(rule.action)); -+ } - -- if (ctx.architectures[2] != SCMP_ARCH_NATIVE) { -- if (!do_resolve_add_rule(ctx.architectures[2], line, -+ if (ctx.architectures[2] != SCMP_ARCH_NATIVE) { -+ if (!do_resolve_add_rule(ctx.architectures[2], line, - ctx.contexts[2], &rule)) -- goto bad_rule; -+ goto bad_rule; - -- INFO("Added native rule for arch %d for %s action %d(%s)", -- ctx.architectures[2], line, rule.action, -- get_action_name(rule.action)); -+ INFO("Added native rule for arch %d for %s action %d(%s)", -+ ctx.architectures[2], line, rule.action, -+ get_action_name(rule.action)); -+ } - } - } - -- INFO("Merging compat seccomp contexts into main context"); -- if (ctx.contexts[0]) { -- if (ctx.needs_merge[0]) { -- ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[0]); -- if (ret < 0) { -- ERROR("Failed to merge first compat seccomp " -+ if (cur_rule_arch == lxc_seccomp_arch_all) { -+ INFO("Merging compat seccomp contexts into main context"); -+ if (ctx.contexts[0]) { -+ if (ctx.needs_merge[0]) { -+ ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[0]); -+ if (ret < 0) { -+ ERROR("Failed to merge first compat seccomp " - "context into main context"); -- goto bad; -- } -+ goto bad; -+ } - -- TRACE("Merged first compat seccomp context into main context"); -- } else { -- seccomp_release(ctx.contexts[0]); -- ctx.contexts[0] = NULL; -+ TRACE("Merged first compat seccomp context into main context"); -+ } else { -+ seccomp_release(ctx.contexts[0]); -+ ctx.contexts[0] = NULL; -+ } - } -- } - -- if (ctx.contexts[1]) { -- if (ctx.needs_merge[1]) { -- ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[1]); -- if (ret < 0) { -- ERROR("Failed to merge first compat seccomp " -- "context into main context"); -- goto bad; -- } -+ if (ctx.contexts[1]) { -+ if (ctx.needs_merge[1]) { -+ ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[1]); -+ if (ret < 0) { -+ ERROR("Failed to merge first compat seccomp " -+ "context into main context"); -+ goto bad; -+ } - -- TRACE("Merged second compat seccomp context into main context"); -- } else { -- seccomp_release(ctx.contexts[1]); -- ctx.contexts[1] = NULL; -+ TRACE("Merged second compat seccomp context into main context"); -+ } else { -+ seccomp_release(ctx.contexts[1]); -+ ctx.contexts[1] = NULL; -+ } - } -- } - -- if (ctx.contexts[2]) { -- if (ctx.needs_merge[2]) { -- ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[2]); -- if (ret < 0) { -- ERROR("Failed to merge third compat seccomp " -- "context into main context"); -- goto bad; -- } -+ if (ctx.contexts[2]) { -+ if (ctx.needs_merge[2]) { -+ ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[2]); -+ if (ret < 0) { -+ ERROR("Failed to merge third compat seccomp " -+ "context into main context"); -+ goto bad; -+ } - -- TRACE("Merged third compat seccomp context into main context"); -- } else { -- seccomp_release(ctx.contexts[2]); -- ctx.contexts[2] = NULL; -+ TRACE("Merged third compat seccomp context into main context"); -+ } else { -+ seccomp_release(ctx.contexts[2]); -+ ctx.contexts[2] = NULL; -+ } - } - } -- - free(line); - return 0; - --- -1.8.3.1 - diff --git a/0043-check-null-pointer-of-handler-to-fix-coredump-of-att.patch b/0043-check-null-pointer-of-handler-to-fix-coredump-of-att.patch deleted file mode 100644 index 897a797bdc728c9346de20fe35c95b0bceb481b3..0000000000000000000000000000000000000000 --- a/0043-check-null-pointer-of-handler-to-fix-coredump-of-att.patch +++ /dev/null @@ -1,28 +0,0 @@ -From b94affbd314be09dcd5927b15bee85459f6bc2ff Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Thu, 17 Jan 2019 10:19:37 +0800 -Subject: [PATCH 043/140] check null pointer of handler to fix coredump of - attach - -Signed-off-by: tanyifeng -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgroup.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/lxc/cgroups/cgroup.c b/src/lxc/cgroups/cgroup.c -index 7442c31..720a6c9 100644 ---- a/src/lxc/cgroups/cgroup.c -+++ b/src/lxc/cgroups/cgroup.c -@@ -44,7 +44,7 @@ struct cgroup_ops *cgroup_init(struct lxc_handler *handler) - { - struct cgroup_ops *cgroup_ops; - -- cgroup_ops = cgfsng_ops_init(handler->conf->errpipe[1]); -+ cgroup_ops = cgfsng_ops_init(handler ? handler->conf->errpipe[1] : -1); - if (!cgroup_ops) { - ERROR("Failed to initialize cgroup driver"); - return NULL; --- -1.8.3.1 - diff --git a/0043-support-error-report.patch b/0043-support-error-report.patch new file mode 100644 index 0000000000000000000000000000000000000000..8f0828d1077aded657092e0336384abf2416dac0 --- /dev/null +++ b/0043-support-error-report.patch @@ -0,0 +1,683 @@ +From 968c9e3e7715c080f23a1fd80c31d4bcf20d241b Mon Sep 17 00:00:00 2001 +From: haozi007 +Date: Thu, 16 Apr 2020 15:16:41 +0800 +Subject: [PATCH 43/49] support error report + +Signed-off-by: haozi007 +--- + src/lxc/attach.c | 60 +++++++++++++++++++++++++++++++++++++++++++---- + src/lxc/attach_options.h | 12 ++++++++++ + src/lxc/cgroups/cgfsng.c | 1 + + src/lxc/conf.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++ + src/lxc/conf.h | 5 ++++ + src/lxc/execute.c | 7 ++++++ + src/lxc/lxccontainer.c | 47 +++++++++++++++++++++++++++++++++++++ + src/lxc/start.c | 21 +++++++++++++++++ + src/lxc/start.h | 4 ++++ + src/lxc/tools/lxc_ls.c | 8 +++++++ + src/lxc/tools/lxc_start.c | 5 ++++ + src/lxc/utils.c | 16 +++++++++++++ + 12 files changed, 241 insertions(+), 4 deletions(-) + +diff --git a/src/lxc/attach.c b/src/lxc/attach.c +index 510c069..734cddd 100644 +--- a/src/lxc/attach.c ++++ b/src/lxc/attach.c +@@ -677,9 +677,13 @@ static int attach_child_main(struct attach_clone_payload *payload) + bool needs_lsm = (options->namespaces & CLONE_NEWNS) && + (options->attach_flags & LXC_ATTACH_LSM) && + init_ctx->lsm_label; +- + #ifdef HAVE_ISULAD +- /*isulad: set system umask */ ++ int msg_fd = -1; ++ ++ /*isulad: record errpipe fd*/ ++ msg_fd = init_ctx->container->lxc_conf->errpipe[1]; ++ init_ctx->container->lxc_conf->errpipe[1] = -1; ++ /*isulad: set system umask */ + umask(init_ctx->container->lxc_conf->umask); + #endif + +@@ -963,10 +967,12 @@ static int attach_child_main(struct attach_clone_payload *payload) + payload->ipc_socket = -EBADF; + lxc_proc_put_context_info(init_ctx); + payload->init_ctx = NULL; +-#endif +- ++ _exit(payload->exec_function(payload->exec_payload, msg_fd)); ++#else + /* We're done, so we can now do whatever the user intended us to do. */ + _exit(payload->exec_function(payload->exec_payload)); ++#endif ++ + + on_error: + lxc_put_attach_clone_payload(payload); +@@ -1331,6 +1337,25 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + return -1; + } + ++#ifdef HAVE_ISULAD ++ /* isulad: pipdfd for get error message of child or grandchild process. */ ++ if (pipe2(conf->errpipe, O_CLOEXEC) != 0) { ++ SYSERROR("Failed to init errpipe"); ++ if (options->attach_flags & LXC_ATTACH_TERMINAL) { ++ lxc_terminal_delete(&terminal); ++ lxc_terminal_conf_free(&terminal); ++ if (exec_command.maincmd_fd != -1) { ++ close(exec_command.maincmd_fd); ++ } ++ } ++ close(ipc_sockets[0]); ++ close(ipc_sockets[1]); ++ free(cwd); ++ lxc_proc_put_context_info(init_ctx); ++ return -1; ++ } ++#endif ++ + /* Create intermediate subprocess, two reasons: + * 1. We can't setns() in the child itself, since we want to make + * sure we are properly attached to the pidns. +@@ -1365,6 +1390,11 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + /* close unneeded file descriptors */ + close(ipc_sockets[1]); + free(cwd); ++#ifdef HAVE_ISULAD ++ /* isulad: close errpipe */ ++ close(conf->errpipe[1]); ++ conf->errpipe[1] = -1; ++#endif + lxc_proc_close_ns_fd(init_ctx); + if (options->attach_flags & LXC_ATTACH_TERMINAL) + lxc_attach_terminal_close_slave(&terminal); +@@ -1398,7 +1428,11 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + + /* Setup resource limits */ + if (!lxc_list_empty(&conf->limits)) { ++#ifdef HAVE_ISULAD ++ ret = setup_resource_limits(&conf->limits, pid, -1); ++#else + ret = setup_resource_limits(&conf->limits, pid); ++#endif + if (ret < 0) + goto on_error; + } +@@ -1561,6 +1595,12 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + /* close unneeded file descriptors */ + close_prot_errno_disarm(ipc_sockets[0]); + ++#ifdef HAVE_ISULAD ++ /* isulad: close errpipe */ ++ close(conf->errpipe[0]); ++ conf->errpipe[0] = -1; ++#endif ++ + if (options->attach_flags & LXC_ATTACH_TERMINAL) { + lxc_attach_terminal_close_master(&terminal); + lxc_attach_terminal_close_peer(&terminal); +@@ -1665,7 +1705,11 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + _exit(EXIT_SUCCESS); + } + ++#ifdef HAVE_ISULAD ++int lxc_attach_run_command(void *payload, int msg_fd) ++#else + int lxc_attach_run_command(void *payload) ++#endif + { + int ret = -1; + lxc_attach_command_t *cmd = payload; +@@ -1681,11 +1725,19 @@ int lxc_attach_run_command(void *payload) + break; + } + } ++#ifdef HAVE_ISULAD ++ /* isulad: write error messages */ ++ lxc_write_error_message(msg_fd, "exec: \"%s\": %s.", cmd->program, strerror(errno)); ++#endif + + return log_error_errno(ret, errno, "Failed to exec \"%s\"", cmd->program); + } + ++#ifdef HAVE_ISULAD ++int lxc_attach_run_shell(void* payload, int msg_fd) ++#else + int lxc_attach_run_shell(void* payload) ++#endif + { + __do_free char *buf = NULL; + uid_t uid; +diff --git a/src/lxc/attach_options.h b/src/lxc/attach_options.h +index 5f01739..d5d4f44 100644 +--- a/src/lxc/attach_options.h ++++ b/src/lxc/attach_options.h +@@ -49,7 +49,11 @@ enum { + * + * \return Function should return \c 0 on success, and any other value to denote failure. + */ ++#ifdef HAVE_ISULAD ++typedef int (*lxc_attach_exec_t)(void* payload, int msg_fd); ++#else + typedef int (*lxc_attach_exec_t)(void* payload); ++#endif + + /*! + * LXC attach options for \ref lxc_container \c attach(). +@@ -153,7 +157,11 @@ typedef struct lxc_attach_command_t { + * + * \return \c -1 on error, exit code of lxc_attach_command_t program on success. + */ ++#ifdef HAVE_ISULAD ++extern int lxc_attach_run_command(void* payload, int msg_fd); ++#else + extern int lxc_attach_run_command(void* payload); ++#endif + + /*! + * \brief Run a shell command in the container. +@@ -162,7 +170,11 @@ extern int lxc_attach_run_command(void* payload); + * + * \return Exit code of shell. + */ ++#ifdef HAVE_ISULAD ++extern int lxc_attach_run_shell(void* payload, int msg_fd); ++#else + extern int lxc_attach_run_shell(void* payload); ++#endif + + #ifdef __cplusplus + } +diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c +index 1e1df3b..002f051 100644 +--- a/src/lxc/cgroups/cgfsng.c ++++ b/src/lxc/cgroups/cgfsng.c +@@ -4233,6 +4233,7 @@ struct cgroup_ops *cgfsng_ops_init(struct lxc_conf *conf) + + cgfsng_ops->data_init = cgfsng_data_init; + #ifdef HAVE_ISULAD ++ cgfsng_ops->errfd = conf ? conf->errpipe[1] : -1; + cgfsng_ops->payload_destroy = isulad_cgfsng_payload_destroy; + #else + cgfsng_ops->payload_destroy = cgfsng_payload_destroy; +diff --git a/src/lxc/conf.c b/src/lxc/conf.c +index e8ee749..d7a78bd 100644 +--- a/src/lxc/conf.c ++++ b/src/lxc/conf.c +@@ -2275,8 +2275,15 @@ static int mount_entry_create_dir_file(const struct mntent *mntent, + + if (hasmntopt(mntent, "create=dir")) { + ret = mkdir_p(path, 0755); ++#ifdef HAVE_ISULAD ++ if (ret < 0 && errno != EEXIST) { ++ lxc_write_error_message(rootfs->errfd, "%s:%d: mkdir %s: %s.", __FILE__, __LINE__, path, strerror(errno)); ++ return log_error_errno(-1, errno, "Failed to create directory \"%s\"", path); ++ } ++#else + if (ret < 0 && errno != EEXIST) + return log_error_errno(-1, errno, "Failed to create directory \"%s\"", path); ++#endif + } + + if (!hasmntopt(mntent, "create=file")) +@@ -2293,12 +2300,26 @@ static int mount_entry_create_dir_file(const struct mntent *mntent, + p2 = dirname(p1); + + ret = mkdir_p(p2, 0755); ++#ifdef HAVE_ISULAD ++ if (ret < 0 && errno != EEXIST) { ++ lxc_write_error_message(rootfs->errfd, "%s:%d: mkdir %s: %s.", __FILE__, __LINE__, path, strerror(errno)); ++ return log_error_errno(-1, errno, "Failed to create directory \"%s\"", path); ++ } ++#else + if (ret < 0 && errno != EEXIST) + return log_error_errno(-1, errno, "Failed to create directory \"%s\"", path); ++#endif + + ret = mknod(path, S_IFREG | 0000, 0); ++#ifdef HAVE_ISULAD ++ if (ret < 0 && errno != EEXIST) { ++ lxc_write_error_message(rootfs->errfd, "%s:%d: open %s: %s.", __FILE__, __LINE__, path, strerror(errno)); ++ return -errno; ++ } ++#else + if (ret < 0 && errno != EEXIST) + return -errno; ++#endif + + return 0; + } +@@ -2960,7 +2981,11 @@ static int parse_resource(const char *res) + return resid; + } + ++#ifdef HAVE_ISULAD ++int setup_resource_limits(struct lxc_list *limits, pid_t pid, int errfd) ++#else + int setup_resource_limits(struct lxc_list *limits, pid_t pid) ++#endif + { + int resid; + struct lxc_list *it; +@@ -2974,8 +2999,17 @@ int setup_resource_limits(struct lxc_list *limits, pid_t pid) + return log_error(-1, "Unknown resource %s", lim->resource); + + #if HAVE_PRLIMIT || HAVE_PRLIMIT64 ++#if HAVE_ISULAD ++ if (prlimit(pid, resid, &lim->limit, NULL) != 0) { ++ lxc_write_error_message(errfd, "%s:%d: Failed to set limit %s %lu %lu: %s.", ++ __FILE__, __LINE__, lim->resource, ++ lim->limit.rlim_cur, lim->limit.rlim_max, strerror(errno)); ++ return log_error_errno(-1, errno, "Failed to set limit %s", lim->resource); ++ } ++#else + if (prlimit(pid, resid, &lim->limit, NULL) != 0) + return log_error_errno(-1, errno, "Failed to set limit %s", lim->resource); ++#endif + + TRACE("Setup \"%s\" limit", lim->resource); + #else +@@ -3134,6 +3168,9 @@ struct lxc_conf *lxc_conf_init(void) + new->console.pipes[2][0] = -1; + new->console.pipes[2][1] = -1; + lxc_list_init(&new->console.fifos); ++ new->errmsg = NULL; ++ new->errpipe[0] = -1; ++ new->errpipe[1] = -1; + #endif + + return new; +@@ -4534,8 +4571,16 @@ int lxc_setup(struct lxc_handler *handler) + char *keyring_context = NULL; + + ret = lxc_setup_rootfs_prepare_root(lxc_conf, name, lxcpath); ++#ifdef HAVE_ISULAD ++ if (ret < 0) { ++ lxc_write_error_message(lxc_conf->errpipe[1], "%s:%d: failed to setup rootfs %s.", ++ __FILE__, __LINE__, lxc_conf->rootfs.path); ++ return log_error(-1, "Failed to setup rootfs"); ++ } ++#else + if (ret < 0) + return log_error(-1, "Failed to setup rootfs"); ++#endif + + if (handler->nsfd[LXC_NS_UTS] == -EBADF) { + ret = setup_utsname(lxc_conf->utsname); +@@ -5243,6 +5288,8 @@ void lxc_conf_free(struct lxc_conf *conf) + lxc_clear_populate_devices(conf); + lxc_clear_rootfs_masked_paths(conf); + lxc_clear_rootfs_ro_paths(conf); ++ free(conf->errmsg); ++ lxc_close_error_pipe(conf->errpipe); + #endif + free(conf); + } +@@ -6127,4 +6174,16 @@ int lxc_clear_rootfs_ro_paths(struct lxc_conf *c) + return 0; + } + ++/*isulad: close error pipe */ ++void lxc_close_error_pipe(int *errpipe) ++{ ++ if (errpipe[0] >= 0) { ++ close(errpipe[0]); ++ errpipe[0] = -1; ++ } ++ if (errpipe[1] >= 0) { ++ close(errpipe[1]); ++ errpipe[1] = -1; ++ } ++} + #endif +diff --git a/src/lxc/conf.h b/src/lxc/conf.h +index 7b6fd3b..4b6409e 100644 +--- a/src/lxc/conf.h ++++ b/src/lxc/conf.h +@@ -506,7 +506,11 @@ extern int lxc_setup_rootfs_prepare_root(struct lxc_conf *conf, + const char *name, const char *lxcpath); + extern int lxc_setup(struct lxc_handler *handler); + extern int lxc_setup_parent(struct lxc_handler *handler); ++#ifdef HAVE_ISULAD ++extern int setup_resource_limits(struct lxc_list *limits, pid_t pid, int errfd); ++#else + extern int setup_resource_limits(struct lxc_list *limits, pid_t pid); ++#endif + extern int find_unmapped_nsid(const struct lxc_conf *conf, enum idtype idtype); + extern int mapped_hostid(unsigned id, const struct lxc_conf *conf, + enum idtype idtype); +@@ -557,5 +561,6 @@ int lxc_clear_rootfs_masked_paths(struct lxc_conf *c); + int lxc_clear_rootfs_ro_paths(struct lxc_conf *c); + int lxc_drop_caps(struct lxc_conf *conf); + int run_oci_hooks(const char *name, const char *hookname, struct lxc_conf *conf, const char *lxcpath); ++void lxc_close_error_pipe(int *errpipe); + #endif + #endif /* __LXC_CONF_H */ +diff --git a/src/lxc/execute.c b/src/lxc/execute.c +index 59ff604..16c0fed 100644 +--- a/src/lxc/execute.c ++++ b/src/lxc/execute.c +@@ -19,7 +19,11 @@ + + lxc_log_define(execute, start); + ++#ifdef HAVE_ISULAD ++static int execute_start(struct lxc_handler *handler, void* data, int fd) ++#else + static int execute_start(struct lxc_handler *handler, void* data) ++#endif + { + int argc_add, j; + char **argv; +@@ -71,6 +75,9 @@ static int execute_start(struct lxc_handler *handler, void* data) + execvp(argv[0], argv); + SYSERROR("Failed to exec %s", argv[0]); + ++#ifdef HAVE_ISULAD ++ lxc_write_error_message(fd, "Failed to exec: \"%s\": %s.", argv[0], strerror(errno)); ++#endif + free(argv); + out1: + return 1; +diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c +index 818848a..ed09a59 100644 +--- a/src/lxc/lxccontainer.c ++++ b/src/lxc/lxccontainer.c +@@ -972,6 +972,8 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a + char **init_cmd = NULL; + #ifdef HAVE_ISULAD + int keepfds[] = {-1, -1, -1, -1, -1}; ++ ssize_t size_read; ++ char errbuf[BUFSIZ + 1] = {0}; + #else + int keepfds[3] = {-1, -1, -1}; + #endif +@@ -1046,10 +1048,23 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a + char title[2048]; + pid_t pid_first, pid_second; + ++#ifdef HAVE_ISULAD ++ //isulad: pipdfd for get error message of child or grandchild process. ++ if (pipe2(conf->errpipe, O_CLOEXEC) != 0) { ++ SYSERROR("Failed to init errpipe"); ++ free_init_cmd(init_cmd); ++ lxc_free_handler(handler); ++ return false; ++ } ++#endif ++ + pid_first = fork(); + if (pid_first < 0) { + free_init_cmd(init_cmd); + lxc_free_handler(handler); ++#ifdef HAVE_ISULAD ++ lxc_close_error_pipe(conf->errpipe); ++#endif + return false; + } + +@@ -1059,11 +1074,25 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a + * the PID file, child will do the free and unlink. + */ + c->pidfile = NULL; ++#ifdef HAVE_ISULAD ++ close(conf->errpipe[1]); ++ conf->errpipe[1] = -1; ++#endif + + /* Wait for container to tell us whether it started + * successfully. + */ + started = wait_on_daemonized_start(handler, pid_first); ++#ifdef HAVE_ISULAD ++ if (!started) { ++ size_read = read(conf->errpipe[0], errbuf, BUFSIZ); ++ if (size_read > 0) { ++ conf->errmsg = safe_strdup(errbuf); ++ } ++ } ++ close(conf->errpipe[0]); ++ conf->errpipe[0] = -1; ++#endif + + free_init_cmd(init_cmd); + lxc_free_handler(handler); +@@ -1099,6 +1128,9 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a + if (pid_second != 0) { + free_init_cmd(init_cmd); + lxc_free_handler(handler); ++#ifdef HAVE_ISULAD ++ lxc_close_error_pipe(conf->errpipe); ++#endif + _exit(EXIT_SUCCESS); + } + +@@ -1114,6 +1146,11 @@ 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]; ++#ifdef HAVE_ISULAD ++ keepfds[4] = conf->errpipe[1]; ++ close(conf->errpipe[0]); ++ conf->errpipe[0] = -1; ++#endif + ret = lxc_check_inherited(conf, true, keepfds, + sizeof(keepfds) / sizeof(keepfds[0])); + if (ret < 0) +@@ -1148,6 +1185,9 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a + if (w < 0 || (size_t)w >= sizeof(pidstr)) { + free_init_cmd(init_cmd); + lxc_free_handler(handler); ++#ifdef HAVE_ISULAD ++ lxc_close_error_pipe(conf->errpipe); ++#endif + + SYSERROR("Failed to write monitor pid to \"%s\"", c->pidfile); + +@@ -1161,6 +1201,9 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a + if (ret < 0) { + free_init_cmd(init_cmd); + lxc_free_handler(handler); ++#ifdef HAVE_ISULAD ++ lxc_close_error_pipe(conf->errpipe); ++#endif + + SYSERROR("Failed to write monitor pid to \"%s\"", c->pidfile); + +@@ -1224,6 +1267,9 @@ reboot: + if (conf->exit_fd >= 0) { + keepfds[3] = conf->exit_fd; + } ++ /* isulad: keep errpipe fd */ ++ if (c->daemonize) ++ keepfds[4] = conf->errpipe[1]; + #endif + + ret = lxc_check_inherited(conf, c->daemonize, keepfds, +@@ -3250,6 +3296,7 @@ static bool container_destroy(struct lxc_container *c, + ERROR("Sprintf failed"); + goto out; + } ++ c->error_string = safe_strdup(msg); + #endif + goto out; + } +diff --git a/src/lxc/start.c b/src/lxc/start.c +index 0bc1143..134235f 100644 +--- a/src/lxc/start.c ++++ b/src/lxc/start.c +@@ -836,6 +836,9 @@ int lxc_init(const char *name, struct lxc_handler *handler) + ret = lxc_terminal_setup(conf); + if (ret < 0) { + ERROR("Failed to create console"); ++#ifdef HAVE_ISULAD ++ lxc_write_error_message(conf->errpipe[1], "Failed to create console for container \"%s\".", name); ++#endif + goto out_restore_sigmask; + } + TRACE("Created console"); +@@ -1470,6 +1473,9 @@ static int do_start(void *data) + /* Setup the container, ip, names, utsname, ... */ + ret = lxc_setup(handler); + if (ret < 0) { ++#ifdef HAVE_ISULAD ++ lxc_write_error_message(handler->conf->errpipe[1], "Failed to setup lxc, please check the config file."); ++#endif + ERROR("Failed to setup container \"%s\"", handler->name); + goto out_warn_father; + } +@@ -1763,7 +1769,11 @@ static int do_start(void *data) + /* After this call, we are in error because this ops should not return + * as it execs. + */ ++#ifdef HAVE_ISULAD ++ handler->ops->start(handler, handler->data, handler->daemonize ? handler->conf->errpipe[1] : -1); ++#else + handler->ops->start(handler, handler->data); ++#endif + + out_warn_father: + /* We want the parent to know something went wrong, so we return a +@@ -2246,7 +2256,11 @@ static int lxc_spawn(struct lxc_handler *handler) + goto out_delete_net; + + if (!lxc_list_empty(&conf->limits)) { ++#ifdef HAVE_ISULAD ++ ret = setup_resource_limits(&conf->limits, handler->pid, conf->errpipe[1]); ++#else + ret = setup_resource_limits(&conf->limits, handler->pid); ++#endif + if (ret < 0) { + ERROR("Failed to setup resource limits"); + goto out_delete_net; +@@ -2652,7 +2666,11 @@ struct start_args { + char *const *argv; + }; + ++#ifdef HAVE_ISULAD ++static int start(struct lxc_handler *handler, void* data, int fd) ++#else + static int start(struct lxc_handler *handler, void* data) ++#endif + { + struct start_args *arg = data; + +@@ -2660,6 +2678,9 @@ static int start(struct lxc_handler *handler, void* data) + + execvp(arg->argv[0], arg->argv); + SYSERROR("Failed to exec \"%s\"", arg->argv[0]); ++#ifdef HAVE_ISULAD ++ lxc_write_error_message(fd, "exec: \"%s\": %s.", arg->argv[0], strerror(errno)); ++#endif + return 0; + } + +diff --git a/src/lxc/start.h b/src/lxc/start.h +index cea37bc..ebeeb72 100644 +--- a/src/lxc/start.h ++++ b/src/lxc/start.h +@@ -141,7 +141,11 @@ struct execute_args { + }; + + struct lxc_operations { ++#ifdef HAVE_ISULAD ++ int (*start)(struct lxc_handler *, void *, int); ++#else + int (*start)(struct lxc_handler *, void *); ++#endif + int (*post_start)(struct lxc_handler *, void *); + }; + +diff --git a/src/lxc/tools/lxc_ls.c b/src/lxc/tools/lxc_ls.c +index 4be8564..e601f9d 100644 +--- a/src/lxc/tools/lxc_ls.c ++++ b/src/lxc/tools/lxc_ls.c +@@ -106,7 +106,11 @@ struct wrapargs { + /* + * Takes struct wrapargs as argument. + */ ++#ifdef HAVE_ISULAD ++static int ls_get_wrapper(void *wrap, int msgfd); ++#else + static int ls_get_wrapper(void *wrap); ++#endif + + /* + * To calculate swap usage we should not simply check memory.usage_in_bytes and +@@ -1005,7 +1009,11 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) + return 0; + } + ++#ifdef HAVE_ISULAD ++static int ls_get_wrapper(void *wrap, int msgfd) ++#else + static int ls_get_wrapper(void *wrap) ++#endif + { + int ret = -1; + size_t len = 0; +diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c +index b430a1e..4f2c8af 100644 +--- a/src/lxc/tools/lxc_start.c ++++ b/src/lxc/tools/lxc_start.c +@@ -392,6 +392,11 @@ int main(int argc, char *argv[]) + else + err = c->start(c, 0, args) ? EXIT_SUCCESS : EXIT_FAILURE; + if (err) { ++#ifdef HAVE_ISULAD ++ if (c->lxc_conf->errmsg) ++ fprintf(stderr, "%s:%s:%s:%d starting container process caused \"%s\"", c->name, ++ __FILE__, __func__, __LINE__, c->lxc_conf->errmsg); ++#endif + ERROR("The container failed to start"); + + if (my_args.daemonize) +diff --git a/src/lxc/utils.c b/src/lxc/utils.c +index 810b7fe..4e418fb 100644 +--- a/src/lxc/utils.c ++++ b/src/lxc/utils.c +@@ -73,6 +73,9 @@ static int _recursive_rmdir(const char *dirname, dev_t pdev, + int ret; + struct dirent *direntp; + char pathname[PATH_MAX]; ++#ifdef HAVE_ISULAD ++ int saved_errno = 0; ++#endif + + dir = opendir(dirname); + if (!dir) +@@ -135,6 +138,11 @@ static int _recursive_rmdir(const char *dirname, dev_t pdev, + } else { + ret = unlink(pathname); + if (ret < 0) { ++#ifdef HAVE_ISULAD ++ if (saved_errno == 0) { ++ saved_errno = errno; ++ } ++#endif + __do_close int fd = -EBADF; + + fd = open(pathname, O_RDONLY | O_CLOEXEC | O_NONBLOCK); +@@ -160,10 +168,18 @@ static int _recursive_rmdir(const char *dirname, dev_t pdev, + } + + if (rmdir(dirname) < 0 && !btrfs_try_remove_subvol(dirname) && !hadexclude) { ++#ifdef HAVE_ISULAD ++ if (saved_errno == 0) { ++ saved_errno = errno; ++ } ++#endif + SYSERROR("Failed to delete \"%s\"", dirname); + failed = 1; + } + ++#ifdef HAVE_ISULAD ++ errno = saved_errno; ++#endif + return failed ? -1 : 0; + } + +-- +1.8.3.1 + diff --git a/0026-remove-filelock-and-do-not-destroy-directory-when-de.patch b/0044-remove-filelock-in-destroy-dir.patch similarity index 43% rename from 0026-remove-filelock-and-do-not-destroy-directory-when-de.patch rename to 0044-remove-filelock-in-destroy-dir.patch index 4f09d9cd3c2b7261215c080d625d0caaaf3d8e68..fbca9d75c43a6b4c70570b9bf08f6dce996501f6 100644 --- a/0026-remove-filelock-and-do-not-destroy-directory-when-de.patch +++ b/0044-remove-filelock-in-destroy-dir.patch @@ -1,63 +1,75 @@ -From 238d4ac14b663aa5db904c55568c3710429d9bca Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Mon, 14 Jan 2019 21:13:00 +0800 -Subject: [PATCH 026/140] remove filelock and do not destroy directory when - destroy container +From 0441dc446ad9f0bc02c5ca7a76d793c8a7734fd9 Mon Sep 17 00:00:00 2001 +From: haozi007 +Date: Thu, 16 Apr 2020 15:39:50 +0800 +Subject: [PATCH 44/49] remove filelock in destroy dir -Signed-off-by: LiFeng +Signed-off-by: haozi007 --- - src/lxc/lxccontainer.c | 14 ++++++++++++-- - src/lxc/lxclock.c | 25 +++++++++++++++++++++++++ - src/lxc/lxclock.h | 5 +++++ - src/lxc/storage/dir.c | 12 +----------- - 4 files changed, 43 insertions(+), 13 deletions(-) + src/lxc/lxccontainer.c | 21 +++++++++++++++++++++ + src/lxc/lxclock.c | 27 +++++++++++++++++++++++++++ + src/lxc/lxclock.h | 4 ++++ + src/lxc/start.c | 7 +++++++ + src/lxc/storage/dir.c | 4 ++++ + 5 files changed, 63 insertions(+) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index 68134d8..81c0ec3 100644 +index ed09a59..6281a8a 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c -@@ -2996,8 +2996,14 @@ static bool container_destroy(struct lxc_container *c, +@@ -3168,8 +3168,19 @@ static bool container_destroy(struct lxc_container *c, bool bret = false; int ret = 0; -- if (!c || !do_lxcapi_is_defined(c)) ++#ifdef HAVE_ISULAD + if (!c) - return false; ++ return false; + // isulad: if container is not defined, we need to remove disk lock file + // which is created in lxc_container_new. + if (!do_lxcapi_is_defined(c)) { + container_disk_removelock(c); + return false; + } ++#else + if (!c || !do_lxcapi_is_defined(c)) + return false; ++#endif conf = c->lxc_conf; if (container_disk_lock(c)) -@@ -3124,12 +3130,16 @@ out: +@@ -3310,13 +3321,23 @@ out: free(path); container_disk_unlock(c); -+ if (bret) { -+ if (container_disk_removelock(c)) -+ bret = false; ++#ifdef HAVE_ISULAD ++ if (bret && container_disk_removelock(c)) { ++ bret = false; + } ++#endif return bret; } static bool do_lxcapi_destroy(struct lxc_container *c) { -- if (!c || !lxcapi_is_defined(c)) ++#ifdef HAVE_ISULAD + if (!c) ++ return false; ++#else + if (!c || !lxcapi_is_defined(c)) return false; ++#endif - if (has_snapshots(c)) { + if (c->lxc_conf && c->lxc_conf->rootfs.managed) { + if (has_snapshots(c)) { diff --git a/src/lxc/lxclock.c b/src/lxc/lxclock.c -index e3d4654..8890968 100644 +index 318e5bf..bb0dca0 100644 --- a/src/lxc/lxclock.c +++ b/src/lxc/lxclock.c -@@ -198,6 +198,21 @@ on_error: - return l; +@@ -370,3 +370,30 @@ void container_disk_unlock(struct lxc_container *c) + lxcunlock(c->slock); + lxcunlock(c->privlock); } - ++ ++#ifdef HAVE_ISULAD +static int lxc_removelock(struct lxc_lock *l) +{ + int ret = 0; @@ -72,14 +84,6 @@ index e3d4654..8890968 100644 + + return ret; +} -+ - int lxclock(struct lxc_lock *l, int timeout) - { - struct flock lk; -@@ -386,3 +401,13 @@ void container_disk_unlock(struct lxc_container *c) - lxcunlock(c->slock); - lxcunlock(c->privlock); - } + +int container_disk_removelock(struct lxc_container *c) +{ @@ -90,43 +94,60 @@ index e3d4654..8890968 100644 + return ret; + return lxc_removelock(c->privlock); +} ++#endif diff --git a/src/lxc/lxclock.h b/src/lxc/lxclock.h -index 364a71b..e86bc34 100644 +index 9f9bc3b..6a71d7c 100644 --- a/src/lxc/lxclock.h +++ b/src/lxc/lxclock.h -@@ -174,4 +174,9 @@ extern int container_disk_lock(struct lxc_container *c); +@@ -154,4 +154,8 @@ extern int container_disk_lock(struct lxc_container *c); */ extern void container_disk_unlock(struct lxc_container *c); -+/*! -+ * \brief isulad: remove the containers disk lock file. -+ */ ++#ifdef HAVE_ISULAD +int container_disk_removelock(struct lxc_container *c); ++#endif + #endif +diff --git a/src/lxc/start.c b/src/lxc/start.c +index 134235f..6779cee 100644 +--- a/src/lxc/start.c ++++ b/src/lxc/start.c +@@ -2143,6 +2143,13 @@ static int lxc_spawn(struct lxc_handler *handler) + if (ret < 0) + SYSERROR("Failed to set environment variable: LXC_PID=%s", pidstr); + ++#ifdef HAVE_ISULAD ++ if (handler->cgroup_ops->container_cgroup) { ++ if (setenv("LXC_CGROUP_PATH", handler->cgroup_ops->container_cgroup, 1)) ++ SYSERROR("Failed to set environment variable: LXC_CGROUP_PATH=%s.", handler->cgroup_ops->container_cgroup); ++ } ++#endif ++ + for (i = 0; i < LXC_NS_MAX; i++) + if (handler->ns_on_clone_flags & ns_info[i].clone_flag) + INFO("Cloned %s", ns_info[i].flag_name); diff --git a/src/lxc/storage/dir.c b/src/lxc/storage/dir.c -index c7b5ee2..deeecec 100644 +index 1dc95f1..485572a 100644 --- a/src/lxc/storage/dir.c +++ b/src/lxc/storage/dir.c -@@ -123,17 +123,7 @@ int dir_create(struct lxc_storage *bdev, const char *dest, const char *n, +@@ -94,6 +94,9 @@ int dir_create(struct lxc_storage *bdev, const char *dest, const char *n, int dir_destroy(struct lxc_storage *orig) { -- int ret; -- const char *src; -- -- src = lxc_storage_get_path(orig->src, orig->src); -- -- ret = lxc_rmdir_onedev(src, NULL); -- if (ret < 0) { -- ERROR("Failed to delete \"%s\"", src); -- return -1; -- } -- ++#ifdef HAVE_ISULAD + // isulad: do not destroy rootfs for directory, it should be managed by caller ++#else + int ret; + const char *src; + +@@ -102,6 +105,7 @@ int dir_destroy(struct lxc_storage *orig) + ret = lxc_rmdir_onedev(src, NULL); + if (ret < 0) + return log_error_errno(ret, errno, "Failed to delete \"%s\"", src); ++#endif + return 0; } - -- 1.8.3.1 diff --git a/0044-support-space-in-volume-mount-and-env.patch b/0044-support-space-in-volume-mount-and-env.patch deleted file mode 100644 index 4fb9100c0c5176184b8c86088df310d002bf0932..0000000000000000000000000000000000000000 --- a/0044-support-space-in-volume-mount-and-env.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 24d0250197bab7b59c3437cce7845af1fc88df7e Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Thu, 17 Jan 2019 10:18:23 +0800 -Subject: [PATCH 044/140] support space in --volume, --mount and --env - -Signed-off-by: tanyifeng -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 16 ++++++++++++++++ - src/lxc/confile.c | 9 ++++++++- - src/lxc/namespace.h | 1 + - src/lxc/utils.h | 3 +++ - 4 files changed, 28 insertions(+), 1 deletion(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 8fa63f7..48e31af 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -54,6 +54,7 @@ - #include - #include - #include -+#include - - #include "af_unix.h" - #include "caps.h" -@@ -2695,6 +2696,19 @@ static int mount_file_entries(const struct lxc_conf *conf, - int ret = -1; - - while (getmntent_r(file, &mntent, buf, sizeof(buf))) { -+ /* Note: Workaround for volume file path with space*/ -+ mntent.mnt_fsname = lxc_string_replace(SPACE_MAGIC_STR, " ", mntent.mnt_fsname); -+ if(!mntent.mnt_fsname) { -+ SYSERROR("memory allocation error"); -+ return -1; -+ } -+ mntent.mnt_dir = lxc_string_replace(SPACE_MAGIC_STR, " ", mntent.mnt_dir); -+ if(!mntent.mnt_dir) { -+ SYSERROR("memory allocation error"); -+ free(mntent.mnt_fsname); -+ return -1; -+ } -+ ERROR("mntent.mnt_fsname:%s, mntent.mnt_dir:%s", mntent.mnt_fsname, mntent.mnt_dir); - if (!rootfs->path) - ret = mount_entry_on_systemfs(&mntent); - else if (mntent.mnt_dir[0] != '/') -@@ -2703,6 +2717,8 @@ static int mount_file_entries(const struct lxc_conf *conf, - else - ret = mount_entry_on_absolute_rootfs(&mntent, rootfs, - lxc_name, lxc_path); -+ free(mntent.mnt_fsname); -+ free(mntent.mnt_dir); - if (ret < 0) - return -1; - } -diff --git a/src/lxc/confile.c b/src/lxc/confile.c -index db63b55..7e9d5c8 100644 ---- a/src/lxc/confile.c -+++ b/src/lxc/confile.c -@@ -1036,6 +1036,7 @@ static int set_config_environment(const char *key, const char *value, - struct lxc_conf *lxc_conf, void *data) - { - struct lxc_list *list_item = NULL; -+ char *replaced; - - if (lxc_config_value_empty(value)) - return lxc_clear_environment(lxc_conf); -@@ -1044,7 +1045,12 @@ static int set_config_environment(const char *key, const char *value, - if (!list_item) - goto on_error; - -- list_item->elem = strdup(value); -+ /* isulad: recover space replaced by SPACE_MAGIC_STR */ -+ replaced = lxc_string_replace(SPACE_MAGIC_STR, " ", value); -+ if(!replaced) -+ goto on_error; -+ -+ list_item->elem = replaced; - - if (!list_item->elem) - goto on_error; -@@ -3661,6 +3667,7 @@ static int get_config_environment(const char *key, char *retv, int inlen, - memset(retv, 0, inlen); - - lxc_list_for_each(it, &c->environment) { -+ - strprint(retv, inlen, "%s\n", (char *)it->elem); - } - -diff --git a/src/lxc/namespace.h b/src/lxc/namespace.h -index ab583da..9caaf89 100644 ---- a/src/lxc/namespace.h -+++ b/src/lxc/namespace.h -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - - #ifndef CLONE_PARENT_SETTID - #define CLONE_PARENT_SETTID 0x00100000 -diff --git a/src/lxc/utils.h b/src/lxc/utils.h -index 4313942..73ffdd9 100644 ---- a/src/lxc/utils.h -+++ b/src/lxc/utils.h -@@ -43,6 +43,9 @@ - #include "raw_syscalls.h" - #include "string_utils.h" - -+/* isulad: replace space with SPACE_MAGIC_STR */ -+#define SPACE_MAGIC_STR "[#)" -+ - /* returns 1 on success, 0 if there were any failures */ - extern int lxc_rmdir_onedev(const char *path, const char *exclude); - extern int get_u16(unsigned short *val, const char *arg, int base); --- -1.8.3.1 - diff --git a/0037-restore-default-signal-handlers-and-set-umask-0027.patch b/0045-restore-default-signal-handler.patch similarity index 36% rename from 0037-restore-default-signal-handlers-and-set-umask-0027.patch rename to 0045-restore-default-signal-handler.patch index e0e5a55ed584e26e6d59a73680d315a46738a740..e605cddab6bf7aa7788626a42b2cbd23e2df0fc4 100644 --- a/0037-restore-default-signal-handlers-and-set-umask-0027.patch +++ b/0045-restore-default-signal-handler.patch @@ -1,44 +1,54 @@ -From 3ac4fd8b31c3c9e650cbe02383f4d65cfa078b20 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Tue, 15 Jan 2019 23:14:14 -0500 -Subject: [PATCH 037/140] restore default signal handlers and set umask 0027 +From 4a609606e050a9a4693541a965e34d8ac366f153 Mon Sep 17 00:00:00 2001 +From: haozi007 +Date: Thu, 16 Apr 2020 15:56:21 +0800 +Subject: [PATCH 45/49] restore default signal handler -Signed-off-by: LiFeng +Signed-off-by: haozi007 --- - src/lxc/attach.c | 22 +++++++++++++++++++++- - src/lxc/conf.c | 3 +++ - src/lxc/start.c | 18 +++++++++++++++++- - 3 files changed, 41 insertions(+), 2 deletions(-) + hooks/Makefile.am | 3 +++ + src/lxc/attach.c | 16 ++++++++++++++++ + src/lxc/initutils.c | 4 ++++ + src/lxc/start.c | 19 +++++++++++++++++++ + 4 files changed, 42 insertions(+) +diff --git a/hooks/Makefile.am b/hooks/Makefile.am +index 5ae73d7..ddfd4bc 100644 +--- a/hooks/Makefile.am ++++ b/hooks/Makefile.am +@@ -10,6 +10,8 @@ hooks_SCRIPTS = \ + squid-deb-proxy-client \ + nvidia + ++ ++if !HAVE_ISULAD + binhooks_PROGRAMS = \ + unmount-namespace + +@@ -20,5 +22,6 @@ if IS_BIONIC + unmount_namespace_SOURCES += \ + ../src/include/lxcmntent.c ../src/include/lxcmntent.h + endif ++endif + + EXTRA_DIST=$(hooks_SCRIPTS) diff --git a/src/lxc/attach.c b/src/lxc/attach.c -index 3f60fe1..4ccdd74 100644 +index 734cddd..1dd2b47 100644 --- a/src/lxc/attach.c +++ b/src/lxc/attach.c -@@ -750,7 +750,7 @@ static void lxc_put_attach_clone_payload(struct attach_clone_payload *p) - - static int attach_child_main(struct attach_clone_payload *payload) - { -- int fd, lsm_fd, ret; -+ int fd, lsm_fd, ret, i; - uid_t new_uid; - gid_t new_gid; - uid_t ns_root_uid = 0; -@@ -761,11 +761,31 @@ static int attach_child_main(struct attach_clone_payload *payload) - bool needs_lsm = (options->namespaces & CLONE_NEWNS) && - (options->attach_flags & LXC_ATTACH_LSM) && +@@ -679,12 +679,28 @@ static int attach_child_main(struct attach_clone_payload *payload) init_ctx->lsm_label; + #ifdef HAVE_ISULAD + int msg_fd = -1; + sigset_t mask; -+ /*isulad: record errpipe fd*/ msg_fd = init_ctx->container->lxc_conf->errpipe[1]; init_ctx->container->lxc_conf->errpipe[1] = -1; - -+ /*isulad: set system umask 0027 for safe control */ -+ umask(0027); + /*isulad: set system umask */ + umask(init_ctx->container->lxc_conf->umask); + + /*isulad: restore default signal handlers and unblock all signals*/ -+ for (i = 1; i < NSIG; i++) ++ for (int i = 1; i < NSIG; i++) + signal(i, SIG_DFL); + + ret = sigfillset(&mask); @@ -51,63 +61,60 @@ index 3f60fe1..4ccdd74 100644 + SYSERROR("Failed to set signal mask"); + goto on_error; + } -+ + #endif + /* A description of the purpose of this functionality is provided in the - * lxc-attach(1) manual page. We have to remount here and not in the - * parent process, otherwise /proc may not properly reflect the new pid -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 6134ed3..88cebfd 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4180,6 +4180,9 @@ int lxc_setup(struct lxc_handler *handler) - } - } +diff --git a/src/lxc/initutils.c b/src/lxc/initutils.c +index 5549c2e..76f0048 100644 +--- a/src/lxc/initutils.c ++++ b/src/lxc/initutils.c +@@ -54,12 +54,16 @@ const char *lxc_global_config_value(const char *option_name) + { NULL, NULL }, + }; -+ /*isulad: set system umask 0027 for safe control*/ -+ umask(0027); -+ - ret = setup_personality(lxc_conf->personality); - if (ret < 0) { - ERROR("Failed to set personality"); ++#ifdef HAVE_ISULAD ++ static const char *values[sizeof(options) / sizeof(options[0])] = {0}; ++#else + /* placed in the thread local storage pool for non-bionic targets */ + #ifdef HAVE_TLS + static thread_local const char *values[sizeof(options) / sizeof(options[0])] = {0}; + #else + static const char *values[sizeof(options) / sizeof(options[0])] = {0}; + #endif ++#endif + + /* user_config_path is freed as soon as it is used */ + char *user_config_path = NULL; diff --git a/src/lxc/start.c b/src/lxc/start.c -index 357e81d..708ab7f 100644 +index 6779cee..5d2faee 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c -@@ -1103,7 +1103,7 @@ void lxc_abort(const char *name, struct lxc_handler *handler) - - static int do_start(void *data) - { -- int ret; -+ int ret, i; - char path[PATH_MAX]; - uid_t new_uid; - gid_t new_gid; -@@ -1112,9 +1112,25 @@ static int do_start(void *data) - gid_t nsgid = 0; - int devnull_fd = -1; - struct lxc_handler *handler = data; -+ sigset_t mask; +@@ -1290,6 +1290,25 @@ static int do_start(void *data) lxc_sync_fini_parent(handler); ++#ifdef HAVE_ISULAD ++ sigset_t mask; ++ + /*isulad: restore default signal handlers and unblock all signals*/ -+ for (i = 1; i < NSIG; i++) ++ for (int i = 1; i < NSIG; i++) + signal(i, SIG_DFL); + + ret = sigfillset(&mask); + if (ret < 0) { + SYSERROR("Failed to fill signal mask"); -+ goto out_warn_father;; ++ goto out_warn_father; + } + ret = sigprocmask(SIG_UNBLOCK, &mask, NULL); + if (ret < 0) { + SYSERROR("Failed to set signal mask"); + goto out_warn_father; + } ++#endif + - /* This prctl must be before the synchro, so if the parent dies before - * we set the parent death signal, we will detect its death with the - * synchro right after, otherwise we have a window where the parent can + if (lxc_abstract_unix_recv_fds(data_sock1, &status_fd, 1, NULL, 0) < 0) { + ERROR("Failed to receive status file descriptor to child process"); + goto out_warn_father; -- 1.8.3.1 diff --git a/0046-Do-not-test-cgroup-writeable.patch b/0046-Do-not-test-cgroup-writeable.patch deleted file mode 100644 index 9e9bc65908cb4db3c26fc862f015c298efb387ea..0000000000000000000000000000000000000000 --- a/0046-Do-not-test-cgroup-writeable.patch +++ /dev/null @@ -1,48 +0,0 @@ -From fc6da7b9465295da1dc1d40d835a8c7680207d66 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Thu, 17 Jan 2019 03:49:16 -0500 -Subject: [PATCH 046/140] Do not test cgroup writeable - -If we run isulad in docker without cgroup namespace, the base_cgroup will be docker/XXX.., -mountpoint+base_cgroup may be not exist - -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgfsng.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index 47b12a6..6bfa693 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -581,7 +581,7 @@ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname) - if (slash) - *slash = '/'; - -- ret = mkdir(cgpath, 0755); -+ ret = mkdir_p(cgpath, 0755); - if (ret < 0) { - if (errno != EEXIST) { - SYSERROR("Failed to create directory \"%s\"", cgpath); -@@ -2489,13 +2489,17 @@ static bool cg_hybrid_init(struct cgroup_ops *ops) - - trim(base_cgroup); - prune_init_scope(base_cgroup); -+ -+ /* isulad: -+ * do not test writeable, if we run isulad in docker without cgroup namespace. -+ * the base_cgroup will be docker/XXX.., mountpoint+base_cgroup may be not exist - if (type == CGROUP2_SUPER_MAGIC) - writeable = test_writeable_v2(mountpoint, base_cgroup); - else - writeable = test_writeable_v1(mountpoint, base_cgroup); - if (!writeable) - goto next; -- -+ */ - if (type == CGROUP2_SUPER_MAGIC) { - char *cgv2_ctrl_path; - --- -1.8.3.1 - diff --git a/0086-confile-add-support-systemd.patch b/0046-add-support-systemd.patch similarity index 60% rename from 0086-confile-add-support-systemd.patch rename to 0046-add-support-systemd.patch index a80285067c71df64b45177078cf6b3aaa9e558e1..e43f20ece1da829f265f1e380b0e4c07d8859044 100644 --- a/0086-confile-add-support-systemd.patch +++ b/0046-add-support-systemd.patch @@ -1,24 +1,20 @@ -From 2b8bafa86e5086ee9f85dba13a73fb3abdf8656f Mon Sep 17 00:00:00 2001 +From 1922cc534f04a7a006064e7eae2dea44d0000cc3 Mon Sep 17 00:00:00 2001 From: tanyifeng Date: Sat, 20 Apr 2019 22:40:18 +0800 -Subject: [PATCH 086/140] confile: add support systemd - -lxc.isulad.systemd=true remount systemd cgroup path to rw +Subject: [PATCH 46/49] add support systemd Signed-off-by: zhangsong -Signed-off-by: LiFeng --- - src/lxc/cgroups/cgfsng.c | 16 ++++++++++++++++ + src/lxc/cgroups/cgfsng.c | 15 +++++++++++++++ src/lxc/conf.c | 1 + - src/lxc/conf.h | 1 + src/lxc/confile.c | 30 ++++++++++++++++++++++++++++++ - 4 files changed, 48 insertions(+) + 3 files changed, 46 insertions(+) diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index cc08737..b1f56b0 100644 +index 002f051..4abaa86 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c -@@ -1567,6 +1567,7 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, +@@ -2096,6 +2096,7 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, { int i, ret; char *tmpfspath = NULL; @@ -26,11 +22,10 @@ index cc08737..b1f56b0 100644 bool has_cgns = false, retval = false, wants_force_mount = false; char **merged = NULL; -@@ -1711,10 +1712,25 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, - goto on_error; +@@ -2242,10 +2243,24 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, } } -+ + + // isulad: remount /sys/fs/cgroup/systemd to readwrite for system container + if (handler->conf->systemd != NULL && strcmp(handler->conf->systemd, "true") == 0) { + systemdpath = must_make_path(root, "/sys/fs/cgroup/systemd", NULL); @@ -53,51 +48,39 @@ index cc08737..b1f56b0 100644 return retval; } diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 20eb840..8cdccf1 100644 +index d7a78bd..235965f 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c -@@ -5320,6 +5320,7 @@ void lxc_conf_free(struct lxc_conf *conf) - if (conf->exit_fd != -1) +@@ -5283,6 +5283,7 @@ void lxc_conf_free(struct lxc_conf *conf) + if (conf->exit_fd != -1) { close(conf->exit_fd); - free(conf->errmsg); + } + free(conf->systemd); - lxc_close_error_pipe(conf->errpipe); - /* isulad add end */ - free(conf); -diff --git a/src/lxc/conf.h b/src/lxc/conf.h -index 11cf596..fb3c156 100644 ---- a/src/lxc/conf.h -+++ b/src/lxc/conf.h -@@ -430,6 +430,7 @@ struct lxc_conf { - char *errmsg; /* record error messages */ - int errpipe[2];//pipdfd for get error message of child or grandchild process. - mode_t umask; //umask value -+ char *systemd; //systemd value - /* isulad add end */ - }; - + lxc_clear_init_args(conf); + lxc_clear_init_groups(conf); + lxc_clear_populate_devices(conf); diff --git a/src/lxc/confile.c b/src/lxc/confile.c -index 60e6c46..93936cc 100644 +index 8790494..771f635 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c -@@ -157,6 +157,7 @@ lxc_config_define(init_args); - lxc_config_define(init_groups); - lxc_config_define(populate_device); +@@ -154,6 +154,7 @@ lxc_config_define(populate_device); lxc_config_define(umask); + lxc_config_define(rootfs_masked_paths); + lxc_config_define(rootfs_ro_paths); +lxc_config_define(systemd); - /*isulad add end*/ + #endif - -@@ -251,6 +252,7 @@ static struct lxc_config_t config_jump_table[] = { + /* +@@ -274,6 +275,7 @@ static struct lxc_config_t config_jump_table[] = { + { "lxc.isulad.umask", set_config_umask, get_config_umask, clr_config_umask, }, { "lxc.isulad.rootfs.maskedpaths", set_config_rootfs_masked_paths, get_config_rootfs_masked_paths, clr_config_rootfs_masked_paths, }, { "lxc.isulad.rootfs.ropaths", set_config_rootfs_ro_paths, get_config_rootfs_ro_paths, clr_config_rootfs_ro_paths, }, - { "lxc.isulad.umask", set_config_umask, get_config_umask, clr_config_umask, }, + { "lxc.isulad.systemd", set_config_systemd, get_config_systemd, clr_config_systemd, }, - /*isulad add end*/ + #endif }; -@@ -2433,6 +2435,18 @@ static int set_config_umask(const char *key, const char *value, - } +@@ -6587,4 +6589,32 @@ static inline int clr_config_rootfs_ro_paths(const char *key, struct lxc_conf *c + return lxc_clear_rootfs_ro_paths(c); } +/* isulad: set config for systemd */ @@ -112,13 +95,6 @@ index 60e6c46..93936cc 100644 + return 0; +} + - struct parse_line_conf { - struct lxc_conf *conf; - bool from_include; -@@ -3210,6 +3224,13 @@ static int get_config_umask(const char *key, char *retv, int inlen, - return lxc_get_conf_size_t(c, retv, inlen, c->umask); - } - +/* isulad add: get systemd value*/ +static int get_config_systemd(const char *key, char *retv, int inlen, + struct lxc_conf *c, void *data) @@ -126,13 +102,6 @@ index 60e6c46..93936cc 100644 + return lxc_get_conf_str(retv, inlen, c->systemd); +} + - static int get_config_tty_dir(const char *key, char *retv, int inlen, - struct lxc_conf *c, void *data) - { -@@ -4491,6 +4512,15 @@ static inline int clr_config_umask(const char *key, struct lxc_conf *c, - return 0; - } - +/* isulad add: clear systemd value */ +static inline int clr_config_systemd(const char *key, struct lxc_conf *c, + void *data) @@ -142,9 +111,7 @@ index 60e6c46..93936cc 100644 + return 0; +} + - static int get_config_includefiles(const char *key, char *retv, int inlen, - struct lxc_conf *c, void *data) - { + #endif -- 1.8.3.1 diff --git a/0047-Fix-memory-leak-in-lxc_global_config_value.patch b/0047-Fix-memory-leak-in-lxc_global_config_value.patch deleted file mode 100644 index 4dc1792d1f93bca3119a1a31687a8b5d89e3b087..0000000000000000000000000000000000000000 --- a/0047-Fix-memory-leak-in-lxc_global_config_value.patch +++ /dev/null @@ -1,44 +0,0 @@ -From f238c892c331361985a2d8f0211b4fd78ce99682 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Thu, 17 Jan 2019 07:43:23 -0500 -Subject: [PATCH 047/140] Fix memory leak in lxc_global_config_value - -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgroup.c | 2 ++ - src/lxc/initutils.c | 5 ----- - 2 files changed, 2 insertions(+), 5 deletions(-) - -diff --git a/src/lxc/cgroups/cgroup.c b/src/lxc/cgroups/cgroup.c -index 720a6c9..8d559be 100644 ---- a/src/lxc/cgroups/cgroup.c -+++ b/src/lxc/cgroups/cgroup.c -@@ -95,6 +95,8 @@ void cgroup_exit(struct cgroup_ops *ops) - } - free(ops->hierarchies); - -+ free(ops); -+ - return; - } - -diff --git a/src/lxc/initutils.c b/src/lxc/initutils.c -index 09b521e..60147a5 100644 ---- a/src/lxc/initutils.c -+++ b/src/lxc/initutils.c -@@ -74,12 +74,7 @@ const char *lxc_global_config_value(const char *option_name) - { NULL, NULL }, - }; - -- /* placed in the thread local storage pool for non-bionic targets */ --#ifdef HAVE_TLS -- static thread_local const char *values[sizeof(options) / sizeof(options[0])] = {0}; --#else - static const char *values[sizeof(options) / sizeof(options[0])] = {0}; --#endif - - /* user_config_path is freed as soon as it is used */ - char *user_config_path = NULL; --- -1.8.3.1 - diff --git a/0091-lxc-support-namespaced-kernel-params-can-be-changed-.patch b/0047-support-namespaced-kernel-params-can-be-changed-in-s.patch similarity index 59% rename from 0091-lxc-support-namespaced-kernel-params-can-be-changed-.patch rename to 0047-support-namespaced-kernel-params-can-be-changed-in-s.patch index 02e1e7fcaf686104612c25417560c5be8b5cd2c6..efb6403002560d8346c20592dd1374c51818bd4f 100644 --- a/0091-lxc-support-namespaced-kernel-params-can-be-changed-.patch +++ b/0047-support-namespaced-kernel-params-can-be-changed-in-s.patch @@ -1,24 +1,23 @@ -From 140cadc75c14917c9d0aa3c6c65d84fd8b682adb Mon Sep 17 00:00:00 2001 +From 288b6934f79456f056a2043216bbfdde4342b694 Mon Sep 17 00:00:00 2001 From: liuhao Date: Fri, 26 Apr 2019 07:13:53 +0800 -Subject: [PATCH 091/140] lxc: support namespaced kernel params can be changed - in system container - -support namespaced kernel params can be changed in system container +Subject: [PATCH 47/49] support namespaced kernel params can be changed in + system container Signed-off-by: yangchenliang --- - src/lxc/conf.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 77 insertions(+) + src/lxc/conf.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 71 insertions(+) diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 14d5d80..0f227aa 100644 +index 235965f..15d8e42 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c -@@ -1516,6 +1516,66 @@ error: +@@ -1449,6 +1449,68 @@ error: return false; } ++#ifdef HAVE_ISULAD +static bool remount_readwrite(const char *path) +{ + int ret, i; @@ -54,13 +53,13 @@ index 14d5d80..0f227aa 100644 + return false; +} + -+static int remount_proc_sys_mount_entries(struct lxc_list *mount_list) ++static int remount_proc_sys_mount_entries(struct lxc_list *mount_list, bool lsm_aa_allow_nesting) +{ + char buf[4096]; + FILE *file; + struct mntent mntent; + -+ file = make_anonymous_mount_file(mount_list); ++ file = make_anonymous_mount_file(mount_list, lsm_aa_allow_nesting); + if (!file) + return -1; + @@ -78,41 +77,27 @@ index 14d5d80..0f227aa 100644 + fclose(file); + return 0; +} ++#endif + // remount_readonly will bind over the top of an existing path and ensure that it is read-only. static bool remount_readonly(const char *path) { -@@ -2699,6 +2759,13 @@ static int mount_file_entries(const struct lxc_conf *conf, - int ret = -1; - - while (getmntent_r(file, &mntent, buf, sizeof(buf))) { -+ //isulad, system contaienr, skip "proc/sys/xxx" path -+ if (conf->systemd != NULL && strcmp(conf->systemd, "true") == 0) { -+ if (strstr(mntent.mnt_dir, "proc/sys") != NULL) { -+ continue; -+ } -+ } -+ - /* Note: Workaround for volume file path with space*/ - mntent.mnt_fsname = lxc_string_replace(SPACE_MAGIC_STR, " ", mntent.mnt_fsname); - if(!mntent.mnt_fsname) { -@@ -4254,6 +4321,16 @@ int lxc_setup(struct lxc_handler *handler) +@@ -4773,6 +4835,15 @@ int lxc_setup(struct lxc_handler *handler) } } + //isulad: system container, remount /proc/sys/xxx by mount_list + if (lxc_conf->systemd != NULL && strcmp(lxc_conf->systemd, "true") == 0) { + if (!lxc_list_empty(&lxc_conf->mount_list)) { -+ if (remount_proc_sys_mount_entries(&lxc_conf->mount_list)) { -+ ERROR("failed to remount /proc/sys"); -+ goto on_error; ++ if (remount_proc_sys_mount_entries(&lxc_conf->mount_list, lxc_conf->lsm_aa_allow_nesting)) { ++ return log_error(-1, "failed to remount /proc/sys"); + } + } + } + - if (!lxc_list_empty(&lxc_conf->keepcaps)) { - if (!lxc_list_empty(&lxc_conf->caps)) { - ERROR("Container requests lxc.cap.drop and " + // isulad: create link /etc/mtab for /proc/mounts + if (create_mtab_link() != 0) { + return log_error(-1, "failed to create link /etc/mtab for target /proc/mounts"); -- 1.8.3.1 diff --git a/0048-clear-ONLCR-flag-from-master-of-terminal.patch b/0048-clear-ONLCR-flag-from-master-of-terminal.patch deleted file mode 100644 index 8ce255b43dc764b7a490ad2a8cdf49b32c302079..0000000000000000000000000000000000000000 --- a/0048-clear-ONLCR-flag-from-master-of-terminal.patch +++ /dev/null @@ -1,59 +0,0 @@ -From fc95cef9efded165758645b8f04da7c0ffd6b762 Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Thu, 17 Jan 2019 20:46:33 +0800 -Subject: [PATCH 048/140] clear ONLCR flag from master of terminal - -clear ONLCR flag from master of terminal - -Signed-off-by: liuhao -Signed-off-by: LiFeng ---- - src/lxc/terminal.c | 25 +++++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - -diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index a33830d..95140e0 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -1066,6 +1066,24 @@ static int lxc_terminal_fifo_default(struct lxc_terminal *terminal) - return lxc_terminal_set_fifo(terminal, terminal->init_fifo[0], terminal->init_fifo[1]); - } - -+/* -+ * isulad: disable (XSI) Map NL to CR-NL on output. -+ * */ -+static int use_unix_newline(int master_fd) -+{ -+ struct termios oldtios; -+ int ret; -+ -+ ret = tcgetattr(master_fd, &oldtios); -+ if (ret < 0) -+ return -1; -+ oldtios.c_oflag &= ~ONLCR; -+ ret = tcsetattr(master_fd, TCSAFLUSH, &oldtios); -+ if (ret < 0) -+ return -1; -+ return 0; -+} -+ - int lxc_terminal_create(struct lxc_terminal *terminal) - { - int ret; -@@ -1082,6 +1100,13 @@ int lxc_terminal_create(struct lxc_terminal *terminal) - goto err; - } - -+ /* isulad: clear ONLCR flag */ -+ ret = use_unix_newline(terminal->master); -+ if (ret < 0) { -+ SYSERROR("Failed to clear ONLCR flag on terminal master"); -+ goto err; -+ } -+ - ret = fd_cloexec(terminal->master, true); - if (ret < 0) { - SYSERROR("Failed to set FD_CLOEXEC flag on terminal master"); --- -1.8.3.1 - diff --git a/0095-lxc-don-t-use-the-unified-hierarchy-for-the-systemd-.patch b/0048-don-t-use-the-unified-hierarchy-for-the-systemd-cgro.patch similarity index 79% rename from 0095-lxc-don-t-use-the-unified-hierarchy-for-the-systemd-.patch rename to 0048-don-t-use-the-unified-hierarchy-for-the-systemd-cgro.patch index b5a550e7f3f3b9f42112a4358f0eaa37ea2c5dcd..aab73c39f6e6005d5e62f3bafe4565368477e5bf 100644 --- a/0095-lxc-don-t-use-the-unified-hierarchy-for-the-systemd-.patch +++ b/0048-don-t-use-the-unified-hierarchy-for-the-systemd-cgro.patch @@ -1,22 +1,18 @@ -From 724ce7ab5bf6dd83ee034d13b2d60515632e1d67 Mon Sep 17 00:00:00 2001 +From 4dfcafd037464a64047b70ffea3b91a70514ae92 Mon Sep 17 00:00:00 2001 From: liuhao Date: Fri, 10 May 2019 11:05:42 +0800 -Subject: [PATCH 095/140] lxc: don't use the unified hierarchy for the systemd - cgroup - -reason:don't use the unified hierarchy for the systemd cgroup +Subject: [PATCH 48/49] don't use the unified hierarchy for the systemd cgroup Signed-off-by: zhangsong -Signed-off-by: LiFeng --- src/lxc/cgroups/cgfsng.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index 2bf142f..eee7ed6 100644 +index 4abaa86..4a0961f 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c -@@ -1571,6 +1571,7 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, +@@ -2097,6 +2097,7 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, int i, ret; char *tmpfspath = NULL; char *systemdpath = NULL; @@ -24,7 +20,7 @@ index 2bf142f..eee7ed6 100644 bool has_cgns = false, retval = false, wants_force_mount = false; char **merged = NULL; -@@ -1718,6 +1719,16 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, +@@ -2245,6 +2246,16 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, // isulad: remount /sys/fs/cgroup/systemd to readwrite for system container if (handler->conf->systemd != NULL && strcmp(handler->conf->systemd, "true") == 0) { @@ -41,7 +37,7 @@ index 2bf142f..eee7ed6 100644 systemdpath = must_make_path(root, "/sys/fs/cgroup/systemd", NULL); ret = mount(systemdpath, systemdpath, "bind", MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_RELATIME|MS_BIND|MS_REMOUNT, NULL); -@@ -1734,6 +1745,9 @@ on_error: +@@ -2261,6 +2272,9 @@ on_error: if (systemdpath != NULL) { free(systemdpath); } diff --git a/0049-Add-100ms-timeout-for-console-epoll.patch b/0049-Add-100ms-timeout-for-console-epoll.patch deleted file mode 100644 index 813462e3852420aaf3a2810177876f9870aa36b5..0000000000000000000000000000000000000000 --- a/0049-Add-100ms-timeout-for-console-epoll.patch +++ /dev/null @@ -1,28 +0,0 @@ -From c144ed16a5a45c8dc2873bbb1016d8bc1fc02a9c Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Sat, 19 Jan 2019 02:05:17 -0500 -Subject: [PATCH 049/140] Add 100ms timeout for console epoll - -add 100ms timeout for console epoll to avoid lose console - -Signed-off-by: LiFeng ---- - src/lxc/start.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/lxc/start.c b/src/lxc/start.c -index 7bbcb00..daf2af4 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -643,7 +643,7 @@ int lxc_poll(const char *name, struct lxc_handler *handler) - goto out_mainloop_console; - - if (has_console) -- ret = lxc_mainloop(&descr_console, 0); -+ ret = lxc_mainloop(&descr_console, 100); - - out_mainloop_console: - if (has_console) { --- -1.8.3.1 - diff --git a/0049-make-dev-bind-mount-from-host-tmpfs-for-system-conta.patch b/0049-make-dev-bind-mount-from-host-tmpfs-for-system-conta.patch new file mode 100644 index 0000000000000000000000000000000000000000..1d10ca4a62f8436a356633855aa97c64490cb646 --- /dev/null +++ b/0049-make-dev-bind-mount-from-host-tmpfs-for-system-conta.patch @@ -0,0 +1,99 @@ +From e1e3ad7bc7cb1a26cca676ff5e4a5ceaf7eedaee Mon Sep 17 00:00:00 2001 +From: tanyifeng +Date: Wed, 15 May 2019 12:42:08 +0800 +Subject: [PATCH 49/49] make /dev bind mount from host tmpfs for system + container + +Signed-off-by: zhangsong +--- + src/lxc/conf.c | 33 +++++++++++++++++++++++++++++++-- + 1 file changed, 31 insertions(+), 2 deletions(-) + +diff --git a/src/lxc/conf.c b/src/lxc/conf.c +index 15d8e42..4d8fa2a 100644 +--- a/src/lxc/conf.c ++++ b/src/lxc/conf.c +@@ -1074,8 +1074,13 @@ on_error: + /* Just create a path for /dev under $lxcpath/$name and in rootfs If we hit an + * error, log it but don't fail yet. + */ ++#ifdef HAVE_ISULAD ++static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs, ++ int autodevtmpfssize, const char *lxcpath, char *systemd) ++#else + static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs, + int autodevtmpfssize, const char *lxcpath) ++#endif + { + __do_free char *path = NULL; + int ret; +@@ -1088,6 +1093,7 @@ static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs, + /* $(rootfs->mount) + "/dev/pts" + '\0' */ + clen = (rootfs->path ? strlen(rootfs->mount) : 0) + 9; + path = must_realloc(NULL, clen); ++ + sprintf(mount_options, "size=%d,mode=755", (autodevtmpfssize != 0) ? autodevtmpfssize : 500000); + DEBUG("Using mount options: %s", mount_options); + +@@ -1103,6 +1109,23 @@ static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs, + goto reset_umask; + } + ++#ifdef HAVE_ISULAD ++ if (systemd != NULL && !strcmp(systemd, "true")) { ++ ret = mount(path, path, "", MS_BIND, NULL); ++ if (ret < 0) { ++ SYSERROR("Failed to bind mount path \"%s\"", path); ++ goto reset_umask; ++ } ++ } else { ++ ret = safe_mount("none", path, "tmpfs", 0, mount_options, ++ rootfs->path ? rootfs->mount : NULL); ++ if (ret < 0) { ++ SYSERROR("Failed to mount tmpfs on \"%s\"", path); ++ goto reset_umask; ++ } ++ TRACE("Mounted tmpfs on \"%s\"", path); ++ } ++#else + ret = safe_mount("none", path, "tmpfs", 0, mount_options, + rootfs->path ? rootfs->mount : NULL ); + if (ret < 0) { +@@ -1110,6 +1133,7 @@ static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs, + goto reset_umask; + } + TRACE("Mounted tmpfs on \"%s\"", path); ++#endif + + ret = snprintf(path, clen, "%s/dev/pts", rootfs->path ? rootfs->mount : ""); + if (ret < 0 || (size_t)ret >= clen) { +@@ -4674,7 +4698,11 @@ int lxc_setup(struct lxc_handler *handler) + } + + if (lxc_conf->autodev > 0) { ++#ifdef HAVE_ISULAD ++ ret = mount_autodev(name, &lxc_conf->rootfs, lxc_conf->autodevtmpfssize, lxcpath, lxc_conf->systemd); ++#else + ret = mount_autodev(name, &lxc_conf->rootfs, lxc_conf->autodevtmpfssize, lxcpath); ++#endif + if (ret < 0) + return log_error(-1, "Failed to mount \"/dev\""); + } +@@ -4838,11 +4866,12 @@ int lxc_setup(struct lxc_handler *handler) + //isulad: system container, remount /proc/sys/xxx by mount_list + if (lxc_conf->systemd != NULL && strcmp(lxc_conf->systemd, "true") == 0) { + if (!lxc_list_empty(&lxc_conf->mount_list)) { +- if (remount_proc_sys_mount_entries(&lxc_conf->mount_list, lxc_conf->lsm_aa_allow_nesting)) { ++ if (remount_proc_sys_mount_entries(&lxc_conf->mount_list, ++ lxc_conf->lsm_aa_allow_nesting)) { + return log_error(-1, "failed to remount /proc/sys"); + } + } +- } ++ } + + // isulad: create link /etc/mtab for /proc/mounts + if (create_mtab_link() != 0) { +-- +1.8.3.1 + diff --git a/0050-clean-add-init-fd-in-lxc_init_clean_handler.patch b/0050-clean-add-init-fd-in-lxc_init_clean_handler.patch new file mode 100644 index 0000000000000000000000000000000000000000..82db29897e80253d7619ea1fb90d75c8884c08d8 --- /dev/null +++ b/0050-clean-add-init-fd-in-lxc_init_clean_handler.patch @@ -0,0 +1,27 @@ +From d15c6e2871202d8d8b928a4b4e11537997c24fc1 Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Thu, 16 Apr 2020 21:39:19 +0800 +Subject: [PATCH] clean: add init fd in lxc_init_clean_handler + +Signed-off-by: LiFeng +--- + src/lxc/start.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/lxc/start.c b/src/lxc/start.c +index 5d2faee..938ca8e 100644 +--- a/src/lxc/start.c ++++ b/src/lxc/start.c +@@ -2913,7 +2913,9 @@ static struct lxc_handler *lxc_init_clean_handler(char *name, char *lxcpath, str + handler->lxcpath = lxcpath; + handler->pinfd = -1; + handler->sigfd = -EBADF; ++ handler->pidfd = -EBADF; + handler->init_died = false; ++ handler->monitor_status_fd = -EBADF; + handler->pid = pid; + handler->state_socket_pair[0] = handler->state_socket_pair[1] = -1; + if (handler->conf->reboot == REBOOT_NONE) +-- +1.8.3.1 + diff --git a/0050-seccomp-add-rules-for-specified-architecture-only.patch b/0050-seccomp-add-rules-for-specified-architecture-only.patch deleted file mode 100644 index 1291f691b7ed25c0ba350e3c5ad77de5efe55c6a..0000000000000000000000000000000000000000 --- a/0050-seccomp-add-rules-for-specified-architecture-only.patch +++ /dev/null @@ -1,408 +0,0 @@ -From 15d3b1e6c5e5ac896b15d04d486ba0c04ca39336 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Fri, 18 Jan 2019 02:11:11 -0500 -Subject: [PATCH 050/140] seccomp: add rules for specified architecture only - -LXC MR: https://github.com/lxc/lxc/pull/2786 - -Signed-off-by: LiFeng ---- - src/lxc/seccomp.c | 234 ++++++++++++++++++++++++++++++------------------------ - 1 file changed, 132 insertions(+), 102 deletions(-) - -diff --git a/src/lxc/seccomp.c b/src/lxc/seccomp.c -index 27bdc22..4a9143b 100644 ---- a/src/lxc/seccomp.c -+++ b/src/lxc/seccomp.c -@@ -291,7 +291,7 @@ on_error: - #endif - - #if HAVE_DECL_SECCOMP_SYSCALL_RESOLVE_NAME_ARCH --enum lxc_hostarch_t { -+enum lxc_arch_t { - lxc_seccomp_arch_all = 0, - lxc_seccomp_arch_native, - lxc_seccomp_arch_i386, -@@ -345,8 +345,8 @@ int get_hostarch(void) - return lxc_seccomp_arch_unknown; - } - --scmp_filter_ctx get_new_ctx(enum lxc_hostarch_t n_arch, -- uint32_t default_policy_action, bool *needs_merge) -+scmp_filter_ctx get_new_ctx(enum lxc_arch_t n_arch, -+ uint32_t default_policy_action) - { - int ret; - uint32_t arch; -@@ -464,10 +464,7 @@ scmp_filter_ctx get_new_ctx(enum lxc_hostarch_t n_arch, - return NULL; - } - TRACE("Removed native arch from main seccomp context"); -- -- *needs_merge = true; - } else { -- *needs_merge = false; - TRACE("Arch %d already present in main seccomp context", (int)n_arch); - } - -@@ -550,6 +547,27 @@ bool do_resolve_add_rule(uint32_t arch, char *line, scmp_filter_ctx ctx, - return true; - } - -+#define SCMP_ARCH_INDEX_MAX 3 -+ -+struct scmp_ctx_info { -+ uint32_t architectures[SCMP_ARCH_INDEX_MAX]; -+ enum lxc_arch_t lxc_arch[SCMP_ARCH_INDEX_MAX]; -+ scmp_filter_ctx contexts[SCMP_ARCH_INDEX_MAX]; -+ bool needs_merge[SCMP_ARCH_INDEX_MAX]; -+}; -+ -+static int get_arch_index(enum lxc_arch_t arch, struct scmp_ctx_info *ctx) -+{ -+ int i; -+ -+ for (i = 0; i < SCMP_ARCH_INDEX_MAX; i++) { -+ if (ctx->lxc_arch[i] == arch) -+ return i; -+ } -+ -+ return -1; -+} -+ - /* - * v2 consists of - * [x86] -@@ -568,15 +586,11 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c - { - int ret; - char *p; -- enum lxc_hostarch_t cur_rule_arch, native_arch; -+ enum lxc_arch_t cur_rule_arch, native_arch; - bool blacklist = false; - uint32_t default_policy_action = -1, default_rule_action = -1; - struct seccomp_v2_rule rule; -- struct scmp_ctx_info { -- uint32_t architectures[3]; -- scmp_filter_ctx contexts[3]; -- bool needs_merge[3]; -- } ctx; -+ struct scmp_ctx_info ctx; - - if (strncmp(line, "blacklist", 9) == 0) - blacklist = true; -@@ -617,23 +631,23 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c - cur_rule_arch = lxc_seccomp_arch_all; - - ctx.architectures[0] = SCMP_ARCH_X86; -+ ctx.lxc_arch[0] = lxc_seccomp_arch_i386; - ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_i386, -- default_policy_action, -- &ctx.needs_merge[0]); -+ default_policy_action); - if (!ctx.contexts[0]) - goto bad; - - ctx.architectures[1] = SCMP_ARCH_X32; -+ ctx.lxc_arch[1] = lxc_seccomp_arch_x32; - ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_x32, -- default_policy_action, -- &ctx.needs_merge[1]); -+ default_policy_action); - if (!ctx.contexts[1]) - goto bad; - - ctx.architectures[2] = SCMP_ARCH_X86_64; -+ ctx.lxc_arch[2] = lxc_seccomp_arch_amd64; - ctx.contexts[2] = get_new_ctx(lxc_seccomp_arch_amd64, -- default_policy_action, -- &ctx.needs_merge[2]); -+ default_policy_action); - if (!ctx.contexts[2]) - goto bad; - #ifdef SCMP_ARCH_PPC -@@ -641,17 +655,17 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c - cur_rule_arch = lxc_seccomp_arch_all; - - ctx.architectures[0] = SCMP_ARCH_PPC; -+ ctx.lxc_arch[0] = lxc_seccomp_arch_ppc; - ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_ppc, -- default_policy_action, -- &ctx.needs_merge[0]); -+ default_policy_action); - if (!ctx.contexts[0]) - goto bad; - -- ctx.architectures[2] = SCMP_ARCH_PPC64; -- ctx.contexts[2] = get_new_ctx(lxc_seccomp_arch_ppc64, -- default_policy_action, -- &ctx.needs_merge[2]); -- if (!ctx.contexts[2]) -+ ctx.architectures[1] = SCMP_ARCH_PPC64; -+ ctx.lxc_arch[1] = lxc_seccomp_arch_ppc64; -+ ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_ppc64, -+ default_policy_action); -+ if (!ctx.contexts[1]) - goto bad; - #endif - #ifdef SCMP_ARCH_ARM -@@ -659,18 +673,18 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c - cur_rule_arch = lxc_seccomp_arch_all; - - ctx.architectures[0] = SCMP_ARCH_ARM; -+ ctx.lxc_arch[0] = lxc_seccomp_arch_arm; - ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_arm, -- default_policy_action, -- &ctx.needs_merge[0]); -+ default_policy_action); - if (!ctx.contexts[0]) - goto bad; - - #ifdef SCMP_ARCH_AARCH64 -- ctx.architectures[2] = SCMP_ARCH_AARCH64; -- ctx.contexts[2] = get_new_ctx(lxc_seccomp_arch_arm64, -- default_policy_action, -- &ctx.needs_merge[2]); -- if (!ctx.contexts[2]) -+ ctx.architectures[1] = SCMP_ARCH_AARCH64; -+ ctx.lxc_arch[1] = lxc_seccomp_arch_arm64; -+ ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_arm64, -+ default_policy_action); -+ if (!ctx.contexts[1]) - goto bad; - #endif - #endif -@@ -679,46 +693,46 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c - cur_rule_arch = lxc_seccomp_arch_all; - - ctx.architectures[0] = SCMP_ARCH_MIPS; -+ ctx.lxc_arch[0] = lxc_seccomp_arch_mips; - ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_mips, -- default_policy_action, -- &ctx.needs_merge[0]); -+ default_policy_action); - if (!ctx.contexts[0]) - goto bad; - - ctx.architectures[1] = SCMP_ARCH_MIPS64N32; -+ ctx.lxc_arch[1] = lxc_seccomp_arch_mips64n32; - ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_mips64n32, -- default_policy_action, -- &ctx.needs_merge[1]); -+ default_policy_action); - if (!ctx.contexts[1]) - goto bad; - - ctx.architectures[2] = SCMP_ARCH_MIPS64; -+ ctx.lxc_arch[2] = lxc_seccomp_arch_mips64; - ctx.contexts[2] = get_new_ctx(lxc_seccomp_arch_mips64, -- default_policy_action, -- &ctx.needs_merge[2]); -+ default_policy_action); - if (!ctx.contexts[2]) - goto bad; - } else if (native_arch == lxc_seccomp_arch_mipsel64) { - cur_rule_arch = lxc_seccomp_arch_all; - - ctx.architectures[0] = SCMP_ARCH_MIPSEL; -+ ctx.lxc_arch[0] = lxc_seccomp_arch_mipsel; - ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_mipsel, -- default_policy_action, -- &ctx.needs_merge[0]); -+ default_policy_action); - if (!ctx.contexts[0]) - goto bad; - - ctx.architectures[1] = SCMP_ARCH_MIPSEL64N32; -+ ctx.lxc_arch[1] = lxc_seccomp_arch_mipsel64n32; - ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_mipsel64n32, -- default_policy_action, -- &ctx.needs_merge[1]); -+ default_policy_action); - if (!ctx.contexts[1]) - goto bad; - - ctx.architectures[2] = SCMP_ARCH_MIPSEL64; -+ ctx.lxc_arch[2] = lxc_seccomp_arch_mipsel64; - ctx.contexts[2] = get_new_ctx(lxc_seccomp_arch_mipsel64, -- default_policy_action, -- &ctx.needs_merge[2]); -+ default_policy_action); - if (!ctx.contexts[2]) - goto bad; - #endif -@@ -928,97 +942,113 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c - goto bad_rule; - } - -- if (!do_resolve_add_rule(SCMP_ARCH_NATIVE, line, -- conf->seccomp_ctx, &rule)) -- goto bad_rule; -+ if (cur_rule_arch == native_arch) { -+ if (!do_resolve_add_rule(SCMP_ARCH_NATIVE, line, -+ conf->seccomp_ctx, &rule)) -+ goto bad_rule; -+ -+ INFO("Added native rule for arch %d for %s action %d(%s)", -+ SCMP_ARCH_NATIVE, line, rule.action, -+ get_action_name(rule.action)); -+ } else if (cur_rule_arch != lxc_seccomp_arch_all) { -+ int arch_index = get_arch_index(cur_rule_arch, &ctx); -+ if (arch_index < 0) -+ goto bad_arch; - -- INFO("Added native rule for arch %d for %s action %d(%s)", -- SCMP_ARCH_NATIVE, line, rule.action, -- get_action_name(rule.action)); -+ if (!do_resolve_add_rule(ctx.architectures[arch_index], line, -+ ctx.contexts[arch_index], &rule)) -+ goto bad_rule; - -- if (cur_rule_arch == lxc_seccomp_arch_all) { -+ INFO("Added compat rule for arch %d for %s action %d(%s)", -+ ctx.architectures[arch_index], line, rule.action, -+ get_action_name(rule.action)); -+ ctx.needs_merge[arch_index] = true; -+ } else { - if (ctx.architectures[0] != SCMP_ARCH_NATIVE) { - if (!do_resolve_add_rule(ctx.architectures[0], line, -- ctx.contexts[0], &rule)) -+ ctx.contexts[0], &rule)) - goto bad_rule; - -- INFO("Added compat rule for arch %d for %s action %d(%s)", -- ctx.architectures[0], line, rule.action, -- get_action_name(rule.action)); -+ INFO("Added compat rule for arch %d for %s action %d(%s)", -+ ctx.architectures[0], line, rule.action, -+ get_action_name(rule.action)); -+ ctx.needs_merge[0] = true; - } - - if (ctx.architectures[1] != SCMP_ARCH_NATIVE) { - if (!do_resolve_add_rule(ctx.architectures[1], line, -- ctx.contexts[1], &rule)) -+ ctx.contexts[1], &rule)) - goto bad_rule; - - INFO("Added compat rule for arch %d for %s action %d(%s)", -- ctx.architectures[1], line, rule.action, -- get_action_name(rule.action)); -+ ctx.architectures[1], line, rule.action, -+ get_action_name(rule.action)); -+ ctx.needs_merge[1] = true; - } - - if (ctx.architectures[2] != SCMP_ARCH_NATIVE) { - if (!do_resolve_add_rule(ctx.architectures[2], line, -- ctx.contexts[2], &rule)) -+ ctx.contexts[2], &rule)) - goto bad_rule; - - INFO("Added native rule for arch %d for %s action %d(%s)", -- ctx.architectures[2], line, rule.action, -- get_action_name(rule.action)); -+ ctx.architectures[2], line, rule.action, -+ get_action_name(rule.action)); -+ ctx.needs_merge[2] = true; - } - } -- } - -- if (cur_rule_arch == lxc_seccomp_arch_all) { -- INFO("Merging compat seccomp contexts into main context"); -- if (ctx.contexts[0]) { -- if (ctx.needs_merge[0]) { -- ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[0]); -- if (ret < 0) { -- ERROR("Failed to merge first compat seccomp " -- "context into main context"); -- goto bad; -- } -+ } - -- TRACE("Merged first compat seccomp context into main context"); -- } else { -- seccomp_release(ctx.contexts[0]); -- ctx.contexts[0] = NULL; -+ INFO("Merging compat seccomp contexts into main context"); -+ if (ctx.contexts[0]) { -+ if (ctx.needs_merge[0]) { -+ ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[0]); -+ if (ret < 0) { -+ ERROR("%s - Failed to merge first compat seccomp " -+ "context into main context", strerror(-ret)); -+ goto bad; - } -- } - -- if (ctx.contexts[1]) { -- if (ctx.needs_merge[1]) { -- ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[1]); -- if (ret < 0) { -- ERROR("Failed to merge first compat seccomp " -- "context into main context"); -- goto bad; -- } -+ TRACE("Merged first compat seccomp context into main context"); -+ } else { -+ seccomp_release(ctx.contexts[0]); -+ ctx.contexts[0] = NULL; -+ } -+ } - -- TRACE("Merged second compat seccomp context into main context"); -- } else { -- seccomp_release(ctx.contexts[1]); -- ctx.contexts[1] = NULL; -+ if (ctx.contexts[1]) { -+ if (ctx.needs_merge[1]) { -+ ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[1]); -+ if (ret < 0) { -+ ERROR("%s - Failed to merge second compat seccomp " -+ "context into main context", strerror(-ret)); -+ goto bad; - } -- } - -- if (ctx.contexts[2]) { -- if (ctx.needs_merge[2]) { -- ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[2]); -- if (ret < 0) { -- ERROR("Failed to merge third compat seccomp " -- "context into main context"); -- goto bad; -- } -+ TRACE("Merged second compat seccomp context into main context"); -+ } else { -+ seccomp_release(ctx.contexts[1]); -+ ctx.contexts[1] = NULL; -+ } -+ } - -- TRACE("Merged third compat seccomp context into main context"); -- } else { -- seccomp_release(ctx.contexts[2]); -- ctx.contexts[2] = NULL; -+ if (ctx.contexts[2]) { -+ if (ctx.needs_merge[2]) { -+ ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[2]); -+ if (ret < 0) { -+ ERROR("%s - Failed to merge third compat seccomp " -+ "context into main context", strerror(-ret)); -+ goto bad; - } -+ -+ TRACE("Merged third compat seccomp context into main context"); -+ } else { -+ seccomp_release(ctx.contexts[2]); -+ ctx.contexts[2] = NULL; - } - } -+ - free(line); - return 0; - --- -1.8.3.1 - diff --git a/0051-if-ocihook-is-empty.patch b/0051-if-ocihook-is-empty.patch deleted file mode 100644 index 71079f9fbe5c5740889df4b59b9f11052366d52c..0000000000000000000000000000000000000000 --- a/0051-if-ocihook-is-empty.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 629036e2732ed24c776b422271cef51cf8458f18 Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Tue, 22 Jan 2019 11:25:45 +0800 -Subject: [PATCH 051/140] if ocihook is empty - -return success - -Signed-off-by: liuhao -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 48e31af..6ea8f9c 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4782,9 +4782,12 @@ static int run_oci_hooks(const char *name, const char *lxcpath, struct lxc_conf - int ret = 0; - char *rootpath; - -- if (!lc || !lc->ocihooks) { -+ if (!lc) { - return -1; - } -+ if (!lc->ocihooks) { -+ return 0; -+ } - - rootpath = get_root_path(lc->rootfs.path, lc->rootfs.bdev_type); - if (!rootpath) { --- -1.8.3.1 - diff --git a/0051-init-pids-add-init-fd-in-lxc_init_pids_handler.patch b/0051-init-pids-add-init-fd-in-lxc_init_pids_handler.patch new file mode 100644 index 0000000000000000000000000000000000000000..8fceaa587c8543cb2628f55f0fee813693ffc081 --- /dev/null +++ b/0051-init-pids-add-init-fd-in-lxc_init_pids_handler.patch @@ -0,0 +1,26 @@ +From 3931e7ef88aa2a8a67ca967ad1fe359df736ac86 Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Thu, 16 Apr 2020 22:15:30 +0800 +Subject: [PATCH] init pids: add init fd in lxc_init_pids_handler + +Signed-off-by: LiFeng +--- + src/lxc/start.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/lxc/start.c b/src/lxc/start.c +index 938ca8e..e099285 100644 +--- a/src/lxc/start.c ++++ b/src/lxc/start.c +@@ -2967,6 +2967,8 @@ static struct lxc_handler *lxc_init_pids_handler(char *name, char *lxcpath, stru + handler->sigfd = -EBADF; + handler->init_died = false; + handler->state_socket_pair[0] = handler->state_socket_pair[1] = -1; ++ handler->monitor_status_fd = -EBADF; ++ handler->pidfd = -EBADF; + if (handler->conf->reboot == REBOOT_NONE) + lxc_list_init(&handler->conf->state_clients); + +-- +1.8.3.1 + diff --git a/0052-Fix-seccomp-fail-when-all-specified-in-config.patch b/0052-Fix-seccomp-fail-when-all-specified-in-config.patch deleted file mode 100644 index 4df5788fa41e9e73c7fac589a6663cedc0b878d7..0000000000000000000000000000000000000000 --- a/0052-Fix-seccomp-fail-when-all-specified-in-config.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 2fbc0027a81a8ec79008afeb5298f5ec99203ea4 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Mon, 21 Jan 2019 23:28:43 -0500 -Subject: [PATCH 052/140] Fix seccomp fail when [all] specified in config - -Signed-off-by: LiFeng ---- - src/lxc/seccomp.c | 56 +++++++++++++++++++++++++++---------------------------- - 1 file changed, 28 insertions(+), 28 deletions(-) - -diff --git a/src/lxc/seccomp.c b/src/lxc/seccomp.c -index 4a9143b..3218a60 100644 ---- a/src/lxc/seccomp.c -+++ b/src/lxc/seccomp.c -@@ -346,7 +346,7 @@ int get_hostarch(void) - } - - scmp_filter_ctx get_new_ctx(enum lxc_arch_t n_arch, -- uint32_t default_policy_action) -+ uint32_t default_policy_action, uint32_t *architectures) - { - int ret; - uint32_t arch; -@@ -464,8 +464,10 @@ scmp_filter_ctx get_new_ctx(enum lxc_arch_t n_arch, - return NULL; - } - TRACE("Removed native arch from main seccomp context"); -+ *architectures = arch; - } else { - TRACE("Arch %d already present in main seccomp context", (int)n_arch); -+ *architectures = SCMP_ARCH_NATIVE; - } - - return ctx; -@@ -630,41 +632,36 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c - if (native_arch == lxc_seccomp_arch_amd64) { - cur_rule_arch = lxc_seccomp_arch_all; - -- ctx.architectures[0] = SCMP_ARCH_X86; - ctx.lxc_arch[0] = lxc_seccomp_arch_i386; - ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_i386, -- default_policy_action); -+ default_policy_action, &ctx.architectures[0]); - if (!ctx.contexts[0]) - goto bad; - -- ctx.architectures[1] = SCMP_ARCH_X32; - ctx.lxc_arch[1] = lxc_seccomp_arch_x32; - ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_x32, -- default_policy_action); -+ default_policy_action, &ctx.architectures[1]); - if (!ctx.contexts[1]) - goto bad; - -- ctx.architectures[2] = SCMP_ARCH_X86_64; - ctx.lxc_arch[2] = lxc_seccomp_arch_amd64; - ctx.contexts[2] = get_new_ctx(lxc_seccomp_arch_amd64, -- default_policy_action); -+ default_policy_action, &ctx.architectures[2]); - if (!ctx.contexts[2]) - goto bad; - #ifdef SCMP_ARCH_PPC - } else if (native_arch == lxc_seccomp_arch_ppc64) { - cur_rule_arch = lxc_seccomp_arch_all; - -- ctx.architectures[0] = SCMP_ARCH_PPC; - ctx.lxc_arch[0] = lxc_seccomp_arch_ppc; - ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_ppc, -- default_policy_action); -+ default_policy_action, &ctx.architectures[0]); - if (!ctx.contexts[0]) - goto bad; - -- ctx.architectures[1] = SCMP_ARCH_PPC64; - ctx.lxc_arch[1] = lxc_seccomp_arch_ppc64; - ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_ppc64, -- default_policy_action); -+ default_policy_action, &ctx.architectures[1]); - if (!ctx.contexts[1]) - goto bad; - #endif -@@ -672,18 +669,16 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c - } else if (native_arch == lxc_seccomp_arch_arm64) { - cur_rule_arch = lxc_seccomp_arch_all; - -- ctx.architectures[0] = SCMP_ARCH_ARM; - ctx.lxc_arch[0] = lxc_seccomp_arch_arm; - ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_arm, -- default_policy_action); -+ default_policy_action, &ctx.architectures[0]); - if (!ctx.contexts[0]) - goto bad; - - #ifdef SCMP_ARCH_AARCH64 -- ctx.architectures[1] = SCMP_ARCH_AARCH64; - ctx.lxc_arch[1] = lxc_seccomp_arch_arm64; - ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_arm64, -- default_policy_action); -+ default_policy_action, &ctx.architectures[1]); - if (!ctx.contexts[1]) - goto bad; - #endif -@@ -692,47 +687,41 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c - } else if (native_arch == lxc_seccomp_arch_mips64) { - cur_rule_arch = lxc_seccomp_arch_all; - -- ctx.architectures[0] = SCMP_ARCH_MIPS; - ctx.lxc_arch[0] = lxc_seccomp_arch_mips; - ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_mips, -- default_policy_action); -+ default_policy_action, &ctx.architectures[0]); - if (!ctx.contexts[0]) - goto bad; - -- ctx.architectures[1] = SCMP_ARCH_MIPS64N32; - ctx.lxc_arch[1] = lxc_seccomp_arch_mips64n32; - ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_mips64n32, -- default_policy_action); -+ default_policy_action, &ctx.architectures[1]); - if (!ctx.contexts[1]) - goto bad; - -- ctx.architectures[2] = SCMP_ARCH_MIPS64; - ctx.lxc_arch[2] = lxc_seccomp_arch_mips64; - ctx.contexts[2] = get_new_ctx(lxc_seccomp_arch_mips64, -- default_policy_action); -+ default_policy_action, &ctx.architectures[2]); - if (!ctx.contexts[2]) - goto bad; - } else if (native_arch == lxc_seccomp_arch_mipsel64) { - cur_rule_arch = lxc_seccomp_arch_all; -- -- ctx.architectures[0] = SCMP_ARCH_MIPSEL; -+; - ctx.lxc_arch[0] = lxc_seccomp_arch_mipsel; - ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_mipsel, -- default_policy_action); -+ default_policy_action, &ctx.architectures[0]); - if (!ctx.contexts[0]) - goto bad; - -- ctx.architectures[1] = SCMP_ARCH_MIPSEL64N32; - ctx.lxc_arch[1] = lxc_seccomp_arch_mipsel64n32; - ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_mipsel64n32, -- default_policy_action); -+ default_policy_action, &ctx.architectures[1]); - if (!ctx.contexts[1]) - goto bad; - -- ctx.architectures[2] = SCMP_ARCH_MIPSEL64; - ctx.lxc_arch[2] = lxc_seccomp_arch_mipsel64; - ctx.contexts[2] = get_new_ctx(lxc_seccomp_arch_mipsel64, -- default_policy_action); -+ default_policy_action, &ctx.architectures[2]); - if (!ctx.contexts[2]) - goto bad; - #endif -@@ -943,6 +932,7 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c - } - - if (cur_rule_arch == native_arch) { -+ /* add for native arch */ - if (!do_resolve_add_rule(SCMP_ARCH_NATIVE, line, - conf->seccomp_ctx, &rule)) - goto bad_rule; -@@ -951,6 +941,7 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c - SCMP_ARCH_NATIVE, line, rule.action, - get_action_name(rule.action)); - } else if (cur_rule_arch != lxc_seccomp_arch_all) { -+ /* add for compat specified arch */ - int arch_index = get_arch_index(cur_rule_arch, &ctx); - if (arch_index < 0) - goto bad_arch; -@@ -964,6 +955,15 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c - get_action_name(rule.action)); - ctx.needs_merge[arch_index] = true; - } else { -+ /* add for all compat archs */ -+ if (!do_resolve_add_rule(SCMP_ARCH_NATIVE, line, -+ conf->seccomp_ctx, &rule)) -+ goto bad_rule; -+ -+ INFO("Added native rule for arch %d for %s action %d(%s)", -+ SCMP_ARCH_NATIVE, line, rule.action, -+ get_action_name(rule.action)); -+ - if (ctx.architectures[0] != SCMP_ARCH_NATIVE) { - if (!do_resolve_add_rule(ctx.architectures[0], line, - ctx.contexts[0], &rule)) --- -1.8.3.1 - diff --git a/0052-setupdev-add-judge-whether-have-mount-dev-entry.patch b/0052-setupdev-add-judge-whether-have-mount-dev-entry.patch new file mode 100644 index 0000000000000000000000000000000000000000..cac78bfbbb1a123bb57a79e0be799da7300fbd51 --- /dev/null +++ b/0052-setupdev-add-judge-whether-have-mount-dev-entry.patch @@ -0,0 +1,132 @@ +From 68d3c92b40e049a257bf86dbb29fb274a5f1125e Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Sat, 18 Apr 2020 18:13:16 +0800 +Subject: [PATCH] setupdev: add judge whether have mount /dev entry + +reason: If user specify the Destination "/dev". + 1.Should not populate devices + 2.Should not setup devpts + +Signed-off-by: LiFeng +--- + src/lxc/conf.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 59 insertions(+), 3 deletions(-) + +diff --git a/src/lxc/conf.c b/src/lxc/conf.c +index 4d8fa2a..e8568d8 100644 +--- a/src/lxc/conf.c ++++ b/src/lxc/conf.c +@@ -1942,6 +1942,9 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs, + if (ret < 0 && errno != EEXIST) + return log_error_errno(-errno, errno, "Failed to create console"); + ++#ifdef HAVE_ISULAD ++ if (console->slave > 0) { ++#endif + ret = fchmod(console->slave, S_IXUSR | S_IXGRP); + if (ret < 0) + return log_error_errno(-errno, errno, "Failed to set mode \"0%o\" to \"%s\"", S_IXUSR | S_IXGRP, console->name); +@@ -1949,7 +1952,9 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs, + ret = safe_mount(console->name, path, "none", MS_BIND, 0, rootfs_path); + if (ret < 0) + return log_error_errno(-1, errno, "Failed to mount \"%s\" on \"%s\"", console->name, path); +- ++#ifdef HAVE_ISULAD ++ } ++#endif + DEBUG("Mounted pts device \"%s\" onto \"%s\"", console->name, path); + return 0; + } +@@ -2913,6 +2918,51 @@ static int setup_mount_entries(const struct lxc_conf *conf, + return mount_file_entries(conf, rootfs, f, lxc_name, lxc_path); + } + ++#ifdef HAVE_ISULAD ++static bool have_dev_bind_mount_entry(FILE *file) ++{ ++ bool have_bind_dev = false; ++ char buf[PATH_MAX]; ++ struct mntent mntent; ++ ++ while (getmntent_r(file, &mntent, buf, sizeof(buf))) { ++ mntent.mnt_dir = lxc_string_replace(SPACE_MAGIC_STR, " ", mntent.mnt_dir); ++ if(!mntent.mnt_dir) { ++ SYSERROR("memory allocation error"); ++ continue; ++ } ++ ++ if (strcmp(mntent.mnt_dir, "dev") == 0 && strcmp(mntent.mnt_type, "bind") == 0) { ++ have_bind_dev = true; ++ } ++ ++ free(mntent.mnt_dir); ++ mntent.mnt_dir = NULL; ++ ++ if (have_bind_dev) ++ return true; ++ } ++ ++ return false; ++} ++ ++// returns true if /dev needs to be set up. ++static bool need_setup_dev(const struct lxc_conf *conf, struct lxc_list *mount) ++{ ++ __do_fclose FILE *f = NULL; ++ ++ f = make_anonymous_mount_file(mount, conf->lsm_aa_allow_nesting); ++ if (!f) ++ return true; ++ ++ if (have_dev_bind_mount_entry(f)) { ++ return false; ++ } else { ++ return true; ++ } ++} ++#endif ++ + static int parse_cap(const char *cap) + { + size_t i; +@@ -4655,6 +4705,9 @@ int lxc_setup(struct lxc_handler *handler) + const char *lxcpath = handler->lxcpath, *name = handler->name; + struct lxc_conf *lxc_conf = handler->conf; + char *keyring_context = NULL; ++#ifdef HAVE_ISULAD ++ bool setup_dev = true; ++#endif + + ret = lxc_setup_rootfs_prepare_root(lxc_conf, name, lxcpath); + #ifdef HAVE_ISULAD +@@ -4723,6 +4776,9 @@ int lxc_setup(struct lxc_handler *handler) + &lxc_conf->mount_list, name, lxcpath); + if (ret < 0) + return log_error(-1, "Failed to setup mount entries"); ++#ifdef HAVE_ISULAD ++ setup_dev = need_setup_dev(lxc_conf, &lxc_conf->mount_list); ++#endif + } + + if (lxc_conf->is_execute) { +@@ -4771,7 +4827,7 @@ int lxc_setup(struct lxc_handler *handler) + + #ifdef HAVE_ISULAD + /* isulad: setup devices which will be populated in the container. */ +- if (!lxc_list_empty(&lxc_conf->populate_devs)) { ++ if (!lxc_list_empty(&lxc_conf->populate_devs) && setup_dev) { + if (setup_populate_devs(&lxc_conf->rootfs, &lxc_conf->populate_devs) != 0) { + return log_error(-1, "Failed to setup devices in the container"); + } +@@ -4813,7 +4869,7 @@ int lxc_setup(struct lxc_handler *handler) + if (setup_rootfs_mountopts(&lxc_conf->rootfs)) { + return log_error(-1, "failed to set rootfs for '%s'", name); + } +- if (lxc_conf->rootfs.path) { ++ if (lxc_conf->rootfs.path != NULL && setup_dev) { + ret = lxc_setup_devpts(lxc_conf); + if (ret < 0) { + return log_error(-1, "Failed to setup new devpts instance for '%s'", name); +-- +1.8.3.1 + diff --git a/0053-attach-seprate-i-and-t-flags.patch b/0053-attach-seprate-i-and-t-flags.patch new file mode 100644 index 0000000000000000000000000000000000000000..ed70a7b290de2ffc282432a57b8b24e4de219b91 --- /dev/null +++ b/0053-attach-seprate-i-and-t-flags.patch @@ -0,0 +1,288 @@ +From 36f64e652afc7fe3feac6d93468cbc4f3d53ec9a Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Tue, 21 Apr 2020 15:36:55 +0800 +Subject: [PATCH] attach: seprate -i and -t flags + +Signed-off-by: LiFeng +--- + src/lxc/attach.c | 100 ++++++++++++++++++++++++++++++++++++++++++++- + src/lxc/attach_options.h | 2 + + src/lxc/start.c | 1 + + src/lxc/terminal.c | 14 ++++--- + src/lxc/tools/lxc_attach.c | 17 +++++++- + 5 files changed, 125 insertions(+), 9 deletions(-) + +diff --git a/src/lxc/attach.c b/src/lxc/attach.c +index 1dd2b47..5539fb1 100644 +--- a/src/lxc/attach.c ++++ b/src/lxc/attach.c +@@ -653,6 +653,9 @@ struct attach_clone_payload { + struct lxc_proc_context_info *init_ctx; + lxc_attach_exec_t exec_function; + void *exec_payload; ++#ifdef HAVE_ISULAD ++ struct lxc_terminal *terminal; ++#endif + }; + + static void lxc_put_attach_clone_payload(struct attach_clone_payload *p) +@@ -665,6 +668,49 @@ static void lxc_put_attach_clone_payload(struct attach_clone_payload *p) + } + } + ++#ifdef HAVE_ISULAD ++static int isulad_set_attach_pipes(struct lxc_terminal *terminal) ++{ ++ int ret = 0; ++ if (terminal->pipes[0][1] >= 0) { ++ close(terminal->pipes[0][1]); ++ terminal->pipes[0][1] = -1; ++ } ++ ++ if (terminal->pipes[0][0] >= 0) { ++ ret = dup2(terminal->pipes[0][0], STDIN_FILENO); ++ if (ret < 0) ++ goto out; ++ } ++ ++ if (terminal->pipes[1][0] >= 0) { ++ close(terminal->pipes[1][0]); ++ terminal->pipes[1][0] = -1; ++ } ++ ++ if (terminal->pipes[1][1] >= 0) { ++ ret = dup2(terminal->pipes[1][1], STDOUT_FILENO); ++ if (ret < 0) ++ goto out; ++ } ++ if (terminal->pipes[2][0] >= 0) { ++ close(terminal->pipes[2][0]); ++ terminal->pipes[2][0] = -1; ++ } ++ ++ if (terminal->pipes[2][1] >= 0) { ++ ret = dup2(terminal->pipes[2][1], STDERR_FILENO); ++ if (ret < 0) ++ goto out; ++ } ++ ++ setsid(); ++out: ++ return ret; ++} ++ ++#endif ++ + static int attach_child_main(struct attach_clone_payload *payload) + { + int lsm_fd, ret; +@@ -933,6 +979,25 @@ static int attach_child_main(struct attach_clone_payload *payload) + } + + if (options->attach_flags & LXC_ATTACH_TERMINAL) { ++ ++#ifdef HAVE_ISULAD ++ /* isulad: dup2 pipe[0][0] to container stdin, pipe[1][1] to container stdout, pipe[2][1] to container stderr */ ++ if (payload->terminal->disable_pty) { ++ ret = isulad_set_attach_pipes(payload->terminal); ++ if (ret < 0) { ++ SYSERROR("Failed to prepare terminal file pipes"); ++ goto on_error; ++ } ++ } ++ ++ if(!payload->terminal->disable_pty && payload->terminal_slave_fd >= 0) { ++ ret = lxc_terminal_prepare_login(payload->terminal_slave_fd); ++ if (ret < 0) { ++ SYSERROR("Failed to prepare terminal file descriptor %d", payload->terminal_slave_fd); ++ goto on_error; ++ } ++ } ++#else + ret = lxc_terminal_prepare_login(payload->terminal_slave_fd); + if (ret < 0) { + SYSERROR("Failed to prepare terminal file descriptor %d", payload->terminal_slave_fd); +@@ -940,6 +1005,7 @@ static int attach_child_main(struct attach_clone_payload *payload) + } + + TRACE("Prepared terminal file descriptor %d", payload->terminal_slave_fd); ++#endif + } + + /* Avoid unnecessary syscalls. */ +@@ -1016,6 +1082,9 @@ static int lxc_attach_terminal(struct lxc_conf *conf, + free(terminal->init_fifo[2]); + terminal->init_fifo[2] = safe_strdup(options->init_fifo[2]); + } ++ ++ terminal->disable_pty = options->disable_pty; ++ terminal->open_stdin = options->open_stdin; + #endif + + ret = lxc_terminal_create(terminal); +@@ -1410,6 +1479,21 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + /* isulad: close errpipe */ + close(conf->errpipe[1]); + conf->errpipe[1] = -1; ++ /* isulad: close pipe after clone */ ++ if (terminal.pipes[0][0] >= 0) { ++ close(terminal.pipes[0][0]); ++ terminal.pipes[0][0] = -1; ++ } ++ ++ if (terminal.pipes[1][1] >= 0) { ++ close(terminal.pipes[1][1]); ++ terminal.pipes[1][1] = -1; ++ } ++ ++ if (terminal.pipes[2][1] >= 0) { ++ close(terminal.pipes[2][1]); ++ terminal.pipes[2][1] = -1; ++ } + #endif + lxc_proc_close_ns_fd(init_ctx); + if (options->attach_flags & LXC_ATTACH_TERMINAL) +@@ -1568,6 +1652,15 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + ret_parent = 0; + to_cleanup_pid = -1; + ++ #ifdef HAVE_ISULAD ++ // iSulad: close stdin pipe if we do not want open_stdin with container stdin ++ if (!terminal.open_stdin) { ++ if (terminal.pipes[0][1] > 0) { ++ close(terminal.pipes[0][1]); ++ terminal.pipes[0][1] = -1; ++ } ++ } ++ #endif + if (options->attach_flags & LXC_ATTACH_TERMINAL) { + ret = lxc_mainloop(&descr, -1); + if (ret < 0) { +@@ -1671,6 +1764,9 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + payload.terminal_slave_fd = terminal.slave; + payload.exec_function = exec_function; + payload.exec_payload = exec_payload; ++#ifdef HAVE_ISULAD ++ payload.terminal = &terminal; ++#endif + + pid = lxc_raw_clone(CLONE_PARENT, NULL); + if (pid < 0) { +@@ -1697,9 +1793,9 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + _exit(EXIT_FAILURE); + } + +- if (options->attach_flags & LXC_ATTACH_TERMINAL) ++ if (options->attach_flags & LXC_ATTACH_TERMINAL) { + lxc_attach_terminal_close_slave(&terminal); +- ++ } + /* Tell grandparent the pid of the pid of the newly created child. */ + ret = lxc_write_nointr(ipc_sockets[1], &pid, sizeof(pid)); + if (ret != sizeof(pid)) { +diff --git a/src/lxc/attach_options.h b/src/lxc/attach_options.h +index d5d4f44..5767560 100644 +--- a/src/lxc/attach_options.h ++++ b/src/lxc/attach_options.h +@@ -121,6 +121,8 @@ typedef struct lxc_attach_options_t { + char *init_fifo[3]; /* isulad: default fifos for the start */ + int64_t timeout;/* isulad: Seconds for waiting on a container to attach/exec before it is killed*/ + const char *suffix; ++ bool disable_pty; ++ bool open_stdin; + } lxc_attach_options_t; + + /*! Default attach options to use */ +diff --git a/src/lxc/start.c b/src/lxc/start.c +index e099285..68a6116 100644 +--- a/src/lxc/start.c ++++ b/src/lxc/start.c +@@ -1789,6 +1789,7 @@ static int do_start(void *data) + * as it execs. + */ + #ifdef HAVE_ISULAD ++ close_prot_errno_disarm(status_fd); + handler->ops->start(handler, handler->data, handler->daemonize ? handler->conf->errpipe[1] : -1); + #else + handler->ops->start(handler, handler->data); +diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c +index c0a4d1a..57def93 100644 +--- a/src/lxc/terminal.c ++++ b/src/lxc/terminal.c +@@ -750,21 +750,23 @@ int lxc_terminal_io_cb(int fd, uint32_t events, void *data, + return LXC_MAINLOOP_CONTINUE; + } else if (fd == terminal->pipes[1][0] || fd == terminal->pipes[2][0]) { + if (fd == terminal->pipes[1][0]) { +- w_log = isulad_lxc_terminal_write_log_file(terminal, "stdout", NULL, 0); ++ if (terminal->log_fd >= 0) { ++ w_log = isulad_lxc_terminal_write_log_file(terminal, "stdout", NULL, 0); ++ } + terminal->pipes[1][0] = -EBADF; + } else if (fd == terminal->pipes[2][0]) { +- w_log = isulad_lxc_terminal_write_log_file(terminal, "stderr", NULL, 0); ++ if (terminal->log_fd >= 0) { ++ w_log = isulad_lxc_terminal_write_log_file(terminal, "stderr", NULL, 0); ++ } + terminal->pipes[2][0] = -EBADF; + } +- if (w_log < 0) +- TRACE("Failed to write %d bytes to terminal log", r); + close(fd); +- return LXC_MAINLOOP_CONTINUE; ++ return LXC_MAINLOOP_CLOSE; + } else if (fd == terminal->pipes[0][1]) { + TRACE("closed stdin pipe of container stdin"); + terminal->pipes[0][1] = -EBADF; + close(fd); +- return LXC_MAINLOOP_CONTINUE; ++ return LXC_MAINLOOP_CLOSE; + } else { + ERROR("Handler received unexpected file descriptor"); + } +diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c +index a855a8d..da7a7d2 100644 +--- a/src/lxc/tools/lxc_attach.c ++++ b/src/lxc/tools/lxc_attach.c +@@ -82,6 +82,8 @@ static const struct option my_longopts[] = { + {"err-fifo", required_argument, 0, OPT_STDERR_FIFO}, + {"suffix", required_argument, 0, OPT_ATTACH_SUFFIX}, + {"timeout", required_argument, 0, OPT_ATTACH_TIMEOUT}, ++ {"disable-pty", no_argument, 0, OPT_DISABLE_PTY}, ++ {"open-stdin", no_argument, 0, OPT_OPEN_STDIN}, + #endif + LXC_COMMON_OPTIONS + }; +@@ -312,9 +314,14 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) + } + args->attach_timeout = (unsigned int)atoll(arg); + break; ++ case OPT_DISABLE_PTY: ++ args->disable_pty = 1; ++ break; ++ case OPT_OPEN_STDIN: ++ args->open_stdin = 1; ++ break; + #endif + } +- + return 0; + } + +@@ -614,6 +621,14 @@ int main(int argc, char *argv[]) + + attach_options.suffix = my_args.suffix; + ++ if (my_args.disable_pty) { ++ attach_options.disable_pty = true; ++ } ++ ++ if (my_args.open_stdin) { ++ attach_options.open_stdin = true; ++ } ++ + /* isulad: add do attach background */ + if (attach_options.attach_flags & LXC_ATTACH_TERMINAL) + wexit = do_attach_foreground(c, &command, &attach_options, &errmsg); +-- +1.8.3.1 + diff --git a/0053-destroy-empty-cgroup-path-return-ture.patch b/0053-destroy-empty-cgroup-path-return-ture.patch deleted file mode 100644 index 4ed4b5dfa4c544a7ff3eab64bdfca62e1cd050dd..0000000000000000000000000000000000000000 --- a/0053-destroy-empty-cgroup-path-return-ture.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 55aa538a996fb98bd76ca41029c93147d22c1ecf Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Tue, 22 Jan 2019 14:45:54 +0800 -Subject: [PATCH 053/140] destroy empty cgroup path return ture - -destroy empty cgroup path return ture - -Signed-off-by: liuhao -Signed-off-by: LiFeng ---- - src/lxc/utils.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index c8fb993..24e975b 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -1776,6 +1776,10 @@ int recursive_destroy(char *dirname) - - dir = opendir(dirname); - if (!dir) { -+ if (errno == ENOENT) { -+ WARN("Destroy path: %s do not exist"); -+ return 0; -+ } - SYSERROR("Failed to open dir \"%s\"", dirname); - return -1; - } --- -1.8.3.1 - diff --git a/0054-fix-invalid-log-message.patch b/0054-fix-invalid-log-message.patch deleted file mode 100644 index 86aa64118845fe017f0e5ff320f17328bc322331..0000000000000000000000000000000000000000 --- a/0054-fix-invalid-log-message.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 6ca37fb9e3838f3ddffec7e0325e37e6925f3562 Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Tue, 22 Jan 2019 20:14:53 +0800 -Subject: [PATCH 054/140] fix invalid log message - -fix invalid log message - -Signed-off-by: liuhao -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 1 - - src/lxc/utils.c | 2 +- - 2 files changed, 1 insertion(+), 2 deletions(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 6ea8f9c..1e403eb 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -2708,7 +2708,6 @@ static int mount_file_entries(const struct lxc_conf *conf, - free(mntent.mnt_fsname); - return -1; - } -- ERROR("mntent.mnt_fsname:%s, mntent.mnt_dir:%s", mntent.mnt_fsname, mntent.mnt_dir); - if (!rootfs->path) - ret = mount_entry_on_systemfs(&mntent); - else if (mntent.mnt_dir[0] != '/') -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index 24e975b..4db61c5 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -1777,7 +1777,7 @@ int recursive_destroy(char *dirname) - dir = opendir(dirname); - if (!dir) { - if (errno == ENOENT) { -- WARN("Destroy path: %s do not exist"); -+ WARN("Destroy path: \"%s\" do not exist", dirname); - return 0; - } - SYSERROR("Failed to open dir \"%s\"", dirname); --- -1.8.3.1 - diff --git a/0041-return-1-when-_lxc_start-fails.patch b/0054-start-do-not-check-pid-die-when-lxc_poll-exit.patch similarity index 36% rename from 0041-return-1-when-_lxc_start-fails.patch rename to 0054-start-do-not-check-pid-die-when-lxc_poll-exit.patch index c62b4d3ddb5bbc7cdf827dc5a410a220d5ce31a4..99681e06fe618895e93650f4f6b67b8b86905a55 100644 --- a/0041-return-1-when-_lxc_start-fails.patch +++ b/0054-start-do-not-check-pid-die-when-lxc_poll-exit.patch @@ -1,25 +1,31 @@ -From 4315f825763d752a9a9dfcb3ade70368634ee15d Mon Sep 17 00:00:00 2001 +From d5558ec70cbc4949d0a411ec32278201fdc189db Mon Sep 17 00:00:00 2001 From: LiFeng -Date: Wed, 16 Jan 2019 05:53:36 -0500 -Subject: [PATCH 041/140] return -1 when _lxc_start fails +Date: Wed, 22 Apr 2020 11:14:22 +0800 +Subject: [PATCH] start: do not check pid die when lxc_poll exit Signed-off-by: LiFeng --- - src/lxc/start.c | 1 + - 1 file changed, 1 insertion(+) + src/lxc/start.c | 2 ++ + 1 file changed, 2 insertions(+) diff --git a/src/lxc/start.c b/src/lxc/start.c -index 3e6854f..7bbcb00 100644 +index 68a6116..51d1325 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c -@@ -2175,6 +2175,7 @@ int __lxc_start(const char *name, struct lxc_handler *handler, +@@ -2595,11 +2595,13 @@ int __lxc_start(struct lxc_handler *handler, struct lxc_operations *ops, + goto out_delete_network; + } ++#ifndef HAVE_ISULAD if (!handler->init_died && handler->pid > 0) { ERROR("Child process is not killed"); -+ ret = -1; - goto out_abort; + ret = -1; + goto out_delete_network; } ++#endif + status = lxc_wait_for_pid_status(handler->pid); + if (status < 0) -- 1.8.3.1 diff --git a/0055-Fix-compile-error.patch b/0055-Fix-compile-error.patch deleted file mode 100644 index 45188cd6a1459837d5a3c0ef1e0528cebb1dff01..0000000000000000000000000000000000000000 --- a/0055-Fix-compile-error.patch +++ /dev/null @@ -1,229 +0,0 @@ -From e1e5091673c7464a320cdfc08d91ad176a636f71 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Thu, 24 Jan 2019 05:14:24 -0500 -Subject: [PATCH 055/140] Fix compile error - -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgfsng.c | 13 ------------- - src/lxc/conf.c | 8 ++------ - src/lxc/confile.c | 1 - - src/lxc/start.c | 2 -- - src/lxc/terminal.c | 32 ++++++++++++++++---------------- - src/lxc/terminal.h | 3 --- - src/lxc/tools/lxc_attach.c | 2 -- - src/lxc/utils.c | 1 - - 8 files changed, 18 insertions(+), 44 deletions(-) - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index 6bfa693..e513218 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -1263,18 +1263,6 @@ static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname, int err - return cg_unified_create_cgroup(h, cgname); - } - --static void remove_path_for_hierarchy(struct hierarchy *h, char *cgname) --{ -- int ret; -- -- ret = rmdir(h->container_full_path); -- if (ret < 0) -- SYSERROR("Failed to rmdir(\"%s\") from failed creation attempt", h->container_full_path); -- -- free(h->container_full_path); -- h->container_full_path = NULL; --} -- - /* isulad: create hierarchies path, if fail, return the error */ - __cgfsng_ops static bool cgfsng_payload_create(struct cgroup_ops *ops, - struct lxc_handler *handler) -@@ -2439,7 +2427,6 @@ static bool cg_hybrid_init(struct cgroup_ops *ops) - - while (getline(&line, &len, f) != -1) { - int type; -- bool writeable; - struct hierarchy *new; - char *base_cgroup = NULL, *mountpoint = NULL; - char **controller_list = NULL; -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 1e403eb..4800943 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -1518,7 +1518,7 @@ error: - // remount_readonly will bind over the top of an existing path and ensure that it is read-only. - static bool remount_readonly(const char *path) - { -- int ret, savederrno, i; -+ int ret, i; - - if (!path) - return true; -@@ -4005,7 +4005,7 @@ static int setup_rootfs_mountopts(const struct lxc_rootfs *rootfs) - if (mntflags & MS_RDONLY) { - mflags = add_required_remount_flags("/", NULL, MS_BIND | MS_REC | mntflags | pflags | MS_REMOUNT); - DEBUG("remounting / as readonly"); -- if (mount("/", "/", NULL, MS_BIND | MS_REMOUNT | MS_RDONLY, 0) < 0) { -+ if (mount("/", "/", NULL, mflags, 0) < 0) { - SYSERROR("Failed to make / readonly."); - return -1; - } -@@ -4776,7 +4776,6 @@ default_out: - static int run_oci_hooks(const char *name, const char *lxcpath, struct lxc_conf *lc, int which, int errfd) - { - struct oci_hook_conf work_conf = {0}; -- oci_runtime_spec_hooks *ocihooks = NULL; - size_t i; - int ret = 0; - char *rootpath; -@@ -4836,7 +4835,6 @@ int run_lxc_hooks(const char *name, char *hookname, struct lxc_conf *conf, - int which = -1; - - if (strcmp(hookname, "oci-prestart") == 0) { -- int ret; - which = OCI_HOOK_PRESTART; - if (!argv || !argv[0]) { - ERROR("oci hook require lxcpath"); -@@ -4844,7 +4842,6 @@ int run_lxc_hooks(const char *name, char *hookname, struct lxc_conf *conf, - } - return run_oci_hooks(name, argv[0], conf, which, conf->errpipe[1]); - } else if (strcmp(hookname, "oci-poststart") == 0) { -- int ret; - which = OCI_HOOK_POSTSTART; - if (!argv || !argv[0]) { - ERROR("oci hook require lxcpath"); -@@ -4852,7 +4849,6 @@ int run_lxc_hooks(const char *name, char *hookname, struct lxc_conf *conf, - } - return run_oci_hooks(name, argv[0], conf, which, conf->errpipe[1]); - } else if (strcmp(hookname, "oci-poststop") == 0) { -- int ret; - which = OCI_HOOK_POSTSTOP; - if (!argv || !argv[0]) { - ERROR("oci hook require lxcpath"); -diff --git a/src/lxc/confile.c b/src/lxc/confile.c -index 7e9d5c8..f66d01b 100644 ---- a/src/lxc/confile.c -+++ b/src/lxc/confile.c -@@ -3909,7 +3909,6 @@ static int get_config_init_args(const char *key, char *retv, int inlen, - struct lxc_conf *c, void *data) - { - int i, len, fulllen = 0; -- struct lxc_list *it; - - if (!retv) - inlen = 0; -diff --git a/src/lxc/start.c b/src/lxc/start.c -index daf2af4..816b4a2 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -2470,8 +2470,6 @@ retry: - ret = -1; - } - -- --out_fini_handler: - lxc_free_handler(handler); - out: - return ret; -diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index 95140e0..252a644 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -418,6 +418,21 @@ static void lxc_forward_data_to_fifo(struct lxc_list *list, char *buf, int r) - return; - } - -+/* isulad: judge the fd whether is fifo */ -+static bool lxc_terminal_is_fifo(int fd, struct lxc_list *list) -+{ -+ struct lxc_list *it,*next; -+ struct lxc_fifos_fd *elem = NULL; -+ -+ lxc_list_for_each_safe(it, list, next) { -+ elem = it->elem; -+ if (elem->in_fd == fd) -+ return true; -+ } -+ -+ return false; -+} -+ - int lxc_terminal_io_cb(int fd, uint32_t events, void *data, - struct lxc_epoll_descr *descr) - { -@@ -1067,7 +1082,7 @@ static int lxc_terminal_fifo_default(struct lxc_terminal *terminal) - } - - /* -- * isulad: disable (XSI) Map NL to CR-NL on output. -+ * isulad: disable (XSI) Map NL to CR-NL on output. - * */ - static int use_unix_newline(int master_fd) - { -@@ -1427,21 +1442,6 @@ void lxc_terminal_init(struct lxc_terminal *terminal) - lxc_list_init(&terminal->fifos); - } - --/* isulad: judge the fd whether is fifo */ --static bool lxc_terminal_is_fifo(int fd, struct lxc_list *list) --{ -- struct lxc_list *it,*next; -- struct lxc_fifos_fd *elem = NULL; -- -- lxc_list_for_each_safe(it, list, next) { -- elem = it->elem; -- if (elem->in_fd == fd) -- return true; -- } -- -- return false; --} -- - /* isulad: if fd == -1, means delete all the fifos*/ - int lxc_terminal_delete_fifo(int fd, struct lxc_list *list) - { -diff --git a/src/lxc/terminal.h b/src/lxc/terminal.h -index d006b80..0c9653c 100644 ---- a/src/lxc/terminal.h -+++ b/src/lxc/terminal.h -@@ -305,9 +305,6 @@ extern void lxc_terminal_info_init(struct lxc_terminal_info *terminal); - extern void lxc_terminal_init(struct lxc_terminal *terminal); - extern int lxc_terminal_map_ids(struct lxc_conf *c, - struct lxc_terminal *terminal); -- --/* isulad: judge the fd whether is fifo*/ --static bool lxc_terminal_is_fifo(int fd, struct lxc_list *list); - /* isulad: if fd == -1, means delete all the fifos*/ - int lxc_terminal_delete_fifo(int fd, struct lxc_list *list); - int lxc_terminal_add_fifos(struct lxc_conf *conf, const char *fifonames); -diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c -index a590fd1..8856934 100644 ---- a/src/lxc/tools/lxc_attach.c -+++ b/src/lxc/tools/lxc_attach.c -@@ -398,11 +398,9 @@ out: - - int main(int argc, char *argv[]) - { -- int ret = -1; - int wexit = 0; - char *errmsg = NULL; - struct lxc_log log; -- pid_t pid; - lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT; - lxc_attach_command_t command = (lxc_attach_command_t){.program = NULL}; - -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index 4db61c5..9a50fce 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -2026,7 +2026,6 @@ void lxc_write_error_message(int errfd, const char *format, ...) - - bool lxc_process_alive(pid_t pid, unsigned long long start_time) - { -- int ret; - int sret = 0; - bool alive = true; - proc_t *pid_info = NULL; --- -1.8.3.1 - diff --git a/0055-terminal-not-close-pipe-when-lxc_poll-exit.patch b/0055-terminal-not-close-pipe-when-lxc_poll-exit.patch new file mode 100644 index 0000000000000000000000000000000000000000..daaee5ea3d5fd29ae51b6328e43ee3be50078d9c --- /dev/null +++ b/0055-terminal-not-close-pipe-when-lxc_poll-exit.patch @@ -0,0 +1,64 @@ +From d0e0cc557dba264c4228e29edb178d57b25af2f5 Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Wed, 22 Apr 2020 20:54:19 +0800 +Subject: [PATCH] terminal: not close pipe when lxc_poll exit + +Signed-off-by: LiFeng +--- + src/lxc/attach.c | 4 +++- + src/lxc/terminal.c | 5 +++-- + src/lxc/tools/lxc_attach.c | 3 +++ + 3 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/src/lxc/attach.c b/src/lxc/attach.c +index 5539fb1..51f5c08 100644 +--- a/src/lxc/attach.c ++++ b/src/lxc/attach.c +@@ -1542,7 +1542,9 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + if (ret < 0) + goto on_error; + #ifdef HAVE_ISULAD +- (void)lxc_exec_cmd_mainloop_add(&descr, &exec_command); ++ if (suffix != NULL) { ++ (void)lxc_exec_cmd_mainloop_add(&descr, &exec_command); ++ } + #endif + TRACE("Initialized terminal mainloop"); + } +diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c +index 57def93..0197503 100644 +--- a/src/lxc/terminal.c ++++ b/src/lxc/terminal.c +@@ -760,12 +760,13 @@ int lxc_terminal_io_cb(int fd, uint32_t events, void *data, + } + terminal->pipes[2][0] = -EBADF; + } +- close(fd); ++ /* notes: do not close the master fd due to if we close the fd, the process may ++ * recive SIGHUP and the exit code will be 141 (128 + 13) ++ */ + return LXC_MAINLOOP_CLOSE; + } else if (fd == terminal->pipes[0][1]) { + TRACE("closed stdin pipe of container stdin"); + terminal->pipes[0][1] = -EBADF; +- close(fd); + return LXC_MAINLOOP_CLOSE; + } else { + ERROR("Handler received unexpected file descriptor"); +diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c +index da7a7d2..190f3c8 100644 +--- a/src/lxc/tools/lxc_attach.c ++++ b/src/lxc/tools/lxc_attach.c +@@ -417,6 +417,9 @@ static int do_attach_foreground(struct lxc_container *c, lxc_attach_command_t *c + signal = WTERMSIG(ret); + wexit = EXIT_SIGNAL_OFFSET + signal; + } ++ ++ ERROR("Execd pid %d exit with %d", pid, wexit); ++ + out: + if (c->lxc_conf->errmsg) + *errmsg = safe_strdup(c->lxc_conf->errmsg); +-- +1.8.3.1 + diff --git a/0056-attach-add-sigfd-to-monitor-the-exit-of-pid.patch b/0056-attach-add-sigfd-to-monitor-the-exit-of-pid.patch new file mode 100644 index 0000000000000000000000000000000000000000..71bb8f6e341df8ee2272ef37e2543d5969a1298e --- /dev/null +++ b/0056-attach-add-sigfd-to-monitor-the-exit-of-pid.patch @@ -0,0 +1,178 @@ +From cb3a7926948c4d9668d54521cb7907436723b67a Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Wed, 22 Apr 2020 23:30:23 +0800 +Subject: [PATCH] attach: add sigfd to monitor the exit of pid + +Signed-off-by: LiFeng +--- + src/lxc/attach.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++- + src/lxc/terminal.c | 4 +-- + 2 files changed, 87 insertions(+), 3 deletions(-) + +diff --git a/src/lxc/attach.c b/src/lxc/attach.c +index 51f5c08..b25222e 100644 +--- a/src/lxc/attach.c ++++ b/src/lxc/attach.c +@@ -1197,6 +1197,56 @@ static int create_attach_timeout_thread(int64_t attach_timeout, pid_t pid) + out: + return ret; + } ++ ++static int attach_signal_handler(int fd, uint32_t events, void *data, ++ struct lxc_epoll_descr *descr) ++{ ++ int ret; ++ siginfo_t info; ++ pid_t *pid = data; ++ ++ /* Check whether init is running. */ ++ info.si_pid = 0; ++ ret = waitid(P_PID, *pid, &info, WEXITED | WNOWAIT | WNOHANG); ++ if (ret == 0 && info.si_pid == *pid) { ++ return log_error(LXC_MAINLOOP_CLOSE, "Container attach init process %d exited", *pid); ++ } ++ ++ return LXC_MAINLOOP_CONTINUE; ++} ++ ++static int isulad_setup_signal_fd(sigset_t *oldmask) ++{ ++ int ret; ++ sigset_t mask; ++ const int signals[] = {SIGBUS, SIGILL, SIGSEGV, SIGWINCH}; ++ ++ /* Block everything except serious error signals. */ ++ ret = sigfillset(&mask); ++ if (ret < 0) ++ return -EBADF; ++ ++ for (int sig = 0; sig < (sizeof(signals) / sizeof(signals[0])); sig++) { ++ ret = sigdelset(&mask, signals[sig]); ++ if (ret < 0) ++ return -EBADF; ++ } ++ ++ ret = pthread_sigmask(SIG_BLOCK, &mask, oldmask); ++ if (ret < 0) ++ return log_error_errno(-EBADF, errno, ++ "Failed to set signal mask"); ++ ++ ret = signalfd(-1, &mask, SFD_CLOEXEC); ++ if (ret < 0) ++ return log_error_errno(-EBADF, ++ errno, "Failed to create signal file descriptor"); ++ ++ TRACE("Created signal file descriptor %d", ret); ++ ++ return ret; ++} ++ + int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + void *exec_payload, lxc_attach_options_t *options, + pid_t *attached_process, char **err_msg) +@@ -1471,6 +1521,11 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + int ret_parent = -1; + pid_t to_cleanup_pid = pid; + struct lxc_epoll_descr descr = {0}; ++#ifdef HAVE_ISULAD ++ int isulad_sigfd; ++ sigset_t isulad_oldmask; ++ struct lxc_epoll_descr isulad_descr = {0}; ++#endif + + /* close unneeded file descriptors */ + close(ipc_sockets[1]); +@@ -1541,7 +1596,12 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + ret = lxc_attach_terminal_mainloop_init(&terminal, &descr); + if (ret < 0) + goto on_error; ++ + #ifdef HAVE_ISULAD ++ ret = lxc_attach_terminal_mainloop_init(&terminal, &isulad_descr); ++ if (ret < 0) ++ goto on_error; ++ + if (suffix != NULL) { + (void)lxc_exec_cmd_mainloop_add(&descr, &exec_command); + } +@@ -1549,6 +1609,16 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + TRACE("Initialized terminal mainloop"); + } + ++#ifdef HAVE_ISULAD ++ /* The signal fd has to be created before forking otherwise if the child ++ * process exits before we setup the signal fd, the event will be lost ++ * and the command will be stuck. ++ */ ++ isulad_sigfd = isulad_setup_signal_fd(&isulad_oldmask); ++ if (isulad_sigfd < 0) ++ goto close_mainloop; ++#endif ++ + /* Let the child process know to go ahead. */ + status = 0; + ret = lxc_write_nointr(ipc_sockets[0], &status, sizeof(status)); +@@ -1637,6 +1707,7 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + /* isulad: read error msg from pipe */ + ssize_t size_read; + char errbuf[BUFSIZ + 1] = {0}; ++ pid_t tmp_pid = *attached_process; + + size_read = read(conf->errpipe[0], errbuf, BUFSIZ); + if (size_read > 0) { +@@ -1644,6 +1715,13 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + *err_msg = safe_strdup(errbuf); + goto close_mainloop; + } ++ if (options->attach_flags & LXC_ATTACH_TERMINAL) { ++ ret = lxc_mainloop_add_handler(&descr, isulad_sigfd, attach_signal_handler, &tmp_pid); ++ if (ret < 0) { ++ ERROR("Failed to add signal handler for %d to mainloop", tmp_pid); ++ goto close_mainloop; ++ } ++ } + #endif + + /* Now shut down communication with child, we're done. */ +@@ -1672,13 +1750,19 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + } + + #ifdef HAVE_ISULAD ++ // do lxc_mainloop to make sure we do not lose any output ++ (void)lxc_mainloop(&isulad_descr, 100); + if (g_attach_timeout_state == ATTACH_TIMEOUT && err_msg != NULL && *err_msg == NULL) { + *err_msg = safe_strdup("Attach exceeded timeout"); + } + #endif + close_mainloop: +- if (options->attach_flags & LXC_ATTACH_TERMINAL) ++ if (options->attach_flags & LXC_ATTACH_TERMINAL) { ++#ifdef HAVE_ISULAD ++ lxc_mainloop_close(&isulad_descr); ++#endif + lxc_mainloop_close(&descr); ++ } + + on_error: + if (ipc_sockets[0] >= 0) { +diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c +index 0197503..e696b4e 100644 +--- a/src/lxc/terminal.c ++++ b/src/lxc/terminal.c +@@ -763,11 +763,11 @@ int lxc_terminal_io_cb(int fd, uint32_t events, void *data, + /* notes: do not close the master fd due to if we close the fd, the process may + * recive SIGHUP and the exit code will be 141 (128 + 13) + */ +- return LXC_MAINLOOP_CLOSE; ++ return LXC_MAINLOOP_CONTINUE; + } else if (fd == terminal->pipes[0][1]) { + TRACE("closed stdin pipe of container stdin"); + terminal->pipes[0][1] = -EBADF; +- return LXC_MAINLOOP_CLOSE; ++ return LXC_MAINLOOP_CONTINUE; + } else { + ERROR("Handler received unexpected file descriptor"); + } +-- +1.8.3.1 + diff --git a/0056-caps-use-_LINUX_CAPABILITY_VERSION_3-to-set-cap.patch b/0056-caps-use-_LINUX_CAPABILITY_VERSION_3-to-set-cap.patch deleted file mode 100644 index 9539bd14df0b5da24959819fcbbba3e9766f9165..0000000000000000000000000000000000000000 --- a/0056-caps-use-_LINUX_CAPABILITY_VERSION_3-to-set-cap.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 94ae346e2bff8bb29eae17604b75b1de19258277 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Sat, 26 Jan 2019 02:22:48 -0500 -Subject: [PATCH 056/140] [caps]: use _LINUX_CAPABILITY_VERSION_3 to set cap - -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 8 ++++---- - src/lxc/seccomp.c | 1 - - 2 files changed, 4 insertions(+), 5 deletions(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 4800943..0c6aa28 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4322,13 +4322,13 @@ int lxc_drop_caps(struct lxc_conf *conf) - memset(cap_data, 0, sizeof(struct __user_cap_data_struct) * 2); - - cap_header->pid = 0; -- cap_header->version = _LINUX_CAPABILITY_VERSION; -+ cap_header->version = _LINUX_CAPABILITY_VERSION_3; - - for (i = 0; i < numcaps; i++) { - if (caplist[i]) { -- cap_data[CAP_TO_INDEX(i)].effective = cap_data[CAP_TO_INDEX(i)].effective | __DEF_CAP_TO_MASK(i); -- cap_data[CAP_TO_INDEX(i)].permitted = cap_data[CAP_TO_INDEX(i)].permitted | __DEF_CAP_TO_MASK(i); -- cap_data[CAP_TO_INDEX(i)].inheritable = cap_data[CAP_TO_INDEX(i)].inheritable | __DEF_CAP_TO_MASK(i); -+ cap_data[CAP_TO_INDEX(i)].effective = cap_data[CAP_TO_INDEX(i)].effective | (i > 31 ? __DEF_CAP_TO_MASK(i % 32) : __DEF_CAP_TO_MASK(i)); -+ cap_data[CAP_TO_INDEX(i)].permitted = cap_data[CAP_TO_INDEX(i)].permitted | (i > 31 ? __DEF_CAP_TO_MASK(i % 32) : __DEF_CAP_TO_MASK(i)); -+ cap_data[CAP_TO_INDEX(i)].inheritable = cap_data[CAP_TO_INDEX(i)].inheritable | (i > 31 ? __DEF_CAP_TO_MASK(i % 32) : __DEF_CAP_TO_MASK(i)); - } - } - -diff --git a/src/lxc/seccomp.c b/src/lxc/seccomp.c -index 3218a60..4a5b3d0 100644 ---- a/src/lxc/seccomp.c -+++ b/src/lxc/seccomp.c -@@ -706,7 +706,6 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c - goto bad; - } else if (native_arch == lxc_seccomp_arch_mipsel64) { - cur_rule_arch = lxc_seccomp_arch_all; --; - ctx.lxc_arch[0] = lxc_seccomp_arch_mipsel; - ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_mipsel, - default_policy_action, &ctx.architectures[0]); --- -1.8.3.1 - diff --git a/0057-attach-add-read-data-from-attach-sigfd.patch b/0057-attach-add-read-data-from-attach-sigfd.patch new file mode 100644 index 0000000000000000000000000000000000000000..e6a3e9ce32e3fbeb4f772a1b13cbbcefccf0829f --- /dev/null +++ b/0057-attach-add-read-data-from-attach-sigfd.patch @@ -0,0 +1,34 @@ +From a2097f947d40ff2da0b6ab47dbbc90a349ed33b9 Mon Sep 17 00:00:00 2001 +From: LiFeng +Date: Thu, 23 Apr 2020 11:05:37 +0800 +Subject: [PATCH] attach: add read data from attach sigfd + +Signed-off-by: LiFeng +--- + src/lxc/attach.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/lxc/attach.c b/src/lxc/attach.c +index b25222e..068cc5f 100644 +--- a/src/lxc/attach.c ++++ b/src/lxc/attach.c +@@ -1203,8 +1203,16 @@ static int attach_signal_handler(int fd, uint32_t events, void *data, + { + int ret; + siginfo_t info; ++ struct signalfd_siginfo siginfo; + pid_t *pid = data; + ++ ret = lxc_read_nointr(fd, &siginfo, sizeof(siginfo)); ++ if (ret < 0) ++ return log_error(LXC_MAINLOOP_ERROR, "Failed to read signal info from signal file descriptor %d", fd); ++ ++ if (ret != sizeof(siginfo)) ++ return log_error(LXC_MAINLOOP_ERROR, "Unexpected size for struct signalfd_siginfo"); ++ + /* Check whether init is running. */ + info.si_pid = 0; + ret = waitid(P_PID, *pid, &info, WEXITED | WNOWAIT | WNOHANG); +-- +1.8.3.1 + diff --git a/0058-do-not-check-ppid-when-set-death-signal.patch b/0058-do-not-check-ppid-when-set-death-signal.patch deleted file mode 100644 index a28818e525a48b4fbf3cc8ac2570a1dd8561892c..0000000000000000000000000000000000000000 --- a/0058-do-not-check-ppid-when-set-death-signal.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 2c5d318fb3a809c017e0b57c80de500bceb9b495 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Tue, 12 Feb 2019 14:00:47 +0800 -Subject: [PATCH 058/140] do not check ppid when set death signal - -ppid will not be 0 if we shared host pid - -Signed-off-by: tanyifeng -Signed-off-by: LiFeng ---- - src/lxc/utils.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index 9a50fce..0aa87aa 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -1722,12 +1722,13 @@ int lxc_set_death_signal(int signal, pid_t parent) - prctl_arg(0), prctl_arg(0)); - - /* Check whether we have been orphaned. */ -- ppid = (pid_t)syscall(SYS_getppid); -+ /* isulad: delete this check, ppid will not be 0 if we shared host pid */ -+ /*ppid = (pid_t)syscall(SYS_getppid); - if (ppid != parent) { - ret = raise(SIGKILL); - if (ret < 0) - return -1; -- } -+ }*/ - - if (ret < 0) - return -1; --- -1.8.3.1 - diff --git a/0058-support-syslog-for-console.patch b/0058-support-syslog-for-console.patch new file mode 100644 index 0000000000000000000000000000000000000000..cab967e02ca37014e5e87f777da7bf7f58c9bc2f --- /dev/null +++ b/0058-support-syslog-for-console.patch @@ -0,0 +1,251 @@ +From da93b4863324d200ffc69eb7eb87b686b47cc2ce Mon Sep 17 00:00:00 2001 +From: haozi007 +Date: Thu, 23 Apr 2020 19:46:22 +0800 +Subject: [PATCH] support syslog for console + +Signed-off-by: haozi007 +--- + src/lxc/confile.c | 109 +++++++++++++++++++++++++++++++++++++++++++++ + src/lxc/terminal.c | 44 +++++++++++++++++- + src/lxc/terminal.h | 10 +++++ + 3 files changed, 162 insertions(+), 1 deletion(-) + +diff --git a/src/lxc/confile.c b/src/lxc/confile.c +index 771f6355..b1d101a9 100644 +--- a/src/lxc/confile.c ++++ b/src/lxc/confile.c +@@ -155,6 +155,9 @@ lxc_config_define(umask); + lxc_config_define(rootfs_masked_paths); + lxc_config_define(rootfs_ro_paths); + lxc_config_define(systemd); ++lxc_config_define(console_log_driver); ++lxc_config_define(console_syslog_tag); ++lxc_config_define(console_syslog_facility); + #endif + + /* +@@ -276,6 +279,9 @@ static struct lxc_config_t config_jump_table[] = { + { "lxc.isulad.rootfs.maskedpaths", set_config_rootfs_masked_paths, get_config_rootfs_masked_paths, clr_config_rootfs_masked_paths, }, + { "lxc.isulad.rootfs.ropaths", set_config_rootfs_ro_paths, get_config_rootfs_ro_paths, clr_config_rootfs_ro_paths, }, + { "lxc.isulad.systemd", set_config_systemd, get_config_systemd, clr_config_systemd, }, ++ { "lxc.console.logdriver", set_config_console_log_driver, get_config_console_log_driver, clr_config_console_log_driver, }, ++ { "lxc.console.syslog_tag", set_config_console_syslog_tag, get_config_console_syslog_tag, clr_config_console_syslog_tag, }, ++ { "lxc.console.syslog_facility", set_config_console_syslog_facility, get_config_console_syslog_facility, clr_config_console_syslog_facility, }, + #endif + }; + +@@ -6617,4 +6623,107 @@ static inline int clr_config_systemd(const char *key, struct lxc_conf *c, + return 0; + } + ++static int set_config_console_log_driver(const char *key, const char *value, ++ struct lxc_conf *lxc_conf, void *data) ++{ ++ return set_config_string_item(&lxc_conf->console.log_driver, value); ++} ++ ++static int set_config_console_syslog_tag(const char *key, const char *value, ++ struct lxc_conf *lxc_conf, void *data) ++{ ++ char buf[16] = { 0 }; ++ ++ if (value == NULL) { ++ return -1; ++ } ++ (void)strlcpy(buf, value, 16); ++ return set_config_string_item(&lxc_conf->console.log_syslog_tag, buf); ++} ++ ++static int parse_facility(const char *facility) ++{ ++#define FACILITIES_LEN 20 ++ const char *facility_keys[FACILITIES_LEN] = { ++ "kern", "user", "mail", "daemon", "auth", ++ "syslog", "lpr", "news", "uucp", "cron", "authpriv", "ftp", ++ "local0", "local1", "local2", "local3", "local4", "local5", "local6", "local7" ++ }; ++ const int facilities[FACILITIES_LEN] = { ++ LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON, LOG_AUTH, LOG_SYSLOG, ++ LOG_LPR, LOG_NEWS, LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_FTP, ++ LOG_LOCAL0, LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4, ++ LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7 ++ }; ++ int i = 0; ++ ++ if (facility == NULL) { ++ return -1; ++ } ++ ++ for (; i < FACILITIES_LEN; i++) { ++ if (strcmp(facility, facility_keys[i]) == 0) { ++ return facilities[i]; ++ } ++ } ++ ++ return -1; ++} ++ ++static int set_config_console_syslog_facility(const char *key, const char *value, ++ struct lxc_conf *lxc_conf, void *data) ++{ ++ int facility; ++ ++ facility = parse_facility(value); ++ if (facility < 0) { ++ NOTICE("Invalid facility: %s", value); ++ facility = LOG_DAEMON; ++ } ++ ++ lxc_conf->console.log_syslog_facility = facility; ++ return 0; ++} ++ ++static int get_config_console_log_driver(const char *key, char *retv, int inlen, ++ struct lxc_conf *c, void *data) ++{ ++ return lxc_get_conf_str(retv, inlen, c->console.log_driver); ++} ++ ++static int get_config_console_syslog_tag(const char *key, char *retv, int inlen, ++ struct lxc_conf *c, void *data) ++{ ++ return lxc_get_conf_str(retv, inlen, c->console.log_syslog_tag); ++} ++ ++static int get_config_console_syslog_facility(const char *key, char *retv, int inlen, ++ struct lxc_conf *c, void *data) ++{ ++ return lxc_get_conf_int(c, retv, inlen, c->console.log_syslog_facility); ++} ++ ++static inline int clr_config_console_log_driver(const char *key, ++ struct lxc_conf *c, void *data) ++{ ++ free(c->console.log_driver); ++ c->console.log_driver = NULL; ++ return 0; ++} ++ ++static inline int clr_config_console_syslog_tag(const char *key, ++ struct lxc_conf *c, void *data) ++{ ++ free(c->console.log_syslog_tag); ++ c->console.log_syslog_tag= NULL; ++ return 0; ++} ++ ++static inline int clr_config_console_syslog_facility(const char *key, ++ struct lxc_conf *c, void *data) ++{ ++ c->console.log_syslog_facility = LOG_DAEMON; ++ return 0; ++} ++ + #endif +diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c +index e696b4e4..9b831dc2 100644 +--- a/src/lxc/terminal.c ++++ b/src/lxc/terminal.c +@@ -30,6 +30,7 @@ + #include "utils.h" + #ifdef HAVE_ISULAD + #include "logger_json_file.h" ++#include "include/strlcpy.h" + #endif + + #if HAVE_PTY_H +@@ -535,7 +536,7 @@ static int isulad_lxc_terminal_rotate_write_data(struct lxc_terminal *terminal, + return bytes_read; + } + +-static ssize_t isulad_logger_write(struct lxc_terminal *terminal, const char *type, const char *buf, ++static ssize_t isulad_logger_json_write(struct lxc_terminal *terminal, const char *type, const char *buf, + int bytes_read) + { + logger_json_file *msg = NULL; +@@ -579,6 +580,31 @@ cleanup: + return ret; + } + ++static ssize_t isulad_logger_syslog_write(struct lxc_terminal *terminal, const char *buf) ++{ ++ syslog(LOG_INFO, "%s", buf); ++ return 0; ++} ++ ++static inline bool is_syslog(const char *driver) ++{ ++ if (driver == NULL) { ++ return false; ++ } ++ ++ return (strcmp("syslog", driver) == 0); ++} ++ ++static inline ssize_t isulad_logger_write(struct lxc_terminal *terminal, const char *type, const char *buf, ++ int bytes_read) ++{ ++ if (is_syslog(terminal->log_driver)) { ++ return isulad_logger_syslog_write(terminal, buf); ++ } ++ ++ return isulad_logger_json_write(terminal, type, buf, bytes_read); ++} ++ + static int isulad_lxc_terminal_write_log_file(struct lxc_terminal *terminal, const char *type, char *buf, + int bytes_read) + { +@@ -1385,6 +1411,10 @@ void lxc_terminal_delete(struct lxc_terminal *terminal) + terminal->log_fd = -1; + + #ifdef HAVE_ISULAD ++ if (is_syslog(terminal->log_driver)) { ++ closelog(); ++ free(terminal->log_driver); ++ } + /* isulad: close all pipes */ + if (terminal->pipes[0][0] >= 0) + close(terminal->pipes[0][0]); +@@ -1776,6 +1806,18 @@ int lxc_terminal_setup(struct lxc_conf *conf) + if (ret < 0) + return -1; + ++#ifdef HAVE_ISULAD ++ if (is_syslog(terminal->log_driver)) { ++ if (terminal->log_syslog_tag == NULL) { ++ terminal->log_syslog_tag = malloc(16 * sizeof(char)); ++ (void)strlcpy(terminal->log_syslog_tag, conf->name, 16); ++ } ++ if (terminal->log_syslog_facility <= 0) { ++ terminal->log_syslog_facility = LOG_DAEMON; ++ } ++ openlog(terminal->log_syslog_tag, LOG_PID, terminal->log_syslog_facility); ++ } ++#endif + ret = lxc_terminal_create_log_file(terminal); + if (ret < 0) + goto err; +diff --git a/src/lxc/terminal.h b/src/lxc/terminal.h +index f49142dc..9de4cd05 100644 +--- a/src/lxc/terminal.h ++++ b/src/lxc/terminal.h +@@ -79,6 +79,16 @@ struct lxc_terminal { + + /* whether the log file will be rotated */ + unsigned int log_rotate; ++#ifdef HAVE_ISULAD ++ /* driver of log, support file and syslog */ ++ char *log_driver; ++ ++ /* syslog tag for every log */ ++ char *log_syslog_tag; ++ ++ /* syslog facility */ ++ int log_syslog_facility; ++#endif + }; + + struct /* lxc_terminal_ringbuf */ { +-- +2.25.3 + diff --git a/0059-delete-unused-variable-ppid.patch b/0059-delete-unused-variable-ppid.patch deleted file mode 100644 index abce72775e78fea5ca6e1437d97e6a2b51329007..0000000000000000000000000000000000000000 --- a/0059-delete-unused-variable-ppid.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 72e156f81d0db66d42724172a9d4b6fefbd6fabc Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Tue, 12 Feb 2019 14:36:35 +0800 -Subject: [PATCH 059/140] delete unused variable ppid - -Signed-off-by: tanyifeng -Signed-off-by: LiFeng ---- - src/lxc/utils.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index 0aa87aa..91ba493 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -1716,7 +1716,7 @@ uint64_t lxc_find_next_power2(uint64_t n) - int lxc_set_death_signal(int signal, pid_t parent) - { - int ret; -- pid_t ppid; -+ //pid_t ppid; - - ret = prctl(PR_SET_PDEATHSIG, prctl_arg(signal), prctl_arg(0), - prctl_arg(0), prctl_arg(0)); --- -1.8.3.1 - diff --git a/0060-using-json-file-to-write-console-log-of-container.patch b/0060-using-json-file-to-write-console-log-of-container.patch deleted file mode 100644 index 3d0e757623e88440ef279e42bc448ced9ac4e77e..0000000000000000000000000000000000000000 --- a/0060-using-json-file-to-write-console-log-of-container.patch +++ /dev/null @@ -1,610 +0,0 @@ -From d402202eb37433f26c1e9f4ab11ce8e530ad19e7 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Wed, 30 Jan 2019 17:44:19 +0800 -Subject: [PATCH 060/140] using json-file to write console log of container - -Signed-off-by: tanyifeng -Signed-off-by: LiFeng ---- - src/lxc/Makefile.am | 2 + - src/lxc/json/json_common.c | 14 ++- - src/lxc/json/json_common.h | 2 + - src/lxc/json/logger_json_file.c | 243 ++++++++++++++++++++++++++++++++++++++++ - src/lxc/json/logger_json_file.h | 45 ++++++++ - src/lxc/terminal.c | 166 +++++++++++++++++++++++++-- - 6 files changed, 457 insertions(+), 15 deletions(-) - create mode 100644 src/lxc/json/logger_json_file.c - create mode 100644 src/lxc/json/logger_json_file.h - -diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am -index 260a7eb..698f8f9 100644 ---- a/src/lxc/Makefile.am -+++ b/src/lxc/Makefile.am -@@ -47,6 +47,7 @@ noinst_HEADERS = attach.h \ - json/json_common.h \ - json/oci_runtime_hooks.h \ - json/oci_runtime_spec.h \ -+ json/logger_json_file.h \ - json/read-file.h \ - utils.h - -@@ -149,6 +150,7 @@ liblxc_la_SOURCES = af_unix.c af_unix.h \ - json/json_common.c json/json_common.h \ - json/defs.h json/defs.c \ - json/oci_runtime_hooks.c json/oci_runtime_hooks.h \ -+ json/logger_json_file.c json/logger_json_file.h \ - json/oci_runtime_spec.c json/oci_runtime_spec.h \ - json/read-file.c json/read-file.h \ - $(LSM_SOURCES) -diff --git a/src/lxc/json/json_common.c b/src/lxc/json/json_common.c -index 8b91844..e339ab3 100755 ---- a/src/lxc/json/json_common.c -+++ b/src/lxc/json/json_common.c -@@ -86,7 +86,7 @@ bool json_gen_init(yajl_gen *g, struct parser_context *ctx) { - - } - yajl_gen_config(*g, yajl_gen_beautify, !(ctx->options & GEN_OPTIONS_SIMPLIFY)); -- yajl_gen_config(*g, yajl_gen_validate_utf8, 1); -+ yajl_gen_config(*g, yajl_gen_validate_utf8, !(ctx->options & GEN_OPTIONS_NOT_VALIDATE_UTF8)); - return true; - } - -@@ -1156,7 +1156,7 @@ json_map_string_string *make_json_map_string_string(yajl_val src, struct parser_ - return ret; - } - int append_json_map_string_string(json_map_string_string *map, const char *key, const char *val) { -- size_t len; -+ size_t len, i; - char **keys; - char **vals; - -@@ -1164,6 +1164,14 @@ int append_json_map_string_string(json_map_string_string *map, const char *key, - return -1; - } - -+ for (i = 0; i < map->len; i++) { -+ if (strcmp(map->keys[i], key) == 0) { -+ free(map->values[i]); -+ map->values[i] = safe_strdup(val ? val : ""); -+ return 0; -+ } -+ } -+ - if ((SIZE_MAX / sizeof(char *) - 1) < map->len) { - return -1; - } -@@ -1193,4 +1201,4 @@ int append_json_map_string_string(json_map_string_string *map, const char *key, - - map->len++; - return 0; --} -+} -\ No newline at end of file -diff --git a/src/lxc/json/json_common.h b/src/lxc/json/json_common.h -index 904fe3c..eb8281c 100755 ---- a/src/lxc/json/json_common.h -+++ b/src/lxc/json/json_common.h -@@ -23,6 +23,8 @@ extern "C" { - # define GEN_OPTIONS_ALLKEYVALUE 0x02 - //options to generate simplify(no indent) json string - # define GEN_OPTIONS_SIMPLIFY 0x04 -+//options not to validate utf8 data -+# define GEN_OPTIONS_NOT_VALIDATE_UTF8 0x08 - - #define GEN_SET_ERROR_AND_RETURN(stat, err) { \ - if (!*(err)) {\ -diff --git a/src/lxc/json/logger_json_file.c b/src/lxc/json/logger_json_file.c -new file mode 100644 -index 0000000..4d78103 ---- /dev/null -+++ b/src/lxc/json/logger_json_file.c -@@ -0,0 +1,243 @@ -+// Generated from json-file.json. Do not edit! -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE -+#endif -+#include -+#include -+#include "securec.h" -+#include "logger_json_file.h" -+ -+logger_json_file *make_logger_json_file(yajl_val tree, struct parser_context *ctx, parser_error *err) { -+ logger_json_file *ret = NULL; -+ *err = 0; -+ if (tree == NULL) -+ return ret; -+ ret = safe_malloc(sizeof(*ret)); -+ { -+ yajl_val tmp = get_val(tree, "log", yajl_t_string); -+ if (tmp) { -+ char *str = YAJL_GET_STRING(tmp); -+ ret->log = (uint8_t *)safe_strdup(str ? str : ""); -+ ret->log_len = str ? strlen(str) : 0; -+ } -+ } -+ { -+ yajl_val val = get_val(tree, "stream", yajl_t_string); -+ if (val) { -+ char *str = YAJL_GET_STRING(val); -+ ret->stream = safe_strdup(str ? str : ""); -+ } -+ } -+ { -+ yajl_val val = get_val(tree, "time", yajl_t_string); -+ if (val) { -+ char *str = YAJL_GET_STRING(val); -+ ret->time = safe_strdup(str ? str : ""); -+ } -+ } -+ { -+ yajl_val tmp = get_val(tree, "attrs", yajl_t_string); -+ if (tmp) { -+ char *str = YAJL_GET_STRING(tmp); -+ ret->attrs = (uint8_t *)safe_strdup(str ? str : ""); -+ ret->attrs_len = str ? strlen(str) : 0; -+ } -+ } -+ -+ if (tree->type == yajl_t_object && (ctx->options & PARSE_OPTIONS_STRICT)) { -+ int i; -+ for (i = 0; i < tree->u.object.len; i++) -+ if (strcmp(tree->u.object.keys[i], "log") && -+ strcmp(tree->u.object.keys[i], "stream") && -+ strcmp(tree->u.object.keys[i], "time") && -+ strcmp(tree->u.object.keys[i], "attrs")) { -+ if (ctx->stderr > 0) -+ fprintf(ctx->stderr, "WARNING: unknown key found: %s\n", tree->u.object.keys[i]); -+ } -+ } -+ return ret; -+} -+ -+void free_logger_json_file(logger_json_file *ptr) { -+ if (!ptr) -+ return; -+ free(ptr->log); -+ ptr->log = NULL; -+ free(ptr->stream); -+ ptr->stream = NULL; -+ free(ptr->time); -+ ptr->time = NULL; -+ free(ptr->attrs); -+ ptr->attrs = NULL; -+ free(ptr); -+} -+ -+yajl_gen_status gen_logger_json_file(yajl_gen g, logger_json_file *ptr, struct parser_context *ctx, parser_error *err) { -+ yajl_gen_status stat = yajl_gen_status_ok; -+ *err = 0; -+ stat = reformat_start_map(g); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) || (ptr && ptr->log && ptr->log_len)) { -+ const char *str = ""; -+ size_t len = 0; -+ stat = reformat_map_key(g, "log", strlen("log")); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (ptr && ptr->log) { -+ str = (const char *)ptr->log; -+ len = ptr->log_len; -+ } -+ stat = reformat_string(g, str, len); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr && ptr->stream)) { -+ char *str = ""; -+ stat = reformat_map_key(g, "stream", strlen("stream")); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (ptr && ptr->stream) { -+ str = ptr->stream; -+ } -+ stat = reformat_string(g, str, strlen(str)); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr && ptr->time)) { -+ char *str = ""; -+ stat = reformat_map_key(g, "time", strlen("time")); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (ptr && ptr->time) { -+ str = ptr->time; -+ } -+ stat = reformat_string(g, str, strlen(str)); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) || (ptr && ptr->attrs && ptr->attrs_len)) { -+ const char *str = ""; -+ size_t len = 0; -+ stat = reformat_map_key(g, "attrs", strlen("attrs")); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (ptr && ptr->attrs) { -+ str = (const char *)ptr->attrs; -+ len = ptr->attrs_len; -+ } -+ stat = reformat_string(g, str, len); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ stat = reformat_end_map(g); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ return yajl_gen_status_ok; -+} -+ -+ -+logger_json_file *logger_json_file_parse_file(const char *filename, struct parser_context *ctx, parser_error *err) { -+ logger_json_file *ptr; -+ size_t filesize; -+ char *content; -+ -+ if (!filename || !err) -+ return NULL; -+ -+ *err = NULL; -+ content = read_file(filename, &filesize); -+ if (content == NULL) { -+ if (asprintf(err, "cannot read the file: %s", filename) < 0) -+ *err = safe_strdup("error allocating memory"); -+ return NULL; -+ } -+ ptr = logger_json_file_parse_data(content, ctx, err); -+ free(content); -+ return ptr; -+} -+ -+logger_json_file *logger_json_file_parse_file_stream(FILE *stream, struct parser_context *ctx, parser_error *err) { -+ logger_json_file *ptr; -+ size_t filesize; -+ char *content ; -+ -+ if (!stream || !err) -+ return NULL; -+ -+ *err = NULL; -+ content = fread_file(stream, &filesize); -+ if (content == NULL) { -+ *err = safe_strdup("cannot read the file"); -+ return NULL; -+ } -+ ptr = logger_json_file_parse_data(content, ctx, err); -+ free(content); -+ return ptr; -+} -+ -+logger_json_file *logger_json_file_parse_data(const char *jsondata, struct parser_context *ctx, parser_error *err) { -+ logger_json_file *ptr; -+ yajl_val tree; -+ char errbuf[1024]; -+ struct parser_context tmp_ctx; -+ -+ if (!jsondata || !err) -+ return NULL; -+ -+ *err = NULL; -+ if (!ctx) { -+ ctx = &tmp_ctx; -+ memset(&tmp_ctx, 0, sizeof(tmp_ctx)); -+ } -+ tree = yajl_tree_parse(jsondata, errbuf, sizeof(errbuf)); -+ if (tree == NULL) { -+ if (asprintf(err, "cannot parse the data: %s", errbuf) < 0) -+ *err = safe_strdup("error allocating memory"); -+ return NULL; -+ } -+ ptr = make_logger_json_file(tree, ctx, err); -+ yajl_tree_free(tree); -+ return ptr; -+} -+char *logger_json_file_generate_json(logger_json_file *ptr, struct parser_context *ctx, parser_error *err) { -+ yajl_gen g = NULL; -+ struct parser_context tmp_ctx; -+ const unsigned char *gen_buf = NULL; -+ char *json_buf = NULL; -+ size_t gen_len = 0; -+ -+ if (!ptr || !err) -+ return NULL; -+ -+ *err = NULL; -+ if (!ctx) { -+ ctx = &tmp_ctx; -+ memset(&tmp_ctx, 0, sizeof(tmp_ctx)); -+ } -+ -+ if (!json_gen_init(&g, ctx)) { -+ *err = safe_strdup("Json_gen init failed"); -+ goto out; -+ } -+ if (yajl_gen_status_ok != gen_logger_json_file(g, ptr, ctx, err)) { -+ if (!*err) -+ *err = safe_strdup("Failed to generate json"); -+ goto free_out; -+ } -+ yajl_gen_get_buf(g, &gen_buf, &gen_len); -+ if (!gen_buf) { -+ *err = safe_strdup("Error to get generated json"); -+ goto free_out; -+ } -+ -+ json_buf = safe_malloc(gen_len + 1); -+ memcpy(json_buf, gen_buf, gen_len); -+ json_buf[gen_len] = '\0'; -+ -+free_out: -+ yajl_gen_clear(g); -+ yajl_gen_free(g); -+out: -+ return json_buf; -+} -diff --git a/src/lxc/json/logger_json_file.h b/src/lxc/json/logger_json_file.h -new file mode 100644 -index 0000000..ad5af7b ---- /dev/null -+++ b/src/lxc/json/logger_json_file.h -@@ -0,0 +1,45 @@ -+// Generated from json-file.json. Do not edit! -+#ifndef LOGGER_JSON_FILE_SCHEMA_H -+#define LOGGER_JSON_FILE_SCHEMA_H -+ -+#include -+#include -+#include "json_common.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+typedef struct { -+ uint8_t *log; -+ size_t log_len; -+ -+ char *stream; -+ -+ char *time; -+ -+ uint8_t *attrs; -+ size_t attrs_len; -+ -+} -+logger_json_file; -+ -+void free_logger_json_file(logger_json_file *ptr); -+ -+logger_json_file *make_logger_json_file(yajl_val tree, struct parser_context *ctx, parser_error *err); -+ -+yajl_gen_status gen_logger_json_file(yajl_gen g, logger_json_file *ptr, struct parser_context *ctx, parser_error *err); -+ -+logger_json_file *logger_json_file_parse_file(const char *filename, struct parser_context *ctx, parser_error *err); -+ -+logger_json_file *logger_json_file_parse_file_stream(FILE *stream, struct parser_context *ctx, parser_error *err); -+ -+logger_json_file *logger_json_file_parse_data(const char *jsondata, struct parser_context *ctx, parser_error *err); -+ -+char *logger_json_file_generate_json(logger_json_file *ptr, struct parser_context *ctx, parser_error *err); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif -diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index 252a644..602d43d 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -47,6 +47,7 @@ - #include "start.h" - #include "syscall_wrappers.h" - #include "terminal.h" -+#include "logger_json_file.h" - #include "utils.h" - - #if HAVE_PTY_H -@@ -298,7 +299,7 @@ static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal) - return lxc_terminal_create_log_file(terminal); - } - --static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf, -+static int lxc_terminal_rotate_write_data(struct lxc_terminal *terminal, const char *buf, - int bytes_read) - { - int ret; -@@ -357,16 +358,6 @@ static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf, - if (bytes_read <= space_left) - return lxc_write_nointr(terminal->log_fd, buf, bytes_read); - -- /* There's not enough space left but at least write as much as we can -- * into the old log file. -- */ -- ret = lxc_write_nointr(terminal->log_fd, buf, space_left); -- if (ret < 0) -- return -1; -- -- /* Calculate how many bytes we still need to write. */ -- bytes_read -= space_left; -- - /* There'd be more to write but we aren't instructed to rotate the log - * file so simply return. There's no error on our side here. - */ -@@ -404,6 +395,151 @@ static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf, - return bytes_read; - } - -+/* get time buffer */ -+static bool get_time_buffer(struct timespec *timestamp, char *timebuffer, -+ size_t maxsize) -+{ -+ struct tm tm_utc = { 0 }; -+ int32_t nanos = 0; -+ time_t seconds; -+ -+ if (!timebuffer || !maxsize) { -+ return false; -+ } -+ -+ seconds = (time_t)timestamp->tv_sec; -+ gmtime_r(&seconds, &tm_utc); -+ strftime(timebuffer, maxsize, "%Y-%m-%dT%H:%M:%S", &tm_utc); -+ -+ nanos = (int32_t)timestamp->tv_nsec; -+ sprintf(timebuffer + strlen(timebuffer), ".%09dZ", nanos); -+ -+ return true; -+} -+ -+/* get now time buffer */ -+static bool get_now_time_buffer(char *timebuffer, size_t maxsize) -+{ -+ int err = 0; -+ struct timespec ts; -+ -+ err = clock_gettime(CLOCK_REALTIME, &ts); -+ if (err != 0) { -+ ERROR("failed to get time"); -+ return false; -+ } -+ -+ return get_time_buffer(&ts, timebuffer, maxsize); -+} -+ -+static ssize_t lxc_logger_write(struct lxc_terminal *terminal, const char *buf, -+ int bytes_read) -+{ -+ logger_json_file *msg = NULL; -+ ssize_t ret = -1; -+ size_t len; -+ char *json = NULL, timebuffer[64]; -+ parser_error err = NULL; -+ struct parser_context ctx = { GEN_OPTIONS_SIMPLIFY | GEN_OPTIONS_NOT_VALIDATE_UTF8, stderr }; -+ -+ msg = calloc(sizeof(logger_json_file), 1); -+ if (!msg) { -+ return -errno; -+ } -+ msg->log = calloc(bytes_read, 1); -+ if (!msg->log) { -+ goto cleanup; -+ } -+ memcpy(msg->log, buf, bytes_read); -+ msg->log_len = bytes_read; -+ msg->stream = strdup("stdout"); -+ -+ get_now_time_buffer(timebuffer, sizeof(timebuffer)); -+ msg->time = strdup(timebuffer); -+ -+ json = logger_json_file_generate_json(msg, &ctx, &err); -+ if (!json) { -+ ERROR("Failed to generate json: %s", err); -+ goto cleanup; -+ } -+ len = strlen(json); -+ json[len] = '\n'; -+ ret = lxc_terminal_rotate_write_data(terminal, json, len + 1); -+cleanup: -+ free(json); -+ free_logger_json_file(msg); -+ free(err); -+ return ret; -+} -+ -+static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf, -+ int bytes_read) -+{ -+#define __BUF_CACHE_SIZE (16 * LXC_TERMINAL_BUFFER_SIZE) -+ static char cache[__BUF_CACHE_SIZE]; -+ static int size = 0; -+ int upto, index; -+ int begin = 0, buf_readed = 0, buf_left = 0; -+ int ret; -+ -+ if (buf != NULL && bytes_read > 0) { -+ /* Work out how much more data we are okay with reading this time. */ -+ upto = size + bytes_read; -+ if (upto > __BUF_CACHE_SIZE) { -+ upto = __BUF_CACHE_SIZE; -+ } -+ -+ if (upto > size) { -+ buf_readed = upto - size; -+ memcpy(cache + size, buf, buf_readed); -+ buf_left = bytes_read - buf_readed; -+ size += buf_readed; -+ } -+ } -+ -+ // If we have no data to log, and there's no more coming, we're done. -+ if (size == 0) -+ return 0; -+ -+ // Break up the data that we've buffered up into lines, and log each in turn. -+ for (index = 0; index < size; index++) { -+ if (cache[index] == '\n') { -+ ret = lxc_logger_write(terminal, cache + begin, index - begin + 1); -+ if (ret < 0) { -+ WARN("Failed to log msg"); -+ } -+ begin = index + 1; -+ } -+ } -+ /* If there's no more coming, or the buffer is full but -+ * has no newlines, log whatever we haven't logged yet, -+ * noting that it's a partial log line. */ -+ if (buf == NULL || (begin == 0 && size == __BUF_CACHE_SIZE)) { -+ if (begin < size) { -+ ret = lxc_logger_write(terminal, cache + begin, index - begin + 1); -+ if (ret < 0) { -+ WARN("Failed to log msg"); -+ } -+ begin = 0; -+ size = 0; -+ } -+ if (buf == NULL) { -+ return 0; -+ } -+ } -+ /* Move any unlogged data to the front of the buffer in preparation for another read. */ -+ if (begin > 0) { -+ memcpy(cache, cache + begin, size - begin); -+ size -= begin; -+ } -+ /* Move left data to cache buffer */ -+ if (buf_left > 0) { -+ memcpy(cache + size, buf + buf_readed, buf_left); -+ size += buf_left; -+ } -+ return 0; -+} -+ - /* isulad: forward data to all fifos */ - static void lxc_forward_data_to_fifo(struct lxc_list *list, char *buf, int r) - { -@@ -437,7 +573,7 @@ int lxc_terminal_io_cb(int fd, uint32_t events, void *data, - struct lxc_epoll_descr *descr) - { - struct lxc_terminal *terminal = data; -- char buf[LXC_TERMINAL_BUFFER_SIZE]; -+ char buf[2 * LXC_TERMINAL_BUFFER_SIZE]; - int r, w, w_log, w_rbuf; - - w = r = lxc_read_nointr(fd, buf, sizeof(buf)); -@@ -447,6 +583,12 @@ int lxc_terminal_io_cb(int fd, uint32_t events, void *data, - - if (fd == terminal->master) { - terminal->master = -EBADF; -+ /* write remained buffer to terminal log */ -+ if (terminal->log_fd >= 0) { -+ w_log = lxc_terminal_write_log_file(terminal, NULL, 0); -+ if (w_log < 0) -+ TRACE("Failed to write %d bytes to terminal log", r); -+ } - } else if (fd == terminal->peer) { - if (terminal->tty_state) { - lxc_terminal_signal_fini(terminal->tty_state); --- -1.8.3.1 - diff --git a/0061-Fix-hook-use-the-path-args-envs-execvp-dirctory.patch b/0061-Fix-hook-use-the-path-args-envs-execvp-dirctory.patch deleted file mode 100644 index 5ba91265342fa3b61cb766524e80e4bcb2da111c..0000000000000000000000000000000000000000 --- a/0061-Fix-hook-use-the-path-args-envs-execvp-dirctory.patch +++ /dev/null @@ -1,50 +0,0 @@ -From fee671d0cd2813016f7d84fad2907ba28c24993d Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Thu, 21 Feb 2019 05:37:05 -0500 -Subject: [PATCH 061/140] Fix hook: use the path, args, envs execvp dirctory - -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 17 ++--------------- - 1 file changed, 2 insertions(+), 15 deletions(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 67beefe..c2f3cf5 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4467,9 +4467,6 @@ static struct lxc_popen_FILE *lxc_popen_ocihook(char *commandpath, char **args, - - if (child_pid == 0) { - /* child */ -- size_t result_capacity; -- int r; -- char **real_args; - - close(pipe_msg[1]); - if (pipe_msg[0] != STDIN_FILENO) -@@ -4514,20 +4511,10 @@ static struct lxc_popen_FILE *lxc_popen_ocihook(char *commandpath, char **args, - sigprocmask(SIG_UNBLOCK, &mask, NULL); - } - -- result_capacity = args_len; -- real_args = malloc(sizeof(char *) * (result_capacity + 2 + 1)); -- if (!real_args) -- _exit(EXIT_FAILURE); -- memset(real_args, 0, sizeof(char *) * (result_capacity + 2 + 1)); -- real_args[0] = strdup("sh"); -- real_args[1] = strdup(commandpath); -- for(r = 2; r < (args_len + 1); r++) -- real_args[r] = strdup(args[r-1]); -- - if (env_len > 0) -- execvpe("/bin/sh", real_args, envs); -+ execvpe(commandpath, args, envs); - else -- execvp("/bin/sh", real_args); -+ execvp(commandpath, args); - exit(127); - } - --- -1.8.3.1 - diff --git a/0062-setup-sysctls-before-set-read-only-path-and-masked-p.patch b/0062-setup-sysctls-before-set-read-only-path-and-masked-p.patch deleted file mode 100644 index d3e62d636be3918d4df515e44c0ed6933012de46..0000000000000000000000000000000000000000 --- a/0062-setup-sysctls-before-set-read-only-path-and-masked-p.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 6fc3c7a016b64583c9f84f90c5303376b4f8f613 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Tue, 26 Feb 2019 17:21:18 +0800 -Subject: [PATCH 062/140] setup sysctls before set read-only path and masked - path - -Signed-off-by: tanyifeng -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 34 +++++++++++++++++----------------- - 1 file changed, 17 insertions(+), 17 deletions(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index c2f3cf5..e139dff 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -3039,7 +3039,7 @@ int setup_sysctl_parameters(struct lxc_list *sysctls) - ret = lxc_write_to_file(filename, elem->value, - strlen(elem->value), false, 0666); - if (ret < 0) { -- ERROR("Failed to setup sysctl parameters %s to %s", -+ SYSERROR("Failed to setup sysctl parameters %s to %s", - elem->key, elem->value); - return -1; - } -@@ -4201,22 +4201,6 @@ int lxc_setup(struct lxc_handler *handler) - if (ret < 0) - goto on_error; - -- //isulad: setup rootfs masked paths -- if (!lxc_list_empty(&lxc_conf->rootfs.maskedpaths)) { -- if (setup_rootfs_maskedpaths(&lxc_conf->rootfs.maskedpaths)) { -- ERROR("failed to setup maskedpaths"); -- goto on_error; -- } -- } -- -- // isulad: setup rootfs ro paths -- if (!lxc_list_empty(&lxc_conf->rootfs.ropaths)) { -- if (setup_rootfs_ropaths(&lxc_conf->rootfs.ropaths)) { -- ERROR("failed to setup readonlypaths"); -- goto on_error; -- } -- } -- - /*isulad: set system umask */ - umask(lxc_conf->umask); - -@@ -4238,6 +4222,22 @@ int lxc_setup(struct lxc_handler *handler) - } - } - -+ // isulad: setup rootfs masked paths -+ if (!lxc_list_empty(&lxc_conf->rootfs.maskedpaths)) { -+ if (setup_rootfs_maskedpaths(&lxc_conf->rootfs.maskedpaths)) { -+ ERROR("failed to setup maskedpaths"); -+ goto on_error; -+ } -+ } -+ -+ // isulad: setup rootfs ro paths -+ if (!lxc_list_empty(&lxc_conf->rootfs.ropaths)) { -+ if (setup_rootfs_ropaths(&lxc_conf->rootfs.ropaths)) { -+ ERROR("failed to setup readonlypaths"); -+ goto on_error; -+ } -+ } -+ - if (!lxc_list_empty(&lxc_conf->keepcaps)) { - if (!lxc_list_empty(&lxc_conf->caps)) { - ERROR("Container requests lxc.cap.drop and " --- -1.8.3.1 - diff --git a/0064-lxc-Reduce-seccomp-processing-log-level.patch b/0064-lxc-Reduce-seccomp-processing-log-level.patch deleted file mode 100644 index 7bd66f0c16cc9144d1fbd18364ffd75d0a5510de..0000000000000000000000000000000000000000 --- a/0064-lxc-Reduce-seccomp-processing-log-level.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 5c4a3db298a0a7857f6bb34a285c40e6f2a4b99b Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Sun, 10 Mar 2019 00:47:05 +0800 -Subject: [PATCH 064/140] lxc: Reduce seccomp processing log level - -Signed-off-by: wujing -Signed-off-by: LiFeng ---- - src/lxc/seccomp.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/src/lxc/seccomp.c b/src/lxc/seccomp.c -index 26eac90..7f10777 100644 ---- a/src/lxc/seccomp.c -+++ b/src/lxc/seccomp.c -@@ -507,14 +507,14 @@ bool do_resolve_add_rule(uint32_t arch, char *line, scmp_filter_ctx ctx, - - nr = seccomp_syscall_resolve_name(line); - if (nr == __NR_SCMP_ERROR) { -- WARN("Failed to resolve syscall \"%s\"", line); -- WARN("This syscall will NOT be handled by seccomp"); -+ DEBUG("Failed to resolve syscall \"%s\"", line); -+ DEBUG("This syscall will NOT be handled by seccomp"); - return true; - } - - if (nr < 0) { -- WARN("Got negative return value %d for syscall \"%s\"", nr, line); -- WARN("This syscall will NOT be handled by seccomp"); -+ DEBUG("Got negative return value %d for syscall \"%s\"", nr, line); -+ DEBUG("This syscall will NOT be handled by seccomp"); - return true; - } - -@@ -541,7 +541,7 @@ bool do_resolve_add_rule(uint32_t arch, char *line, scmp_filter_ctx ctx, - rule->args_num, arg_cmp); - if (ret < 0) { - errno = -ret; -- SYSERROR("Failed loading rule for %s (nr %d action %d (%s))", -+ DEBUG("Failed loading rule for %s (nr %d action %d (%s))", - line, nr, rule->action, get_action_name(rule->action)); - return true; - } --- -1.8.3.1 - diff --git a/0065-Storage-return-true-if-storage_init-init-fail.patch b/0065-Storage-return-true-if-storage_init-init-fail.patch deleted file mode 100644 index 9a6fbfe9ca3386cd6c5a4de28d95c1c76b3581bf..0000000000000000000000000000000000000000 --- a/0065-Storage-return-true-if-storage_init-init-fail.patch +++ /dev/null @@ -1,30 +0,0 @@ -From c3f85efe70c8dabe1c7393a5fd83f4465ec46812 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Mon, 11 Mar 2019 23:26:27 -0400 -Subject: [PATCH 065/140] Storage: return true if storage_init init fail - -Signed-off-by: LiFeng ---- - src/lxc/storage/storage.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/src/lxc/storage/storage.c b/src/lxc/storage/storage.c -index 18f754a..88ed788 100644 ---- a/src/lxc/storage/storage.c -+++ b/src/lxc/storage/storage.c -@@ -610,8 +610,11 @@ bool storage_destroy(struct lxc_conf *conf) - int destroy_rv = 0; - - r = storage_init(conf); -- if (!r) -+ if (r == NULL) { -+ ERROR("%s 's storage init failed, the storage may be deleted already", conf->name); -+ ret = true; - return ret; -+ } - - destroy_rv = r->ops->destroy(r); - if (destroy_rv == 0) --- -1.8.3.1 - diff --git a/0066-lxc-Pids-limit-does-not-report-an-error-after-execut.patch b/0066-lxc-Pids-limit-does-not-report-an-error-after-execut.patch deleted file mode 100644 index 7958457285af5a52a960f986ea72b8d1381bda09..0000000000000000000000000000000000000000 --- a/0066-lxc-Pids-limit-does-not-report-an-error-after-execut.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 54a21ab4594e606168d690ef09bbbd13329de843 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Fri, 15 Mar 2019 10:11:10 +0800 -Subject: [PATCH 066/140] lxc: Pids limit does not report an error after - executing the limit in the background - -Signed-off-by: wujing -Signed-off-by: LiFeng ---- - src/lxc/tools/lxc_attach.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c -index 8856934..acdf8a0 100644 ---- a/src/lxc/tools/lxc_attach.c -+++ b/src/lxc/tools/lxc_attach.c -@@ -378,6 +378,8 @@ static int do_attach_background(struct lxc_container *c, lxc_attach_command_t *c - if (ret < 0) { - if (c->lxc_conf->errmsg) - lxc_write_error_message(msgpipe[1], "%s", c->lxc_conf->errmsg); -+ else -+ lxc_write_error_message(msgpipe[1], "Failed to attach container"); - close(msgpipe[1]); - msgpipe[1] = -1; - ret = -1; --- -1.8.3.1 - diff --git a/0067-lxc-report-error-when-remove-directory-failed.patch b/0067-lxc-report-error-when-remove-directory-failed.patch deleted file mode 100644 index 07078d4195b1b0c7412f628301ac512ebb2a2641..0000000000000000000000000000000000000000 --- a/0067-lxc-report-error-when-remove-directory-failed.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 8f356ca0106a31ac7a14a17d06fb325aa16519ee Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Sat, 16 Mar 2019 10:06:13 +0800 -Subject: [PATCH 067/140] lxc: report error when remove directory failed - -Signed-off-by: tanyifeng -Signed-off-by: LiFeng ---- - src/lxc/lxccontainer.c | 3 +++ - src/lxc/utils.c | 9 ++++++++- - 2 files changed, 11 insertions(+), 1 deletion(-) - -diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index bfbf223..3fd1a66 100644 ---- a/src/lxc/lxccontainer.c -+++ b/src/lxc/lxccontainer.c -@@ -3148,8 +3148,11 @@ static bool container_destroy(struct lxc_container *c, - else - ret = lxc_rmdir_onedev(path, "snaps"); - if (ret < 0) { -+ char msg[BUFSIZ] = { 0 }; - ERROR("Failed to destroy directory \"%s\" for \"%s\"", path, - c->name); -+ sprintf(msg, "Failed to destroy directory \"%s\": %s", path, errno ? strerror(errno) : "error"); -+ c->error_string = strdup(msg); - goto out; - } - INFO("Destroyed directory \"%s\" for \"%s\"", path, c->name); -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index 91ba493..480e6d0 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -88,6 +88,7 @@ static int _recursive_rmdir(const char *dirname, dev_t pdev, - int ret, failed = 0; - char pathname[PATH_MAX]; - bool hadexclude = false; -+ int saved_errno = 0; - - dir = opendir(dirname); - if (!dir) { -@@ -153,6 +154,9 @@ static int _recursive_rmdir(const char *dirname, dev_t pdev, - failed=1; - } else { - if (unlink(pathname) < 0) { -+ if (saved_errno == 0) { -+ saved_errno = errno; -+ } - SYSERROR("Failed to delete \"%s\"", pathname); - failed=1; - } -@@ -160,6 +164,9 @@ static int _recursive_rmdir(const char *dirname, dev_t pdev, - } - - if (rmdir(dirname) < 0 && !btrfs_try_remove_subvol(dirname) && !hadexclude) { -+ if (saved_errno == 0) { -+ saved_errno = errno; -+ } - SYSERROR("Failed to delete \"%s\"", dirname); - failed=1; - } -@@ -169,7 +176,7 @@ static int _recursive_rmdir(const char *dirname, dev_t pdev, - SYSERROR("Failed to close directory \"%s\"", dirname); - failed=1; - } -- -+ errno = saved_errno; - return failed ? -1 : 0; - } - --- -1.8.3.1 - diff --git a/0068-support-record-stdout-stderr-log-of-container-consol.patch b/0068-support-record-stdout-stderr-log-of-container-consol.patch deleted file mode 100644 index 50ec371cdc46f87c366a949e303a0731df067176..0000000000000000000000000000000000000000 --- a/0068-support-record-stdout-stderr-log-of-container-consol.patch +++ /dev/null @@ -1,1244 +0,0 @@ -From 8168df14e2a9c51a2d1637485d45e957d0a23438 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Thu, 21 Feb 2019 20:27:47 +0800 -Subject: [PATCH 068/140] support record stdout, stderr log of container - console - -Signed-off-by: tanyifeng -Signed-off-by: LiFeng ---- - src/lxc/attach.c | 15 +- - src/lxc/attach_options.h | 2 +- - src/lxc/commands.c | 15 +- - src/lxc/commands.h | 2 +- - src/lxc/conf.c | 33 +++-- - src/lxc/lxccontainer.c | 79 +++++++--- - src/lxc/lxccontainer.h | 35 ++++- - src/lxc/start.c | 67 ++++++++- - src/lxc/start.h | 5 + - src/lxc/terminal.c | 351 ++++++++++++++++++++++++++++++++------------- - src/lxc/terminal.h | 7 +- - src/lxc/tools/arguments.h | 14 +- - src/lxc/tools/lxc_attach.c | 7 +- - src/lxc/tools/lxc_start.c | 22 ++- - 14 files changed, 502 insertions(+), 152 deletions(-) - -diff --git a/src/lxc/attach.c b/src/lxc/attach.c -index 9768897..c979c85 100644 ---- a/src/lxc/attach.c -+++ b/src/lxc/attach.c -@@ -1052,15 +1052,18 @@ static int lxc_attach_terminal(struct lxc_conf *conf, - lxc_terminal_init(terminal); - - /* isulad: if we pass fifo in option, use them as init fifos */ -- if (options->init_fifo[0] && options->init_fifo[1]) { -- if (terminal->init_fifo[0]) -- free(terminal->init_fifo[0]); -+ if (options->init_fifo[0]) { -+ free(terminal->init_fifo[0]); - terminal->init_fifo[0] = strdup(options->init_fifo[0]); -- -- if (terminal->init_fifo[1]) -- free(terminal->init_fifo[1]); -+ } -+ if (options->init_fifo[1]) { -+ free(terminal->init_fifo[1]); - terminal->init_fifo[1] = strdup(options->init_fifo[1]); - } -+ if (options->init_fifo[2]) { -+ free(terminal->init_fifo[2]); -+ terminal->init_fifo[2] = strdup(options->init_fifo[2]); -+ } - - ret = lxc_terminal_create(terminal); - if (ret < 0) { -diff --git a/src/lxc/attach_options.h b/src/lxc/attach_options.h -index 7b0a8cb..71c1739 100644 ---- a/src/lxc/attach_options.h -+++ b/src/lxc/attach_options.h -@@ -136,7 +136,7 @@ typedef struct lxc_attach_options_t { - /*! File descriptor to log output. */ - int log_fd; - -- char *init_fifo[2]; /* isulad: default fifos for the start */ -+ char *init_fifo[3]; /* isulad: default fifos for the start */ - } lxc_attach_options_t; - - /*! Default attach options to use */ -diff --git a/src/lxc/commands.c b/src/lxc/commands.c -index 46b2805..f0c95df 100644 ---- a/src/lxc/commands.c -+++ b/src/lxc/commands.c -@@ -1064,21 +1064,22 @@ reap_client_fd: - * - * Returns 0 when success, else when fail. - */ --int lxc_cmd_set_terminal_fifos(const char *name, const char *lxcpath, const char *in_fifo, const char *out_fifo) -+int lxc_cmd_set_terminal_fifos(const char *name, const char *lxcpath, const char *in_fifo, -+ const char *out_fifo, const char *err_fifo) - { - int ret = 0, stopped = 0; - int len = 0; - char *tmp = NULL; -+ const char *split = "&&&&", *none_fifo_name = "none"; -+ const char *cmd_in_fifo = in_fifo ? in_fifo : none_fifo_name; -+ const char *cmd_out_fifo = out_fifo ? out_fifo : none_fifo_name; -+ const char *cmd_err_fifo = err_fifo ? err_fifo : none_fifo_name; - -- if (!in_fifo || !out_fifo) { -- return -1; -- } -- -- len = strlen(in_fifo) + strlen("&&&&") + strlen(out_fifo) + 1; -+ len += strlen(cmd_in_fifo) + strlen(split) + strlen(cmd_out_fifo) + strlen(split) + strlen(cmd_err_fifo) + 1; - tmp = malloc(len); - if (!tmp) - return -1; -- snprintf(tmp, len, "%s%s%s", in_fifo, "&&&&", out_fifo); -+ snprintf(tmp, len, "%s%s%s%s%s", cmd_in_fifo, split, cmd_out_fifo, split, cmd_err_fifo); - - struct lxc_cmd_rr cmd = { - .req = { -diff --git a/src/lxc/commands.h b/src/lxc/commands.h -index 0c64544..6b64849 100644 ---- a/src/lxc/commands.h -+++ b/src/lxc/commands.h -@@ -127,6 +127,6 @@ extern int lxc_cmd_console_log(const char *name, const char *lxcpath, - struct lxc_console_log *log); - - extern int lxc_cmd_set_terminal_fifos(const char *name, const char *lxcpath, -- const char *in_fifo, const char *out_fifo); -+ const char *in_fifo, const char *out_fifo, const char *err_fifo); - - #endif /* __commands_h */ -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index e139dff..a6b9797 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -2067,20 +2067,22 @@ static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs, - return -errno; - } - -- ret = fchmod(console->slave, S_IXUSR | S_IXGRP); -- if (ret < 0) { -- SYSERROR("Failed to set mode \"0%o\" to \"%s\"", -- S_IXUSR | S_IXGRP, console->name); -- return -errno; -- } -+ if (console->slave > 0) { -+ ret = fchmod(console->slave, S_IXUSR | S_IXGRP); -+ if (ret < 0) { -+ SYSERROR("Failed to set mode \"0%o\" to \"%s\"", -+ S_IXUSR | S_IXGRP, console->name); -+ return -errno; -+ } - -- /* bind mount console->name to '/dev//console' */ -- ret = safe_mount(console->name, lxcpath, "none", MS_BIND, 0, rootfs_path); -- if (ret < 0) { -- ERROR("Failed to mount \"%s\" on \"%s\"", console->name, lxcpath); -- return -1; -+ /* bind mount console->name to '/dev//console' */ -+ ret = safe_mount(console->name, lxcpath, "none", MS_BIND, 0, rootfs_path); -+ if (ret < 0) { -+ ERROR("Failed to mount \"%s\" on \"%s\"", console->name, lxcpath); -+ return -1; -+ } -+ DEBUG("Mounted \"%s\" onto \"%s\"", console->name, lxcpath); - } -- DEBUG("Mounted \"%s\" onto \"%s\"", console->name, lxcpath); - - /* bind mount '/dev//console' to '/dev/console' */ - ret = safe_mount(lxcpath, path, "none", MS_BIND, 0, rootfs_path); -@@ -3158,6 +3160,13 @@ struct lxc_conf *lxc_conf_init(void) - /* isulad init console fifos */ - new->console.init_fifo[0] = NULL; - new->console.init_fifo[1] = NULL; -+ new->console.init_fifo[2] = NULL; -+ new->console.pipes[0][0] = -1; -+ new->console.pipes[0][1] = -1; -+ new->console.pipes[1][0] = -1; -+ new->console.pipes[1][1] = -1; -+ new->console.pipes[2][0] = -1; -+ new->console.pipes[2][1] = -1; - lxc_list_init(&new->console.fifos); - - new->errmsg = NULL; -diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index 3fd1a66..8a3724c 100644 ---- a/src/lxc/lxccontainer.c -+++ b/src/lxc/lxccontainer.c -@@ -702,6 +702,40 @@ static bool do_lxcapi_want_daemonize(struct lxc_container *c, bool state) - - WRAP_API_1(bool, lxcapi_want_daemonize, bool) - -+static bool do_lxcapi_want_disable_pty(struct lxc_container *c, bool state) -+{ -+ if (!c || !c->lxc_conf) -+ return false; -+ -+ if (container_mem_lock(c)) -+ return false; -+ -+ c->disable_pty = state; -+ -+ container_mem_unlock(c); -+ -+ return true; -+} -+ -+WRAP_API_1(bool, lxcapi_want_disable_pty, bool) -+ -+static bool do_lxcapi_want_open_stdin(struct lxc_container *c, bool state) -+{ -+ if (!c || !c->lxc_conf) -+ return false; -+ -+ if (container_mem_lock(c)) -+ return false; -+ -+ c->open_stdin = state; -+ -+ container_mem_unlock(c); -+ -+ return true; -+} -+ -+WRAP_API_1(bool, lxcapi_want_open_stdin, bool) -+ - static bool do_lxcapi_want_close_all_fds(struct lxc_container *c, bool state) - { - if (!c || !c->lxc_conf) -@@ -1198,12 +1232,15 @@ reboot: - goto on_error; - } - -- if (useinit) -+ if (useinit) { - ret = lxc_execute(c->name, argv, 1, handler, c->config_path, - c->daemonize, &c->error_num, c->start_timeout); -- else -+ } else { -+ handler->disable_pty = c->disable_pty; -+ handler->open_stdin = c->open_stdin; - ret = lxc_start(c->name, argv, handler, c->config_path, - c->daemonize, &c->error_num, c->start_timeout); -+ } - - if (conf->reboot == REBOOT_REQ) { - INFO("Container requested reboot"); -@@ -5085,11 +5122,11 @@ out: - } - - /* isulad add set console fifos*/ --static bool do_lxcapi_set_terminal_default_fifos(struct lxc_container *c, const char *in, const char *out) -+static bool do_lxcapi_set_terminal_default_fifos(struct lxc_container *c, const char *in, const char *out, const char *err) - { - struct lxc_conf *conf; - -- if (!c || !c->lxc_conf || !in || !out) -+ if (!c || !c->lxc_conf) - return false; - if (container_mem_lock(c)) { - ERROR("Error getting mem lock"); -@@ -5097,19 +5134,27 @@ static bool do_lxcapi_set_terminal_default_fifos(struct lxc_container *c, const - } - - conf = c->lxc_conf; -- if (conf->console.init_fifo[0]) -- free(conf->console.init_fifo[0]); -- conf->console.init_fifo[0] = strdup(in); -- -- if (conf->console.init_fifo[1]) -- free(conf->console.init_fifo[1]); -- conf->console.init_fifo[1] = strdup(out); -+ if (in) { -+ if (conf->console.init_fifo[0]) -+ free(conf->console.init_fifo[0]); -+ conf->console.init_fifo[0] = strdup(in); -+ } -+ if (out) { -+ if (conf->console.init_fifo[1]) -+ free(conf->console.init_fifo[1]); -+ conf->console.init_fifo[1] = strdup(out); -+ } -+ if (err) { -+ if (conf->console.init_fifo[2]) -+ free(conf->console.init_fifo[2]); -+ conf->console.init_fifo[2] = strdup(err); -+ } - - container_mem_unlock(c); - return true; - } - --WRAP_API_2(bool, lxcapi_set_terminal_default_fifos, const char *, const char *) -+WRAP_API_3(bool, lxcapi_set_terminal_default_fifos, const char *, const char *, const char *) - - /* isulad add set info file path */ - static bool do_lxcapi_set_container_info_file(struct lxc_container *c, const char *info_file) -@@ -5168,18 +5213,18 @@ static bool do_lxcapi_clean_container_resource(struct lxc_container *c, pid_t pi - WRAP_API_1(bool, lxcapi_clean_container_resource, pid_t) - - /* isulad add clean resources */ --static bool do_lxcapi_add_terminal_fifo(struct lxc_container *c, const char *in_fifo, const char *out_fifo) -+static bool do_lxcapi_add_terminal_fifo(struct lxc_container *c, const char *in_fifo, const char *out_fifo, const char *err_fifo) - { - bool ret = true; - -- if (!c || !c->lxc_conf || !in_fifo || !out_fifo) -+ if (!c || !c->lxc_conf) - return false; - if (container_mem_lock(c)) { - ERROR("Error getting mem lock"); - return false; - } - -- if (lxc_cmd_set_terminal_fifos(c->name, c->config_path, in_fifo, out_fifo)) { -+ if (lxc_cmd_set_terminal_fifos(c->name, c->config_path, in_fifo, out_fifo, err_fifo)) { - ERROR("Error set console fifos"); - ret = false; - } -@@ -5188,7 +5233,7 @@ static bool do_lxcapi_add_terminal_fifo(struct lxc_container *c, const char *in_ - return ret; - } - --WRAP_API_2(bool, lxcapi_add_terminal_fifo, const char *, const char *) -+WRAP_API_3(bool, lxcapi_add_terminal_fifo, const char *, const char *, const char *) - - static struct lxc_container *do_lxc_container_new(const char *name, const char *configpath, bool load_config) - { -@@ -5274,6 +5319,8 @@ static struct lxc_container *do_lxc_container_new(const char *name, const char * - c->init_pid = lxcapi_init_pid; - c->load_config = lxcapi_load_config; - c->want_daemonize = lxcapi_want_daemonize; -+ c->want_disable_pty = lxcapi_want_disable_pty; -+ c->want_open_stdin = lxcapi_want_open_stdin; - c->want_close_all_fds = lxcapi_want_close_all_fds; - c->start = lxcapi_start; - c->startl = lxcapi_startl; -diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h -index c1d83ba..c3368e4 100644 ---- a/src/lxc/lxccontainer.h -+++ b/src/lxc/lxccontainer.h -@@ -137,6 +137,15 @@ struct lxc_container { - /*! Whether container wishes to be daemonized */ - bool daemonize; - -+ /*! Whether container wishes to create pty or pipes for console log */ -+ bool disable_pty; -+ -+ /*! Whether container wishes to keep stdin active */ -+ bool open_stdin; -+ -+ /*! Whether container wishes to detach from container stdio */ -+ bool detach; -+ - /*! Full path to configuration file */ - char *config_path; - -@@ -244,6 +253,28 @@ struct lxc_container { - bool (*stop)(struct lxc_container *c); - - /*! -+ * \brief Change whether the container wants to create pty or pipes -+ * from the console log. -+ * -+ * \param c Container. -+ * \param state Value for the disable pty bit (0 or 1). -+ * -+ * \return \c true on success, else \c false. -+ */ -+ bool (*want_disable_pty)(struct lxc_container *c, bool state); -+ -+ /*! -+ * \brief Change whether the container wants to keep stdin active -+ * for parent process of container -+ * -+ * \param c Container. -+ * \param state Value for the open_stdin bit (0 or 1). -+ * -+ * \return \c true on success, else \c false. -+ */ -+ bool (*want_open_stdin)(struct lxc_container *c, bool state); -+ -+ /*! - * \brief Change whether the container wants to run disconnected - * from the terminal. - * -@@ -875,7 +906,7 @@ struct lxc_container { - * - * \return \c true on success, else \c false. - */ -- bool (*set_terminal_init_fifos)(struct lxc_container *c, const char *in, const char *out); -+ bool (*set_terminal_init_fifos)(struct lxc_container *c, const char *in, const char *out, const char *err); - - /*! isulad add - * \brief An API call to add the path of terminal fifos -@@ -885,7 +916,7 @@ struct lxc_container { - * - * \return \c true on success, else \c false. - */ -- bool (*add_terminal_fifos)(struct lxc_container *c, const char *in, const char *out); -+ bool (*add_terminal_fifos)(struct lxc_container *c, const char *in, const char *out, const char *err); - - /*! isulad add - * \brief An API call to set the path of info file -diff --git a/src/lxc/start.c b/src/lxc/start.c -index 816b4a2..cad0d76 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -635,6 +635,13 @@ int lxc_poll(const char *name, struct lxc_handler *handler) - } - - TRACE("Mainloop is ready"); -+ // iSulad: close stdin pipe if we do not want open_stdin with container stdin -+ if (!handler->conf->console.open_stdin) { -+ if (handler->conf->console.pipes[0][1] > 0) { -+ close(handler->conf->console.pipes[0][1]); -+ handler->conf->console.pipes[0][1] = -1; -+ } -+ } - - ret = lxc_mainloop(&descr, -1); - close(descr.epfd); -@@ -788,6 +795,8 @@ int lxc_init(const char *name, struct lxc_handler *handler) - int ret; - const char *loglevel; - struct lxc_conf *conf = handler->conf; -+ conf->console.disable_pty = handler->disable_pty; -+ conf->console.open_stdin = handler->open_stdin; - - lsm_init(); - TRACE("Initialized LSM"); -@@ -1244,7 +1253,7 @@ static int do_start(void *data) - * means that migration won't work, but at least we won't spew output - * where it isn't wanted. - */ -- if (handler->daemonize && !handler->conf->autodev) { -+ if (!handler->disable_pty && handler->daemonize && !handler->conf->autodev) { - ret = access(path, F_OK); - if (ret != 0) { - devnull_fd = open_devnull(); -@@ -1325,6 +1334,42 @@ static int do_start(void *data) - "privileges"); - } - -+ /* isulad: dup2 pipe[0][0] to container stdin, pipe[1][1] to container stdout, pipe[2][1] to container stderr */ -+ if (handler->disable_pty) { -+ if (handler->conf->console.pipes[0][1] >= 0) { -+ close(handler->conf->console.pipes[0][1]); -+ handler->conf->console.pipes[0][1] = -1; -+ } -+ -+ if (handler->conf->console.pipes[0][0] >= 0) { -+ ret = dup2(handler->conf->console.pipes[0][0], STDIN_FILENO); -+ if (ret < 0) -+ goto out_warn_father; -+ } -+ -+ if (handler->conf->console.pipes[1][0] >= 0) { -+ close(handler->conf->console.pipes[1][0]); -+ handler->conf->console.pipes[1][0] = -1; -+ } -+ -+ if (handler->conf->console.pipes[1][1] >= 0) { -+ ret = dup2(handler->conf->console.pipes[1][1], STDOUT_FILENO); -+ if (ret < 0) -+ goto out_warn_father; -+ } -+ if (handler->conf->console.pipes[2][0] >= 0) { -+ close(handler->conf->console.pipes[2][0]); -+ handler->conf->console.pipes[2][0] = -1; -+ } -+ -+ if (handler->conf->console.pipes[2][1] >= 0) { -+ ret = dup2(handler->conf->console.pipes[2][1], STDERR_FILENO); -+ if (ret < 0) -+ goto out_warn_father; -+ } -+ -+ } -+ - /* Some init's such as busybox will set sane tty settings on stdin, - * stdout, stderr which it thinks is the console. We already set them - * the way we wanted on the real terminal, and we want init to do its -@@ -1332,7 +1377,7 @@ static int do_start(void *data) - * make sure that that pty is stdin,stdout,stderr. - */ - setsid(); -- if (handler->conf->console.slave >= 0) { -+ if (!handler->disable_pty && handler->conf->console.slave >= 0) { - /* isulad:make the given terminal as controlling terminal to avoid warning - * sh: cannot set terminal process group (-1): Inappropriate ioctl for device - * sh: no job control in this shell */ -@@ -1367,7 +1412,7 @@ static int do_start(void *data) - - close(handler->sigfd); - -- if (handler->conf->console.slave < 0 && handler->daemonize) { -+ if (!handler->disable_pty && handler->conf->console.slave < 0 && handler->daemonize) { - if (devnull_fd < 0) { - devnull_fd = open_devnull(); - if (devnull_fd < 0) -@@ -1789,6 +1834,22 @@ static int lxc_spawn(struct lxc_handler *handler) - } - TRACE("Cloned child process %d", handler->pid); - -+ /* isulad: close pipe after clone */ -+ if (handler->conf->console.pipes[0][0] >= 0) { -+ close(handler->conf->console.pipes[0][0]); -+ handler->conf->console.pipes[0][0] = -1; -+ } -+ -+ if (handler->conf->console.pipes[1][1] >= 0) { -+ close(handler->conf->console.pipes[1][1]); -+ handler->conf->console.pipes[1][1] = -1; -+ } -+ -+ if (handler->conf->console.pipes[2][1] >= 0) { -+ close(handler->conf->console.pipes[2][1]); -+ handler->conf->console.pipes[2][1] = -1; -+ } -+ - /* isulad: save pid/ppid info into file*/ - if (handler->conf->container_info_file) { - if (lxc_save_container_info(handler->conf->container_info_file, handler->pid)) { -diff --git a/src/lxc/start.h b/src/lxc/start.h -index ab72e6e..0298991 100644 ---- a/src/lxc/start.h -+++ b/src/lxc/start.h -@@ -99,6 +99,11 @@ struct lxc_handler { - /* Indicates whether should we close std{in,out,err} on start. */ - bool daemonize; - -+ /* Indicates whether should we using pipes or pty dup to std{in,out,err} for console log. */ -+ bool disable_pty; -+ /* Indicates whether should we keep stdin active. */ -+ bool open_stdin; -+ - /* The child's pid. */ - pid_t pid; - -diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index 602d43d..dfce92e 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -432,7 +432,7 @@ static bool get_now_time_buffer(char *timebuffer, size_t maxsize) - return get_time_buffer(&ts, timebuffer, maxsize); - } - --static ssize_t lxc_logger_write(struct lxc_terminal *terminal, const char *buf, -+static ssize_t lxc_logger_write(struct lxc_terminal *terminal, const char *type, const char *buf, - int bytes_read) - { - logger_json_file *msg = NULL; -@@ -452,7 +452,7 @@ static ssize_t lxc_logger_write(struct lxc_terminal *terminal, const char *buf, - } - memcpy(msg->log, buf, bytes_read); - msg->log_len = bytes_read; -- msg->stream = strdup("stdout"); -+ msg->stream = type ? strdup(type) : strdup("stdout"); - - get_now_time_buffer(timebuffer, sizeof(timebuffer)); - msg->time = strdup(timebuffer); -@@ -472,7 +472,7 @@ cleanup: - return ret; - } - --static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf, -+static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, const char *type, char *buf, - int bytes_read) - { - #define __BUF_CACHE_SIZE (16 * LXC_TERMINAL_BUFFER_SIZE) -@@ -504,7 +504,7 @@ static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf, - // Break up the data that we've buffered up into lines, and log each in turn. - for (index = 0; index < size; index++) { - if (cache[index] == '\n') { -- ret = lxc_logger_write(terminal, cache + begin, index - begin + 1); -+ ret = lxc_logger_write(terminal, type, cache + begin, index - begin + 1); - if (ret < 0) { - WARN("Failed to log msg"); - } -@@ -516,7 +516,7 @@ static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf, - * noting that it's a partial log line. */ - if (buf == NULL || (begin == 0 && size == __BUF_CACHE_SIZE)) { - if (begin < size) { -- ret = lxc_logger_write(terminal, cache + begin, index - begin + 1); -+ ret = lxc_logger_write(terminal, type, cache + begin, index - begin + 1); - if (ret < 0) { - WARN("Failed to log msg"); - } -@@ -541,14 +541,20 @@ static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, char *buf, - } - - /* isulad: forward data to all fifos */ --static void lxc_forward_data_to_fifo(struct lxc_list *list, char *buf, int r) -+static void lxc_forward_data_to_fifo(struct lxc_list *list, bool is_err, char *buf, int r) - { - struct lxc_list *it,*next; - struct lxc_fifos_fd *elem = NULL; - - lxc_list_for_each_safe(it, list, next) { - elem = it->elem; -- lxc_write_nointr(elem->out_fd, buf, r); -+ if (is_err) { -+ if (elem->err_fd >= 0) -+ lxc_write_nointr(elem->err_fd, buf, r); -+ } else { -+ if (elem->out_fd >= 0) -+ lxc_write_nointr(elem->out_fd, buf, r); -+ } - } - - return; -@@ -585,7 +591,7 @@ int lxc_terminal_io_cb(int fd, uint32_t events, void *data, - terminal->master = -EBADF; - /* write remained buffer to terminal log */ - if (terminal->log_fd >= 0) { -- w_log = lxc_terminal_write_log_file(terminal, NULL, 0); -+ w_log = lxc_terminal_write_log_file(terminal, "stdout", NULL, 0); - if (w_log < 0) - TRACE("Failed to write %d bytes to terminal log", r); - } -@@ -601,33 +607,57 @@ int lxc_terminal_io_cb(int fd, uint32_t events, void *data, - /* isulad: delete fifos when the client close */ - lxc_terminal_delete_fifo(fd, &terminal->fifos); - return LXC_MAINLOOP_CONTINUE; -- } else { -+ } else if (fd == terminal->pipes[1][0] || fd == terminal->pipes[2][0]) { -+ if (fd == terminal->pipes[1][0]) { -+ w_log = lxc_terminal_write_log_file(terminal, "stdout", NULL, 0); -+ terminal->pipes[1][0] = -EBADF; -+ } else if (fd == terminal->pipes[2][0]) { -+ w_log = lxc_terminal_write_log_file(terminal, "stderr", NULL, 0); -+ terminal->pipes[2][0] = -EBADF; -+ } -+ if (w_log < 0) -+ TRACE("Failed to write %d bytes to terminal log", r); -+ close(fd); -+ return LXC_MAINLOOP_CONTINUE; -+ } else if (fd == terminal->pipes[0][1]) { -+ TRACE("closed stdin pipe of container stdin"); -+ terminal->pipes[0][1] = -EBADF; -+ close(fd); -+ return LXC_MAINLOOP_CONTINUE; -+ } else { - ERROR("Handler received unexpected file descriptor"); - } - close(fd); -- - return LXC_MAINLOOP_CLOSE; - } - -- if (fd == terminal->peer || lxc_terminal_is_fifo(fd, &terminal->fifos)) -- w = lxc_write_nointr(terminal->master, buf, r); -+ if (fd == terminal->peer || lxc_terminal_is_fifo(fd, &terminal->fifos)) { -+ if (terminal->master > 0) -+ w = lxc_write_nointr(terminal->master, buf, r); -+ if (terminal->pipes[0][1] > 0) -+ w = lxc_write_nointr(terminal->pipes[0][1], buf, r); -+ } - - w_rbuf = w_log = 0; -- if (fd == terminal->master) { -+ if (fd == terminal->master || fd == terminal->pipes[1][0] || fd == terminal->pipes[2][0]) { - /* write to peer first */ - if (terminal->peer >= 0) - w = lxc_write_nointr(terminal->peer, buf, r); - - /* isulad: forward data to fifos */ -- lxc_forward_data_to_fifo(&terminal->fifos, buf, r); -+ lxc_forward_data_to_fifo(&terminal->fifos, fd == terminal->pipes[2][0], buf, r); - - /* write to terminal ringbuffer */ - if (terminal->buffer_size > 0) - w_rbuf = lxc_ringbuf_write(&terminal->ringbuf, buf, r); - - /* write to terminal log */ -- if (terminal->log_fd >= 0) -- w_log = lxc_terminal_write_log_file(terminal, buf, r); -+ if (terminal->log_fd >= 0) { -+ if (fd == terminal->master || fd == terminal->pipes[1][0]) -+ w_log = lxc_terminal_write_log_file(terminal, "stdout", buf, r); -+ else if (fd == terminal->pipes[2][0]) -+ w_log = lxc_terminal_write_log_file(terminal, "stderr", buf, r); -+ } - } - - if (w != r) -@@ -670,6 +700,41 @@ static int lxc_terminal_mainloop_add_peer(struct lxc_terminal *terminal) - return 0; - } - -+/* isulad add pipes to mainloop */ -+static int lxc_terminal_mainloop_add_pipes(struct lxc_terminal *terminal) -+{ -+ int ret = 0; -+ -+ // parent read data from fifo, and send to stdin of container -+ if (terminal->pipes[0][1] > 0) { -+ ret = lxc_mainloop_add_handler(terminal->descr, terminal->pipes[0][1], -+ lxc_terminal_io_cb, terminal); -+ if (ret) { -+ ERROR("pipe fd %d not added to mainloop", terminal->pipes[0][1]); -+ return -1; -+ } -+ } -+ // parent read data from stdout of container, and send to fifo -+ if (terminal->pipes[1][0] > 0) { -+ ret = lxc_mainloop_add_handler(terminal->descr, terminal->pipes[1][0], -+ lxc_terminal_io_cb, terminal); -+ if (ret) { -+ ERROR("pipe fd %d not added to mainloop", terminal->pipes[1][0]); -+ return -1; -+ } -+ } -+ // parent read data from stderr of container, and send to fifo -+ if (terminal->pipes[2][0] > 0) { -+ ret = lxc_mainloop_add_handler(terminal->descr, terminal->pipes[2][0], -+ lxc_terminal_io_cb, terminal); -+ if (ret) { -+ ERROR("pipe fd %d not added to mainloop", terminal->pipes[2][0]); -+ return -1; -+ } -+ } -+ return ret; -+} -+ - /* isulad add fifo to mainloop */ - static int lxc_terminal_mainloop_add_fifo(struct lxc_terminal *terminal) - { -@@ -696,19 +761,6 @@ int lxc_terminal_mainloop_add(struct lxc_epoll_descr *descr, - { - int ret; - -- if (terminal->master < 0) { -- INFO("Terminal is not initialized"); -- return 0; -- } -- -- ret = lxc_mainloop_add_handler(descr, terminal->master, -- lxc_terminal_io_cb, terminal); -- if (ret < 0) { -- ERROR("Failed to add handler for terminal master fd %d to " -- "mainloop", terminal->master); -- return -1; -- } -- - /* We cache the descr so that we can add an fd to it when someone - * does attach to it in lxc_terminal_allocate(). - */ -@@ -720,6 +772,13 @@ int lxc_terminal_mainloop_add(struct lxc_epoll_descr *descr, - return -1; - } - -+ /* isulad add pipes to mainloop */ -+ ret = lxc_terminal_mainloop_add_pipes(terminal); -+ if (ret < 0) { -+ ERROR("Failed to add handler for terminal fifos to mainloop"); -+ return -1; -+ } -+ - /* isulad add fifo to mainloop */ - ret = lxc_terminal_mainloop_add_fifo(terminal); - if (ret < 0) { -@@ -727,6 +786,19 @@ int lxc_terminal_mainloop_add(struct lxc_epoll_descr *descr, - return -1; - } - -+ if (terminal->master < 0) { -+ INFO("Terminal is not initialized"); -+ return 0; -+ } -+ -+ ret = lxc_mainloop_add_handler(descr, terminal->master, -+ lxc_terminal_io_cb, terminal); -+ if (ret < 0) { -+ ERROR("Failed to add handler for terminal master fd %d to " -+ "mainloop", terminal->master); -+ return -1; -+ } -+ - return 0; - } - -@@ -1082,6 +1154,26 @@ void lxc_terminal_delete(struct lxc_terminal *terminal) - close(terminal->log_fd); - terminal->log_fd = -1; - -+ /* isulad: close all pipes */ -+ if (terminal->pipes[0][0] >= 0) -+ close(terminal->pipes[0][0]); -+ terminal->pipes[0][0] = -1; -+ if (terminal->pipes[0][1] >= 0) -+ close(terminal->pipes[0][1]); -+ terminal->pipes[0][1] = -1; -+ if (terminal->pipes[1][0] >= 0) -+ close(terminal->pipes[1][0]); -+ terminal->pipes[1][0] = -1; -+ if (terminal->pipes[1][1] >= 0) -+ close(terminal->pipes[1][1]); -+ terminal->pipes[1][1] = -1; -+ if (terminal->pipes[2][0] >= 0) -+ close(terminal->pipes[2][0]); -+ terminal->pipes[2][0] = -1; -+ if (terminal->pipes[2][1] >= 0) -+ close(terminal->pipes[2][1]); -+ terminal->pipes[2][1] = -1; -+ - /* isulad: delete all fifos */ - lxc_terminal_delete_fifo(-1, &terminal->fifos); - } -@@ -1168,59 +1260,79 @@ static int terminal_fifo_open(const char *fifo_path, int flags) - } - - /* isulad: set terminal fifos */ --static int lxc_terminal_set_fifo(struct lxc_terminal *console, const char *in, const char *out) -+static int lxc_terminal_set_fifo(struct lxc_terminal *console, const char *in, const char *out, const char *err, int *input_fd) - { -- int fifofd_in = -1, fifofd_out = -1; -+ int fifofd_in = -1, fifofd_out = -1, fifofd_err = -1; - struct lxc_fifos_fd *fifo_elem = NULL; - -- if (!in || !out) -+ if ((in && !fifo_exists(in)) || (out && !fifo_exists(out)) || (err && !fifo_exists(err))) { -+ ERROR("File %s or %s or %s does not refer to a FIFO", in, out, err); - return -1; -+ } - -- if (!fifo_exists(in) || !fifo_exists(out)) { -- ERROR("File %s or %s does not refer to a FIFO", in, out); -- return -1; -+ if (in) { -+ fifofd_in = terminal_fifo_open(in, O_RDONLY | O_NONBLOCK | O_CLOEXEC); -+ if (fifofd_in < 0) { -+ SYSERROR("Failed to open FIFO: %s", in); -+ return -1; -+ } - } - -- fifofd_in = terminal_fifo_open(in, O_RDONLY | O_NONBLOCK | O_CLOEXEC); -- if (fifofd_in < 0) { -- ERROR("Failed to open FIFO: %s", in); -- return -1; -+ if (out) { -+ fifofd_out = terminal_fifo_open(out, O_WRONLY | O_NONBLOCK | O_CLOEXEC); -+ if (fifofd_out < 0) { -+ SYSERROR("Failed to open FIFO: %s", out); -+ if (fifofd_in >= 0) -+ close(fifofd_in); -+ return -1; -+ } - } - -- fifofd_out = terminal_fifo_open(out, O_WRONLY | O_NONBLOCK | O_CLOEXEC); -- if (fifofd_out < 0) { -- ERROR("Failed to open FIFO: %s", out); -- close(fifofd_in); -- return -1; -+ if (err) { -+ fifofd_err = terminal_fifo_open(err, O_WRONLY | O_NONBLOCK | O_CLOEXEC); -+ if (fifofd_err < 0) { -+ SYSERROR("Failed to open FIFO: %s", err); -+ if (fifofd_in >= 0) -+ close(fifofd_in); -+ if (fifofd_out >= 0) -+ close(fifofd_out); -+ return -1; -+ } - } - - fifo_elem = malloc(sizeof(*fifo_elem)); - if (!fifo_elem) { -- close(fifofd_in); -- close(fifofd_out); -+ if (fifofd_in >= 0) -+ close(fifofd_in); -+ if (fifofd_out >= 0) -+ close(fifofd_out); -+ if (fifofd_err >= 0) -+ close(fifofd_err); - return -1; - } - memset(fifo_elem, 0, sizeof(*fifo_elem)); - -- fifo_elem->in_fifo = strdup(in); -- fifo_elem->out_fifo = strdup(out); -+ fifo_elem->in_fifo = strdup(in ? in : ""); -+ fifo_elem->out_fifo = strdup(out ? out : ""); -+ fifo_elem->err_fifo = strdup(err ? err : ""); - fifo_elem->in_fd = fifofd_in; - fifo_elem->out_fd = fifofd_out; -+ fifo_elem->err_fd = fifofd_err; - lxc_list_add_elem(&fifo_elem->node, fifo_elem); - lxc_list_add_tail(&console->fifos, &fifo_elem->node); - -- return fifofd_in; -+ if (input_fd) -+ *input_fd = fifofd_in; -+ -+ return 0; - } - - /* isulad: add default fifos */ - static int lxc_terminal_fifo_default(struct lxc_terminal *terminal) - { -- if (!terminal->init_fifo[0] || !terminal->init_fifo[1]) { -- DEBUG("Invalid default terminal fifos"); -- return 0; -- } -- -- return lxc_terminal_set_fifo(terminal, terminal->init_fifo[0], terminal->init_fifo[1]); -+ if (terminal->init_fifo[0] || terminal->init_fifo[1] || terminal->init_fifo[2]) -+ return lxc_terminal_set_fifo(terminal, terminal->init_fifo[0], terminal->init_fifo[1], terminal->init_fifo[2], NULL); -+ return 0; - } - - /* -@@ -1245,48 +1357,67 @@ int lxc_terminal_create(struct lxc_terminal *terminal) - { - int ret; - -- ret = openpty(&terminal->master, &terminal->slave, NULL, NULL, NULL); -- if (ret < 0) { -- SYSERROR("Failed to open terminal"); -- return -1; -- } -+ if (!terminal->disable_pty) { -+ ret = openpty(&terminal->master, &terminal->slave, NULL, NULL, NULL); -+ if (ret < 0) { -+ SYSERROR("Failed to open terminal"); -+ return -1; -+ } - -- ret = ttyname_r(terminal->slave, terminal->name, sizeof(terminal->name)); -- if (ret < 0) { -- SYSERROR("Failed to retrieve name of terminal slave"); -- goto err; -- } -+ ret = ttyname_r(terminal->slave, terminal->name, sizeof(terminal->name)); -+ if (ret < 0) { -+ SYSERROR("Failed to retrieve name of terminal slave"); -+ goto err; -+ } - -- /* isulad: clear ONLCR flag */ -- ret = use_unix_newline(terminal->master); -- if (ret < 0) { -- SYSERROR("Failed to clear ONLCR flag on terminal master"); -- goto err; -- } -+ /* isulad: clear ONLCR flag */ -+ ret = use_unix_newline(terminal->master); -+ if (ret < 0) { -+ SYSERROR("Failed to clear ONLCR flag on terminal master"); -+ goto err; -+ } - -- ret = fd_cloexec(terminal->master, true); -- if (ret < 0) { -- SYSERROR("Failed to set FD_CLOEXEC flag on terminal master"); -- goto err; -- } -+ ret = fd_cloexec(terminal->master, true); -+ if (ret < 0) { -+ SYSERROR("Failed to set FD_CLOEXEC flag on terminal master"); -+ goto err; -+ } - -- /* isulad: make master NONBLOCK */ -- ret = fd_nonblock(terminal->master); -- if (ret < 0) { -- SYSERROR("Failed to set O_NONBLOCK flag on terminal master"); -- goto err; -- } -+ /* isulad: make master NONBLOCK */ -+ ret = fd_nonblock(terminal->master); -+ if (ret < 0) { -+ SYSERROR("Failed to set O_NONBLOCK flag on terminal master"); -+ goto err; -+ } - -- ret = fd_cloexec(terminal->slave, true); -- if (ret < 0) { -- SYSERROR("Failed to set FD_CLOEXEC flag on terminal slave"); -- goto err; -- } -+ ret = fd_cloexec(terminal->slave, true); -+ if (ret < 0) { -+ SYSERROR("Failed to set FD_CLOEXEC flag on terminal slave"); -+ goto err; -+ } - -- ret = lxc_terminal_peer_default(terminal); -- if (ret < 0) { -- ERROR("Failed to allocate proxy terminal"); -- goto err; -+ ret = lxc_terminal_peer_default(terminal); -+ if (ret < 0) { -+ ERROR("Failed to allocate proxy terminal"); -+ goto err; -+ } -+ } else { -+ /* isulad: create 3 pipes */ -+ /* for stdin */ -+ if (pipe2(terminal->pipes[0], O_CLOEXEC)) { -+ ERROR("Failed to create stdin pipe"); -+ goto err; -+ } -+ /* for stdout */ -+ if (pipe2(terminal->pipes[1], O_NONBLOCK | O_CLOEXEC)) { -+ ERROR("Failed to create stdout pipe"); -+ goto err; -+ } -+ /* for stderr */ -+ if (pipe2(terminal->pipes[2], O_NONBLOCK | O_CLOEXEC)) { -+ ERROR("Failed to create stderr pipe"); -+ goto err; -+ } - } - - /* isulad: open fifos */ -@@ -1581,6 +1712,13 @@ void lxc_terminal_init(struct lxc_terminal *terminal) - /* isulad init console fifos */ - terminal->init_fifo[0] = NULL; - terminal->init_fifo[1] = NULL; -+ terminal->init_fifo[2] = NULL; -+ terminal->pipes[0][0] = -1; -+ terminal->pipes[0][1] = -1; -+ terminal->pipes[1][0] = -1; -+ terminal->pipes[1][1] = -1; -+ terminal->pipes[2][0] = -1; -+ terminal->pipes[2][1] = -1; - lxc_list_init(&terminal->fifos); - } - -@@ -1599,8 +1737,14 @@ int lxc_terminal_delete_fifo(int fd, struct lxc_list *list) - free(elem->in_fifo); - if (elem->out_fifo) - free(elem->out_fifo); -- close(elem->in_fd); -- close(elem->out_fd); -+ if (elem->err_fifo) -+ free(elem->err_fifo); -+ if (elem->in_fd >= 0) -+ close(elem->in_fd); -+ if (elem->out_fd >= 0) -+ close(elem->out_fd); -+ if (elem->err_fd >= 0) -+ close(elem->err_fd); - free(elem); - } - } -@@ -1617,6 +1761,7 @@ void lxc_terminal_conf_free(struct lxc_terminal *terminal) - /*isulad: free console fifos */ - free(terminal->init_fifo[0]); - free(terminal->init_fifo[1]); -+ free(terminal->init_fifo[2]); - lxc_terminal_delete_fifo(-1, &terminal->fifos); - } - -@@ -1647,7 +1792,8 @@ int lxc_terminal_add_fifos(struct lxc_conf *conf, const char *fifonames) - int ret = 0; - struct lxc_terminal *terminal = &conf->console; - int fifofd_in = -1; -- char *tmp = NULL, *saveptr = NULL, *in = NULL, *out = NULL; -+ char *tmp = NULL, *saveptr = NULL, *in = NULL, *out = NULL, *err = NULL; -+ const char *none_fifo_name = "none"; - - tmp = strdup(fifonames); - if (!tmp) { -@@ -1660,14 +1806,27 @@ int lxc_terminal_add_fifos(struct lxc_conf *conf, const char *fifonames) - ret = -1; - goto free_out; - } -+ if (strcmp(in, none_fifo_name) == 0) -+ in = NULL; -+ - out = strtok_r(NULL, "&&&&", &saveptr); - if (!out) { - ret = -1; - goto free_out; - } -+ if (strcmp(out, none_fifo_name) == 0) -+ out = NULL; - -- fifofd_in = lxc_terminal_set_fifo(terminal, in, out); -- if (fifofd_in < 0) { -+ err = strtok_r(NULL, "&&&&", &saveptr); -+ if (!err) { -+ ret = -1; -+ goto free_out; -+ } -+ if (strcmp(err, none_fifo_name) == 0) -+ err = NULL; -+ -+ ret = lxc_terminal_set_fifo(terminal, in, out, err, &fifofd_in); -+ if (ret < 0) { - ERROR("Faild to set fifos to console config"); - ret = -1; - goto free_out; -diff --git a/src/lxc/terminal.h b/src/lxc/terminal.h -index 0c9653c..9bb341f 100644 ---- a/src/lxc/terminal.h -+++ b/src/lxc/terminal.h -@@ -115,16 +115,21 @@ struct lxc_terminal { - /* the in-memory ringbuffer */ - struct lxc_ringbuf ringbuf; - }; -- char *init_fifo[2]; /* isulad: default fifos for the start */ -+ char *init_fifo[3]; /* isulad: default fifos for the start */ - struct lxc_list fifos; /* isulad: fifos used to forward teminal */ -+ bool disable_pty; -+ bool open_stdin; -+ int pipes[3][2]; /* isulad: pipes for dup to container fds of stdin,stdout,stderr on daemonize mode*/ - }; - - /* isulad: fifo struct */ - struct lxc_fifos_fd { - char *in_fifo; - char *out_fifo; -+ char *err_fifo; - int in_fd; - int out_fd; -+ int err_fd; - struct lxc_list node; - }; - -diff --git a/src/lxc/tools/arguments.h b/src/lxc/tools/arguments.h -index afab9f5..d03f8a4 100644 ---- a/src/lxc/tools/arguments.h -+++ b/src/lxc/tools/arguments.h -@@ -51,6 +51,8 @@ struct lxc_arguments { - char *log_priority; - int quiet; - int daemonize; -+ int disable_pty; -+ int open_stdin; - const char *rcfile; - const char *console; - const char *console_log; -@@ -62,7 +64,7 @@ struct lxc_arguments { - - /* for lxc-start */ - const char *share_ns[32]; /* size must be greater than LXC_NS_MAX */ -- char *terminal_fifos[2]; /* isulad add, fifos used to redirct stdin/out/err */ -+ char *terminal_fifos[3]; /* isulad add, fifos used to redirct stdin/out/err */ - const char *container_info; /* isulad: file used to store pid and ppid info of container */ - const char *exit_monitor_fifo; /* isulad: fifo used to monitor state of monitor process */ - unsigned int start_timeout; /* isulad: Seconds for waiting on a container to start before it is killed*/ -@@ -179,9 +181,13 @@ struct lxc_arguments { - /* isulad add begin */ - #define OPT_INPUT_FIFO OPT_USAGE - 7 - #define OPT_OUTPUT_FIFO OPT_USAGE - 8 --#define OPT_CONTAINER_INFO OPT_USAGE - 9 --#define OPT_EXIT_FIFO OPT_USAGE - 10 --#define OPT_START_TIMEOUT OPT_USAGE - 11 -+#define OPT_STDERR_FIFO OPT_USAGE - 9 -+#define OPT_CONTAINER_INFO OPT_USAGE - 10 -+#define OPT_EXIT_FIFO OPT_USAGE - 11 -+#define OPT_START_TIMEOUT OPT_USAGE - 12 -+#define OPT_DISABLE_PTY OPT_USAGE - 13 -+#define OPT_OPEN_STDIN OPT_USAGE - 14 -+ - /* isulad add end*/ - - extern int lxc_arguments_parse(struct lxc_arguments *args, int argc, -diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c -index acdf8a0..674050d 100644 ---- a/src/lxc/tools/lxc_attach.c -+++ b/src/lxc/tools/lxc_attach.c -@@ -77,6 +77,7 @@ static const struct option my_longopts[] = { - {"rcfile", required_argument, 0, 'f'}, - {"in-fifo", required_argument, 0, OPT_INPUT_FIFO}, /* isulad add terminal fifos*/ - {"out-fifo", required_argument, 0, OPT_OUTPUT_FIFO}, -+ {"err-fifo", required_argument, 0, OPT_STDERR_FIFO}, - LXC_COMMON_OPTIONS - }; - -@@ -201,6 +202,9 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) - case OPT_OUTPUT_FIFO: - args->terminal_fifos[1] = arg; - break; -+ case OPT_STDERR_FIFO: -+ args->terminal_fifos[2] = arg; -+ break; - } - - return 0; -@@ -460,9 +464,10 @@ int main(int argc, char *argv[]) - if (elevated_privileges) - attach_options.attach_flags &= ~(elevated_privileges); - -- if (my_args.terminal_fifos[0] && my_args.terminal_fifos[1]) { -+ if (my_args.terminal_fifos[0] || my_args.terminal_fifos[1] || my_args.terminal_fifos[2]) { - attach_options.init_fifo[0] = my_args.terminal_fifos[0]; - attach_options.init_fifo[1] = my_args.terminal_fifos[1]; -+ attach_options.init_fifo[2] = my_args.terminal_fifos[2]; - attach_options.attach_flags |= LXC_ATTACH_TERMINAL; - } else if (stdfd_is_pty()) { - attach_options.attach_flags |= LXC_ATTACH_TERMINAL; -diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c -index ec48701..183fafc 100644 ---- a/src/lxc/tools/lxc_start.c -+++ b/src/lxc/tools/lxc_start.c -@@ -73,9 +73,12 @@ static const struct option my_longopts[] = { - /* isulad add begin */ - {"in-fifo", required_argument, 0, OPT_INPUT_FIFO}, - {"out-fifo", required_argument, 0, OPT_OUTPUT_FIFO}, -+ {"err-fifo", required_argument, 0, OPT_STDERR_FIFO}, - {"container-pidfile", required_argument, 0, OPT_CONTAINER_INFO}, - {"exit-fifo", required_argument, 0, OPT_EXIT_FIFO}, - {"start-timeout", required_argument, 0, OPT_START_TIMEOUT}, -+ {"disable-pty", no_argument, 0, OPT_DISABLE_PTY}, -+ {"open-stdin", no_argument, 0, OPT_OPEN_STDIN}, - /* isulad add end */ - LXC_COMMON_OPTIONS - }; -@@ -166,6 +169,9 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) - case OPT_OUTPUT_FIFO: - args->terminal_fifos[1] = arg; - break; -+ case OPT_STDERR_FIFO: -+ args->terminal_fifos[2] = arg; -+ break; - case OPT_CONTAINER_INFO: - args->container_info = arg; - break; -@@ -179,6 +185,12 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) - } - args->start_timeout = (unsigned int)atoi(arg); - break; -+ case OPT_DISABLE_PTY: -+ args->disable_pty = 1; -+ break; -+ case OPT_OPEN_STDIN: -+ args->open_stdin = 1; -+ break; - } - return 0; - } -@@ -381,11 +393,17 @@ int main(int argc, char *argv[]) - if (!my_args.daemonize) - c->want_daemonize(c, false); - -+ if (my_args.disable_pty) -+ c->want_disable_pty(c, true); -+ -+ if (my_args.open_stdin) -+ c->want_open_stdin(c, true); -+ - if (my_args.close_all_fds) - c->want_close_all_fds(c, true); - -- if (my_args.terminal_fifos[0] && my_args.terminal_fifos[1]) -- c->set_terminal_init_fifos(c, my_args.terminal_fifos[0], my_args.terminal_fifos[1]); -+ 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]); - - if (args == default_args) - err = c->start(c, 0, NULL) ? EXIT_SUCCESS : EXIT_FAILURE; --- -1.8.3.1 - diff --git a/0069-lxc-killall-processes-if-container-shared-pid-namesp.patch b/0069-lxc-killall-processes-if-container-shared-pid-namesp.patch deleted file mode 100644 index 2f7da6a0ff220eb7e48e5ffea59ecd046feb573c..0000000000000000000000000000000000000000 --- a/0069-lxc-killall-processes-if-container-shared-pid-namesp.patch +++ /dev/null @@ -1,207 +0,0 @@ -From 7a5088c289e2c9a543ba08137bffe873206962ba Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Thu, 21 Mar 2019 15:48:02 +0800 -Subject: [PATCH 069/140] lxc: killall processes if container shared pid - namespace - -Signed-off-by: tanyifeng -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgfsng.c | 2 +- - src/lxc/start.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 161 insertions(+), 1 deletion(-) - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index e513218..ab7ca35 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -1056,7 +1056,7 @@ static int cgroup_rmdir(struct hierarchy **hierarchies, - - ret = recursive_destroy(h->container_full_path); - if (ret < 0) { -- ERROR("Failed to destroy \"%s\"", h->container_full_path); -+ SYSERROR("Failed to destroy \"%s\"", h->container_full_path); - return -1; - } - -diff --git a/src/lxc/start.c b/src/lxc/start.c -index cad0d76..1c9eb0a 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -2494,6 +2494,162 @@ static void clean_resource_set_env(struct lxc_handler *handler) - /* End of environment variable setup for hooks. */ - } - -+void trim_line(char *s) -+{ -+ size_t len; -+ -+ len = strlen(s); -+ while ((len > 1) && (s[len - 1] == '\n')) -+ s[--len] = '\0'; -+} -+ -+static int _read_procs_file(const char *path, pid_t **pids, size_t *len) -+{ -+ FILE *f; -+ char *line = NULL; -+ size_t sz = 0; -+ -+ f = fopen_cloexec(path, "r"); -+ if (!f) -+ return -1; -+ -+ while (getline(&line, &sz, f) != -1) { -+ pid_t pid; -+ trim_line(line); -+ pid = (pid_t)atoll(line); -+ *pids = realloc(*pids, sizeof(pid_t) * (*len + 1)); -+ (*pids)[*len] = pid; -+ (*len)++; -+ } -+ -+ free(line); -+ fclose(f); -+ return 0; -+} -+ -+static int _recursive_read_cgroup_procs(const char *dirpath, pid_t **pids, size_t *len) -+{ -+ struct dirent *direntp; -+ DIR *dir; -+ int ret, failed = 0; -+ char pathname[PATH_MAX]; -+ -+ dir = opendir(dirpath); -+ if (!dir && errno != ENOENT) { -+ WARN("Failed to open \"%s\"", dirpath); -+ return 0; -+ } -+ -+ while ((direntp = readdir(dir))) { -+ struct stat mystat; -+ int rc; -+ -+ if (!strcmp(direntp->d_name, ".") || -+ !strcmp(direntp->d_name, "..")) -+ continue; -+ -+ rc = snprintf(pathname, PATH_MAX, "%s/%s", dirpath, direntp->d_name); -+ if (rc < 0 || rc >= PATH_MAX) { -+ failed = 1; -+ continue; -+ } -+ -+ if (strcmp(direntp->d_name, "cgroup.procs") == 0) { -+ if (_read_procs_file(pathname, pids, len)) { -+ failed = 1; -+ -+ } -+ continue; -+ } -+ -+ ret = lstat(pathname, &mystat); -+ if (ret) { -+ failed = 1; -+ continue; -+ } -+ -+ if (S_ISDIR(mystat.st_mode)) { -+ if (_recursive_read_cgroup_procs(pathname, pids, len) < 0) -+ failed = 1; -+ } -+ } -+ -+ ret = closedir(dir); -+ if (ret) { -+ WARN("Failed to close directory \"%s\"", dirpath); -+ failed = 1; -+ } -+ -+ return failed ? -1 : 0; -+} -+ -+int get_all_pids(struct cgroup_ops *cg_ops, pid_t **pids, size_t *len) -+{ -+ char *devices_path = NULL; -+ int ret; -+ -+ devices_path = must_make_path("/sys/fs/cgroup", "devices", cg_ops->container_cgroup, NULL); -+ if (!file_exists(devices_path)) { -+ free(devices_path); -+ return 0; -+ } -+ -+ ret = _recursive_read_cgroup_procs(devices_path, pids, len); -+ free(devices_path); -+ return ret; -+} -+ -+static int set_cgroup_freezer(struct cgroup_ops *cg_ops, const char *value) -+{ -+ char *fullpath; -+ int ret; -+ -+ fullpath = must_make_path("/sys/fs/cgroup", "freezer", cg_ops->container_cgroup, "freezer.state", NULL); -+ ret = lxc_write_to_file(fullpath, value, strlen(value), false, 0666); -+ free(fullpath); -+ return ret; -+} -+ -+/* isulad: kill all process in container cgroup path */ -+static void signal_all_processes(struct lxc_handler *handler) -+{ -+ int ret; -+ struct cgroup_ops *cg_ops = handler->cgroup_ops; -+ pid_t *pids = NULL; -+ size_t len = 0, i; -+ -+ ret = set_cgroup_freezer(cg_ops, "FROZEN"); -+ if (ret < 0 && errno != ENOENT) { -+ WARN("cgroup_set frozen failed"); -+ } -+ -+ ret = get_all_pids(cg_ops, &pids, &len); -+ if (ret < 0) { -+ WARN("failed to get all pids"); -+ } -+ -+ for (i = 0; i < len; i++) { -+ ret = kill(pids[i], SIGKILL); -+ if (ret < 0 && errno != ESRCH) { -+ WARN("Can not kill process (pid=%d) with SIGKILL for container %s", pids[i], handler->name); -+ } -+ } -+ -+ ret = set_cgroup_freezer(cg_ops, "THAWED"); -+ if (ret < 0 && errno != ENOENT) { -+ WARN("cgroup_set thawed failed"); -+ } -+ -+ for (i = 0; i < len; i++) { -+ ret = lxc_wait_for_pid_status(pids[i]); -+ if (ret < 0 && errno != ECHILD) { -+ WARN("Failed to wait pid %d for container %s: %s", pids[i], handler->name, strerror(errno)); -+ } -+ } -+ -+ free(pids); -+} -+ - /*isulad: do_lxcapi_clean_resource */ - int do_lxcapi_clean_resource(char *name, char *lxcpath, struct lxc_conf *conf, pid_t pid) - { -@@ -2510,6 +2666,10 @@ int do_lxcapi_clean_resource(char *name, char *lxcpath, struct lxc_conf *conf, p - } - - clean_resource_set_env(handler); -+ // if we shared pid namespace with others, should kill all processes within container cgroup -+ if (handler->conf->ns_share[LXC_NS_PID] != NULL) { -+ signal_all_processes(handler); -+ } - - char* oci_hook_args[1]; - oci_hook_args[0] = alloca(strlen(handler->lxcpath) + 1); --- -1.8.3.1 - diff --git a/0071-lxc-get-cgroup-path-according-to-cgroup-mountpoint.patch b/0071-lxc-get-cgroup-path-according-to-cgroup-mountpoint.patch deleted file mode 100644 index 8a0171bde4a4214521d6a1dcf883419802d09a81..0000000000000000000000000000000000000000 --- a/0071-lxc-get-cgroup-path-according-to-cgroup-mountpoint.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 6b5baec9fce40d498c3a9d3e8fbe08ff1e3751fd Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Thu, 21 Mar 2019 22:05:09 +0800 -Subject: [PATCH 071/140] lxc: get cgroup path according to cgroup mountpoint - -Signed-off-by: tanyifeng -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgfsng.c | 6 ++++-- - src/lxc/cgroups/cgroup.h | 2 +- - src/lxc/commands.c | 6 +++--- - src/lxc/criu.c | 2 +- - src/lxc/start.c | 8 +++----- - 5 files changed, 12 insertions(+), 12 deletions(-) - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index 5ceb06b..62d58f9 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -1852,7 +1852,7 @@ __cgfsng_ops static bool cgfsng_unfreeze(struct cgroup_ops *ops) - } - - __cgfsng_ops static const char *cgfsng_get_cgroup(struct cgroup_ops *ops, -- const char *controller) -+ const char *controller, bool skip_mount) - { - struct hierarchy *h; - -@@ -1863,7 +1863,9 @@ __cgfsng_ops static const char *cgfsng_get_cgroup(struct cgroup_ops *ops, - return NULL; - } - -- return h->container_full_path ? h->container_full_path + strlen(h->mountpoint) : NULL; -+ if (!h->container_full_path) -+ h->container_full_path = must_make_path(h->mountpoint, h->container_base_path, ops->container_cgroup, NULL); -+ return skip_mount ? h->container_full_path + strlen(h->mountpoint) : h->container_full_path; - } - - /* Given a cgroup path returned from lxc_cmd_get_cgroup_path, build a full path, -diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h -index b6116f6..edbb1e3 100644 ---- a/src/lxc/cgroups/cgroup.h -+++ b/src/lxc/cgroups/cgroup.h -@@ -129,7 +129,7 @@ struct cgroup_ops { - bool (*destroy)(struct cgroup_ops *ops, struct lxc_handler *handler); - bool (*payload_create)(struct cgroup_ops *ops, struct lxc_handler *handler); - bool (*payload_enter)(struct cgroup_ops *ops, pid_t pid); -- const char *(*get_cgroup)(struct cgroup_ops *ops, const char *controller); -+ const char *(*get_cgroup)(struct cgroup_ops *ops, const char *controller, bool skip_mount); - bool (*escape)(const struct cgroup_ops *ops); - int (*num_hierarchies)(struct cgroup_ops *ops); - bool (*get_hierarchies)(struct cgroup_ops *ops, int n, char ***out); -diff --git a/src/lxc/commands.c b/src/lxc/commands.c -index f0c95df..c74b8c1 100644 ---- a/src/lxc/commands.c -+++ b/src/lxc/commands.c -@@ -481,9 +481,9 @@ static int lxc_cmd_get_cgroup_callback(int fd, struct lxc_cmd_req *req, - struct cgroup_ops *cgroup_ops = handler->cgroup_ops; - - if (req->datalen > 0) -- path = cgroup_ops->get_cgroup(cgroup_ops, req->data); -+ path = cgroup_ops->get_cgroup(cgroup_ops, req->data, true); - else -- path = cgroup_ops->get_cgroup(cgroup_ops, NULL); -+ path = cgroup_ops->get_cgroup(cgroup_ops, NULL, true); - if (!path) - return -1; - -@@ -655,7 +655,7 @@ static int lxc_cmd_stop_callback(int fd, struct lxc_cmd_req *req, - * lxc_unfreeze() would do another cmd (GET_CGROUP) which would - * deadlock us. - */ -- if (!cgroup_ops->get_cgroup(cgroup_ops, "freezer")) -+ if (!cgroup_ops->get_cgroup(cgroup_ops, "freezer", true)) - return 0; - - if (cgroup_ops->unfreeze(cgroup_ops)) -diff --git a/src/lxc/criu.c b/src/lxc/criu.c -index bb97859..5c77979 100644 ---- a/src/lxc/criu.c -+++ b/src/lxc/criu.c -@@ -332,7 +332,7 @@ static void exec_criu(struct cgroup_ops *cgroup_ops, struct lxc_conf *conf, - } else { - const char *p; - -- p = cgroup_ops->get_cgroup(cgroup_ops, controllers[0]); -+ p = cgroup_ops->get_cgroup(cgroup_ops, controllers[0], true); - if (!p) { - ERROR("failed to get cgroup path for %s", controllers[0]); - goto err; -diff --git a/src/lxc/start.c b/src/lxc/start.c -index b14e46f..9243a6d 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -1032,17 +1032,15 @@ static int _recursive_read_cgroup_procs(const char *dirpath, pid_t **pids, size_ - - int get_all_pids(struct cgroup_ops *cg_ops, pid_t **pids, size_t *len) - { -- char *devices_path = NULL; -+ const char *devices_path = NULL; - int ret; - -- devices_path = must_make_path("/sys/fs/cgroup", "devices", cg_ops->container_cgroup, NULL); -+ devices_path = cg_ops->get_cgroup(cg_ops, "devices", false); - if (!file_exists(devices_path)) { -- free(devices_path); - return 0; - } - - ret = _recursive_read_cgroup_procs(devices_path, pids, len); -- free(devices_path); - return ret; - } - -@@ -1051,7 +1049,7 @@ static int set_cgroup_freezer(struct cgroup_ops *cg_ops, const char *value) - char *fullpath; - int ret; - -- fullpath = must_make_path("/sys/fs/cgroup", "freezer", cg_ops->container_cgroup, "freezer.state", NULL); -+ fullpath = must_make_path(cg_ops->get_cgroup(cg_ops, "freezer", false), "freezer.state", NULL); - ret = lxc_write_to_file(fullpath, value, strlen(value), false, 0666); - free(fullpath); - return ret; --- -1.8.3.1 - diff --git a/0072-lxc-adapt-to-docker-18.09.patch b/0072-lxc-adapt-to-docker-18.09.patch deleted file mode 100644 index 19c6284d2568264bb58d4d3cc3efc7519e5325a9..0000000000000000000000000000000000000000 --- a/0072-lxc-adapt-to-docker-18.09.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 15e78bbe59a574b5c41405cfdb84a496095a1662 Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Mon, 25 Mar 2019 18:03:23 +0800 -Subject: [PATCH 072/140] lxc: adapt to docker-18.09 - -1. adapt to docker-18.09 -2. fix strlcpy bug - -Signed-off-by: liuhao -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 8 ++++---- - src/lxc/start.c | 4 ++-- - 2 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index a6b9797..abfba04 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4382,9 +4382,9 @@ static char* generate_json_str(const char *name, const char *lxcpath, const char - ERROR("Get container %s pid failed: %s", name, strerror(errno)); - cpid = "-1"; - } -- // {"ociVersion":"","id":"xxx","pid":777,"root":"xxx","bundlePath":"xxx"} -- size = 1 + 16 + 5 + strlen(name) + 3 + 6 + strlen(cpid) + 1 -- + 7 + strlen(rootfs) + 3 + 13 + strlen(lxcpath) + 1 + strlen(name) + 3 + 1; -+ // {"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; - inmsg = malloc(size); - if (!inmsg) { - ERROR("Out of memory"); -@@ -4392,7 +4392,7 @@ static char* generate_json_str(const char *name, const char *lxcpath, const char - goto out_free; - } - rc = snprintf(inmsg, size, -- "{\"ociVersion\":\"\",\"id\":\"%s\",\"pid\":%s,\"root\":\"%s\",\"bundlePath\":\"%s/%s\"}", -+ "{\"ociVersion\":\"\",\"id\":\"%s\",\"pid\":%s,\"root\":\"%s\",\"bundle\":\"%s/%s\"}", - name, cpid, rootfs, lxcpath, name); - if (rc < 0 || rc >= size) { - ERROR("Create json string failed"); -diff --git a/src/lxc/start.c b/src/lxc/start.c -index 9243a6d..2fca4e1 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -2186,7 +2186,7 @@ static int lxc_spawn(struct lxc_handler *handler) - /* isulad: Run oci prestart hook at here */ - char* oci_hook_args[1]; - oci_hook_args[0] = alloca(strlen(lxcpath) + 1); -- (void)strlcpy(oci_hook_args[0], lxcpath, strlen(lxcpath)); -+ (void)strlcpy(oci_hook_args[0], lxcpath, strlen(lxcpath) + 1); - ret = run_lxc_hooks(name, "oci-prestart", conf, oci_hook_args); - if (ret < 0) { - ERROR("Failed to run oci prestart hooks"); -@@ -2687,7 +2687,7 @@ int do_lxcapi_clean_resource(char *name, char *lxcpath, struct lxc_conf *conf, p - - char* oci_hook_args[1]; - oci_hook_args[0] = alloca(strlen(handler->lxcpath) + 1); -- (void)strlcpy(oci_hook_args[0], handler->lxcpath, strlen(handler->lxcpath)); -+ (void)strlcpy(oci_hook_args[0], handler->lxcpath, strlen(handler->lxcpath) + 1); - - if (run_lxc_hooks(handler->name, "oci-poststop", handler->conf, oci_hook_args)) { - ERROR("Failed to run lxc.hook.post-stop for container \"%s\".", handler->name); --- -1.8.3.1 - diff --git a/0073-lxc-support-set-additional-groups.patch b/0073-lxc-support-set-additional-groups.patch deleted file mode 100644 index 9a8ef322708093a580206c5980630b1a2883d146..0000000000000000000000000000000000000000 --- a/0073-lxc-support-set-additional-groups.patch +++ /dev/null @@ -1,247 +0,0 @@ -From d766c43da139d6e893e7d450943425e524be639a Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Mon, 25 Mar 2019 17:17:00 +0800 -Subject: [PATCH 073/140] lxc: support set additional groups - -Signed-off-by: tanyifeng -Signed-off-by: LiFeng ---- - src/lxc/attach.c | 8 ++++--- - src/lxc/conf.c | 12 ++++++++++ - src/lxc/conf.h | 3 +++ - src/lxc/confile.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- - src/lxc/start.c | 25 ++++++++++++--------- - 5 files changed, 100 insertions(+), 14 deletions(-) - -diff --git a/src/lxc/attach.c b/src/lxc/attach.c -index c979c85..618f2f1 100644 ---- a/src/lxc/attach.c -+++ b/src/lxc/attach.c -@@ -903,9 +903,6 @@ static int attach_child_main(struct attach_clone_payload *payload) - goto on_error; - } - -- if (!lxc_setgroups(0, NULL) && errno != EPERM) -- goto on_error; -- - /* Set {u,g}id. */ - if (options->uid != LXC_INVALID_UID) - new_uid = options->uid; -@@ -1017,6 +1014,11 @@ static int attach_child_main(struct attach_clone_payload *payload) - goto on_error; - } - -+ if (init_ctx->container && init_ctx->container->lxc_conf && -+ !lxc_setgroups(init_ctx->container->lxc_conf->init_groups_len, -+ init_ctx->container->lxc_conf->init_groups)) -+ goto on_error; -+ - if (!lxc_switch_uid_gid(new_uid, new_gid)) - goto on_error; - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index abfba04..58fc059 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -5184,10 +5184,21 @@ int lxc_clear_init_args(struct lxc_conf *lxc_conf) - for (i = 0; i < lxc_conf->init_argc; i++) - free(lxc_conf->init_argv[i]); - free(lxc_conf->init_argv); -+ lxc_conf->init_argc = 0; - - return 0; - } - -+/*isulad clear init groups*/ -+int lxc_clear_init_groups(struct lxc_conf *lxc_conf) -+{ -+ free(lxc_conf->init_groups); -+ lxc_conf->init_groups_len = 0; -+ -+ return 0; -+} -+ -+ - /*isulad: clear populate devices*/ - int lxc_clear_populate_devices(struct lxc_conf *c) - { -@@ -5294,6 +5305,7 @@ void lxc_conf_free(struct lxc_conf *conf) - free(conf->cgroup_meta.controllers); - /* isulad add begin */ - lxc_clear_init_args(conf); -+ lxc_clear_init_groups(conf); - lxc_clear_populate_devices(conf); - lxc_clear_rootfs_masked_paths(conf); - lxc_clear_rootfs_ro_paths(conf); -diff --git a/src/lxc/conf.h b/src/lxc/conf.h -index 93cf15d..11cf596 100644 ---- a/src/lxc/conf.h -+++ b/src/lxc/conf.h -@@ -418,6 +418,8 @@ struct lxc_conf { - /* init args used to repalce init_cmd*/ - char **init_argv; - size_t init_argc; -+ gid_t *init_groups; -+ size_t init_groups_len; - /* populate devices*/ - struct lxc_list populate_devs; - -@@ -498,6 +500,7 @@ extern int lxc_clear_namespace(struct lxc_conf *c); - - /* isulad add begin */ - int lxc_clear_init_args(struct lxc_conf *lxc_conf); -+int lxc_clear_init_groups(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); -diff --git a/src/lxc/confile.c b/src/lxc/confile.c -index 3940b32..60e6c46 100644 ---- a/src/lxc/confile.c -+++ b/src/lxc/confile.c -@@ -154,6 +154,7 @@ lxc_config_define(sysctl); - lxc_config_define(proc); - /*isulad add begin*/ - lxc_config_define(init_args); -+lxc_config_define(init_groups); - lxc_config_define(populate_device); - lxc_config_define(umask); - /*isulad add end*/ -@@ -245,6 +246,7 @@ static struct lxc_config_t config_jump_table[] = { - - /*isulad add begin*/ - { "lxc.isulad.init.args", set_config_init_args, get_config_init_args, clr_config_init_args, }, -+ { "lxc.isulad.init.groups", set_config_init_groups, get_config_init_groups, clr_config_init_groups, }, - { "lxc.isulad.populate.device", set_config_populate_device, get_config_populate_device, clr_config_populate_device, }, - { "lxc.isulad.rootfs.maskedpaths", set_config_rootfs_masked_paths, get_config_rootfs_masked_paths, clr_config_rootfs_masked_paths, }, - { "lxc.isulad.rootfs.ropaths", set_config_rootfs_ro_paths, get_config_rootfs_ro_paths, clr_config_rootfs_ro_paths, }, -@@ -2230,6 +2232,43 @@ static int set_config_init_args(const char *key, const char *value, - return 0; - } - -+/* isulad: set config for init groups */ -+static int set_config_init_groups(const char *key, const char *value, -+ struct lxc_conf *lxc_conf, void *data) -+{ -+ char *groups, *token; -+ int ret = -1; -+ -+ if (lxc_config_value_empty(value)) -+ return lxc_clear_init_groups(lxc_conf); -+ -+ groups = strdup(value); -+ if (!groups) -+ return -1; -+ -+ /* In case several capability keep is specified in a single line -+ * split these caps in a single element for the list. -+ */ -+ lxc_iterate_parts(token, groups, " \t") { -+ gid_t *tmp; -+ tmp = realloc(lxc_conf->init_groups, (lxc_conf->init_groups_len + 1) * sizeof(gid_t)); -+ if (!tmp) { -+ ERROR("Out of memory"); -+ goto on_error; -+ } -+ lxc_conf->init_groups = tmp; -+ tmp[lxc_conf->init_groups_len] = atoll(token); -+ lxc_conf->init_groups_len++; -+ } -+ -+ ret = 0; -+ -+on_error: -+ free(groups); -+ -+ return ret; -+} -+ - /* isulad: set config for populate device */ - static int set_config_populate_device(const char *key, const char *value, - struct lxc_conf *lxc_conf, void *data) -@@ -3947,7 +3986,25 @@ static int get_config_init_args(const char *key, char *retv, int inlen, - - for (i = 0; i < c->init_argc; i++) { - strprint(retv, inlen, "%s", c->init_argv[i]); -- } -+ } -+ -+ return fulllen; -+} -+ -+/* isulad: get config init groups */ -+static int get_config_init_groups(const char *key, char *retv, int inlen, -+ struct lxc_conf *c, void *data) -+{ -+ int i, len, fulllen = 0; -+ -+ if (!retv) -+ inlen = 0; -+ else -+ memset(retv, 0, inlen); -+ -+ for (i = 0; i < c->init_groups_len; i++) { -+ strprint(retv, inlen, "%u\n", c->init_groups[i]); -+ } - - return fulllen; - } -@@ -4836,6 +4893,13 @@ static inline int clr_config_init_args(const char *key, struct lxc_conf *c, - return lxc_clear_init_args(c); - } - -+/* isulad: clr config init args*/ -+static inline int clr_config_init_groups(const char *key, struct lxc_conf *c, -+ void *data) -+{ -+ return lxc_clear_init_groups(c); -+} -+ - /* isulad: clr config populate devices*/ - static inline int clr_config_populate_device(const char *key, struct lxc_conf *c, - void *data) -diff --git a/src/lxc/start.c b/src/lxc/start.c -index 2fca4e1..ae92c13 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -1666,6 +1666,20 @@ static int do_start(void *data) - if (lxc_setup_env_home(new_uid) < 0) - goto out_warn_father; - -+ /* If we are in a new user namespace we already dropped all groups when -+ * we switched to root in the new user namespace further above. Only -+ * drop groups if we can, so ensure that we have necessary privilege. -+ */ -+ if (lxc_list_empty(&handler->conf->id_map)) -+ #if HAVE_LIBCAP -+ if (lxc_proc_cap_is_set(CAP_SETGID, CAP_EFFECTIVE)) -+ #endif -+ /* isulad: set groups for init process, and before we set uid and gid */ -+ if (!lxc_setgroups(handler->conf->init_groups_len, handler->conf->init_groups)) { -+ ERROR("Can not set groups"); -+ goto out_warn_father; -+ } -+ - /* Avoid unnecessary syscalls. */ - if (new_uid == nsuid) - new_uid = LXC_INVALID_UID; -@@ -1676,16 +1690,7 @@ static int do_start(void *data) - if (!lxc_switch_uid_gid(new_uid, new_gid)) - goto out_warn_father; - -- /* If we are in a new user namespace we already dropped all groups when -- * we switched to root in the new user namespace further above. Only -- * drop groups if we can, so ensure that we have necessary privilege. -- */ -- if (lxc_list_empty(&handler->conf->id_map)) -- #if HAVE_LIBCAP -- if (lxc_proc_cap_is_set(CAP_SETGID, CAP_EFFECTIVE)) -- #endif -- if (!lxc_setgroups(0, NULL)) -- goto out_warn_father; -+ - - ret = lxc_ambient_caps_down(); - if (ret < 0) { --- -1.8.3.1 - diff --git a/0074-lxc-only-add-valid-fd-to-mainloop.patch b/0074-lxc-only-add-valid-fd-to-mainloop.patch deleted file mode 100644 index dc0df1274d09bcb5020c3385a697c04b9df1a669..0000000000000000000000000000000000000000 --- a/0074-lxc-only-add-valid-fd-to-mainloop.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0a90b2cbb4e0a2e7dd3f533e4a20d9e522889ea5 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Tue, 26 Mar 2019 16:11:13 +0800 -Subject: [PATCH 074/140] lxc: only add valid fd to mainloop - -Signed-off-by: tanyifeng -Signed-off-by: LiFeng ---- - src/lxc/mainloop.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/src/lxc/mainloop.c b/src/lxc/mainloop.c -index b169aa6..9603d1e 100644 ---- a/src/lxc/mainloop.c -+++ b/src/lxc/mainloop.c -@@ -85,6 +85,9 @@ int lxc_mainloop_add_handler(struct lxc_epoll_descr *descr, int fd, - struct mainloop_handler *handler; - struct lxc_list *item; - -+ if (fd < 0) -+ return 0; -+ - handler = malloc(sizeof(*handler)); - if (!handler) - return -1; --- -1.8.3.1 - diff --git a/0075-lxc-add-timeout-for-attach.patch b/0075-lxc-add-timeout-for-attach.patch deleted file mode 100644 index 14faaac4ea9349dbf05365ef113ae9073be0d4b3..0000000000000000000000000000000000000000 --- a/0075-lxc-add-timeout-for-attach.patch +++ /dev/null @@ -1,278 +0,0 @@ -From 2ce6149708aaa421373497cffa412d9815c7f7f7 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Wed, 3 Apr 2019 19:54:36 +0800 -Subject: [PATCH 075/140] lxc: add timeout for attach - -Signed-off-by: wujing -Signed-off-by: LiFeng ---- - src/lxc/attach.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++ - src/lxc/attach_options.h | 1 + - src/lxc/tools/arguments.h | 4 +++ - src/lxc/tools/lxc_attach.c | 11 +++++++ - src/lxc/tools/lxc_start.c | 13 +------- - src/lxc/utils.c | 13 ++++++++ - src/lxc/utils.h | 2 ++ - 7 files changed, 111 insertions(+), 12 deletions(-) - -diff --git a/src/lxc/attach.c b/src/lxc/attach.c -index 618f2f1..79049c3 100644 ---- a/src/lxc/attach.c -+++ b/src/lxc/attach.c -@@ -69,6 +69,20 @@ - #include - #endif - -+typedef enum { -+ ATTACH_INIT, -+ ATTACH_TIMEOUT, -+ ATTACH_MAX, -+} attach_timeout_t; -+ -+static volatile attach_timeout_t g_attach_timeout_state = ATTACH_INIT; -+ -+struct attach_timeout_conf { -+ unsigned int timeout; -+ unsigned long long start_time; -+ pid_t pid; -+}; -+ - lxc_log_define(attach, lxc); - - /* Define default options if no options are supplied by the user. */ -@@ -1145,6 +1159,59 @@ static inline void lxc_attach_terminal_close_log(struct lxc_terminal *terminal) - terminal->log_fd = -EBADF; - } - -+/* isulad: attach timeout thread function */ -+static void* wait_attach_timeout(void *arg) -+{ -+ struct attach_timeout_conf *conf = (struct attach_timeout_conf *)arg; -+ -+ if (!conf || conf->timeout < 1) -+ goto out; -+ sleep(conf->timeout); -+ if (lxc_process_alive(conf->pid, conf->start_time)) { -+ g_attach_timeout_state = ATTACH_TIMEOUT; -+ if (kill(conf->pid, SIGKILL) < 0) { -+ ERROR("Failed to send signal %d to pid %d", SIGKILL, conf->pid); -+ } -+ } -+ -+out: -+ free(conf); -+ return ((void *)0); -+} -+ -+/* isulad: create attach timeout thread */ -+static int create_attach_timeout_thread(unsigned int attach_timeout, pid_t pid) -+{ -+ int ret = 0; -+ pthread_t ptid; -+ pthread_attr_t attr; -+ struct attach_timeout_conf *timeout_conf = NULL; -+ -+ timeout_conf = malloc(sizeof(struct attach_timeout_conf)); -+ if (!timeout_conf) { -+ ERROR("Failed to malloc attach timeout conf"); -+ ret = -1; -+ goto out; -+ } -+ -+ memset(timeout_conf, 0, sizeof(struct attach_timeout_conf)); -+ timeout_conf->timeout = attach_timeout; -+ timeout_conf->pid = pid; -+ timeout_conf->start_time = lxc_get_process_startat(pid); -+ -+ pthread_attr_init(&attr); -+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); -+ ret = pthread_create(&ptid, &attr, wait_attach_timeout, timeout_conf); -+ if (ret != 0) { -+ ERROR("Create attach wait timeout thread failed"); -+ free(timeout_conf); -+ goto out; -+ } -+ -+out: -+ return ret; -+} -+ - int lxc_attach(const char *name, const char *lxcpath, - lxc_attach_exec_t exec_function, void *exec_payload, - lxc_attach_options_t *options, pid_t *attached_process, char **err_msg) -@@ -1481,6 +1548,13 @@ int lxc_attach(const char *name, const char *lxcpath, - - *attached_process = attached_pid; - -+ if (options->timeout > 0) { -+ ret = create_attach_timeout_thread(options->timeout, *attached_process); -+ if (ret) { -+ ERROR("Failed to create attach timeout thread for container."); -+ goto close_mainloop; -+ } -+ } - /* isulad: read error msg from pipe */ - ssize_t size_read; - char errbuf[BUFSIZ + 1] = {0}; -@@ -1510,6 +1584,11 @@ int lxc_attach(const char *name, const char *lxcpath, - } - } - -+ if (g_attach_timeout_state == ATTACH_TIMEOUT && err_msg != NULL && *err_msg == NULL) { -+ *err_msg = strdup("Attach exceeded timeout"); -+ if (!(*err_msg)) -+ ERROR("Out of memory"); -+ } - close_mainloop: - if (options->attach_flags & LXC_ATTACH_TERMINAL) - lxc_mainloop_close(&descr); -diff --git a/src/lxc/attach_options.h b/src/lxc/attach_options.h -index 71c1739..5e279ba 100644 ---- a/src/lxc/attach_options.h -+++ b/src/lxc/attach_options.h -@@ -137,6 +137,7 @@ typedef struct lxc_attach_options_t { - int log_fd; - - char *init_fifo[3]; /* isulad: default fifos for the start */ -+ unsigned int timeout;/* isulad: Seconds for waiting on a container to attach/exec before it is killed*/ - } lxc_attach_options_t; - - /*! Default attach options to use */ -diff --git a/src/lxc/tools/arguments.h b/src/lxc/tools/arguments.h -index d03f8a4..2fc90ad 100644 ---- a/src/lxc/tools/arguments.h -+++ b/src/lxc/tools/arguments.h -@@ -69,6 +69,9 @@ struct lxc_arguments { - const char *exit_monitor_fifo; /* isulad: fifo used to monitor state of monitor process */ - unsigned int start_timeout; /* isulad: Seconds for waiting on a container to start before it is killed*/ - -+ /* for lxc-attach */ -+ unsigned int attach_timeout; -+ - /* for lxc-console */ - unsigned int ttynum; - char escape; -@@ -187,6 +190,7 @@ struct lxc_arguments { - #define OPT_START_TIMEOUT OPT_USAGE - 12 - #define OPT_DISABLE_PTY OPT_USAGE - 13 - #define OPT_OPEN_STDIN OPT_USAGE - 14 -+#define OPT_ATTACH_TIMEOUT OPT_USAGE - 15 - - /* isulad add end*/ - -diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c -index 674050d..2861ef4 100644 ---- a/src/lxc/tools/lxc_attach.c -+++ b/src/lxc/tools/lxc_attach.c -@@ -62,6 +62,7 @@ static char **extra_env; - static ssize_t extra_env_size; - static char **extra_keep; - static ssize_t extra_keep_size; -+static unsigned int timeout = 0; - - static const struct option my_longopts[] = { - {"elevated-privileges", optional_argument, 0, 'e'}, -@@ -78,6 +79,7 @@ static const struct option my_longopts[] = { - {"in-fifo", required_argument, 0, OPT_INPUT_FIFO}, /* isulad add terminal fifos*/ - {"out-fifo", required_argument, 0, OPT_OUTPUT_FIFO}, - {"err-fifo", required_argument, 0, OPT_STDERR_FIFO}, -+ {"timeout", required_argument, 0, OPT_ATTACH_TIMEOUT}, - LXC_COMMON_OPTIONS - }; - -@@ -128,6 +130,7 @@ Options :\n\ - multiple times.\n\ - -f, --rcfile=FILE\n\ - Load configuration file FILE\n\ -+ --timeout Timeout in seconds (default: 0)\n\ - ", - .options = my_longopts, - .parser = my_parser, -@@ -205,6 +208,13 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) - case OPT_STDERR_FIFO: - args->terminal_fifos[2] = arg; - break; -+ case OPT_ATTACH_TIMEOUT: -+ if(!is_non_negative_num(arg)) { -+ ERROR("Error attach timeout parameter:%s.\n", arg); -+ return -1; -+ } -+ args->attach_timeout = (unsigned int)atoi(arg); -+ break; - } - - return 0; -@@ -478,6 +488,7 @@ int main(int argc, char *argv[]) - attach_options.env_policy = env_policy; - attach_options.extra_env_vars = extra_env; - attach_options.extra_keep_env = extra_keep; -+ attach_options.timeout = my_args.attach_timeout; - - if (my_args.argc > 0) { - command.program = my_args.argv[0]; -diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c -index 183fafc..af63f58 100644 ---- a/src/lxc/tools/lxc_start.c -+++ b/src/lxc/tools/lxc_start.c -@@ -49,6 +49,7 @@ - #include "config.h" - #include "confile.h" - #include "log.h" -+#include "utils.h" - - lxc_log_define(lxc_start, lxc); - -@@ -113,18 +114,6 @@ Options :\n\ - .pidfile = NULL, - }; - --static bool is_non_negative_num(const char *s) --{ -- if (!s || !strcmp(s, "")) -- return false; -- while(*s != '\0') { -- if(!isdigit(*s)) -- return false; -- ++s; -- } -- return true; --} -- - static int my_parser(struct lxc_arguments *args, int c, char *arg) - { - switch (c) { -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index 480e6d0..69eb3e5 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -2069,3 +2069,16 @@ out: - free(pid_info); - return alive; - } -+ -+bool is_non_negative_num(const char *s) -+{ -+ if (!s || !strcmp(s, "")) -+ return false; -+ while(*s != '\0') { -+ if(!isdigit(*s)) -+ return false; -+ ++s; -+ } -+ return true; -+} -+ -diff --git a/src/lxc/utils.h b/src/lxc/utils.h -index 73ffdd9..20407af 100644 ---- a/src/lxc/utils.h -+++ b/src/lxc/utils.h -@@ -322,4 +322,6 @@ extern void lxc_write_error_message(int errfd, const char *format, ...); - - extern bool lxc_process_alive(pid_t pid, unsigned long long start_time); - -+extern bool is_non_negative_num(const char *s); -+ - #endif /* __LXC_UTILS_H */ --- -1.8.3.1 - diff --git a/0076-lxc-delete-unused-variable.patch b/0076-lxc-delete-unused-variable.patch deleted file mode 100644 index 5f33534fee624420dcc847b00e3fc906709e7f0d..0000000000000000000000000000000000000000 --- a/0076-lxc-delete-unused-variable.patch +++ /dev/null @@ -1,26 +0,0 @@ -From b2904bbeda12d9d1e6864717f76052c05b213ab2 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Thu, 4 Apr 2019 11:19:48 +0800 -Subject: [PATCH 076/140] lxc: delete unused variable - -Signed-off-by: wujing -Signed-off-by: LiFeng ---- - src/lxc/tools/lxc_attach.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c -index 2861ef4..440c0bc 100644 ---- a/src/lxc/tools/lxc_attach.c -+++ b/src/lxc/tools/lxc_attach.c -@@ -62,7 +62,6 @@ static char **extra_env; - static ssize_t extra_env_size; - static char **extra_keep; - static ssize_t extra_keep_size; --static unsigned int timeout = 0; - - static const struct option my_longopts[] = { - {"elevated-privileges", optional_argument, 0, 'e'}, --- -1.8.3.1 - diff --git a/0077-lxc-set-negative-files.limit-to-max-and-fix-bug-of-s.patch b/0077-lxc-set-negative-files.limit-to-max-and-fix-bug-of-s.patch deleted file mode 100644 index 7684c79e8d67cc1155580e955763edd9b5945f5c..0000000000000000000000000000000000000000 --- a/0077-lxc-set-negative-files.limit-to-max-and-fix-bug-of-s.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 940815cbc68a12ada2b0d9b212ded98a59590de6 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Tue, 2 Apr 2019 23:59:20 -0400 -Subject: [PATCH 077/140] lxc: set negative files.limit to max and fix bug of - setting homedir - -Signed-off-by: tanyifeng -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgfsng.c | 19 +++++++++++++++---- - src/lxc/storage/storage.c | 5 ++--- - src/lxc/utils.c | 29 ++++++++++++++++++++--------- - 3 files changed, 37 insertions(+), 16 deletions(-) - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index 62d58f9..cc08737 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -2259,19 +2259,30 @@ static bool __cg_legacy_setup_limits(struct cgroup_ops *ops, - cg = iterator->elem; - - if (do_devices == !strncmp("devices", cg->subsystem, 7)) { -- if (cg_legacy_set_data(ops, cg->subsystem, cg->value)) { -+ const char *cgvalue = cg->value; -+ if (strcmp(cg->subsystem, "files.limit") == 0) { -+ if (lxc_safe_long_long(cgvalue, &setvalue) != 0) { -+ SYSERROR("Invalid integer value %s", cgvalue); -+ goto out; -+ } -+ if (setvalue <= 0) { -+ cgvalue = "max"; -+ } -+ } -+ if (cg_legacy_set_data(ops, cg->subsystem, cgvalue)) { - if (do_devices && (errno == EACCES || errno == EPERM)) { - WARN("Failed to set \"%s\" to \"%s\"", -- cg->subsystem, cg->value); -+ cg->subsystem, cgvalue); - continue; - } - WARN("Failed to set \"%s\" to \"%s\"", -- cg->subsystem, cg->value); -+ cg->subsystem, cgvalue); - goto out; - } - DEBUG("Set controller \"%s\" set to \"%s\"", -- cg->subsystem, cg->value); -+ cg->subsystem, cgvalue); - } -+ - // isulad: check cpu shares - if (strcmp(cg->subsystem, "cpu.shares") == 0) { - if (cg_legacy_get_data(ops, cg->subsystem, value, sizeof(value)) < 0) { -diff --git a/src/lxc/storage/storage.c b/src/lxc/storage/storage.c -index 88ed788..fa79762 100644 ---- a/src/lxc/storage/storage.c -+++ b/src/lxc/storage/storage.c -@@ -611,9 +611,8 @@ bool storage_destroy(struct lxc_conf *conf) - - r = storage_init(conf); - if (r == NULL) { -- ERROR("%s 's storage init failed, the storage may be deleted already", conf->name); -- ret = true; -- return ret; -+ WARN("%s 's storage init failed, the storage may be deleted already", conf->name); -+ return true; - } - - destroy_rv = r->ops->destroy(r); -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index 69eb3e5..7b82d06 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -1873,20 +1873,31 @@ int lxc_setup_keyring(void) - // isulad: set env home in container - int lxc_setup_env_home(uid_t uid) - { --#define __DEFAULT_HOMEDIR__ "/" -+#define __PASSWD_FILE__ "/etc/passwd" - int ret = 0; -- char *homedir; -- struct passwd pwd, *result = NULL; -+ char *homedir = "/"; // default home dir is / -+ FILE *stream = NULL; -+ struct passwd pw, *pwbufp = NULL; - char buf[BUFSIZ]; - -- ret = getpwuid_r(uid, &pwd, buf, BUFSIZ, &result); -- if (ret || !result || !result->pw_dir) { -- WARN("User invalid, can not find user '%u'", uid); -- homedir = __DEFAULT_HOMEDIR__; -- } else { -- homedir = result->pw_dir; -+ stream = fopen_cloexec(__PASSWD_FILE__, "r"); -+ if (stream == NULL) { -+ SYSWARN("Failed to open %s: %s", __PASSWD_FILE__); -+ goto set_env; - } - -+ while (fgetpwent_r(stream, &pw, buf, sizeof(buf), &pwbufp) == 0 && pwbufp != NULL) { -+ if (pwbufp->pw_uid == uid) { -+ homedir = pwbufp->pw_dir; -+ goto set_env; -+ } -+ } -+ WARN("User invalid, can not find user '%u'", uid); -+ -+set_env: -+ if (stream) -+ fclose(stream); -+ - // if we didn't configure HOME, set it based on uid - if (setenv("HOME", homedir, 0) < 0) { - SYSERROR("Unable to set env 'HOME'"); --- -1.8.3.1 - diff --git a/0078-Run-pre-start-hook-before-chroot.patch b/0078-Run-pre-start-hook-before-chroot.patch deleted file mode 100644 index 138a07d7ef4d34e61facc636c811b1e1b6e1bdfa..0000000000000000000000000000000000000000 --- a/0078-Run-pre-start-hook-before-chroot.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 8820d8dcd7684f123a99304df532139315a1276f Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Wed, 3 Apr 2019 23:36:04 -0400 -Subject: [PATCH 078/140] Run pre-start hook before chroot - -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 7 +++++++ - src/lxc/start.c | 6 ++++++ - src/lxc/sync.h | 2 ++ - 3 files changed, 15 insertions(+) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 58fc059..a9421c5 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -82,6 +82,7 @@ - #include "loop.h" - #include "path.h" - #include "utils.h" -+#include "sync.h" - - #ifdef MAJOR_IN_MKDEV - #include -@@ -4186,6 +4187,12 @@ int lxc_setup(struct lxc_handler *handler) - goto on_error; - } - -+ /* Ask father to run start host hooks and wait for him to finish. */ -+ if (lxc_sync_barrier_parent(handler, LXC_SYNC_START_HOST_HOOK)) { -+ ERROR("Failed to sync parent to start host hook"); -+ goto on_error; -+ } -+ - ret = lxc_setup_rootfs_switch_root(&lxc_conf->rootfs); - if (ret < 0) { - ERROR("Failed to pivot root into rootfs"); -diff --git a/src/lxc/start.c b/src/lxc/start.c -index ae92c13..10f922d 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -2204,6 +2204,12 @@ static int lxc_spawn(struct lxc_handler *handler) - goto out_delete_net; - } - -+ /* Tell the child to continue its initialization. We'll get -+ * LXC_SYNC_CGROUP when it is ready for us to setup cgroups. -+ */ -+ if (lxc_sync_barrier_child(handler, LXC_SYNC_POST_START_HOST_HOOK)) -+ goto out_delete_net; -+ - /* Tell the child to complete its initialization and wait for it to exec - * or return an error. (The child will never return - * LXC_SYNC_READY_START+1. It will either close the sync pipe, causing -diff --git a/src/lxc/sync.h b/src/lxc/sync.h -index 5c0fb34..787911d 100644 ---- a/src/lxc/sync.h -+++ b/src/lxc/sync.h -@@ -31,6 +31,8 @@ enum { - LXC_SYNC_POST_CONFIGURE, - LXC_SYNC_CGROUP, - LXC_SYNC_CGROUP_UNSHARE, -+ LXC_SYNC_START_HOST_HOOK, -+ LXC_SYNC_POST_START_HOST_HOOK, - LXC_SYNC_CGROUP_LIMITS, - LXC_SYNC_READY_START, - LXC_SYNC_RESTART, --- -1.8.3.1 - diff --git a/0079-inherid-env-from-parent-in-oci-hooks.patch b/0079-inherid-env-from-parent-in-oci-hooks.patch deleted file mode 100644 index ddb933258cc40096ae1d9ad930a586008cf539ad..0000000000000000000000000000000000000000 --- a/0079-inherid-env-from-parent-in-oci-hooks.patch +++ /dev/null @@ -1,29 +0,0 @@ -From e87fd4a3b69a4c98d2c50ede559d56b43f65578a Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Thu, 4 Apr 2019 17:21:56 +0800 -Subject: [PATCH 079/140] inherid env from parent in oci hooks - -env: LD_LIBRAY_PAHT and PATH - -Signed-off-by: liuhao -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index a9421c5..20eb840 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4420,7 +4420,7 @@ static char **merge_ocihook_env(char **oldenvs, size_t env_len, size_t *merge_en - size_t result_len = env_len; - size_t i, j; - char *tmpenv; -- char *lxc_envs[] = {"LXC_CGNS_AWARE", "LXC_PID", "LXC_ROOTFS_MOUNT", -+ 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; - --- -1.8.3.1 - diff --git a/0080-lxc-fix-compile-error.patch b/0080-lxc-fix-compile-error.patch deleted file mode 100644 index 44ac724871b4fb3b01f40c1ef9d5bcb68d9ad88b..0000000000000000000000000000000000000000 --- a/0080-lxc-fix-compile-error.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 1e70c61ab75a71c99926e5f7c9e852dc81102bb9 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Mon, 8 Apr 2019 08:29:46 -0400 -Subject: [PATCH 080/140] lxc: fix compile error - -Signed-off-by: tanyifeng -Signed-off-by: LiFeng ---- - src/lxc/utils.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index 7b82d06..fd6075f 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -1874,7 +1874,6 @@ int lxc_setup_keyring(void) - int lxc_setup_env_home(uid_t uid) - { - #define __PASSWD_FILE__ "/etc/passwd" -- int ret = 0; - char *homedir = "/"; // default home dir is / - FILE *stream = NULL; - struct passwd pw, *pwbufp = NULL; -@@ -1882,7 +1881,7 @@ int lxc_setup_env_home(uid_t uid) - - stream = fopen_cloexec(__PASSWD_FILE__, "r"); - if (stream == NULL) { -- SYSWARN("Failed to open %s: %s", __PASSWD_FILE__); -+ SYSWARN("Failed to open %s", __PASSWD_FILE__); - goto set_env; - } - --- -1.8.3.1 - diff --git a/0081-lxc-Change-the-range-of-attach-timeout.patch b/0081-lxc-Change-the-range-of-attach-timeout.patch deleted file mode 100644 index 8e06619f58a06aa45c781dd15d53a96a0086356a..0000000000000000000000000000000000000000 --- a/0081-lxc-Change-the-range-of-attach-timeout.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 5cfdce31c3afcf8d688151e71e84d056f2229a27 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Mon, 8 Apr 2019 16:42:43 +0800 -Subject: [PATCH 081/140] lxc: Change the range of attach timeout - -Signed-off-by: wujing -Signed-off-by: LiFeng ---- - src/lxc/attach.c | 4 ++-- - src/lxc/attach_options.h | 2 +- - src/lxc/tools/arguments.h | 2 +- - src/lxc/tools/lxc_attach.c | 2 +- - 4 files changed, 5 insertions(+), 5 deletions(-) - -diff --git a/src/lxc/attach.c b/src/lxc/attach.c -index 79049c3..6480eb9 100644 ---- a/src/lxc/attach.c -+++ b/src/lxc/attach.c -@@ -78,7 +78,7 @@ typedef enum { - static volatile attach_timeout_t g_attach_timeout_state = ATTACH_INIT; - - struct attach_timeout_conf { -- unsigned int timeout; -+ int64_t timeout; - unsigned long long start_time; - pid_t pid; - }; -@@ -1180,7 +1180,7 @@ out: - } - - /* isulad: create attach timeout thread */ --static int create_attach_timeout_thread(unsigned int attach_timeout, pid_t pid) -+static int create_attach_timeout_thread(int64_t attach_timeout, pid_t pid) - { - int ret = 0; - pthread_t ptid; -diff --git a/src/lxc/attach_options.h b/src/lxc/attach_options.h -index 5e279ba..9744a2e 100644 ---- a/src/lxc/attach_options.h -+++ b/src/lxc/attach_options.h -@@ -137,7 +137,7 @@ typedef struct lxc_attach_options_t { - int log_fd; - - char *init_fifo[3]; /* isulad: default fifos for the start */ -- unsigned int timeout;/* isulad: Seconds for waiting on a container to attach/exec before it is killed*/ -+ int64_t timeout;/* isulad: Seconds for waiting on a container to attach/exec before it is killed*/ - } lxc_attach_options_t; - - /*! Default attach options to use */ -diff --git a/src/lxc/tools/arguments.h b/src/lxc/tools/arguments.h -index 2fc90ad..de02aeb 100644 ---- a/src/lxc/tools/arguments.h -+++ b/src/lxc/tools/arguments.h -@@ -70,7 +70,7 @@ struct lxc_arguments { - unsigned int start_timeout; /* isulad: Seconds for waiting on a container to start before it is killed*/ - - /* for lxc-attach */ -- unsigned int attach_timeout; -+ int64_t attach_timeout; - - /* for lxc-console */ - unsigned int ttynum; -diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c -index 440c0bc..854b3a2 100644 ---- a/src/lxc/tools/lxc_attach.c -+++ b/src/lxc/tools/lxc_attach.c -@@ -212,7 +212,7 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) - ERROR("Error attach timeout parameter:%s.\n", arg); - return -1; - } -- args->attach_timeout = (unsigned int)atoi(arg); -+ args->attach_timeout = (unsigned int)atoll(arg); - break; - } - --- -1.8.3.1 - diff --git a/0082-lxc-fix-memory-leak-cause-by-setenv.patch b/0082-lxc-fix-memory-leak-cause-by-setenv.patch deleted file mode 100644 index 286737de0264b0d4d815b75f4c32d5f5cb972099..0000000000000000000000000000000000000000 --- a/0082-lxc-fix-memory-leak-cause-by-setenv.patch +++ /dev/null @@ -1,150 +0,0 @@ -From ccec379d6577df3a01f11f054f37ce7e5b95088c Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Thu, 11 Apr 2019 15:27:31 +0800 -Subject: [PATCH 082/140] lxc: fix memory leak cause by setenv - -isulad will call do_lxcapi_clean_resource(), so setenv at here, will -change env of isulad. - -Signed-off-by: liuhao -Signed-off-by: LiFeng ---- - src/lxc/start.c | 107 ++++++++++++++++++++++++++++++++++++++++---------------- - 1 file changed, 76 insertions(+), 31 deletions(-) - -diff --git a/src/lxc/start.c b/src/lxc/start.c -index 10f922d..87e07d3 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -2635,44 +2635,85 @@ on_error: - } - - /*isulad: set env for clean resources */ --static void clean_resource_set_env(struct lxc_handler *handler) -+static int clean_resource_set_env(struct lxc_handler *handler) - { - const char *name = handler->name; - struct lxc_conf *conf = handler->conf; -- char pidstr[20]; -- -- /* Start of environment variable setup for hooks. */ -- if (name && setenv("LXC_NAME", name, 1)) -- SYSERROR("Failed to set environment variable: LXC_NAME=%s.", name); -- -- if (conf->rcfile && setenv("LXC_CONFIG_FILE", conf->rcfile, 1)) -- SYSERROR("Failed to set environment variable: LXC_CONFIG_FILE=%s.", conf->rcfile); -- -- if (conf->rootfs.mount && setenv("LXC_ROOTFS_MOUNT", conf->rootfs.mount, 1)) -- SYSERROR("Failed to set environment variable: LXC_ROOTFS_MOUNT=%s.", conf->rootfs.mount); -+ char bufstr[PATH_MAX + 1]; -+ int i = 0; -+ int j = 0; -+ int len = 2; //set "LXC_PID" and "LXC_CGNS_AWARE" - -- if (conf->rootfs.path && setenv("LXC_ROOTFS_PATH", conf->rootfs.path, 1)) -- SYSERROR("Failed to set environment variable: LXC_ROOTFS_PATH=%s.", conf->rootfs.path); -- -- if (conf->console.path && setenv("LXC_CONSOLE", conf->console.path, 1)) -- SYSERROR("Failed to set environment variable: LXC_CONSOLE=%s.", conf->console.path); -- -- if (conf->console.log_path && setenv("LXC_CONSOLE_LOGPATH", conf->console.log_path, 1)) -- SYSERROR("Failed to set environment variable: LXC_CONSOLE_LOGPATH=%s.", conf->console.log_path); -- -- if (setenv("LXC_CGNS_AWARE", "1", 1)) -- SYSERROR("Failed to set environment variable LXC_CGNS_AWARE=1."); -+ if (conf == NULL || conf->ocihooks == NULL || conf->ocihooks->poststop_len == 0) { -+ return 0; -+ } - -+ 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++; -+ } - -- snprintf(pidstr, 20, "%d", handler->pid); -- if (setenv("LXC_PID", pidstr, 1)) -- SYSERROR("Failed to set environment variable: LXC_PID=%s.", pidstr); -+ 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++] = strdup(bufstr); -+ } -+ if (conf->rcfile) { -+ snprintf(bufstr, PATH_MAX + 1, "LXC_CONFIG_FILE=%s", conf->rcfile); -+ conf->ocihooks->poststop[i]->env[j++] = strdup(bufstr); -+ } -+ if (conf->rootfs.mount) { -+ snprintf(bufstr, PATH_MAX + 1, "LXC_ROOTFS_MOUNT=%s", conf->rootfs.mount); -+ conf->ocihooks->poststop[i]->env[j++] = strdup(bufstr); -+ } -+ if (conf->rootfs.path) { -+ snprintf(bufstr, PATH_MAX + 1, "LXC_ROOTFS_PATH=%s", conf->rootfs.path); -+ conf->ocihooks->poststop[i]->env[j++] = strdup(bufstr); -+ } -+ if (conf->console.path) { -+ snprintf(bufstr, PATH_MAX + 1, "LXC_CONSOLE=%s", conf->console.path); -+ conf->ocihooks->poststop[i]->env[j++] = 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++] = strdup(bufstr); -+ } -+ conf->ocihooks->poststop[i]->env[j++] = strdup("LXC_CGNS_AWARE=1"); - -- if (handler->cgroup_ops->container_cgroup) { -- if (setenv("LXC_CGROUP_PATH", handler->cgroup_ops->container_cgroup, 1)) -- SYSERROR("Failed to set environment variable: LXC_CGROUP_PATH=%s.", handler->cgroup_ops->container_cgroup); -+ snprintf(bufstr, PATH_MAX + 1, "LXC_PID=%d", handler->pid); -+ conf->ocihooks->poststop[i]->env[j++] = 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++] = strdup(bufstr); -+ } -+ conf->ocihooks->poststop[i]->env_len = j; -+ /* End of environment variable setup for hooks. */ - } -- /* End of environment variable setup for hooks. */ -+ return 0; - } - - /*isulad: do_lxcapi_clean_resource */ -@@ -2690,7 +2731,11 @@ int do_lxcapi_clean_resource(char *name, char *lxcpath, struct lxc_conf *conf, p - goto out; - } - -- clean_resource_set_env(handler); -+ if (clean_resource_set_env(handler) != 0) { -+ ERROR("Failed to set env for poststop hooks"); -+ ret = -1; -+ goto out; -+ } - // if we shared pid namespace with others, should kill all processes within container cgroup - if (handler->conf->ns_share[LXC_NS_PID] != NULL) { - signal_all_processes(handler); --- -1.8.3.1 - diff --git a/0083-lxc-free-lxc-handler.patch b/0083-lxc-free-lxc-handler.patch deleted file mode 100644 index 8b35c5b0b9ecbfbf738d8e7cad569aa8af092ced..0000000000000000000000000000000000000000 --- a/0083-lxc-free-lxc-handler.patch +++ /dev/null @@ -1,41 +0,0 @@ -From ec26a6a90167cc2a4624a4a5fc68bb9bcb56c651 Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Thu, 11 Apr 2019 20:34:51 +0800 -Subject: [PATCH 083/140] lxc: free lxc-handler - -free handler if failed - -Signed-off-by: liuhao -Signed-off-by: LiFeng ---- - src/lxc/start.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/src/lxc/start.c b/src/lxc/start.c -index 87e07d3..f1cd7fa 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -695,6 +695,10 @@ void lxc_zero_handler(struct lxc_handler *handler) - - void lxc_free_handler(struct lxc_handler *handler) - { -+ if (handler == NULL) { -+ return; -+ } -+ - if (handler->pinfd >= 0) - close(handler->pinfd); - -@@ -2761,8 +2765,8 @@ retry: - ret = -1; - } - -- lxc_free_handler(handler); - out: -+ lxc_free_handler(handler); - return ret; - } - --- -1.8.3.1 - diff --git a/0084-lxc-memory-leak-of-lxc_grow_array.patch b/0084-lxc-memory-leak-of-lxc_grow_array.patch deleted file mode 100644 index 42566f7fadcc500c1dac23e45130b1ba7dc87bb8..0000000000000000000000000000000000000000 --- a/0084-lxc-memory-leak-of-lxc_grow_array.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 4e84395bebe59ac94bf9d7ee11a985c776a05fbe Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Thu, 11 Apr 2019 22:36:42 +0800 -Subject: [PATCH 084/140] lxc: memory leak of lxc_grow_array - -fix memory leak of lxc_grow_array - -Signed-off-by: liuhao -Signed-off-by: LiFeng ---- - src/lxc/string_utils.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/lxc/string_utils.c b/src/lxc/string_utils.c -index 0d7538c..31c4340 100644 ---- a/src/lxc/string_utils.c -+++ b/src/lxc/string_utils.c -@@ -523,6 +523,7 @@ int lxc_grow_array(void ***array, size_t *capacity, size_t new_size, size_t capa - /* first time around, catch some trivial mistakes of the user - * only initializing one of these */ - if (!*array || !*capacity) { -+ free(*array); - *array = NULL; - *capacity = 0; - } --- -1.8.3.1 - diff --git a/0085-lxc-update-json-file-from-isulad.patch b/0085-lxc-update-json-file-from-isulad.patch deleted file mode 100644 index 46221d1d06632d1d37021614cdaeec3e8d9ea12e..0000000000000000000000000000000000000000 --- a/0085-lxc-update-json-file-from-isulad.patch +++ /dev/null @@ -1,1089 +0,0 @@ -From 1c36fa9e699c1bf892e89ba71b0052b34b55a89d Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Fri, 12 Apr 2019 06:06:12 -0400 -Subject: [PATCH 085/140] lxc: update json file from isulad - -Signed-off-by: tanyifeng -Signed-off-by: LiFeng ---- - src/lxc/json/defs.c | 38 +++++----- - src/lxc/json/json_common.c | 160 +++++++++++++++++++-------------------- - src/lxc/json/json_common.h | 2 +- - src/lxc/json/logger_json_file.c | 50 ++++++------ - src/lxc/json/oci_runtime_hooks.c | 3 +- - src/lxc/json/oci_runtime_spec.c | 32 ++++---- - 6 files changed, 142 insertions(+), 143 deletions(-) - -diff --git a/src/lxc/json/defs.c b/src/lxc/json/defs.c -index 38df2f7..e7d9a09 100644 ---- a/src/lxc/json/defs.c -+++ b/src/lxc/json/defs.c -@@ -15,20 +15,20 @@ defs_hook *make_defs_hook(yajl_val tree, struct parser_context *ctx, parser_erro - ret = safe_malloc(sizeof(*ret)); - { - yajl_val val = get_val(tree, "path", yajl_t_string); -- if (val) { -+ if (val != NULL) { - char *str = YAJL_GET_STRING(val); - ret->path = safe_strdup(str ? str : ""); - } - } - { - yajl_val tmp = get_val(tree, "args", yajl_t_array); -- if (tmp && YAJL_GET_ARRAY(tmp)) { -+ if (tmp != NULL && YAJL_GET_ARRAY(tmp) != NULL && YAJL_GET_ARRAY(tmp)->len > 0) { - size_t i; - ret->args_len = YAJL_GET_ARRAY(tmp)->len; - ret->args = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->args)); - for (i = 0; i < YAJL_GET_ARRAY(tmp)->len; i++) { - yajl_val val = YAJL_GET_ARRAY(tmp)->values[i]; -- if (val) { -+ if (val != NULL) { - char *str = YAJL_GET_STRING(val); - ret->args[i] = safe_strdup(str ? str : ""); - } -@@ -37,13 +37,13 @@ defs_hook *make_defs_hook(yajl_val tree, struct parser_context *ctx, parser_erro - } - { - yajl_val tmp = get_val(tree, "env", yajl_t_array); -- if (tmp && YAJL_GET_ARRAY(tmp)) { -+ if (tmp != NULL && YAJL_GET_ARRAY(tmp) != NULL && YAJL_GET_ARRAY(tmp)->len > 0) { - size_t i; - ret->env_len = YAJL_GET_ARRAY(tmp)->len; - ret->env = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->env)); - for (i = 0; i < YAJL_GET_ARRAY(tmp)->len; i++) { - yajl_val val = YAJL_GET_ARRAY(tmp)->values[i]; -- if (val) { -+ if (val != NULL) { - char *str = YAJL_GET_STRING(val); - ret->env[i] = safe_strdup(str ? str : ""); - } -@@ -52,7 +52,7 @@ defs_hook *make_defs_hook(yajl_val tree, struct parser_context *ctx, parser_erro - } - { - yajl_val val = get_val(tree, "timeout", yajl_t_number); -- if (val) { -+ if (val != NULL) { - int invalid = common_safe_int(YAJL_GET_NUMBER(val), (int *)&ret->timeout); - if (invalid) { - if (asprintf(err, "Invalid value '%s' with type 'integer' for key 'timeout': %s", YAJL_GET_NUMBER(val), strerror(-invalid)) < 0) -@@ -84,14 +84,14 @@ defs_hook *make_defs_hook(yajl_val tree, struct parser_context *ctx, parser_erro - } - - void free_defs_hook(defs_hook *ptr) { -- if (!ptr) -+ if (ptr == NULL) - return; - free(ptr->path); - ptr->path = NULL; -- if (ptr->args) { -+ if (ptr->args != NULL) { - size_t i; - for (i = 0; i < ptr->args_len; i++) { -- if (ptr->args[i]) { -+ if (ptr->args[i] != NULL) { - free(ptr->args[i]); - ptr->args[i] = NULL; - } -@@ -99,10 +99,10 @@ void free_defs_hook(defs_hook *ptr) { - free(ptr->args); - ptr->args = NULL; - } -- if (ptr->env) { -+ if (ptr->env != NULL) { - size_t i; - for (i = 0; i < ptr->env_len; i++) { -- if (ptr->env[i]) { -+ if (ptr->env[i] != NULL) { - free(ptr->env[i]); - ptr->env[i] = NULL; - } -@@ -119,24 +119,24 @@ yajl_gen_status gen_defs_hook(yajl_gen g, defs_hook *ptr, struct parser_context - stat = reformat_start_map(g); - if (yajl_gen_status_ok != stat) - GEN_SET_ERROR_AND_RETURN(stat, err); -- if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr && ptr->path)) { -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->path != NULL)) { - char *str = ""; - stat = reformat_map_key(g, "path", strlen("path")); - if (yajl_gen_status_ok != stat) - GEN_SET_ERROR_AND_RETURN(stat, err); -- if (ptr && ptr->path) { -+ if (ptr != NULL && ptr->path != NULL) { - str = ptr->path; - } - stat = reformat_string(g, str, strlen(str)); - if (yajl_gen_status_ok != stat) - GEN_SET_ERROR_AND_RETURN(stat, err); - } -- if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr && ptr->args)) { -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) || (ptr != NULL && ptr->args != NULL)) { - size_t len = 0, i; - stat = reformat_map_key(g, "args", strlen("args")); - if (yajl_gen_status_ok != stat) - GEN_SET_ERROR_AND_RETURN(stat, err); -- if (ptr && ptr->args) { -+ if (ptr != NULL && ptr->args != NULL) { - len = ptr->args_len; - } - if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) -@@ -155,12 +155,12 @@ yajl_gen_status gen_defs_hook(yajl_gen g, defs_hook *ptr, struct parser_context - if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) - yajl_gen_config(g, yajl_gen_beautify, 1); - } -- if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr && ptr->env)) { -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) || (ptr != NULL && ptr->env != NULL)) { - size_t len = 0, i; - stat = reformat_map_key(g, "env", strlen("env")); - if (yajl_gen_status_ok != stat) - GEN_SET_ERROR_AND_RETURN(stat, err); -- if (ptr && ptr->env) { -+ if (ptr != NULL && ptr->env != NULL) { - len = ptr->env_len; - } - if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) -@@ -179,12 +179,12 @@ yajl_gen_status gen_defs_hook(yajl_gen g, defs_hook *ptr, struct parser_context - if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) - yajl_gen_config(g, yajl_gen_beautify, 1); - } -- if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr && ptr->timeout)) { -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->timeout)) { - long long int num = 0; - stat = reformat_map_key(g, "timeout", strlen("timeout")); - if (yajl_gen_status_ok != stat) - GEN_SET_ERROR_AND_RETURN(stat, err); -- if (ptr && ptr->timeout) { -+ if (ptr != NULL && ptr->timeout) { - num = (long long int)ptr->timeout; - } - stat = reformat_int(g, num); -diff --git a/src/lxc/json/json_common.c b/src/lxc/json/json_common.c -index e339ab3..54b7b61 100755 ---- a/src/lxc/json/json_common.c -+++ b/src/lxc/json/json_common.c -@@ -111,7 +111,7 @@ int common_safe_double(const char *numstr, double *converted) { - char *err_str = NULL; - double d; - -- if (!numstr) { -+ if (numstr == NULL) { - return -EINVAL; - } - -@@ -121,7 +121,7 @@ int common_safe_double(const char *numstr, double *converted) { - return -errno; - } - -- if (!err_str || err_str == numstr || *err_str != '\0') { -+ if (err_str == NULL || err_str == numstr || *err_str != '\0') { - return -EINVAL; - } - -@@ -133,7 +133,7 @@ int common_safe_uint8(const char *numstr, uint8_t *converted) { - char *err = NULL; - unsigned long int uli; - -- if (!numstr) { -+ if (numstr == NULL) { - return -EINVAL; - } - -@@ -143,7 +143,7 @@ int common_safe_uint8(const char *numstr, uint8_t *converted) { - return -errno; - } - -- if (!err || err == numstr || *err != '\0') { -+ if (err == NULL || err == numstr || *err != '\0') { - return -EINVAL; - } - -@@ -159,7 +159,7 @@ int common_safe_uint16(const char *numstr, uint16_t *converted) { - char *err = NULL; - unsigned long int uli; - -- if (!numstr) { -+ if (numstr == NULL) { - return -EINVAL; - } - -@@ -169,7 +169,7 @@ int common_safe_uint16(const char *numstr, uint16_t *converted) { - return -errno; - } - -- if (!err || err == numstr || *err != '\0') { -+ if (err == NULL || err == numstr || *err != '\0') { - return -EINVAL; - } - -@@ -185,7 +185,7 @@ int common_safe_uint32(const char *numstr, uint32_t *converted) { - char *err = NULL; - unsigned long long int ull; - -- if (!numstr) { -+ if (numstr == NULL) { - return -EINVAL; - } - -@@ -195,7 +195,7 @@ int common_safe_uint32(const char *numstr, uint32_t *converted) { - return -errno; - } - -- if (!err || err == numstr || *err != '\0') { -+ if (err == NULL || err == numstr || *err != '\0') { - return -EINVAL; - } - -@@ -211,7 +211,7 @@ int common_safe_uint64(const char *numstr, uint64_t *converted) { - char *err = NULL; - unsigned long long int ull; - -- if (!numstr) { -+ if (numstr == NULL) { - return -EINVAL; - } - -@@ -221,7 +221,7 @@ int common_safe_uint64(const char *numstr, uint64_t *converted) { - return -errno; - } - -- if (!err || err == numstr || *err != '\0') { -+ if (err == NULL || err == numstr || *err != '\0') { - return -EINVAL; - } - -@@ -233,7 +233,7 @@ int common_safe_uint(const char *numstr, unsigned int *converted) { - char *err = NULL; - unsigned long long int ull; - -- if (!numstr) { -+ if (numstr == NULL) { - return -EINVAL; - } - -@@ -243,7 +243,7 @@ int common_safe_uint(const char *numstr, unsigned int *converted) { - return -errno; - } - -- if (!err || err == numstr || *err != '\0') { -+ if (err == NULL || err == numstr || *err != '\0') { - return -EINVAL; - } - -@@ -259,7 +259,7 @@ int common_safe_int8(const char *numstr, int8_t *converted) { - char *err = NULL; - long int li; - -- if (!numstr) { -+ if (numstr == NULL) { - return -EINVAL; - } - -@@ -269,7 +269,7 @@ int common_safe_int8(const char *numstr, int8_t *converted) { - return -errno; - } - -- if (!err || err == numstr || *err != '\0') { -+ if (err == NULL || err == numstr || *err != '\0') { - return -EINVAL; - } - -@@ -285,7 +285,7 @@ int common_safe_int16(const char *numstr, int16_t *converted) { - char *err = NULL; - long int li; - -- if (!numstr) { -+ if (numstr == NULL) { - return -EINVAL; - } - -@@ -295,7 +295,7 @@ int common_safe_int16(const char *numstr, int16_t *converted) { - return -errno; - } - -- if (!err || err == numstr || *err != '\0') { -+ if (err == NULL || err == numstr || *err != '\0') { - return -EINVAL; - } - -@@ -311,7 +311,7 @@ int common_safe_int32(const char *numstr, int32_t *converted) { - char *err = NULL; - long long int lli; - -- if (!numstr) { -+ if (numstr == NULL) { - return -EINVAL; - } - -@@ -321,7 +321,7 @@ int common_safe_int32(const char *numstr, int32_t *converted) { - return -errno; - } - -- if (!err || err == numstr || *err != '\0') { -+ if (err == NULL || err == numstr || *err != '\0') { - return -EINVAL; - } - -@@ -337,7 +337,7 @@ int common_safe_int64(const char *numstr, int64_t *converted) { - char *err = NULL; - long long int lli; - -- if (!numstr) { -+ if (numstr == NULL) { - return -EINVAL; - } - -@@ -347,7 +347,7 @@ int common_safe_int64(const char *numstr, int64_t *converted) { - return -errno; - } - -- if (!err || err == numstr || *err != '\0') { -+ if (err == NULL || err == numstr || *err != '\0') { - return -EINVAL; - } - -@@ -359,7 +359,7 @@ int common_safe_int(const char *numstr, int *converted) { - char *err = NULL; - long long int lli; - -- if (!numstr) { -+ if (numstr == NULL) { - return -EINVAL; - } - -@@ -369,7 +369,7 @@ int common_safe_int(const char *numstr, int *converted) { - return -errno; - } - -- if (!err || err == numstr || *err != '\0') { -+ if (err == NULL || err == numstr || *err != '\0') { - return -EINVAL; - } - -@@ -385,12 +385,12 @@ char *safe_strdup(const char *src) - { - char *dst = NULL; - -- if (!src) { -+ if (src == NULL) { - return NULL; - } - - dst = strdup(src); -- if (!dst) { -+ if (dst == NULL) { - abort(); - } - -@@ -402,7 +402,7 @@ yajl_gen_status gen_json_map_int_int(void *ctx, json_map_int_int *map, struct pa - yajl_gen_status stat = yajl_gen_status_ok; - yajl_gen g = (yajl_gen) ctx; - size_t len = 0, i = 0; -- if (map) { -+ if (map != NULL) { - len = map->len; - } - if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { -@@ -444,7 +444,7 @@ yajl_gen_status gen_json_map_int_int(void *ctx, json_map_int_int *map, struct pa - } - - void free_json_map_int_int(json_map_int_int *map) { -- if (map) { -+ if (map != NULL) { - size_t i; - for (i = 0; i < map->len; i++) { - // No need to free key for type int -@@ -459,7 +459,7 @@ void free_json_map_int_int(json_map_int_int *map) { - } - json_map_int_int *make_json_map_int_int(yajl_val src, struct parser_context *ctx, parser_error *err) { - json_map_int_int *ret = NULL; -- if (src && YAJL_GET_OBJECT(src)) { -+ if (src != NULL && YAJL_GET_OBJECT(src) != NULL) { - size_t i; - size_t len = YAJL_GET_OBJECT(src)->len; - ret = safe_malloc(sizeof(*ret)); -@@ -470,11 +470,11 @@ json_map_int_int *make_json_map_int_int(yajl_val src, struct parser_context *ctx - const char *srckey = YAJL_GET_OBJECT(src)->keys[i]; - yajl_val srcval = YAJL_GET_OBJECT(src)->values[i]; - -- if (srckey) { -+ if (srckey != NULL) { - int invalid; - invalid = common_safe_int(srckey, &(ret->keys[i])); - if (invalid) { -- if (!*err && asprintf(err, "Invalid key '%s' with type 'int': %s", srckey, strerror(-invalid)) < 0) { -+ if (*err == NULL && asprintf(err, "Invalid key '%s' with type 'int': %s", srckey, strerror(-invalid)) < 0) { - *(err) = safe_strdup("error allocating memory"); - } - free_json_map_int_int(ret); -@@ -482,10 +482,10 @@ json_map_int_int *make_json_map_int_int(yajl_val src, struct parser_context *ctx - } - } - -- if (srcval) { -+ if (srcval != NULL) { - int invalid; - if (!YAJL_IS_NUMBER(srcval)) { -- if (!*err && asprintf(err, "Invalid value with type 'int' for key '%s'", srckey) < 0) { -+ if (*err == NULL && asprintf(err, "Invalid value with type 'int' for key '%s'", srckey) < 0) { - *(err) = safe_strdup("error allocating memory"); - } - free_json_map_int_int(ret); -@@ -493,7 +493,7 @@ json_map_int_int *make_json_map_int_int(yajl_val src, struct parser_context *ctx - } - invalid = common_safe_int(YAJL_GET_NUMBER(srcval), &(ret->values[i])); - if (invalid) { -- if (!*err && asprintf(err, "Invalid value with type 'int' for key '%s': %s", srckey, strerror(-invalid)) < 0) { -+ if (*err == NULL && asprintf(err, "Invalid value with type 'int' for key '%s': %s", srckey, strerror(-invalid)) < 0) { - *(err) = safe_strdup("error allocating memory"); - } - free_json_map_int_int(ret); -@@ -506,10 +506,10 @@ json_map_int_int *make_json_map_int_int(yajl_val src, struct parser_context *ctx - } - int append_json_map_int_int(json_map_int_int *map, int key, int val) { - size_t len; -- int *keys; -- int *vals; -+ int *keys = NULL; -+ int *vals = NULL; - -- if (!map) { -+ if (map == NULL) { - return -1; - } - -@@ -548,7 +548,7 @@ yajl_gen_status gen_json_map_int_bool(void *ctx, json_map_int_bool *map, struct - yajl_gen_status stat = yajl_gen_status_ok; - yajl_gen g = (yajl_gen) ctx; - size_t len = 0, i = 0; -- if (map) { -+ if (map != NULL) { - len = map->len; - } - if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { -@@ -590,7 +590,7 @@ yajl_gen_status gen_json_map_int_bool(void *ctx, json_map_int_bool *map, struct - } - - void free_json_map_int_bool(json_map_int_bool *map) { -- if (map) { -+ if (map != NULL) { - size_t i; - for (i = 0; i < map->len; i++) { - // No need to free key for type int -@@ -605,7 +605,7 @@ void free_json_map_int_bool(json_map_int_bool *map) { - } - json_map_int_bool *make_json_map_int_bool(yajl_val src, struct parser_context *ctx, parser_error *err) { - json_map_int_bool *ret = NULL; -- if (src && YAJL_GET_OBJECT(src)) { -+ if (src != NULL && YAJL_GET_OBJECT(src) != NULL) { - size_t i; - size_t len = YAJL_GET_OBJECT(src)->len; - ret = safe_malloc(sizeof(*ret)); -@@ -616,11 +616,11 @@ json_map_int_bool *make_json_map_int_bool(yajl_val src, struct parser_context *c - const char *srckey = YAJL_GET_OBJECT(src)->keys[i]; - yajl_val srcval = YAJL_GET_OBJECT(src)->values[i]; - -- if (srckey) { -+ if (srckey != NULL) { - int invalid; - invalid = common_safe_int(srckey, &(ret->keys[i])); - if (invalid) { -- if (!*err && asprintf(err, "Invalid key '%s' with type 'int': %s", srckey, strerror(-invalid)) < 0) { -+ if (*err == NULL && asprintf(err, "Invalid key '%s' with type 'int': %s", srckey, strerror(-invalid)) < 0) { - *(err) = safe_strdup("error allocating memory"); - } - free_json_map_int_bool(ret); -@@ -628,13 +628,13 @@ json_map_int_bool *make_json_map_int_bool(yajl_val src, struct parser_context *c - } - } - -- if (srcval) { -+ if (srcval != NULL) { - if (YAJL_IS_TRUE(srcval)) { - ret->values[i] = true; - } else if (YAJL_IS_FALSE(srcval)) { - ret->values[i] = false; - } else { -- if (!*err && asprintf(err, "Invalid value with type 'bool' for key '%s'", srckey) < 0) { -+ if (*err == NULL && asprintf(err, "Invalid value with type 'bool' for key '%s'", srckey) < 0) { - *(err) = safe_strdup("error allocating memory"); - } - free_json_map_int_bool(ret); -@@ -647,10 +647,10 @@ json_map_int_bool *make_json_map_int_bool(yajl_val src, struct parser_context *c - } - int append_json_map_int_bool(json_map_int_bool *map, int key, bool val) { - size_t len; -- int *keys; -- bool *vals; -+ int *keys = NULL; -+ bool *vals = NULL; - -- if (!map) { -+ if (map == NULL) { - return -1; - } - -@@ -689,7 +689,7 @@ yajl_gen_status gen_json_map_int_string(void *ctx, json_map_int_string *map, str - yajl_gen_status stat = yajl_gen_status_ok; - yajl_gen g = (yajl_gen) ctx; - size_t len = 0, i = 0; -- if (map) { -+ if (map != NULL) { - len = map->len; - } - if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { -@@ -731,7 +731,7 @@ yajl_gen_status gen_json_map_int_string(void *ctx, json_map_int_string *map, str - } - - void free_json_map_int_string(json_map_int_string *map) { -- if (map) { -+ if (map != NULL) { - size_t i; - for (i = 0; i < map->len; i++) { - // No need to free key for type int -@@ -747,7 +747,7 @@ void free_json_map_int_string(json_map_int_string *map) { - } - json_map_int_string *make_json_map_int_string(yajl_val src, struct parser_context *ctx, parser_error *err) { - json_map_int_string *ret = NULL; -- if (src && YAJL_GET_OBJECT(src)) { -+ if (src != NULL && YAJL_GET_OBJECT(src) != NULL) { - size_t i; - size_t len = YAJL_GET_OBJECT(src)->len; - ret = safe_malloc(sizeof(*ret)); -@@ -758,11 +758,11 @@ json_map_int_string *make_json_map_int_string(yajl_val src, struct parser_contex - const char *srckey = YAJL_GET_OBJECT(src)->keys[i]; - yajl_val srcval = YAJL_GET_OBJECT(src)->values[i]; - -- if (srckey) { -+ if (srckey != NULL) { - int invalid; - invalid = common_safe_int(srckey, &(ret->keys[i])); - if (invalid) { -- if (!*err && asprintf(err, "Invalid key '%s' with type 'int': %s", srckey, strerror(-invalid)) < 0) { -+ if (*err == NULL && asprintf(err, "Invalid key '%s' with type 'int': %s", srckey, strerror(-invalid)) < 0) { - *(err) = safe_strdup("error allocating memory"); - } - free_json_map_int_string(ret); -@@ -770,9 +770,9 @@ json_map_int_string *make_json_map_int_string(yajl_val src, struct parser_contex - } - } - -- if (srcval) { -+ if (srcval != NULL) { - if (!YAJL_IS_STRING(srcval)) { -- if (!*err && asprintf(err, "Invalid value with type 'string' for key '%s'", srckey) < 0) { -+ if (*err == NULL && asprintf(err, "Invalid value with type 'string' for key '%s'", srckey) < 0) { - *(err) = safe_strdup("error allocating memory"); - } - free_json_map_int_string(ret); -@@ -787,10 +787,10 @@ json_map_int_string *make_json_map_int_string(yajl_val src, struct parser_contex - } - int append_json_map_int_string(json_map_int_string *map, int key, const char *val) { - size_t len; -- int *keys; -- char **vals; -+ int *keys = NULL; -+ char **vals = NULL; - -- if (!map) { -+ if (map == NULL) { - return -1; - } - -@@ -829,7 +829,7 @@ yajl_gen_status gen_json_map_string_int(void *ctx, json_map_string_int *map, str - yajl_gen_status stat = yajl_gen_status_ok; - yajl_gen g = (yajl_gen) ctx; - size_t len = 0, i = 0; -- if (map) { -+ if (map != NULL) { - len = map->len; - } - if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { -@@ -862,7 +862,7 @@ yajl_gen_status gen_json_map_string_int(void *ctx, json_map_string_int *map, str - } - - void free_json_map_string_int(json_map_string_int *map) { -- if (map) { -+ if (map != NULL) { - size_t i; - for (i = 0; i < map->len; i++) { - free(map->keys[i]); -@@ -878,7 +878,7 @@ void free_json_map_string_int(json_map_string_int *map) { - } - json_map_string_int *make_json_map_string_int(yajl_val src, struct parser_context *ctx, parser_error *err) { - json_map_string_int *ret = NULL; -- if (src && YAJL_GET_OBJECT(src)) { -+ if (src != NULL && YAJL_GET_OBJECT(src) != NULL) { - size_t i; - size_t len = YAJL_GET_OBJECT(src)->len; - ret = safe_malloc(sizeof(*ret)); -@@ -890,10 +890,10 @@ json_map_string_int *make_json_map_string_int(yajl_val src, struct parser_contex - yajl_val srcval = YAJL_GET_OBJECT(src)->values[i]; - ret->keys[i] = safe_strdup(srckey ? srckey : ""); - -- if (srcval) { -+ if (srcval != NULL) { - int invalid; - if (!YAJL_IS_NUMBER(srcval)) { -- if (!*err && asprintf(err, "Invalid value with type 'int' for key '%s'", srckey) < 0) { -+ if (*err == NULL && asprintf(err, "Invalid value with type 'int' for key '%s'", srckey) < 0) { - *(err) = safe_strdup("error allocating memory"); - } - free_json_map_string_int(ret); -@@ -901,7 +901,7 @@ json_map_string_int *make_json_map_string_int(yajl_val src, struct parser_contex - } - invalid = common_safe_int(YAJL_GET_NUMBER(srcval), &(ret->values[i])); - if (invalid) { -- if (!*err && asprintf(err, "Invalid value with type 'int' for key '%s': %s", srckey, strerror(-invalid)) < 0) { -+ if (*err == NULL && asprintf(err, "Invalid value with type 'int' for key '%s': %s", srckey, strerror(-invalid)) < 0) { - *(err) = safe_strdup("error allocating memory"); - } - free_json_map_string_int(ret); -@@ -914,10 +914,10 @@ json_map_string_int *make_json_map_string_int(yajl_val src, struct parser_contex - } - int append_json_map_string_int(json_map_string_int *map, const char *key, int val) { - size_t len; -- char **keys; -- int *vals; -+ char **keys = NULL; -+ int *vals = NULL; - -- if (!map) { -+ if (map == NULL) { - return -1; - } - -@@ -956,7 +956,7 @@ yajl_gen_status gen_json_map_string_bool(void *ctx, json_map_string_bool *map, s - yajl_gen_status stat = yajl_gen_status_ok; - yajl_gen g = (yajl_gen) ctx; - size_t len = 0, i = 0; -- if (map) { -+ if (map != NULL) { - len = map->len; - } - if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { -@@ -989,7 +989,7 @@ yajl_gen_status gen_json_map_string_bool(void *ctx, json_map_string_bool *map, s - } - - void free_json_map_string_bool(json_map_string_bool *map) { -- if (map) { -+ if (map != NULL) { - size_t i; - for (i = 0; i < map->len; i++) { - free(map->keys[i]); -@@ -1005,7 +1005,7 @@ void free_json_map_string_bool(json_map_string_bool *map) { - } - json_map_string_bool *make_json_map_string_bool(yajl_val src, struct parser_context *ctx, parser_error *err) { - json_map_string_bool *ret = NULL; -- if (src && YAJL_GET_OBJECT(src)) { -+ if (src != NULL && YAJL_GET_OBJECT(src) != NULL) { - size_t i; - size_t len = YAJL_GET_OBJECT(src)->len; - ret = safe_malloc(sizeof(*ret)); -@@ -1017,13 +1017,13 @@ json_map_string_bool *make_json_map_string_bool(yajl_val src, struct parser_cont - yajl_val srcval = YAJL_GET_OBJECT(src)->values[i]; - ret->keys[i] = safe_strdup(srckey ? srckey : ""); - -- if (srcval) { -+ if (srcval != NULL) { - if (YAJL_IS_TRUE(srcval)) { - ret->values[i] = true; - } else if (YAJL_IS_FALSE(srcval)) { - ret->values[i] = false; - } else { -- if (!*err && asprintf(err, "Invalid value with type 'bool' for key '%s'", srckey) < 0) { -+ if (*err == NULL && asprintf(err, "Invalid value with type 'bool' for key '%s'", srckey) < 0) { - *(err) = safe_strdup("error allocating memory"); - } - free_json_map_string_bool(ret); -@@ -1036,10 +1036,10 @@ json_map_string_bool *make_json_map_string_bool(yajl_val src, struct parser_cont - } - int append_json_map_string_bool(json_map_string_bool *map, const char *key, bool val) { - size_t len; -- char **keys; -- bool *vals; -+ char **keys = NULL; -+ bool *vals = NULL; - -- if (!map) { -+ if (map == NULL) { - return -1; - } - -@@ -1078,7 +1078,7 @@ yajl_gen_status gen_json_map_string_string(void *ctx, json_map_string_string *ma - yajl_gen_status stat = yajl_gen_status_ok; - yajl_gen g = (yajl_gen) ctx; - size_t len = 0, i = 0; -- if (map) { -+ if (map != NULL) { - len = map->len; - } - if (!len && !(ptx->options & GEN_OPTIONS_SIMPLIFY)) { -@@ -1111,7 +1111,7 @@ yajl_gen_status gen_json_map_string_string(void *ctx, json_map_string_string *ma - } - - void free_json_map_string_string(json_map_string_string *map) { -- if (map) { -+ if (map != NULL) { - size_t i; - for (i = 0; i < map->len; i++) { - free(map->keys[i]); -@@ -1128,7 +1128,7 @@ void free_json_map_string_string(json_map_string_string *map) { - } - json_map_string_string *make_json_map_string_string(yajl_val src, struct parser_context *ctx, parser_error *err) { - json_map_string_string *ret = NULL; -- if (src && YAJL_GET_OBJECT(src)) { -+ if (src != NULL && YAJL_GET_OBJECT(src) != NULL) { - size_t i; - size_t len = YAJL_GET_OBJECT(src)->len; - ret = safe_malloc(sizeof(*ret)); -@@ -1140,9 +1140,9 @@ json_map_string_string *make_json_map_string_string(yajl_val src, struct parser_ - yajl_val srcval = YAJL_GET_OBJECT(src)->values[i]; - ret->keys[i] = safe_strdup(srckey ? srckey : ""); - -- if (srcval) { -+ if (srcval != NULL) { - if (!YAJL_IS_STRING(srcval)) { -- if (!*err && asprintf(err, "Invalid value with type 'string' for key '%s'", srckey) < 0) { -+ if (*err == NULL && asprintf(err, "Invalid value with type 'string' for key '%s'", srckey) < 0) { - *(err) = safe_strdup("error allocating memory"); - } - free_json_map_string_string(ret); -@@ -1157,10 +1157,10 @@ json_map_string_string *make_json_map_string_string(yajl_val src, struct parser_ - } - int append_json_map_string_string(json_map_string_string *map, const char *key, const char *val) { - size_t len, i; -- char **keys; -- char **vals; -+ char **keys = NULL; -+ char **vals = NULL; - -- if (!map) { -+ if (map == NULL) { - return -1; - } - -diff --git a/src/lxc/json/json_common.h b/src/lxc/json/json_common.h -index eb8281c..218a837 100755 ---- a/src/lxc/json/json_common.h -+++ b/src/lxc/json/json_common.h -@@ -27,7 +27,7 @@ extern "C" { - # define GEN_OPTIONS_NOT_VALIDATE_UTF8 0x08 - - #define GEN_SET_ERROR_AND_RETURN(stat, err) { \ -- if (!*(err)) {\ -+ if (*(err) == NULL) {\ - if (asprintf(err, "%s: %s: %d: error generating json, errcode: %d", __FILE__, __func__, __LINE__, stat) < 0) { \ - *(err) = safe_strdup("error allocating memory"); \ - } \ -diff --git a/src/lxc/json/logger_json_file.c b/src/lxc/json/logger_json_file.c -index 4d78103..6433b04 100644 ---- a/src/lxc/json/logger_json_file.c -+++ b/src/lxc/json/logger_json_file.c -@@ -15,32 +15,32 @@ logger_json_file *make_logger_json_file(yajl_val tree, struct parser_context *ct - ret = safe_malloc(sizeof(*ret)); - { - yajl_val tmp = get_val(tree, "log", yajl_t_string); -- if (tmp) { -+ if (tmp != NULL) { - char *str = YAJL_GET_STRING(tmp); - ret->log = (uint8_t *)safe_strdup(str ? str : ""); -- ret->log_len = str ? strlen(str) : 0; -+ ret->log_len = str != NULL ? strlen(str) : 0; - } - } - { - yajl_val val = get_val(tree, "stream", yajl_t_string); -- if (val) { -+ if (val != NULL) { - char *str = YAJL_GET_STRING(val); - ret->stream = safe_strdup(str ? str : ""); - } - } - { - yajl_val val = get_val(tree, "time", yajl_t_string); -- if (val) { -+ if (val != NULL) { - char *str = YAJL_GET_STRING(val); - ret->time = safe_strdup(str ? str : ""); - } - } - { - yajl_val tmp = get_val(tree, "attrs", yajl_t_string); -- if (tmp) { -+ if (tmp != NULL) { - char *str = YAJL_GET_STRING(tmp); - ret->attrs = (uint8_t *)safe_strdup(str ? str : ""); -- ret->attrs_len = str ? strlen(str) : 0; -+ ret->attrs_len = str != NULL ? strlen(str) : 0; - } - } - -@@ -59,7 +59,7 @@ logger_json_file *make_logger_json_file(yajl_val tree, struct parser_context *ct - } - - void free_logger_json_file(logger_json_file *ptr) { -- if (!ptr) -+ if (ptr == NULL) - return; - free(ptr->log); - ptr->log = NULL; -@@ -78,13 +78,13 @@ yajl_gen_status gen_logger_json_file(yajl_gen g, logger_json_file *ptr, struct p - stat = reformat_start_map(g); - if (yajl_gen_status_ok != stat) - GEN_SET_ERROR_AND_RETURN(stat, err); -- if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) || (ptr && ptr->log && ptr->log_len)) { -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) || (ptr != NULL && ptr->log != NULL && ptr->log_len)) { - const char *str = ""; - size_t len = 0; - stat = reformat_map_key(g, "log", strlen("log")); - if (yajl_gen_status_ok != stat) - GEN_SET_ERROR_AND_RETURN(stat, err); -- if (ptr && ptr->log) { -+ if (ptr != NULL && ptr->log != NULL) { - str = (const char *)ptr->log; - len = ptr->log_len; - } -@@ -92,37 +92,37 @@ yajl_gen_status gen_logger_json_file(yajl_gen g, logger_json_file *ptr, struct p - if (yajl_gen_status_ok != stat) - GEN_SET_ERROR_AND_RETURN(stat, err); - } -- if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr && ptr->stream)) { -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->stream != NULL)) { - char *str = ""; - stat = reformat_map_key(g, "stream", strlen("stream")); - if (yajl_gen_status_ok != stat) - GEN_SET_ERROR_AND_RETURN(stat, err); -- if (ptr && ptr->stream) { -+ if (ptr != NULL && ptr->stream != NULL) { - str = ptr->stream; - } - stat = reformat_string(g, str, strlen(str)); - if (yajl_gen_status_ok != stat) - GEN_SET_ERROR_AND_RETURN(stat, err); - } -- if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr && ptr->time)) { -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->time != NULL)) { - char *str = ""; - stat = reformat_map_key(g, "time", strlen("time")); - if (yajl_gen_status_ok != stat) - GEN_SET_ERROR_AND_RETURN(stat, err); -- if (ptr && ptr->time) { -+ if (ptr != NULL && ptr->time != NULL) { - str = ptr->time; - } - stat = reformat_string(g, str, strlen(str)); - if (yajl_gen_status_ok != stat) - GEN_SET_ERROR_AND_RETURN(stat, err); - } -- if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) || (ptr && ptr->attrs && ptr->attrs_len)) { -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) || (ptr != NULL && ptr->attrs != NULL && ptr->attrs_len)) { - const char *str = ""; - size_t len = 0; - stat = reformat_map_key(g, "attrs", strlen("attrs")); - if (yajl_gen_status_ok != stat) - GEN_SET_ERROR_AND_RETURN(stat, err); -- if (ptr && ptr->attrs) { -+ if (ptr != NULL && ptr->attrs != NULL) { - str = (const char *)ptr->attrs; - len = ptr->attrs_len; - } -@@ -140,9 +140,9 @@ yajl_gen_status gen_logger_json_file(yajl_gen g, logger_json_file *ptr, struct p - logger_json_file *logger_json_file_parse_file(const char *filename, struct parser_context *ctx, parser_error *err) { - logger_json_file *ptr; - size_t filesize; -- char *content; -+ char *content = NULL; - -- if (!filename || !err) -+ if (filename == NULL || err == NULL) - return NULL; - - *err = NULL; -@@ -160,9 +160,9 @@ logger_json_file *logger_json_file_parse_file(const char *filename, struct parse - logger_json_file *logger_json_file_parse_file_stream(FILE *stream, struct parser_context *ctx, parser_error *err) { - logger_json_file *ptr; - size_t filesize; -- char *content ; -+ char *content = NULL ; - -- if (!stream || !err) -+ if (stream == NULL || err == NULL) - return NULL; - - *err = NULL; -@@ -182,11 +182,11 @@ logger_json_file *logger_json_file_parse_data(const char *jsondata, struct parse - char errbuf[1024]; - struct parser_context tmp_ctx; - -- if (!jsondata || !err) -+ if (jsondata == NULL || err == NULL) - return NULL; - - *err = NULL; -- if (!ctx) { -+ if (ctx == NULL) { - ctx = &tmp_ctx; - memset(&tmp_ctx, 0, sizeof(tmp_ctx)); - } -@@ -207,11 +207,11 @@ char *logger_json_file_generate_json(logger_json_file *ptr, struct parser_contex - char *json_buf = NULL; - size_t gen_len = 0; - -- if (!ptr || !err) -+ if (ptr == NULL || err == NULL) - return NULL; - - *err = NULL; -- if (!ctx) { -+ if (ctx == NULL) { - ctx = &tmp_ctx; - memset(&tmp_ctx, 0, sizeof(tmp_ctx)); - } -@@ -221,12 +221,12 @@ char *logger_json_file_generate_json(logger_json_file *ptr, struct parser_contex - goto out; - } - if (yajl_gen_status_ok != gen_logger_json_file(g, ptr, ctx, err)) { -- if (!*err) -+ if (*err == NULL) - *err = safe_strdup("Failed to generate json"); - goto free_out; - } - yajl_gen_get_buf(g, &gen_buf, &gen_len); -- if (!gen_buf) { -+ if (gen_buf == NULL) { - *err = safe_strdup("Error to get generated json"); - goto free_out; - } -diff --git a/src/lxc/json/oci_runtime_hooks.c b/src/lxc/json/oci_runtime_hooks.c -index 3aa134e..43ff8d7 100644 ---- a/src/lxc/json/oci_runtime_hooks.c -+++ b/src/lxc/json/oci_runtime_hooks.c -@@ -46,8 +46,7 @@ oci_runtime_spec_hooks *oci_runtime_spec_hooks_parse_file(const char *filename, - } - return NULL; - } -- oci_runtime_spec_hooks *ptr = make_oci_runtime_spec_hooks(tree, ctx, -- err); -+ oci_runtime_spec_hooks *ptr = make_oci_runtime_spec_hooks(tree, ctx, err); - yajl_tree_free(tree); - return ptr; - } -diff --git a/src/lxc/json/oci_runtime_spec.c b/src/lxc/json/oci_runtime_spec.c -index 1f6073c..4ccb635 100644 ---- a/src/lxc/json/oci_runtime_spec.c -+++ b/src/lxc/json/oci_runtime_spec.c -@@ -15,7 +15,7 @@ oci_runtime_spec_hooks *make_oci_runtime_spec_hooks(yajl_val tree, struct parser - ret = safe_malloc(sizeof(*ret)); - { - yajl_val tmp = get_val(tree, "prestart", yajl_t_array); -- if (tmp && YAJL_GET_ARRAY(tmp)) { -+ if (tmp != NULL && YAJL_GET_ARRAY(tmp) != NULL && YAJL_GET_ARRAY(tmp)->len > 0) { - size_t i; - ret->prestart_len = YAJL_GET_ARRAY(tmp)->len; - ret->prestart = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->prestart)); -@@ -31,7 +31,7 @@ oci_runtime_spec_hooks *make_oci_runtime_spec_hooks(yajl_val tree, struct parser - } - { - yajl_val tmp = get_val(tree, "poststart", yajl_t_array); -- if (tmp && YAJL_GET_ARRAY(tmp)) { -+ if (tmp != NULL && YAJL_GET_ARRAY(tmp) != NULL && YAJL_GET_ARRAY(tmp)->len > 0) { - size_t i; - ret->poststart_len = YAJL_GET_ARRAY(tmp)->len; - ret->poststart = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->poststart)); -@@ -47,7 +47,7 @@ oci_runtime_spec_hooks *make_oci_runtime_spec_hooks(yajl_val tree, struct parser - } - { - yajl_val tmp = get_val(tree, "poststop", yajl_t_array); -- if (tmp && YAJL_GET_ARRAY(tmp)) { -+ if (tmp != NULL && YAJL_GET_ARRAY(tmp) != NULL && YAJL_GET_ARRAY(tmp)->len > 0) { - size_t i; - ret->poststop_len = YAJL_GET_ARRAY(tmp)->len; - ret->poststop = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->poststop)); -@@ -76,32 +76,32 @@ oci_runtime_spec_hooks *make_oci_runtime_spec_hooks(yajl_val tree, struct parser - } - - void free_oci_runtime_spec_hooks(oci_runtime_spec_hooks *ptr) { -- if (!ptr) -+ if (ptr == NULL) - return; -- if (ptr->prestart) { -+ if (ptr->prestart != NULL) { - size_t i; - for (i = 0; i < ptr->prestart_len; i++) -- if (ptr->prestart[i]) { -+ if (ptr->prestart[i] != NULL) { - free_defs_hook(ptr->prestart[i]); - ptr->prestart[i] = NULL; - } - free(ptr->prestart); - ptr->prestart = NULL; - } -- if (ptr->poststart) { -+ if (ptr->poststart != NULL) { - size_t i; - for (i = 0; i < ptr->poststart_len; i++) -- if (ptr->poststart[i]) { -+ if (ptr->poststart[i] != NULL) { - free_defs_hook(ptr->poststart[i]); - ptr->poststart[i] = NULL; - } - free(ptr->poststart); - ptr->poststart = NULL; - } -- if (ptr->poststop) { -+ if (ptr->poststop != NULL) { - size_t i; - for (i = 0; i < ptr->poststop_len; i++) -- if (ptr->poststop[i]) { -+ if (ptr->poststop[i] != NULL) { - free_defs_hook(ptr->poststop[i]); - ptr->poststop[i] = NULL; - } -@@ -117,12 +117,12 @@ yajl_gen_status gen_oci_runtime_spec_hooks(yajl_gen g, oci_runtime_spec_hooks *p - stat = reformat_start_map(g); - if (yajl_gen_status_ok != stat) - GEN_SET_ERROR_AND_RETURN(stat, err); -- if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr && ptr->prestart)) { -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->prestart != NULL)) { - size_t len = 0, i; - stat = reformat_map_key(g, "prestart", strlen("prestart")); - if (yajl_gen_status_ok != stat) - GEN_SET_ERROR_AND_RETURN(stat, err); -- if (ptr && ptr->prestart) { -+ if (ptr != NULL && ptr->prestart != NULL) { - len = ptr->prestart_len; - } - if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) -@@ -141,12 +141,12 @@ yajl_gen_status gen_oci_runtime_spec_hooks(yajl_gen g, oci_runtime_spec_hooks *p - if (yajl_gen_status_ok != stat) - GEN_SET_ERROR_AND_RETURN(stat, err); - } -- if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr && ptr->poststart)) { -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->poststart != NULL)) { - size_t len = 0, i; - stat = reformat_map_key(g, "poststart", strlen("poststart")); - if (yajl_gen_status_ok != stat) - GEN_SET_ERROR_AND_RETURN(stat, err); -- if (ptr && ptr->poststart) { -+ if (ptr != NULL && ptr->poststart != NULL) { - len = ptr->poststart_len; - } - if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) -@@ -165,12 +165,12 @@ yajl_gen_status gen_oci_runtime_spec_hooks(yajl_gen g, oci_runtime_spec_hooks *p - if (yajl_gen_status_ok != stat) - GEN_SET_ERROR_AND_RETURN(stat, err); - } -- if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr && ptr->poststop)) { -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->poststop != NULL)) { - size_t len = 0, i; - stat = reformat_map_key(g, "poststop", strlen("poststop")); - if (yajl_gen_status_ok != stat) - GEN_SET_ERROR_AND_RETURN(stat, err); -- if (ptr && ptr->poststop) { -+ if (ptr != NULL && ptr->poststop != NULL) { - len = ptr->poststop_len; - } - if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) --- -1.8.3.1 - diff --git a/0087-lxc-adapt-to-spec-of-oci-hook.patch b/0087-lxc-adapt-to-spec-of-oci-hook.patch deleted file mode 100644 index f2262871f192339fbe1e780f884c290cd94a41da..0000000000000000000000000000000000000000 --- a/0087-lxc-adapt-to-spec-of-oci-hook.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 363ac4aedbf09ade3de55bca20692cf157860f92 Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Wed, 24 Apr 2019 22:22:55 +0800 -Subject: [PATCH 087/140] lxc: adapt to spec of oci hook - -poststart failed do not cause run failed - -Signed-off-by: liuhao -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 8cdccf1..a1d77eb 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4782,6 +4782,7 @@ static int run_oci_hooks(const char *name, const char *lxcpath, struct lxc_conf - struct oci_hook_conf work_conf = {0}; - size_t i; - int ret = 0; -+ int nret = 0; - char *rootpath; - - if (!lc) { -@@ -4811,9 +4812,9 @@ static int run_oci_hooks(const char *name, const char *lxcpath, struct lxc_conf - case OCI_HOOK_POSTSTART: - for (i = 0; i < lc->ocihooks->poststart_len; i++) { - work_conf.ocihook = lc->ocihooks->poststart[i]; -- ret = run_ocihook_script_argv(name, "lxc", &work_conf, lxcpath, rootpath); -- if (ret != 0) -- break; -+ nret = run_ocihook_script_argv(name, "lxc", &work_conf, lxcpath, rootpath); -+ if (nret != 0) -+ WARN("running poststart hook %d failed, ContainerId: %s", i, name); - } - break; - case OCI_HOOK_POSTSTOP: --- -1.8.3.1 - diff --git a/0088-fix-lxc-build-error.patch b/0088-fix-lxc-build-error.patch deleted file mode 100644 index f94b11b348875e5b0f6d5428cadaed348bcae85d..0000000000000000000000000000000000000000 --- a/0088-fix-lxc-build-error.patch +++ /dev/null @@ -1,29 +0,0 @@ -From c0efbe3c3aafaad6842d8a28cd06635bbb5a566c Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Thu, 25 Apr 2019 10:12:16 +0800 -Subject: [PATCH 088/140] fix lxc build error - -cause by invalid print format - -Signed-off-by: liuhao -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index a1d77eb..14d5d80 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4814,7 +4814,7 @@ static int run_oci_hooks(const char *name, const char *lxcpath, struct lxc_conf - 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 %d failed, ContainerId: %s", i, name); -+ WARN("running poststart hook %ld failed, ContainerId: %s", i, name); - } - break; - case OCI_HOOK_POSTSTOP: --- -1.8.3.1 - diff --git a/0089-lxc-add-get-container-processes-pids-func.patch b/0089-lxc-add-get-container-processes-pids-func.patch deleted file mode 100644 index 964f7ae3d8922684752d618e6dc15696702c1b61..0000000000000000000000000000000000000000 --- a/0089-lxc-add-get-container-processes-pids-func.patch +++ /dev/null @@ -1,177 +0,0 @@ -From e67bd0cb9f6228f5ff95e71ae3cb1332cb1ff851 Mon Sep 17 00:00:00 2001 -From: maoweiyong -Date: Tue, 23 Apr 2019 12:12:55 +0800 -Subject: [PATCH 089/140] lxc:add get container processes pids func - -Signed-off-by: maoweiyong ---- - src/lxc/lxccontainer.c | 18 ++++++++++++ - src/lxc/lxccontainer.h | 11 ++++++++ - src/lxc/start.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++ - src/lxc/start.h | 2 ++ - 4 files changed, 107 insertions(+) - -diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index 8a3724c..fa13e52 100644 ---- a/src/lxc/lxccontainer.c -+++ b/src/lxc/lxccontainer.c -@@ -5212,6 +5212,23 @@ static bool do_lxcapi_clean_container_resource(struct lxc_container *c, pid_t pi - - WRAP_API_1(bool, lxcapi_clean_container_resource, pid_t) - -+/* isulad get coantainer pids */ -+static bool do_lxcapi_get_container_pids(struct lxc_container *c, pid_t **pids,size_t *pids_len) -+{ -+ int ret; -+ -+ if (!c) -+ return false; -+ -+ 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; -+ -+} -+ -+WRAP_API_2(bool, lxcapi_get_container_pids, pid_t **,size_t *) -+ - /* isulad add clean resources */ - static bool do_lxcapi_add_terminal_fifo(struct lxc_container *c, const char *in_fifo, const char *out_fifo, const char *err_fifo) - { -@@ -5373,6 +5390,7 @@ static struct lxc_container *do_lxc_container_new(const char *name, const char * - c->set_start_timeout = lxcapi_set_start_timeout; - c->clean_container_resource = lxcapi_clean_container_resource; - c->add_terminal_fifos = lxcapi_add_terminal_fifo; -+ c->get_container_pids = lxcapi_get_container_pids; - /* isulad add end */ - return c; - -diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h -index c3368e4..608f815 100644 ---- a/src/lxc/lxccontainer.h -+++ b/src/lxc/lxccontainer.h -@@ -947,6 +947,17 @@ struct lxc_container { - * \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); - }; - - /*! -diff --git a/src/lxc/start.c b/src/lxc/start.c -index f1cd7fa..2b0d43e 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -2638,6 +2638,55 @@ on_error: - return NULL; - } - -+/*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) -+ 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. -+ */ -+ 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(handler); -+ if (!handler->cgroup_ops) { -+ ERROR("Failed to initialize cgroup driver"); -+ goto on_error; -+ } -+ -+ INFO("Container \"%s\" 's clean handler is initialized.", name); -+ -+ return handler; -+ -+on_error: -+ lxc_free_handler(handler); -+ -+ return NULL; -+} -+ - /*isulad: set env for clean resources */ - static int clean_resource_set_env(struct lxc_handler *handler) - { -@@ -2770,3 +2819,30 @@ out: - return ret; - } - -+/*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) -+{ -+ int ret = 0; -+ struct lxc_handler *handler = NULL; -+ int retry_count = 0; -+ int max_retry = 10; -+ struct cgroup_ops *cg_ops = NULL; -+ -+ handler = lxc_init_pids_handler(name, lxcpath, conf); -+ if (!handler) { -+ ERROR("Failed to init container %s clean handler", name); -+ ret = -1; -+ goto out; -+ } -+ -+ cg_ops = handler->cgroup_ops; -+ ret = get_all_pids(cg_ops, pids, pids_len); -+ if (ret < 0) { -+ WARN("failed to get all pids"); -+ } -+ -+out: -+ lxc_free_handler(handler); -+ return ret; -+} -+ -diff --git a/src/lxc/start.h b/src/lxc/start.h -index 0298991..20e667c 100644 ---- a/src/lxc/start.h -+++ b/src/lxc/start.h -@@ -188,5 +188,7 @@ extern int resolve_clone_flags(struct lxc_handler *handler); - /*isulad: do_lxcapi_clean_resource */ - extern int do_lxcapi_clean_resource(char *name, char *lxcpath, struct lxc_conf *conf, pid_t pid); - -+/*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 --- -1.8.3.1 - diff --git a/0090-lxc-remove-unused-variable.patch b/0090-lxc-remove-unused-variable.patch deleted file mode 100644 index 9ffdd59fbbcfa03a08bd5561796a2f10e5367a66..0000000000000000000000000000000000000000 --- a/0090-lxc-remove-unused-variable.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 9d7bdd43ca5710e625f02b2dcc7b178071f4ae2b Mon Sep 17 00:00:00 2001 -From: maoweiyong -Date: Thu, 25 Apr 2019 21:21:12 +0800 -Subject: [PATCH 090/140] lxc: remove unused variable - -Signed-off-by: maoweiyong ---- - src/lxc/start.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/src/lxc/start.c b/src/lxc/start.c -index 2b0d43e..3657d4e 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -2824,8 +2824,6 @@ int do_lxcapi_get_pids(char *name, char *lxcpath, struct lxc_conf *conf, pid_t * - { - int ret = 0; - struct lxc_handler *handler = NULL; -- int retry_count = 0; -- int max_retry = 10; - struct cgroup_ops *cg_ops = NULL; - - handler = lxc_init_pids_handler(name, lxcpath, conf); --- -1.8.3.1 - diff --git a/0092-lxc-add-output-error-when-create-unified-cgroup.patch b/0092-lxc-add-output-error-when-create-unified-cgroup.patch deleted file mode 100644 index ea2a75a100013d68028697f5a316f716fe5e98eb..0000000000000000000000000000000000000000 --- a/0092-lxc-add-output-error-when-create-unified-cgroup.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 3e1d32785539e016dbca1e69fdb3a8bf93299238 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Mon, 29 Apr 2019 04:13:52 -0400 -Subject: [PATCH 092/140] lxc: add output error when create unified cgroup - -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgfsng.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index b1f56b0..2bf142f 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -1132,7 +1132,7 @@ __cgfsng_ops static bool cgfsng_payload_destroy(struct cgroup_ops *ops, - return true; - } - --static bool cg_unified_create_cgroup(struct hierarchy *h, char *cgname) -+static bool cg_unified_create_cgroup(struct hierarchy *h, char *cgname, int errfd) - { - size_t i, parts_len; - char **it; -@@ -1187,6 +1187,9 @@ static bool cg_unified_create_cgroup(struct hierarchy *h, char *cgname) - if (ret < 0) { - SYSERROR("Could not enable \"%s\" controllers in the " - "unified cgroup \"%s\"", add_controllers, cgroup); -+ lxc_write_error_message(errfd, "%s:%d: Could not enable \"%s\" controllers in the " -+ "unified cgroup: \"%s\"", -+ __FILE__, __LINE__, add_controllers, strerror(errno)); - goto on_error; - } - } -@@ -1260,7 +1263,7 @@ static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname, int err - return false; - } - -- return cg_unified_create_cgroup(h, cgname); -+ return cg_unified_create_cgroup(h, cgname, errfd); - } - - /* isulad: create hierarchies path, if fail, return the error */ --- -1.8.3.1 - diff --git a/0093-optimize-isulad_kit-operator.patch b/0093-optimize-isulad_kit-operator.patch deleted file mode 100644 index 10d5720c2d4b2b4ff3f925fe43ad74aaa98d6a85..0000000000000000000000000000000000000000 --- a/0093-optimize-isulad_kit-operator.patch +++ /dev/null @@ -1,424 +0,0 @@ -From eeaf0b1638d87626655577c5b1c1e32e3b3d10a0 Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Thu, 2 May 2019 11:23:50 +0800 -Subject: [PATCH 093/140] optimize isulad_kit operator - -parse group add start container - -Signed-off-by: liuhao -Signed-off-by: LiFeng ---- - src/lxc/Makefile.am | 2 + - src/lxc/json/container_start_generate_config.c | 245 +++++++++++++++++++++++++ - src/lxc/json/container_start_generate_config.h | 43 +++++ - src/lxc/tools/lxc_start.c | 58 ++++++ - 4 files changed, 348 insertions(+) - create mode 100644 src/lxc/json/container_start_generate_config.c - create mode 100644 src/lxc/json/container_start_generate_config.h - -diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am -index 698f8f9..4ec2081 100644 ---- a/src/lxc/Makefile.am -+++ b/src/lxc/Makefile.am -@@ -45,6 +45,7 @@ noinst_HEADERS = attach.h \ - storage/storage_utils.h \ - json/defs.h \ - json/json_common.h \ -+ json/container_start_generate_config.h \ - json/oci_runtime_hooks.h \ - json/oci_runtime_spec.h \ - json/logger_json_file.h \ -@@ -152,6 +153,7 @@ liblxc_la_SOURCES = af_unix.c af_unix.h \ - json/oci_runtime_hooks.c json/oci_runtime_hooks.h \ - json/logger_json_file.c json/logger_json_file.h \ - json/oci_runtime_spec.c json/oci_runtime_spec.h \ -+ json/container_start_generate_config.c json/container_start_generate_config.h \ - json/read-file.c json/read-file.h \ - $(LSM_SOURCES) - -diff --git a/src/lxc/json/container_start_generate_config.c b/src/lxc/json/container_start_generate_config.c -new file mode 100644 -index 0000000..5ec8311 ---- /dev/null -+++ b/src/lxc/json/container_start_generate_config.c -@@ -0,0 +1,245 @@ -+// Generated from start-generate-config.json. Do not edit! -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE -+#endif -+#include -+#include "read-file.h" -+#include "container_start_generate_config.h" -+ -+container_start_generate_config *make_container_start_generate_config(yajl_val tree, struct parser_context *ctx, parser_error *err) { -+ container_start_generate_config *ret = NULL; -+ *err = 0; -+ if (tree == NULL) -+ return ret; -+ ret = safe_malloc(sizeof(*ret)); -+ { -+ yajl_val val = get_val(tree, "uid", yajl_t_number); -+ if (val != NULL) { -+ int invalid = common_safe_uint(YAJL_GET_NUMBER(val), (unsigned int *)&ret->uid); -+ if (invalid) { -+ if (asprintf(err, "Invalid value '%s' with type 'UID' for key 'uid': %s", YAJL_GET_NUMBER(val), strerror(-invalid)) < 0) -+ *err = safe_strdup("error allocating memory"); -+ free_container_start_generate_config(ret); -+ return NULL; -+ } -+ } -+ } -+ { -+ yajl_val val = get_val(tree, "gid", yajl_t_number); -+ if (val != NULL) { -+ int invalid = common_safe_uint(YAJL_GET_NUMBER(val), (unsigned int *)&ret->gid); -+ if (invalid) { -+ if (asprintf(err, "Invalid value '%s' with type 'GID' for key 'gid': %s", YAJL_GET_NUMBER(val), strerror(-invalid)) < 0) -+ *err = safe_strdup("error allocating memory"); -+ free_container_start_generate_config(ret); -+ return NULL; -+ } -+ } -+ } -+ { -+ yajl_val tmp = get_val(tree, "additionalGids", yajl_t_array); -+ if (tmp != NULL && YAJL_GET_ARRAY(tmp) != NULL && YAJL_GET_ARRAY(tmp)->len > 0) { -+ size_t i; -+ ret->additional_gids_len = YAJL_GET_ARRAY(tmp)->len; -+ ret->additional_gids = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->additional_gids)); -+ for (i = 0; i < YAJL_GET_ARRAY(tmp)->len; i++) { -+ yajl_val val = YAJL_GET_ARRAY(tmp)->values[i]; -+ if (val != NULL) { -+ int invalid = common_safe_uint(YAJL_GET_NUMBER(val), (unsigned int *)&ret->additional_gids[i]); -+ if (invalid) { -+ if (asprintf(err, "Invalid value '%s' with type 'GID' for key 'additionalGids': %s", YAJL_GET_NUMBER(val), strerror(-invalid)) < 0) -+ *err = safe_strdup("error allocating memory"); -+ free_container_start_generate_config(ret); -+ return NULL; -+ } -+ } -+ } -+ } -+ } -+ -+ if (tree->type == yajl_t_object && (ctx->options & PARSE_OPTIONS_STRICT)) { -+ int i; -+ for (i = 0; i < tree->u.object.len; i++) -+ if (strcmp(tree->u.object.keys[i], "uid") && -+ strcmp(tree->u.object.keys[i], "gid") && -+ strcmp(tree->u.object.keys[i], "additionalGids")) { -+ if (ctx->stderr > 0) -+ fprintf(ctx->stderr, "WARNING: unknown key found: %s\n", tree->u.object.keys[i]); -+ } -+ } -+ return ret; -+} -+ -+void free_container_start_generate_config(container_start_generate_config *ptr) { -+ if (ptr == NULL) -+ return; -+ free(ptr->additional_gids); -+ ptr->additional_gids = NULL; -+ free(ptr); -+} -+ -+yajl_gen_status gen_container_start_generate_config(yajl_gen g, container_start_generate_config *ptr, struct parser_context *ctx, parser_error *err) { -+ yajl_gen_status stat = yajl_gen_status_ok; -+ *err = 0; -+ stat = reformat_start_map(g); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->uid)) { -+ long long unsigned int num = 0; -+ stat = reformat_map_key(g, "uid", strlen("uid")); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (ptr != NULL && ptr->uid) { -+ num = (long long unsigned int)ptr->uid; -+ } -+ stat = reformat_uint(g, num); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->gid)) { -+ long long unsigned int num = 0; -+ stat = reformat_map_key(g, "gid", strlen("gid")); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (ptr != NULL && ptr->gid) { -+ num = (long long unsigned int)ptr->gid; -+ } -+ stat = reformat_uint(g, num); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) || (ptr != NULL && ptr->additional_gids != NULL)) { -+ size_t len = 0, i; -+ stat = reformat_map_key(g, "additionalGids", strlen("additionalGids")); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (ptr != NULL && ptr->additional_gids != NULL) { -+ len = ptr->additional_gids_len; -+ } -+ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) -+ yajl_gen_config(g, yajl_gen_beautify, 0); -+ stat = reformat_start_array(g); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ for (i = 0; i < len; i++) { -+ stat = reformat_uint(g, ptr->additional_gids[i]); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ stat = reformat_end_array(g); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (!len && !(ctx->options & GEN_OPTIONS_SIMPLIFY)) -+ yajl_gen_config(g, yajl_gen_beautify, 1); -+ } -+ stat = reformat_end_map(g); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ return yajl_gen_status_ok; -+} -+ -+ -+container_start_generate_config *container_start_generate_config_parse_file(const char *filename, struct parser_context *ctx, parser_error *err) { -+ container_start_generate_config *ptr = NULL; -+ size_t filesize; -+ char *content = NULL; -+ -+ if (filename == NULL || err == NULL) -+ return NULL; -+ -+ *err = NULL; -+ content = read_file(filename, &filesize); -+ if (content == NULL) { -+ if (asprintf(err, "cannot read the file: %s", filename) < 0) -+ *err = safe_strdup("error allocating memory"); -+ return NULL; -+ } -+ ptr = container_start_generate_config_parse_data(content, ctx, err); -+ free(content); -+ return ptr; -+} -+ -+container_start_generate_config *container_start_generate_config_parse_file_stream(FILE *stream, struct parser_context *ctx, parser_error *err) { -+ container_start_generate_config *ptr = NULL; -+ size_t filesize; -+ char *content = NULL ; -+ -+ if (stream == NULL || err == NULL) -+ return NULL; -+ -+ *err = NULL; -+ content = fread_file(stream, &filesize); -+ if (content == NULL) { -+ *err = safe_strdup("cannot read the file"); -+ return NULL; -+ } -+ ptr = container_start_generate_config_parse_data(content, ctx, err); -+ free(content); -+ return ptr; -+} -+ -+container_start_generate_config *container_start_generate_config_parse_data(const char *jsondata, struct parser_context *ctx, parser_error *err) { -+ container_start_generate_config *ptr = NULL; -+ yajl_val tree; -+ char errbuf[1024]; -+ struct parser_context tmp_ctx; -+ -+ if (jsondata == NULL || err == NULL) -+ return NULL; -+ -+ *err = NULL; -+ if (ctx == NULL) { -+ ctx = &tmp_ctx; -+ (void)memset(&tmp_ctx, 0, sizeof(tmp_ctx)); -+ } -+ tree = yajl_tree_parse(jsondata, errbuf, sizeof(errbuf)); -+ if (tree == NULL) { -+ if (asprintf(err, "cannot parse the data: %s", errbuf) < 0) -+ *err = safe_strdup("error allocating memory"); -+ return NULL; -+ } -+ ptr = make_container_start_generate_config(tree, ctx, err); -+ yajl_tree_free(tree); -+ return ptr; -+} -+char *container_start_generate_config_generate_json(container_start_generate_config *ptr, struct parser_context *ctx, parser_error *err) { -+ yajl_gen g = NULL; -+ struct parser_context tmp_ctx; -+ const unsigned char *gen_buf = NULL; -+ char *json_buf = NULL; -+ size_t gen_len = 0; -+ -+ if (ptr == NULL || err == NULL) -+ return NULL; -+ -+ *err = NULL; -+ if (ctx == NULL) { -+ ctx = &tmp_ctx; -+ (void)memset(&tmp_ctx, 0, sizeof(tmp_ctx)); -+ } -+ -+ if (!json_gen_init(&g, ctx)) { -+ *err = safe_strdup("Json_gen init failed"); -+ goto out; -+ } -+ if (yajl_gen_status_ok != gen_container_start_generate_config(g, ptr, ctx, err)) { -+ if (*err == NULL) -+ *err = safe_strdup("Failed to generate json"); -+ goto free_out; -+ } -+ yajl_gen_get_buf(g, &gen_buf, &gen_len); -+ if (gen_buf == NULL) { -+ *err = safe_strdup("Error to get generated json"); -+ goto free_out; -+ } -+ -+ json_buf = safe_malloc(gen_len + 1); -+ (void)memcpy(json_buf, gen_buf, gen_len); -+ json_buf[gen_len] = '\0'; -+ -+free_out: -+ yajl_gen_clear(g); -+ yajl_gen_free(g); -+out: -+ return json_buf; -+} -diff --git a/src/lxc/json/container_start_generate_config.h b/src/lxc/json/container_start_generate_config.h -new file mode 100644 -index 0000000..e1dcf56 ---- /dev/null -+++ b/src/lxc/json/container_start_generate_config.h -@@ -0,0 +1,43 @@ -+// Generated from start-generate-config.json. Do not edit! -+#ifndef CONTAINER_START_GENERATE_CONFIG_SCHEMA_H -+#define CONTAINER_START_GENERATE_CONFIG_SCHEMA_H -+ -+#include -+#include -+#include "json_common.h" -+#include "defs.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+typedef struct { -+ uid_t uid; -+ -+ gid_t gid; -+ -+ gid_t *additional_gids; -+ size_t additional_gids_len; -+ -+} -+container_start_generate_config; -+ -+void free_container_start_generate_config(container_start_generate_config *ptr); -+ -+container_start_generate_config *make_container_start_generate_config(yajl_val tree, struct parser_context *ctx, parser_error *err); -+ -+yajl_gen_status gen_container_start_generate_config(yajl_gen g, container_start_generate_config *ptr, struct parser_context *ctx, parser_error *err); -+ -+container_start_generate_config *container_start_generate_config_parse_file(const char *filename, struct parser_context *ctx, parser_error *err); -+ -+container_start_generate_config *container_start_generate_config_parse_file_stream(FILE *stream, struct parser_context *ctx, parser_error *err); -+ -+container_start_generate_config *container_start_generate_config_parse_data(const char *jsondata, struct parser_context *ctx, parser_error *err); -+ -+char *container_start_generate_config_generate_json(container_start_generate_config *ptr, struct parser_context *ctx, parser_error *err); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif -diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c -index af63f58..4069204 100644 ---- a/src/lxc/tools/lxc_start.c -+++ b/src/lxc/tools/lxc_start.c -@@ -50,6 +50,7 @@ - #include "confile.h" - #include "log.h" - #include "utils.h" -+#include "container_start_generate_config.h" - - lxc_log_define(lxc_start, lxc); - -@@ -213,6 +214,57 @@ static int ensure_path(char **confpath, const char *path) - return 0; - } - -+static int set_start_extral_configs(const char *lxcpath, const char *name, struct lxc_container *c) -+{ -+#define START_GENERATE_CONFIG "start_generate_config.json" -+ char fpath[PATH_MAX] = {0}; -+ parser_error jerr = NULL; -+ int ret = -1; -+ container_start_generate_config *start_conf = NULL; -+ struct lxc_conf *lconf = c->lxc_conf; -+ size_t i = 0; -+ -+ if (sprintf(fpath, "%s/%s/%s", lxcpath, name, START_GENERATE_CONFIG) < 0) { -+ ERROR("Sprintf config path failed"); -+ return -1; -+ } -+ if (!file_exists(fpath)) { -+ return 0; -+ } -+ start_conf = container_start_generate_config_parse_file(fpath, NULL, &jerr); -+ if (start_conf == NULL) { -+ ERROR("Parse start generate config file: %s failed", fpath); -+ goto out; -+ } -+ if (start_conf->uid != 0) { -+ lconf->init_uid = start_conf->uid; -+ } -+ if (start_conf->gid != 0) { -+ lconf->init_gid = start_conf->gid; -+ } -+ if (start_conf->additional_gids != NULL && start_conf->additional_gids_len > 0) { -+ gid_t *tmp; -+ tmp = realloc(lconf->init_groups, (lconf->init_groups_len + start_conf->additional_gids_len) * sizeof(gid_t)); -+ if (tmp == NULL) { -+ ERROR("Out of memory"); -+ goto out; -+ } -+ lconf->init_groups = tmp; -+ for (; i < start_conf->additional_gids_len; i++) { -+ tmp[lconf->init_groups_len] = start_conf->additional_gids[i]; -+ lconf->init_groups_len++; -+ } -+ } -+ -+ ret = 0; -+out: -+ free(jerr); -+ if (start_conf != NULL) { -+ free_container_start_generate_config(start_conf); -+ } -+ return ret; -+} -+ - int main(int argc, char *argv[]) - { - const char *lxcpath; -@@ -358,6 +410,12 @@ int main(int argc, char *argv[]) - } - } - -+ /* isulad: load extral config for start container */ -+ if (set_start_extral_configs(lxcpath, my_args.name, c) != 0) { -+ ERROR("Failed to load extral config for container"); -+ goto out; -+ } -+ - /* isulad: fifo used to monitor state of monitor process */ - if (my_args.exit_monitor_fifo != NULL) { - c->exit_fifo = strdup(my_args.exit_monitor_fifo); --- -1.8.3.1 - diff --git a/0094-exec-load-uid-gid-and-groups.patch b/0094-exec-load-uid-gid-and-groups.patch deleted file mode 100644 index 89d3b82a87bafaea7ee178643daad80bb0af07ae..0000000000000000000000000000000000000000 --- a/0094-exec-load-uid-gid-and-groups.patch +++ /dev/null @@ -1,197 +0,0 @@ -From 64febbef5f589ae93aebb1845a78e4379d5c584b Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Tue, 7 May 2019 12:55:03 +0800 -Subject: [PATCH 094/140] exec load uid gid and groups - -exec load uid gid and groups - -Signed-off-by: liuhao -Signed-off-by: LiFeng ---- - src/lxc/lxccontainer.c | 69 +++++++++++++++++++++++++++++++++++++++++++++-- - src/lxc/tools/lxc_start.c | 58 --------------------------------------- - 2 files changed, 67 insertions(+), 60 deletions(-) - -diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index fa13e52..e0c4de3 100644 ---- a/src/lxc/lxccontainer.c -+++ b/src/lxc/lxccontainer.c -@@ -74,6 +74,7 @@ - #include "terminal.h" - #include "utils.h" - #include "version.h" -+#include "container_start_generate_config.h" - - /* major()/minor() */ - #ifdef MAJOR_IN_MKDEV -@@ -5252,6 +5253,65 @@ static bool do_lxcapi_add_terminal_fifo(struct lxc_container *c, const char *in_ - - WRAP_API_3(bool, lxcapi_add_terminal_fifo, const char *, const char *, const char *) - -+static int set_start_extral_configs(struct lxc_container *c) -+{ -+#define START_GENERATE_CONFIG "start_generate_config.json" -+ char fpath[PATH_MAX] = {0}; -+ parser_error jerr = NULL; -+ int ret = -1; -+ container_start_generate_config *start_conf = NULL; -+ struct lxc_conf *lconf = c->lxc_conf; -+ size_t i = 0; -+ -+ if (lconf == NULL) { -+ c->lxc_conf = malloc(sizeof(struct lxc_conf)); -+ lconf = c->lxc_conf; -+ if (lconf == NULL) { -+ fprintf(stderr, "Out of memory\n"); -+ return -1; -+ } -+ } -+ if (sprintf(fpath, "%s/%s/%s", c->config_path, c->name, START_GENERATE_CONFIG) < 0) { -+ fprintf(stderr, "Sprintf config path failed\n"); -+ return -1; -+ } -+ if (!file_exists(fpath)) { -+ return 0; -+ } -+ start_conf = container_start_generate_config_parse_file(fpath, NULL, &jerr); -+ if (start_conf == NULL) { -+ fprintf(stderr, "Parse start generate config file: %s failed", fpath); -+ goto out; -+ } -+ if (start_conf->uid != 0) { -+ lconf->init_uid = start_conf->uid; -+ } -+ if (start_conf->gid != 0) { -+ lconf->init_gid = start_conf->gid; -+ } -+ if (start_conf->additional_gids != NULL && start_conf->additional_gids_len > 0) { -+ gid_t *tmp; -+ tmp = realloc(lconf->init_groups, (lconf->init_groups_len + start_conf->additional_gids_len) * sizeof(gid_t)); -+ if (tmp == NULL) { -+ fprintf(stderr, "Out of memory"); -+ goto out; -+ } -+ lconf->init_groups = tmp; -+ for (; i < start_conf->additional_gids_len; i++) { -+ tmp[lconf->init_groups_len] = start_conf->additional_gids[i]; -+ lconf->init_groups_len++; -+ } -+ } -+ -+ ret = 0; -+out: -+ free(jerr); -+ if (start_conf != NULL) { -+ free_container_start_generate_config(start_conf); -+ } -+ return ret; -+} -+ - static struct lxc_container *do_lxc_container_new(const char *name, const char *configpath, bool load_config) - { - struct lxc_container *c; -@@ -5309,11 +5369,16 @@ static struct lxc_container *do_lxc_container_new(const char *name, const char * - goto err; - } - -- if (load_config) { -- if (file_exists(c->configfile) && !lxcapi_load_config(c, NULL)) { -+ if (load_config && file_exists(c->configfile)) { -+ if (!lxcapi_load_config(c, NULL)) { - fprintf(stderr, "Failed to load config for %s\n", name); - goto err; - } -+ /* isulad: load extral config for start container */ -+ if (set_start_extral_configs(c) != 0) { -+ fprintf(stderr, "Failed to load extral config for container: %s\n", name); -+ goto err; -+ } - } - - if (ongoing_create(c) == 2) { -diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c -index 4069204..af63f58 100644 ---- a/src/lxc/tools/lxc_start.c -+++ b/src/lxc/tools/lxc_start.c -@@ -50,7 +50,6 @@ - #include "confile.h" - #include "log.h" - #include "utils.h" --#include "container_start_generate_config.h" - - lxc_log_define(lxc_start, lxc); - -@@ -214,57 +213,6 @@ static int ensure_path(char **confpath, const char *path) - return 0; - } - --static int set_start_extral_configs(const char *lxcpath, const char *name, struct lxc_container *c) --{ --#define START_GENERATE_CONFIG "start_generate_config.json" -- char fpath[PATH_MAX] = {0}; -- parser_error jerr = NULL; -- int ret = -1; -- container_start_generate_config *start_conf = NULL; -- struct lxc_conf *lconf = c->lxc_conf; -- size_t i = 0; -- -- if (sprintf(fpath, "%s/%s/%s", lxcpath, name, START_GENERATE_CONFIG) < 0) { -- ERROR("Sprintf config path failed"); -- return -1; -- } -- if (!file_exists(fpath)) { -- return 0; -- } -- start_conf = container_start_generate_config_parse_file(fpath, NULL, &jerr); -- if (start_conf == NULL) { -- ERROR("Parse start generate config file: %s failed", fpath); -- goto out; -- } -- if (start_conf->uid != 0) { -- lconf->init_uid = start_conf->uid; -- } -- if (start_conf->gid != 0) { -- lconf->init_gid = start_conf->gid; -- } -- if (start_conf->additional_gids != NULL && start_conf->additional_gids_len > 0) { -- gid_t *tmp; -- tmp = realloc(lconf->init_groups, (lconf->init_groups_len + start_conf->additional_gids_len) * sizeof(gid_t)); -- if (tmp == NULL) { -- ERROR("Out of memory"); -- goto out; -- } -- lconf->init_groups = tmp; -- for (; i < start_conf->additional_gids_len; i++) { -- tmp[lconf->init_groups_len] = start_conf->additional_gids[i]; -- lconf->init_groups_len++; -- } -- } -- -- ret = 0; --out: -- free(jerr); -- if (start_conf != NULL) { -- free_container_start_generate_config(start_conf); -- } -- return ret; --} -- - int main(int argc, char *argv[]) - { - const char *lxcpath; -@@ -410,12 +358,6 @@ int main(int argc, char *argv[]) - } - } - -- /* isulad: load extral config for start container */ -- if (set_start_extral_configs(lxcpath, my_args.name, c) != 0) { -- ERROR("Failed to load extral config for container"); -- goto out; -- } -- - /* isulad: fifo used to monitor state of monitor process */ - if (my_args.exit_monitor_fifo != NULL) { - c->exit_fifo = strdup(my_args.exit_monitor_fifo); --- -1.8.3.1 - diff --git a/0096-close-inherited-fd-in-hook-process.patch b/0096-close-inherited-fd-in-hook-process.patch deleted file mode 100644 index 847beeddb8007a4fcf956ce2df47d2296d4d5abc..0000000000000000000000000000000000000000 --- a/0096-close-inherited-fd-in-hook-process.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 69556473f1e248be4ec79ccf069c65238ee9b8c1 Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Mon, 13 May 2019 16:45:50 +0800 -Subject: [PATCH 096/140] close inherited fd in hook process - -close inherited fd in hook process - -Signed-off-by: liuhao -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 0f227aa..6cf86a4 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4560,6 +4560,13 @@ static struct lxc_popen_FILE *lxc_popen_ocihook(char *commandpath, char **args, - - if (child_pid == 0) { - /* child */ -+ int inherit_fds[2] = { -+ pipe_msg[0], pipe_fds[1] -+ }; -+ if (lxc_check_inherited(NULL, true, inherit_fds, 2) != 0) { -+ SYSERROR("check inherited fd failed"); -+ exit(127); -+ } - - close(pipe_msg[1]); - if (pipe_msg[0] != STDIN_FILENO) --- -1.8.3.1 - diff --git a/0097-lxc-report-error-when-fork-exec-error-for-hooks.patch b/0097-lxc-report-error-when-fork-exec-error-for-hooks.patch deleted file mode 100644 index 360670a8549dc973fcecb72cc6079146b1076fcd..0000000000000000000000000000000000000000 --- a/0097-lxc-report-error-when-fork-exec-error-for-hooks.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 5afd4ebc85644ab8e1443ad80ba9bd311fe5f056 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Wed, 15 May 2019 00:53:49 -0400 -Subject: [PATCH 097/140] lxc: report error when fork/exec error for hooks - -Signed-off-by: tanyifeng -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 21 +++++++++------------ - 1 file changed, 9 insertions(+), 12 deletions(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 6cf86a4..341fdab 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4559,21 +4559,12 @@ static struct lxc_popen_FILE *lxc_popen_ocihook(char *commandpath, char **args, - goto on_error; - - if (child_pid == 0) { -- /* child */ -- int inherit_fds[2] = { -- pipe_msg[0], pipe_fds[1] -- }; -- if (lxc_check_inherited(NULL, true, inherit_fds, 2) != 0) { -- SYSERROR("check inherited fd failed"); -- exit(127); -- } -- - 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) { -- SYSERROR("Failed to remove FD_CLOEXEC from fd."); -+ fprintf(stderr, "Failed to remove FD_CLOEXEC from fd."); - exit(127); - } - } -@@ -4600,6 +4591,11 @@ static struct lxc_popen_FILE *lxc_popen_ocihook(char *commandpath, char **args, - if (ret < 0) - _exit(EXIT_FAILURE); - -+ if (lxc_check_inherited(NULL, true, NULL, 0) != 0) { -+ fprintf(stderr, "check inherited fd failed"); -+ exit(127); -+ } -+ - /* - * Unblock signals. - * This is the main/only reason -@@ -4615,6 +4611,7 @@ static struct lxc_popen_FILE *lxc_popen_ocihook(char *commandpath, char **args, - execvpe(commandpath, args, envs); - else - execvp(commandpath, args); -+ fprintf(stderr, "fork/exec %s: %s", commandpath, strerror(errno)); - exit(127); - } - -@@ -4764,8 +4761,8 @@ static int run_ocihook_buffer(struct oci_hook_conf *oconf, char *inmsg) - SYSERROR("Script exited with error."); - goto print_hook; - } else if (WIFEXITED(ret) && WEXITSTATUS(ret) != 0) { -- ERROR("Script exited with status %d. output:%s", WEXITSTATUS(ret), output); -- lxc_write_error_message(conf->errfd, "%s:%d: running %s hook caused \"error running hook: exit status %d, output:%s\".", -+ ERROR("Script exited with status %d. output: %s", WEXITSTATUS(ret), output); -+ lxc_write_error_message(conf->errfd, "%s:%d: running %s hook caused \"error running hook: exit status %d, output: %s\".", - __FILE__, __LINE__, - (conf->which >= NUM_LXC_HOOKS) ? "invalid type" : lxchook_names[conf->which], - WEXITSTATUS(ret), output); --- -1.8.3.1 - diff --git a/0098-lxc-make-dev-bind-mount-from-host-tmpfs-for-system-c.patch b/0098-lxc-make-dev-bind-mount-from-host-tmpfs-for-system-c.patch deleted file mode 100644 index 20d0de699e7d913303851b6b5062ed92d41b8c15..0000000000000000000000000000000000000000 --- a/0098-lxc-make-dev-bind-mount-from-host-tmpfs-for-system-c.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 5fd25f9a207a2c401e9bae990a96ec9b9056a2df Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Wed, 15 May 2019 12:42:08 +0800 -Subject: [PATCH 098/140] lxc: make /dev bind mount from host tmpfs for system - container - -reason:make /dev bind mount from host tmpfs for system container - -Signed-off-by: zhangsong -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 24 ++++++++++++++++-------- - 1 file changed, 16 insertions(+), 8 deletions(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 341fdab..3780966 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -1122,7 +1122,7 @@ on_error: - * error, log it but don't fail yet. - */ - static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs, -- const char *lxcpath) -+ const char *lxcpath, char *systemd) - { - int ret; - size_t clen; -@@ -1147,13 +1147,21 @@ static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs, - goto reset_umask; - } - -- ret = safe_mount("none", path, "tmpfs", 0, "size=500000,mode=755", -+ if (systemd != NULL && !strcmp(systemd, "true")) { -+ ret = mount(path, path, "", MS_BIND, NULL); -+ if (ret < 0) { -+ SYSERROR("Failed to bind mount path \"%s\"", path); -+ goto reset_umask; -+ } -+ } else { -+ ret = safe_mount("none", path, "tmpfs", 0, "size=500000,mode=755", - rootfs->path ? rootfs->mount : NULL); -- if (ret < 0) { -- SYSERROR("Failed to mount tmpfs on \"%s\"", path); -- goto reset_umask; -- } -- TRACE("Mounted tmpfs on \"%s\"", path); -+ if (ret < 0) { -+ SYSERROR("Failed to mount tmpfs on \"%s\"", path); -+ goto reset_umask; -+ } -+ TRACE("Mounted tmpfs on \"%s\"", path); -+ } - - ret = snprintf(path, clen, "%s/dev/pts", rootfs->path ? rootfs->mount : ""); - if (ret < 0 || (size_t)ret >= clen) { -@@ -4130,7 +4138,7 @@ int lxc_setup(struct lxc_handler *handler) - } - - if (lxc_conf->autodev > 0) { -- ret = mount_autodev(name, &lxc_conf->rootfs, lxcpath); -+ ret = mount_autodev(name, &lxc_conf->rootfs, lxcpath, lxc_conf->systemd); - if (ret < 0) { - ERROR("Failed to mount \"/dev\""); - goto on_error; --- -1.8.3.1 - diff --git a/0099-terminal-do-not-close-the-master-fd-of-pty.patch b/0099-terminal-do-not-close-the-master-fd-of-pty.patch deleted file mode 100644 index a2e05f37e02d245929d96ad48daf951d2014eb63..0000000000000000000000000000000000000000 --- a/0099-terminal-do-not-close-the-master-fd-of-pty.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 3d4a2fd9e5db67d6771ebd3268b05d7e461d3c74 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Tue, 21 May 2019 04:53:16 -0400 -Subject: [PATCH 099/140] terminal: do not close the master fd of pty - -Signed-off-by: LiFeng ---- - src/lxc/terminal.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index dfce92e..88653b4 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -595,6 +595,10 @@ int lxc_terminal_io_cb(int fd, uint32_t events, void *data, - if (w_log < 0) - TRACE("Failed to write %d bytes to terminal log", r); - } -+ /* notes: do not close the master fd due to if we close the fd, the process may -+ * recive SIGHUP and the exit code will be 129 (128 + 1) -+ */ -+ return LXC_MAINLOOP_CLOSE; - } else if (fd == terminal->peer) { - if (terminal->tty_state) { - lxc_terminal_signal_fini(terminal->tty_state); --- -1.8.3.1 - diff --git a/0100-start-add-check-save-pid-info-file.patch b/0100-start-add-check-save-pid-info-file.patch deleted file mode 100644 index 9aa93bc2330e0c33d480888dd9a866c804e5c29d..0000000000000000000000000000000000000000 --- a/0100-start-add-check-save-pid-info-file.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 33221d0ca431710cc1f83502d4223f1848c88ae9 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Wed, 22 May 2019 23:00:17 -0400 -Subject: [PATCH 100/140] start: add check save pid info file - -Signed-off-by: LiFeng ---- - src/lxc/start.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++-------- - src/lxc/utils.c | 2 +- - src/lxc/utils.h | 1 + - 3 files changed, 64 insertions(+), 11 deletions(-) - -diff --git a/src/lxc/start.c b/src/lxc/start.c -index 3657d4e..4541793 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -1850,14 +1850,10 @@ static inline int do_share_ns(void *arg) - return 0; - } - --/* isuald: save pid/ppid info */ --static int lxc_save_container_info(char *filename, pid_t pid) -+static int lxc_write_container_info(char *filename, pid_t pid, pid_t p_pid, unsigned long long start_at, unsigned long long p_start_at) - { - FILE *pid_fp = NULL; - int ret = 0; -- pid_t p_pid = 0; -- unsigned long long start_at = 0; -- unsigned long long p_start_at = 0; - - pid_fp = fopen(filename, "w"); - if (pid_fp == NULL) { -@@ -1866,11 +1862,6 @@ static int lxc_save_container_info(char *filename, pid_t pid) - goto out; - } - -- start_at = lxc_get_process_startat(pid); -- -- p_pid = getpid(); -- p_start_at = lxc_get_process_startat(p_pid); -- - if (fprintf(pid_fp, "%d %llu %d %llu\n", pid, start_at, p_pid, p_start_at) < 0) { - SYSERROR("Failed to write '%s'", filename); - ret = -1; -@@ -1883,6 +1874,67 @@ out: - return ret; - } - -+static int lxc_check_container_info(char *filename, pid_t pid, pid_t p_pid, unsigned long long start_at, unsigned long long p_start_at) -+{ -+ int ret = 0; -+ int num; -+ char sbuf[1024] = {0}; /* bufs for stat */ -+ int saved_pid; /* process id */ -+ int saved_ppid; /* pid of parent process */ -+ unsigned long long saved_start_time; /* start time of process -- seconds since 1-1-70 */ -+ unsigned long long saved_pstart_time; /* start time of parent process -- seconds since 1-1-70 */ -+ -+ if ((lxc_file2str(filename, sbuf, sizeof(sbuf))) == -1) { -+ SYSERROR("Failed to read pidfile %s", filename); -+ ret = -1; -+ goto out; -+ } -+ -+ num = sscanf(sbuf, "%d %Lu %d %Lu", &saved_pid, &saved_start_time, &saved_ppid, &saved_pstart_time); -+ if (num < 0) { -+ SYSERROR("Call sscanf error"); -+ ret = -1; -+ goto out; -+ } -+ -+ if (pid != saved_pid || p_pid != saved_ppid -+ || start_at != saved_start_time || p_start_at != saved_pstart_time) { -+ ERROR("Check container info failed"); -+ ret = -1; -+ goto out; -+ } -+ -+out: -+ return ret; -+} -+ -+ -+/* isuald: save pid/ppid info */ -+static int lxc_save_container_info(char *filename, pid_t pid) -+{ -+ int ret = 0; -+ pid_t p_pid = 0; -+ unsigned long long start_at = 0; -+ unsigned long long p_start_at = 0; -+ -+ start_at = lxc_get_process_startat(pid); -+ p_pid = getpid(); -+ p_start_at = lxc_get_process_startat(p_pid); -+ -+ ret = lxc_write_container_info(filename, pid, p_pid, start_at, p_start_at); -+ if (ret != 0) { -+ goto out; -+ } -+ -+ ret = lxc_check_container_info(filename, pid, p_pid, start_at, p_start_at); -+ if (ret != 0) { -+ goto out; -+ } -+ -+out: -+ return ret; -+} -+ - /* lxc_spawn() performs crucial setup tasks and clone()s the new process which - * exec()s the requested container binary. - * Note that lxc_spawn() runs in the parent namespaces. Any operations performed -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index fd6075f..dc0e6c5 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -1909,7 +1909,7 @@ set_env: - - - /* isulad: read file to buffer */ --static int lxc_file2str(const char *filename, char ret[], int cap) -+int lxc_file2str(const char *filename, char ret[], int cap) - { - int fd, num_read; - -diff --git a/src/lxc/utils.h b/src/lxc/utils.h -index 20407af..4410ff2 100644 ---- a/src/lxc/utils.h -+++ b/src/lxc/utils.h -@@ -323,5 +323,6 @@ extern void lxc_write_error_message(int errfd, const char *format, ...); - extern bool lxc_process_alive(pid_t pid, unsigned long long start_time); - - extern bool is_non_negative_num(const char *s); -+extern int lxc_file2str(const char *filename, char ret[], int cap); - - #endif /* __LXC_UTILS_H */ --- -1.8.3.1 - diff --git a/0101-lxc-fix-code-error.patch b/0101-lxc-fix-code-error.patch deleted file mode 100644 index 100a42bc61c12c182c69a650bbc32414cc85e9a2..0000000000000000000000000000000000000000 --- a/0101-lxc-fix-code-error.patch +++ /dev/null @@ -1,8983 +0,0 @@ -From f0f4a3317205ff6d0d9dcad3445b9e2947a082e1 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Mon, 3 Jun 2019 05:14:46 -0400 -Subject: [PATCH 101/140] lxc: fix code error - -Signed-off-by: LiFeng ---- - src/lxc/af_unix.c | 28 +- - src/lxc/cgroups/cgfsng.c | 263 ++++++------ - src/lxc/conf.c | 575 ++++++++++++++------------ - src/lxc/conf.h | 28 +- - src/lxc/confile.c | 897 ++++++++++++++++++++-------------------- - src/lxc/confile_utils.c | 42 +- - src/lxc/json/logger_json_file.c | 422 +++++++++---------- - src/lxc/json/read-file.c | 139 +++---- - src/lxc/log.c | 48 +-- - src/lxc/lxccontainer.c | 239 ++++++----- - src/lxc/mainloop.c | 8 +- - src/lxc/path.c | 584 +++++++++++++++----------- - src/lxc/path.h | 18 +- - src/lxc/start.c | 194 ++++----- - src/lxc/storage/block.c | 3 +- - src/lxc/terminal.c | 129 +++--- - src/lxc/utils.c | 159 ++++--- - src/lxc/utils.h | 11 +- - 18 files changed, 2019 insertions(+), 1768 deletions(-) - -diff --git a/src/lxc/af_unix.c b/src/lxc/af_unix.c -index 24500a8..4c45946 100644 ---- a/src/lxc/af_unix.c -+++ b/src/lxc/af_unix.c -@@ -47,7 +47,7 @@ - lxc_log_define(af_unix, lxc); - - static ssize_t lxc_abstract_unix_set_sockaddr(struct sockaddr_un *addr, -- const char *path) -+ const char *path) - { - size_t len; - -@@ -96,7 +96,7 @@ int lxc_abstract_unix_open(const char *path, int type, int flags) - } - - ret = bind(fd, (struct sockaddr *)&addr, -- offsetof(struct sockaddr_un, sun_path) + len + 1); -+ offsetof(struct sockaddr_un, sun_path) + len + 1); - if (ret < 0) { - int saved_errno = errno; - close(fd); -@@ -141,7 +141,7 @@ int lxc_abstract_unix_connect(const char *path) - } - - ret = connect(fd, (struct sockaddr *)&addr, -- offsetof(struct sockaddr_un, sun_path) + len + 1); -+ offsetof(struct sockaddr_un, sun_path) + len + 1); - if (ret < 0) { - int saved_errno = errno; - close(fd); -@@ -153,7 +153,7 @@ int lxc_abstract_unix_connect(const char *path) - } - - int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds, -- void *data, size_t size) -+ void *data, size_t size) - { - int ret; - struct msghdr msg; -@@ -196,14 +196,14 @@ int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds, - - /* isulad: add wait timeout Microseconds*/ - int lxc_abstract_unix_recv_fds_timeout(int fd, int *recvfds, int num_recvfds, -- void *data, size_t size, unsigned int timeout) -+ void *data, size_t size, unsigned int timeout) - { - int ret; - struct msghdr msg; - struct iovec iov; - struct cmsghdr *cmsg = NULL; - char buf[1] = {0}; -- char *cmsgbuf; -+ char *cmsgbuf = NULL; - size_t cmsgbufsize = CMSG_SPACE(num_recvfds * sizeof(int)); - struct timeval out; - -@@ -229,10 +229,10 @@ int lxc_abstract_unix_recv_fds_timeout(int fd, int *recvfds, int num_recvfds, - out.tv_sec = timeout / 1000000; - out.tv_usec = timeout % 1000000; - ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, -- (const void *)&out, sizeof(out)); -+ (const void *)&out, sizeof(out)); - if (ret < 0) { - ERROR("Failed to set %u timeout on containter " -- "state socket", timeout); -+ "state socket", timeout); - goto out; - } - } -@@ -245,7 +245,7 @@ int lxc_abstract_unix_recv_fds_timeout(int fd, int *recvfds, int num_recvfds, - - memset(recvfds, -1, num_recvfds * sizeof(int)); - if (cmsg && cmsg->cmsg_len == CMSG_LEN(num_recvfds * sizeof(int)) && -- cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) -+ cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) - memcpy(recvfds, CMSG_DATA(cmsg), num_recvfds * sizeof(int)); - - out: -@@ -254,7 +254,7 @@ out: - } - - int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds, -- void *data, size_t size) -+ void *data, size_t size) - { - return lxc_abstract_unix_recv_fds_timeout(fd, recvfds, num_recvfds, data, size, 0); - } -@@ -265,7 +265,7 @@ int lxc_abstract_unix_send_credential(int fd, void *data, size_t size) - struct iovec iov; - struct cmsghdr *cmsg; - struct ucred cred = { -- .pid = lxc_raw_getpid(), .uid = getuid(), .gid = getgid(), -+ .pid = lxc_raw_getpid(), .uid = getuid(), .gid = getgid(), - }; - char cmsgbuf[CMSG_SPACE(sizeof(cred))] = {0}; - char buf[1] = {0}; -@@ -317,11 +317,11 @@ int lxc_abstract_unix_rcv_credential(int fd, void *data, size_t size) - cmsg = CMSG_FIRSTHDR(&msg); - - if (cmsg && cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)) && -- cmsg->cmsg_level == SOL_SOCKET && -- cmsg->cmsg_type == SCM_CREDENTIALS) { -+ cmsg->cmsg_level == SOL_SOCKET && -+ cmsg->cmsg_type == SCM_CREDENTIALS) { - memcpy(&cred, CMSG_DATA(cmsg), sizeof(cred)); - if (cred.uid && -- (cred.uid != getuid() || cred.gid != getgid())) { -+ (cred.uid != getuid() || cred.gid != getgid())) { - INFO("Message denied for '%d/%d'", cred.uid, cred.gid); - errno = EACCES; - return -1; -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index eee7ed6..67c7a0e 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -149,7 +149,7 @@ static char *cg_legacy_must_prefix_named(char *entry) - * The last entry will always be NULL. - */ - static void must_append_controller(char **klist, char **nlist, char ***clist, -- char *entry) -+ char *entry) - { - int newentry; - char *copy; -@@ -190,7 +190,7 @@ struct hierarchy *get_hierarchy(struct cgroup_ops *ops, const char *controller) - if (!controller) { - /* This is the empty unified hierarchy. */ - if (ops->hierarchies[i]->controllers && -- !ops->hierarchies[i]->controllers[0]) -+ !ops->hierarchies[i]->controllers[0]) - return ops->hierarchies[i]; - - continue; -@@ -591,7 +591,7 @@ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname) - } - - clonechildrenpath = -- must_make_path(cgpath, "cgroup.clone_children", NULL); -+ must_make_path(cgpath, "cgroup.clone_children", NULL); - /* unified hierarchy doesn't have clone_children */ - if (!file_exists(clonechildrenpath)) { - free(clonechildrenpath); -@@ -722,7 +722,7 @@ static bool all_controllers_found(struct cgroup_ops *ops) - * be /sys/fs/cgroup/controller-list - */ - static char **cg_hybrid_get_controllers(char **klist, char **nlist, char *line, -- int type) -+ int type) - { - /* The fourth field is /sys/fs/cgroup/comma-delimited-controller-list - * for legacy hierarchies. -@@ -809,7 +809,7 @@ static char **cg_unified_get_controllers(const char *file) - } - - static struct hierarchy *add_hierarchy(struct hierarchy ***h, char **clist, char *mountpoint, -- char *container_base_path, int type) -+ char *container_base_path, int type) - { - struct hierarchy *new; - int newentry; -@@ -903,7 +903,7 @@ static bool controller_in_clist(char *cgline, char *c) - * @controller. - */ - static char *cg_hybrid_get_current_cgroup(char *basecginfo, char *controller, -- int type) -+ int type) - { - char *p = basecginfo; - -@@ -1023,7 +1023,7 @@ static void lxc_cgfsng_print_hierarchies(struct cgroup_ops *ops) - } - - static void lxc_cgfsng_print_basecg_debuginfo(char *basecginfo, char **klist, -- char **nlist) -+ char **nlist) - { - int k; - char **it; -@@ -1039,7 +1039,7 @@ static void lxc_cgfsng_print_basecg_debuginfo(char *basecginfo, char **klist, - } - - static int cgroup_rmdir(struct hierarchy **hierarchies, -- const char *container_cgroup) -+ const char *container_cgroup) - { - int i; - -@@ -1085,14 +1085,14 @@ static int cgroup_rmdir_wrapper(void *data) - ret = setresgid(nsgid, nsgid, nsgid); - if (ret < 0) { - SYSERROR("Failed to setresgid(%d, %d, %d)", (int)nsgid, -- (int)nsgid, (int)nsgid); -+ (int)nsgid, (int)nsgid); - return -1; - } - - ret = setresuid(nsuid, nsuid, nsuid); - if (ret < 0) { - SYSERROR("Failed to setresuid(%d, %d, %d)", (int)nsuid, -- (int)nsuid, (int)nsuid); -+ (int)nsuid, (int)nsuid); - return -1; - } - -@@ -1107,7 +1107,7 @@ static int cgroup_rmdir_wrapper(void *data) - - /* isulad: fix return bool instead of void*/ - __cgfsng_ops static bool cgfsng_payload_destroy(struct cgroup_ops *ops, -- struct lxc_handler *handler) -+ struct lxc_handler *handler) - { - int ret; - struct generic_userns_exec_data wrap; -@@ -1121,7 +1121,7 @@ __cgfsng_ops static bool cgfsng_payload_destroy(struct cgroup_ops *ops, - - if (handler->conf && !lxc_list_empty(&handler->conf->id_map)) - ret = userns_exec_1(handler->conf, cgroup_rmdir_wrapper, &wrap, -- "cgroup_rmdir_wrapper"); -+ "cgroup_rmdir_wrapper"); - else - ret = cgroup_rmdir(ops->hierarchies, ops->container_cgroup); - if (ret < 0) { -@@ -1186,10 +1186,10 @@ static bool cg_unified_create_cgroup(struct hierarchy *h, char *cgname, int errf - free(target); - if (ret < 0) { - SYSERROR("Could not enable \"%s\" controllers in the " -- "unified cgroup \"%s\"", add_controllers, cgroup); -+ "unified cgroup \"%s\"", add_controllers, cgroup); - lxc_write_error_message(errfd, "%s:%d: Could not enable \"%s\" controllers in the " -- "unified cgroup: \"%s\"", -- __FILE__, __LINE__, add_controllers, strerror(errno)); -+ "unified cgroup: \"%s\"", -+ __FILE__, __LINE__, add_controllers, strerror(errno)); - goto on_error; - } - } -@@ -1248,7 +1248,7 @@ static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname, int err - if (file_exists(h->container_full_path)) { // it must not already exist - ERROR("Cgroup path \"%s\" already exist.", h->container_full_path); - lxc_write_error_message(errfd, "%s:%d: Cgroup path \"%s\" already exist.", -- __FILE__, __LINE__, h->container_full_path); -+ __FILE__, __LINE__, h->container_full_path); - return false; - } - -@@ -1268,7 +1268,7 @@ static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname, int err - - /* isulad: create hierarchies path, if fail, return the error */ - __cgfsng_ops static bool cgfsng_payload_create(struct cgroup_ops *ops, -- struct lxc_handler *handler) -+ struct lxc_handler *handler) - { - int i; - char *container_cgroup = ops->container_cgroup; -@@ -1302,7 +1302,7 @@ __cgfsng_ops static bool cgfsng_payload_enter(struct cgroup_ops *ops, pid_t pid) - char *fullpath; - - fullpath = must_make_path(ops->hierarchies[i]->container_full_path, -- "cgroup.procs", NULL); -+ "cgroup.procs", NULL); - ret = lxc_write_to_file(fullpath, pidstr, len, false, 0666); - if (ret != 0) { - SYSERROR("Failed to enter cgroup \"%s\"", fullpath); -@@ -1316,7 +1316,7 @@ __cgfsng_ops static bool cgfsng_payload_enter(struct cgroup_ops *ops, pid_t pid) - } - - static int chowmod(char *path, uid_t chown_uid, gid_t chown_gid, -- mode_t chmod_mode) -+ mode_t chmod_mode) - { - int ret; - -@@ -1353,14 +1353,14 @@ static int chown_cgroup_wrapper(void *data) - ret = setresgid(nsgid, nsgid, nsgid); - if (ret < 0) { - SYSERROR("Failed to setresgid(%d, %d, %d)", -- (int)nsgid, (int)nsgid, (int)nsgid); -+ (int)nsgid, (int)nsgid, (int)nsgid); - return -1; - } - - ret = setresuid(nsuid, nsuid, nsuid); - if (ret < 0) { - SYSERROR("Failed to setresuid(%d, %d, %d)", -- (int)nsuid, (int)nsuid, (int)nsuid); -+ (int)nsuid, (int)nsuid, (int)nsuid); - return -1; - } - -@@ -1415,7 +1415,7 @@ static int chown_cgroup_wrapper(void *data) - } - - __cgfsng_ops static bool cgfsng_chown(struct cgroup_ops *ops, -- struct lxc_conf *conf) -+ struct lxc_conf *conf) - { - struct generic_userns_exec_data wrap; - -@@ -1428,7 +1428,7 @@ __cgfsng_ops static bool cgfsng_chown(struct cgroup_ops *ops, - wrap.conf = conf; - - if (userns_exec_1(conf, chown_cgroup_wrapper, &wrap, -- "chown_cgroup_wrapper") < 0) { -+ "chown_cgroup_wrapper") < 0) { - ERROR("Error requesting cgroup chown in new user namespace"); - return false; - } -@@ -1450,8 +1450,8 @@ static bool cg_mount_needs_subdirs(int type) - * control/the/cg/path. - */ - static int cg_legacy_mount_controllers(int type, struct hierarchy *h, -- char *controllerpath, char *cgpath, -- const char *container_cgroup) -+ char *controllerpath, char *cgpath, -+ const char *container_cgroup) - { - int ret, remount_flags; - char *sourcepath; -@@ -1461,16 +1461,16 @@ static int cg_legacy_mount_controllers(int type, struct hierarchy *h, - ret = mount(controllerpath, controllerpath, "cgroup", MS_BIND, NULL); - if (ret < 0) { - SYSERROR("Failed to bind mount \"%s\" onto \"%s\"", -- controllerpath, controllerpath); -+ controllerpath, controllerpath); - return -1; - } - - remount_flags = add_required_remount_flags(controllerpath, -- controllerpath, -- flags | MS_REMOUNT); -+ controllerpath, -+ flags | MS_REMOUNT); - ret = mount(controllerpath, controllerpath, "cgroup", -- remount_flags | MS_REMOUNT | MS_BIND | MS_RDONLY, -- NULL); -+ remount_flags | MS_REMOUNT | MS_BIND | MS_RDONLY, -+ NULL); - if (ret < 0) { - SYSERROR("Failed to remount \"%s\" ro", controllerpath); - return -1; -@@ -1480,7 +1480,7 @@ static int cg_legacy_mount_controllers(int type, struct hierarchy *h, - } - - sourcepath = must_make_path(h->mountpoint, h->container_base_path, -- container_cgroup, NULL); -+ container_cgroup, NULL); - if (type == LXC_AUTO_CGROUP_RO) - flags |= MS_RDONLY; - -@@ -1494,7 +1494,7 @@ static int cg_legacy_mount_controllers(int type, struct hierarchy *h, - - if (flags & MS_RDONLY) { - remount_flags = add_required_remount_flags(sourcepath, cgpath, -- flags | MS_REMOUNT); -+ flags | MS_REMOUNT); - ret = mount(sourcepath, cgpath, "cgroup", remount_flags, NULL); - if (ret < 0) { - SYSERROR("Failed to remount \"%s\" ro", cgpath); -@@ -1516,26 +1516,26 @@ static int cg_legacy_mount_controllers(int type, struct hierarchy *h, - * cgroups for the LXC_AUTO_CGROUP_FULL option. - */ - static int __cg_mount_direct(int type, struct hierarchy *h, -- const char *controllerpath) -+ const char *controllerpath) - { -- int ret; -- char *controllers = NULL; -- char *fstype = "cgroup2"; -- unsigned long flags = 0; -+ int ret; -+ char *controllers = NULL; -+ char *fstype = "cgroup2"; -+ unsigned long flags = 0; - -- flags |= MS_NOSUID; -- flags |= MS_NOEXEC; -- flags |= MS_NODEV; -- flags |= MS_RELATIME; -+ flags |= MS_NOSUID; -+ flags |= MS_NOEXEC; -+ flags |= MS_NODEV; -+ flags |= MS_RELATIME; - -- if (type == LXC_AUTO_CGROUP_RO || type == LXC_AUTO_CGROUP_FULL_RO) -- flags |= MS_RDONLY; -+ if (type == LXC_AUTO_CGROUP_RO || type == LXC_AUTO_CGROUP_FULL_RO) -+ flags |= MS_RDONLY; - -- if (h->version != CGROUP2_SUPER_MAGIC) { -- controllers = lxc_string_join(",", (const char **)h->controllers, false); -- if (!controllers) -- return -ENOMEM; -- fstype = "cgroup"; -+ if (h->version != CGROUP2_SUPER_MAGIC) { -+ controllers = lxc_string_join(",", (const char **)h->controllers, false); -+ if (!controllers) -+ return -ENOMEM; -+ fstype = "cgroup"; - } - - ret = mount("cgroup", controllerpath, fstype, flags, controllers); -@@ -1550,13 +1550,13 @@ static int __cg_mount_direct(int type, struct hierarchy *h, - } - - static inline int cg_mount_in_cgroup_namespace(int type, struct hierarchy *h, -- const char *controllerpath) -+ const char *controllerpath) - { - return __cg_mount_direct(type, h, controllerpath); - } - - static inline int cg_mount_cgroup_full(int type, struct hierarchy *h, -- const char *controllerpath) -+ const char *controllerpath) - { - if (type < LXC_AUTO_CGROUP_FULL_RO || type > LXC_AUTO_CGROUP_FULL_MIXED) - return 0; -@@ -1565,8 +1565,8 @@ static inline int cg_mount_cgroup_full(int type, struct hierarchy *h, - } - - __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, -- struct lxc_handler *handler, -- const char *root, int type) -+ struct lxc_handler *handler, -+ const char *root, int type) - { - int i, ret; - char *tmpfspath = NULL; -@@ -1583,7 +1583,7 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, - wants_force_mount = true; - } - -- if (!wants_force_mount){ -+ if (!wants_force_mount) { - if (!lxc_list_empty(&handler->conf->keepcaps)) - wants_force_mount = !in_caplist(CAP_SYS_ADMIN, &handler->conf->keepcaps); - else -@@ -1606,13 +1606,14 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, - goto on_error; - } - ret = safe_mount(NULL, tmpfspath, "tmpfs", -- MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME, -- "size=10240k,mode=755", root); -+ MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME, -+ "size=10240k,mode=755", root); - if (ret < 0) - goto on_error; - - for (i = 0; ops->hierarchies[i]; i++) { -- char *controllerpath, *path2; -+ char *controllerpath = NULL; -+ char *path2 = NULL; - struct hierarchy *h = ops->hierarchies[i]; - char *controller = strrchr(h->mountpoint, '/'); - -@@ -1676,7 +1677,7 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, - } - - ret = cg_legacy_mount_controllers(type, h, controllerpath, -- path2, ops->container_cgroup); -+ path2, ops->container_cgroup); - free(controllerpath); - free(path2); - if (ret < 0) -@@ -1685,7 +1686,7 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, - - // isulad: symlink subcgroup - if (merged) { -- char **mc; -+ char **mc = NULL; - for (mc = merged; *mc; mc++) { - char *token; - char *copy = must_copy_string(*mc); -@@ -1710,44 +1711,44 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, - // isulad: remount /sys/fs/cgroup to readonly - if (type == LXC_AUTO_CGROUP_FULL_RO || type == LXC_AUTO_CGROUP_RO) { - ret = mount(tmpfspath, tmpfspath, "bind", -- MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_RELATIME|MS_RDONLY|MS_BIND|MS_REMOUNT, NULL); -+ MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_RELATIME|MS_RDONLY|MS_BIND|MS_REMOUNT, NULL); - if (ret < 0) { - SYSERROR("Failed to remount /sys/fs/cgroup."); - goto on_error; - } - } - -- // isulad: remount /sys/fs/cgroup/systemd to readwrite for system container -- if (handler->conf->systemd != NULL && strcmp(handler->conf->systemd, "true") == 0) { -- // isulad: don't use the unified hierarchy for the systemd cgroup -- unifiedpath = must_make_path(root, "/sys/fs/cgroup/unified", NULL); -- if (dir_exists(unifiedpath)) { -- ret = umount2(unifiedpath, MNT_DETACH); -- if (ret < 0) { -- SYSERROR("Failed to umount /sys/fs/cgroup/unified."); -- goto on_error; -- } -- } -- -- systemdpath = must_make_path(root, "/sys/fs/cgroup/systemd", NULL); -- ret = mount(systemdpath, systemdpath, "bind", -- MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_RELATIME|MS_BIND|MS_REMOUNT, NULL); -- if (ret < 0) { -- SYSERROR("Failed to remount /sys/fs/cgroup/systemd."); -- goto on_error; -- } -- } -+ // isulad: remount /sys/fs/cgroup/systemd to readwrite for system container -+ if (handler->conf->systemd != NULL && strcmp(handler->conf->systemd, "true") == 0) { -+ // isulad: don't use the unified hierarchy for the systemd cgroup -+ unifiedpath = must_make_path(root, "/sys/fs/cgroup/unified", NULL); -+ if (dir_exists(unifiedpath)) { -+ ret = umount2(unifiedpath, MNT_DETACH); -+ if (ret < 0) { -+ SYSERROR("Failed to umount /sys/fs/cgroup/unified."); -+ goto on_error; -+ } -+ } -+ -+ systemdpath = must_make_path(root, "/sys/fs/cgroup/systemd", NULL); -+ ret = mount(systemdpath, systemdpath, "bind", -+ MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_RELATIME|MS_BIND|MS_REMOUNT, NULL); -+ if (ret < 0) { -+ SYSERROR("Failed to remount /sys/fs/cgroup/systemd."); -+ goto on_error; -+ } -+ } - - retval = true; - - on_error: - free(tmpfspath); -- if (systemdpath != NULL) { -- free(systemdpath); -- } -- if (unifiedpath != NULL) { -- free(unifiedpath); -- } -+ if (systemdpath != NULL) { -+ free(systemdpath); -+ } -+ if (unifiedpath != NULL) { -+ free(unifiedpath); -+ } - lxc_free_array((void **)merged, free); - return retval; - } -@@ -1767,7 +1768,7 @@ static int recursive_count_nrtasks(char *dirname) - struct stat mystat; - - if (!strcmp(direntp->d_name, ".") || -- !strcmp(direntp->d_name, "..")) -+ !strcmp(direntp->d_name, "..")) - continue; - - path = must_make_path(dirname, direntp->d_name, NULL); -@@ -1779,7 +1780,7 @@ static int recursive_count_nrtasks(char *dirname) - goto next; - - count += recursive_count_nrtasks(path); -- next: -+next: - free(path); - } - -@@ -1821,8 +1822,8 @@ __cgfsng_ops static bool cgfsng_escape(const struct cgroup_ops *ops) - char *fullpath; - - fullpath = must_make_path(ops->hierarchies[i]->mountpoint, -- ops->hierarchies[i]->container_base_path, -- "cgroup.procs", NULL); -+ ops->hierarchies[i]->container_base_path, -+ "cgroup.procs", NULL); - ret = lxc_write_to_file(fullpath, "0", 2, false, 0666); - if (ret != 0) { - SYSERROR("Failed to escape to cgroup \"%s\"", fullpath); -@@ -1885,7 +1886,7 @@ __cgfsng_ops static bool cgfsng_unfreeze(struct cgroup_ops *ops) - } - - __cgfsng_ops static const char *cgfsng_get_cgroup(struct cgroup_ops *ops, -- const char *controller, bool skip_mount) -+ const char *controller, bool skip_mount) - { - struct hierarchy *h; - -@@ -1905,8 +1906,8 @@ __cgfsng_ops static const char *cgfsng_get_cgroup(struct cgroup_ops *ops, - * which must be freed by the caller. - */ - static inline char *build_full_cgpath_from_monitorpath(struct hierarchy *h, -- const char *inpath, -- const char *filename) -+ const char *inpath, -+ const char *filename) - { - return must_make_path(h->mountpoint, inpath, filename, NULL); - } -@@ -1921,8 +1922,8 @@ static inline char *build_full_cgpath_from_monitorpath(struct hierarchy *h, - * cgroup for the attaching process. - */ - static int __cg_unified_attach(const struct hierarchy *h, const char *name, -- const char *lxcpath, const char *pidstr, -- size_t pidstr_len, const char *controller) -+ const char *lxcpath, const char *pidstr, -+ size_t pidstr_len, const char *controller) - { - int ret; - size_t len; -@@ -1952,7 +1953,7 @@ static int __cg_unified_attach(const struct hierarchy *h, const char *name, - do { - if (idx) - ret = snprintf(full_path, len + 1, "%s/lxc-%d", -- base_path, idx); -+ base_path, idx); - else - ret = snprintf(full_path, len + 1, "%s/lxc", base_path); - if (ret < 0 || (size_t)ret >= len + 1) -@@ -1987,7 +1988,7 @@ on_error: - } - - __cgfsng_ops static bool cgfsng_attach(struct cgroup_ops *ops, const char *name, -- const char *lxcpath, pid_t pid) -+ const char *lxcpath, pid_t pid) - { - int i, len, ret; - char pidstr[INTTYPE_TO_STRLEN(pid_t)]; -@@ -2003,7 +2004,7 @@ __cgfsng_ops static bool cgfsng_attach(struct cgroup_ops *ops, const char *name, - - if (h->version == CGROUP2_SUPER_MAGIC) { - ret = __cg_unified_attach(h, name, lxcpath, pidstr, len, -- h->controllers[0]); -+ h->controllers[0]); - if (ret < 0) - return false; - -@@ -2034,8 +2035,8 @@ __cgfsng_ops static bool cgfsng_attach(struct cgroup_ops *ops, const char *name, - * commands API for the cgroup path. - */ - __cgfsng_ops static int cgfsng_get(struct cgroup_ops *ops, const char *filename, -- char *value, size_t len, const char *name, -- const char *lxcpath) -+ char *value, size_t len, const char *name, -+ const char *lxcpath) - { - int ret = -1; - size_t controller_len; -@@ -2073,8 +2074,8 @@ __cgfsng_ops static int cgfsng_get(struct cgroup_ops *ops, const char *filename, - * commands API for the cgroup path. - */ - __cgfsng_ops static int cgfsng_set(struct cgroup_ops *ops, -- const char *filename, const char *value, -- const char *name, const char *lxcpath) -+ const char *filename, const char *value, -+ const char *name, const char *lxcpath) - { - int ret = -1; - size_t controller_len; -@@ -2189,7 +2190,7 @@ out: - * we created the cgroups. - */ - static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, -- const char *value) -+ const char *value) - { - size_t len; - char *fullpath, *p; -@@ -2228,8 +2229,8 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, - ret = lxc_write_to_file(fullpath, value, strlen(value), false, 0666); - if (ret) { - lxc_write_error_message(ops->errfd, -- "%s:%d: setting cgroup config for ready process caused \"failed to write %s to %s: %s\".", -- __FILE__, __LINE__, value, fullpath, strerror(errno)); -+ "%s:%d: setting cgroup config for ready process caused \"failed to write %s to %s: %s\".", -+ __FILE__, __LINE__, value, fullpath, strerror(errno)); - } - free(fullpath); - return ret; -@@ -2239,15 +2240,16 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, - * we created the cgroups. - */ - static int cg_legacy_get_data(struct cgroup_ops *ops, const char *filename, -- char *value, size_t len) -+ char *value, size_t len) - { -- char *fullpath, *p; -- struct hierarchy *h; -+ char *fullpath = NULL; -+ char *p = NULL; -+ struct hierarchy *h = NULL; - int ret = 0; - char *controller = NULL; - - len = strlen(filename); -- controller = alloca(len + 1); -+ controller = calloc(1, len + 1); - (void)strlcpy(controller, filename, len + 1); - - p = strchr(controller, '.'); -@@ -2262,23 +2264,25 @@ static int cg_legacy_get_data(struct cgroup_ops *ops, const char *filename, - "driver or not enabled on the cgroup hierarchy", - controller); - errno = ENOENT; -+ free(controller); - return -ENOENT; - } - - fullpath = must_make_path(h->container_full_path, filename, NULL); - ret = lxc_read_from_file(fullpath, value, len); - free(fullpath); -+ free(controller); - return ret; - } - - static bool __cg_legacy_setup_limits(struct cgroup_ops *ops, -- struct lxc_list *cgroup_settings, -- bool do_devices) -+ struct lxc_list *cgroup_settings, -+ bool do_devices) - { - struct lxc_list *iterator, *next, *sorted_cgroup_settings; - struct lxc_cgroup *cg; - bool ret = false; -- char value[21]; -+ char value[21 + 1] = { 0 }; - long long int readvalue, setvalue; - - if (lxc_list_empty(cgroup_settings)) -@@ -2318,7 +2322,7 @@ static bool __cg_legacy_setup_limits(struct cgroup_ops *ops, - - // isulad: check cpu shares - if (strcmp(cg->subsystem, "cpu.shares") == 0) { -- if (cg_legacy_get_data(ops, cg->subsystem, value, sizeof(value)) < 0) { -+ if (cg_legacy_get_data(ops, cg->subsystem, value, sizeof(value) - 1) < 0) { - SYSERROR("Error get %s", cg->subsystem); - goto out; - } -@@ -2334,14 +2338,14 @@ static bool __cg_legacy_setup_limits(struct cgroup_ops *ops, - if (setvalue > readvalue) { - ERROR("The maximum allowed cpu-shares is %s", value); - lxc_write_error_message(ops->errfd, -- "%s:%d: setting cgroup config for ready process caused \"The maximum allowed cpu-shares is %s\".", -- __FILE__, __LINE__, value); -+ "%s:%d: setting cgroup config for ready process caused \"The maximum allowed cpu-shares is %s\".", -+ __FILE__, __LINE__, value); - goto out; - } else if (setvalue < readvalue) { - ERROR("The minimum allowed cpu-shares is %s", value); - lxc_write_error_message(ops->errfd, -- "%s:%d: setting cgroup config for ready process caused \"The minimum allowed cpu-shares is %s\".", -- __FILE__, __LINE__, value); -+ "%s:%d: setting cgroup config for ready process caused \"The minimum allowed cpu-shares is %s\".", -+ __FILE__, __LINE__, value); - goto out; - } - } -@@ -2359,7 +2363,7 @@ out: - } - - static bool __cg_unified_setup_limits(struct cgroup_ops *ops, -- struct lxc_list *cgroup_settings) -+ struct lxc_list *cgroup_settings) - { - struct lxc_list *iterator; - struct hierarchy *h = ops->unified; -@@ -2380,7 +2384,7 @@ static bool __cg_unified_setup_limits(struct cgroup_ops *ops, - free(fullpath); - if (ret < 0) { - SYSERROR("Failed to set \"%s\" to \"%s\"", -- cg->subsystem, cg->value); -+ cg->subsystem, cg->value); - return false; - } - TRACE("Set \"%s\" to \"%s\"", cg->subsystem, cg->value); -@@ -2391,8 +2395,8 @@ static bool __cg_unified_setup_limits(struct cgroup_ops *ops, - } - - __cgfsng_ops static bool cgfsng_setup_limits(struct cgroup_ops *ops, -- struct lxc_conf *conf, -- bool do_devices) -+ struct lxc_conf *conf, -+ bool do_devices) - { - bool bret; - -@@ -2404,7 +2408,7 @@ __cgfsng_ops static bool cgfsng_setup_limits(struct cgroup_ops *ops, - } - - static bool cgroup_use_wants_controllers(const struct cgroup_ops *ops, -- char **controllers) -+ char **controllers) - { - char **cur_ctrl, **cur_use; - -@@ -2537,8 +2541,8 @@ static bool cg_hybrid_init(struct cgroup_ops *ops) - char *cgv2_ctrl_path; - - cgv2_ctrl_path = must_make_path(mountpoint, base_cgroup, -- "cgroup.controllers", -- NULL); -+ "cgroup.controllers", -+ NULL); - - controller_list = cg_unified_get_controllers(cgv2_ctrl_path); - free(cgv2_ctrl_path); -@@ -2559,7 +2563,7 @@ static bool cg_hybrid_init(struct cgroup_ops *ops) - - continue; - -- next: -+next: - free_string_list(controller_list); - free(mountpoint); - free(base_cgroup); -@@ -2658,7 +2662,7 @@ static int cg_unified_init(struct cgroup_ops *ops) - */ - mountpoint = must_copy_string("/sys/fs/cgroup"); - subtree_path = must_make_path(mountpoint, base_cgroup, -- "cgroup.subtree_control", NULL); -+ "cgroup.subtree_control", NULL); - delegatable = cg_unified_get_controllers(subtree_path); - free(subtree_path); - if (!delegatable) -@@ -2710,8 +2714,9 @@ static bool cg_init(struct cgroup_ops *ops) - - __cgfsng_ops static bool cgfsng_data_init(struct cgroup_ops *ops, struct lxc_handler *handler) - { -- const char *cgroup_pattern; -- char *container_cgroup, *tmp; -+ const char *cgroup_pattern = NULL; -+ char *container_cgroup = NULL; -+ char *tmp = NULL; - struct lxc_conf *conf = NULL; - size_t len; - -@@ -2730,7 +2735,9 @@ __cgfsng_ops static bool cgfsng_data_init(struct cgroup_ops *ops, struct lxc_han - /* isulad: init ops->container_cgroup here instead of in cgfsng_payload_create*/ - if (conf) { - if (conf->cgroup_meta.dir) -- tmp = lxc_string_join("/", (const char *[]){conf->cgroup_meta.dir, handler->name, NULL}, false); -+ tmp = lxc_string_join("/", (const char *[]) { -+ conf->cgroup_meta.dir, handler->name, NULL -+ }, false); - else - tmp = lxc_string_replace("%n", handler->name, ops->cgroup_pattern); - if (!tmp) { -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 3780966..ec1667d 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -351,8 +351,8 @@ static int run_buffer(char *buffer) - } - - int run_script_argv(const char *name, unsigned int hook_version, -- const char *section, const char *script, -- const char *hookname, char **argv) -+ const char *section, const char *script, -+ const char *hookname, char **argv) - { - int buf_pos, i, ret; - char *buffer; -@@ -407,7 +407,7 @@ int run_script_argv(const char *name, unsigned int hook_version, - ret = setenv("LXC_HOOK_TYPE", hookname, 1); - if (ret < 0) { - SYSERROR("Failed to set environment variable: " -- "LXC_HOOK_TYPE=%s", hookname); -+ "LXC_HOOK_TYPE=%s", hookname); - goto on_error; - } - TRACE("Set environment variable: LXC_HOOK_TYPE=%s", hookname); -@@ -415,7 +415,7 @@ int run_script_argv(const char *name, unsigned int hook_version, - ret = setenv("LXC_HOOK_SECTION", section, 1); - if (ret < 0) { - SYSERROR("Failed to set environment variable: " -- "LXC_HOOK_SECTION=%s", section); -+ "LXC_HOOK_SECTION=%s", section); - goto on_error; - } - TRACE("Set environment variable: LXC_HOOK_SECTION=%s", section); -@@ -429,7 +429,7 @@ int run_script_argv(const char *name, unsigned int hook_version, - ret = setenv("LXC_NET_TYPE", argv[0], 1); - if (ret < 0) { - SYSERROR("Failed to set environment variable: " -- "LXC_NET_TYPE=%s", argv[0]); -+ "LXC_NET_TYPE=%s", argv[0]); - goto on_error; - } - TRACE("Set environment variable: LXC_NET_TYPE=%s", argv[0]); -@@ -440,7 +440,7 @@ int run_script_argv(const char *name, unsigned int hook_version, - ret = setenv("LXC_NET_PARENT", parent, 1); - if (ret < 0) { - SYSERROR("Failed to set environment " -- "variable: LXC_NET_PARENT=%s", parent); -+ "variable: LXC_NET_PARENT=%s", parent); - goto on_error; - } - TRACE("Set environment variable: LXC_NET_PARENT=%s", parent); -@@ -448,7 +448,7 @@ int run_script_argv(const char *name, unsigned int hook_version, - ret = setenv("LXC_NET_PARENT", parent, 1); - if (ret < 0) { - SYSERROR("Failed to set environment " -- "variable: LXC_NET_PARENT=%s", parent); -+ "variable: LXC_NET_PARENT=%s", parent); - goto on_error; - } - TRACE("Set environment variable: LXC_NET_PARENT=%s", parent); -@@ -458,7 +458,7 @@ int run_script_argv(const char *name, unsigned int hook_version, - ret = setenv("LXC_NET_PEER", peer, 1); - if (ret < 0) { - SYSERROR("Failed to set environment " -- "variable: LXC_NET_PEER=%s", peer); -+ "variable: LXC_NET_PEER=%s", peer); - goto on_error; - } - TRACE("Set environment variable: LXC_NET_PEER=%s", peer); -@@ -466,7 +466,7 @@ int run_script_argv(const char *name, unsigned int hook_version, - ret = setenv("LXC_NET_PARENT", parent, 1); - if (ret < 0) { - SYSERROR("Failed to set environment " -- "variable: LXC_NET_PARENT=%s", parent); -+ "variable: LXC_NET_PARENT=%s", parent); - goto on_error; - } - TRACE("Set environment variable: LXC_NET_PARENT=%s", parent); -@@ -600,7 +600,7 @@ int pin_rootfs(const char *rootfs) - * honored. - */ - unsigned long add_required_remount_flags(const char *s, const char *d, -- unsigned long flags) -+ unsigned long flags) - { - #ifdef HAVE_STATVFS - int ret; -@@ -728,10 +728,10 @@ static int lxc_mount_auto_mounts(struct lxc_conf *conf, int flags, struct lxc_ha - } - - mflags = add_required_remount_flags(source, destination, -- default_mounts[i].flags); -+ default_mounts[i].flags); - r = safe_mount(source, destination, default_mounts[i].fstype, -- mflags, default_mounts[i].options, -- conf->rootfs.path ? conf->rootfs.mount : NULL); -+ mflags, default_mounts[i].options, -+ conf->rootfs.path ? conf->rootfs.mount : NULL); - saved_errno = errno; - if (r < 0 && errno == ENOENT) { - INFO("Mount source for \"%s\" on \"%s\" does " -@@ -781,9 +781,9 @@ static int lxc_mount_auto_mounts(struct lxc_conf *conf, int flags, struct lxc_ha - cg_flags |= LXC_AUTO_CGROUP_FORCE; - - if (!handler->cgroup_ops->mount(handler->cgroup_ops, -- handler, -- conf->rootfs.path ? conf->rootfs.mount : "", -- cg_flags)) { -+ handler, -+ conf->rootfs.path ? conf->rootfs.mount : "", -+ cg_flags)) { - SYSERROR("Failed to mount \"/sys/fs/cgroup\""); - return -1; - } -@@ -832,7 +832,7 @@ static int lxc_setup_dev_symlinks(const struct lxc_rootfs *rootfs) - const struct dev_symlinks *d = &dev_symlinks[i]; - - ret = snprintf(path, sizeof(path), "%s/dev/%s", -- rootfs->path ? rootfs->mount : "", d->name); -+ rootfs->path ? rootfs->mount : "", d->name); - if (ret < 0 || ret >= PATH_MAX) - return -1; - -@@ -901,7 +901,7 @@ static int lxc_setup_ttys(struct lxc_conf *conf) - if (ttydir) { - /* create dev/lxc/tty%d" */ - ret = snprintf(lxcpath, sizeof(lxcpath), -- "/dev/%s/tty%d", ttydir, i + 1); -+ "/dev/%s/tty%d", ttydir, i + 1); - if (ret < 0 || (size_t)ret >= sizeof(lxcpath)) - return -1; - -@@ -920,14 +920,14 @@ static int lxc_setup_ttys(struct lxc_conf *conf) - ret = mount(tty->name, lxcpath, "none", MS_BIND, 0); - if (ret < 0) { - SYSWARN("Failed to bind mount \"%s\" onto \"%s\"", -- tty->name, lxcpath); -+ tty->name, lxcpath); - continue; - } - DEBUG("Bind mounted \"%s\" onto \"%s\"", tty->name, - lxcpath); - - ret = snprintf(lxcpath, sizeof(lxcpath), "%s/tty%d", -- ttydir, i + 1); -+ ttydir, i + 1); - if (ret < 0 || (size_t)ret >= sizeof(lxcpath)) - return -1; - -@@ -1122,7 +1122,7 @@ on_error: - * error, log it but don't fail yet. - */ - static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs, -- const char *lxcpath, char *systemd) -+ const char *lxcpath, const char *systemd) - { - int ret; - size_t clen; -@@ -1147,21 +1147,21 @@ static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs, - goto reset_umask; - } - -- if (systemd != NULL && !strcmp(systemd, "true")) { -- ret = mount(path, path, "", MS_BIND, NULL); -- if (ret < 0) { -- SYSERROR("Failed to bind mount path \"%s\"", path); -- goto reset_umask; -- } -- } else { -- ret = safe_mount("none", path, "tmpfs", 0, "size=500000,mode=755", -- rootfs->path ? rootfs->mount : NULL); -- if (ret < 0) { -- SYSERROR("Failed to mount tmpfs on \"%s\"", path); -- goto reset_umask; -- } -- TRACE("Mounted tmpfs on \"%s\"", path); -- } -+ if (systemd != NULL && !strcmp(systemd, "true")) { -+ ret = mount(path, path, "", MS_BIND, NULL); -+ if (ret < 0) { -+ SYSERROR("Failed to bind mount path \"%s\"", path); -+ goto reset_umask; -+ } -+ } else { -+ ret = safe_mount("none", path, "tmpfs", 0, "size=500000,mode=755", -+ rootfs->path ? rootfs->mount : NULL); -+ if (ret < 0) { -+ SYSERROR("Failed to mount tmpfs on \"%s\"", path); -+ goto reset_umask; -+ } -+ TRACE("Mounted tmpfs on \"%s\"", path); -+ } - - ret = snprintf(path, clen, "%s/dev/pts", rootfs->path ? rootfs->mount : ""); - if (ret < 0 || (size_t)ret >= clen) { -@@ -1220,7 +1220,7 @@ static int lxc_fill_autodev(const struct lxc_rootfs *rootfs) - int use_mknod = LXC_DEVNODE_MKNOD; - - ret = snprintf(path, PATH_MAX, "%s/dev", -- rootfs->path ? rootfs->mount : ""); -+ rootfs->path ? rootfs->mount : ""); - if (ret < 0 || ret >= PATH_MAX) - return -1; - -@@ -1236,7 +1236,7 @@ static int lxc_fill_autodev(const struct lxc_rootfs *rootfs) - const struct lxc_device_node *device = &lxc_devices[i]; - - ret = snprintf(path, PATH_MAX, "%s/dev/%s", -- rootfs->path ? rootfs->mount : "", device->name); -+ rootfs->path ? rootfs->mount : "", device->name); - if (ret < 0 || ret >= PATH_MAX) - return -1; - -@@ -1294,10 +1294,10 @@ static int lxc_fill_autodev(const struct lxc_rootfs *rootfs) - return -1; - - ret = safe_mount(hostpath, path, 0, MS_BIND, NULL, -- rootfs->path ? rootfs->mount : NULL); -+ rootfs->path ? rootfs->mount : NULL); - if (ret < 0) { - SYSERROR("Failed to bind mount host device node \"%s\" " -- "onto \"%s\"", hostpath, path); -+ "onto \"%s\"", hostpath, path); - return -1; - } - DEBUG("Bind mounted host device node \"%s\" onto \"%s\"", -@@ -1350,7 +1350,9 @@ static int rootfs_parent_mount_private(char *rootfs) - } - - while (getline(&line, &len, f) != -1) { -- char *target, *opts, *tmptarget; -+ char *target = NULL; -+ char *opts = NULL; -+ char *tmptarget = NULL; - target = get_field(line, 4); - if (!target) - continue; -@@ -1401,10 +1403,10 @@ static int rootfs_parent_mount_private(char *rootfs) - static int lxc_mount_rootfs(struct lxc_conf *conf) - { - int ret; -- struct lxc_storage *bdev; -+ struct lxc_storage *bdev = NULL; - struct lxc_rootfs *rootfs = &conf->rootfs; - unsigned long flags, mntflags, pflags; -- char *mntdata; -+ char *mntdata = NULL; - - if (!rootfs->path) { - ret = mount("", "/", NULL, MS_SLAVE | MS_REC, 0); -@@ -1430,7 +1432,7 @@ static int lxc_mount_rootfs(struct lxc_conf *conf) - ret = access(rootfs->mount, F_OK); - if (ret != 0) { - SYSERROR("Failed to access to \"%s\". Check it is present", -- rootfs->mount); -+ rootfs->mount); - return -1; - } - -@@ -1540,7 +1542,7 @@ static bool remount_readwrite(const char *path) - if (ret < 0) - goto on_error; - ret = mount(path, path, "", MS_BIND | MS_REMOUNT | MS_REC | \ -- MS_NOEXEC | MS_NOSUID | MS_NODEV, ""); -+ MS_NOEXEC | MS_NOSUID | MS_NODEV, ""); - if (ret < 0) - goto on_error; - } else if (errno == EBUSY) { -@@ -1601,7 +1603,7 @@ static bool remount_readonly(const char *path) - if (ret < 0) - goto on_error; - ret = mount(path, path, "", MS_BIND | MS_REMOUNT | MS_RDONLY | MS_REC | \ -- MS_NOEXEC | MS_NOSUID | MS_NODEV, ""); -+ MS_NOEXEC | MS_NOSUID | MS_NODEV, ""); - if (ret < 0) - goto on_error; - } else if (errno == EBUSY) { -@@ -1626,8 +1628,8 @@ static int setup_rootfs_maskedpaths(struct lxc_list *maskedpaths) - struct lxc_list *it; - - lxc_list_for_each(it, maskedpaths) { -- if (!mask_path((char *)it->elem)) -- return -1; -+ if (!mask_path((char *)it->elem)) -+ return -1; - } - - return 0; -@@ -1638,8 +1640,8 @@ static int setup_rootfs_ropaths(struct lxc_list *ropaths) - struct lxc_list *it; - - lxc_list_for_each(it, ropaths) { -- if (!remount_readonly((char *)it->elem)) -- return -1; -+ if (!remount_readonly((char *)it->elem)) -+ return -1; - } - - return 0; -@@ -1873,8 +1875,8 @@ static int lxc_setup_rootfs_switch_root(const struct lxc_rootfs *rootfs) - } - - static const struct id_map *find_mapped_nsid_entry(struct lxc_conf *conf, -- unsigned id, -- enum idtype idtype) -+ unsigned id, -+ enum idtype idtype) - { - struct lxc_list *it; - struct id_map *map; -@@ -1918,7 +1920,7 @@ static int lxc_setup_devpts(struct lxc_conf *conf) - } - - ret = snprintf(devpts_mntopts, sizeof(devpts_mntopts), "%s,max=%zu", -- default_devpts_mntopts, conf->pty_max); -+ default_devpts_mntopts, conf->pty_max); - if (ret < 0 || (size_t)ret >= sizeof(devpts_mntopts)) - return -1; - -@@ -2031,7 +2033,7 @@ static int setup_personality(int persona) - } - - static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs, -- const struct lxc_terminal *console) -+ const struct lxc_terminal *console) - { - int ret; - char path[PATH_MAX]; -@@ -2069,7 +2071,7 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs, - ret = fchmod(console->slave, S_IXUSR | S_IXGRP); - if (ret < 0) { - SYSERROR("Failed to set mode \"0%o\" to \"%s\"", -- S_IXUSR | S_IXGRP, console->name); -+ S_IXUSR | S_IXGRP, console->name); - return -errno; - } - -@@ -2084,8 +2086,8 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs, - } - - static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs, -- const struct lxc_terminal *console, -- char *ttydir) -+ const struct lxc_terminal *console, -+ char *ttydir) - { - int ret; - char path[PATH_MAX], lxcpath[PATH_MAX]; -@@ -2104,7 +2106,7 @@ static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs, - SYSERROR("Failed to create \"%s\"", path); - return -errno; - } -- DEBUG("Created directory for console and tty devices at \"%s\"", path); -+ DEBUG("Created directory for console and tty devices at \"%s\"", path); - - ret = snprintf(lxcpath, sizeof(lxcpath), "%s/dev/%s/console", rootfs_path, ttydir); - if (ret < 0 || (size_t)ret >= sizeof(lxcpath)) -@@ -2140,7 +2142,7 @@ static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs, - ret = fchmod(console->slave, S_IXUSR | S_IXGRP); - if (ret < 0) { - SYSERROR("Failed to set mode \"0%o\" to \"%s\"", -- S_IXUSR | S_IXGRP, console->name); -+ S_IXUSR | S_IXGRP, console->name); - return -errno; - } - -@@ -2166,7 +2168,7 @@ static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs, - } - - static int lxc_setup_console(const struct lxc_rootfs *rootfs, -- const struct lxc_terminal *console, char *ttydir) -+ const struct lxc_terminal *console, char *ttydir) - { - - if (!ttydir) -@@ -2236,7 +2238,7 @@ int parse_mntopts(const char *mntopts, unsigned long *mntflags, unsigned long *p - *data = 0; - - lxc_iterate_parts(p, s, ",") -- parse_mntopt(p, mntflags, pflags, &data, size); -+ parse_mntopt(p, mntflags, pflags, &data, size); - - if (*data) - *mntdata = data; -@@ -2248,9 +2250,9 @@ int parse_mntopts(const char *mntopts, unsigned long *mntflags, unsigned long *p - } - - static int mount_entry(const char *fsname, const char *target, -- const char *fstype, unsigned long mountflags, -- unsigned long pflags, const char *data, bool optional, -- bool dev, bool relative, const char *rootfs) -+ const char *fstype, unsigned long mountflags, -+ unsigned long pflags, const char *data, bool optional, -+ bool dev, bool relative, const char *rootfs) - { - int ret; - char srcbuf[PATH_MAX]; -@@ -2269,7 +2271,7 @@ static int mount_entry(const char *fsname, const char *target, - } - - ret = safe_mount(srcpath, target, fstype, mountflags & ~MS_REMOUNT, data, -- rootfs); -+ rootfs); - if (ret < 0) { - if (optional) { - SYSINFO("Failed to mount \"%s\" on \"%s\" (optional)", -@@ -2278,7 +2280,7 @@ static int mount_entry(const char *fsname, const char *target, - } - - SYSERROR("Failed to mount \"%s\" on \"%s\"", -- srcpath ? srcpath : "(null)", target); -+ srcpath ? srcpath : "(null)", target); - return -1; - } - -@@ -2315,7 +2317,7 @@ static int mount_entry(const char *fsname, const char *target, - */ - if (!(mountflags & MS_REMOUNT)) { - if (!(required_flags & ~mountflags) && -- rqd_flags == 0) { -+ rqd_flags == 0) { - DEBUG("Mountflags already were %lu, " - "skipping remount", mountflags); - goto skipremount; -@@ -2335,13 +2337,13 @@ static int mount_entry(const char *fsname, const char *target, - } - - SYSERROR("Failed to mount \"%s\" on \"%s\"", -- srcpath ? srcpath : "(null)", target); -+ srcpath ? srcpath : "(null)", target); - return -1; - } - } - - #ifdef HAVE_STATVFS -- skipremount: -+skipremount: - #endif - if (pflags) { - ret = mount(NULL, target, NULL, pflags, NULL); -@@ -2352,7 +2354,7 @@ static int mount_entry(const char *fsname, const char *target, - return 0; - } else { - SYSERROR("Failed to change mount propagation " -- "for \"%s\" (optional)", target); -+ "for \"%s\" (optional)", target); - return -1; - } - } -@@ -2416,10 +2418,12 @@ static int check_mount_destination(const char *rootfs, const char *dest) - "/proc/net/dev", - NULL - }; -- const char **valid, **invalid; -+ const char **valid = NULL; -+ const char **invalid = NULL; - - for(valid = valid_destinations; *valid != NULL; valid++) { -- char *fullpath, *relpath; -+ char *fullpath = NULL; -+ char *relpath = NULL; - const char *parts[3] = { - rootfs, - *valid, -@@ -2469,9 +2473,9 @@ static int check_mount_destination(const char *rootfs, const char *dest) - } - - static int mount_entry_create_dir_file(const struct mntent *mntent, -- const char *path, -- const struct lxc_rootfs *rootfs, -- const char *lxc_name, const char *lxc_path) -+ const char *path, -+ const struct lxc_rootfs *rootfs, -+ const char *lxc_name, const char *lxc_path) - { - int ret; - char *p1, *p2; -@@ -2487,7 +2491,7 @@ static int mount_entry_create_dir_file(const struct mntent *mntent, - if (ret < 0 && errno != EEXIST) { - SYSERROR("Failed to create directory \"%s\"", path); - lxc_write_error_message(rootfs->errfd, "%s:%d: mkdir %s: %s.", -- __FILE__, __LINE__, path, strerror(errno)); -+ __FILE__, __LINE__, path, strerror(errno)); - return -1; - } - } -@@ -2510,14 +2514,14 @@ static int mount_entry_create_dir_file(const struct mntent *mntent, - if (ret < 0 && errno != EEXIST) { - SYSERROR("Failed to create directory \"%s\"", path); - lxc_write_error_message(rootfs->errfd, "%s:%d: mkdir %s: %s.", -- __FILE__, __LINE__, p2, strerror(errno)); -+ __FILE__, __LINE__, p2, strerror(errno)); - return -1; - } - - ret = mknod(path, S_IFREG | 0000, 0); - if (ret < 0 && errno != EEXIST) { - lxc_write_error_message(rootfs->errfd, "%s:%d: open %s: %s.", -- __FILE__, __LINE__, path, strerror(errno)); -+ __FILE__, __LINE__, path, strerror(errno)); - return -errno; - } - -@@ -2525,7 +2529,7 @@ static int mount_entry_create_dir_file(const struct mntent *mntent, - } - - static int mount_entry_with_loop_dev(const char *src, const char *dest, const char *fstype, -- char *mnt_opts, const char *rootfs) -+ char *mnt_opts, const char *rootfs) - { - int srcfd = -1, destfd, ret, saved_errno; - char srcbuf[50], destbuf[50]; // only needs enough for /proc/self/fd/ -@@ -2603,10 +2607,10 @@ retry: - /* rootfs, lxc_name, and lxc_path can be NULL when the container is created - * without a rootfs. */ - static inline int mount_entry_on_generic(struct mntent *mntent, -- const char *path, -- const struct lxc_rootfs *rootfs, -- const char *lxc_name, -- const char *lxc_path) -+ const char *path, -+ const struct lxc_rootfs *rootfs, -+ const char *lxc_name, -+ const char *lxc_path) - { - int ret; - unsigned long mntflags, pflags; -@@ -2631,7 +2635,7 @@ static inline int mount_entry_on_generic(struct mntent *mntent, - if (!rpath) { - ERROR("Failed to get real path of '%s' in scope '%s'.", path, rootfs_path); - lxc_write_error_message(rootfs->errfd, "%s:%d: failed to get real path of '%s' in scope '%s'.", -- __FILE__, __LINE__, path, rootfs_path); -+ __FILE__, __LINE__, path, rootfs_path); - return -1; - } - dest = rpath; -@@ -2640,7 +2644,7 @@ static inline int mount_entry_on_generic(struct mntent *mntent, - if (ret) { - ERROR("Mount destination is invalid: '%s'", dest); - lxc_write_error_message(rootfs->errfd, "%s:%d: mount destination is invalid: '%s'.", -- __FILE__, __LINE__, dest); -+ __FILE__, __LINE__, dest); - free(rpath); - return -1; - } -@@ -2665,14 +2669,14 @@ static inline int mount_entry_on_generic(struct mntent *mntent, - // isulad: support squashfs - if (strcmp(mntent->mnt_type, "squashfs") == 0) { - ret = mount_entry_with_loop_dev(mntent->mnt_fsname, dest, mntent->mnt_type, -- mntent->mnt_opts, rootfs_path); -+ mntent->mnt_opts, rootfs_path); - } else { - ret = mount_entry(mntent->mnt_fsname, dest, mntent->mnt_type, mntflags, -- pflags, mntdata, optional, dev, relative, rootfs_path); -+ pflags, mntdata, optional, dev, relative, rootfs_path); - } - if (ret < 0) { - lxc_write_error_message(rootfs->errfd, "%s:%d: failed to mount %s as type %s.", -- __FILE__, __LINE__, mntent->mnt_fsname, mntent->mnt_type); -+ __FILE__, __LINE__, mntent->mnt_fsname, mntent->mnt_type); - } - - free(mntdata); -@@ -2699,9 +2703,9 @@ static inline int mount_entry_on_systemfs(struct mntent *mntent) - } - - static int mount_entry_on_absolute_rootfs(struct mntent *mntent, -- const struct lxc_rootfs *rootfs, -- const char *lxc_name, -- const char *lxc_path) -+ const struct lxc_rootfs *rootfs, -+ const char *lxc_name, -+ const char *lxc_path) - { - int offset; - char *aux; -@@ -2743,9 +2747,9 @@ skipabs: - } - - static int mount_entry_on_relative_rootfs(struct mntent *mntent, -- const struct lxc_rootfs *rootfs, -- const char *lxc_name, -- const char *lxc_path) -+ const struct lxc_rootfs *rootfs, -+ const char *lxc_name, -+ const char *lxc_path) - { - int ret; - char path[PATH_MAX]; -@@ -2759,8 +2763,8 @@ static int mount_entry_on_relative_rootfs(struct mntent *mntent, - } - - static int mount_file_entries(const struct lxc_conf *conf, -- const struct lxc_rootfs *rootfs, FILE *file, -- const char *lxc_name, const char *lxc_path) -+ const struct lxc_rootfs *rootfs, FILE *file, -+ const char *lxc_name, const char *lxc_path) - { - char buf[4096]; - struct mntent mntent; -@@ -2790,10 +2794,10 @@ static int mount_file_entries(const struct lxc_conf *conf, - ret = mount_entry_on_systemfs(&mntent); - else if (mntent.mnt_dir[0] != '/') - ret = mount_entry_on_relative_rootfs(&mntent, rootfs, -- lxc_name, lxc_path); -+ lxc_name, lxc_path); - else - ret = mount_entry_on_absolute_rootfs(&mntent, rootfs, -- lxc_name, lxc_path); -+ lxc_name, lxc_path); - free(mntent.mnt_fsname); - free(mntent.mnt_dir); - if (ret < 0) -@@ -2806,8 +2810,8 @@ static int mount_file_entries(const struct lxc_conf *conf, - } - - static int setup_mount(const struct lxc_conf *conf, -- const struct lxc_rootfs *rootfs, const char *fstab, -- const char *lxc_name, const char *lxc_path) -+ const struct lxc_rootfs *rootfs, const char *fstab, -+ const char *lxc_name, const char *lxc_path) - { - FILE *f; - int ret; -@@ -2880,9 +2884,9 @@ on_error: - } - - static int setup_mount_entries(const struct lxc_conf *conf, -- const struct lxc_rootfs *rootfs, -- struct lxc_list *mount, const char *lxc_name, -- const char *lxc_path) -+ const struct lxc_rootfs *rootfs, -+ struct lxc_list *mount, const char *lxc_name, -+ const char *lxc_path) - { - int ret; - FILE *f; -@@ -2966,7 +2970,7 @@ static int setup_caps(struct lxc_list *caps) - } - - ret = prctl(PR_CAPBSET_DROP, prctl_arg(capid), prctl_arg(0), -- prctl_arg(0), prctl_arg(0)); -+ prctl_arg(0), prctl_arg(0)); - if (ret < 0) { - SYSERROR("Failed to remove %s capability", drop_entry); - return -1; -@@ -3025,7 +3029,7 @@ static int dropcaps_except(struct lxc_list *caps) - continue; - - ret = prctl(PR_CAPBSET_DROP, prctl_arg(i), prctl_arg(0), -- prctl_arg(0), prctl_arg(0)); -+ prctl_arg(0), prctl_arg(0)); - if (ret < 0) { - SYSERROR("Failed to remove capability %d", i); - return -1; -@@ -3076,8 +3080,8 @@ int setup_resource_limits(struct lxc_list *limits, pid_t pid, int errfd) - if (prlimit(pid, resid, &lim->limit, NULL) != 0) { - SYSERROR("Failed to set limit %s %lu %lu.", lim->resource, lim->limit.rlim_cur, lim->limit.rlim_max); - lxc_write_error_message(errfd, "%s:%d: Failed to set limit %s %lu %lu: %s.", -- __FILE__, __LINE__, lim->resource, -- lim->limit.rlim_cur, lim->limit.rlim_max, strerror(errno)); -+ __FILE__, __LINE__, lim->resource, -+ lim->limit.rlim_cur, lim->limit.rlim_max, strerror(errno)); - return -1; - } - -@@ -3115,10 +3119,10 @@ int setup_sysctl_parameters(struct lxc_list *sysctls) - } - - ret = lxc_write_to_file(filename, elem->value, -- strlen(elem->value), false, 0666); -+ strlen(elem->value), false, 0666); - if (ret < 0) { - SYSERROR("Failed to setup sysctl parameters %s to %s", -- elem->key, elem->value); -+ elem->key, elem->value); - return -1; - } - } -@@ -3150,7 +3154,7 @@ int setup_proc_filesystem(struct lxc_list *procs, pid_t pid) - } - - ret = lxc_write_to_file(filename, elem->value, -- strlen(elem->value), false, 0666); -+ strlen(elem->value), false, 0666); - if (ret < 0) { - ERROR("Failed to setup proc filesystem %s to %s", - elem->filename, elem->value); -@@ -3255,7 +3259,7 @@ struct lxc_conf *lxc_conf_init(void) - } - - int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf, -- size_t buf_size) -+ size_t buf_size) - { - int fd, ret; - char path[PATH_MAX]; -@@ -3280,7 +3284,7 @@ int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf, - close(fd); - if (ret != buflen) { - SYSERROR("Failed to write \"deny\" to " -- "\"/proc/%d/setgroups\"", pid); -+ "\"/proc/%d/setgroups\"", pid); - return -1; - } - TRACE("Wrote \"deny\" to \"/proc/%d/setgroups\"", pid); -@@ -3288,7 +3292,7 @@ int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf, - } - - ret = snprintf(path, PATH_MAX, "/proc/%d/%cid_map", pid, -- idtype == ID_TYPE_UID ? 'u' : 'g'); -+ idtype == ID_TYPE_UID ? 'u' : 'g'); - if (ret < 0 || ret >= PATH_MAX) - return -E2BIG; - -@@ -3303,7 +3307,7 @@ int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf, - close(fd); - if (ret != buf_size) { - SYSERROR("Failed to write %cid mapping to \"%s\"", -- idtype == ID_TYPE_UID ? 'u' : 'g', path); -+ idtype == ID_TYPE_UID ? 'u' : 'g', path); - return -1; - } - -@@ -3347,8 +3351,8 @@ static int idmaptool_on_path_and_privileged(const char *binary, cap_value_t cap) - #if HAVE_LIBCAP && LIBCAP_SUPPORTS_FILE_CAPABILITIES - /* Check if it has the CAP_SETUID capability. */ - if ((cap & CAP_SETUID) && -- lxc_file_cap_is_set(path, CAP_SETUID, CAP_EFFECTIVE) && -- lxc_file_cap_is_set(path, CAP_SETUID, CAP_PERMITTED)) { -+ lxc_file_cap_is_set(path, CAP_SETUID, CAP_EFFECTIVE) && -+ lxc_file_cap_is_set(path, CAP_SETUID, CAP_PERMITTED)) { - DEBUG("The binary \"%s\" has CAP_SETUID in its CAP_EFFECTIVE " - "and CAP_PERMITTED sets", path); - fret = 1; -@@ -3357,8 +3361,8 @@ static int idmaptool_on_path_and_privileged(const char *binary, cap_value_t cap) - - /* Check if it has the CAP_SETGID capability. */ - if ((cap & CAP_SETGID) && -- lxc_file_cap_is_set(path, CAP_SETGID, CAP_EFFECTIVE) && -- lxc_file_cap_is_set(path, CAP_SETGID, CAP_PERMITTED)) { -+ lxc_file_cap_is_set(path, CAP_SETGID, CAP_EFFECTIVE) && -+ lxc_file_cap_is_set(path, CAP_SETGID, CAP_PERMITTED)) { - DEBUG("The binary \"%s\" has CAP_SETGID in its CAP_EFFECTIVE " - "and CAP_PERMITTED sets", path); - fret = 1; -@@ -3451,10 +3455,10 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid) - lxc_list_for_each(iterator, idmap) { - map = iterator->elem; - if (map->idtype == ID_TYPE_UID && map->range == 1 && -- map->nsid == hostuid && map->hostid == hostuid) -+ map->nsid == hostuid && map->hostid == hostuid) - continue; - if (map->idtype == ID_TYPE_GID && map->range == 1 && -- map->nsid == hostgid && map->hostid == hostgid) -+ map->nsid == hostgid && map->hostid == hostgid) - continue; - use_shadow = true; - break; -@@ -3462,7 +3466,7 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid) - } - - for (type = ID_TYPE_UID, u_or_g = 'u'; type <= ID_TYPE_GID; -- type++, u_or_g = 'g') { -+ type++, u_or_g = 'g') { - pos = mapbuf; - - if (use_shadow) -@@ -3477,9 +3481,9 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid) - - left = LXC_IDMAPLEN - (pos - mapbuf); - fill = snprintf(pos, left, "%s%lu %lu %lu%s", -- use_shadow ? " " : "", map->nsid, -- map->hostid, map->range, -- use_shadow ? "" : "\n"); -+ use_shadow ? " " : "", map->nsid, -+ map->hostid, map->range, -+ use_shadow ? "" : "\n"); - if (fill <= 0 || fill >= left) { - /* The kernel only takes <= 4k for writes to - * /proc//{g,u}id_map -@@ -3498,8 +3502,8 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid) - */ - if (use_shadow) { - ret = run_command(cmd_output, sizeof(cmd_output), -- lxc_map_ids_exec_wrapper, -- (void *)mapbuf); -+ lxc_map_ids_exec_wrapper, -+ (void *)mapbuf); - if (ret < 0) { - ERROR("new%cidmap failed to write mapping \"%s\": %s", - u_or_g, cmd_output, mapbuf); -@@ -3525,7 +3529,7 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid) - * Return true if id was found, false otherwise. - */ - bool get_mapped_rootid(struct lxc_conf *conf, enum idtype idtype, -- unsigned long *val) -+ unsigned long *val) - { - unsigned nsid; - struct id_map *map; -@@ -3609,20 +3613,22 @@ int chown_mapped_root(const char *path, struct lxc_conf *conf) - char map1[100], map2[100], map3[100], map4[100], map5[100]; - char ugid[100]; - const char *args1[] = {"lxc-usernsexec", -- "-m", map1, -- "-m", map2, -- "-m", map3, -- "-m", map5, -- "--", "chown", ugid, path, -- NULL}; -+ "-m", map1, -+ "-m", map2, -+ "-m", map3, -+ "-m", map5, -+ "--", "chown", ugid, path, -+ NULL -+ }; - const char *args2[] = {"lxc-usernsexec", -- "-m", map1, -- "-m", map2, -- "-m", map3, -- "-m", map4, -- "-m", map5, -- "--", "chown", ugid, path, -- NULL}; -+ "-m", map1, -+ "-m", map2, -+ "-m", map3, -+ "-m", map4, -+ "-m", map5, -+ "--", "chown", ugid, path, -+ NULL -+ }; - char cmd_output[PATH_MAX]; - - hostuid = geteuid(); -@@ -3671,8 +3677,8 @@ int chown_mapped_root(const char *path, struct lxc_conf *conf) - */ - DEBUG("trying to chown \"%s\" to %d", path, hostgid); - if (sb.st_uid == hostuid && -- mapped_hostid(sb.st_gid, conf, ID_TYPE_GID) < 0 && -- chown(path, -1, hostgid) < 0) { -+ mapped_hostid(sb.st_gid, conf, ID_TYPE_GID) < 0 && -+ chown(path, -1, hostgid) < 0) { - ERROR("Failed chgrping %s", path); - return -1; - } -@@ -3700,7 +3706,7 @@ int chown_mapped_root(const char *path, struct lxc_conf *conf) - - /* "g:pathgid:rootgid+pathgid:1" */ - ret = snprintf(map4, 100, "g:%d:%d:1", (gid_t)sb.st_gid, -- rootgid + (gid_t)sb.st_gid); -+ rootgid + (gid_t)sb.st_gid); - if (ret < 0 || ret >= 100) { - ERROR("Error gid printing map string"); - return -1; -@@ -3722,12 +3728,12 @@ int chown_mapped_root(const char *path, struct lxc_conf *conf) - - if (hostgid == sb.st_gid) - ret = run_command(cmd_output, sizeof(cmd_output), -- chown_mapped_root_exec_wrapper, -- (void *)args1); -+ chown_mapped_root_exec_wrapper, -+ (void *)args1); - else - ret = run_command(cmd_output, sizeof(cmd_output), -- chown_mapped_root_exec_wrapper, -- (void *)args2); -+ chown_mapped_root_exec_wrapper, -+ (void *)args2); - if (ret < 0) - ERROR("lxc-usernsexec failed: %s", cmd_output); - -@@ -3820,7 +3826,7 @@ again: - f = fdopen(memfd, "r"); - if (!f) { - SYSERROR("Failed to open copy of \"/proc/self/mountinfo\" to mark " -- "all shared. Continuing"); -+ "all shared. Continuing"); - close(memfd); - return; - } -@@ -3918,7 +3924,7 @@ out: - * pre-mount hooks, and mounting the rootfs. - */ - int lxc_setup_rootfs_prepare_root(struct lxc_conf *conf, const char *name, -- const char *lxcpath) -+ const char *lxcpath) - { - int ret; - -@@ -3967,15 +3973,15 @@ static bool verify_start_hooks(struct lxc_conf *conf) - char *hookname = it->elem; - - ret = snprintf(path, PATH_MAX, "%s%s", -- conf->rootfs.path ? conf->rootfs.mount : "", -- hookname); -+ conf->rootfs.path ? conf->rootfs.mount : "", -+ hookname); - if (ret < 0 || ret >= PATH_MAX) - return false; - - ret = access(path, X_OK); - if (ret < 0) { - SYSERROR("Start hook \"%s\" not found in container", -- hookname); -+ hookname); - return false; - } - -@@ -3997,13 +4003,13 @@ static bool execveat_supported(void) - /* isulad: setup devices which will be populated in the container.*/ - static int setup_populate_devs(const struct lxc_rootfs *rootfs, struct lxc_list *devs) - { -- int ret; -- char *pathdirname; -+ int ret = 0; -+ char *pathdirname = NULL; - char path[MAXPATHLEN]; - mode_t cmask; - mode_t file_mode = 0; -- struct lxc_populate_devs *dev_elem; -- struct lxc_list *it; -+ struct lxc_populate_devs *dev_elem = NULL; -+ struct lxc_list *it = NULL; - - INFO("Populating devices into container"); - cmask = umask(S_IXUSR | S_IXGRP | S_IXOTH); -@@ -4034,12 +4040,12 @@ static int setup_populate_devs(const struct lxc_rootfs *rootfs, struct lxc_list - } - - DEBUG("Try to mknod '%s':'%d':'%d':'%d'\n", path, -- file_mode, dev_elem->maj, dev_elem->min); -+ file_mode, dev_elem->maj, dev_elem->min); - - ret = mknod(path, file_mode, makedev(dev_elem->maj, dev_elem->min)); - if (ret && errno != EEXIST) { - SYSERROR("Failed to mknod '%s':'%d':'%d':'%d'", dev_elem->name, -- file_mode, dev_elem->maj, dev_elem->min); -+ file_mode, dev_elem->maj, dev_elem->min); - - char hostpath[MAXPATHLEN]; - FILE *pathfile; -@@ -4049,16 +4055,16 @@ static int setup_populate_devs(const struct lxc_rootfs *rootfs, struct lxc_list - ret = snprintf(hostpath, MAXPATHLEN, "/dev/%s", dev_elem->name); - if (ret < 0 || ret >= MAXPATHLEN) - return -1; -- pathfile = fopen(path, "wb"); -+ pathfile = lxc_fopen(path, "wb"); - if (!pathfile) { - SYSERROR("Failed to create device mount target '%s'", path); - return -1; - } - fclose(pathfile); - if (safe_mount(hostpath, path, 0, MS_BIND, NULL, -- rootfs->path ? rootfs->mount : NULL) != 0) { -+ rootfs->path ? rootfs->mount : NULL) != 0) { - SYSERROR("Failed bind mounting device %s from host into container", -- dev_elem->name); -+ dev_elem->name); - return -1; - } - } -@@ -4077,7 +4083,7 @@ static int setup_populate_devs(const struct lxc_rootfs *rootfs, struct lxc_list - static int setup_rootfs_mountopts(const struct lxc_rootfs *rootfs) - { - unsigned long mflags, mntflags, pflags; -- char *mntdata; -+ char *mntdata = NULL; - - if(!rootfs || !rootfs->options) - return 0; -@@ -4109,7 +4115,7 @@ int lxc_setup(struct lxc_handler *handler) - if (ret < 0) { - ERROR("Failed to setup rootfs"); - lxc_write_error_message(lxc_conf->errpipe[1], "%s:%d: failed to setup rootfs %s.", -- __FILE__, __LINE__, lxc_conf->rootfs.path); -+ __FILE__, __LINE__, lxc_conf->rootfs.path); - return -1; - } - -@@ -4202,7 +4208,7 @@ int lxc_setup(struct lxc_handler *handler) - /*isulad: move mount entries here, before we do lxc_fill_autodev and populate devices */ - if (!lxc_list_empty(&lxc_conf->mount_list)) { - ret = setup_mount_entries(lxc_conf, &lxc_conf->rootfs, -- &lxc_conf->mount_list, name, lxcpath); -+ &lxc_conf->mount_list, name, lxcpath); - if (ret < 0) { - ERROR("Failed to setup mount entries"); - goto on_error; -@@ -4244,7 +4250,7 @@ int lxc_setup(struct lxc_handler *handler) - } - - ret = lxc_setup_console(&lxc_conf->rootfs, &lxc_conf->console, -- lxc_conf->ttys.dir); -+ lxc_conf->ttys.dir); - if (ret < 0) { - ERROR("Failed to setup console"); - goto on_error; -@@ -4369,11 +4375,13 @@ int lxc_drop_caps(struct lxc_conf *conf) - { - #define __DEF_CAP_TO_MASK(x) (1U << ((x) & 31)) - #if HAVE_LIBCAP -- struct lxc_list *iterator; -- char *keep_entry; -+ int ret = 0; -+ struct lxc_list *iterator = NULL; -+ char *keep_entry = NULL; - int i, capid; - int numcaps = lxc_caps_last_cap() + 1; - struct lxc_list *caps = NULL; -+ int *caplist = NULL; - - if (lxc_list_empty(&conf->keepcaps)) - return 0; -@@ -4384,7 +4392,7 @@ int lxc_drop_caps(struct lxc_conf *conf) - return -1; - - // caplist[i] is 1 if we keep capability i -- int *caplist = alloca(numcaps * sizeof(int)); -+ caplist = malloc(numcaps * sizeof(int)); - memset(caplist, 0, numcaps * sizeof(int)); - - lxc_list_for_each(iterator, caps) { -@@ -4404,9 +4412,10 @@ int lxc_drop_caps(struct lxc_conf *conf) - if (capid == -2) - continue; - -- if (capid < 0) { -+ if (capid < 0) { - ERROR("unknown capability %s", keep_entry); -- return -1; -+ ret = -1; -+ goto out; - } - - DEBUG("keep capability '%s' (%d)", keep_entry, capid); -@@ -4420,7 +4429,7 @@ int lxc_drop_caps(struct lxc_conf *conf) - cap_user_header_t cap_header = &cap_header_data; - cap_user_data_t cap_data = &cap_data_data[0]; - -- memset(cap_header, 0 ,sizeof(struct __user_cap_header_struct)); -+ memset(cap_header, 0,sizeof(struct __user_cap_header_struct)); - memset(cap_data, 0, sizeof(struct __user_cap_data_struct) * 2); - - cap_header->pid = 0; -@@ -4435,12 +4444,16 @@ int lxc_drop_caps(struct lxc_conf *conf) - } - - if (capset(cap_header, cap_data)) { -- SYSERROR("Failed to set capabilitys"); -- return -1; -+ SYSERROR("Failed to set capabilitys"); -+ ret = -1; -+ goto out; - } - - #endif -- return 0; -+ -+out: -+ free(caplist); -+ return ret; - } - - struct oci_hook_conf { -@@ -4474,9 +4487,17 @@ static char* generate_json_str(const char *name, const char *lxcpath, const char - ERROR("Get container %s pid failed: %s", name, strerror(errno)); - cpid = "-1"; - } -+ -+ if ((SIZE_MAX - strlen(name) - strlen(cpid) - strlen(rootfs) - strlen(lxcpath) - strlen(name)) < -+ (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; -+ strlen(name) + strlen(cpid) + strlen(rootfs) + strlen(lxcpath) + 1 + strlen(name) + 1; - inmsg = malloc(size); - if (!inmsg) { - ERROR("Out of memory"); -@@ -4484,8 +4505,8 @@ static char* generate_json_str(const char *name, const char *lxcpath, const char - goto out_free; - } - rc = snprintf(inmsg, size, -- "{\"ociVersion\":\"\",\"id\":\"%s\",\"pid\":%s,\"root\":\"%s\",\"bundle\":\"%s/%s\"}", -- name, cpid, rootfs, lxcpath, name); -+ "{\"ociVersion\":\"\",\"id\":\"%s\",\"pid\":%s,\"root\":\"%s\",\"bundle\":\"%s/%s\"}", -+ name, cpid, rootfs, lxcpath, name); - if (rc < 0 || rc >= size) { - ERROR("Create json string failed"); - ret = -1; -@@ -4501,13 +4522,14 @@ out_free: - - static char **merge_ocihook_env(char **oldenvs, size_t env_len, size_t *merge_env_len) - { -- char **result; -+ char **result = NULL; - size_t result_len = env_len; - size_t i, j; -- char *tmpenv; -+ 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; -+ "LXC_CONFIG_FILE", "LXC_CGROUP_PATH", "LXC_ROOTFS_PATH", "LXC_NAME" -+ }; -+ char *lxcenv_buf = NULL; - - result_len += (sizeof(lxc_envs) / sizeof(char *)) + 1; - result = malloc(sizeof(char *) * result_len); -@@ -4541,8 +4563,8 @@ static char **merge_ocihook_env(char **oldenvs, size_t env_len, size_t *merge_en - return result; - } - --static struct lxc_popen_FILE *lxc_popen_ocihook(char *commandpath, char **args, int args_len, -- char **envs, int env_len, const char *instr) -+static struct lxc_popen_FILE *lxc_popen_ocihook(const char *commandpath, char **args, int args_len, -+ char **envs, int env_len, const char *instr) - { - int ret; - struct lxc_popen_FILE *fp = NULL; -@@ -4684,12 +4706,12 @@ void* wait_ocihook_timeout(void *arg) - - if (alive) { - ERROR("%s:%d: running %s hook caused \"hook ran past specified timeout of %.1fs\"", -- __FILE__, __LINE__, lxchook_names[conf->which], -- (double)conf->timeout); -+ __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); -+ __FILE__, __LINE__, lxchook_names[conf->which], -+ (double)conf->timeout); - - if (kill(conf->pid, SIGKILL) && errno != ESRCH) { - ERROR("Send kill signal failed"); -@@ -4702,7 +4724,7 @@ out: - return ((void *)0); - } - --static int run_ocihook_buffer(struct oci_hook_conf *oconf, char *inmsg) -+static int run_ocihook_buffer(struct oci_hook_conf *oconf, const char *inmsg) - { - struct lxc_popen_FILE *f; - char output[LXC_LOG_BUFFER_SIZE] = {0}; -@@ -4771,17 +4793,17 @@ static int run_ocihook_buffer(struct oci_hook_conf *oconf, char *inmsg) - } else if (WIFEXITED(ret) && WEXITSTATUS(ret) != 0) { - ERROR("Script exited with status %d. output: %s", WEXITSTATUS(ret), output); - lxc_write_error_message(conf->errfd, "%s:%d: running %s hook caused \"error running hook: exit status %d, output: %s\".", -- __FILE__, __LINE__, -- (conf->which >= NUM_LXC_HOOKS) ? "invalid type" : lxchook_names[conf->which], -- WEXITSTATUS(ret), output); -+ __FILE__, __LINE__, -+ (conf->which >= NUM_LXC_HOOKS) ? "invalid type" : lxchook_names[conf->which], -+ WEXITSTATUS(ret), output); - - goto print_hook; - } else if (WIFSIGNALED(ret)) { - ERROR("Script terminated by signal %d.", WTERMSIG(ret)); - lxc_write_error_message(conf->errfd, "%s:%d: running %s hook caused \"error running hook: Script terminated by signal %d\".", -- __FILE__, __LINE__, -- (conf->which >= NUM_LXC_HOOKS) ? "invalid type" : lxchook_names[conf->which], -- WTERMSIG(ret)); -+ __FILE__, __LINE__, -+ (conf->which >= NUM_LXC_HOOKS) ? "invalid type" : lxchook_names[conf->which], -+ WTERMSIG(ret)); - - goto print_hook; - } -@@ -4801,8 +4823,8 @@ print_hook: - 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.", -- buffer, err_args_msg ? err_args_msg : "", -- err_envs_msg ? err_envs_msg : "", conf->timeout); -+ buffer, err_args_msg ? err_args_msg : "", -+ err_envs_msg ? err_envs_msg : "", conf->timeout); - - free(err_args_msg); - free(err_envs_msg); -@@ -4810,8 +4832,8 @@ print_hook: - } - - static int run_ocihook_script_argv(const char *name, const char *section, -- struct oci_hook_conf *oconf, -- const char *lxcpath, const char *rootfs) -+ struct oci_hook_conf *oconf, -+ const char *lxcpath, const char *rootfs) - { - int ret; - const char *script = oconf->ocihook->path; -@@ -4845,9 +4867,13 @@ static char *get_root_path(const char *path, const char *backend) - } - - if (strcmp(backend, "aufs") == 0 || -- strcmp(backend, "overlayfs") == 0 || -- strcmp(backend, "loop") == 0) { -+ strcmp(backend, "overlayfs") == 0 || -+ strcmp(backend, "loop") == 0) { - tmp = strrchr(path, ':'); -+ if (tmp == NULL) { -+ ERROR("Out of memory"); -+ return NULL; -+ } - tmp++; - ret = strdup(tmp); - if (!ret) { -@@ -4866,13 +4892,13 @@ default_out: - return ret; - } - --static int run_oci_hooks(const char *name, const char *lxcpath, struct lxc_conf *lc, int which, int errfd) -+static int do_run_oci_hooks(const char *name, const char *lxcpath, struct lxc_conf *lc, int which, int errfd) - { - struct oci_hook_conf work_conf = {0}; - size_t i; - int ret = 0; - int nret = 0; -- char *rootpath; -+ char *rootpath = NULL; - - if (!lc) { - return -1; -@@ -4890,32 +4916,32 @@ static int run_oci_hooks(const char *name, const char *lxcpath, struct lxc_conf - work_conf.errfd = errfd; - work_conf.which = which; - switch (which) { -- 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 %ld 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]; -- ret = run_ocihook_script_argv(name, "lxc", &work_conf, lxcpath, rootpath); -- if (ret != 0) -- break; -- } -- break; -- default: -- ret = -1; -+ 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 %ld 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]; -+ ret = run_ocihook_script_argv(name, "lxc", &work_conf, lxcpath, rootpath); -+ if (ret != 0) -+ break; -+ } -+ break; -+ default: -+ ret = -1; - } - if (rootpath) - free(rootpath); -@@ -4923,33 +4949,12 @@ static int run_oci_hooks(const char *name, const char *lxcpath, struct lxc_conf - } - - int run_lxc_hooks(const char *name, char *hookname, struct lxc_conf *conf, -- char *argv[]) -+ char *argv[]) - { - struct lxc_list *it; - int which = -1; - -- if (strcmp(hookname, "oci-prestart") == 0) { -- which = OCI_HOOK_PRESTART; -- if (!argv || !argv[0]) { -- ERROR("oci hook require lxcpath"); -- return -1; -- } -- return run_oci_hooks(name, argv[0], conf, which, conf->errpipe[1]); -- } else if (strcmp(hookname, "oci-poststart") == 0) { -- which = OCI_HOOK_POSTSTART; -- if (!argv || !argv[0]) { -- ERROR("oci hook require lxcpath"); -- return -1; -- } -- return run_oci_hooks(name, argv[0], conf, which, conf->errpipe[1]); -- } else if (strcmp(hookname, "oci-poststop") == 0) { -- which = OCI_HOOK_POSTSTOP; -- if (!argv || !argv[0]) { -- ERROR("oci hook require lxcpath"); -- return -1; -- } -- return run_oci_hooks(name, argv[0], conf, which, conf->errpipe[1]); -- } else if (strcmp(hookname, "pre-start") == 0) -+ if (strcmp(hookname, "pre-start") == 0) - which = LXCHOOK_PRESTART; - else if (strcmp(hookname, "start-host") == 0) - which = LXCHOOK_START_HOST; -@@ -4977,7 +4982,7 @@ int run_lxc_hooks(const char *name, char *hookname, struct lxc_conf *conf, - char *hook = it->elem; - - ret = run_script_argv(name, conf->hooks_version, "lxc", hook, -- hookname, argv); -+ hookname, argv); - if (ret < 0) - return -1; - } -@@ -4985,6 +4990,39 @@ int run_lxc_hooks(const char *name, char *hookname, struct lxc_conf *conf, - return 0; - } - -+int run_oci_hooks(const char *name, char *hookname, struct lxc_conf *conf, const char *lxcpath) -+{ -+ struct lxc_list *it; -+ int which = -1; -+ -+ if (strcmp(hookname, "oci-prestart") == 0) { -+ which = OCI_HOOK_PRESTART; -+ if (!lxcpath) { -+ ERROR("oci hook require lxcpath"); -+ return -1; -+ } -+ return do_run_oci_hooks(name, lxcpath, conf, which, conf->errpipe[1]); -+ } else if (strcmp(hookname, "oci-poststart") == 0) { -+ which = OCI_HOOK_POSTSTART; -+ if (!lxcpath) { -+ ERROR("oci hook require lxcpath"); -+ return -1; -+ } -+ return do_run_oci_hooks(name, lxcpath, conf, which, conf->errpipe[1]); -+ } else if (strcmp(hookname, "oci-poststop") == 0) { -+ which = OCI_HOOK_POSTSTOP; -+ if (!lxcpath) { -+ ERROR("oci hook require lxcpath"); -+ return -1; -+ } -+ return do_run_oci_hooks(name, lxcpath, conf, which, conf->errpipe[1]); -+ } else -+ return -1; -+ -+ return 0; -+} -+ -+ - int lxc_clear_config_caps(struct lxc_conf *c) - { - struct lxc_list *it, *next; -@@ -5299,7 +5337,8 @@ int lxc_clear_init_groups(struct lxc_conf *lxc_conf) - /*isulad: clear populate devices*/ - int lxc_clear_populate_devices(struct lxc_conf *c) - { -- struct lxc_list *it,*next; -+ struct lxc_list *it = NULL; -+ struct lxc_list *next = NULL; - - lxc_list_for_each_safe(it, &c->populate_devs, next) { - struct lxc_populate_devs *dev_elem = it->elem; -@@ -5315,7 +5354,8 @@ int lxc_clear_populate_devices(struct lxc_conf *c) - /*isulad: clear rootfs masked paths*/ - int lxc_clear_rootfs_masked_paths(struct lxc_conf *c) - { -- struct lxc_list *it,*next; -+ struct lxc_list *it = NULL; -+ struct lxc_list *next = NULL; - - lxc_list_for_each_safe(it, &c->rootfs.maskedpaths, next) { - lxc_list_del(it); -@@ -5328,7 +5368,8 @@ int lxc_clear_rootfs_masked_paths(struct lxc_conf *c) - /*isulad: clear rootfs ro paths*/ - int lxc_clear_rootfs_ro_paths(struct lxc_conf *c) - { -- struct lxc_list *it,*next; -+ struct lxc_list *it = NULL; -+ struct lxc_list *next = NULL; - - lxc_list_for_each_safe(it, &c->rootfs.ropaths, next) { - lxc_list_del(it); -@@ -5449,7 +5490,7 @@ static int run_userns_fn(void *data) - } - - static struct id_map *mapped_nsid_add(struct lxc_conf *conf, unsigned id, -- enum idtype idtype) -+ enum idtype idtype) - { - const struct id_map *map; - struct id_map *retmap; -@@ -5467,7 +5508,7 @@ static struct id_map *mapped_nsid_add(struct lxc_conf *conf, unsigned id, - } - - static struct id_map *find_mapped_hostid_entry(struct lxc_conf *conf, -- unsigned id, enum idtype idtype) -+ unsigned id, enum idtype idtype) - { - struct id_map *map; - struct lxc_list *it; -@@ -5491,7 +5532,7 @@ static struct id_map *find_mapped_hostid_entry(struct lxc_conf *conf, - * existing one or establish a new one. - */ - static struct id_map *mapped_hostid_add(struct lxc_conf *conf, uid_t id, -- enum idtype type) -+ enum idtype type) - { - int hostid_mapped; - struct id_map *entry = NULL, *tmp = NULL; -@@ -5528,7 +5569,7 @@ struct lxc_list *get_minimal_idmap(struct lxc_conf *conf) - gid_t nsgid = (conf->root_nsgid_map != NULL) ? 0 : conf->init_gid; - struct lxc_list *idmap = NULL, *tmplist = NULL; - struct id_map *container_root_uid = NULL, *container_root_gid = NULL, -- *host_uid_map = NULL, *host_gid_map = NULL; -+ *host_uid_map = NULL, *host_gid_map = NULL; - - /* Find container root mappings. */ - container_root_uid = mapped_nsid_add(conf, nsuid, ID_TYPE_UID); -@@ -5538,7 +5579,7 @@ struct lxc_list *get_minimal_idmap(struct lxc_conf *conf) - } - euid = geteuid(); - if (euid >= container_root_uid->hostid && -- euid < (container_root_uid->hostid + container_root_uid->range)) -+ euid < (container_root_uid->hostid + container_root_uid->range)) - host_uid_map = container_root_uid; - - container_root_gid = mapped_nsid_add(conf, nsgid, ID_TYPE_GID); -@@ -5548,7 +5589,7 @@ struct lxc_list *get_minimal_idmap(struct lxc_conf *conf) - } - egid = getegid(); - if (egid >= container_root_gid->hostid && -- egid < (container_root_gid->hostid + container_root_gid->range)) -+ egid < (container_root_gid->hostid + container_root_gid->range)) - host_gid_map = container_root_gid; - - /* Check whether the {g,u}id of the user has a mapping. */ -@@ -5648,7 +5689,7 @@ on_error: - * there to start the container in the first place. - */ - int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data, -- const char *fn_name) -+ const char *fn_name) - { - pid_t pid; - int p[2]; -@@ -5686,7 +5727,7 @@ int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data, - p[0] = -1; - - if (lxc_log_get_level() == LXC_LOG_LEVEL_TRACE || -- conf->loglevel == LXC_LOG_LEVEL_TRACE) { -+ conf->loglevel == LXC_LOG_LEVEL_TRACE) { - struct id_map *map; - struct lxc_list *it; - -@@ -5729,7 +5770,7 @@ on_error: - } - - int userns_exec_full(struct lxc_conf *conf, int (*fn)(void *), void *data, -- const char *fn_name) -+ const char *fn_name) - { - pid_t pid; - uid_t euid, egid; -@@ -5741,7 +5782,7 @@ int userns_exec_full(struct lxc_conf *conf, int (*fn)(void *), void *data, - char c = '1'; - struct lxc_list *idmap = NULL, *tmplist = NULL; - struct id_map *container_root_uid = NULL, *container_root_gid = NULL, -- *host_uid_map = NULL, *host_gid_map = NULL; -+ *host_uid_map = NULL, *host_gid_map = NULL; - - if (!conf) - return -EINVAL; -@@ -5866,7 +5907,7 @@ int userns_exec_full(struct lxc_conf *conf, int (*fn)(void *), void *data, - host_gid_map = NULL; - - if (lxc_log_get_level() == LXC_LOG_LEVEL_TRACE || -- conf->loglevel == LXC_LOG_LEVEL_TRACE) { -+ conf->loglevel == LXC_LOG_LEVEL_TRACE) { - lxc_list_for_each (cur, idmap) { - map = cur->elem; - TRACE("establishing %cid mapping for \"%d\" in new " -@@ -6139,7 +6180,7 @@ struct lxc_list *sort_cgroup_settings(struct lxc_list *cgroup_settings) - /* Store the memsw_limit location */ - memsw_limit = item; - } else if (strcmp(cg->subsystem, "memory.limit_in_bytes") == 0 && -- memsw_limit != NULL) { -+ memsw_limit != NULL) { - /* lxc.cgroup.memory.memsw.limit_in_bytes is found - * before lxc.cgroup.memory.limit_in_bytes, swap these - * two items */ -diff --git a/src/lxc/conf.h b/src/lxc/conf.h -index fb3c156..26bb70f 100644 ---- a/src/lxc/conf.h -+++ b/src/lxc/conf.h -@@ -70,14 +70,14 @@ typedef void * scmp_filter_ctx; - struct lxc_cgroup { - union { - /* information about a specific controller */ -- struct /* controller */ { -+ struct { /* controller */ - int version; - char *subsystem; - char *value; - }; - - /* meta information about cgroup configuration */ -- struct /* meta */ { -+ struct { /* meta */ - char *controllers; - char *dir; - }; -@@ -435,7 +435,7 @@ struct lxc_conf { - }; - - extern int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf, -- size_t buf_size); -+ size_t buf_size); - - #ifdef HAVE_TLS - extern thread_local struct lxc_conf *current_config; -@@ -444,7 +444,9 @@ extern struct lxc_conf *current_config; - #endif - - extern int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf, -- char *argv[]); -+ char *argv[]); -+extern int run_oci_hooks(const char *name, char *hookname, struct lxc_conf *conf, const char *lxcpath); -+ - extern int detect_shared_rootfs(void); - extern struct lxc_conf *lxc_conf_init(void); - extern void lxc_conf_free(struct lxc_conf *conf); -@@ -465,20 +467,20 @@ extern int lxc_clear_limits(struct lxc_conf *c, const char *key); - extern int lxc_delete_autodev(struct lxc_handler *handler); - extern void lxc_clear_includes(struct lxc_conf *conf); - extern int lxc_setup_rootfs_prepare_root(struct lxc_conf *conf, -- const char *name, const char *lxcpath); -+ const char *name, const char *lxcpath); - extern int lxc_setup(struct lxc_handler *handler); - extern int lxc_setup_parent(struct lxc_handler *handler); - extern int setup_resource_limits(struct lxc_list *limits, pid_t pid, int errfd); - extern int find_unmapped_nsid(struct lxc_conf *conf, enum idtype idtype); - extern int mapped_hostid(unsigned id, struct lxc_conf *conf, -- enum idtype idtype); -+ enum idtype idtype); - extern int chown_mapped_root(const char *path, struct lxc_conf *conf); - extern int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data, -- const char *fn_name); -+ const char *fn_name); - extern int userns_exec_full(struct lxc_conf *conf, int (*fn)(void *), -- void *data, const char *fn_name); -+ void *data, const char *fn_name); - extern int parse_mntopts(const char *mntopts, unsigned long *mntflags, -- unsigned long *pflags, char **mntdata); -+ unsigned long *pflags, char **mntdata); - extern int parse_propagationopts(const char *mntopts, unsigned long *pflags); - extern void tmp_proc_unmount(struct lxc_conf *lxc_conf); - extern void remount_all_slave(void); -@@ -486,12 +488,12 @@ extern void suggest_default_idmap(void); - extern FILE *make_anonymous_mount_file(struct lxc_list *mount); - extern struct lxc_list *sort_cgroup_settings(struct lxc_list *cgroup_settings); - extern unsigned long add_required_remount_flags(const char *s, const char *d, -- unsigned long flags); -+ unsigned long flags); - extern int run_script(const char *name, const char *section, const char *script, -- ...); -+ ...); - extern int run_script_argv(const char *name, unsigned int hook_version, -- const char *section, const char *script, -- const char *hookname, char **argsin); -+ const char *section, const char *script, -+ const char *hookname, char **argsin); - extern int in_caplist(int cap, struct lxc_list *caps); - extern int setup_sysctl_parameters(struct lxc_list *sysctls); - extern int lxc_clear_sysctls(struct lxc_conf *c, const char *key); -diff --git a/src/lxc/confile.c b/src/lxc/confile.c -index 93936cc..216a688 100644 ---- a/src/lxc/confile.c -+++ b/src/lxc/confile.c -@@ -270,7 +270,7 @@ struct lxc_config_t *lxc_get_config(const char *key) - } - - static int set_config_net(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - if (!lxc_config_value_empty(value)) { - ERROR("lxc.net must not have a value"); -@@ -281,7 +281,7 @@ static int set_config_net(const char *key, const char *value, - } - - static int set_config_net_type(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_netdev *netdev = data; - -@@ -296,7 +296,7 @@ static int set_config_net_type(const char *key, const char *value, - } else if (!strcmp(value, "macvlan")) { - netdev->type = LXC_NET_MACVLAN; - lxc_macvlan_mode_to_flag(&netdev->priv.macvlan_attr.mode, -- "private"); -+ "private"); - } else if (!strcmp(value, "vlan")) { - netdev->type = LXC_NET_VLAN; - } else if (!strcmp(value, "phys")) { -@@ -314,7 +314,7 @@ static int set_config_net_type(const char *key, const char *value, - } - - static int set_config_net_flags(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_netdev *netdev = data; - -@@ -330,7 +330,7 @@ static int set_config_net_flags(const char *key, const char *value, - } - - static int create_matched_ifnames(const char *value, struct lxc_conf *lxc_conf, -- struct lxc_netdev *netdev) -+ struct lxc_netdev *netdev) - { - struct netns_ifaddrs *ifaddr, *ifa; - int n; -@@ -339,7 +339,9 @@ static int create_matched_ifnames(const char *value, struct lxc_conf *lxc_conf, - const char *link_key = "lxc.net.link"; - const char *tmpvalue = "phys"; - -- if (netns_getifaddrs(&ifaddr, -1, &(bool){false}) < 0) { -+ if (netns_getifaddrs(&ifaddr, -1, &(bool) { -+ false -+}) < 0) { - SYSERROR("Failed to get network interfaces"); - return -1; - } -@@ -353,10 +355,10 @@ static int create_matched_ifnames(const char *value, struct lxc_conf *lxc_conf, - - if (!strncmp(value, ifa->ifa_name, strlen(value) - 1)) { - ret = set_config_net_type(type_key, tmpvalue, lxc_conf, -- netdev); -+ netdev); - if (!ret) { - ret = set_config_net_link( -- link_key, ifa->ifa_name, lxc_conf, netdev); -+ link_key, ifa->ifa_name, lxc_conf, netdev); - if (ret) { - ERROR("Failed to create matched ifnames"); - break; -@@ -375,7 +377,7 @@ static int create_matched_ifnames(const char *value, struct lxc_conf *lxc_conf, - } - - static int set_config_net_link(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_netdev *netdev = data; - int ret = 0; -@@ -395,7 +397,7 @@ static int set_config_net_link(const char *key, const char *value, - } - - static int set_config_net_name(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_netdev *netdev = data; - -@@ -409,7 +411,7 @@ static int set_config_net_name(const char *key, const char *value, - } - - static int set_config_net_veth_pair(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_netdev *netdev = data; - -@@ -423,7 +425,7 @@ static int set_config_net_veth_pair(const char *key, const char *value, - } - - static int set_config_net_macvlan_mode(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_netdev *netdev = data; - -@@ -437,7 +439,7 @@ static int set_config_net_macvlan_mode(const char *key, const char *value, - } - - static int set_config_net_hwaddr(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_netdev *netdev = data; - char *new_value; -@@ -466,7 +468,7 @@ static int set_config_net_hwaddr(const char *key, const char *value, - } - - static int set_config_net_vlan_id(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - int ret; - struct lxc_netdev *netdev = data; -@@ -485,7 +487,7 @@ static int set_config_net_vlan_id(const char *key, const char *value, - } - - static int set_config_net_mtu(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_netdev *netdev = data; - -@@ -499,7 +501,7 @@ static int set_config_net_mtu(const char *key, const char *value, - } - - static int set_config_net_ipv4_address(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - int ret; - struct lxc_netdev *netdev = data; -@@ -596,7 +598,7 @@ static int set_config_net_ipv4_address(const char *key, const char *value, - } - - static int set_config_net_ipv4_gateway(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_netdev *netdev = data; - -@@ -634,7 +636,7 @@ static int set_config_net_ipv4_gateway(const char *key, const char *value, - } - - static int set_config_net_ipv6_address(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - int ret; - struct lxc_netdev *netdev = data; -@@ -700,7 +702,7 @@ static int set_config_net_ipv6_address(const char *key, const char *value, - } - - static int set_config_net_ipv6_gateway(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_netdev *netdev = data; - -@@ -738,7 +740,7 @@ static int set_config_net_ipv6_gateway(const char *key, const char *value, - } - - static int set_config_net_script_up(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_netdev *netdev = data; - -@@ -752,7 +754,7 @@ static int set_config_net_script_up(const char *key, const char *value, - } - - static int set_config_net_script_down(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_netdev *netdev = data; - -@@ -782,31 +784,31 @@ static int add_hook(struct lxc_conf *lxc_conf, int which, char *hook) - } - - static int set_config_seccomp_profile(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - return set_config_path_item(&lxc_conf->seccomp, value); - } - - static int set_config_execute_cmd(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - return set_config_path_item(&lxc_conf->execute_cmd, value); - } - - static int set_config_init_cmd(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - return set_config_path_item(&lxc_conf->init_cmd, value); - } - - static int set_config_init_cwd(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - return set_config_path_item(&lxc_conf->init_cwd, value); - } - - static int set_config_init_uid(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - unsigned int init_uid; - -@@ -824,7 +826,7 @@ static int set_config_init_uid(const char *key, const char *value, - } - - static int set_config_init_gid(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - unsigned int init_gid; - -@@ -842,7 +844,7 @@ static int set_config_init_gid(const char *key, const char *value, - } - - static int set_config_hooks(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - char *copy; - -@@ -885,7 +887,7 @@ static int set_config_hooks(const char *key, const char *value, - } - - static int set_config_hooks_version(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - int ret; - unsigned int tmp; -@@ -909,7 +911,7 @@ static int set_config_hooks_version(const char *key, const char *value, - } - - static int set_config_personality(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - signed long personality = lxc_config_parse_arch(value); - -@@ -922,7 +924,7 @@ static int set_config_personality(const char *key, const char *value, - } - - static int set_config_pty_max(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - int ret; - unsigned int max = 0; -@@ -947,7 +949,7 @@ static int set_config_pty_max(const char *key, const char *value, - * noticed when the callback was called. - */ - static int set_config_start(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - bool is_empty; - -@@ -986,7 +988,7 @@ static int set_config_start(const char *key, const char *value, - } - - static int set_config_monitor(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - if (lxc_config_value_empty(value)) { - lxc_conf->monitor_unshare = 0; -@@ -1000,7 +1002,7 @@ static int set_config_monitor(const char *key, const char *value, - } - - static int set_config_group(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - char *groups, *token; - struct lxc_list *grouplist; -@@ -1039,10 +1041,10 @@ static int set_config_group(const char *key, const char *value, - } - - static int set_config_environment(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_list *list_item = NULL; -- char *replaced; -+ char *replaced = NULL; - - if (lxc_config_value_empty(value)) - return lxc_clear_environment(lxc_conf); -@@ -1072,7 +1074,7 @@ on_error: - } - - static int set_config_tty_max(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - int ret; - unsigned int nbtty = 0; -@@ -1092,22 +1094,22 @@ static int set_config_tty_max(const char *key, const char *value, - } - - static int set_config_tty_dir(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - return set_config_string_item_max(&lxc_conf->ttys.dir, value, -- NAME_MAX + 1); -+ NAME_MAX + 1); - } - - static int set_config_apparmor_profile(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - return set_config_string_item(&lxc_conf->lsm_aa_profile, value); - } - - static int set_config_apparmor_allow_incomplete(const char *key, -- const char *value, -- struct lxc_conf *lxc_conf, -- void *data) -+ const char *value, -+ struct lxc_conf *lxc_conf, -+ void *data) - { - if (lxc_config_value_empty(value)) { - lxc_conf->lsm_aa_allow_incomplete = 0; -@@ -1124,13 +1126,13 @@ static int set_config_apparmor_allow_incomplete(const char *key, - } - - static int set_config_selinux_context(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - return set_config_string_item(&lxc_conf->lsm_se_context, value); - } - - static int set_config_log_file(const char *key, const char *value, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int ret; - -@@ -1151,7 +1153,7 @@ static int set_config_log_file(const char *key, const char *value, - } - - static int set_config_log_level(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - int newlevel; - -@@ -1176,7 +1178,7 @@ static int set_config_log_level(const char *key, const char *value, - } - - static int set_config_autodev(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - if (lxc_config_value_empty(value)) { - lxc_conf->autodev = 0; -@@ -1193,7 +1195,7 @@ static int set_config_autodev(const char *key, const char *value, - } - - static int set_config_signal_halt(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - int sig_n; - -@@ -1212,7 +1214,7 @@ static int set_config_signal_halt(const char *key, const char *value, - } - - static int set_config_signal_reboot(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - int sig_n; - -@@ -1231,7 +1233,7 @@ static int set_config_signal_reboot(const char *key, const char *value, - } - - static int set_config_signal_stop(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - int sig_n; - -@@ -1250,7 +1252,7 @@ static int set_config_signal_stop(const char *key, const char *value, - } - - static int __set_config_cgroup_controller(const char *key, const char *value, -- struct lxc_conf *lxc_conf, int version) -+ struct lxc_conf *lxc_conf, int version) - { - const char *subkey, *token; - size_t token_len; -@@ -1317,22 +1319,22 @@ out: - } - - static int set_config_cgroup_controller(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - return __set_config_cgroup_controller(key, value, lxc_conf, -- CGROUP_SUPER_MAGIC); -+ CGROUP_SUPER_MAGIC); - } - - static int set_config_cgroup2_controller(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - return __set_config_cgroup_controller(key, value, lxc_conf, -- CGROUP2_SUPER_MAGIC); -+ CGROUP2_SUPER_MAGIC); - } - - - static int set_config_cgroup_dir(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - if (lxc_config_value_empty(value)) - return clr_config_cgroup_dir(key, lxc_conf, NULL); -@@ -1341,7 +1343,7 @@ static int set_config_cgroup_dir(const char *key, const char *value, - } - - static int set_config_prlimit(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_list *iter; - struct rlimit limit; -@@ -1434,7 +1436,7 @@ on_error: - } - - static int set_config_sysctl(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_list *iter; - char *replace_value = NULL; -@@ -1502,7 +1504,7 @@ on_error: - } - - static int set_config_proc(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - const char *subkey; - struct lxc_list *proclist = NULL; -@@ -1552,7 +1554,7 @@ on_error: - } - - static int set_config_idmaps(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - unsigned long hostid, nsid, range; - char type; -@@ -1612,7 +1614,7 @@ on_error: - } - - static int set_config_mount_fstab(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - if (lxc_config_value_empty(value)) { - clr_config_mount_fstab(key, lxc_conf, NULL); -@@ -1623,7 +1625,7 @@ static int set_config_mount_fstab(const char *key, const char *value, - } - - static int set_config_mount_auto(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - char *autos, *token; - int i; -@@ -1633,34 +1635,34 @@ static int set_config_mount_auto(const char *key, const char *value, - int mask; - int flag; - } allowed_auto_mounts[] = { -- { "proc", LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED }, -- { "proc:mixed", LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED }, -- { "proc:rw", LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_RW }, -- { "sys", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED }, -- { "sys:ro", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RO }, -- { "sys:mixed", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED }, -- { "sys:rw", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RW }, -- { "cgroup", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_NOSPEC }, -- { "cgroup:mixed", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_MIXED }, -- { "cgroup:ro", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RO }, -- { "cgroup:rw", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RW }, -- { "cgroup:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_NOSPEC | LXC_AUTO_CGROUP_FORCE }, -- { "cgroup:mixed:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_MIXED | LXC_AUTO_CGROUP_FORCE }, -- { "cgroup:ro:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RO | LXC_AUTO_CGROUP_FORCE }, -- { "cgroup:rw:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RW | LXC_AUTO_CGROUP_FORCE }, -- { "cgroup-full", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_NOSPEC }, -- { "cgroup-full:mixed", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_MIXED }, -- { "cgroup-full:ro", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RO }, -- { "cgroup-full:rw", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RW }, -- { "cgroup-full:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_NOSPEC | LXC_AUTO_CGROUP_FORCE }, -- { "cgroup-full:mixed:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_MIXED | LXC_AUTO_CGROUP_FORCE }, -- { "cgroup-full:ro:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RO | LXC_AUTO_CGROUP_FORCE }, -- { "cgroup-full:rw:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RW | LXC_AUTO_CGROUP_FORCE }, -- /* For adding anything that is just a single on/off, but has no -- * options: keep mask and flag identical and just define the enum -- * value as an unused bit so far -- */ -- { NULL, 0, 0 } -+ { "proc", LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED }, -+ { "proc:mixed", LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED }, -+ { "proc:rw", LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_RW }, -+ { "sys", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED }, -+ { "sys:ro", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RO }, -+ { "sys:mixed", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED }, -+ { "sys:rw", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RW }, -+ { "cgroup", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_NOSPEC }, -+ { "cgroup:mixed", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_MIXED }, -+ { "cgroup:ro", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RO }, -+ { "cgroup:rw", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RW }, -+ { "cgroup:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_NOSPEC | LXC_AUTO_CGROUP_FORCE }, -+ { "cgroup:mixed:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_MIXED | LXC_AUTO_CGROUP_FORCE }, -+ { "cgroup:ro:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RO | LXC_AUTO_CGROUP_FORCE }, -+ { "cgroup:rw:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RW | LXC_AUTO_CGROUP_FORCE }, -+ { "cgroup-full", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_NOSPEC }, -+ { "cgroup-full:mixed", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_MIXED }, -+ { "cgroup-full:ro", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RO }, -+ { "cgroup-full:rw", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RW }, -+ { "cgroup-full:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_NOSPEC | LXC_AUTO_CGROUP_FORCE }, -+ { "cgroup-full:mixed:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_MIXED | LXC_AUTO_CGROUP_FORCE }, -+ { "cgroup-full:ro:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RO | LXC_AUTO_CGROUP_FORCE }, -+ { "cgroup-full:rw:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RW | LXC_AUTO_CGROUP_FORCE }, -+ /* For adding anything that is just a single on/off, but has no -+ * options: keep mask and flag identical and just define the enum -+ * value as an unused bit so far -+ */ -+ { NULL, 0, 0 } - }; - - if (lxc_config_value_empty(value)) { -@@ -1696,7 +1698,7 @@ on_error: - } - - static int set_config_mount(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - char *mntelem; - struct lxc_list *mntlist; -@@ -1721,7 +1723,7 @@ static int set_config_mount(const char *key, const char *value, - } - - static int set_config_cap_keep(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - char *keepcaps, *token; - struct lxc_list *keeplist; -@@ -1763,7 +1765,7 @@ on_error: - } - - static int set_config_cap_drop(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - char *dropcaps, *token; - struct lxc_list *droplist; -@@ -1793,7 +1795,7 @@ static int set_config_cap_drop(const char *key, const char *value, - lxc_list_add_tail(&lxc_conf->caps, droplist); - } - -- ret = 0; -+ ret = 0; - - on_error: - free(dropcaps); -@@ -1802,13 +1804,13 @@ on_error: - } - - static int set_config_console_path(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - return set_config_path_item(&lxc_conf->console.path, value); - } - - static int set_config_console_rotate(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - if (lxc_config_value_empty(value)) { - lxc_conf->console.log_rotate = 0; -@@ -1831,13 +1833,13 @@ static int set_config_console_rotate(const char *key, const char *value, - } - - static int set_config_console_logfile(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - return set_config_path_item(&lxc_conf->console.log_path, value); - } - - static int set_config_console_buffer_size(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - int ret; - int64_t size; -@@ -1885,7 +1887,7 @@ static int set_config_console_buffer_size(const char *key, const char *value, - } - - static int set_config_console_size(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - int ret; - int64_t size; -@@ -1942,7 +1944,7 @@ int append_unexp_config_line(const char *line, struct lxc_conf *conf) - linelen = strlen(line); - while (conf->unexpanded_alloced <= len + linelen + 2) { - char *tmp = realloc(conf->unexpanded_config, -- conf->unexpanded_alloced + 1024); -+ conf->unexpanded_alloced + 1024); - if (!tmp) - return -1; - -@@ -2007,7 +2009,7 @@ out: - } - - static int set_config_includefiles(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - if (lxc_config_value_empty(value)) { - clr_config_includefiles(key, lxc_conf, NULL); -@@ -2021,7 +2023,7 @@ static int set_config_includefiles(const char *key, const char *value, - } - - static int set_config_rootfs_path(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - int ret; - char *dup, *tmp; -@@ -2064,13 +2066,13 @@ static int set_config_rootfs_path(const char *key, const char *value, - } - - static int set_config_rootfs_mount(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - return set_config_path_item(&lxc_conf->rootfs.mount, value); - } - - static int set_config_rootfs_options(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - int ret; - unsigned long mflags = 0, pflags = 0; -@@ -2095,7 +2097,7 @@ static int set_config_rootfs_options(const char *key, const char *value, - } - - static int set_config_uts_name(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct utsname *utsname; - -@@ -2121,7 +2123,7 @@ static int set_config_uts_name(const char *key, const char *value, - } - - static int set_config_namespace_clone(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - char *ns, *token; - int cloneflag = 0; -@@ -2156,7 +2158,7 @@ static int set_config_namespace_clone(const char *key, const char *value, - } - - static int set_config_namespace_keep(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - char *ns, *token; - int cloneflag = 0; -@@ -2191,7 +2193,7 @@ static int set_config_namespace_keep(const char *key, const char *value, - } - - static int set_config_namespace_share(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - int ns_idx; - const char *namespace; -@@ -2209,7 +2211,7 @@ static int set_config_namespace_share(const char *key, const char *value, - - /* isulad: set config for init args */ - static int set_config_init_args(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - int ret = 0; - char *tmp = NULL; -@@ -2219,8 +2221,8 @@ static int set_config_init_args(const char *key, const char *value, - if (ret || !new_value) - return ret; - -- tmp = realloc(lxc_conf->init_argv, (lxc_conf->init_argc + 1) * sizeof(char *)); -- if (!tmp) { -+ if (lxc_mem_realloc((void **)&tmp, (lxc_conf->init_argc + 1) * sizeof(char *), lxc_conf->init_argv, -+ (lxc_conf->init_argc) * sizeof(char *)) != 0) { - ERROR("Out of memory"); - free(new_value); - return -1; -@@ -2236,9 +2238,10 @@ static int set_config_init_args(const char *key, const char *value, - - /* isulad: set config for init groups */ - static int set_config_init_groups(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { -- char *groups, *token; -+ char *groups = NULL; -+ char *token = NULL; - int ret = -1; - - if (lxc_config_value_empty(value)) -@@ -2252,9 +2255,9 @@ static int set_config_init_groups(const char *key, const char *value, - * split these caps in a single element for the list. - */ - lxc_iterate_parts(token, groups, " \t") { -- gid_t *tmp; -- tmp = realloc(lxc_conf->init_groups, (lxc_conf->init_groups_len + 1) * sizeof(gid_t)); -- if (!tmp) { -+ gid_t *tmp = NULL; -+ if (lxc_mem_realloc((void **)&tmp, (lxc_conf->init_groups_len + 1) * sizeof(gid_t), lxc_conf->init_groups, -+ (lxc_conf->init_groups_len) * sizeof(gid_t)) != 0) { - ERROR("Out of memory"); - goto on_error; - } -@@ -2273,93 +2276,93 @@ on_error: - - /* isulad: set config for populate device */ - static int set_config_populate_device(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) --{ -- int ret = 0, major = 0, minor = 0; -- uid_t uid = (uid_t)-1; -- gid_t gid = (gid_t)-1; -- char name[PATH_MAX] = {0}; -- char type[3] = {0}; -- char *replace_value = NULL; -- mode_t filemode = 0; -- struct lxc_list *iter; -- struct lxc_list *dev_list = NULL; -- struct lxc_populate_devs *dev_elem = NULL; -- -- if (lxc_config_value_empty(value)) -- return lxc_clear_populate_devices(lxc_conf); -- -- /* lxc.populate.device = PATH_IN_CONTAINER:DEVICETYPE:MAJOR:MINOR:MODE:UID:GID -- * For e.g. lxc.populate.device = /dev/sda:b:8:0:0666:0:0 -- */ -- ret = sscanf(value, "%[^:]:%2[^:]:%i:%i:%i:%u:%u", name, type, &major, &minor, &filemode, &uid, &gid); -- if (ret != 7) -- return -1; -- -- /* find existing list element */ -- lxc_list_for_each(iter, &lxc_conf->populate_devs) { -- dev_elem = iter->elem; -- -- if (strcmp(name, dev_elem->name) != 0) -- continue; -- -- replace_value = strdup(type); -- if (!replace_value) -- return -1; -- -- free(dev_elem->type); -- dev_elem->type = replace_value; -- dev_elem->file_mode = filemode; -- dev_elem->maj = major; -- dev_elem->min = minor; -- dev_elem->uid = (uid_t)uid; -- dev_elem->gid = (gid_t)gid; -- return 0; -- } -- -- /* allocate list element */ -- dev_list = malloc(sizeof(*dev_list)); -- if (!dev_list) -- goto on_error; -- -- lxc_list_init(dev_list); -- -- dev_elem = malloc(sizeof(*dev_elem)); -- if (!dev_elem) -- goto on_error; -- memset(dev_elem, 0, sizeof(*dev_elem)); -- -- dev_elem->name = strdup(name); -- if (!dev_elem->name) -- goto on_error; -- -- dev_elem->type = strdup(type); -- if (!dev_elem->type) -- goto on_error; -- -- dev_elem->file_mode = filemode; -- dev_elem->maj = major; -- dev_elem->min = minor; -- -- lxc_list_add_elem(dev_list, dev_elem); -- -- lxc_list_add_tail(&lxc_conf->populate_devs, dev_list); -- -- return 0; -+ struct lxc_conf *lxc_conf, void *data) -+{ -+ int ret = 0, major = 0, minor = 0; -+ uid_t uid = (uid_t)-1; -+ gid_t gid = (gid_t)-1; -+ char name[PATH_MAX] = {0}; -+ char type[3] = {0}; -+ char *replace_value = NULL; -+ mode_t filemode = 0; -+ struct lxc_list *iter = NULL; -+ struct lxc_list *dev_list = NULL; -+ struct lxc_populate_devs *dev_elem = NULL; -+ -+ if (lxc_config_value_empty(value)) -+ return lxc_clear_populate_devices(lxc_conf); -+ -+ /* lxc.populate.device = PATH_IN_CONTAINER:DEVICETYPE:MAJOR:MINOR:MODE:UID:GID -+ * For e.g. lxc.populate.device = /dev/sda:b:8:0:0666:0:0 -+ */ -+ ret = sscanf(value, "%[^:]:%2[^:]:%i:%i:%i:%u:%u", name, type, &major, &minor, &filemode, &uid, &gid); -+ if (ret != 7) -+ return -1; -+ -+ /* find existing list element */ -+ lxc_list_for_each(iter, &lxc_conf->populate_devs) { -+ dev_elem = iter->elem; -+ -+ if (strcmp(name, dev_elem->name) != 0) -+ continue; -+ -+ replace_value = strdup(type); -+ if (!replace_value) -+ return -1; -+ -+ free(dev_elem->type); -+ dev_elem->type = replace_value; -+ dev_elem->file_mode = filemode; -+ dev_elem->maj = major; -+ dev_elem->min = minor; -+ dev_elem->uid = (uid_t)uid; -+ dev_elem->gid = (gid_t)gid; -+ return 0; -+ } -+ -+ /* allocate list element */ -+ dev_list = malloc(sizeof(*dev_list)); -+ if (!dev_list) -+ goto on_error; -+ -+ lxc_list_init(dev_list); -+ -+ dev_elem = malloc(sizeof(*dev_elem)); -+ if (!dev_elem) -+ goto on_error; -+ memset(dev_elem, 0, sizeof(*dev_elem)); -+ -+ dev_elem->name = strdup(name); -+ if (!dev_elem->name) -+ goto on_error; -+ -+ dev_elem->type = strdup(type); -+ if (!dev_elem->type) -+ goto on_error; -+ -+ dev_elem->file_mode = filemode; -+ dev_elem->maj = major; -+ dev_elem->min = minor; -+ -+ lxc_list_add_elem(dev_list, dev_elem); -+ -+ lxc_list_add_tail(&lxc_conf->populate_devs, dev_list); -+ -+ return 0; - - on_error: -- free(dev_list); -- if (dev_elem) { -- free(dev_elem->name); -- free(dev_elem->type); -- free(dev_elem); -- } -- return -1; -+ free(dev_list); -+ if (dev_elem) { -+ free(dev_elem->name); -+ free(dev_elem->type); -+ free(dev_elem); -+ } -+ return -1; - } - - /* isulad: set config for rootfs masked paths */ - static int set_config_rootfs_masked_paths(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_list *list_item = NULL; - -@@ -2387,7 +2390,7 @@ on_error: - - /* isulad: set config for rootfs ro paths */ - static int set_config_rootfs_ro_paths(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_list *list_item = NULL; - -@@ -2416,7 +2419,7 @@ on_error: - - /* isulad: set config for umask */ - static int set_config_umask(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - if (lxc_config_value_empty(value)) { - ERROR("Empty umask"); -@@ -2437,7 +2440,7 @@ static int set_config_umask(const char *key, const char *value, - - /* isulad: set config for systemd */ - static int set_config_systemd(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - if (lxc_config_value_empty(value)) { - ERROR("Empty umask"); -@@ -2673,32 +2676,32 @@ signed long lxc_config_parse_arch(const char *arch) - char *name; - unsigned long per; - } pername[] = { -- { "arm", PER_LINUX32 }, -- { "armel", PER_LINUX32 }, -- { "armhf", PER_LINUX32 }, -- { "armv7l", PER_LINUX32 }, -- { "athlon", PER_LINUX32 }, -- { "i386", PER_LINUX32 }, -- { "i486", PER_LINUX32 }, -- { "i586", PER_LINUX32 }, -- { "i686", PER_LINUX32 }, -- { "linux32", PER_LINUX32 }, -- { "mips", PER_LINUX32 }, -- { "mipsel", PER_LINUX32 }, -- { "ppc", PER_LINUX32 }, -- { "powerpc", PER_LINUX32 }, -- { "x86", PER_LINUX32 }, -- { "amd64", PER_LINUX }, -- { "arm64", PER_LINUX }, -- { "linux64", PER_LINUX }, -- { "mips64", PER_LINUX }, -- { "mips64el", PER_LINUX }, -- { "ppc64", PER_LINUX }, -- { "ppc64el", PER_LINUX }, -- { "ppc64le", PER_LINUX }, -- { "powerpc64", PER_LINUX }, -- { "s390x", PER_LINUX }, -- { "x86_64", PER_LINUX }, -+ { "arm", PER_LINUX32 }, -+ { "armel", PER_LINUX32 }, -+ { "armhf", PER_LINUX32 }, -+ { "armv7l", PER_LINUX32 }, -+ { "athlon", PER_LINUX32 }, -+ { "i386", PER_LINUX32 }, -+ { "i486", PER_LINUX32 }, -+ { "i586", PER_LINUX32 }, -+ { "i686", PER_LINUX32 }, -+ { "linux32", PER_LINUX32 }, -+ { "mips", PER_LINUX32 }, -+ { "mipsel", PER_LINUX32 }, -+ { "ppc", PER_LINUX32 }, -+ { "powerpc", PER_LINUX32 }, -+ { "x86", PER_LINUX32 }, -+ { "amd64", PER_LINUX }, -+ { "arm64", PER_LINUX }, -+ { "linux64", PER_LINUX }, -+ { "mips64", PER_LINUX }, -+ { "mips64el", PER_LINUX }, -+ { "ppc64", PER_LINUX }, -+ { "ppc64el", PER_LINUX }, -+ { "ppc64le", PER_LINUX }, -+ { "powerpc64", PER_LINUX }, -+ { "s390x", PER_LINUX }, -+ { "x86_64", PER_LINUX }, - }; - size_t len = sizeof(pername) / sizeof(pername[0]); - -@@ -2769,7 +2772,7 @@ int write_config(int fd, const struct lxc_conf *conf) - } - - bool do_append_unexp_config_line(struct lxc_conf *conf, const char *key, -- const char *v) -+ const char *v) - { - int ret; - size_t len; -@@ -2793,7 +2796,7 @@ bool do_append_unexp_config_line(struct lxc_conf *conf, const char *key, - } - - void clear_unexp_config_line(struct lxc_conf *conf, const char *key, -- bool rm_subkeys) -+ bool rm_subkeys) - { - char *lend; - char *lstart = conf->unexpanded_config; -@@ -2835,8 +2838,8 @@ void clear_unexp_config_line(struct lxc_conf *conf, const char *key, - } - - bool clone_update_unexp_ovl_paths(struct lxc_conf *conf, const char *oldpath, -- const char *newpath, const char *oldname, -- const char *newname, const char *ovldir) -+ const char *newpath, const char *oldname, -+ const char *newname, const char *ovldir) - { - int ret; - char *lend, *newdir, *olddir, *p, *q; -@@ -2847,14 +2850,14 @@ bool clone_update_unexp_ovl_paths(struct lxc_conf *conf, const char *oldpath, - olddirlen = strlen(ovldir) + strlen(oldpath) + strlen(oldname) + 2; - olddir = alloca(olddirlen + 1); - ret = snprintf(olddir, olddirlen + 1, "%s=%s/%s", ovldir, oldpath, -- oldname); -+ oldname); - if (ret < 0 || ret >= olddirlen + 1) - return false; - - newdirlen = strlen(ovldir) + strlen(newpath) + strlen(newname) + 2; - newdir = alloca(newdirlen + 1); - ret = snprintf(newdir, newdirlen + 1, "%s=%s/%s", ovldir, newpath, -- newname); -+ newname); - if (ret < 0 || ret >= newdirlen + 1) - return false; - -@@ -2935,7 +2938,7 @@ bool clone_update_unexp_ovl_paths(struct lxc_conf *conf, const char *oldpath, - lend += diff; - } - -- next: -+next: - lstart = lend; - } - -@@ -2943,8 +2946,8 @@ bool clone_update_unexp_ovl_paths(struct lxc_conf *conf, const char *oldpath, - } - - bool clone_update_unexp_hooks(struct lxc_conf *conf, const char *oldpath, -- const char *newpath, const char *oldname, -- const char *newname) -+ const char *newpath, const char *oldname, -+ const char *newname) - { - int ret; - char *lend, *newdir, *olddir, *p; -@@ -3029,7 +3032,7 @@ bool clone_update_unexp_hooks(struct lxc_conf *conf, const char *oldpath, - lend += diff; - } - -- next: -+next: - lstart = lend; - } - -@@ -3117,7 +3120,7 @@ bool network_new_hwaddrs(struct lxc_conf *conf) - } - - static int set_config_ephemeral(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - if (lxc_config_value_empty(value)) { - lxc_conf->ephemeral = 0; -@@ -3134,7 +3137,7 @@ static int set_config_ephemeral(const char *key, const char *value, - } - - static int set_config_log_syslog(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - int facility; - -@@ -3156,7 +3159,7 @@ static int set_config_log_syslog(const char *key, const char *value, - } - - static int set_config_no_new_privs(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - unsigned int v; - -@@ -3178,7 +3181,7 @@ static int set_config_no_new_privs(const char *key, const char *value, - - /* Callbacks to get configuration items. */ - static int get_config_personality(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int fulllen = 0; - -@@ -3206,53 +3209,53 @@ static int get_config_personality(const char *key, char *retv, int inlen, - } - - static int get_config_pty_max(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_size_t(c, retv, inlen, c->pty_max); - } - - static int get_config_tty_max(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_size_t(c, retv, inlen, c->ttys.max); - } - - /* isulad add: get umask value*/ - static int get_config_umask(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_size_t(c, retv, inlen, c->umask); - } - - /* isulad add: get systemd value*/ - static int get_config_systemd(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_str(retv, inlen, c->systemd); - } - - static int get_config_tty_dir(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_str(retv, inlen, c->ttys.dir); - } - - static int get_config_apparmor_profile(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_str(retv, inlen, c->lsm_aa_profile); - } - - static int get_config_apparmor_allow_incomplete(const char *key, char *retv, -- int inlen, struct lxc_conf *c, -- void *data) -+ int inlen, struct lxc_conf *c, -+ void *data) - { - return lxc_get_conf_int(c, retv, inlen, -- c->lsm_aa_allow_incomplete); -+ c->lsm_aa_allow_incomplete); - } - - static int get_config_selinux_context(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_str(retv, inlen, c->lsm_se_context); - } -@@ -3266,8 +3269,8 @@ static int get_config_selinux_context(const char *key, char *retv, int inlen, - * 'lxc.cgroup.subsystem.key = value' format. - */ - static int __get_config_cgroup_controller(const char *key, char *retv, -- int inlen, struct lxc_conf *c, -- int version) -+ int inlen, struct lxc_conf *c, -+ int version) - { - int len; - size_t namespaced_token_len; -@@ -3308,7 +3311,7 @@ static int __get_config_cgroup_controller(const char *key, char *retv, - continue; - - strprint(retv, inlen, "%s.%s = %s\n", global_token, -- cg->subsystem, cg->value); -+ cg->subsystem, cg->value); - } else if (strcmp(cg->subsystem, key) == 0) { - strprint(retv, inlen, "%s\n", cg->value); - } -@@ -3318,21 +3321,21 @@ static int __get_config_cgroup_controller(const char *key, char *retv, - } - - static int get_config_cgroup_controller(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return __get_config_cgroup_controller(key, retv, inlen, c, -- CGROUP_SUPER_MAGIC); -+ CGROUP_SUPER_MAGIC); - } - - static int get_config_cgroup2_controller(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return __get_config_cgroup_controller(key, retv, inlen, c, -- CGROUP2_SUPER_MAGIC); -+ CGROUP2_SUPER_MAGIC); - } - - static int get_config_cgroup_dir(const char *key, char *retv, int inlen, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - int len; - int fulllen = 0; -@@ -3348,31 +3351,31 @@ static int get_config_cgroup_dir(const char *key, char *retv, int inlen, - } - - static int get_config_idmaps(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - struct lxc_list *it; - int len, listlen, ret; - int fulllen = 0; --/* "u 1000 1000000 65536" -- * -- * let's render this as -- * -- * sizeof(char) -- * + -- * sizeof(" ") -- * + -- * sizeof(uint32_t) -- * + -- * sizeof(" ") -- * + -- * sizeof(uint32_t) -- * + -- * sizeof(" ") -- * + -- * sizeof(uint32_t) -- * + -- * \0 -- */ -+ /* "u 1000 1000000 65536" -+ * -+ * let's render this as -+ * -+ * sizeof(char) -+ * + -+ * sizeof(" ") -+ * + -+ * sizeof(uint32_t) -+ * + -+ * sizeof(" ") -+ * + -+ * sizeof(uint32_t) -+ * + -+ * sizeof(" ") -+ * + -+ * sizeof(uint32_t) -+ * + -+ * \0 -+ */ - #define __LXC_IDMAP_STR_BUF (3 * INTTYPE_TO_STRLEN(uint32_t) + 3 + 1 + 1) - char buf[__LXC_IDMAP_STR_BUF]; - -@@ -3385,8 +3388,8 @@ static int get_config_idmaps(const char *key, char *retv, int inlen, - lxc_list_for_each(it, &c->id_map) { - struct id_map *map = it->elem; - ret = snprintf(buf, __LXC_IDMAP_STR_BUF, "%c %lu %lu %lu", -- (map->idtype == ID_TYPE_UID) ? 'u' : 'g', -- map->nsid, map->hostid, map->range); -+ (map->idtype == ID_TYPE_UID) ? 'u' : 'g', -+ map->nsid, map->hostid, map->range); - if (ret < 0 || ret >= __LXC_IDMAP_STR_BUF) - return -1; - -@@ -3397,7 +3400,7 @@ static int get_config_idmaps(const char *key, char *retv, int inlen, - } - - static int get_config_log_level(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - const char *v; - v = lxc_log_priority_to_string(c->loglevel); -@@ -3405,19 +3408,19 @@ static int get_config_log_level(const char *key, char *retv, int inlen, - } - - static int get_config_log_file(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_str(retv, inlen, c->logfile); - } - - static int get_config_mount_fstab(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_str(retv, inlen, c->fstab); - } - - static int get_config_mount_auto(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len, fulllen = 0; - const char *sep = ""; -@@ -3493,7 +3496,7 @@ static int get_config_mount_auto(const char *key, char *retv, int inlen, - } - - static int get_config_mount(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len, fulllen = 0; - struct lxc_list *it; -@@ -3511,33 +3514,33 @@ static int get_config_mount(const char *key, char *retv, int inlen, - } - - static int get_config_rootfs_path(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_str(retv, inlen, c->rootfs.path); - } - - static int get_config_rootfs_mount(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_str(retv, inlen, c->rootfs.mount); - } - - static int get_config_rootfs_options(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_str(retv, inlen, c->rootfs.options); - } - - static int get_config_uts_name(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_str( -- retv, inlen, -- c->utsname ? c->utsname->nodename : NULL); -+ retv, inlen, -+ c->utsname ? c->utsname->nodename : NULL); - } - - static int get_config_hooks(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - char *subkey; - int len, fulllen = 0, found = -1; -@@ -3578,13 +3581,13 @@ static int get_config_hooks(const char *key, char *retv, int inlen, - } - - static int get_config_hooks_version(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_int(c, retv, inlen, c->hooks_version); - } - - static int get_config_net(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len, fulllen = 0; - struct lxc_list *it; -@@ -3604,7 +3607,7 @@ static int get_config_net(const char *key, char *retv, int inlen, - } - - static int get_config_cap_drop(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len, fulllen = 0; - struct lxc_list *it; -@@ -3622,7 +3625,7 @@ static int get_config_cap_drop(const char *key, char *retv, int inlen, - } - - static int get_config_cap_keep(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len, fulllen = 0; - struct lxc_list *it; -@@ -3640,70 +3643,70 @@ static int get_config_cap_keep(const char *key, char *retv, int inlen, - } - - static int get_config_console_path(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_str(retv, inlen, c->console.path); - } - - static int get_config_console_logfile(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_str(retv, inlen, c->console.log_path); - } - - static int get_config_console_rotate(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_int(c, retv, inlen, c->console.log_rotate); - } - - - static int get_config_console_buffer_size(const char *key, char *retv, -- int inlen, struct lxc_conf *c, -- void *data) -+ int inlen, struct lxc_conf *c, -+ void *data) - { - return lxc_get_conf_uint64(c, retv, inlen, c->console.buffer_size); - } - - static int get_config_console_size(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_uint64(c, retv, inlen, c->console.log_size); - } - - - static int get_config_seccomp_profile(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_str(retv, inlen, c->seccomp); - } - - static int get_config_autodev(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_int(c, retv, inlen, c->autodev); - } - - static int get_config_signal_halt(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_int(c, retv, inlen, c->haltsignal); - } - - static int get_config_signal_reboot(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_int(c, retv, inlen, c->rebootsignal); - } - - static int get_config_signal_stop(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_int(c, retv, inlen, c->stopsignal); - } - - static int get_config_start(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - if (strcmp(key + 10, "auto") == 0) - return lxc_get_conf_int(c, retv, inlen, c->start_auto); -@@ -3716,19 +3719,19 @@ static int get_config_start(const char *key, char *retv, int inlen, - } - - static int get_config_log_syslog(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_str(retv, inlen, c->syslog); - } - - static int get_config_monitor(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_int(c, retv, inlen, c->monitor_unshare); - } - - static int get_config_group(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len, fulllen = 0; - struct lxc_list *it; -@@ -3746,7 +3749,7 @@ static int get_config_group(const char *key, char *retv, int inlen, - } - - static int get_config_environment(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len, fulllen = 0; - struct lxc_list *it; -@@ -3765,43 +3768,43 @@ static int get_config_environment(const char *key, char *retv, int inlen, - } - - static int get_config_execute_cmd(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_str(retv, inlen, c->execute_cmd); - } - - static int get_config_init_cmd(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_str(retv, inlen, c->init_cmd); - } - - static int get_config_init_cwd(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_str(retv, inlen, c->init_cwd); - } - - static int get_config_init_uid(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_int(c, retv, inlen, c->init_uid); - } - - static int get_config_init_gid(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_int(c, retv, inlen, c->init_gid); - } - - static int get_config_ephemeral(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_int(c, retv, inlen, c->ephemeral); - } - - static int get_config_no_new_privs(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_get_conf_int(c, retv, inlen, c->no_new_privs); - } -@@ -3811,7 +3814,7 @@ static int get_config_no_new_privs(const char *key, char *retv, int inlen, - * printed, in 'lxc.prlimit.resource = value' format. - */ - static int get_config_prlimit(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int fulllen = 0, len; - bool get_all = false; -@@ -3840,7 +3843,7 @@ static int get_config_prlimit(const char *key, char *retv, int inlen, - partlen = STRLITERALLEN("unlimited"); - } else { - partlen = sprintf(buf, "%" PRIu64, -- (uint64_t)lim->limit.rlim_cur); -+ (uint64_t)lim->limit.rlim_cur); - } - - if (lim->limit.rlim_cur != lim->limit.rlim_max) { -@@ -3849,12 +3852,12 @@ static int get_config_prlimit(const char *key, char *retv, int inlen, - STRLITERALLEN(":unlimited") + 1); - else - sprintf(buf + partlen, ":%" PRIu64, -- (uint64_t)lim->limit.rlim_max); -+ (uint64_t)lim->limit.rlim_max); - } - - if (get_all) { - strprint(retv, inlen, "lxc.prlimit.%s = %s\n", -- lim->resource, buf); -+ lim->resource, buf); - } else if (strcmp(lim->resource, key) == 0) { - strprint(retv, inlen, "%s", buf); - } -@@ -3868,7 +3871,7 @@ static int get_config_prlimit(const char *key, char *retv, int inlen, - * entries will be printed, in 'lxc.sysctl.key = value' format. - */ - static int get_config_sysctl(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len; - struct lxc_list *it; -@@ -3891,7 +3894,7 @@ static int get_config_sysctl(const char *key, char *retv, int inlen, - struct lxc_sysctl *elem = it->elem; - if (get_all) { - strprint(retv, inlen, "lxc.sysctl.%s = %s\n", elem->key, -- elem->value); -+ elem->value); - } else if (strcmp(elem->key, key) == 0) { - strprint(retv, inlen, "%s", elem->value); - } -@@ -3901,7 +3904,7 @@ static int get_config_sysctl(const char *key, char *retv, int inlen, - } - - static int get_config_proc(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - struct lxc_list *it; - int len; -@@ -3935,7 +3938,7 @@ static int get_config_proc(const char *key, char *retv, int inlen, - } - - static int get_config_namespace_clone(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int i, len; - int fulllen = 0; -@@ -3954,7 +3957,7 @@ static int get_config_namespace_clone(const char *key, char *retv, int inlen, - } - - static int get_config_namespace_keep(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int i, len; - int fulllen = 0; -@@ -3973,7 +3976,7 @@ static int get_config_namespace_keep(const char *key, char *retv, int inlen, - } - - static int get_config_namespace_share(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len, ns_idx; - const char *namespace; -@@ -3996,7 +3999,7 @@ static int get_config_namespace_share(const char *key, char *retv, int inlen, - - /* isulad: get config init args */ - static int get_config_init_args(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int i, len, fulllen = 0; - -@@ -4006,7 +4009,7 @@ static int get_config_init_args(const char *key, char *retv, int inlen, - memset(retv, 0, inlen); - - for (i = 0; i < c->init_argc; i++) { -- strprint(retv, inlen, "%s", c->init_argv[i]); -+ strprint(retv, inlen, "%s", c->init_argv[i]); - } - - return fulllen; -@@ -4014,7 +4017,7 @@ static int get_config_init_args(const char *key, char *retv, int inlen, - - /* isulad: get config init groups */ - static int get_config_init_groups(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int i, len, fulllen = 0; - -@@ -4024,7 +4027,7 @@ static int get_config_init_groups(const char *key, char *retv, int inlen, - memset(retv, 0, inlen); - - for (i = 0; i < c->init_groups_len; i++) { -- strprint(retv, inlen, "%u\n", c->init_groups[i]); -+ strprint(retv, inlen, "%u\n", c->init_groups[i]); - } - - return fulllen; -@@ -4036,10 +4039,10 @@ static int get_config_init_groups(const char *key, char *retv, int inlen, - * For e.g. lxc.populate.device = /dev/sda:b:8:0:0666:0:0 - */ - static int get_config_populate_device(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len; -- struct lxc_list *it; -+ struct lxc_list *it = NULL; - int fulllen = 0; - - if (!retv) -@@ -4050,8 +4053,8 @@ static int get_config_populate_device(const char *key, char *retv, int inlen, - lxc_list_for_each(it, &c->populate_devs) { - struct lxc_populate_devs *elem = it->elem; - strprint(retv, inlen, "lxc.populate.device = %s:%s:%d:%d:%o:%u:%u\n", -- elem->name, elem->type, elem->maj, -- elem->min, elem->file_mode, elem->uid, elem->gid); -+ elem->name, elem->type, elem->maj, -+ elem->min, elem->file_mode, elem->uid, elem->gid); - } - - return fulllen; -@@ -4059,10 +4062,10 @@ static int get_config_populate_device(const char *key, char *retv, int inlen, - - // isulad: get config rootfs masked paths - static int get_config_rootfs_masked_paths(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len, fulllen = 0; -- struct lxc_list *it; -+ struct lxc_list *it = NULL; - - if (!retv) - inlen = 0; -@@ -4078,10 +4081,10 @@ static int get_config_rootfs_masked_paths(const char *key, char *retv, int inlen - - // isulad: get config rootfs ro paths - static int get_config_rootfs_ro_paths(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len, fulllen = 0; -- struct lxc_list *it; -+ struct lxc_list *it = NULL; - - if (!retv) - inlen = 0; -@@ -4097,28 +4100,28 @@ static int get_config_rootfs_ro_paths(const char *key, char *retv, int inlen, - - /* Callbacks to clear config items. */ - static inline int clr_config_personality(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - c->personality = -1; - return 0; - } - - static inline int clr_config_pty_max(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - c->pty_max = 0; - return 0; - } - - static inline int clr_config_tty_max(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - c->ttys.tty = 0; - return 0; - } - - static inline int clr_config_tty_dir(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - free(c->ttys.dir); - c->ttys.dir = NULL; -@@ -4126,7 +4129,7 @@ static inline int clr_config_tty_dir(const char *key, struct lxc_conf *c, - } - - static inline int clr_config_apparmor_profile(const char *key, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - free(c->lsm_aa_profile); - c->lsm_aa_profile = NULL; -@@ -4134,15 +4137,15 @@ static inline int clr_config_apparmor_profile(const char *key, - } - - static inline int clr_config_apparmor_allow_incomplete(const char *key, -- struct lxc_conf *c, -- void *data) -+ struct lxc_conf *c, -+ void *data) - { - c->lsm_aa_allow_incomplete = 0; - return 0; - } - - static inline int clr_config_selinux_context(const char *key, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - free(c->lsm_se_context); - c->lsm_se_context = NULL; -@@ -4150,19 +4153,19 @@ static inline int clr_config_selinux_context(const char *key, - } - - static inline int clr_config_cgroup_controller(const char *key, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_clear_cgroups(c, key, CGROUP_SUPER_MAGIC); - } - - static inline int clr_config_cgroup2_controller(const char *key, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return lxc_clear_cgroups(c, key, CGROUP2_SUPER_MAGIC); - } - - static int clr_config_cgroup_dir(const char *key, struct lxc_conf *lxc_conf, -- void *data) -+ void *data) - { - if (lxc_conf->cgroup_meta.dir) { - free(lxc_conf->cgroup_meta.dir); -@@ -4173,20 +4176,20 @@ static int clr_config_cgroup_dir(const char *key, struct lxc_conf *lxc_conf, - } - - static inline int clr_config_idmaps(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - return lxc_clear_idmaps(c); - } - - static inline int clr_config_log_level(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - c->loglevel = LXC_LOG_LEVEL_NOTSET; - return 0; - } - - static inline int clr_config_log_file(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - free(c->logfile); - c->logfile = NULL; -@@ -4194,19 +4197,19 @@ static inline int clr_config_log_file(const char *key, struct lxc_conf *c, - } - - static inline int clr_config_mount(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - return lxc_clear_mount_entries(c); - } - - static inline int clr_config_mount_auto(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - return lxc_clear_automounts(c); - } - - static inline int clr_config_mount_fstab(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - free(c->fstab); - c->fstab = NULL; -@@ -4214,7 +4217,7 @@ static inline int clr_config_mount_fstab(const char *key, struct lxc_conf *c, - } - - static inline int clr_config_rootfs_path(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - free(c->rootfs.path); - c->rootfs.path = NULL; -@@ -4222,7 +4225,7 @@ static inline int clr_config_rootfs_path(const char *key, struct lxc_conf *c, - } - - static inline int clr_config_rootfs_mount(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - free(c->rootfs.mount); - c->rootfs.mount = NULL; -@@ -4230,7 +4233,7 @@ static inline int clr_config_rootfs_mount(const char *key, struct lxc_conf *c, - } - - static inline int clr_config_rootfs_options(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - free(c->rootfs.options); - c->rootfs.options = NULL; -@@ -4242,7 +4245,7 @@ static inline int clr_config_rootfs_options(const char *key, struct lxc_conf *c, - } - - static inline int clr_config_uts_name(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - free(c->utsname); - c->utsname = NULL; -@@ -4250,13 +4253,13 @@ static inline int clr_config_uts_name(const char *key, struct lxc_conf *c, - } - - static inline int clr_config_hooks(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - return lxc_clear_hooks(c, key); - } - - static inline int clr_config_hooks_version(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - /* default to legacy hooks version */ - c->hooks_version = 0; -@@ -4264,7 +4267,7 @@ static inline int clr_config_hooks_version(const char *key, struct lxc_conf *c, - } - - static inline int clr_config_net(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - lxc_free_networks(&c->network); - -@@ -4272,19 +4275,19 @@ static inline int clr_config_net(const char *key, struct lxc_conf *c, - } - - static inline int clr_config_cap_drop(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - return lxc_clear_config_caps(c); - } - - static inline int clr_config_cap_keep(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - return lxc_clear_config_keepcaps(c); - } - - static inline int clr_config_console_path(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - free(c->console.path); - c->console.path = NULL; -@@ -4292,7 +4295,7 @@ static inline int clr_config_console_path(const char *key, struct lxc_conf *c, - } - - static inline int clr_config_console_logfile(const char *key, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - free(c->console.log_path); - c->console.log_path = NULL; -@@ -4300,28 +4303,28 @@ static inline int clr_config_console_logfile(const char *key, - } - - static inline int clr_config_console_rotate(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - c->console.log_rotate = 0; - return 0; - } - - static inline int clr_config_console_buffer_size(const char *key, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - c->console.buffer_size = 0; - return 0; - } - - static inline int clr_config_console_size(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - c->console.log_size = 0; - return 0; - } - - static inline int clr_config_seccomp_profile(const char *key, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - free(c->seccomp); - c->seccomp = NULL; -@@ -4329,35 +4332,35 @@ static inline int clr_config_seccomp_profile(const char *key, - } - - static inline int clr_config_autodev(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - c->autodev = 1; - return 0; - } - - static inline int clr_config_signal_halt(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - c->haltsignal = 0; - return 0; - } - - static inline int clr_config_signal_reboot(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - c->rebootsignal = 0; - return 0; - } - - static inline int clr_config_signal_stop(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - c->stopsignal = 0; - return 0; - } - - static inline int clr_config_start(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - if (strcmp(key + 10, "auto") == 0) - c->start_auto = 0; -@@ -4370,7 +4373,7 @@ static inline int clr_config_start(const char *key, struct lxc_conf *c, - } - - static inline int clr_config_log_syslog(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - free(c->syslog); - c->syslog = NULL; -@@ -4378,26 +4381,26 @@ static inline int clr_config_log_syslog(const char *key, struct lxc_conf *c, - } - - static inline int clr_config_monitor(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - c->monitor_unshare = 0; - return 0; - } - - static inline int clr_config_group(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - return lxc_clear_groups(c); - } - - static inline int clr_config_environment(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - return lxc_clear_environment(c); - } - - static inline int clr_config_execute_cmd(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - free(c->execute_cmd); - c->execute_cmd = NULL; -@@ -4405,7 +4408,7 @@ static inline int clr_config_execute_cmd(const char *key, struct lxc_conf *c, - } - - static inline int clr_config_init_cmd(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - free(c->init_cmd); - c->init_cmd = NULL; -@@ -4413,7 +4416,7 @@ static inline int clr_config_init_cmd(const char *key, struct lxc_conf *c, - } - - static inline int clr_config_init_cwd(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - free(c->init_cwd); - c->init_cwd = NULL; -@@ -4421,74 +4424,74 @@ static inline int clr_config_init_cwd(const char *key, struct lxc_conf *c, - } - - static inline int clr_config_init_uid(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - c->init_uid = 0; - return 0; - } - - static inline int clr_config_init_gid(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - c->init_gid = 0; - return 0; - } - - static inline int clr_config_ephemeral(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - c->ephemeral = 0; - return 0; - } - - static inline int clr_config_no_new_privs(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - c->no_new_privs = false; - return 0; - } - - static inline int clr_config_prlimit(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - return lxc_clear_limits(c, key); - } - - static inline int clr_config_sysctl(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - return lxc_clear_sysctls(c, key); - } - - static inline int clr_config_proc(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - return lxc_clear_procs(c, key); - } - - static inline int clr_config_includefiles(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - lxc_clear_includes(c); - return 0; - } - - static int clr_config_namespace_clone(const char *key, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - lxc_conf->ns_clone = 0; - return 0; - } - - static int clr_config_namespace_keep(const char *key, struct lxc_conf *lxc_conf, -- void *data) -+ void *data) - { - lxc_conf->ns_keep = 0; - return 0; - } - - static int clr_config_namespace_share(const char *key, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - int ns_idx; - const char *namespace; -@@ -4506,7 +4509,7 @@ static int clr_config_namespace_share(const char *key, - - /* isulad add: clear umask value */ - static inline int clr_config_umask(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - c->umask = 0027; - return 0; -@@ -4514,7 +4517,7 @@ static inline int clr_config_umask(const char *key, struct lxc_conf *c, - - /* isulad add: clear systemd value */ - static inline int clr_config_systemd(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - free(c->systemd); - c->systemd = NULL; -@@ -4522,15 +4525,15 @@ static inline int clr_config_systemd(const char *key, struct lxc_conf *c, - } - - static int get_config_includefiles(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - return -ENOSYS; - } - - static struct lxc_config_t *get_network_config_ops(const char *key, -- struct lxc_conf *lxc_conf, -- ssize_t *idx, -- char **deindexed_key) -+ struct lxc_conf *lxc_conf, -+ ssize_t *idx, -+ char **deindexed_key) - { - int ret; - unsigned int tmpidx; -@@ -4624,7 +4627,7 @@ on_error: - * rewriting the key), and call it. - */ - static int set_config_net_nic(const char *key, const char *value, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - int ret; - const char *idxstring; -@@ -4657,7 +4660,7 @@ static int set_config_net_nic(const char *key, const char *value, - } - - static int clr_config_net_nic(const char *key, struct lxc_conf *lxc_conf, -- void *data) -+ void *data) - { - int ret; - const char *idxstring; -@@ -4703,7 +4706,7 @@ static int clr_config_net_nic(const char *key, struct lxc_conf *lxc_conf, - } - - static int clr_config_net_type(const char *key, struct lxc_conf *lxc_conf, -- void *data) -+ void *data) - { - struct lxc_netdev *netdev = data; - -@@ -4716,7 +4719,7 @@ static int clr_config_net_type(const char *key, struct lxc_conf *lxc_conf, - } - - static int clr_config_net_name(const char *key, struct lxc_conf *lxc_conf, -- void *data) -+ void *data) - { - struct lxc_netdev *netdev = data; - -@@ -4729,7 +4732,7 @@ static int clr_config_net_name(const char *key, struct lxc_conf *lxc_conf, - } - - static int clr_config_net_flags(const char *key, struct lxc_conf *lxc_conf, -- void *data) -+ void *data) - { - struct lxc_netdev *netdev = data; - -@@ -4742,7 +4745,7 @@ static int clr_config_net_flags(const char *key, struct lxc_conf *lxc_conf, - } - - static int clr_config_net_link(const char *key, struct lxc_conf *lxc_conf, -- void *data) -+ void *data) - { - struct lxc_netdev *netdev = data; - -@@ -4755,7 +4758,7 @@ static int clr_config_net_link(const char *key, struct lxc_conf *lxc_conf, - } - - static int clr_config_net_macvlan_mode(const char *key, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_netdev *netdev = data; - -@@ -4771,7 +4774,7 @@ static int clr_config_net_macvlan_mode(const char *key, - } - - static int clr_config_net_veth_pair(const char *key, struct lxc_conf *lxc_conf, -- void *data) -+ void *data) - { - struct lxc_netdev *netdev = data; - -@@ -4784,7 +4787,7 @@ static int clr_config_net_veth_pair(const char *key, struct lxc_conf *lxc_conf, - } - - static int clr_config_net_script_up(const char *key, struct lxc_conf *lxc_conf, -- void *data) -+ void *data) - { - struct lxc_netdev *netdev = data; - -@@ -4798,7 +4801,7 @@ static int clr_config_net_script_up(const char *key, struct lxc_conf *lxc_conf, - } - - static int clr_config_net_script_down(const char *key, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_netdev *netdev = data; - -@@ -4812,7 +4815,7 @@ static int clr_config_net_script_down(const char *key, - } - - static int clr_config_net_hwaddr(const char *key, struct lxc_conf *lxc_conf, -- void *data) -+ void *data) - { - struct lxc_netdev *netdev = data; - -@@ -4826,7 +4829,7 @@ static int clr_config_net_hwaddr(const char *key, struct lxc_conf *lxc_conf, - } - - static int clr_config_net_mtu(const char *key, struct lxc_conf *lxc_conf, -- void *data) -+ void *data) - { - struct lxc_netdev *netdev = data; - -@@ -4840,7 +4843,7 @@ static int clr_config_net_mtu(const char *key, struct lxc_conf *lxc_conf, - } - - static int clr_config_net_vlan_id(const char *key, struct lxc_conf *lxc_conf, -- void *data) -+ void *data) - { - struct lxc_netdev *netdev = data; - -@@ -4853,7 +4856,7 @@ static int clr_config_net_vlan_id(const char *key, struct lxc_conf *lxc_conf, - } - - static int clr_config_net_ipv4_gateway(const char *key, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_netdev *netdev = data; - -@@ -4867,7 +4870,7 @@ static int clr_config_net_ipv4_gateway(const char *key, - } - - static int clr_config_net_ipv4_address(const char *key, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_netdev *netdev = data; - struct lxc_list *cur, *next; -@@ -4885,7 +4888,7 @@ static int clr_config_net_ipv4_address(const char *key, - } - - static int clr_config_net_ipv6_gateway(const char *key, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_netdev *netdev = data; - -@@ -4899,7 +4902,7 @@ static int clr_config_net_ipv6_gateway(const char *key, - } - - static int clr_config_net_ipv6_address(const char *key, -- struct lxc_conf *lxc_conf, void *data) -+ struct lxc_conf *lxc_conf, void *data) - { - struct lxc_netdev *netdev = data; - struct lxc_list *cur, *next; -@@ -4918,41 +4921,41 @@ static int clr_config_net_ipv6_address(const char *key, - - /* isulad: clr config init args*/ - static inline int clr_config_init_args(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - return lxc_clear_init_args(c); - } - - /* isulad: clr config init args*/ - static inline int clr_config_init_groups(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - return lxc_clear_init_groups(c); - } - - /* isulad: clr config populate devices*/ - static inline int clr_config_populate_device(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - return lxc_clear_populate_devices(c); - } - - /* isulad: clr config rootfs masked paths */ - static inline int clr_config_rootfs_masked_paths(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - return lxc_clear_rootfs_masked_paths(c); - } - - /* isulad: clr config rootfs ro paths */ - static inline int clr_config_rootfs_ro_paths(const char *key, struct lxc_conf *c, -- void *data) -+ void *data) - { - return lxc_clear_rootfs_ro_paths(c); - } - - static int get_config_net_nic(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int ret; - const char *idxstring; -@@ -4982,7 +4985,7 @@ static int get_config_net_nic(const char *key, char *retv, int inlen, - } - - static int get_config_net_type(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len; - int fulllen = 0; -@@ -5002,7 +5005,7 @@ static int get_config_net_type(const char *key, char *retv, int inlen, - } - - static int get_config_net_flags(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len; - int fulllen = 0; -@@ -5023,7 +5026,7 @@ static int get_config_net_flags(const char *key, char *retv, int inlen, - } - - static int get_config_net_link(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len; - int fulllen = 0; -@@ -5044,7 +5047,7 @@ static int get_config_net_link(const char *key, char *retv, int inlen, - } - - static int get_config_net_name(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len; - int fulllen = 0; -@@ -5065,7 +5068,7 @@ static int get_config_net_name(const char *key, char *retv, int inlen, - } - - static int get_config_net_macvlan_mode(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len; - int fulllen = 0; -@@ -5107,7 +5110,7 @@ static int get_config_net_macvlan_mode(const char *key, char *retv, int inlen, - } - - static int get_config_net_veth_pair(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len; - int fulllen = 0; -@@ -5125,15 +5128,15 @@ static int get_config_net_veth_pair(const char *key, char *retv, int inlen, - return 0; - - strprint(retv, inlen, "%s", -- netdev->priv.veth_attr.pair[0] != '\0' -- ? netdev->priv.veth_attr.pair -- : netdev->priv.veth_attr.veth1); -+ netdev->priv.veth_attr.pair[0] != '\0' -+ ? netdev->priv.veth_attr.pair -+ : netdev->priv.veth_attr.veth1); - - return fulllen; - } - - static int get_config_net_script_up(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len; - int fulllen = 0; -@@ -5154,7 +5157,7 @@ static int get_config_net_script_up(const char *key, char *retv, int inlen, - } - - static int get_config_net_script_down(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len; - int fulllen = 0; -@@ -5175,7 +5178,7 @@ static int get_config_net_script_down(const char *key, char *retv, int inlen, - } - - static int get_config_net_hwaddr(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len; - int fulllen = 0; -@@ -5196,7 +5199,7 @@ static int get_config_net_hwaddr(const char *key, char *retv, int inlen, - } - - static int get_config_net_mtu(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len; - int fulllen = 0; -@@ -5217,7 +5220,7 @@ static int get_config_net_mtu(const char *key, char *retv, int inlen, - } - - static int get_config_net_vlan_id(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len; - int fulllen = 0; -@@ -5240,7 +5243,7 @@ static int get_config_net_vlan_id(const char *key, char *retv, int inlen, - } - - static int get_config_net_ipv4_gateway(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len; - char buf[INET_ADDRSTRLEN]; -@@ -5266,7 +5269,7 @@ static int get_config_net_ipv4_gateway(const char *key, char *retv, int inlen, - } - - static int get_config_net_ipv4_address(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len; - size_t listlen; -@@ -5289,14 +5292,14 @@ static int get_config_net_ipv4_address(const char *key, char *retv, int inlen, - struct lxc_inetdev *i = it->elem; - inet_ntop(AF_INET, &i->addr, buf, sizeof(buf)); - strprint(retv, inlen, "%s/%u%s", buf, i->prefix, -- (listlen-- > 1) ? "\n" : ""); -+ (listlen-- > 1) ? "\n" : ""); - } - - return fulllen; - } - - static int get_config_net_ipv6_gateway(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len; - char buf[INET6_ADDRSTRLEN]; -@@ -5322,7 +5325,7 @@ static int get_config_net_ipv6_gateway(const char *key, char *retv, int inlen, - } - - static int get_config_net_ipv6_address(const char *key, char *retv, int inlen, -- struct lxc_conf *c, void *data) -+ struct lxc_conf *c, void *data) - { - int len; - size_t listlen; -@@ -5345,7 +5348,7 @@ static int get_config_net_ipv6_address(const char *key, char *retv, int inlen, - struct lxc_inet6dev *i = it->elem; - inet_ntop(AF_INET6, &i->addr, buf, sizeof(buf)); - strprint(retv, inlen, "%s/%u%s", buf, i->prefix, -- (listlen-- > 1) ? "\n" : ""); -+ (listlen-- > 1) ? "\n" : ""); - } - - return fulllen; -@@ -5375,7 +5378,7 @@ int lxc_list_config_items(char *retv, int inlen) - } - - int lxc_list_subkeys(struct lxc_conf *conf, const char *key, char *retv, -- int inlen) -+ int inlen) - { - int len; - int fulllen = 0; -diff --git a/src/lxc/confile_utils.c b/src/lxc/confile_utils.c -index 9049ce8..8c5208f 100644 ---- a/src/lxc/confile_utils.c -+++ b/src/lxc/confile_utils.c -@@ -46,7 +46,7 @@ - lxc_log_define(confile_utils, lxc); - - int parse_idmaps(const char *idmap, char *type, unsigned long *nsid, -- unsigned long *hostid, unsigned long *range) -+ unsigned long *hostid, unsigned long *range) - { - int ret = -1; - unsigned long tmp_hostid, tmp_nsid, tmp_range; -@@ -223,7 +223,7 @@ struct lxc_netdev *lxc_network_add(struct lxc_list *networks, int idx, bool tail - * allocates a new one if it couldn't be found. - */ - struct lxc_netdev *lxc_get_netdev_by_idx(struct lxc_conf *conf, -- unsigned int idx, bool allocate) -+ unsigned int idx, bool allocate) - { - struct lxc_netdev *netdev = NULL; - struct lxc_list *networks = &conf->network; -@@ -252,7 +252,7 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf) - struct lxc_list *it = (struct lxc_list *)&conf->network;; - - if ((conf->loglevel != LXC_LOG_LEVEL_TRACE) && -- (lxc_log_get_level() != LXC_LOG_LEVEL_TRACE)) -+ (lxc_log_get_level() != LXC_LOG_LEVEL_TRACE)) - return; - - if (lxc_list_empty(it)) { -@@ -294,7 +294,7 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf) - char *mode; - - mode = lxc_macvlan_flag_to_mode( -- netdev->priv.macvlan_attr.mode); -+ netdev->priv.macvlan_attr.mode); - TRACE("macvlan mode: %s", - mode ? mode : "(invalid mode)"); - } -@@ -348,14 +348,14 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf) - - if (netdev->ipv4_gateway) { - inet_ntop(AF_INET, netdev->ipv4_gateway, -- bufinet4, sizeof(bufinet4)); -+ bufinet4, sizeof(bufinet4)); - TRACE("ipv4 gateway: %s", bufinet4); - } - - lxc_list_for_each_safe(cur, &netdev->ipv4, next) { - inet4dev = cur->elem; - inet_ntop(AF_INET, &inet4dev->addr, bufinet4, -- sizeof(bufinet4)); -+ sizeof(bufinet4)); - TRACE("ipv4 addr: %s", bufinet4); - } - -@@ -364,14 +364,14 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf) - - if (netdev->ipv6_gateway) { - inet_ntop(AF_INET6, netdev->ipv6_gateway, -- bufinet6, sizeof(bufinet6)); -+ bufinet6, sizeof(bufinet6)); - TRACE("ipv6 gateway: %s", bufinet6); - } - - lxc_list_for_each_safe(cur, &netdev->ipv6, next) { - inet6dev = cur->elem; - inet_ntop(AF_INET6, &inet6dev->addr, bufinet6, -- sizeof(bufinet6)); -+ sizeof(bufinet6)); - TRACE("ipv6 addr: %s", bufinet6); - } - } -@@ -448,10 +448,10 @@ static struct lxc_macvlan_mode { - char *name; - int mode; - } macvlan_mode[] = { -- { "private", MACVLAN_MODE_PRIVATE }, -- { "vepa", MACVLAN_MODE_VEPA }, -- { "bridge", MACVLAN_MODE_BRIDGE }, -- { "passthru", MACVLAN_MODE_PASSTHRU }, -+ { "private", MACVLAN_MODE_PRIVATE }, -+ { "vepa", MACVLAN_MODE_VEPA }, -+ { "bridge", MACVLAN_MODE_BRIDGE }, -+ { "passthru", MACVLAN_MODE_PASSTHRU }, - }; - - int lxc_macvlan_mode_to_flag(int *mode, const char *value) -@@ -595,7 +595,7 @@ bool lxc_config_net_hwaddr(const char *line) - return true; - - if (sscanf(line, "lxc.net.%u.%6s", &index, tmp) == 2 || -- sscanf(line, "lxc.network.%u.%6s", &index, tmp) == 2) -+ sscanf(line, "lxc.network.%u.%6s", &index, tmp) == 2) - return strncmp(tmp, "hwaddr", 6) == 0; - - return false; -@@ -644,13 +644,13 @@ bool new_hwaddr(char *hwaddr) - seed = randseed(false); - - ret = snprintf(hwaddr, 18, "00:16:3e:%02x:%02x:%02x", rand_r(&seed) % 255, -- rand_r(&seed) % 255, rand_r(&seed) % 255); -+ rand_r(&seed) % 255, rand_r(&seed) % 255); - #else - - (void)randseed(true); - - ret = snprintf(hwaddr, 18, "00:16:3e:%02x:%02x:%02x", rand() % 255, -- rand() % 255, rand() % 255); -+ rand() % 255, rand() % 255); - #endif - if (ret < 0 || ret >= 18) { - SYSERROR("Failed to call snprintf()"); -@@ -740,7 +740,7 @@ bool parse_limit_value(const char **value, rlim_t *res) - } - - static int lxc_container_name_to_pid(const char *lxcname_or_pid, -- const char *lxcpath) -+ const char *lxcpath) - { - int ret; - signed long int pid; -@@ -784,16 +784,18 @@ static int lxc_container_name_to_pid(const char *lxcname_or_pid, - } - - int lxc_inherit_namespace(const char *lxcname_or_pid, const char *lxcpath, -- const char *namespace) -+ const char *namespace) - { -- int fd, pid; -- char *dup, *lastslash; -+ int fd = -1; -+ int pid = -1; -+ char *dup = NULL; -+ char *lastslash = NULL; - - /* isulad: add support share namespace by path. - * e.g. "lxc.namespace.share.net = /proc/PID/ns/net or /var/run/netns/net" - */ - if (file_exists(lxcname_or_pid) && !dir_exists(lxcname_or_pid)) { -- fd = open(lxcname_or_pid, O_RDONLY | O_CLOEXEC); -+ fd = lxc_open(lxcname_or_pid, O_RDONLY | O_CLOEXEC, 0); - if (fd < 0) - return -EINVAL; - -diff --git a/src/lxc/json/logger_json_file.c b/src/lxc/json/logger_json_file.c -index 6433b04..409ea11 100644 ---- a/src/lxc/json/logger_json_file.c -+++ b/src/lxc/json/logger_json_file.c -@@ -8,236 +8,236 @@ - #include "logger_json_file.h" - - logger_json_file *make_logger_json_file(yajl_val tree, struct parser_context *ctx, parser_error *err) { -- logger_json_file *ret = NULL; -- *err = 0; -- if (tree == NULL) -- return ret; -- ret = safe_malloc(sizeof(*ret)); -- { -- yajl_val tmp = get_val(tree, "log", yajl_t_string); -- if (tmp != NULL) { -- char *str = YAJL_GET_STRING(tmp); -- ret->log = (uint8_t *)safe_strdup(str ? str : ""); -- ret->log_len = str != NULL ? strlen(str) : 0; -- } -- } -- { -- yajl_val val = get_val(tree, "stream", yajl_t_string); -- if (val != NULL) { -- char *str = YAJL_GET_STRING(val); -- ret->stream = safe_strdup(str ? str : ""); -- } -- } -- { -- yajl_val val = get_val(tree, "time", yajl_t_string); -- if (val != NULL) { -- char *str = YAJL_GET_STRING(val); -- ret->time = safe_strdup(str ? str : ""); -- } -- } -- { -- yajl_val tmp = get_val(tree, "attrs", yajl_t_string); -- if (tmp != NULL) { -- char *str = YAJL_GET_STRING(tmp); -- ret->attrs = (uint8_t *)safe_strdup(str ? str : ""); -- ret->attrs_len = str != NULL ? strlen(str) : 0; -- } -- } -- -- if (tree->type == yajl_t_object && (ctx->options & PARSE_OPTIONS_STRICT)) { -- int i; -- for (i = 0; i < tree->u.object.len; i++) -- if (strcmp(tree->u.object.keys[i], "log") && -- strcmp(tree->u.object.keys[i], "stream") && -- strcmp(tree->u.object.keys[i], "time") && -- strcmp(tree->u.object.keys[i], "attrs")) { -- if (ctx->stderr > 0) -- fprintf(ctx->stderr, "WARNING: unknown key found: %s\n", tree->u.object.keys[i]); -- } -- } -- return ret; -+ logger_json_file *ret = NULL; -+ *err = 0; -+ if (tree == NULL) -+ return ret; -+ ret = safe_malloc(sizeof(*ret)); -+ { -+ yajl_val tmp = get_val(tree, "log", yajl_t_string); -+ if (tmp != NULL) { -+ char *str = YAJL_GET_STRING(tmp); -+ ret->log = (uint8_t *)safe_strdup(str ? str : ""); -+ ret->log_len = str != NULL ? strlen(str) : 0; -+ } -+ } -+ { -+ yajl_val val = get_val(tree, "stream", yajl_t_string); -+ if (val != NULL) { -+ char *str = YAJL_GET_STRING(val); -+ ret->stream = safe_strdup(str ? str : ""); -+ } -+ } -+ { -+ yajl_val val = get_val(tree, "time", yajl_t_string); -+ if (val != NULL) { -+ char *str = YAJL_GET_STRING(val); -+ ret->time = safe_strdup(str ? str : ""); -+ } -+ } -+ { -+ yajl_val tmp = get_val(tree, "attrs", yajl_t_string); -+ if (tmp != NULL) { -+ char *str = YAJL_GET_STRING(tmp); -+ ret->attrs = (uint8_t *)safe_strdup(str ? str : ""); -+ ret->attrs_len = str != NULL ? strlen(str) : 0; -+ } -+ } -+ -+ if (tree->type == yajl_t_object && (ctx->options & PARSE_OPTIONS_STRICT)) { -+ int i; -+ for (i = 0; i < tree->u.object.len; i++) -+ if (strcmp(tree->u.object.keys[i], "log") && -+ strcmp(tree->u.object.keys[i], "stream") && -+ strcmp(tree->u.object.keys[i], "time") && -+ strcmp(tree->u.object.keys[i], "attrs")) { -+ if (ctx->stderr > 0) -+ fprintf(ctx->stderr, "WARNING: unknown key found: %s\n", tree->u.object.keys[i]); -+ } -+ } -+ return ret; - } - - void free_logger_json_file(logger_json_file *ptr) { -- if (ptr == NULL) -- return; -- free(ptr->log); -- ptr->log = NULL; -- free(ptr->stream); -- ptr->stream = NULL; -- free(ptr->time); -- ptr->time = NULL; -- free(ptr->attrs); -- ptr->attrs = NULL; -- free(ptr); -+ if (ptr == NULL) -+ return; -+ free(ptr->log); -+ ptr->log = NULL; -+ free(ptr->stream); -+ ptr->stream = NULL; -+ free(ptr->time); -+ ptr->time = NULL; -+ free(ptr->attrs); -+ ptr->attrs = NULL; -+ free(ptr); - } - - yajl_gen_status gen_logger_json_file(yajl_gen g, logger_json_file *ptr, struct parser_context *ctx, parser_error *err) { -- yajl_gen_status stat = yajl_gen_status_ok; -- *err = 0; -- stat = reformat_start_map(g); -- if (yajl_gen_status_ok != stat) -- GEN_SET_ERROR_AND_RETURN(stat, err); -- if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) || (ptr != NULL && ptr->log != NULL && ptr->log_len)) { -- const char *str = ""; -- size_t len = 0; -- stat = reformat_map_key(g, "log", strlen("log")); -- if (yajl_gen_status_ok != stat) -- GEN_SET_ERROR_AND_RETURN(stat, err); -- if (ptr != NULL && ptr->log != NULL) { -- str = (const char *)ptr->log; -- len = ptr->log_len; -- } -- stat = reformat_string(g, str, len); -- if (yajl_gen_status_ok != stat) -- GEN_SET_ERROR_AND_RETURN(stat, err); -- } -- if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->stream != NULL)) { -- char *str = ""; -- stat = reformat_map_key(g, "stream", strlen("stream")); -- if (yajl_gen_status_ok != stat) -- GEN_SET_ERROR_AND_RETURN(stat, err); -- if (ptr != NULL && ptr->stream != NULL) { -- str = ptr->stream; -- } -- stat = reformat_string(g, str, strlen(str)); -- if (yajl_gen_status_ok != stat) -- GEN_SET_ERROR_AND_RETURN(stat, err); -- } -- if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->time != NULL)) { -- char *str = ""; -- stat = reformat_map_key(g, "time", strlen("time")); -- if (yajl_gen_status_ok != stat) -- GEN_SET_ERROR_AND_RETURN(stat, err); -- if (ptr != NULL && ptr->time != NULL) { -- str = ptr->time; -- } -- stat = reformat_string(g, str, strlen(str)); -- if (yajl_gen_status_ok != stat) -- GEN_SET_ERROR_AND_RETURN(stat, err); -- } -- if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) || (ptr != NULL && ptr->attrs != NULL && ptr->attrs_len)) { -- const char *str = ""; -- size_t len = 0; -- stat = reformat_map_key(g, "attrs", strlen("attrs")); -- if (yajl_gen_status_ok != stat) -- GEN_SET_ERROR_AND_RETURN(stat, err); -- if (ptr != NULL && ptr->attrs != NULL) { -- str = (const char *)ptr->attrs; -- len = ptr->attrs_len; -- } -- stat = reformat_string(g, str, len); -- if (yajl_gen_status_ok != stat) -- GEN_SET_ERROR_AND_RETURN(stat, err); -- } -- stat = reformat_end_map(g); -- if (yajl_gen_status_ok != stat) -- GEN_SET_ERROR_AND_RETURN(stat, err); -- return yajl_gen_status_ok; -+ yajl_gen_status stat = yajl_gen_status_ok; -+ *err = 0; -+ stat = reformat_start_map(g); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) || (ptr != NULL && ptr->log != NULL && ptr->log_len)) { -+ const char *str = ""; -+ size_t len = 0; -+ stat = reformat_map_key(g, "log", strlen("log")); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (ptr != NULL && ptr->log != NULL) { -+ str = (const char *)ptr->log; -+ len = ptr->log_len; -+ } -+ stat = reformat_string(g, str, len); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->stream != NULL)) { -+ char *str = ""; -+ stat = reformat_map_key(g, "stream", strlen("stream")); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (ptr != NULL && ptr->stream != NULL) { -+ str = ptr->stream; -+ } -+ stat = reformat_string(g, str, strlen(str)); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) ||(ptr != NULL && ptr->time != NULL)) { -+ char *str = ""; -+ stat = reformat_map_key(g, "time", strlen("time")); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (ptr != NULL && ptr->time != NULL) { -+ str = ptr->time; -+ } -+ stat = reformat_string(g, str, strlen(str)); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ if ((ctx->options & GEN_OPTIONS_ALLKEYVALUE) || (ptr != NULL && ptr->attrs != NULL && ptr->attrs_len)) { -+ const char *str = ""; -+ size_t len = 0; -+ stat = reformat_map_key(g, "attrs", strlen("attrs")); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ if (ptr != NULL && ptr->attrs != NULL) { -+ str = (const char *)ptr->attrs; -+ len = ptr->attrs_len; -+ } -+ stat = reformat_string(g, str, len); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ } -+ stat = reformat_end_map(g); -+ if (yajl_gen_status_ok != stat) -+ GEN_SET_ERROR_AND_RETURN(stat, err); -+ return yajl_gen_status_ok; - } - - - logger_json_file *logger_json_file_parse_file(const char *filename, struct parser_context *ctx, parser_error *err) { -- logger_json_file *ptr; -- size_t filesize; -- char *content = NULL; -- -- if (filename == NULL || err == NULL) -- return NULL; -- -- *err = NULL; -- content = read_file(filename, &filesize); -- if (content == NULL) { -- if (asprintf(err, "cannot read the file: %s", filename) < 0) -- *err = safe_strdup("error allocating memory"); -- return NULL; -- } -- ptr = logger_json_file_parse_data(content, ctx, err); -- free(content); -- return ptr; -+ logger_json_file *ptr = NULL; -+ size_t filesize; -+ char *content = NULL; -+ -+ if (filename == NULL || err == NULL) -+ return NULL; -+ -+ *err = NULL; -+ content = read_file(filename, &filesize); -+ if (content == NULL) { -+ if (asprintf(err, "cannot read the file: %s", filename) < 0) -+ *err = safe_strdup("error allocating memory"); -+ return NULL; -+ } -+ ptr = logger_json_file_parse_data(content, ctx, err); -+ free(content); -+ return ptr; - } - - logger_json_file *logger_json_file_parse_file_stream(FILE *stream, struct parser_context *ctx, parser_error *err) { -- logger_json_file *ptr; -- size_t filesize; -- char *content = NULL ; -- -- if (stream == NULL || err == NULL) -- return NULL; -- -- *err = NULL; -- content = fread_file(stream, &filesize); -- if (content == NULL) { -- *err = safe_strdup("cannot read the file"); -- return NULL; -- } -- ptr = logger_json_file_parse_data(content, ctx, err); -- free(content); -- return ptr; -+ logger_json_file *ptr = NULL; -+ size_t filesize; -+ char *content = NULL ; -+ -+ if (stream == NULL || err == NULL) -+ return NULL; -+ -+ *err = NULL; -+ content = fread_file(stream, &filesize); -+ if (content == NULL) { -+ *err = safe_strdup("cannot read the file"); -+ return NULL; -+ } -+ ptr = logger_json_file_parse_data(content, ctx, err); -+ free(content); -+ return ptr; - } - - logger_json_file *logger_json_file_parse_data(const char *jsondata, struct parser_context *ctx, parser_error *err) { -- logger_json_file *ptr; -- yajl_val tree; -- char errbuf[1024]; -- struct parser_context tmp_ctx; -- -- if (jsondata == NULL || err == NULL) -- return NULL; -- -- *err = NULL; -- if (ctx == NULL) { -- ctx = &tmp_ctx; -- memset(&tmp_ctx, 0, sizeof(tmp_ctx)); -- } -- tree = yajl_tree_parse(jsondata, errbuf, sizeof(errbuf)); -- if (tree == NULL) { -- if (asprintf(err, "cannot parse the data: %s", errbuf) < 0) -- *err = safe_strdup("error allocating memory"); -- return NULL; -- } -- ptr = make_logger_json_file(tree, ctx, err); -- yajl_tree_free(tree); -- return ptr; -+ logger_json_file *ptr = NULL; -+ yajl_val tree; -+ char errbuf[1024]; -+ struct parser_context tmp_ctx; -+ -+ if (jsondata == NULL || err == NULL) -+ return NULL; -+ -+ *err = NULL; -+ if (ctx == NULL) { -+ ctx = &tmp_ctx; -+ memset(&tmp_ctx, 0, sizeof(tmp_ctx)); -+ } -+ tree = yajl_tree_parse(jsondata, errbuf, sizeof(errbuf)); -+ if (tree == NULL) { -+ if (asprintf(err, "cannot parse the data: %s", errbuf) < 0) -+ *err = safe_strdup("error allocating memory"); -+ return NULL; -+ } -+ ptr = make_logger_json_file(tree, ctx, err); -+ yajl_tree_free(tree); -+ return ptr; - } - char *logger_json_file_generate_json(logger_json_file *ptr, struct parser_context *ctx, parser_error *err) { -- yajl_gen g = NULL; -- struct parser_context tmp_ctx; -- const unsigned char *gen_buf = NULL; -- char *json_buf = NULL; -- size_t gen_len = 0; -- -- if (ptr == NULL || err == NULL) -- return NULL; -- -- *err = NULL; -- if (ctx == NULL) { -- ctx = &tmp_ctx; -- memset(&tmp_ctx, 0, sizeof(tmp_ctx)); -- } -- -- if (!json_gen_init(&g, ctx)) { -- *err = safe_strdup("Json_gen init failed"); -- goto out; -- } -- if (yajl_gen_status_ok != gen_logger_json_file(g, ptr, ctx, err)) { -- if (*err == NULL) -- *err = safe_strdup("Failed to generate json"); -- goto free_out; -- } -- yajl_gen_get_buf(g, &gen_buf, &gen_len); -- if (gen_buf == NULL) { -- *err = safe_strdup("Error to get generated json"); -- goto free_out; -- } -- -- json_buf = safe_malloc(gen_len + 1); -- memcpy(json_buf, gen_buf, gen_len); -- json_buf[gen_len] = '\0'; -+ yajl_gen g = NULL; -+ struct parser_context tmp_ctx; -+ const unsigned char *gen_buf = NULL; -+ char *json_buf = NULL; -+ size_t gen_len = 0; -+ -+ if (ptr == NULL || err == NULL) -+ return NULL; -+ -+ *err = NULL; -+ if (ctx == NULL) { -+ ctx = &tmp_ctx; -+ memset(&tmp_ctx, 0, sizeof(tmp_ctx)); -+ } -+ -+ if (!json_gen_init(&g, ctx)) { -+ *err = safe_strdup("Json_gen init failed"); -+ goto out; -+ } -+ if (yajl_gen_status_ok != gen_logger_json_file(g, ptr, ctx, err)) { -+ if (*err == NULL) -+ *err = safe_strdup("Failed to generate json"); -+ goto free_out; -+ } -+ yajl_gen_get_buf(g, &gen_buf, &gen_len); -+ if (gen_buf == NULL) { -+ *err = safe_strdup("Error to get generated json"); -+ goto free_out; -+ } -+ -+ json_buf = safe_malloc(gen_len + 1); -+ memcpy(json_buf, gen_buf, gen_len); -+ json_buf[gen_len] = '\0'; - - free_out: -- yajl_gen_clear(g); -- yajl_gen_free(g); -+ yajl_gen_clear(g); -+ yajl_gen_free(g); - out: -- return json_buf; -+ return json_buf; - } -diff --git a/src/lxc/json/read-file.c b/src/lxc/json/read-file.c -index ad0eda1..70e73e5 100644 ---- a/src/lxc/json/read-file.c -+++ b/src/lxc/json/read-file.c -@@ -16,79 +16,80 @@ - - char *fread_file(FILE *stream, size_t *length) - { -- char *buf = NULL, *tmpbuf = NULL; -- size_t off = 0; -- -- while (1) { -- size_t ret, newsize; -- -- newsize = off + BUFSIZ + 1; -- tmpbuf = (char *)calloc(1, newsize); -- if (tmpbuf == NULL) { -- goto out; -- } -- -- if (buf) { -- memcpy(tmpbuf, buf, off); -- -- memset(buf, 0, off); -- -- free(buf); -- } -- -- buf = tmpbuf; -- ret = fread(buf + off, 1, BUFSIZ, stream); -- if (!ret && ferror(stream)) { -- tmpbuf = NULL; -- goto out; -- } -- if (ret < BUFSIZ || feof(stream)) { -- *length = off + ret + 1; -- buf[*length - 1] = '\0'; -- return buf; -- } -- off += BUFSIZ; -- } -+ char *buf = NULL, *tmpbuf = NULL; -+ size_t off = 0; -+ -+ while (1) { -+ size_t ret, newsize; -+ -+ newsize = off + BUFSIZ + 1; -+ tmpbuf = (char *)calloc(1, newsize); -+ if (tmpbuf == NULL) { -+ goto out; -+ } -+ -+ if (buf) { -+ memcpy(tmpbuf, buf, off); -+ -+ memset(buf, 0, off); -+ -+ free(buf); -+ } -+ -+ buf = tmpbuf; -+ ret = fread(buf + off, 1, BUFSIZ, stream); -+ if (!ret && ferror(stream)) { -+ tmpbuf = NULL; -+ goto out; -+ } -+ if (ret < BUFSIZ || feof(stream)) { -+ *length = off + ret + 1; -+ buf[*length - 1] = '\0'; -+ return buf; -+ } -+ off += BUFSIZ; -+ } - out: -- if (buf) { -- free(buf); -- } -- if (tmpbuf) { -- free(tmpbuf); -- } -- return NULL; -+ if (buf) { -+ free(buf); -+ } -+ if (tmpbuf) { -+ free(tmpbuf); -+ } -+ return NULL; - - } - - char *read_file(const char *path, size_t *length) - { -- char *buf = NULL; -- char rpath[PATH_MAX + 1] = {0}; -- int fd, tmperrno; -- FILE *fp; -- -- if (!path || !length) { -- return NULL; -- } -- -- if (strlen(path) > PATH_MAX || NULL == realpath(path, rpath)) { -- return NULL; -- } -- -- fd = open(rpath, O_RDONLY | O_CLOEXEC, 0640); -- if (fd < 0) { -- return NULL; -- } -- -- fp = fdopen(fd, "r"); -- tmperrno = errno; -- if (!fp) { -- close(fd); -- errno = tmperrno; -- return NULL; -- } -- -- buf = fread_file(fp, length); -- fclose(fp); -- return buf; -+ char *buf = NULL; -+ char rpath[PATH_MAX + 1] = {0}; -+ int fd = -1; -+ int tmperrno; -+ FILE *fp = NULL; -+ -+ if (!path || !length) { -+ return NULL; -+ } -+ -+ if (strlen(path) > PATH_MAX || NULL == realpath(path, rpath)) { -+ return NULL; -+ } -+ -+ fd = open(rpath, O_RDONLY | O_CLOEXEC, 0640); -+ if (fd < 0) { -+ return NULL; -+ } -+ -+ fp = fdopen(fd, "r"); -+ tmperrno = errno; -+ if (!fp) { -+ close(fd); -+ errno = tmperrno; -+ return NULL; -+ } -+ -+ buf = fread_file(fp, length); -+ fclose(fp); -+ return buf; - } -diff --git a/src/lxc/log.c b/src/lxc/log.c -index 91fb7ef..e598a5f 100644 ---- a/src/lxc/log.c -+++ b/src/lxc/log.c -@@ -157,7 +157,7 @@ static int isulad_open_fifo(const char *file_path) - #define LOG_FIFO_SIZE (1024 * 1024) - int fd = -1; - -- fd = lxc_unpriv(open(file_path, O_RDWR | O_NONBLOCK | O_CLOEXEC, 0640)); -+ fd = lxc_unpriv(lxc_open(file_path, O_RDWR | O_NONBLOCK | O_CLOEXEC, 0640)); - if (fd == -1) { - fprintf(stderr, "Open fifo %s failed: %s\n", file_path, strerror(errno)); - return -1; -@@ -174,7 +174,7 @@ static int isulad_open_fifo(const char *file_path) - - /*---------------------------------------------------------------------------*/ - static int log_append_syslog(const struct lxc_log_appender *appender, -- struct lxc_log_event *event) -+ struct lxc_log_event *event) - { - char *msg; - const char *log_container_name; -@@ -189,7 +189,7 @@ static int log_append_syslog(const struct lxc_log_appender *appender, - return 0; - - syslog(lxc_log_priority_to_syslog(event->priority), -- "%s%s %s - %s:%s:%d - %s" , -+ "%s%s %s - %s:%s:%d - %s", - log_container_name ? log_container_name : "", - log_container_name ? ":" : "", - event->category, -@@ -203,7 +203,7 @@ static int log_append_syslog(const struct lxc_log_appender *appender, - - /*---------------------------------------------------------------------------*/ - static int log_append_stderr(const struct lxc_log_appender *appender, -- struct lxc_log_event *event) -+ struct lxc_log_event *event) - { - const char *log_container_name; - -@@ -227,7 +227,7 @@ static int log_append_stderr(const struct lxc_log_appender *appender, - static int lxc_unix_epoch_to_utc(char *buf, size_t bufsize, const struct timespec *time) - { - int64_t epoch_to_days, z, era, doe, yoe, year, doy, mp, day, month, -- d_in_s, hours, h_in_s, minutes, seconds; -+ d_in_s, hours, h_in_s, minutes, seconds; - char nanosec[INTTYPE_TO_STRLEN(int64_t)]; - int ret; - -@@ -313,9 +313,9 @@ static int lxc_unix_epoch_to_utc(char *buf, size_t bufsize, const struct timespe - * digit precision. - */ - ret = snprintf(buf, bufsize, -- "%" PRId64 "%02" PRId64 "%02" PRId64 "%02" PRId64 -- "%02" PRId64 "%02" PRId64 ".%.3s", -- year, month, day, hours, minutes, seconds, nanosec); -+ "%" PRId64 "%02" PRId64 "%02" PRId64 "%02" PRId64 -+ "%02" PRId64 "%02" PRId64 ".%.3s", -+ year, month, day, hours, minutes, seconds, nanosec); - if (ret < 0 || (size_t)ret >= bufsize) - return -1; - -@@ -343,15 +343,15 @@ static int lxc_unix_epoch_to_utc(char *buf, size_t bufsize, const struct timespe - * to make it pretty. Pretty might cost you thread-safety. - */ - static int log_append_logfile(const struct lxc_log_appender *appender, -- struct lxc_log_event *event) -+ struct lxc_log_event *event) - { - char buffer[LXC_LOG_BUFFER_SIZE]; - char date_time[LXC_LOG_TIME_SIZE]; - int n; - ssize_t ret; - int fd_to_use = -1; -- const char *log_container_name; -- const char *isulad_prefix; -+ const char *log_container_name = NULL; -+ const char *isulad_prefix = NULL; - size_t isulad_len = 0; - - #ifndef NO_LXC_CONF -@@ -377,13 +377,13 @@ static int log_append_logfile(const struct lxc_log_appender *appender, - } - isulad_prefix = log_container_name ? (log_container_name + isulad_len) : log_prefix; - n = snprintf(buffer, sizeof(buffer), -- "%15s %s %-8s %s - %s:%s:%d - ", -- isulad_prefix, -- date_time, -- lxc_log_priority_to_string(event->priority), -- event->category, -- event->locinfo->file, event->locinfo->func, -- event->locinfo->line); -+ "%15s %s %-8s %s - %s:%s:%d - ", -+ isulad_prefix, -+ date_time, -+ lxc_log_priority_to_string(event->priority), -+ event->category, -+ event->locinfo->file, event->locinfo->func, -+ event->locinfo->line); - if (n < 0) - return n; - -@@ -405,7 +405,7 @@ static int log_append_logfile(const struct lxc_log_appender *appender, - - #if HAVE_DLOG - static int log_append_dlog(const struct lxc_log_appender *appender, -- struct lxc_log_event *event) -+ struct lxc_log_event *event) - { - char *msg = lxc_log_get_va_msg(event); - const char *log_container_name = lxc_log_get_container_name(); -@@ -643,10 +643,10 @@ static int __lxc_log_set_file(const char *fname, int create_dirs) - */ - if (create_dirs) - #endif -- if (build_dir(fname)) { -- SYSERROR("Failed to create dir for log file \"%s\"", fname); -- return -1; -- } -+ if (build_dir(fname)) { -+ SYSERROR("Failed to create dir for log file \"%s\"", fname); -+ return -1; -+ } - - if (isulad_use_log_fifo_flag) { - lxc_log_fd = isulad_open_fifo(fname); -@@ -685,7 +685,7 @@ int lxc_log_init(struct lxc_log *log) - { - int ret; - int lxc_priority = LXC_LOG_LEVEL_ERROR; -- const char *tmp_log_fname; -+ const char *tmp_log_fname = NULL; - - if (!log) - return -1; -diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index e0c4de3..e32f524 100644 ---- a/src/lxc/lxccontainer.c -+++ b/src/lxc/lxccontainer.c -@@ -111,7 +111,7 @@ static const char *lxcapi_get_config_path(struct lxc_container *c); - #define do_lxcapi_get_config_path(c) lxcapi_get_config_path(c) - static bool do_lxcapi_set_config_item(struct lxc_container *c, const char *key, const char *v); - static bool container_destroy(struct lxc_container *c, -- struct lxc_storage *storage); -+ struct lxc_storage *storage); - static bool get_snappath_dir(struct lxc_container *c, char *snappath); - static bool lxcapi_snapshot_destroy_all(struct lxc_container *c); - static bool do_lxcapi_save_config(struct lxc_container *c, const char *alt_file); -@@ -551,7 +551,7 @@ static int do_lxcapi_console_getfd(struct lxc_container *c, int *ttynum, int *ma - WRAP_API_2(int, lxcapi_console_getfd, int *, int *) - - static int lxcapi_console(struct lxc_container *c, int ttynum, int stdinfd, -- int stdoutfd, int stderrfd, int escape) -+ int stdoutfd, int stderrfd, int escape) - { - int ret; - -@@ -619,7 +619,7 @@ static bool load_config_locked(struct lxc_container *c, const char *fname) - static bool load_ocihooks_locked(struct lxc_container *c) - { - parser_error err = NULL; -- oci_runtime_spec_hooks *hooks; -+ oci_runtime_spec_hooks *hooks = NULL; - - if (!c->lxc_conf) - c->lxc_conf = lxc_conf_init(); -@@ -755,7 +755,7 @@ static bool do_lxcapi_want_close_all_fds(struct lxc_container *c, bool state) - WRAP_API_1(bool, lxcapi_want_close_all_fds, bool) - - static bool do_lxcapi_wait(struct lxc_container *c, const char *state, -- int timeout) -+ int timeout) - { - int ret; - -@@ -833,7 +833,7 @@ static char **split_init_cmd(const char *incmd) - - argv[0] = NULL; - lxc_iterate_parts(p, copy, " ") -- push_arg(&argv, p, &nargs); -+ push_arg(&argv, p, &nargs); - - if (nargs == 0) { - free(argv); -@@ -1116,7 +1116,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a - keepfds[2] = handler->state_socket_pair[1]; - keepfds[4] = conf->errpipe[1]; - ret = lxc_check_inherited(conf, true, keepfds, -- sizeof(keepfds) / sizeof(keepfds[0])); -+ sizeof(keepfds) / sizeof(keepfds[0])); - if (ret < 0) - _exit(EXIT_FAILURE); - -@@ -1176,7 +1176,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a - - /* isulad: open exit fifo */ - if (c->exit_fifo) { -- conf->exit_fd = open(c->exit_fifo, O_WRONLY | O_NONBLOCK | O_CLOEXEC); -+ 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)); - ret = 1; -@@ -1226,7 +1226,7 @@ reboot: - if (c->daemonize) - keepfds[4] = conf->errpipe[1]; - ret = lxc_check_inherited(conf, c->daemonize, keepfds, -- sizeof(keepfds) / sizeof(keepfds[0])); -+ sizeof(keepfds) / sizeof(keepfds[0])); - if (ret < 0) { - lxc_free_handler(handler); - ret = 1; -@@ -1235,12 +1235,12 @@ reboot: - - if (useinit) { - ret = lxc_execute(c->name, argv, 1, handler, c->config_path, -- c->daemonize, &c->error_num, c->start_timeout); -+ c->daemonize, &c->error_num, c->start_timeout); - } else { - handler->disable_pty = c->disable_pty; - handler->open_stdin = c->open_stdin; - ret = lxc_start(c->name, argv, handler, c->config_path, -- c->daemonize, &c->error_num, c->start_timeout); -+ c->daemonize, &c->error_num, c->start_timeout); - } - - if (conf->reboot == REBOOT_REQ) { -@@ -1269,7 +1269,7 @@ on_error: - } - - static bool lxcapi_start(struct lxc_container *c, int useinit, -- char *const argv[]) -+ char *const argv[]) - { - bool ret; - -@@ -1390,8 +1390,8 @@ static bool create_container_dir(struct lxc_container *c) - * storage_create(), it returns a mounted bdev on success, NULL on error. - */ - static struct lxc_storage *do_storage_create(struct lxc_container *c, -- const char *type, -- struct bdev_specs *specs) -+ const char *type, -+ struct bdev_specs *specs) - { - int ret; - size_t len; -@@ -1400,7 +1400,7 @@ static struct lxc_storage *do_storage_create(struct lxc_container *c, - - /* rootfs.path or lxcpath/lxcname/rootfs */ - if (c->lxc_conf->rootfs.path && -- (access(c->lxc_conf->rootfs.path, F_OK) == 0)) { -+ (access(c->lxc_conf->rootfs.path, F_OK) == 0)) { - const char *rpath = c->lxc_conf->rootfs.path; - len = strlen(rpath) + 1; - dest = alloca(len); -@@ -1454,7 +1454,7 @@ static char *lxcbasename(char *path) - } - - static bool create_run_template(struct lxc_container *c, char *tpath, -- bool need_null_stdfds, char *const argv[]) -+ bool need_null_stdfds, char *const argv[]) - { - int ret; - pid_t pid; -@@ -1515,7 +1515,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, - } - - if (strcmp(bdev->type, "overlay") == 0 || -- strcmp(bdev->type, "overlayfs") == 0) { -+ strcmp(bdev->type, "overlayfs") == 0) { - /* If we create an overlay container we need to - * rsync the contents into - * //rootfs. -@@ -1535,7 +1535,9 @@ static bool create_run_template(struct lxc_container *c, char *tpath, - */ - char *src; - -- src = ovl_get_rootfs(bdev->src, &(size_t){0}); -+ src = ovl_get_rootfs(bdev->src, &(size_t) { -+ 0 -+ }); - if (!src) { - ERROR("Failed to get rootfs"); - _exit(EXIT_FAILURE); -@@ -1654,8 +1656,8 @@ static bool create_run_template(struct lxc_container *c, char *tpath, - _exit(EXIT_FAILURE); - - ret = snprintf(n2[n2args - 1], 200, "%c:%lu:%lu:%lu", -- map->idtype == ID_TYPE_UID ? 'u' : 'g', -- map->nsid, map->hostid, map->range); -+ map->idtype == ID_TYPE_UID ? 'u' : 'g', -+ map->nsid, map->hostid, map->range); - if (ret < 0 || ret >= 200) - _exit(EXIT_FAILURE); - } -@@ -1682,7 +1684,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, - } - - ret = snprintf(n2[n2args - 1], 200, "u:%d:%d:1", -- hostuid_mapped, geteuid()); -+ hostuid_mapped, geteuid()); - if (ret < 0 || ret >= 200) - _exit(EXIT_FAILURE); - } -@@ -1709,7 +1711,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, - } - - ret = snprintf(n2[n2args - 1], 200, "g:%d:%d:1", -- hostgid_mapped, getegid()); -+ hostgid_mapped, getegid()); - if (ret < 0 || ret >= 200) - _exit(EXIT_FAILURE); - } -@@ -1915,8 +1917,8 @@ static void lxcapi_clear_config(struct lxc_container *c) - * arguments, you can just pass NULL. - */ - static bool do_lxcapi_create(struct lxc_container *c, const char *t, -- const char *bdevtype, struct bdev_specs *specs, -- int flags, char *const argv[]) -+ const char *bdevtype, struct bdev_specs *specs, -+ int flags, char *const argv[]) - { - int partial_fd; - mode_t mask; -@@ -1940,7 +1942,7 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t, - * existing container. Return an error, but do NOT delete the container. - */ - if (do_lxcapi_is_defined(c) && c->lxc_conf && c->lxc_conf->rootfs.path && -- access(c->lxc_conf->rootfs.path, F_OK) == 0 && tpath) { -+ access(c->lxc_conf->rootfs.path, F_OK) == 0 && tpath) { - ERROR("Container \"%s\" already exists in \"%s\"", c->name, - c->config_path); - goto free_tpath; -@@ -2072,8 +2074,8 @@ free_tpath: - } - - static bool lxcapi_create(struct lxc_container *c, const char *t, -- const char *bdevtype, struct bdev_specs *specs, -- int flags, char *const argv[]) -+ const char *bdevtype, struct bdev_specs *specs, -+ int flags, char *const argv[]) - { - bool ret; - -@@ -2140,7 +2142,7 @@ static bool do_lxcapi_reboot2(struct lxc_container *c, int timeout) - if (timeout != 0) { - states[RUNNING] = 2; - ret = lxc_cmd_add_state_client(c->name, c->config_path, states, -- &state_client_fd); -+ &state_client_fd); - if (ret < 0) - return false; - -@@ -2209,7 +2211,7 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout) - if (timeout != 0) { - states[STOPPED] = 1; - ret = lxc_cmd_add_state_client(c->name, c->config_path, states, -- &state_client_fd); -+ &state_client_fd); - if (ret < 0) - return false; - -@@ -2252,7 +2254,7 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout) - WRAP_API_1(bool, lxcapi_shutdown, int) - - static bool lxcapi_createl(struct lxc_container *c, const char *t, -- const char *bdevtype, struct bdev_specs *specs, int flags, ...) -+ const char *bdevtype, struct bdev_specs *specs, int flags, ...) - { - bool bret = false; - char **args = NULL; -@@ -2300,7 +2302,9 @@ static void do_clear_unexp_config_line(struct lxc_conf *conf, const char *key) - const char *idx; - - idx = key + 8; -- ret = lxc_safe_uint(idx, &(unsigned int){0}); -+ ret = lxc_safe_uint(idx, &(unsigned int) { -+ 0 -+ }); - if (!ret) - return clear_unexp_config_line(conf, key, true); - } -@@ -2312,7 +2316,7 @@ static void do_clear_unexp_config_line(struct lxc_conf *conf, const char *key) - } - - static bool do_lxcapi_clear_config_item(struct lxc_container *c, -- const char *key) -+ const char *key) - { - int ret = 1; - struct lxc_config_t *config; -@@ -2344,7 +2348,7 @@ static inline bool enter_net_ns(struct lxc_container *c) - pid_t pid = do_lxcapi_init_pid(c); - - if ((geteuid() != 0 || (c->lxc_conf && !lxc_list_empty(&c->lxc_conf->id_map))) && -- (access("/proc/self/ns/user", F_OK) == 0)) -+ (access("/proc/self/ns/user", F_OK) == 0)) - if (!switch_to_ns(pid, "user")) - return false; - -@@ -2359,7 +2363,7 @@ static inline int string_cmp(char **first, char **second) - - /* Used by qsort and bsearch functions for comparing container names. */ - static inline int container_cmp(struct lxc_container **first, -- struct lxc_container **second) -+ struct lxc_container **second) - { - return strcmp((*first)->name, (*second)->name); - } -@@ -2385,7 +2389,7 @@ static bool add_to_array(char ***names, char *cname, int pos) - } - - static bool add_to_clist(struct lxc_container ***list, struct lxc_container *c, -- int pos, bool sort) -+ int pos, bool sort) - { - struct lxc_container **newlist = realloc(*list, (pos + 1) * sizeof(struct lxc_container *)); - if (!newlist) { -@@ -2459,14 +2463,16 @@ static char **do_lxcapi_get_interfaces(struct lxc_container *c) - } - - /* Grab the list of interfaces */ -- if (netns_getifaddrs(&interfaceArray, -1, &(bool){false})) { -+ if (netns_getifaddrs(&interfaceArray, -1, &(bool) { -+ false -+ })) { - SYSERROR("Failed to get interfaces list"); - goto out; - } - - /* Iterate through the interfaces */ - for (tempIfAddr = interfaceArray; tempIfAddr != NULL; -- tempIfAddr = tempIfAddr->ifa_next) { -+ tempIfAddr = tempIfAddr->ifa_next) { - nbytes = lxc_write_nointr(pipefd[1], tempIfAddr->ifa_name, IFNAMSIZ); - if (nbytes < 0) - goto out; -@@ -2476,7 +2482,7 @@ static char **do_lxcapi_get_interfaces(struct lxc_container *c) - - ret = 0; - -- out: -+out: - if (interfaceArray) - netns_freeifaddrs(interfaceArray); - -@@ -2521,7 +2527,7 @@ static char **do_lxcapi_get_interfaces(struct lxc_container *c) - WRAP_API(char **, lxcapi_get_interfaces) - - static char **do_lxcapi_get_ips(struct lxc_container *c, const char *interface, -- const char *family, int scope) -+ const char *family, int scope) - { - int i, ret; - pid_t pid; -@@ -2561,14 +2567,16 @@ static char **do_lxcapi_get_ips(struct lxc_container *c, const char *interface, - } - - /* Grab the list of interfaces */ -- if (netns_getifaddrs(&interfaceArray, -1, &(bool){false})) { -+ if (netns_getifaddrs(&interfaceArray, -1, &(bool) { -+ false -+ })) { - SYSERROR("Failed to get interfaces list"); - goto out; - } - - /* Iterate through the interfaces */ - for (tempIfAddr = interfaceArray; tempIfAddr; -- tempIfAddr = tempIfAddr->ifa_next) { -+ tempIfAddr = tempIfAddr->ifa_next) { - if (tempIfAddr->ifa_addr == NULL) - continue; - -@@ -2598,15 +2606,15 @@ static char **do_lxcapi_get_ips(struct lxc_container *c, const char *interface, - continue; - - address = (char *)inet_ntop(tempIfAddr->ifa_addr->sa_family, -- tempAddrPtr, addressOutputBuffer, -- sizeof(addressOutputBuffer)); -+ tempAddrPtr, addressOutputBuffer, -+ sizeof(addressOutputBuffer)); - if (!address) - continue; - - nbytes = lxc_write_nointr(pipefd[1], address, INET6_ADDRSTRLEN); - if (nbytes != INET6_ADDRSTRLEN) { - SYSERROR("Failed to send ipv6 address \"%s\"", -- address); -+ address); - goto out; - } - -@@ -2615,7 +2623,7 @@ static char **do_lxcapi_get_ips(struct lxc_container *c, const char *interface, - - ret = 0; - -- out: -+out: - if (interfaceArray) - netns_freeifaddrs(interfaceArray); - -@@ -2766,7 +2774,7 @@ static bool do_lxcapi_save_config(struct lxc_container *c, const char *alt_file) - return false; - - fd = open(alt_file, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, -- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); -+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); - if (fd < 0) - goto on_error; - -@@ -2926,7 +2934,7 @@ void mod_all_rdeps(struct lxc_container *c, bool inc) - int ret; - - ret = snprintf(path, PATH_MAX, "%s/%s/lxc_rdepends", -- c->config_path, c->name); -+ c->config_path, c->name); - if (ret < 0 || ret >= PATH_MAX) { - ERROR("Path name too long"); - return; -@@ -2947,13 +2955,13 @@ void mod_all_rdeps(struct lxc_container *c, bool inc) - - if ((p = lxc_container_new(lxcname, lxcpath)) == NULL) { - ERROR("Unable to find dependent container %s:%s", -- lxcpath, lxcname); -+ lxcpath, lxcname); - continue; - } - - if (!mod_rdep(p, c, inc)) - ERROR("Failed to update snapshots file for %s:%s", -- lxcpath, lxcname); -+ lxcpath, lxcname); - - lxc_container_put(p); - } -@@ -2973,7 +2981,7 @@ static bool has_fs_snapshots(struct lxc_container *c) - bool bret = false; - - ret = snprintf(path, PATH_MAX, "%s/%s/lxc_snapshots", c->config_path, -- c->name); -+ c->name); - if (ret < 0 || ret > PATH_MAX) - goto out; - -@@ -3033,7 +3041,7 @@ static bool do_destroy_container(struct lxc_conf *conf) { - - if (am_guest_unpriv()) { - ret = userns_exec_full(conf, storage_destroy_wrapper, conf, -- "storage_destroy_wrapper"); -+ "storage_destroy_wrapper"); - if (ret < 0) - return false; - -@@ -3056,7 +3064,7 @@ static int lxc_unlink_exec_wrapper(void *data) - } - - static bool container_destroy(struct lxc_container *c, -- struct lxc_storage *storage) -+ struct lxc_storage *storage) - { - const char *p1; - size_t len; -@@ -3154,15 +3162,15 @@ static bool container_destroy(struct lxc_container *c, - * cannot be removed when restoring from a snapshot. - */ - if (storage && (!strcmp(storage->type, "overlay") || -- !strcmp(storage->type, "overlayfs")) && -- (storage->flags & LXC_STORAGE_INTERNAL_OVERLAY_RESTORE)) { -+ !strcmp(storage->type, "overlayfs")) && -+ (storage->flags & LXC_STORAGE_INTERNAL_OVERLAY_RESTORE)) { - ret = snprintf(path, len, "%s/%s/config", p1, c->name); - if (ret < 0 || (size_t)ret >= len) - goto out; - - if (am_guest_unpriv()) - ret = userns_exec_1(conf, lxc_unlink_exec_wrapper, path, -- "lxc_unlink_exec_wrapper"); -+ "lxc_unlink_exec_wrapper"); - else - ret = unlink(path); - if (ret < 0) { -@@ -3182,7 +3190,7 @@ static bool container_destroy(struct lxc_container *c, - - if (am_guest_unpriv()) - ret = userns_exec_full(conf, lxc_rmdir_onedev_wrapper, path, -- "lxc_rmdir_onedev_wrapper"); -+ "lxc_rmdir_onedev_wrapper"); - else - ret = lxc_rmdir_onedev(path, "snaps"); - if (ret < 0) { -@@ -3245,7 +3253,7 @@ static bool do_lxcapi_destroy_with_snapshots(struct lxc_container *c) - WRAP_API(bool, lxcapi_destroy_with_snapshots) - - int lxc_set_config_item_locked(struct lxc_conf *conf, const char *key, -- const char *v) -+ const char *v) - { - int ret; - struct lxc_config_t *config; -@@ -3270,7 +3278,7 @@ int lxc_set_config_item_locked(struct lxc_conf *conf, const char *key, - } - - static bool do_set_config_item_locked(struct lxc_container *c, const char *key, -- const char *v) -+ const char *v) - { - int ret; - -@@ -3360,7 +3368,7 @@ static bool set_config_filename(struct lxc_container *c) - static bool set_oci_hook_config_filename(struct lxc_container *c) - { - #define OCI_HOOK_JSON_FILE_NAME "ocihooks.json" -- char *newpath; -+ char *newpath = NULL; - int len, ret; - - if (!c->config_path) -@@ -3466,7 +3474,7 @@ static int do_lxcapi_get_cgroup_item(struct lxc_container *c, const char *subsys - return -1; - - ret = cgroup_ops->get(cgroup_ops, subsys, retv, inlen, c->name, -- c->config_path); -+ c->config_path); - - cgroup_exit(cgroup_ops); - -@@ -3578,7 +3586,7 @@ static int copyhooks(struct lxc_container *oldc, struct lxc_container *c) - - /* copy the script, and change the entry in confile */ - ret = snprintf(tmppath, PATH_MAX, "%s/%s/%s", -- c->config_path, c->name, fname+1); -+ c->config_path, c->name, fname+1); - if (ret < 0 || ret >= PATH_MAX) - return -1; - -@@ -3597,7 +3605,7 @@ static int copyhooks(struct lxc_container *oldc, struct lxc_container *c) - } - - if (!clone_update_unexp_hooks(c->lxc_conf, oldc->config_path, -- c->config_path, oldc->name, c->name)) { -+ c->config_path, oldc->name, c->name)) { - ERROR("Error saving new hooks in clone"); - return -1; - } -@@ -3623,7 +3631,7 @@ static int copy_fstab(struct lxc_container *oldc, struct lxc_container *c) - return -1; - - ret = snprintf(newpath, PATH_MAX, "%s/%s%s", -- c->config_path, c->name, p); -+ c->config_path, c->name, p); - if (ret < 0 || ret >= PATH_MAX) { - ERROR("error printing new path for %s", oldpath); - return -1; -@@ -3661,14 +3669,14 @@ static void copy_rdepends(struct lxc_container *c, struct lxc_container *c0) - int ret; - - ret = snprintf(path0, PATH_MAX, "%s/%s/lxc_rdepends", c0->config_path, -- c0->name); -+ c0->name); - if (ret < 0 || ret >= PATH_MAX) { - WARN("Error copying reverse dependencies"); - return; - } - - ret = snprintf(path1, PATH_MAX, "%s/%s/lxc_rdepends", c->config_path, -- c->name); -+ c->name); - if (ret < 0 || ret >= PATH_MAX) { - WARN("Error copying reverse dependencies"); - return; -@@ -3688,7 +3696,7 @@ static bool add_rdepends(struct lxc_container *c, struct lxc_container *c0) - bool bret; - - ret = snprintf(path, PATH_MAX, "%s/%s/lxc_rdepends", c->config_path, -- c->name); -+ c->name); - if (ret < 0 || ret >= PATH_MAX) - return false; - -@@ -3714,7 +3722,7 @@ static bool add_rdepends(struct lxc_container *c, struct lxc_container *c0) - * Currently we only do this for btrfs. - */ - bool should_default_to_snapshot(struct lxc_container *c0, -- struct lxc_container *c1) -+ struct lxc_container *c1) - { - int ret; - size_t l0 = strlen(c0->config_path) + strlen(c0->name) + 2; -@@ -3741,8 +3749,8 @@ bool should_default_to_snapshot(struct lxc_container *c0, - } - - static int copy_storage(struct lxc_container *c0, struct lxc_container *c, -- const char *newtype, int flags, const char *bdevdata, -- uint64_t newsize) -+ const char *newtype, int flags, const char *bdevdata, -+ uint64_t newsize) - { - struct lxc_storage *bdev; - bool need_rdep; -@@ -3751,7 +3759,7 @@ static int copy_storage(struct lxc_container *c0, struct lxc_container *c, - flags |= LXC_CLONE_SNAPSHOT; - - bdev = storage_copy(c0, c->name, c->config_path, newtype, flags, -- bdevdata, newsize, &need_rdep); -+ bdevdata, newsize, &need_rdep); - if (!bdev) { - ERROR("Error copying storage."); - return -1; -@@ -3770,7 +3778,7 @@ static int copy_storage(struct lxc_container *c0, struct lxc_container *c, - /* Append a new lxc.rootfs.path entry to the unexpanded config. */ - clear_unexp_config_line(c->lxc_conf, "lxc.rootfs.path", false); - if (!do_append_unexp_config_line(c->lxc_conf, "lxc.rootfs.path", -- c->lxc_conf->rootfs.path)) { -+ c->lxc_conf->rootfs.path)) { - ERROR("Error saving new rootfs to cloned config."); - return -1; - } -@@ -3940,9 +3948,9 @@ static int create_file_dirname(char *path, struct lxc_conf *conf) - } - - static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char *newname, -- const char *lxcpath, int flags, -- const char *bdevtype, const char *bdevdata, uint64_t newsize, -- char **hookargs) -+ const char *lxcpath, int flags, -+ const char *bdevtype, const char *bdevdata, uint64_t newsize, -+ char **hookargs) - { - char newpath[PATH_MAX]; - int fd, ret; -@@ -3995,7 +4003,7 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char - } - - fd = open(newpath, O_WRONLY | O_CREAT | O_CLOEXEC, -- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); -+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); - if (fd < 0) { - SYSERROR("Failed to open \"%s\"", newpath); - goto out; -@@ -4033,7 +4041,7 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char - * snapshot. - */ - if (errno != ENOENT && -- !(flags & LXC_STORAGE_INTERNAL_OVERLAY_RESTORE)) { -+ !(flags & LXC_STORAGE_INTERNAL_OVERLAY_RESTORE)) { - SYSERROR("Failed to create directory \"%s\"", newpath); - goto out; - } -@@ -4049,7 +4057,7 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char - c2 = lxc_container_new(newname, lxcpath); - if (!c2) { - ERROR("clone: failed to create new container (%s %s)", newname, -- lxcpath); -+ lxcpath); - goto out; - } - -@@ -4122,7 +4130,7 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char - - if (am_guest_unpriv()) - ret = userns_exec_full(c->lxc_conf, clone_update_rootfs_wrapper, -- &data, "clone_update_rootfs_wrapper"); -+ &data, "clone_update_rootfs_wrapper"); - else - ret = clone_update_rootfs(&data); - if (ret < 0) -@@ -4145,9 +4153,9 @@ out: - } - - static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *newname, -- const char *lxcpath, int flags, -- const char *bdevtype, const char *bdevdata, uint64_t newsize, -- char **hookargs) -+ const char *lxcpath, int flags, -+ const char *bdevtype, const char *bdevdata, uint64_t newsize, -+ char **hookargs) - { - struct lxc_container * ret; - -@@ -4331,7 +4339,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile) - * created in the original container - */ - flags = LXC_CLONE_SNAPSHOT | LXC_CLONE_KEEPMACADDR | LXC_CLONE_KEEPNAME | -- LXC_CLONE_KEEPBDEVTYPE | LXC_CLONE_MAYBE_SNAPSHOT; -+ LXC_CLONE_KEEPBDEVTYPE | LXC_CLONE_MAYBE_SNAPSHOT; - if (storage_is_dir(c->lxc_conf)) { - ERROR("Snapshot of directory-backed container requested"); - ERROR("Making a copy-clone. If you do want snapshots, then"); -@@ -4601,7 +4609,7 @@ static bool do_lxcapi_snapshot_restore(struct lxc_container *c, const char *snap - flags |= LXC_STORAGE_INTERNAL_OVERLAY_RESTORE; - - rest = lxcapi_clone(snap, newname, c->config_path, flags, bdev->type, -- NULL, 0, NULL); -+ NULL, 0, NULL); - storage_put(bdev); - if (rest && lxcapi_is_defined(rest)) - b = true; -@@ -4714,7 +4722,7 @@ static bool do_lxcapi_may_control(struct lxc_container *c) - WRAP_API(bool, lxcapi_may_control) - - static bool do_add_remove_node(pid_t init_pid, const char *path, bool add, -- struct stat *st) -+ struct stat *st) - { - int ret; - char *tmp; -@@ -4865,8 +4873,8 @@ static bool do_lxcapi_remove_device_node(struct lxc_container *c, const char *sr - WRAP_API_2(bool, lxcapi_remove_device_node, const char *, const char *) - - static bool do_lxcapi_attach_interface(struct lxc_container *c, -- const char *ifname, -- const char *dst_ifname) -+ const char *ifname, -+ const char *dst_ifname) - { - pid_t init_pid; - int ret = 0; -@@ -4904,8 +4912,8 @@ err: - WRAP_API_2(bool, lxcapi_attach_interface, const char *, const char *) - - static bool do_lxcapi_detach_interface(struct lxc_container *c, -- const char *ifname, -- const char *dst_ifname) -+ const char *ifname, -+ const char *dst_ifname) - { - int ret; - pid_t pid, pid_outside; -@@ -4980,7 +4988,7 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c, - WRAP_API_2(bool, lxcapi_detach_interface, const char *, const char *) - - static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd, -- struct migrate_opts *opts, unsigned int size) -+ struct migrate_opts *opts, unsigned int size) - { - int ret = -1; - struct migrate_opts *valid_opts = opts; -@@ -5125,7 +5133,7 @@ out: - /* isulad add set console fifos*/ - static bool do_lxcapi_set_terminal_default_fifos(struct lxc_container *c, const char *in, const char *out, const char *err) - { -- struct lxc_conf *conf; -+ struct lxc_conf *conf = NULL; - - if (!c || !c->lxc_conf) - return false; -@@ -5160,7 +5168,7 @@ WRAP_API_3(bool, lxcapi_set_terminal_default_fifos, const char *, const char *, - /* isulad add set info file path */ - static bool do_lxcapi_set_container_info_file(struct lxc_container *c, const char *info_file) - { -- struct lxc_conf *conf; -+ struct lxc_conf *conf = NULL; - - if (!c || !c->lxc_conf || !info_file) - return false; -@@ -5263,16 +5271,16 @@ static int set_start_extral_configs(struct lxc_container *c) - struct lxc_conf *lconf = c->lxc_conf; - size_t i = 0; - -- if (lconf == NULL) { -- c->lxc_conf = malloc(sizeof(struct lxc_conf)); -- lconf = c->lxc_conf; -- if (lconf == NULL) { -- fprintf(stderr, "Out of memory\n"); -- return -1; -- } -- } -+ if (lconf == NULL) { -+ c->lxc_conf = malloc(sizeof(struct lxc_conf)); -+ lconf = c->lxc_conf; -+ if (lconf == NULL) { -+ fprintf(stderr, "Out of memory\n"); -+ return -1; -+ } -+ } - if (sprintf(fpath, "%s/%s/%s", c->config_path, c->name, START_GENERATE_CONFIG) < 0) { -- fprintf(stderr, "Sprintf config path failed\n"); -+ fprintf(stderr, "Sprintf config path failed\n"); - return -1; - } - if (!file_exists(fpath)) { -@@ -5290,9 +5298,10 @@ static int set_start_extral_configs(struct lxc_container *c) - lconf->init_gid = start_conf->gid; - } - if (start_conf->additional_gids != NULL && start_conf->additional_gids_len > 0) { -- gid_t *tmp; -- tmp = realloc(lconf->init_groups, (lconf->init_groups_len + start_conf->additional_gids_len) * sizeof(gid_t)); -- if (tmp == NULL) { -+ gid_t *tmp = NULL; -+ ret = lxc_mem_realloc((void **)&tmp, (lconf->init_groups_len + start_conf->additional_gids_len) * sizeof(gid_t), -+ lconf->init_groups, (lconf->init_groups_len) * sizeof(gid_t)); -+ if (ret != 0) { - fprintf(stderr, "Out of memory"); - goto out; - } -@@ -5314,8 +5323,9 @@ out: - - static struct lxc_container *do_lxc_container_new(const char *name, const char *configpath, bool load_config) - { -- struct lxc_container *c; -+ struct lxc_container *c = NULL; - size_t len; -+ const char *tmp = NULL; - - if (!name) - return NULL; -@@ -5327,10 +5337,17 @@ static struct lxc_container *do_lxc_container_new(const char *name, const char * - } - memset(c, 0, sizeof(*c)); - -- if (configpath) -+ if (configpath) { - c->config_path = strdup(configpath); -- else -- c->config_path = strdup(lxc_global_config_value("lxc.lxcpath")); -+ } -+ else { -+ tmp = lxc_global_config_value("lxc.lxcpath"); -+ if (tmp == NULL) { -+ fprintf(stderr, "Failed to get lxc path for %s\n", name); -+ goto err; -+ } -+ c->config_path = strdup(tmp); -+ } - if (!c->config_path) { - fprintf(stderr, "Failed to allocate memory for %s\n", name); - goto err; -@@ -5534,7 +5551,7 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta - c = lxc_container_new(direntp->d_name, lxcpath); - if (!c) { - INFO("Container %s:%s has a config but could not be loaded", -- lxcpath, direntp->d_name); -+ lxcpath, direntp->d_name); - - if (names) - if(!remove_from_array(names, direntp->d_name, cfound--)) -@@ -5545,7 +5562,7 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta - - if (!do_lxcapi_is_defined(c)) { - INFO("Container %s:%s has a config but is not defined", -- lxcpath, direntp->d_name); -+ lxcpath, direntp->d_name); - - if (names) - if(!remove_from_array(names, direntp->d_name, cfound--)) -@@ -5584,7 +5601,7 @@ free_bad: - } - - int list_active_containers(const char *lxcpath, char ***nret, -- struct lxc_container ***cret) -+ struct lxc_container ***cret) - { - int i, ret = -1, cret_cnt = 0, ct_name_cnt = 0; - int lxcpath_len; -@@ -5680,7 +5697,7 @@ int list_active_containers(const char *lxcpath, char ***nret, - c = lxc_container_new(p, lxcpath); - if (!c) { - INFO("Container %s:%s is running but could not be loaded", -- lxcpath, p); -+ lxcpath, p); - - remove_from_array(&ct_name, p, ct_name_cnt--); - if (is_hashed) -@@ -5741,7 +5758,7 @@ out: - } - - int list_all_containers(const char *lxcpath, char ***nret, -- struct lxc_container ***cret) -+ struct lxc_container ***cret) - { - int i, ret, active_cnt, ct_cnt, ct_list_cnt; - char **active_name; -diff --git a/src/lxc/mainloop.c b/src/lxc/mainloop.c -index 9603d1e..a127a13 100644 ---- a/src/lxc/mainloop.c -+++ b/src/lxc/mainloop.c -@@ -65,7 +65,7 @@ int lxc_mainloop(struct lxc_epoll_descr *descr, int timeout_ms) - * mainloop. - */ - ret = handler->callback(handler->fd, events[i].events, -- handler->data, descr); -+ handler->data, descr); - if (ret == LXC_MAINLOOP_CLOSE) - return 0; - } -@@ -79,11 +79,11 @@ int lxc_mainloop(struct lxc_epoll_descr *descr, int timeout_ms) - } - - int lxc_mainloop_add_handler(struct lxc_epoll_descr *descr, int fd, -- lxc_mainloop_callback_t callback, void *data) -+ lxc_mainloop_callback_t callback, void *data) - { - struct epoll_event ev; -- struct mainloop_handler *handler; -- struct lxc_list *item; -+ struct mainloop_handler *handler = NULL; -+ struct lxc_list *item = NULL; - - if (fd < 0) - return 0; -diff --git a/src/lxc/path.c b/src/lxc/path.c -index e917dcb..45ab4c3 100644 ---- a/src/lxc/path.c -+++ b/src/lxc/path.c -@@ -10,6 +10,7 @@ - - #include "path.h" - #include "log.h" -+#include "utils.h" - - lxc_log_define(lxc_path_ui, lxc); - -@@ -29,6 +30,10 @@ bool specify_current_dir(const char *path) - } - - bname = basename(basec); -+ if (bname == NULL) { -+ ERROR("Out of memory"); -+ return false; -+ } - res = !strcmp(bname, "."); - free(basec); - return res; -@@ -45,11 +50,15 @@ bool has_traling_path_separator(const char *path) - // path already ends in a `.` path segment, then another is not added. If the - // clean path already ends in a path separator, then another is not added. - char *preserve_trailing_dot_or_separator(const char *cleanedpath, -- const char *originalpath) -+ const char *originalpath) - { - char *respath = NULL; - size_t len; - -+ if (strlen(cleanedpath) > (SIZE_MAX - 3)) { -+ return NULL; -+ } -+ - len = strlen(cleanedpath) + 3; - respath = malloc(len); - if (!respath) { -@@ -66,7 +75,7 @@ char *preserve_trailing_dot_or_separator(const char *cleanedpath, - } - - if (!has_traling_path_separator(respath) && -- has_traling_path_separator(originalpath)) -+ has_traling_path_separator(originalpath)) - strcat(respath, "/"); - - return respath; -@@ -107,160 +116,373 @@ bool filepath_split(const char *path, char **dir, char **base) - return true; - } - --/* -- * cleanpath is similar to realpath of glibc, but not expands symbolic links, -- * and not check the existence of components of the path. -- */ --char *cleanpath(const char *path, char *resolved) -+ -+static bool do_clean_path_continue(const char *endpos, const char *stpos, const char *respath, char **dst) - { -- char *rpath, *dest; -- const char *start, *end, *rpath_limit; -+ if (endpos - stpos == 1 && stpos[0] == '.') { -+ return true; -+ } else if (endpos - stpos == 2 && stpos[0] == '.' && stpos[1] == '.') { -+ char *dest = *dst; -+ if (dest <= respath + 1) { -+ return true; -+ } -+ for (--dest; dest > respath && !ISSLASH(dest[-1]); --dest) { -+ *dst = dest; -+ return true; -+ } -+ *dst = dest; -+ return true; -+ } -+ return false; -+} - -- if (path == NULL || path[0] == '\0') -- return NULL; -+int do_clean_path(const char *respath, const char *limit_respath, -+ const char *stpos, char **dst) -+{ -+ char *dest = *dst; -+ const char *endpos = NULL; -+ errno_t ret; - -- if (resolved == NULL) { -- rpath = malloc(PATH_MAX); -- if (rpath == NULL) { -- ERROR("Out of memory"); -- return NULL; -+ for (endpos = stpos; *stpos; stpos = endpos) { -+ while (ISSLASH(*stpos)) { -+ ++stpos; - } -- } else { -- rpath = resolved; -+ -+ for (endpos = stpos; *endpos && !ISSLASH(*endpos); ++endpos) { -+ } -+ -+ if (endpos - stpos == 0) { -+ break; -+ } else if (do_clean_path_continue(endpos, stpos, respath, &dest)) { -+ continue; -+ } -+ -+ if (!ISSLASH(dest[-1])) { -+ *dest++ = '/'; -+ } -+ -+ if (dest + (endpos - stpos) >= limit_respath) { -+ ERROR("Path is too long"); -+ if (dest > respath + 1) { -+ dest--; -+ } -+ *dest = '\0'; -+ return -1; -+ } -+ -+ memcpy(dest, stpos, (size_t)(endpos - stpos)); -+ dest += endpos - stpos; -+ *dest = '\0'; - } -- rpath_limit = rpath + PATH_MAX; -+ *dst = dest; -+ return 0; -+} -+ -+char *cleanpath(const char *path, char *realpath, size_t realpath_len) -+{ -+ char *respath = NULL; -+ char *dest = NULL; -+ const char *stpos = NULL; -+ const char *limit_respath = NULL; -+ errno_t ret; -+ -+ if (path == NULL || path[0] == '\0' || \ -+ realpath == NULL || (realpath_len < PATH_MAX)) { -+ return NULL; -+ } -+ -+ respath = realpath; -+ -+ memset(respath, 0, realpath_len); -+ limit_respath = respath + PATH_MAX; - - if (!IS_ABSOLUTE_FILE_NAME(path)) { -- if (!getcwd(rpath, PATH_MAX)) { -+ if (!getcwd(respath, PATH_MAX)) { - ERROR("Failed to getcwd"); -- rpath[0] = '\0'; -+ respath[0] = '\0'; - goto error; - } -- dest = strchr(rpath, '\0'); -- start = path; -+ dest = strchr(respath, '\0'); -+ if (dest == NULL) { -+ ERROR("Failed to get the end of respath"); -+ goto error; -+ } -+ strcat(respath, path); -+ stpos = path; - } else { -- dest = rpath; -+ dest = respath; - *dest++ = '/'; -- start = path; -+ stpos = path; - } - -- for (end = start; *start; start = end) { -- /* Skip sequence of multiple path-separators. */ -- while (ISSLASH(*start)) -- ++start; -+ if (do_clean_path(respath, limit_respath, stpos, &dest)) { -+ goto error; -+ } - -- /* Find end of path component. */ -- for (end = start; *end && !ISSLASH(*end); ++end) -- /* Nothing. */; -+ if (dest > respath + 1 && ISSLASH(dest[-1])) { -+ --dest; -+ } -+ *dest = '\0'; - -- if (end - start == 0) { -- break; -- } else if (end - start == 1 && start[0] == '.') { -- /* nothing */; -- } else if (end - start == 2 && start[0] == '.' && start[1] == '.') { -- /* Back up to previous component, ignore if at root already. */ -- if (dest > rpath + 1) -- for (--dest; dest > rpath && !ISSLASH(dest[-1]); --dest) -- continue; -- } else { -- size_t new_size; -- -- if (!ISSLASH(dest[-1])) -- *dest++ = '/'; -- -- if (dest + (end - start) >= rpath_limit) { -- long long dest_offset = dest - rpath; -- char *new_rpath; -- -- if (resolved) { -- printf("Path is to long"); -- if (dest > rpath + 1) -- dest--; -- *dest = '\0'; -- goto error; -- } -- -- new_size = rpath_limit - rpath; -- if (end - start + 1 > PATH_MAX) -- new_size += end - start + 1; -- else -- new_size += PATH_MAX; -- new_rpath = (char *) realloc(rpath, new_size); -- if (new_rpath == NULL) { -- ERROR("Out of memory"); -- goto error; -- } -- rpath = new_rpath; -- rpath_limit = rpath + new_size; -- -- dest = rpath + dest_offset; -+ return respath; -+ -+error: -+ return NULL; -+} -+ -+static int do_path_realloc(const char *start, const char *end, -+ char **rpath, char **dest, const char **rpath_limit) -+{ -+ long long dest_offset = *dest - *rpath; -+ char *new_rpath = NULL; -+ size_t new_size; -+ int nret = 0; -+ size_t gap = 0; -+ -+ if (*dest + (end - start) < *rpath_limit) { -+ return 0; -+ } -+ -+ gap = (size_t)(end - start) + 1; -+ new_size = (size_t)(*rpath_limit - *rpath); -+ if (new_size > SIZE_MAX - gap) { -+ ERROR("Out of range!"); -+ return -1; -+ } -+ -+ if (gap > PATH_MAX) { -+ new_size += gap; -+ } else { -+ new_size += PATH_MAX; -+ } -+ nret = lxc_mem_realloc((void **)&new_rpath, new_size, *rpath, PATH_MAX); -+ if (nret) { -+ ERROR("Failed to realloc memory for files limit variables"); -+ return -1; -+ } -+ *rpath = new_rpath; -+ *rpath_limit = *rpath + new_size; -+ -+ *dest = *rpath + dest_offset; -+ -+ return 0; -+} -+ -+static int do_get_symlinks_copy_buf(const char *buf, const char *prefix, size_t prefix_len, -+ char **rpath, char **dest) -+{ -+ if (IS_ABSOLUTE_FILE_NAME(buf)) { -+ if (prefix_len) { -+ memcpy(*rpath, prefix, prefix_len); -+ } -+ *dest = *rpath + prefix_len; -+ *(*dest)++ = '/'; -+ } else { -+ if (*dest > *rpath + prefix_len + 1) { -+ for (--(*dest); *dest > *rpath && !ISSLASH((*dest)[-1]); --(*dest)) { -+ continue; - } -+ } -+ } -+ return 0; -+} - -- memcpy(dest, start, end - start); -- dest += end - start; -- *dest = '\0'; -+static int do_get_symlinks(const char **fullpath, const char *prefix, size_t prefix_len, -+ char **rpath, char **dest, const char **end, -+ int *num_links, char **extra_buf) -+{ -+ char *buf = NULL; -+ size_t len; -+ errno_t rc = EOK; -+ ssize_t n; -+ int ret = -1; -+ -+ if (++(*num_links) > MAXSYMLINKS) { -+ ERROR("Too many links in '%s'", *fullpath); -+ goto out; -+ } -+ -+ buf = lxc_common_calloc_s(PATH_MAX); -+ if (buf == NULL) { -+ ERROR("Out of memory"); -+ goto out; -+ } -+ -+ n = readlink(*rpath, buf, PATH_MAX - 1); -+ if (n < 0) { -+ goto out; -+ } -+ buf[n] = '\0'; -+ -+ if (*extra_buf == NULL) { -+ *extra_buf = lxc_common_calloc_s(PATH_MAX); -+ if (*extra_buf == NULL) { -+ ERROR("Out of memory"); -+ goto out; - } - } -- if (dest > rpath + 1 && ISSLASH(dest[-1])) -- --dest; -- *dest = '\0'; - -- return rpath; -+ len = strlen(*end); -+ if (len >= PATH_MAX - n) { -+ ERROR("Path is too long"); -+ goto out; -+ } - --error: -- if (resolved == NULL) -- free(rpath); -- return NULL; -+ memmove(&(*extra_buf)[n], *end, len + 1); -+ memcpy(*extra_buf, buf, (size_t)n); -+ -+ *fullpath = *end = *extra_buf; -+ -+ if (do_get_symlinks_copy_buf(buf, prefix, prefix_len, rpath, dest) != 0) { -+ goto out; -+ } -+ -+ ret = 0; -+out: -+ free(buf); -+ return ret; - } - --// evalSymlinksInScope will evaluate symlinks in `path` within a scope `root` and return --// a result guaranteed to be contained within the scope `root`, at the time of the call. --// Symlinks in `root` are not evaluated and left as-is. --// Errors encountered while attempting to evaluate symlinks in path will be returned. --// Non-existing paths are valid and do not constitute an error. --// `path` has to contain `root` as a prefix, or else an error will be returned. --// Trying to break out from `root` does not constitute an error. --// --// Example: --// If /foo/bar -> /outside, --// FollowSymlinkInScope("/foo/bar", "/foo") == "/foo/outside" instead of "/oustide" --char *eval_symlinks_in_scope(const char *fullpath, const char *rootpath) -+static bool do_eval_symlinks_in_scope_is_symlink(const char *path) - { -- char resroot[PATH_MAX] = {0}, *root = NULL; -- char *rpath, *dest, *prefix, *extra_buf = NULL; -- const char *start, *end, *rpath_limit; -+ struct stat st; -+ -+ if (lstat(path, &st) < 0) { -+ return true; -+ } -+ -+ if (!S_ISLNK(st.st_mode)) { -+ return true; -+ } -+ return false; -+} -+ -+static void do_eval_symlinks_skip_slash(const char **start, const char **end) -+{ -+ while (ISSLASH(**start)) { -+ ++(*start); -+ } -+ -+ for (*end = *start; **end && !ISSLASH(**end); ++(*end)) { -+ } -+} -+ -+static inline void skip_dest_traling_slash(char **dest, char **rpath, size_t prefix_len) -+{ -+ if (*dest > *rpath + prefix_len + 1) { -+ for (--(*dest); *dest > *rpath && !ISSLASH((*dest)[-1]); --(*dest)) { -+ continue; -+ } -+ } -+} -+ -+static inline bool is_current_char(const char c) -+{ -+ return c == '.'; -+} -+ -+static inline bool is_specify_current(const char *end, const char *start) -+{ -+ return (end - start == 1) && is_current_char(start[0]); -+} -+ -+static inline bool is_specify_parent(const char *end, const char *start) -+{ -+ return (end - start == 2) && is_current_char(start[0]) && is_current_char(start[1]); -+} -+ -+static int do_eval_symlinks_in_scope(const char *fullpath, const char *prefix, -+ size_t prefix_len, -+ char **rpath, char **dest, const char *rpath_limit) -+{ -+ const char *start = NULL; -+ const char *end = NULL; -+ char *extra_buf = NULL; -+ errno_t rc = EOK; -+ int nret = 0; - int num_links = 0; -+ -+ start = fullpath + prefix_len; -+ for (end = start; *start; start = end) { -+ do_eval_symlinks_skip_slash(&start, &end); -+ if (end - start == 0) { -+ break; -+ } else if (is_specify_current(end, start)) { -+ ; -+ } else if (is_specify_parent(end, start)) { -+ skip_dest_traling_slash(dest, rpath, prefix_len); -+ } else { -+ if (!ISSLASH((*dest)[-1])) { -+ *(*dest)++ = '/'; -+ } -+ -+ nret = do_path_realloc(start, end, rpath, dest, &rpath_limit); -+ if (nret != 0) { -+ nret = -1; -+ goto out; -+ } -+ -+ memcpy(*dest, start, (size_t)(end - start)); -+ *dest += end - start; -+ **dest = '\0'; -+ -+ if (do_eval_symlinks_in_scope_is_symlink(*rpath)) { -+ continue; -+ } -+ -+ nret = do_get_symlinks(&fullpath, prefix, prefix_len, rpath, dest, &end, &num_links, &extra_buf); -+ if (nret != 0) { -+ nret = -1; -+ goto out; -+ } -+ } -+ } -+out: -+ free(extra_buf); -+ return nret; -+} -+static char *eval_symlinks_in_scope(const char *fullpath, const char *rootpath) -+{ -+ char resroot[PATH_MAX] = {0}; -+ char *root = NULL; -+ char *rpath = NULL; -+ char *dest = NULL; -+ char *prefix = NULL; -+ const char *rpath_limit = NULL; - size_t prefix_len; -+ errno_t rc = EOK; - -- if (!fullpath || !rootpath) -+ if (fullpath == NULL || rootpath == NULL) { - return NULL; -+ } - -- root = cleanpath(rootpath, resroot); -- if (!root) { -+ root = cleanpath(rootpath, resroot, sizeof(resroot)); -+ if (root == NULL) { - ERROR("Failed to get cleaned path"); - return NULL; - } - -- if (!strcmp(fullpath, root)) -+ if (!strcmp(fullpath, root)) { - return strdup(fullpath); -+ } - -- if (!strstr(fullpath, root)) { -+ if (strstr(fullpath, root) == NULL) { - ERROR("Path '%s' is not in '%s'", fullpath, root); - return NULL; - } - -- rpath = malloc(PATH_MAX); -+ rpath = lxc_common_calloc_s(PATH_MAX); - if (rpath == NULL) { - ERROR("Out of memory"); -- goto error; -- return NULL; -+ goto out; - } - rpath_limit = rpath + PATH_MAX; - - prefix = root; -- prefix_len = strlen(prefix); -- if (!strcmp(prefix, "/")) -+ prefix_len = (size_t)strlen(prefix); -+ if (!strcmp(prefix, "/")) { - prefix_len = 0; -+ } - - dest = rpath; - if (prefix_len) { -@@ -268,133 +490,19 @@ char *eval_symlinks_in_scope(const char *fullpath, const char *rootpath) - dest += prefix_len; - } - *dest++ = '/'; -- start = fullpath + prefix_len; - -- for (end = start; *start; start = end) { -- struct stat st; -- int n; -- -- /* Skip sequence of multiple path-separators. */ -- while (ISSLASH(*start)) -- ++start; -- -- /* Find end of path component. */ -- for (end = start; *end && !ISSLASH(*end); ++end) -- /* Nothing. */; -- -- if (end - start == 0) { -- break; -- } else if (end - start == 1 && start[0] == '.') { -- /* nothing */; -- } else if (end - start == 2 && start[0] == '.' && start[1] == '.') { -- /* Back up to previous component, ignore if at root already. */ -- if (dest > rpath + prefix_len + 1) -- for (--dest; dest > rpath && !ISSLASH(dest[-1]); --dest) -- continue; -- } else { -- size_t new_size; -- -- if (!ISSLASH(dest[-1])) -- *dest++ = '/'; -- -- if (dest + (end - start) >= rpath_limit) { -- long long dest_offset = dest - rpath; -- char *new_rpath; -- -- new_size = rpath_limit - rpath; -- if (end - start + 1 > PATH_MAX) -- new_size += end - start + 1; -- else -- new_size += PATH_MAX; -- new_rpath = (char *) realloc(rpath, new_size); -- if (new_rpath == NULL) { -- ERROR("Out of memory"); -- goto error; -- } -- rpath = new_rpath; -- rpath_limit = rpath + new_size; -- -- dest = rpath + dest_offset; -- } -- -- memcpy(dest, start, end - start); -- dest += end - start; -- *dest = '\0'; -- -- if (lstat(rpath, &st) < 0) { -- // if rpath does not exist, accept it -- continue; -- } -- -- if (S_ISLNK(st.st_mode)) { -- char *buf; -- size_t len; -- -- if (++num_links > MAXSYMLINKS) { -- ERROR("Too many links in '%s'", fullpath); -- goto error; -- } -- -- buf = malloc(PATH_MAX); -- if (!buf) { -- ERROR("Out of memory"); -- goto error; -- } -- -- n = readlink(rpath, buf, PATH_MAX - 1); -- if (n < 0) { -- free(buf); -- goto error; -- } -- buf[n] = '\0'; -- -- if (!extra_buf) { -- extra_buf = malloc(PATH_MAX); -- if (!extra_buf) { -- ERROR("Out of memory"); -- free(buf); -- goto error; -- } -- } -- -- len = strlen(end); -- if ((long int)(n + len) >= PATH_MAX) { -- free(buf); -- ERROR("Path is too long"); -- goto error; -- } -- -- /* Careful here, end may be a pointer into extra_buf... */ -- memmove(&extra_buf[n], end, len + 1); -- fullpath = end = memcpy(extra_buf, buf, n); -- -- if (IS_ABSOLUTE_FILE_NAME(buf)) { -- if (prefix_len) -- memcpy(rpath, prefix, prefix_len); -- dest = rpath + prefix_len; -- *dest++ = '/'; /* It's an absolute symlink */ -- } else { -- /* Back up to previous component, ignore if at root -- already: */ -- if (dest > rpath + prefix_len + 1) -- for (--dest; dest > rpath && !ISSLASH(dest[-1]); --dest) -- continue; -- } -- } -- } -+ if (do_eval_symlinks_in_scope(fullpath, prefix, prefix_len, &rpath, &dest, -+ rpath_limit)) { -+ goto out; - } -- if (dest > rpath + prefix_len + 1 && ISSLASH(dest[-1])) -+ -+ if (dest > rpath + prefix_len + 1 && ISSLASH(dest[-1])) { - --dest; -+ } - *dest = '\0'; -- -- if (extra_buf) -- free(extra_buf); -- - return rpath; - --error: -- if (extra_buf) -- free(extra_buf); -+out: - free(rpath); - return NULL; - } -@@ -406,13 +514,13 @@ char *follow_symlink_in_scope(const char *fullpath, const char *rootpath) - char resfull[PATH_MAX] = {0}, *full = NULL; - char resroot[PATH_MAX] = {0}, *root = NULL; - -- full = cleanpath(fullpath, resfull); -+ full = cleanpath(fullpath, resfull, PATH_MAX); - if (!full) { - ERROR("Failed to get cleaned path"); - return NULL; - } - -- root = cleanpath(rootpath, resroot); -+ root = cleanpath(rootpath, resroot, PATH_MAX); - if (!root) { - ERROR("Failed to get cleaned path"); - return NULL; -@@ -430,7 +538,7 @@ char *follow_symlink_in_scope(const char *fullpath, const char *rootpath) - // particular path inside the container as though you were a process in that - // container. - int get_resource_path(const char *rootpath, const char *path, -- char **scopepath) -+ char **scopepath) - { - char resolved[PATH_MAX] = {0}, *cleanedpath = NULL; - char *fullpath = NULL; -@@ -441,7 +549,7 @@ int get_resource_path(const char *rootpath, const char *path, - - *scopepath = NULL; - -- cleanedpath = cleanpath(path, resolved); -+ cleanedpath = cleanpath(path, resolved, PATH_MAX); - if (!cleanedpath) { - ERROR("Failed to get cleaned path"); - return -1; -@@ -475,13 +583,13 @@ char *path_relative(const char *basepath, const char *targpath) - char restarg[PATH_MAX] = {0}, *targ = NULL; - size_t bl = 0, tl = 0, b0 = 0, bi = 0, t0 = 0, ti = 0; - -- base = cleanpath(basepath, resbase); -+ base = cleanpath(basepath, resbase, PATH_MAX); - if (!base) { - ERROR("Failed to get cleaned path"); - return NULL; - } - -- targ = cleanpath(targpath, restarg); -+ targ = cleanpath(targpath, restarg, PATH_MAX); - if (!targ) { - ERROR("Failed to get cleaned path"); - return NULL; -@@ -512,7 +620,7 @@ char *path_relative(const char *basepath, const char *targpath) - // Base elements left. Must go up before going down. - int seps = 0, i; - size_t ncopyed = 0, seps_size; -- char *buf; -+ char *buf = NULL; - - for (bi = b0; bi < bl; bi++) { - if (ISSLASH(base[bi])) -@@ -543,4 +651,4 @@ char *path_relative(const char *basepath, const char *targpath) - } - - return strdup(targ + t0); --} -\ No newline at end of file -+} -diff --git a/src/lxc/path.h b/src/lxc/path.h -index e3a04cc..5100941 100644 ---- a/src/lxc/path.h -+++ b/src/lxc/path.h -@@ -13,7 +13,7 @@ bool has_traling_path_separator(const char *path); - // path already ends in a `.` path segment, then another is not added. If the - // clean path already ends in a path separator, then another is not added. - char *preserve_trailing_dot_or_separator(const char *cleanedpath, -- const char *originalpath); -+ const char *originalpath); - - - // Split splits path immediately following the final Separator, -@@ -27,20 +27,8 @@ bool filepath_split(const char *path, char **dir, char **base); - * cleanpath is similar to realpath of glibc, but not expands symbolic links, - * and not check the existence of components of the path. - */ --char *cleanpath(const char *path, char *resolved); -+char *cleanpath(const char *path, char *realpath, size_t realpath_len); - --// evalSymlinksInScope will evaluate symlinks in `path` within a scope `root` and return --// a result guaranteed to be contained within the scope `root`, at the time of the call. --// Symlinks in `root` are not evaluated and left as-is. --// Errors encountered while attempting to evaluate symlinks in path will be returned. --// Non-existing paths are valid and do not constitute an error. --// `path` has to contain `root` as a prefix, or else an error will be returned. --// Trying to break out from `root` does not constitute an error. --// --// Example: --// If /foo/bar -> /outside, --// FollowSymlinkInScope("/foo/bar", "/foo") == "/foo/outside" instead of "/oustide" --char *eval_symlinks_in_scope(const char *fullpath, const char *rootpath); - - // FollowSymlinkInScope is a wrapper around evalSymlinksInScope that returns an - // absolute path. This function handles paths in a platform-agnostic manner. -@@ -55,7 +43,7 @@ char *follow_symlink_in_scope(const char *fullpath, const char *rootpath); - // particular path inside the container as though you were a process in that - // container. - int get_resource_path(const char *rootpath, const char *path, -- char **scopepath); -+ char **scopepath); - - // Rel returns a relative path that is lexically equivalent to targpath when - // joined to basepath with an intervening separator. That is, -diff --git a/src/lxc/start.c b/src/lxc/start.c -index 4541793..ccdd844 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -93,7 +93,7 @@ extern void mod_all_rdeps(struct lxc_container *c, bool inc); - static bool do_destroy_container(struct lxc_handler *handler); - static int lxc_rmdir_onedev_wrapper(void *data); - static void lxc_destroy_container_on_signal(struct lxc_handler *handler, -- const char *name); -+ const char *name); - - /* isulad: start timeout thread */ - typedef enum { -@@ -136,8 +136,8 @@ static void print_top_failing_dir(const char *path) - ret = access(copy, X_OK); - if (ret != 0) { - SYSERROR("Could not access %s. Please grant it x " -- "access, or add an ACL for the container " -- "root", copy); -+ "access, or add an ACL for the container " -+ "root", copy); - return; - } - *p = saved; -@@ -180,7 +180,7 @@ static int lxc_try_preserve_ns(const int pid, const char *ns) - * Return true on success, false on failure. - */ - static bool lxc_try_preserve_namespaces(struct lxc_handler *handler, -- int ns_clone_flags, pid_t pid) -+ int ns_clone_flags, pid_t pid) - { - int i; - -@@ -243,8 +243,8 @@ static bool match_dlog_fds(struct dirent *direntp) - } - - if (strcmp(link, "/dev/log_main") == 0 || -- strcmp(link, "/dev/log_system") == 0 || -- strcmp(link, "/dev/log_radio") == 0) -+ strcmp(link, "/dev/log_system") == 0 || -+ strcmp(link, "/dev/log_radio") == 0) - return true; - - return false; -@@ -252,7 +252,7 @@ static bool match_dlog_fds(struct dirent *direntp) - #endif - - int lxc_check_inherited(struct lxc_conf *conf, bool closeall, -- int *fds_to_ignore, size_t len_fds) -+ int *fds_to_ignore, size_t len_fds) - { - int fd, fddir; - size_t i; -@@ -293,7 +293,7 @@ restart: - break; - - if (fd == fddir || fd == lxc_log_fd || -- (i < len_fds && fd == fds_to_ignore[i])) -+ (i < len_fds && fd == fds_to_ignore[i])) - continue; - - /* Keep state clients that wait on reboots. */ -@@ -377,7 +377,7 @@ static int setup_signal_fd(sigset_t *oldmask) - } - - static int signal_handler(int fd, uint32_t events, void *data, -- struct lxc_epoll_descr *descr) -+ struct lxc_epoll_descr *descr) - { - int ret; - siginfo_t info; -@@ -427,14 +427,14 @@ static int signal_handler(int fd, uint32_t events, void *data, - kill(hdlr->pid, SIGTERM); - INFO("Killing %d since terminal hung up", hdlr->pid); - return hdlr->init_died ? LXC_MAINLOOP_CLOSE -- : LXC_MAINLOOP_CONTINUE; -+ : LXC_MAINLOOP_CONTINUE; - } - - if (siginfo.ssi_signo != SIGCHLD) { - kill(hdlr->pid, siginfo.ssi_signo); - INFO("Forwarded signal %d to pid %d", siginfo.ssi_signo, hdlr->pid); - return hdlr->init_died ? LXC_MAINLOOP_CLOSE -- : LXC_MAINLOOP_CONTINUE; -+ : LXC_MAINLOOP_CONTINUE; - } - - /* More robustness, protect ourself from a SIGCHLD sent -@@ -444,19 +444,19 @@ static int signal_handler(int fd, uint32_t events, void *data, - NOTICE("Received %d from pid %d instead of container init %d", - siginfo.ssi_signo, siginfo.ssi_pid, hdlr->pid); - return hdlr->init_died ? LXC_MAINLOOP_CLOSE -- : LXC_MAINLOOP_CONTINUE; -+ : LXC_MAINLOOP_CONTINUE; - } - - if (siginfo.ssi_code == CLD_STOPPED) { - INFO("Container init process was stopped"); - return hdlr->init_died ? LXC_MAINLOOP_CLOSE -- : LXC_MAINLOOP_CONTINUE; -+ : LXC_MAINLOOP_CONTINUE; - } - - if (siginfo.ssi_code == CLD_CONTINUED) { - INFO("Container init process was continued"); - return hdlr->init_died ? LXC_MAINLOOP_CLOSE -- : LXC_MAINLOOP_CONTINUE; -+ : LXC_MAINLOOP_CONTINUE; - } - - DEBUG("Container init process %d exited", hdlr->pid); -@@ -465,7 +465,7 @@ static int signal_handler(int fd, uint32_t events, void *data, - } - - int lxc_serve_state_clients(const char *name, struct lxc_handler *handler, -- lxc_state_t state) -+ lxc_state_t state) - { - size_t retlen; - ssize_t ret; -@@ -516,14 +516,14 @@ int lxc_serve_state_clients(const char *name, struct lxc_handler *handler, - } - - static int lxc_serve_state_socket_pair(const char *name, -- struct lxc_handler *handler, -- lxc_state_t state) -+ struct lxc_handler *handler, -+ lxc_state_t state) - { - ssize_t ret; - - if (!handler->daemonize || -- handler->state_socket_pair[1] < 0 || -- state == STARTING) -+ handler->state_socket_pair[1] < 0 || -+ state == STARTING) - return 0; - - /* Close read end of the socket pair. */ -@@ -532,7 +532,9 @@ static int lxc_serve_state_socket_pair(const char *name, - - again: - ret = lxc_abstract_unix_send_credential(handler->state_socket_pair[1], -- &(int){state}, sizeof(int)); -+ &(int) { -+ state -+ }, sizeof(int)); - if (ret < 0) { - SYSERROR("Failed to send state to %d", handler->state_socket_pair[1]); - -@@ -558,7 +560,7 @@ again: - } - - int lxc_set_state(const char *name, struct lxc_handler *handler, -- lxc_state_t state) -+ lxc_state_t state) - { - int ret; - -@@ -587,7 +589,7 @@ int lxc_poll(const char *name, struct lxc_handler *handler) - struct lxc_epoll_descr descr, descr_console; - - if (handler->conf->console.path && -- strcmp(handler->conf->console.path, "none") == 0) -+ strcmp(handler->conf->console.path, "none") == 0) - has_console = false; - - ret = lxc_mainloop_open(&descr); -@@ -726,7 +728,7 @@ void lxc_free_handler(struct lxc_handler *handler) - } - - struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf, -- const char *lxcpath, bool daemonize) -+ const char *lxcpath, bool daemonize) - { - int i, ret; - struct lxc_handler *handler; -@@ -764,7 +766,7 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf, - * again currently so don't open another socketpair(). - */ - ret = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, -- handler->state_socket_pair); -+ handler->state_socket_pair); - if (ret < 0) { - ERROR("Failed to create anonymous pair of unix sockets"); - goto on_error; -@@ -829,49 +831,49 @@ int lxc_init(const char *name, struct lxc_handler *handler) - ret = setenv("LXC_CONFIG_FILE", conf->rcfile, 1); - if (ret < 0) - SYSERROR("Failed to set environment variable: " -- "LXC_CONFIG_FILE=%s", conf->rcfile); -+ "LXC_CONFIG_FILE=%s", conf->rcfile); - } - - if (conf->rootfs.mount) { - ret = setenv("LXC_ROOTFS_MOUNT", conf->rootfs.mount, 1); - if (ret < 0) - SYSERROR("Failed to set environment variable: " -- "LXC_ROOTFS_MOUNT=%s", conf->rootfs.mount); -+ "LXC_ROOTFS_MOUNT=%s", conf->rootfs.mount); - } - - if (conf->rootfs.path) { - ret = setenv("LXC_ROOTFS_PATH", conf->rootfs.path, 1); - if (ret < 0) - SYSERROR("Failed to set environment variable: " -- "LXC_ROOTFS_PATH=%s", conf->rootfs.path); -+ "LXC_ROOTFS_PATH=%s", conf->rootfs.path); - } - - if (conf->console.path) { - ret = setenv("LXC_CONSOLE", conf->console.path, 1); - if (ret < 0) - SYSERROR("Failed to set environment variable: " -- "LXC_CONSOLE=%s", conf->console.path); -+ "LXC_CONSOLE=%s", conf->console.path); - } - - if (conf->console.log_path) { - ret = setenv("LXC_CONSOLE_LOGPATH", conf->console.log_path, 1); - if (ret < 0) - SYSERROR("Failed to set environment variable: " -- "LXC_CONSOLE_LOGPATH=%s", conf->console.log_path); -+ "LXC_CONSOLE_LOGPATH=%s", conf->console.log_path); - } - - if (cgns_supported()) { - ret = setenv("LXC_CGNS_AWARE", "1", 1); - if (ret < 0) - SYSERROR("Failed to set environment variable " -- "LXC_CGNS_AWARE=1"); -+ "LXC_CGNS_AWARE=1"); - } - - loglevel = lxc_log_priority_to_string(lxc_log_get_level()); - ret = setenv("LXC_LOG_LEVEL", loglevel, 1); - if (ret < 0) - SYSERROR("Set environment variable LXC_LOG_LEVEL=%s", -- loglevel); -+ loglevel); - - if (conf->hooks_version == 0) - ret = setenv("LXC_HOOK_VERSION", "0", 1); -@@ -959,6 +961,7 @@ static int _read_procs_file(const char *path, pid_t **pids, size_t *len) - FILE *f; - char *line = NULL; - size_t sz = 0; -+ pid_t *tmp_pids = NULL; - - f = fopen_cloexec(path, "r"); - if (!f) -@@ -968,7 +971,16 @@ static int _read_procs_file(const char *path, pid_t **pids, size_t *len) - pid_t pid; - trim_line(line); - pid = (pid_t)atoll(line); -- *pids = realloc(*pids, sizeof(pid_t) * (*len + 1)); -+ if (lxc_mem_realloc((void **)&tmp_pids, sizeof(pid_t) * (*len + 1), *pids, sizeof(pid_t) * (*len)) != 0) { -+ free(*pids); -+ *pids = NULL; -+ ERROR("out of memory"); -+ free(line); -+ fclose(f); -+ return -1; -+ } -+ *pids = tmp_pids; -+ - (*pids)[*len] = pid; - (*len)++; - } -@@ -980,8 +992,8 @@ static int _read_procs_file(const char *path, pid_t **pids, size_t *len) - - static int _recursive_read_cgroup_procs(const char *dirpath, pid_t **pids, size_t *len) - { -- struct dirent *direntp; -- DIR *dir; -+ struct dirent *direntp = NULL; -+ DIR *dir = NULL; - int ret, failed = 0; - char pathname[PATH_MAX]; - -@@ -996,7 +1008,7 @@ static int _recursive_read_cgroup_procs(const char *dirpath, pid_t **pids, size_ - int rc; - - if (!strcmp(direntp->d_name, ".") || -- !strcmp(direntp->d_name, "..")) -+ !strcmp(direntp->d_name, "..")) - continue; - - rc = snprintf(pathname, PATH_MAX, "%s/%s", dirpath, direntp->d_name); -@@ -1122,11 +1134,11 @@ void lxc_fini(const char *name, struct lxc_handler *handler) - - if (handler->conf->hooks_version == 0) - ret = asprintf(&namespaces[namespace_count], -- "%s:/proc/%d/fd/%d", ns_info[i].proc_name, -- self, handler->nsfd[i]); -+ "%s:/proc/%d/fd/%d", ns_info[i].proc_name, -+ self, handler->nsfd[i]); - else - ret = asprintf(&namespaces[namespace_count], -- "/proc/%d/fd/%d", self, handler->nsfd[i]); -+ "/proc/%d/fd/%d", self, handler->nsfd[i]); - if (ret == -1) { - SYSERROR("Failed to allocate memory"); - break; -@@ -1140,7 +1152,7 @@ void lxc_fini(const char *name, struct lxc_handler *handler) - ret = setenv(ns_info[i].env_name, namespaces[namespace_count], 1); - if (ret < 0) - SYSERROR("Failed to set environment variable %s=%s", -- ns_info[i].env_name, namespaces[namespace_count]); -+ ns_info[i].env_name, namespaces[namespace_count]); - else - TRACE("Set environment variable %s=%s", - ns_info[i].env_name, namespaces[namespace_count]); -@@ -1153,14 +1165,14 @@ void lxc_fini(const char *name, struct lxc_handler *handler) - ret = setenv("LXC_TARGET", "reboot", 1); - if (ret < 0) - SYSERROR("Failed to set environment variable: " -- "LXC_TARGET=reboot"); -+ "LXC_TARGET=reboot"); - } - - if (handler->conf->reboot == REBOOT_NONE) { - ret = setenv("LXC_TARGET", "stop", 1); - if (ret < 0) - SYSERROR("Failed to set environment variable: " -- "LXC_TARGET=stop"); -+ "LXC_TARGET=stop"); - } - - if (handler->conf->hooks_version == 0) -@@ -1252,7 +1264,7 @@ retry: - - /* Keep state clients that want to be notified about reboots. */ - if ((handler->conf->reboot > REBOOT_NONE) && -- (client->states[RUNNING] == 2)) -+ (client->states[RUNNING] == 2)) - continue; - - /* close state client socket */ -@@ -1287,7 +1299,8 @@ void lxc_abort(const char *name, struct lxc_handler *handler) - - static int do_start(void *data) - { -- int ret, i; -+ int ret = 0; -+ int i; - char path[PATH_MAX]; - uid_t new_uid; - gid_t new_gid; -@@ -1351,7 +1364,7 @@ static int do_start(void *data) - * https://github.com/lxc/lxd/issues/1978. - */ - if ((handler->ns_clone_flags & (CLONE_NEWNET | CLONE_NEWUSER)) == -- (CLONE_NEWNET | CLONE_NEWUSER)) { -+ (CLONE_NEWNET | CLONE_NEWUSER)) { - ret = unshare(CLONE_NEWNET); - if (ret < 0) { - SYSERROR("Failed to unshare CLONE_NEWNET"); -@@ -1390,11 +1403,11 @@ static int do_start(void *data) - * user namespace. - */ - if (!lxc_setgroups(0, NULL) && -- (handler->am_root || errno != EPERM)) -+ (handler->am_root || errno != EPERM)) - goto out_warn_father; - - ret = prctl(PR_SET_DUMPABLE, prctl_arg(1), prctl_arg(0), -- prctl_arg(0), prctl_arg(0)); -+ prctl_arg(0), prctl_arg(0)); - if (ret < 0) - goto out_warn_father; - -@@ -1413,7 +1426,7 @@ static int do_start(void *data) - } - - ret = snprintf(path, sizeof(path), "%s/dev/null", -- handler->conf->rootfs.mount); -+ handler->conf->rootfs.mount); - if (ret < 0 || ret >= sizeof(path)) - goto out_warn_father; - -@@ -1474,7 +1487,7 @@ static int do_start(void *data) - ret = putenv((char *)iterator->elem); - if (ret < 0) { - SYSERROR("Failed to set environment variable: %s", -- (char *)iterator->elem); -+ (char *)iterator->elem); - goto out_warn_father; - } - } -@@ -1498,10 +1511,10 @@ static int do_start(void *data) - */ - if (handler->conf->no_new_privs) { - ret = prctl(PR_SET_NO_NEW_PRIVS, prctl_arg(1), prctl_arg(0), -- prctl_arg(0), prctl_arg(0)); -+ prctl_arg(0), prctl_arg(0)); - if (ret < 0) { - SYSERROR("Could not set PR_SET_NO_NEW_PRIVS to block " -- "execve() gainable privileges"); -+ "execve() gainable privileges"); - goto out_warn_father; - } - DEBUG("Set PR_SET_NO_NEW_PRIVS to block execve() gainable " -@@ -1550,25 +1563,25 @@ static int do_start(void *data) - * setup on its console ie. the pty allocated in lxc_terminal_setup() so - * make sure that that pty is stdin,stdout,stderr. - */ -- setsid(); -- if (!handler->disable_pty && handler->conf->console.slave >= 0) { -+ setsid(); -+ if (!handler->disable_pty && handler->conf->console.slave >= 0) { - /* isulad:make the given terminal as controlling terminal to avoid warning - * sh: cannot set terminal process group (-1): Inappropriate ioctl for device - * sh: no job control in this shell */ -- if (ioctl(handler->conf->console.slave, TIOCSCTTY, NULL) < 0) { -- ERROR("Faild to make the given terminal the controlling terminal of the calling process"); -- goto out_warn_father; -- } -- if (handler->daemonize || !handler->conf->is_execute) -- ret = set_stdfds(handler->conf->console.slave); -- else -- ret = lxc_terminal_set_stdfds(handler->conf->console.slave); -- if (ret < 0) { -+ if (ioctl(handler->conf->console.slave, TIOCSCTTY, NULL) < 0) { -+ ERROR("Faild to make the given terminal the controlling terminal of the calling process"); -+ goto out_warn_father; -+ } -+ if (handler->daemonize || !handler->conf->is_execute) -+ ret = set_stdfds(handler->conf->console.slave); -+ else -+ ret = lxc_terminal_set_stdfds(handler->conf->console.slave); -+ if (ret < 0) { - ERROR("Failed to redirect std{in,out,err} to pty file " - "descriptor %d", handler->conf->console.slave); - goto out_warn_father; -- } -- } -+ } -+ } - - /* If we mounted a temporary proc, then unmount it now. */ - tmp_proc_unmount(handler->conf); -@@ -1611,7 +1624,7 @@ static int do_start(void *data) - if (stat(handler->conf->init_cwd, &st) < 0 && mkdir_p(handler->conf->init_cwd, 0755) < 0) { - SYSERROR("Try to create directory \"%s\" as workdir failed", handler->conf->init_cwd); - lxc_write_error_message(handler->conf->errpipe[1], "%s:%d: Failed to create workdir: %s.", -- __FILE__, __LINE__, strerror(errno)); -+ __FILE__, __LINE__, strerror(errno)); - goto out_warn_father; - } - if (chdir(handler->conf->init_cwd)) { -@@ -1636,7 +1649,7 @@ static int do_start(void *data) - ret = putenv((char *)iterator->elem); - if (ret < 0) { - SYSERROR("Failed to set environment variable: %s", -- (char *)iterator->elem); -+ (char *)iterator->elem); - goto out_warn_father; - } - } -@@ -1675,9 +1688,9 @@ static int do_start(void *data) - * drop groups if we can, so ensure that we have necessary privilege. - */ - if (lxc_list_empty(&handler->conf->id_map)) -- #if HAVE_LIBCAP -+#if HAVE_LIBCAP - if (lxc_proc_cap_is_set(CAP_SETGID, CAP_EFFECTIVE)) -- #endif -+#endif - /* isulad: set groups for init process, and before we set uid and gid */ - if (!lxc_setgroups(handler->conf->init_groups_len, handler->conf->init_groups)) { - ERROR("Can not set groups"); -@@ -1834,7 +1847,7 @@ static inline int do_share_ns(void *arg) - * setns() will fail here. - */ - SYSERROR("Failed to inherit %s namespace", -- ns_info[i].proc_name); -+ ns_info[i].proc_name); - return -1; - } - -@@ -1855,7 +1868,7 @@ static int lxc_write_container_info(char *filename, pid_t pid, pid_t p_pid, unsi - FILE *pid_fp = NULL; - int ret = 0; - -- pid_fp = fopen(filename, "w"); -+ pid_fp = lxc_fopen(filename, "w"); - if (pid_fp == NULL) { - SYSERROR("Failed to create pidfile '%s'",filename); - ret = -1; -@@ -1898,7 +1911,7 @@ static int lxc_check_container_info(char *filename, pid_t pid, pid_t p_pid, unsi - } - - if (pid != saved_pid || p_pid != saved_ppid -- || start_at != saved_start_time || p_start_at != saved_pstart_time) { -+ || start_at != saved_start_time || p_start_at != saved_pstart_time) { - ERROR("Check container info failed"); - ret = -1; - goto out; -@@ -1973,7 +1986,7 @@ static int lxc_spawn(struct lxc_handler *handler) - return -1; - - ret = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, -- handler->data_sock); -+ handler->data_sock); - if (ret < 0) { - lxc_sync_fini(handler); - return -1; -@@ -2044,7 +2057,7 @@ static int lxc_spawn(struct lxc_handler *handler) - pid_t attacher_pid; - - attacher_pid = lxc_clone(do_share_ns, handler, -- CLONE_VFORK | CLONE_VM | CLONE_FILES); -+ CLONE_VFORK | CLONE_VM | CLONE_FILES); - if (attacher_pid < 0) { - SYSERROR(LXC_CLONE_ERROR); - goto out_delete_net; -@@ -2057,7 +2070,7 @@ static int lxc_spawn(struct lxc_handler *handler) - } - } else { - handler->pid = lxc_raw_clone_cb(do_start, handler, -- handler->ns_on_clone_flags); -+ handler->ns_on_clone_flags); - } - if (handler->pid < 0) { - SYSERROR(LXC_CLONE_ERROR); -@@ -2108,7 +2121,7 @@ static int lxc_spawn(struct lxc_handler *handler) - */ - if (wants_to_map_ids) { - if (!handler->conf->ns_share[LXC_NS_USER] && -- (handler->conf->ns_keep & CLONE_NEWUSER) == 0) { -+ (handler->conf->ns_keep & CLONE_NEWUSER) == 0) { - ret = lxc_map_ids(id_map, handler->pid); - if (ret < 0) { - ERROR("Failed to set up id mapping."); -@@ -2157,16 +2170,16 @@ static int lxc_spawn(struct lxc_handler *handler) - /* Create the network configuration. */ - if (handler->ns_clone_flags & CLONE_NEWNET) { - ret = lxc_network_move_created_netdev_priv(handler->lxcpath, -- handler->name, -- &conf->network, -- handler->pid); -+ handler->name, -+ &conf->network, -+ handler->pid); - if (ret < 0) { - ERROR("Failed to create the configured network"); - goto out_delete_net; - } - - ret = lxc_create_network_unpriv(handler->lxcpath, handler->name, -- &conf->network, handler->pid, conf->hooks_version); -+ &conf->network, handler->pid, conf->hooks_version); - if (ret < 0) { - ERROR("Failed to create the configured network"); - goto out_delete_net; -@@ -2245,10 +2258,7 @@ static int lxc_spawn(struct lxc_handler *handler) - } - - /* isulad: Run oci prestart hook at here */ -- char* oci_hook_args[1]; -- oci_hook_args[0] = alloca(strlen(lxcpath) + 1); -- (void)strlcpy(oci_hook_args[0], lxcpath, strlen(lxcpath) + 1); -- ret = run_lxc_hooks(name, "oci-prestart", conf, oci_hook_args); -+ ret = run_oci_hooks(name, "oci-prestart", conf, lxcpath); - if (ret < 0) { - ERROR("Failed to run oci prestart hooks"); - goto out_delete_net; -@@ -2302,7 +2312,7 @@ static int lxc_spawn(struct lxc_handler *handler) - goto out_abort; - - /* isulad: Run oci prestart hook at here */ -- ret = run_lxc_hooks(name, "oci-poststart", conf, oci_hook_args); -+ ret = run_oci_hooks(name, "oci-poststart", conf, lxcpath); - if (ret < 0) { - ERROR("Failed to run oci poststart hooks"); - goto out_abort; -@@ -2402,8 +2412,8 @@ out: - #define ExitSignalOffset 128 - - int __lxc_start(const char *name, struct lxc_handler *handler, -- struct lxc_operations* ops, void *data, const char *lxcpath, -- bool daemonize, int *error_num, unsigned int start_timeout) -+ struct lxc_operations* ops, void *data, const char *lxcpath, -+ bool daemonize, int *error_num, unsigned int start_timeout) - { - int ret, status, exit_code; - struct lxc_conf *conf = handler->conf; -@@ -2560,7 +2570,7 @@ static struct lxc_operations start_ops = { - }; - - int lxc_start(const char *name, char *const argv[], struct lxc_handler *handler, -- const char *lxcpath, bool daemonize, int *error_num, unsigned int start_timeout) -+ const char *lxcpath, bool daemonize, int *error_num, unsigned int start_timeout) - { - struct start_args start_arg = { - .argv = argv, -@@ -2571,7 +2581,7 @@ int lxc_start(const char *name, char *const argv[], struct lxc_handler *handler, - } - - static void lxc_destroy_container_on_signal(struct lxc_handler *handler, -- const char *name) -+ const char *name) - { - char destroy[PATH_MAX]; - struct lxc_container *c; -@@ -2607,7 +2617,7 @@ static void lxc_destroy_container_on_signal(struct lxc_handler *handler, - - if (!handler->am_root) - ret = userns_exec_full(handler->conf, lxc_rmdir_onedev_wrapper, -- destroy, "lxc_rmdir_onedev_wrapper"); -+ destroy, "lxc_rmdir_onedev_wrapper"); - else - ret = lxc_rmdir_onedev(destroy, NULL); - -@@ -2630,7 +2640,7 @@ static bool do_destroy_container(struct lxc_handler *handler) - - if (!handler->am_root) { - ret = userns_exec_full(handler->conf, storage_destroy_wrapper, -- handler->conf, "storage_destroy_wrapper"); -+ handler->conf, "storage_destroy_wrapper"); - if (ret < 0) - return false; - -@@ -2846,11 +2856,7 @@ int do_lxcapi_clean_resource(char *name, char *lxcpath, struct lxc_conf *conf, p - signal_all_processes(handler); - } - -- char* oci_hook_args[1]; -- oci_hook_args[0] = alloca(strlen(handler->lxcpath) + 1); -- (void)strlcpy(oci_hook_args[0], handler->lxcpath, strlen(handler->lxcpath) + 1); -- -- if (run_lxc_hooks(handler->name, "oci-poststop", handler->conf, oci_hook_args)) { -+ 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; - } -diff --git a/src/lxc/storage/block.c b/src/lxc/storage/block.c -index eb75e70..8998923 100644 ---- a/src/lxc/storage/block.c -+++ b/src/lxc/storage/block.c -@@ -62,7 +62,8 @@ bool blk_detect(const char *path) - - int blk_mount(struct lxc_storage *bdev) - { -- const char *src; -+ const char *src = NULL; -+ - if (strcmp(bdev->type, "blk")) - return -22; - -diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index 88653b4..802bf39 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -113,7 +113,7 @@ void lxc_terminal_sigwinch(int sig) - } - - int lxc_terminal_signalfd_cb(int fd, uint32_t events, void *cbdata, -- struct lxc_epoll_descr *descr) -+ struct lxc_epoll_descr *descr) - { - ssize_t ret; - struct signalfd_siginfo siginfo; -@@ -300,7 +300,7 @@ static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal) - } - - static int lxc_terminal_rotate_write_data(struct lxc_terminal *terminal, const char *buf, -- int bytes_read) -+ int bytes_read) - { - int ret; - struct stat st; -@@ -310,7 +310,7 @@ static int lxc_terminal_rotate_write_data(struct lxc_terminal *terminal, const c - return 0; - - /* A log size <= 0 means that there's no limit on the size of the log -- * file at which point we simply ignore whether the log is supposed to -+ * file at which point we simply ignore whether the log is supposed to - * be rotated or not. - */ - if (terminal->log_size <= 0) -@@ -397,48 +397,49 @@ static int lxc_terminal_rotate_write_data(struct lxc_terminal *terminal, const c - - /* get time buffer */ - static bool get_time_buffer(struct timespec *timestamp, char *timebuffer, -- size_t maxsize) -+ size_t maxsize) - { -- struct tm tm_utc = { 0 }; -- int32_t nanos = 0; -- time_t seconds; -+ struct tm tm_utc = { 0 }; -+ int32_t nanos = 0; -+ time_t seconds; - -- if (!timebuffer || !maxsize) { -- return false; -- } -+ if (!timebuffer || !maxsize) { -+ return false; -+ } - -- seconds = (time_t)timestamp->tv_sec; -- gmtime_r(&seconds, &tm_utc); -- strftime(timebuffer, maxsize, "%Y-%m-%dT%H:%M:%S", &tm_utc); -+ seconds = (time_t)timestamp->tv_sec; -+ gmtime_r(&seconds, &tm_utc); -+ strftime(timebuffer, maxsize, "%Y-%m-%dT%H:%M:%S", &tm_utc); - -- nanos = (int32_t)timestamp->tv_nsec; -- sprintf(timebuffer + strlen(timebuffer), ".%09dZ", nanos); -+ nanos = (int32_t)timestamp->tv_nsec; -+ sprintf(timebuffer + strlen(timebuffer), ".%09dZ", nanos); - -- return true; -+ return true; - } - - /* get now time buffer */ - static bool get_now_time_buffer(char *timebuffer, size_t maxsize) - { -- int err = 0; -- struct timespec ts; -+ int err = 0; -+ struct timespec ts; - -- err = clock_gettime(CLOCK_REALTIME, &ts); -- if (err != 0) { -- ERROR("failed to get time"); -- return false; -- } -+ err = clock_gettime(CLOCK_REALTIME, &ts); -+ if (err != 0) { -+ ERROR("failed to get time"); -+ return false; -+ } - -- return get_time_buffer(&ts, timebuffer, maxsize); -+ return get_time_buffer(&ts, timebuffer, maxsize); - } - - static ssize_t lxc_logger_write(struct lxc_terminal *terminal, const char *type, const char *buf, -- int bytes_read) -+ int bytes_read) - { - logger_json_file *msg = NULL; - ssize_t ret = -1; - size_t len; -- char *json = NULL, timebuffer[64]; -+ char *json = NULL; -+ char timebuffer[64] = { 0 }; - parser_error err = NULL; - struct parser_context ctx = { GEN_OPTIONS_SIMPLIFY | GEN_OPTIONS_NOT_VALIDATE_UTF8, stderr }; - -@@ -473,7 +474,7 @@ cleanup: - } - - static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, const char *type, char *buf, -- int bytes_read) -+ int bytes_read) - { - #define __BUF_CACHE_SIZE (16 * LXC_TERMINAL_BUFFER_SIZE) - static char cache[__BUF_CACHE_SIZE]; -@@ -541,9 +542,10 @@ static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, const char - } - - /* isulad: forward data to all fifos */ --static void lxc_forward_data_to_fifo(struct lxc_list *list, bool is_err, char *buf, int r) -+static void lxc_forward_data_to_fifo(struct lxc_list *list, bool is_err, const char *buf, int r) - { -- struct lxc_list *it,*next; -+ struct lxc_list *it = NULL; -+ struct lxc_list *next = NULL; - struct lxc_fifos_fd *elem = NULL; - - lxc_list_for_each_safe(it, list, next) { -@@ -563,7 +565,8 @@ static void lxc_forward_data_to_fifo(struct lxc_list *list, bool is_err, char *b - /* isulad: judge the fd whether is fifo */ - static bool lxc_terminal_is_fifo(int fd, struct lxc_list *list) - { -- struct lxc_list *it,*next; -+ struct lxc_list *it = NULL; -+ struct lxc_list *next = NULL; - struct lxc_fifos_fd *elem = NULL; - - lxc_list_for_each_safe(it, list, next) { -@@ -576,7 +579,7 @@ static bool lxc_terminal_is_fifo(int fd, struct lxc_list *list) - } - - int lxc_terminal_io_cb(int fd, uint32_t events, void *data, -- struct lxc_epoll_descr *descr) -+ struct lxc_epoll_descr *descr) - { - struct lxc_terminal *terminal = data; - char buf[2 * LXC_TERMINAL_BUFFER_SIZE]; -@@ -684,7 +687,7 @@ static int lxc_terminal_mainloop_add_peer(struct lxc_terminal *terminal) - - if (terminal->peer >= 0) { - ret = lxc_mainloop_add_handler(terminal->descr, terminal->peer, -- lxc_terminal_io_cb, terminal); -+ lxc_terminal_io_cb, terminal); - if (ret < 0) { - WARN("Failed to add terminal peer handler to mainloop"); - return -1; -@@ -695,7 +698,7 @@ static int lxc_terminal_mainloop_add_peer(struct lxc_terminal *terminal) - return 0; - - ret = lxc_mainloop_add_handler(terminal->descr, terminal->tty_state->sigfd, -- lxc_terminal_signalfd_cb, terminal->tty_state); -+ lxc_terminal_signalfd_cb, terminal->tty_state); - if (ret < 0) { - WARN("Failed to add signal handler to mainloop"); - return -1; -@@ -712,7 +715,7 @@ static int lxc_terminal_mainloop_add_pipes(struct lxc_terminal *terminal) - // parent read data from fifo, and send to stdin of container - if (terminal->pipes[0][1] > 0) { - ret = lxc_mainloop_add_handler(terminal->descr, terminal->pipes[0][1], -- lxc_terminal_io_cb, terminal); -+ lxc_terminal_io_cb, terminal); - if (ret) { - ERROR("pipe fd %d not added to mainloop", terminal->pipes[0][1]); - return -1; -@@ -721,7 +724,7 @@ static int lxc_terminal_mainloop_add_pipes(struct lxc_terminal *terminal) - // parent read data from stdout of container, and send to fifo - if (terminal->pipes[1][0] > 0) { - ret = lxc_mainloop_add_handler(terminal->descr, terminal->pipes[1][0], -- lxc_terminal_io_cb, terminal); -+ lxc_terminal_io_cb, terminal); - if (ret) { - ERROR("pipe fd %d not added to mainloop", terminal->pipes[1][0]); - return -1; -@@ -730,7 +733,7 @@ static int lxc_terminal_mainloop_add_pipes(struct lxc_terminal *terminal) - // parent read data from stderr of container, and send to fifo - if (terminal->pipes[2][0] > 0) { - ret = lxc_mainloop_add_handler(terminal->descr, terminal->pipes[2][0], -- lxc_terminal_io_cb, terminal); -+ lxc_terminal_io_cb, terminal); - if (ret) { - ERROR("pipe fd %d not added to mainloop", terminal->pipes[2][0]); - return -1; -@@ -743,14 +746,15 @@ static int lxc_terminal_mainloop_add_pipes(struct lxc_terminal *terminal) - static int lxc_terminal_mainloop_add_fifo(struct lxc_terminal *terminal) - { - int ret = 0; -- struct lxc_list *it,*next; -+ struct lxc_list *it = NULL; -+ struct lxc_list *next = NULL; - struct lxc_fifos_fd *elem = NULL; - - lxc_list_for_each_safe(it, &terminal->fifos, next) { - elem = it->elem; - if (elem->in_fd >= 0) { - ret = lxc_mainloop_add_handler(terminal->descr, elem->in_fd, -- lxc_terminal_io_cb, terminal); -+ lxc_terminal_io_cb, terminal); - if (ret) { - ERROR("console fifo %s not added to mainloop", elem->in_fifo); - return -1; -@@ -761,7 +765,7 @@ static int lxc_terminal_mainloop_add_fifo(struct lxc_terminal *terminal) - } - - int lxc_terminal_mainloop_add(struct lxc_epoll_descr *descr, -- struct lxc_terminal *terminal) -+ struct lxc_terminal *terminal) - { - int ret; - -@@ -796,7 +800,7 @@ int lxc_terminal_mainloop_add(struct lxc_epoll_descr *descr, - } - - ret = lxc_mainloop_add_handler(descr, terminal->master, -- lxc_terminal_io_cb, terminal); -+ lxc_terminal_io_cb, terminal); - if (ret < 0) { - ERROR("Failed to add handler for terminal master fd %d to " - "mainloop", terminal->master); -@@ -879,7 +883,7 @@ static void lxc_terminal_peer_proxy_free(struct lxc_terminal *terminal) - } - - static int lxc_terminal_peer_proxy_alloc(struct lxc_terminal *terminal, -- int sockfd) -+ int sockfd) - { - int ret; - struct termios oldtermio; -@@ -904,14 +908,14 @@ static int lxc_terminal_peer_proxy_alloc(struct lxc_terminal *terminal, - * that the real terminal master will send to / recv from. - */ - ret = openpty(&terminal->proxy.master, &terminal->proxy.slave, NULL, -- NULL, NULL); -+ NULL, NULL); - if (ret < 0) { - SYSERROR("Failed to open proxy terminal"); - return -1; - } - - ret = ttyname_r(terminal->proxy.slave, terminal->proxy.name, -- sizeof(terminal->proxy.name)); -+ sizeof(terminal->proxy.name)); - if (ret < 0) { - SYSERROR("Failed to retrieve name of proxy terminal slave"); - goto on_error; -@@ -1253,7 +1257,7 @@ static int terminal_fifo_open(const char *fifo_path, int flags) - { - int fd = -1; - -- fd = open(fifo_path, flags); -+ fd = lxc_open(fifo_path, flags, 0); - if (fd < 0) { - WARN("Failed to open fifo %s to send message: %s.", fifo_path, - strerror(errno)); -@@ -1491,15 +1495,17 @@ int lxc_terminal_set_stdfds(int fd) - return 0; - - for (i = 0; i < 3; i++) -- if (!__terminal_dup2(fd, (int[]){STDIN_FILENO, STDOUT_FILENO, -- STDERR_FILENO}[i])) -- return -1; -+ if (!__terminal_dup2(fd, (int[]) { -+ STDIN_FILENO, STDOUT_FILENO, -+ STDERR_FILENO -+ }[i])) -+ return -1; - - return 0; - } - - int lxc_terminal_stdin_cb(int fd, uint32_t events, void *cbdata, -- struct lxc_epoll_descr *descr) -+ struct lxc_epoll_descr *descr) - { - int ret; - char c; -@@ -1533,7 +1539,7 @@ int lxc_terminal_stdin_cb(int fd, uint32_t events, void *cbdata, - } - - int lxc_terminal_master_cb(int fd, uint32_t events, void *cbdata, -- struct lxc_epoll_descr *descr) -+ struct lxc_epoll_descr *descr) - { - int r, w; - char buf[LXC_TERMINAL_BUFFER_SIZE]; -@@ -1559,8 +1565,8 @@ int lxc_terminal_getfd(struct lxc_container *c, int *ttynum, int *masterfd) - } - - int lxc_console(struct lxc_container *c, int ttynum, -- int stdinfd, int stdoutfd, int stderrfd, -- int escape) -+ int stdinfd, int stdoutfd, int stderrfd, -+ int escape) - { - int masterfd, ret, ttyfd; - struct lxc_epoll_descr descr; -@@ -1602,7 +1608,7 @@ int lxc_console(struct lxc_container *c, int ttynum, - - if (ts->sigfd != -1) { - ret = lxc_mainloop_add_handler(&descr, ts->sigfd, -- lxc_terminal_signalfd_cb, ts); -+ lxc_terminal_signalfd_cb, ts); - if (ret < 0) { - ERROR("Failed to add signal handler to mainloop"); - goto close_mainloop; -@@ -1610,14 +1616,14 @@ int lxc_console(struct lxc_container *c, int ttynum, - } - - ret = lxc_mainloop_add_handler(&descr, ts->stdinfd, -- lxc_terminal_stdin_cb, ts); -+ lxc_terminal_stdin_cb, ts); - if (ret < 0) { - ERROR("Failed to add stdin handler"); - goto close_mainloop; - } - - ret = lxc_mainloop_add_handler(&descr, ts->masterfd, -- lxc_terminal_master_cb, ts); -+ lxc_terminal_master_cb, ts); - if (ret < 0) { - ERROR("Failed to add master handler"); - goto close_mainloop; -@@ -1625,11 +1631,11 @@ int lxc_console(struct lxc_container *c, int ttynum, - - if (ts->escape >= 1) { - fprintf(stderr, -- "\n" -- "Connected to tty %1$d\n" -- "Type to exit the console, " -- " to enter Ctrl+%2$c itself\n", -- ttynum, 'a' + escape - 1); -+ "\n" -+ "Connected to tty %1$d\n" -+ "Type to exit the console, " -+ " to enter Ctrl+%2$c itself\n", -+ ttynum, 'a' + escape - 1); - } - - if (istty) { -@@ -1729,7 +1735,8 @@ void lxc_terminal_init(struct lxc_terminal *terminal) - /* isulad: if fd == -1, means delete all the fifos*/ - int lxc_terminal_delete_fifo(int fd, struct lxc_list *list) - { -- struct lxc_list *it,*next; -+ struct lxc_list *it = NULL; -+ struct lxc_list *next = NULL; - struct lxc_fifos_fd *elem = NULL; - - lxc_list_for_each_safe(it, list, next) { -@@ -1837,7 +1844,7 @@ int lxc_terminal_add_fifos(struct lxc_conf *conf, const char *fifonames) - } - - if (lxc_mainloop_add_handler(terminal->descr, fifofd_in, -- lxc_terminal_io_cb, terminal)) { -+ lxc_terminal_io_cb, terminal)) { - ERROR("console fifo not added to mainloop"); - lxc_terminal_delete_fifo(fifofd_in, &terminal->fifos); - ret = -1; -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index dc0e6c5..9ce2473 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -56,6 +56,7 @@ - #include "raw_syscalls.h" - #include "syscall_wrappers.h" - #include "utils.h" -+#include "path.h" - - #ifndef HAVE_STRLCPY - #include "include/strlcpy.h" -@@ -81,7 +82,7 @@ lxc_log_define(utils, lxc); - extern bool btrfs_try_remove_subvol(const char *path); - - static int _recursive_rmdir(const char *dirname, dev_t pdev, -- const char *exclude, int level, bool onedev) -+ const char *exclude, int level, bool onedev) - { - struct dirent *direntp; - DIR *dir; -@@ -101,7 +102,7 @@ static int _recursive_rmdir(const char *dirname, dev_t pdev, - int rc; - - if (!strcmp(direntp->d_name, ".") || -- !strcmp(direntp->d_name, "..")) -+ !strcmp(direntp->d_name, "..")) - continue; - - rc = snprintf(pathname, PATH_MAX, "%s/%s", dirname, direntp->d_name); -@@ -155,8 +156,8 @@ static int _recursive_rmdir(const char *dirname, dev_t pdev, - } else { - if (unlink(pathname) < 0) { - if (saved_errno == 0) { -- saved_errno = errno; -- } -+ saved_errno = errno; -+ } - SYSERROR("Failed to delete \"%s\"", pathname); - failed=1; - } -@@ -186,7 +187,7 @@ static int _recursive_rmdir(const char *dirname, dev_t pdev, - static bool is_native_overlayfs(const char *path) - { - if (has_fs_type(path, OVERLAY_SUPER_MAGIC) || -- has_fs_type(path, OVERLAYFS_SUPER_MAGIC)) -+ has_fs_type(path, OVERLAYFS_SUPER_MAGIC)) - return true; - - return false; -@@ -650,7 +651,7 @@ uint64_t fnv_64a_buf(void *buf, size_t len, uint64_t hval) - * multiply by the 64 bit FNV magic prime mod 2^64 - */ - hval += (hval << 1) + (hval << 4) + (hval << 5) + -- (hval << 7) + (hval << 8) + (hval << 40); -+ (hval << 7) + (hval << 8) + (hval << 40); - } - - return hval; -@@ -792,7 +793,7 @@ char *on_path(const char *cmd, const char *rootfs) - lxc_iterate_parts (entry, path, ":") { - if (rootfs) - ret = snprintf(cmdpath, PATH_MAX, "%s/%s/%s", rootfs, -- entry, cmd); -+ entry, cmd); - else - ret = snprintf(cmdpath, PATH_MAX, "%s/%s", entry, cmd); - if (ret < 0 || ret >= PATH_MAX) -@@ -820,7 +821,7 @@ char *choose_init(const char *rootfs) - { - char *retv = NULL; - const char *empty = "", -- *tmp; -+ *tmp; - int ret, env_set = 0; - - if (!getenv("PATH")) { -@@ -1141,7 +1142,7 @@ out: - * setup before executing the container's init - */ - int safe_mount(const char *src, const char *dest, const char *fstype, -- unsigned long flags, const void *data, const char *rootfs) -+ unsigned long flags, const void *data, const char *rootfs) - { - int destfd, ret, saved_errno; - /* Only needs enough for /proc/self/fd/. */ -@@ -1368,7 +1369,7 @@ out: - int lxc_preserve_ns(const int pid, const char *ns) - { - int ret; --/* 5 /proc + 21 /int_as_str + 3 /ns + 20 /NS_NAME + 1 \0 */ -+ /* 5 /proc + 21 /int_as_str + 3 /ns + 20 /NS_NAME + 1 \0 */ - #define __NS_PATH_LEN 50 - char path[__NS_PATH_LEN]; - -@@ -1377,8 +1378,8 @@ int lxc_preserve_ns(const int pid, const char *ns) - * string. - */ - ret = snprintf(path, __NS_PATH_LEN, "/proc/%d/ns%s%s", pid, -- !ns || strcmp(ns, "") == 0 ? "" : "/", -- !ns || strcmp(ns, "") == 0 ? "" : ns); -+ !ns || strcmp(ns, "") == 0 ? "" : "/", -+ !ns || strcmp(ns, "") == 0 ? "" : ns); - if (ret < 0 || (size_t)ret >= __NS_PATH_LEN) { - errno = EFBIG; - return -1; -@@ -1452,7 +1453,7 @@ static int lxc_get_unused_loop_dev_legacy(char *loop_name) - ret = ioctl(fd, LOOP_GET_STATUS64, &lo64); - if (ret < 0) { - if (ioctl(fd, LOOP_GET_STATUS64, &lo64) == 0 || -- errno != ENXIO) { -+ errno != ENXIO) { - close(fd); - fd = -1; - continue; -@@ -1726,7 +1727,7 @@ int lxc_set_death_signal(int signal, pid_t parent) - //pid_t ppid; - - ret = prctl(PR_SET_PDEATHSIG, prctl_arg(signal), prctl_arg(0), -- prctl_arg(0), prctl_arg(0)); -+ prctl_arg(0), prctl_arg(0)); - - /* Check whether we have been orphaned. */ - /* isulad: delete this check, ppid will not be 0 if we shared host pid */ -@@ -1770,7 +1771,7 @@ int fd_nonblock(int fd) - { - long flags; - -- flags = fcntl(fd, F_GETFL); -+ flags = fcntl(fd, F_GETFL); - - return fcntl(fd, F_SETFL, flags | O_NONBLOCK); - } -@@ -1797,7 +1798,7 @@ int recursive_destroy(char *dirname) - struct stat mystat; - - if (!strcmp(direntp->d_name, ".") || -- !strcmp(direntp->d_name, "..")) -+ !strcmp(direntp->d_name, "..")) - continue; - - pathname = must_make_path(dirname, direntp->d_name, NULL); -@@ -1818,7 +1819,7 @@ int recursive_destroy(char *dirname) - if (ret < 0) - r = -1; - -- next: -+next: - free(pathname); - } - -@@ -1850,7 +1851,7 @@ int lxc_setup_keyring(void) - * information leaks. - */ - keyring = keyctl(KEYCTL_JOIN_SESSION_KEYRING, prctl_arg(0), -- prctl_arg(0), prctl_arg(0), prctl_arg(0)); -+ prctl_arg(0), prctl_arg(0), prctl_arg(0)); - if (keyring < 0) { - switch (errno) { - case ENOSYS: -@@ -1913,7 +1914,7 @@ int lxc_file2str(const char *filename, char ret[], int cap) - { - int fd, num_read; - -- if ((fd = open(filename, O_RDONLY | O_CLOEXEC)) == -1) -+ if ((fd = lxc_open(filename, O_RDONLY | O_CLOEXEC, 0)) == -1) - return -1; - if ((num_read = read(fd, ret, cap - 1)) <= 0) - num_read = -1; -@@ -1929,7 +1930,7 @@ int lxc_file2str(const char *filename, char ret[], int cap) - * Such names confuse %s (see scanf(3)), so the string is split and %39c - * is used instead. (except for embedded ')' "(%[^)]c)" would work. - */ --static proc_t *lxc_stat2proc(char *S) -+static proc_t *lxc_stat2proc(const char *S) - { - int num; - proc_t *P = NULL; -@@ -1956,33 +1957,33 @@ static proc_t *lxc_stat2proc(char *S) - return NULL; - } - num = sscanf(tmp + 2, /* skip space after ')' too */ -- "%c " -- "%d %d %d %d %d " -- "%lu %lu %lu %lu %lu " -- "%Lu %Lu %Lu %Lu " /* utime stime cutime cstime */ -- "%ld %ld %ld %ld " -- "%Lu " /* start_time */ -- "%lu " -- "%ld " -- "%lu %lu %lu %lu %lu %lu " -- "%*s %*s %*s %*s " /* discard, no RT signals & Linux 2.1 used hex */ -- "%lu %lu %lu " -- "%d %d " -- "%lu %lu", -- &P->state, -- &P->ppid, &P->pgrp, &P->session, &P->tty, &P->tpgid, -- &P->flags, &P->min_flt, &P->cmin_flt, &P->maj_flt, &P->cmaj_flt, -- &P->utime, &P->stime, &P->cutime, &P->cstime, -- &P->priority, &P->nice, &P->timeout, &P->it_real_value, -- &P->start_time, -- &P->vsize, -- &P->rss, -- &P->rss_rlim, &P->start_code, &P->end_code, &P->start_stack, &P->kstk_esp, -- &P->kstk_eip, -- &P->wchan, &P->nswap, &P->cnswap, -- &P->exit_signal, &P->processor, /* 2.2.1 ends with "exit_signal" */ -- &P->rtprio, &P->sched /* both added to 2.5.18 */ -- ); -+ "%c " -+ "%d %d %d %d %d " -+ "%lu %lu %lu %lu %lu " -+ "%Lu %Lu %Lu %Lu " /* utime stime cutime cstime */ -+ "%ld %ld %ld %ld " -+ "%Lu " /* start_time */ -+ "%lu " -+ "%ld " -+ "%lu %lu %lu %lu %lu %lu " -+ "%*s %*s %*s %*s " /* discard, no RT signals & Linux 2.1 used hex */ -+ "%lu %lu %lu " -+ "%d %d " -+ "%lu %lu", -+ &P->state, -+ &P->ppid, &P->pgrp, &P->session, &P->tty, &P->tpgid, -+ &P->flags, &P->min_flt, &P->cmin_flt, &P->maj_flt, &P->cmaj_flt, -+ &P->utime, &P->stime, &P->cutime, &P->cstime, -+ &P->priority, &P->nice, &P->timeout, &P->it_real_value, -+ &P->start_time, -+ &P->vsize, -+ &P->rss, -+ &P->rss_rlim, &P->start_code, &P->end_code, &P->start_stack, &P->kstk_esp, -+ &P->kstk_eip, -+ &P->wchan, &P->nswap, &P->cnswap, -+ &P->exit_signal, &P->processor, /* 2.2.1 ends with "exit_signal" */ -+ &P->rtprio, &P->sched /* both added to 2.5.18 */ -+ ); - - if (P->tty == 0) - P->tty = -1; /* the old notty val, update elsewhere bef. moving to 0 */ -@@ -2092,3 +2093,67 @@ bool is_non_negative_num(const char *s) - return true; - } - -+void *lxc_common_calloc_s(size_t size) -+{ -+ if (size == 0 || size > SIZE_MAX) { -+ return NULL; -+ } -+ -+ return calloc((size_t)1, size); -+} -+ -+ -+int lxc_mem_realloc(void **newptr, size_t newsize, void *oldptr, size_t oldsize) -+{ -+ void *tmp = NULL; -+ int nret = 0; -+ if (newsize == 0) { -+ goto err_out; -+ } -+ -+ tmp = lxc_common_calloc_s(newsize); -+ if (tmp == NULL) { -+ ERROR("Failed to malloc memory"); -+ goto err_out; -+ } -+ -+ if (oldptr != NULL) { -+ memcpy(tmp, oldptr, (newsize < oldsize) ? newsize : oldsize); -+ -+ memset(oldptr, 0, oldsize); -+ -+ free(oldptr); -+ } -+ -+ *newptr = tmp; -+ return 0; -+ -+err_out: -+ return -1; -+} -+ -+int lxc_open(const char *filename, int flags, mode_t mode) -+{ -+ char rpath[PATH_MAX] = {0x00}; -+ -+ if (cleanpath(filename, rpath, sizeof(rpath)) == NULL) { -+ return -1; -+ } -+ if (mode) { -+ return open(rpath, flags | O_CLOEXEC, mode); -+ } else { -+ return open(rpath, flags | O_CLOEXEC); -+ } -+} -+ -+FILE *lxc_fopen(const char *filename, const char *mode) -+{ -+ char rpath[PATH_MAX] = {0x00}; -+ -+ if (cleanpath(filename, rpath, sizeof(rpath)) == NULL) { -+ return NULL; -+ } -+ -+ return fopen_cloexec(rpath, mode); -+} -+ -diff --git a/src/lxc/utils.h b/src/lxc/utils.h -index 4410ff2..2406ee1 100644 ---- a/src/lxc/utils.h -+++ b/src/lxc/utils.h -@@ -229,8 +229,8 @@ extern bool switch_to_ns(pid_t pid, const char *ns); - extern char *get_template_path(const char *t); - extern int open_without_symlink(const char *target, const char *prefix_skip); - extern int safe_mount(const char *src, const char *dest, const char *fstype, -- unsigned long flags, const void *data, -- const char *rootfs); -+ unsigned long flags, const void *data, -+ const char *rootfs); - extern int lxc_mount_proc_if_needed(const char *rootfs); - extern int open_devnull(void); - extern int set_stdfds(int fd); -@@ -269,7 +269,7 @@ extern int lxc_unstack_mountpoint(const char *path, bool lazy); - * @param[in] args Arguments to be passed to child_fn. - */ - extern int run_command(char *buf, size_t buf_size, int (*child_fn)(void *), -- void *args); -+ void *args); - - /* Concatenate all passed-in strings into one path. Do not fail. If any piece - * is not prefixed with '/', add a '/'. -@@ -324,5 +324,8 @@ extern bool lxc_process_alive(pid_t pid, unsigned long long start_time); - - extern bool is_non_negative_num(const char *s); - extern int lxc_file2str(const char *filename, char ret[], int cap); -- -+extern int lxc_mem_realloc(void **newptr, size_t newsize, void *oldptr, size_t oldsize); -+extern void *lxc_common_calloc_s(size_t size); -+extern int lxc_open(const char *filename, int flags, mode_t mode); -+extern FILE *lxc_fopen(const char *filename, const char *mode); - #endif /* __LXC_UTILS_H */ --- -1.8.3.1 - diff --git a/0102-lxc-fix-compile-warnings.patch b/0102-lxc-fix-compile-warnings.patch deleted file mode 100644 index 88e0d741123ca1ec0365708fa4253826b4af4e3a..0000000000000000000000000000000000000000 --- a/0102-lxc-fix-compile-warnings.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 1615cf43284c6e91c2b0ea0826ce7dba7ab216f0 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Mon, 3 Jun 2019 06:19:07 -0400 -Subject: [PATCH 102/140] lxc: fix compile warnings - -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 1 - - src/lxc/path.c | 5 ----- - src/lxc/utils.c | 2 +- - 3 files changed, 1 insertion(+), 7 deletions(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index ec1667d..e7df336 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4992,7 +4992,6 @@ int run_lxc_hooks(const char *name, char *hookname, struct lxc_conf *conf, - - int run_oci_hooks(const char *name, char *hookname, struct lxc_conf *conf, const char *lxcpath) - { -- struct lxc_list *it; - int which = -1; - - if (strcmp(hookname, "oci-prestart") == 0) { -diff --git a/src/lxc/path.c b/src/lxc/path.c -index 45ab4c3..92692de 100644 ---- a/src/lxc/path.c -+++ b/src/lxc/path.c -@@ -141,7 +141,6 @@ int do_clean_path(const char *respath, const char *limit_respath, - { - char *dest = *dst; - const char *endpos = NULL; -- errno_t ret; - - for (endpos = stpos; *stpos; stpos = endpos) { - while (ISSLASH(*stpos)) { -@@ -184,7 +183,6 @@ char *cleanpath(const char *path, char *realpath, size_t realpath_len) - char *dest = NULL; - const char *stpos = NULL; - const char *limit_respath = NULL; -- errno_t ret; - - if (path == NULL || path[0] == '\0' || \ - realpath == NULL || (realpath_len < PATH_MAX)) { -@@ -293,7 +291,6 @@ static int do_get_symlinks(const char **fullpath, const char *prefix, size_t pre - { - char *buf = NULL; - size_t len; -- errno_t rc = EOK; - ssize_t n; - int ret = -1; - -@@ -398,7 +395,6 @@ static int do_eval_symlinks_in_scope(const char *fullpath, const char *prefix, - const char *start = NULL; - const char *end = NULL; - char *extra_buf = NULL; -- errno_t rc = EOK; - int nret = 0; - int num_links = 0; - -@@ -450,7 +446,6 @@ static char *eval_symlinks_in_scope(const char *fullpath, const char *rootpath) - char *prefix = NULL; - const char *rpath_limit = NULL; - size_t prefix_len; -- errno_t rc = EOK; - - if (fullpath == NULL || rootpath == NULL) { - return NULL; -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index 9ce2473..e674947 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -2106,7 +2106,7 @@ void *lxc_common_calloc_s(size_t size) - int lxc_mem_realloc(void **newptr, size_t newsize, void *oldptr, size_t oldsize) - { - void *tmp = NULL; -- int nret = 0; -+ - if (newsize == 0) { - goto err_out; - } --- -1.8.3.1 - diff --git a/0103-lxc-fix-code-error-in-conf.c.patch b/0103-lxc-fix-code-error-in-conf.c.patch deleted file mode 100644 index 82f64d3a4e2e0d79af401dc7a12310c86e66aeef..0000000000000000000000000000000000000000 --- a/0103-lxc-fix-code-error-in-conf.c.patch +++ /dev/null @@ -1,109 +0,0 @@ -From ae19c33cf486d719210ebe624ab8873369bb3170 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Mon, 3 Jun 2019 11:14:22 -0400 -Subject: [PATCH 103/140] lxc: fix code error in conf.c - -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 21 ++++++++++++++++----- - src/lxc/conf.h | 2 +- - 2 files changed, 17 insertions(+), 6 deletions(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index e7df336..127ef77 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -2446,7 +2446,8 @@ static int check_mount_destination(const char *rootfs, const char *dest) - } - - for(invalid = invalid_destinations; *invalid != NULL; invalid++) { -- char *fullpath, *relpath; -+ char *fullpath = NULL; -+ char *relpath = NULL; - const char *parts[3] = { - rootfs, - *invalid, -@@ -2588,6 +2589,8 @@ retry: - max_retry--; - DEBUG("mount entry with loop dev failed, retry mount." - "retry count left %d", max_retry); -+ if (loop.lofd != -1) -+ close(loop.lofd); - goto retry; - } - } -@@ -2799,7 +2802,9 @@ static int mount_file_entries(const struct lxc_conf *conf, - ret = mount_entry_on_absolute_rootfs(&mntent, rootfs, - lxc_name, lxc_path); - free(mntent.mnt_fsname); -+ mntent.mnt_fsname = NULL; - free(mntent.mnt_dir); -+ mntent.mnt_dir = NULL; - if (ret < 0) - return -1; - } -@@ -4378,8 +4383,9 @@ int lxc_drop_caps(struct lxc_conf *conf) - int ret = 0; - struct lxc_list *iterator = NULL; - char *keep_entry = NULL; -- int i, capid; -- int numcaps = lxc_caps_last_cap() + 1; -+ size_t i = 0; -+ int capid; -+ size_t numcaps = (size_t)lxc_caps_last_cap() + 1; - struct lxc_list *caps = NULL; - int *caplist = NULL; - -@@ -4545,6 +4551,10 @@ static char **merge_ocihook_env(char **oldenvs, size_t env_len, size_t *merge_en - for(j = 0; j < (sizeof(lxc_envs) / sizeof(char *)); j++) { - tmpenv = getenv(lxc_envs[j]); - if (tmpenv && i < (result_len - 1)) { -+ if (strlen(tmpenv) > (SIZE_MAX - 1 - 1 - strlen(lxc_envs[j]))) { -+ lxc_free_array((void **)result, free); -+ return NULL; -+ } - lxcenv_buf = malloc(strlen(tmpenv) + 1 + strlen(lxc_envs[j]) + 1); - if (!lxcenv_buf) { - lxc_free_array((void **)result, free); -@@ -4837,7 +4847,7 @@ static int run_ocihook_script_argv(const char *name, const char *section, - { - int ret; - const char *script = oconf->ocihook->path; -- char *inmsg; -+ char *inmsg = NULL; - - INFO("Executing script \"%s\" for container \"%s\", config section \"%s\".", - script, name, section); -@@ -4990,7 +5000,7 @@ int run_lxc_hooks(const char *name, char *hookname, struct lxc_conf *conf, - return 0; - } - --int run_oci_hooks(const char *name, char *hookname, struct lxc_conf *conf, const char *lxcpath) -+int run_oci_hooks(const char *name, const char *hookname, struct lxc_conf *conf, const char *lxcpath) - { - int which = -1; - -@@ -5327,6 +5337,7 @@ int lxc_clear_init_args(struct lxc_conf *lxc_conf) - int lxc_clear_init_groups(struct lxc_conf *lxc_conf) - { - free(lxc_conf->init_groups); -+ lxc_conf->init_groups = NULL; - lxc_conf->init_groups_len = 0; - - return 0; -diff --git a/src/lxc/conf.h b/src/lxc/conf.h -index 26bb70f..e4bfc48 100644 ---- a/src/lxc/conf.h -+++ b/src/lxc/conf.h -@@ -445,7 +445,7 @@ extern struct lxc_conf *current_config; - - extern int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf, - char *argv[]); --extern int run_oci_hooks(const char *name, char *hookname, struct lxc_conf *conf, const char *lxcpath); -+extern int run_oci_hooks(const char *name, const char *hookname, struct lxc_conf *conf, const char *lxcpath); - - extern int detect_shared_rootfs(void); - extern struct lxc_conf *lxc_conf_init(void); --- -1.8.3.1 - diff --git a/0104-lxc-fix-code-error.patch b/0104-lxc-fix-code-error.patch deleted file mode 100644 index b46007277037e8f86e5b002d9f020f6528695bdd..0000000000000000000000000000000000000000 --- a/0104-lxc-fix-code-error.patch +++ /dev/null @@ -1,179 +0,0 @@ -From 1f2f95d5cc90ecd7d3d8c8a6aab5381cda0483b5 Mon Sep 17 00:00:00 2001 -From: tanyifeng -Date: Mon, 3 Jun 2019 11:27:34 -0400 -Subject: [PATCH 104/140] lxc: fix code error - -Signed-off-by: tanyifeng -Signed-off-by: LiFeng ---- - src/lxc/af_unix.c | 8 +++++++- - src/lxc/cgroups/cgfsng.c | 10 +++++++++- - src/lxc/lxccontainer.c | 2 ++ - src/lxc/path.c | 1 + - src/lxc/terminal.c | 16 ++++++++-------- - src/lxc/utils.c | 8 ++++---- - 6 files changed, 31 insertions(+), 14 deletions(-) - -diff --git a/src/lxc/af_unix.c b/src/lxc/af_unix.c -index 4c45946..1fc8ab0 100644 ---- a/src/lxc/af_unix.c -+++ b/src/lxc/af_unix.c -@@ -204,12 +204,18 @@ int lxc_abstract_unix_recv_fds_timeout(int fd, int *recvfds, int num_recvfds, - struct cmsghdr *cmsg = NULL; - char buf[1] = {0}; - char *cmsgbuf = NULL; -- size_t cmsgbufsize = CMSG_SPACE(num_recvfds * sizeof(int)); -+ size_t cmsgbufsize = 0; - struct timeval out; - - memset(&msg, 0, sizeof(msg)); - memset(&iov, 0, sizeof(iov)); - -+ if (num_recvfds <= 0 || (SIZE_MAX / sizeof(int) < num_recvfds)) { -+ errno = EINVAL; -+ return -1; -+ } -+ -+ cmsgbufsize = CMSG_SPACE((num_recvfds * sizeof(int))); - cmsgbuf = malloc(cmsgbufsize); - if (!cmsgbuf) { - errno = ENOMEM; -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index 67c7a0e..46f13f4 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -1688,7 +1688,7 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, - if (merged) { - char **mc = NULL; - for (mc = merged; *mc; mc++) { -- char *token; -+ char *token = NULL; - char *copy = must_copy_string(*mc); - lxc_iterate_parts(token, copy, ",") { - int mret; -@@ -2249,7 +2249,15 @@ static int cg_legacy_get_data(struct cgroup_ops *ops, const char *filename, - char *controller = NULL; - - len = strlen(filename); -+ if (SIZE_MAX - 1 < len) { -+ errno = EINVAL; -+ return -1; -+ } - controller = calloc(1, len + 1); -+ if (controller == NULL) { -+ errno = ENOMEM; -+ return -1; -+ } - (void)strlcpy(controller, filename, len + 1); - - p = strchr(controller, '.'); -diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index e32f524..72417ed 100644 ---- a/src/lxc/lxccontainer.c -+++ b/src/lxc/lxccontainer.c -@@ -1208,6 +1208,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a - reboot: - if (conf->reboot == REBOOT_INIT) { - /* initialize handler */ -+ lxc_free_handler(handler); - handler = lxc_init_handler(c->name, conf, c->config_path, c->daemonize); - if (!handler) { - ret = 1; -@@ -1248,6 +1249,7 @@ reboot: - conf->reboot = REBOOT_INIT; - goto reboot; - } -+ lxc_free_handler(handler); - - on_error: - if (c->pidfile) { -diff --git a/src/lxc/path.c b/src/lxc/path.c -index 92692de..36d5e0b 100644 ---- a/src/lxc/path.c -+++ b/src/lxc/path.c -@@ -31,6 +31,7 @@ bool specify_current_dir(const char *path) - - bname = basename(basec); - if (bname == NULL) { -+ free(basec); - ERROR("Out of memory"); - return false; - } -diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index 802bf39..a8a0dc9 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -231,7 +231,7 @@ static int lxc_terminal_truncate_log_file(struct lxc_terminal *terminal) - } - - /* -- * isuald: support mult-logfiles -+ * isulad: support mult-logfiles - * */ - static int lxc_terminal_rename_old_log_file(struct lxc_terminal *terminal) - { -@@ -242,10 +242,10 @@ static int lxc_terminal_rename_old_log_file(struct lxc_terminal *terminal) - - for (i = terminal->log_rotate - 1; i > 1; i--) { - ret = sprintf(tmp, "%s.%u", terminal->log_path, i); -- if (ret < 0) -+ if (ret < 0) { - return -EFBIG; -- if (rename_fname) -- free(rename_fname); -+ } -+ free(rename_fname); - rename_fname = strdup(tmp); - ret = sprintf(tmp, "%s.%u", terminal->log_path, (i - 1)); - if (ret < 0) { -@@ -253,13 +253,13 @@ static int lxc_terminal_rename_old_log_file(struct lxc_terminal *terminal) - return -EFBIG; - } - ret = lxc_unpriv(rename(tmp, rename_fname)); -- if (ret < 0 && errno != ENOENT) -+ if (ret < 0 && errno != ENOENT) { -+ free(rename_fname); - return ret; -+ } - } - -- if (rename_fname) -- free(rename_fname); -- -+ free(rename_fname); - return 0; - } - -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index e674947..9db762f 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -1769,11 +1769,11 @@ int fd_cloexec(int fd, bool cloexec) - /* isulad: fd_nonblock */ - int fd_nonblock(int fd) - { -- long flags; -+ int flags; - - flags = fcntl(fd, F_GETFL); - -- return fcntl(fd, F_SETFL, flags | O_NONBLOCK); -+ return fcntl(fd, F_SETFL, (int)((unsigned int)flags | O_NONBLOCK)); - } - - int recursive_destroy(char *dirname) -@@ -2140,9 +2140,9 @@ int lxc_open(const char *filename, int flags, mode_t mode) - return -1; - } - if (mode) { -- return open(rpath, flags | O_CLOEXEC, mode); -+ return open(rpath, (int)((unsigned int)flags | O_CLOEXEC), mode); - } else { -- return open(rpath, flags | O_CLOEXEC); -+ return open(rpath, (int)((unsigned int)flags | O_CLOEXEC)); - } - } - --- -1.8.3.1 - diff --git a/0105-lxc-fix-code-error-warnings.patch b/0105-lxc-fix-code-error-warnings.patch deleted file mode 100644 index 542aa71b6d785fbf93f11e7adf3ecf2bcb16cae0..0000000000000000000000000000000000000000 --- a/0105-lxc-fix-code-error-warnings.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 3e73fc4707851601f3538502e8364a1550da2741 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Mon, 3 Jun 2019 23:02:50 -0400 -Subject: [PATCH 105/140] lxc: fix code error warnings - -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 5 ++++- - src/lxc/lxccontainer.c | 3 +-- - src/lxc/start.c | 2 +- - 3 files changed, 6 insertions(+), 4 deletions(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 127ef77..8311723 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -5325,9 +5325,12 @@ int lxc_clear_init_args(struct lxc_conf *lxc_conf) - { - int i; - -- for (i = 0; i < lxc_conf->init_argc; i++) -+ for (i = 0; i < lxc_conf->init_argc; i++) { - free(lxc_conf->init_argv[i]); -+ lxc_conf->init_argv[i] = NULL; -+ } - free(lxc_conf->init_argv); -+ lxc_conf->init_argv = NULL; - lxc_conf->init_argc = 0; - - return 0; -diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index 72417ed..a09e066 100644 ---- a/src/lxc/lxccontainer.c -+++ b/src/lxc/lxccontainer.c -@@ -1180,6 +1180,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a - if (conf->exit_fd < 0) { - ERROR("Failed to open exit fifo %s: %s.", c->exit_fifo, strerror(errno)); - ret = 1; -+ lxc_free_handler(handler); - goto on_error; - } - } -@@ -1208,7 +1209,6 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a - reboot: - if (conf->reboot == REBOOT_INIT) { - /* initialize handler */ -- lxc_free_handler(handler); - handler = lxc_init_handler(c->name, conf, c->config_path, c->daemonize); - if (!handler) { - ret = 1; -@@ -1249,7 +1249,6 @@ reboot: - conf->reboot = REBOOT_INIT; - goto reboot; - } -- lxc_free_handler(handler); - - on_error: - if (c->pidfile) { -diff --git a/src/lxc/start.c b/src/lxc/start.c -index ccdd844..2380581 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -2421,7 +2421,7 @@ int __lxc_start(const char *name, struct lxc_handler *handler, - ret = lxc_init(name, handler); - if (ret < 0) { - ERROR("Failed to initialize container \"%s\"", name); -- return -1; -+ goto out_fini_nonet; - } - handler->ops = ops; - handler->data = data; --- -1.8.3.1 - diff --git a/0106-set-timeout-to-1s-for-cmds-send-to-lxc-monitor.patch b/0106-set-timeout-to-1s-for-cmds-send-to-lxc-monitor.patch deleted file mode 100644 index 876838263de95d2874009dc802cd122d364ec5ad..0000000000000000000000000000000000000000 --- a/0106-set-timeout-to-1s-for-cmds-send-to-lxc-monitor.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 307920aff38a933a7df5245917933a35f9cf7a15 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Thu, 6 Jun 2019 22:48:38 -0400 -Subject: [PATCH 106/140] set timeout to 1s for cmds send to [lxc monitor] - -Signed-off-by: LiFeng ---- - src/lxc/commands.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/src/lxc/commands.c b/src/lxc/commands.c -index c74b8c1..0802a16 100644 ---- a/src/lxc/commands.c -+++ b/src/lxc/commands.c -@@ -127,10 +127,10 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd) - int ret, rspfd; - struct lxc_cmd_rsp *rsp = &cmd->rsp; - -- /*isulad: add timeout 200ms to avoid long block due to [lxc monitor] error*/ -- ret = lxc_abstract_unix_recv_fds_timeout(sock, &rspfd, 1, rsp, sizeof(*rsp), 200 * 1000); -+ /*isulad: add timeout 1s to avoid long block due to [lxc monitor] error*/ -+ ret = lxc_abstract_unix_recv_fds_timeout(sock, &rspfd, 1, rsp, sizeof(*rsp), 1000 * 1000); - if (ret < 0) { -- SYSWARN("Failed to receive response for command \"%s\"", -+ SYSERROR("Failed to receive response for command \"%s\"", - lxc_cmd_str(cmd->req.cmd)); - - if (errno == ECONNRESET || errno == EAGAIN || errno == EWOULDBLOCK) { --- -1.8.3.1 - diff --git a/0107-add-log-for-failure-of-rename-file.patch b/0107-add-log-for-failure-of-rename-file.patch deleted file mode 100644 index de0c29f6514cc73dad4c6c9927de45759cf4dd2f..0000000000000000000000000000000000000000 --- a/0107-add-log-for-failure-of-rename-file.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 819a1a3a4badd6f794cc161199eb2446a2325cdf Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Mon, 17 Jun 2019 20:17:37 +0800 -Subject: [PATCH 107/140] add log for failure of rename file - -1. add log message of rename operator -2. if rename console file failed, reopen terminal fd - -Signed-off-by: liuhao -Signed-off-by: LiFeng ---- - src/lxc/terminal.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index a8a0dc9..778a0ab 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -293,8 +293,9 @@ static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal) - close(terminal->log_fd); - terminal->log_fd = -1; - ret = lxc_unpriv(rename(terminal->log_path, tmp)); -- if (ret < 0) -- return ret; -+ if (ret < 0) { -+ SYSERROR("Rename container log file failed"); -+ } - - return lxc_terminal_create_log_file(terminal); - } --- -1.8.3.1 - diff --git a/0108-check-calloc-input-valid.patch b/0108-check-calloc-input-valid.patch deleted file mode 100644 index 27a62f3f95fbaba229334141d92da01dccc2add4..0000000000000000000000000000000000000000 --- a/0108-check-calloc-input-valid.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 68336a66df175c8f59e49ded276f95073326bfcd Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Tue, 18 Jun 2019 23:16:09 +0800 -Subject: [PATCH 108/140] check calloc input valid - -check calloc input valid - -Signed-off-by: liuhao -Signed-off-by: LiFeng ---- - src/lxc/terminal.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index 778a0ab..6b117de 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -444,8 +444,11 @@ static ssize_t lxc_logger_write(struct lxc_terminal *terminal, const char *type, - parser_error err = NULL; - struct parser_context ctx = { GEN_OPTIONS_SIMPLIFY | GEN_OPTIONS_NOT_VALIDATE_UTF8, stderr }; - -+ if (bytes_read < 0 || bytes_read >= INT_MAX) { -+ return -1; -+ } - msg = calloc(sizeof(logger_json_file), 1); -- if (!msg) { -+ if (msg == NULL) { - return -errno; - } - msg->log = calloc(bytes_read, 1); --- -1.8.3.1 - diff --git a/0109-add-secure-compile-flags-to-lxc.patch b/0109-add-secure-compile-flags-to-lxc.patch deleted file mode 100644 index 9982169e572fc87df6773a651f44d892441345da..0000000000000000000000000000000000000000 --- a/0109-add-secure-compile-flags-to-lxc.patch +++ /dev/null @@ -1,104 +0,0 @@ -From d723e8b3a179e8f469242c9dc9eaab9383d2ee3b Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Thu, 20 Jun 2019 17:46:40 +0800 -Subject: [PATCH 109/140] add secure compile flags to lxc - -add secure compile flags to lxc - -Signed-off-by: liuhao -Signed-off-by: LiFeng ---- - configure.ac | 25 +++++++++++++++++++------ - src/lxc/Makefile.am | 5 +++++ - 2 files changed, 24 insertions(+), 6 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 4da52a2..a714779 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -44,6 +44,7 @@ AM_INIT_AUTOMAKE([-Wall -Werror -Wno-portability subdir-objects]) - AC_CANONICAL_HOST - AM_PROG_CC_C_O - AC_GNU_SOURCE -+CFLAGS=`echo "${CFLAGS#\-g}"` - - # Test if we have a new enough compiler. - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -@@ -192,6 +193,11 @@ AC_ARG_ENABLE([werror], - [do not treat warnings as errors])], - [], [enable_werror=yes]) - -+AC_ARG_ENABLE([debug], -+ [AC_HELP_STRING([--enable-debug], -+ [set -g into cflags [default=no]])], -+ [], [enable_debug=no]) -+ - # Allow disabling rpath - AC_ARG_ENABLE([rpath], - [AC_HELP_STRING([--enable-rpath], [set rpath in executables [default=no]])], -@@ -200,8 +206,8 @@ AM_CONDITIONAL([ENABLE_RPATH], [test "x$enable_rpath" = "xyes"]) - - # Documentation (manpages) - AC_ARG_ENABLE([doc], -- [AC_HELP_STRING([--enable-doc], [make man pages [default=auto]])], -- [], [enable_doc=auto]) -+ [AC_HELP_STRING([--enable-doc], [make man pages [default=no]])], -+ [], [enable_doc=no]) - - if test "x$enable_doc" = "xyes" -o "x$enable_doc" = "xauto"; then - db2xman="" -@@ -692,18 +698,25 @@ AX_CHECK_COMPILE_FLAG([-Wstrict-prototypes], [CFLAGS="$CFLAGS -Wstrict-prototype - AX_CHECK_COMPILE_FLAG([-fno-strict-aliasing], [CFLAGS="$CFLAGS -fno-strict-aliasing"],,[-Werror]) - AX_CHECK_COMPILE_FLAG([-fstack-clash-protection], [CFLAGS="$CFLAGS -fstack-clash-protection"],,[-Werror]) - AX_CHECK_COMPILE_FLAG([-fstack-protector-strong], [CFLAGS="$CFLAGS -fstack-protector-strong"],,[-Werror]) --AX_CHECK_COMPILE_FLAG([-g], [CFLAGS="$CFLAGS -g"],,[-Werror]) - AX_CHECK_COMPILE_FLAG([--mcet -fcf-protection], [CFLAGS="$CFLAGS --mcet -fcf-protection"],,[-Werror]) - AX_CHECK_COMPILE_FLAG([-Werror=implicit-function-declaration], [CFLAGS="$CFLAGS -Werror=implicit-function-declaration"],,[-Werror]) - --AX_CHECK_LINK_FLAG([-z relro], [LDLAGS="$LDLAGS -z relro"],,[]) --AX_CHECK_LINK_FLAG([-z now], [LDLAGS="$LDLAGS -z now"],,[]) - --CFLAGS="$CFLAGS -Wvla -std=gnu11" -+AX_CHECK_LINK_FLAG([-z relro], [LDFLAGS="$LDFLAGS -z relro"],,[]) -+AX_CHECK_LINK_FLAG([-z now], [LDFLAGS="$LDFLAGS -z now"],,[]) -+AX_CHECK_LINK_FLAG([-z noexecstack], [LDFLAGS="$LDFLAGS -z noexecstack"],,[]) -+ -+LDFLAGS="$LDFLAGS -fPIE -pie" -+ -+CFLAGS="$CFLAGS -Wvla -std=gnu11 -D_FORTIFY_SOURCE=2 -Wall -fPIC -fPIE -pie" - if test "x$enable_werror" = "xyes"; then - CFLAGS="$CFLAGS -Werror" - fi - -+if test "x$enable_debug" = "xyes"; then -+ CFLAGS="$CFLAGS -g" -+fi -+ - AC_ARG_ENABLE([thread-safety], - [AC_HELP_STRING([--enable-thread-safety], [enforce thread-safety otherwise fail the build [default=yes]])], - [], [enable_thread_safety=yes]) -diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am -index 4ec2081..b24fcfd 100644 ---- a/src/lxc/Makefile.am -+++ b/src/lxc/Makefile.am -@@ -233,12 +233,17 @@ endif - - # build the shared library - liblxc_la_CFLAGS = -fPIC \ -+ -fPIE -pie \ - -DPIC \ -+ -D_FORTIFY_SOURCE=2 -Wall \ - $(AM_CFLAGS) \ - -pthread - - liblxc_la_LDFLAGS = -pthread \ - -Wl,-no-undefined \ -+ -Wl,-z,relro \ -+ -Wl,-z,now \ -+ -Wl,-z,noexecstack \ - -Wl,-soname,liblxc.so.$(firstword $(subst ., ,@LXC_ABI@)) \ - -version-info @LXC_ABI_MAJOR@ @YAJL_LIBS@ - --- -1.8.3.1 - diff --git a/0110-add-doc-for-lxc.patch b/0110-add-doc-for-lxc.patch deleted file mode 100644 index c1ca60b07121a7f42ca8b048c6cf750398226f4a..0000000000000000000000000000000000000000 --- a/0110-add-doc-for-lxc.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 3e92134299a675e474074415b68be3755be24c9b Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Fri, 21 Jun 2019 17:20:43 +0800 -Subject: [PATCH 110/140] add doc for lxc - -add doc for lxc - -Signed-off-by: liuhao -Signed-off-by: LiFeng ---- - configure.ac | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/configure.ac b/configure.ac -index a714779..5963fab 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -206,8 +206,8 @@ AM_CONDITIONAL([ENABLE_RPATH], [test "x$enable_rpath" = "xyes"]) - - # Documentation (manpages) - AC_ARG_ENABLE([doc], -- [AC_HELP_STRING([--enable-doc], [make man pages [default=no]])], -- [], [enable_doc=no]) -+ [AC_HELP_STRING([--enable-doc], [make man pages [default=auto]])], -+ [], [enable_doc=auto]) - - if test "x$enable_doc" = "xyes" -o "x$enable_doc" = "xauto"; then - db2xman="" --- -1.8.3.1 - diff --git a/0111-lxc-use-safe_strdup-instead-of-strdup.patch b/0111-lxc-use-safe_strdup-instead-of-strdup.patch deleted file mode 100644 index 257e8b91fe0c888adf1d458f7d1222ac1c460ced..0000000000000000000000000000000000000000 --- a/0111-lxc-use-safe_strdup-instead-of-strdup.patch +++ /dev/null @@ -1,752 +0,0 @@ -From b1ff42de6d5a507d66e9fe091a18d003f3022fbb Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Wed, 3 Jul 2019 23:41:15 -0400 -Subject: [PATCH 111/140] lxc: use safe_strdup instead of strdup - -Signed-off-by: LiFeng ---- - src/lxc/attach.c | 14 +++++--------- - src/lxc/conf.c | 32 +++++++++---------------------- - src/lxc/confile.c | 32 +++++++++---------------------- - src/lxc/json/defs.c | 1 - - src/lxc/json/json_common.c | 41 ++++++++++++---------------------------- - src/lxc/json/json_common.h | 4 +--- - src/lxc/json/logger_json_file.c | 1 - - src/lxc/json/oci_runtime_hooks.c | 4 ++-- - src/lxc/json/oci_runtime_spec.c | 1 - - src/lxc/lxccontainer.c | 16 +++++++--------- - src/lxc/path.c | 20 +++++--------------- - src/lxc/start.c | 18 +++++++++--------- - src/lxc/terminal.c | 18 +++++++----------- - src/lxc/tools/lxc_attach.c | 4 ++-- - src/lxc/tools/lxc_start.c | 2 +- - src/lxc/utils.c | 16 ++++++++++++++++ - src/lxc/utils.h | 2 ++ - 17 files changed, 87 insertions(+), 139 deletions(-) - -diff --git a/src/lxc/attach.c b/src/lxc/attach.c -index 6480eb9..d7b16e3 100644 ---- a/src/lxc/attach.c -+++ b/src/lxc/attach.c -@@ -1070,15 +1070,15 @@ static int lxc_attach_terminal(struct lxc_conf *conf, - /* isulad: if we pass fifo in option, use them as init fifos */ - if (options->init_fifo[0]) { - free(terminal->init_fifo[0]); -- terminal->init_fifo[0] = strdup(options->init_fifo[0]); -+ terminal->init_fifo[0] = safe_strdup(options->init_fifo[0]); - } - if (options->init_fifo[1]) { - free(terminal->init_fifo[1]); -- terminal->init_fifo[1] = strdup(options->init_fifo[1]); -+ terminal->init_fifo[1] = safe_strdup(options->init_fifo[1]); - } - if (options->init_fifo[2]) { - free(terminal->init_fifo[2]); -- terminal->init_fifo[2] = strdup(options->init_fifo[2]); -+ terminal->init_fifo[2] = safe_strdup(options->init_fifo[2]); - } - - ret = lxc_terminal_create(terminal); -@@ -1562,9 +1562,7 @@ int lxc_attach(const char *name, const char *lxcpath, - size_read = read(conf->errpipe[0], errbuf, BUFSIZ); - if (size_read > 0) { - if (err_msg) -- *err_msg = strdup(errbuf); -- if (!(*err_msg)) -- ERROR("Out of memory"); -+ *err_msg = safe_strdup(errbuf); - goto close_mainloop; - } - -@@ -1585,9 +1583,7 @@ int lxc_attach(const char *name, const char *lxcpath, - } - - if (g_attach_timeout_state == ATTACH_TIMEOUT && err_msg != NULL && *err_msg == NULL) { -- *err_msg = strdup("Attach exceeded timeout"); -- if (!(*err_msg)) -- ERROR("Out of memory"); -+ *err_msg = safe_strdup("Attach exceeded timeout"); - } - close_mainloop: - if (options->attach_flags & LXC_ATTACH_TERMINAL) -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 8311723..1dfdaf3 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -1356,9 +1356,7 @@ static int rootfs_parent_mount_private(char *rootfs) - target = get_field(line, 4); - if (!target) - continue; -- tmptarget = strdup(target); -- if (!tmptarget) -- continue; -+ tmptarget = safe_strdup(target); - null_endofword(tmptarget); - if (!strstr(rootfs, tmptarget)) { - free(tmptarget); -@@ -1376,9 +1374,7 @@ static int rootfs_parent_mount_private(char *rootfs) - continue; - null_endofword(opts); - free(options); -- options = strdup(opts); -- if (!options) -- continue; -+ options = safe_strdup(opts); - } - - if (!parent || !options) { -@@ -1417,7 +1413,7 @@ static int lxc_mount_rootfs(struct lxc_conf *conf) - - // isulad: bind mount / to rootfs.mount. then we can do pivot root even if we use / as root. - if (!access(rootfs->mount, F_OK)) { -- rootfs->path = strdup("/"); -+ rootfs->path = safe_strdup("/"); - if (mount("/", rootfs->mount, NULL, MS_BIND, 0)) { - SYSERROR("Failed to mount / to %s.", rootfs->mount); - return -1; -@@ -2225,9 +2221,7 @@ int parse_mntopts(const char *mntopts, unsigned long *mntflags, unsigned long *p - if (!mntopts) - return 0; - -- s = strdup(mntopts); -- if (!s) -- return -1; -+ s = safe_strdup(mntopts); - - size = strlen(s) + 1; - data = malloc(size); -@@ -4026,7 +4020,7 @@ static int setup_populate_devs(const struct lxc_rootfs *rootfs, struct lxc_list - return -1; - - /* create any missing directories */ -- pathdirname = strdup(path); -+ pathdirname = safe_strdup(path); - pathdirname = dirname(pathdirname); - ret = mkdir_p(pathdirname, 0750); - free(pathdirname); -@@ -4545,7 +4539,7 @@ static char **merge_ocihook_env(char **oldenvs, size_t env_len, size_t *merge_en - - for(i = 0; i < env_len; i++) { - if (oldenvs[i]) -- result[i] = strdup(oldenvs[i]); -+ result[i] = safe_strdup(oldenvs[i]); - } - - for(j = 0; j < (sizeof(lxc_envs) / sizeof(char *)); j++) { -@@ -4869,7 +4863,7 @@ static char *get_root_path(const char *path, const char *backend) - char *tmp = NULL; - - if (!path) { -- ret = strdup("/"); -+ ret = safe_strdup("/"); - return ret; - } - if (!backend) { -@@ -4885,20 +4879,12 @@ static char *get_root_path(const char *path, const char *backend) - return NULL; - } - tmp++; -- ret = strdup(tmp); -- if (!ret) { -- ERROR("Out of memory"); -- return NULL; -- } -+ ret = safe_strdup(tmp); - return ret; - } - - default_out: -- ret = strdup(path); -- if (!ret) { -- ERROR("Out of memory"); -- return NULL; -- } -+ ret = safe_strdup(path); - return ret; - } - -diff --git a/src/lxc/confile.c b/src/lxc/confile.c -index 216a688..8262d1e 100644 ---- a/src/lxc/confile.c -+++ b/src/lxc/confile.c -@@ -1011,9 +1011,7 @@ static int set_config_group(const char *key, const char *value, - if (lxc_config_value_empty(value)) - return lxc_clear_groups(lxc_conf); - -- groups = strdup(value); -- if (!groups) -- return -1; -+ groups = safe_strdup(value); - - /* In case several groups are specified in a single line split these - * groups in a single element for the list. -@@ -2281,7 +2279,7 @@ static int set_config_populate_device(const char *key, const char *value, - int ret = 0, major = 0, minor = 0; - uid_t uid = (uid_t)-1; - gid_t gid = (gid_t)-1; -- char name[PATH_MAX] = {0}; -+ char name[4096] = {0}; /* MAX dev path name */ - char type[3] = {0}; - char *replace_value = NULL; - mode_t filemode = 0; -@@ -2295,7 +2293,7 @@ static int set_config_populate_device(const char *key, const char *value, - /* lxc.populate.device = PATH_IN_CONTAINER:DEVICETYPE:MAJOR:MINOR:MODE:UID:GID - * For e.g. lxc.populate.device = /dev/sda:b:8:0:0666:0:0 - */ -- ret = sscanf(value, "%[^:]:%2[^:]:%i:%i:%i:%u:%u", name, type, &major, &minor, &filemode, &uid, &gid); -+ ret = sscanf(value, "%4095[^:]:%2[^:]:%i:%i:%i:%u:%u", name, type, &major, &minor, &filemode, &uid, &gid); - if (ret != 7) - return -1; - -@@ -2306,9 +2304,7 @@ static int set_config_populate_device(const char *key, const char *value, - if (strcmp(name, dev_elem->name) != 0) - continue; - -- replace_value = strdup(type); -- if (!replace_value) -- return -1; -+ replace_value = safe_strdup(type); - - free(dev_elem->type); - dev_elem->type = replace_value; -@@ -2332,13 +2328,9 @@ static int set_config_populate_device(const char *key, const char *value, - goto on_error; - memset(dev_elem, 0, sizeof(*dev_elem)); - -- dev_elem->name = strdup(name); -- if (!dev_elem->name) -- goto on_error; -+ dev_elem->name = safe_strdup(name); - -- dev_elem->type = strdup(type); -- if (!dev_elem->type) -- goto on_error; -+ dev_elem->type = safe_strdup(type); - - dev_elem->file_mode = filemode; - dev_elem->maj = major; -@@ -2373,10 +2365,7 @@ static int set_config_rootfs_masked_paths(const char *key, const char *value, - if (!list_item) - goto on_error; - -- list_item->elem = strdup(value); -- -- if (!list_item->elem) -- goto on_error; -+ list_item->elem = safe_strdup(value); - - lxc_list_add_tail(&lxc_conf->rootfs.maskedpaths, list_item); - -@@ -2401,10 +2390,7 @@ static int set_config_rootfs_ro_paths(const char *key, const char *value, - if (!list_item) - goto on_error; - -- list_item->elem = strdup(value); -- -- if (!list_item->elem) -- goto on_error; -+ list_item->elem = safe_strdup(value); - - lxc_list_add_tail(&lxc_conf->rootfs.ropaths, list_item); - -@@ -2446,7 +2432,7 @@ static int set_config_systemd(const char *key, const char *value, - ERROR("Empty umask"); - return -1; - } -- lxc_conf->systemd = strdup(value); -+ lxc_conf->systemd = safe_strdup(value); - return 0; - } - -diff --git a/src/lxc/json/defs.c b/src/lxc/json/defs.c -index e7d9a09..8a052a8 100644 ---- a/src/lxc/json/defs.c -+++ b/src/lxc/json/defs.c -@@ -4,7 +4,6 @@ - #endif - #include - #include --#include "securec.h" - #include "defs.h" - - defs_hook *make_defs_hook(yajl_val tree, struct parser_context *ctx, parser_error *err) { -diff --git a/src/lxc/json/json_common.c b/src/lxc/json/json_common.c -index 54b7b61..bea9b14 100755 ---- a/src/lxc/json/json_common.c -+++ b/src/lxc/json/json_common.c -@@ -381,23 +381,6 @@ int common_safe_int(const char *numstr, int *converted) { - return 0; - } - --char *safe_strdup(const char *src) --{ -- char *dst = NULL; -- -- if (src == NULL) { -- return NULL; -- } -- -- dst = strdup(src); -- if (dst == NULL) { -- abort(); -- } -- -- return dst; --} -- -- - yajl_gen_status gen_json_map_int_int(void *ctx, json_map_int_int *map, struct parser_context *ptx, parser_error *err) { - yajl_gen_status stat = yajl_gen_status_ok; - yajl_gen g = (yajl_gen) ctx; -@@ -522,12 +505,12 @@ int append_json_map_int_int(json_map_int_int *map, int key, int val) { - vals = safe_malloc(len * sizeof(int)); - - if (map->len) { -- if (memcpy(keys, map->keys, map->len * sizeof(int)) != EOK) { -+ if (memcpy(keys, map->keys, map->len * sizeof(int)) != NULL) { - free(keys); - free(vals); - return -1; - } -- if (memcpy(vals, map->values, map->len * sizeof(int)) != EOK) { -+ if (memcpy(vals, map->values, map->len * sizeof(int)) != NULL) { - free(keys); - free(vals); - return -1; -@@ -663,12 +646,12 @@ int append_json_map_int_bool(json_map_int_bool *map, int key, bool val) { - vals = safe_malloc(len * sizeof(bool)); - - if (map->len) { -- if (memcpy(keys, map->keys, map->len * sizeof(int)) != EOK) { -+ if (memcpy(keys, map->keys, map->len * sizeof(int)) != NULL) { - free(keys); - free(vals); - return -1; - } -- if (memcpy(vals, map->values, map->len * sizeof(bool)) != EOK) { -+ if (memcpy(vals, map->values, map->len * sizeof(bool)) != NULL) { - free(keys); - free(vals); - return -1; -@@ -803,12 +786,12 @@ int append_json_map_int_string(json_map_int_string *map, int key, const char *va - vals = safe_malloc(len * sizeof(char *)); - - if (map->len) { -- if (memcpy(keys, map->keys, map->len * sizeof(int)) != EOK) { -+ if (memcpy(keys, map->keys, map->len * sizeof(int)) != NULL) { - free(keys); - free(vals); - return -1; - } -- if (memcpy(vals, map->values, map->len * sizeof(char *)) != EOK) { -+ if (memcpy(vals, map->values, map->len * sizeof(char *)) != NULL) { - free(keys); - free(vals); - return -1; -@@ -930,12 +913,12 @@ int append_json_map_string_int(json_map_string_int *map, const char *key, int va - vals = safe_malloc(len * sizeof(int)); - - if (map->len) { -- if (memcpy(keys, map->keys, map->len * sizeof(char *)) != EOK) { -+ if (memcpy(keys, map->keys, map->len * sizeof(char *)) != NULL) { - free(keys); - free(vals); - return -1; - } -- if (memcpy(vals, map->values, map->len * sizeof(int)) != EOK) { -+ if (memcpy(vals, map->values, map->len * sizeof(int)) != NULL) { - free(keys); - free(vals); - return -1; -@@ -1052,12 +1035,12 @@ int append_json_map_string_bool(json_map_string_bool *map, const char *key, bool - vals = safe_malloc(len * sizeof(bool)); - - if (map->len) { -- if (memcpy(keys, map->keys, map->len * sizeof(char *)) != EOK) { -+ if (memcpy(keys, map->keys, map->len * sizeof(char *)) != NULL) { - free(keys); - free(vals); - return -1; - } -- if (memcpy(vals, map->values, map->len * sizeof(bool)) != EOK) { -+ if (memcpy(vals, map->values, map->len * sizeof(bool)) != NULL) { - free(keys); - free(vals); - return -1; -@@ -1181,12 +1164,12 @@ int append_json_map_string_string(json_map_string_string *map, const char *key, - vals = safe_malloc(len * sizeof(char *)); - - if (map->len) { -- if (memcpy(keys, map->keys, map->len * sizeof(char *)) != EOK) { -+ if (memcpy(keys, map->keys, map->len * sizeof(char *)) != NULL) { - free(keys); - free(vals); - return -1; - } -- if (memcpy(vals, map->values, map->len * sizeof(char *)) != EOK) { -+ if (memcpy(vals, map->values, map->len * sizeof(char *)) != NULL) { - free(keys); - free(vals); - return -1; -diff --git a/src/lxc/json/json_common.h b/src/lxc/json/json_common.h -index 218a837..60aa5fd 100755 ---- a/src/lxc/json/json_common.h -+++ b/src/lxc/json/json_common.h -@@ -9,7 +9,7 @@ - #include - #include - #include --#include "securec.h" -+#include "utils.h" - - #ifdef __cplusplus - extern "C" { -@@ -94,8 +94,6 @@ int common_safe_int64(const char *numstr, int64_t *converted); - - int common_safe_int(const char *numstr, int *converted); - --char *safe_strdup(const char *src); -- - typedef struct { - int *keys; - int *values; -diff --git a/src/lxc/json/logger_json_file.c b/src/lxc/json/logger_json_file.c -index 409ea11..842d35b 100644 ---- a/src/lxc/json/logger_json_file.c -+++ b/src/lxc/json/logger_json_file.c -@@ -4,7 +4,6 @@ - #endif - #include - #include --#include "securec.h" - #include "logger_json_file.h" - - logger_json_file *make_logger_json_file(yajl_val tree, struct parser_context *ctx, parser_error *err) { -diff --git a/src/lxc/json/oci_runtime_hooks.c b/src/lxc/json/oci_runtime_hooks.c -index 43ff8d7..41ddb67 100644 ---- a/src/lxc/json/oci_runtime_hooks.c -+++ b/src/lxc/json/oci_runtime_hooks.c -@@ -34,7 +34,7 @@ oci_runtime_spec_hooks *oci_runtime_spec_hooks_parse_file(const char *filename, - char errbuf[PARSE_ERR_BUFFER_SIZE]; - if (content == NULL) { - if (asprintf(err, "cannot read the file: %s", filename) < 0) { -- *err = strdup("error allocating memory"); -+ *err = safe_strdup("error allocating memory"); - } - return NULL; - } -@@ -42,7 +42,7 @@ oci_runtime_spec_hooks *oci_runtime_spec_hooks_parse_file(const char *filename, - free(content); - if (tree == NULL) { - if (asprintf(err, "cannot parse the file: %s", errbuf) < 0) { -- *err = strdup("error allocating memory"); -+ *err = safe_strdup("error allocating memory"); - } - return NULL; - } -diff --git a/src/lxc/json/oci_runtime_spec.c b/src/lxc/json/oci_runtime_spec.c -index 4ccb635..fd342de 100644 ---- a/src/lxc/json/oci_runtime_spec.c -+++ b/src/lxc/json/oci_runtime_spec.c -@@ -4,7 +4,6 @@ - #endif - #include - #include --#include "securec.h" - #include "oci_runtime_spec.h" - - oci_runtime_spec_hooks *make_oci_runtime_spec_hooks(yajl_val tree, struct parser_context *ctx, parser_error *err) { -diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index a09e066..ede4c88 100644 ---- a/src/lxc/lxccontainer.c -+++ b/src/lxc/lxccontainer.c -@@ -1055,9 +1055,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a - if (!started) { - size_read = read(conf->errpipe[0], errbuf, BUFSIZ); - if (size_read > 0) { -- conf->errmsg = strdup(errbuf); -- if (!conf->errmsg) -- ERROR("Out of memory"); -+ conf->errmsg = safe_strdup(errbuf); - } - } - close(conf->errpipe[0]); -@@ -3199,7 +3197,7 @@ static bool container_destroy(struct lxc_container *c, - ERROR("Failed to destroy directory \"%s\" for \"%s\"", path, - c->name); - sprintf(msg, "Failed to destroy directory \"%s\": %s", path, errno ? strerror(errno) : "error"); -- c->error_string = strdup(msg); -+ c->error_string = safe_strdup(msg); - goto out; - } - INFO("Destroyed directory \"%s\" for \"%s\"", path, c->name); -@@ -5147,17 +5145,17 @@ static bool do_lxcapi_set_terminal_default_fifos(struct lxc_container *c, const - if (in) { - if (conf->console.init_fifo[0]) - free(conf->console.init_fifo[0]); -- conf->console.init_fifo[0] = strdup(in); -+ conf->console.init_fifo[0] = safe_strdup(in); - } - if (out) { - if (conf->console.init_fifo[1]) - free(conf->console.init_fifo[1]); -- conf->console.init_fifo[1] = strdup(out); -+ conf->console.init_fifo[1] = safe_strdup(out); - } - if (err) { - if (conf->console.init_fifo[2]) - free(conf->console.init_fifo[2]); -- conf->console.init_fifo[2] = strdup(err); -+ conf->console.init_fifo[2] = safe_strdup(err); - } - - container_mem_unlock(c); -@@ -5181,7 +5179,7 @@ static bool do_lxcapi_set_container_info_file(struct lxc_container *c, const cha - conf = c->lxc_conf; - if (conf->container_info_file) - free(conf->container_info_file); -- conf->container_info_file = strdup(info_file); -+ conf->container_info_file = safe_strdup(info_file); - - container_mem_unlock(c); - return true; -@@ -5347,7 +5345,7 @@ static struct lxc_container *do_lxc_container_new(const char *name, const char * - fprintf(stderr, "Failed to get lxc path for %s\n", name); - goto err; - } -- c->config_path = strdup(tmp); -+ c->config_path = safe_strdup(tmp); - } - if (!c->config_path) { - fprintf(stderr, "Failed to allocate memory for %s\n", name); -diff --git a/src/lxc/path.c b/src/lxc/path.c -index 36d5e0b..c545887 100644 ---- a/src/lxc/path.c -+++ b/src/lxc/path.c -@@ -23,11 +23,7 @@ bool specify_current_dir(const char *path) - char *basec = NULL, *bname = NULL; - bool res = false; - -- basec = strdup(path); -- if (!basec) { -- ERROR("Out of memory"); -- return false; -- } -+ basec = safe_strdup(path); - - bname = basename(basec); - if (bname == NULL) { -@@ -106,13 +102,7 @@ bool filepath_split(const char *path, char **dir, char **base) - memcpy(*dir, path, i + 1); - *(*dir + i + 1) = '\0'; - -- *base = strdup(path + i + 1); -- if (!*base) { -- ERROR("Out of memory"); -- free(*dir); -- *dir = NULL; -- return false; -- } -+ *base = safe_strdup(path + i + 1); - - return true; - } -@@ -459,7 +449,7 @@ static char *eval_symlinks_in_scope(const char *fullpath, const char *rootpath) - } - - if (!strcmp(fullpath, root)) { -- return strdup(fullpath); -+ return safe_strdup(fullpath); - } - - if (strstr(fullpath, root) == NULL) { -@@ -592,7 +582,7 @@ char *path_relative(const char *basepath, const char *targpath) - } - - if (strcmp(base, targ) == 0) -- return strdup("."); -+ return safe_strdup("."); - - bl = strlen(base); - tl = strlen(targ); -@@ -646,5 +636,5 @@ char *path_relative(const char *basepath, const char *targpath) - return buf; - } - -- return strdup(targ + t0); -+ return safe_strdup(targ + t0); - } -diff --git a/src/lxc/start.c b/src/lxc/start.c -index 2380581..d6c706e 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -2795,35 +2795,35 @@ static int clean_resource_set_env(struct lxc_handler *handler) - /* Start of environment variable setup for hooks. */ - if (name) { - snprintf(bufstr, PATH_MAX + 1, "LXC_NAME=%s", name); -- conf->ocihooks->poststop[i]->env[j++] = strdup(bufstr); -+ 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++] = strdup(bufstr); -+ 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++] = strdup(bufstr); -+ 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++] = strdup(bufstr); -+ 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++] = strdup(bufstr); -+ 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++] = strdup(bufstr); -+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup(bufstr); - } -- conf->ocihooks->poststop[i]->env[j++] = strdup("LXC_CGNS_AWARE=1"); -+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup("LXC_CGNS_AWARE=1"); - - snprintf(bufstr, PATH_MAX + 1, "LXC_PID=%d", handler->pid); -- conf->ocihooks->poststop[i]->env[j++] = strdup(bufstr); -+ 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++] = strdup(bufstr); -+ conf->ocihooks->poststop[i]->env[j++] = safe_strdup(bufstr); - } - conf->ocihooks->poststop[i]->env_len = j; - /* End of environment variable setup for hooks. */ -diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index 6b117de..970db69 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -246,7 +246,7 @@ static int lxc_terminal_rename_old_log_file(struct lxc_terminal *terminal) - return -EFBIG; - } - free(rename_fname); -- rename_fname = strdup(tmp); -+ rename_fname = safe_strdup(tmp); - ret = sprintf(tmp, "%s.%u", terminal->log_path, (i - 1)); - if (ret < 0) { - free(rename_fname); -@@ -457,10 +457,10 @@ static ssize_t lxc_logger_write(struct lxc_terminal *terminal, const char *type, - } - memcpy(msg->log, buf, bytes_read); - msg->log_len = bytes_read; -- msg->stream = type ? strdup(type) : strdup("stdout"); -+ msg->stream = type ? safe_strdup(type) : safe_strdup("stdout"); - - get_now_time_buffer(timebuffer, sizeof(timebuffer)); -- msg->time = strdup(timebuffer); -+ msg->time = safe_strdup(timebuffer); - - json = logger_json_file_generate_json(msg, &ctx, &err); - if (!json) { -@@ -1324,9 +1324,9 @@ static int lxc_terminal_set_fifo(struct lxc_terminal *console, const char *in, c - } - memset(fifo_elem, 0, sizeof(*fifo_elem)); - -- fifo_elem->in_fifo = strdup(in ? in : ""); -- fifo_elem->out_fifo = strdup(out ? out : ""); -- fifo_elem->err_fifo = strdup(err ? err : ""); -+ fifo_elem->in_fifo = safe_strdup(in ? in : ""); -+ fifo_elem->out_fifo = safe_strdup(out ? out : ""); -+ fifo_elem->err_fifo = safe_strdup(err ? err : ""); - fifo_elem->in_fd = fifofd_in; - fifo_elem->out_fd = fifofd_out; - fifo_elem->err_fd = fifofd_err; -@@ -1810,11 +1810,7 @@ int lxc_terminal_add_fifos(struct lxc_conf *conf, const char *fifonames) - char *tmp = NULL, *saveptr = NULL, *in = NULL, *out = NULL, *err = NULL; - const char *none_fifo_name = "none"; - -- tmp = strdup(fifonames); -- if (!tmp) { -- ret = -1; -- goto free_out; -- } -+ tmp = safe_strdup(fifonames); - - in = strtok_r(tmp, "&&&&", &saveptr); - if (!in) { -diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c -index 854b3a2..7d51ad7 100644 ---- a/src/lxc/tools/lxc_attach.c -+++ b/src/lxc/tools/lxc_attach.c -@@ -309,7 +309,7 @@ static int do_attach_foreground(struct lxc_container *c, lxc_attach_command_t *c - } - out: - if (c->lxc_conf->errmsg) -- *errmsg = strdup(c->lxc_conf->errmsg); -+ *errmsg = safe_strdup(c->lxc_conf->errmsg); - return wexit; - } - -@@ -353,7 +353,7 @@ static int do_attach_background(struct lxc_container *c, lxc_attach_command_t *c - msgpipe[1] = -1; - size_read = read(msgpipe[0], msgbuf, BUFSIZ); - if (size_read > 0) { -- *errmsg = strdup(msgbuf); -+ *errmsg = safe_strdup(msgbuf); - ret = -1; - } - -diff --git a/src/lxc/tools/lxc_start.c b/src/lxc/tools/lxc_start.c -index af63f58..e48e5b3 100644 ---- a/src/lxc/tools/lxc_start.c -+++ b/src/lxc/tools/lxc_start.c -@@ -360,7 +360,7 @@ int main(int argc, char *argv[]) - - /* isulad: fifo used to monitor state of monitor process */ - if (my_args.exit_monitor_fifo != NULL) { -- c->exit_fifo = strdup(my_args.exit_monitor_fifo); -+ c->exit_fifo = safe_strdup(my_args.exit_monitor_fifo); - } - - /* isulad: add start timeout */ -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index 9db762f..e6e8905 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -2157,3 +2157,19 @@ FILE *lxc_fopen(const char *filename, const char *mode) - return fopen_cloexec(rpath, mode); - } - -+char *safe_strdup(const char *src) -+{ -+ char *dst = NULL; -+ -+ if (src == NULL) { -+ return NULL; -+ } -+ -+ dst = strdup(src); -+ if (dst == NULL) { -+ abort(); -+ } -+ -+ return dst; -+} -+ -diff --git a/src/lxc/utils.h b/src/lxc/utils.h -index 2406ee1..0b33f69 100644 ---- a/src/lxc/utils.h -+++ b/src/lxc/utils.h -@@ -328,4 +328,6 @@ extern int lxc_mem_realloc(void **newptr, size_t newsize, void *oldptr, size_t o - extern void *lxc_common_calloc_s(size_t size); - extern int lxc_open(const char *filename, int flags, mode_t mode); - extern FILE *lxc_fopen(const char *filename, const char *mode); -+extern char *safe_strdup(const char *src); -+ - #endif /* __LXC_UTILS_H */ --- -1.8.3.1 - diff --git a/0112-fix-secure-errors.patch b/0112-fix-secure-errors.patch deleted file mode 100644 index 617cd16c381f96cf18db194ba10b0b044ce45f11..0000000000000000000000000000000000000000 --- a/0112-fix-secure-errors.patch +++ /dev/null @@ -1,278 +0,0 @@ -From 57d1ff71ce9c6d456e2fcaa8ca1229419d184ea9 Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Thu, 4 Jul 2019 11:08:26 +0800 -Subject: [PATCH 112/140] fix secure errors - -1. use snprintf replace sprintf -2. use malloc replace alloca - -Signed-off-by: liuhao -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 6 ++++-- - src/lxc/confile.c | 38 ++++++++++++++++++++++++-------------- - src/lxc/json/json_common.c | 12 ++++++------ - src/lxc/lxccontainer.c | 8 ++++++-- - src/lxc/terminal.c | 31 ++++++++++++++++++++++++------- - 5 files changed, 64 insertions(+), 31 deletions(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 1dfdaf3..996d267 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4543,18 +4543,20 @@ static char **merge_ocihook_env(char **oldenvs, size_t env_len, size_t *merge_en - } - - for(j = 0; j < (sizeof(lxc_envs) / sizeof(char *)); j++) { -+ size_t env_buf_len = 0; - tmpenv = getenv(lxc_envs[j]); - if (tmpenv && i < (result_len - 1)) { - if (strlen(tmpenv) > (SIZE_MAX - 1 - 1 - strlen(lxc_envs[j]))) { - lxc_free_array((void **)result, free); - return NULL; - } -- lxcenv_buf = malloc(strlen(tmpenv) + 1 + strlen(lxc_envs[j]) + 1); -+ env_buf_len = ((strlen(tmpenv) + 1) + strlen(lxc_envs[j])) + 1; -+ lxcenv_buf = malloc(env_buf_len); - if (!lxcenv_buf) { - lxc_free_array((void **)result, free); - return NULL; - } -- if (sprintf(lxcenv_buf, "%s=%s", lxc_envs[j], tmpenv) < 0) { -+ if (snprintf(lxcenv_buf, env_buf_len, "%s=%s", lxc_envs[j], tmpenv) < 0) { - free(lxcenv_buf); - continue; - } -diff --git a/src/lxc/confile.c b/src/lxc/confile.c -index 8262d1e..8a082d5 100644 ---- a/src/lxc/confile.c -+++ b/src/lxc/confile.c -@@ -3802,9 +3802,11 @@ static int get_config_no_new_privs(const char *key, char *retv, int inlen, - static int get_config_prlimit(const char *key, char *retv, int inlen, - struct lxc_conf *c, void *data) - { -- int fulllen = 0, len; -+ int fulllen = 0; -+ int len = 0; - bool get_all = false; -- struct lxc_list *it; -+ struct lxc_list *it = NULL; -+ int nret = 0; - - if (!retv) - inlen = 0; -@@ -3818,32 +3820,40 @@ static int get_config_prlimit(const char *key, char *retv, int inlen, - else - return -1; - -+#define MAX_LIMIT_BUF_LEN ((INTTYPE_TO_STRLEN(uint64_t) * 2) + 2) - lxc_list_for_each(it, &c->limits) { - /* 2 colon separated 64 bit integers or the word 'unlimited' */ -- char buf[INTTYPE_TO_STRLEN(uint64_t) * 2 + 2]; -+ char buf[MAX_LIMIT_BUF_LEN] = { 0 }; - int partlen; - struct lxc_limit *lim = it->elem; - - if (lim->limit.rlim_cur == RLIM_INFINITY) { -- memcpy(buf, "unlimited", STRLITERALLEN("unlimited") + 1); -+ if (memcpy(buf, "unlimited", STRLITERALLEN("unlimited") + 1) == NULL) { -+ return -1; -+ } - partlen = STRLITERALLEN("unlimited"); - } else { -- partlen = sprintf(buf, "%" PRIu64, -- (uint64_t)lim->limit.rlim_cur); -+ partlen = snprintf(buf, MAX_LIMIT_BUF_LEN, "%" PRIu64, (uint64_t)lim->limit.rlim_cur); -+ if (partlen < 0) { -+ return -1; -+ } - } - - if (lim->limit.rlim_cur != lim->limit.rlim_max) { -- if (lim->limit.rlim_max == RLIM_INFINITY) -- memcpy(buf + partlen, ":unlimited", -- STRLITERALLEN(":unlimited") + 1); -- else -- sprintf(buf + partlen, ":%" PRIu64, -- (uint64_t)lim->limit.rlim_max); -+ if (lim->limit.rlim_max == RLIM_INFINITY) { -+ if (memcpy(buf + partlen, ":unlimited", STRLITERALLEN(":unlimited") + 1) == NULL) { -+ return -1; -+ } -+ } else { -+ nret = snprintf(buf + partlen, (MAX_LIMIT_BUF_LEN - partlen), ":%" PRIu64, (uint64_t)lim->limit.rlim_max); -+ if (nret < 0) { -+ return -1; -+ } -+ } - } - - if (get_all) { -- strprint(retv, inlen, "lxc.prlimit.%s = %s\n", -- lim->resource, buf); -+ strprint(retv, inlen, "lxc.prlimit.%s = %s\n", lim->resource, buf); - } else if (strcmp(lim->resource, key) == 0) { - strprint(retv, inlen, "%s", buf); - } -diff --git a/src/lxc/json/json_common.c b/src/lxc/json/json_common.c -index bea9b14..5da1e6d 100755 ---- a/src/lxc/json/json_common.c -+++ b/src/lxc/json/json_common.c -@@ -16,7 +16,7 @@ yajl_gen_status reformat_uint(void *ctx, long long unsigned int num) { - char numstr[MAX_NUM_STR_LEN]; - int ret; - -- ret = sprintf(numstr, "%llu", num); -+ ret = snprintf(numstr, MAX_NUM_STR_LEN, "%llu", num); - if (ret < 0) { - return yajl_gen_in_error_state; - } -@@ -27,7 +27,7 @@ yajl_gen_status reformat_int(void *ctx, long long int num) { - char numstr[MAX_NUM_STR_LEN]; - int ret; - -- ret = sprintf(numstr, "%lld", num); -+ ret = snprintf(numstr, MAX_NUM_STR_LEN, "%lld", num); - if (ret < 0) { - return yajl_gen_in_error_state; - } -@@ -399,7 +399,7 @@ yajl_gen_status gen_json_map_int_int(void *ctx, json_map_int_int *map, struct pa - for (i = 0; i < len; i++) { - char numstr[MAX_NUM_STR_LEN]; - int nret; -- nret = sprintf(numstr, "%lld", (long long int)map->keys[i]); -+ nret = snprintf(numstr, MAX_NUM_STR_LEN, "%lld", (long long int)map->keys[i]); - if (nret < 0) { - if (!*err && asprintf(err, "Error to print string") < 0) { - *(err) = safe_strdup("error allocating memory"); -@@ -545,7 +545,7 @@ yajl_gen_status gen_json_map_int_bool(void *ctx, json_map_int_bool *map, struct - for (i = 0; i < len; i++) { - char numstr[MAX_NUM_STR_LEN]; - int nret; -- nret = sprintf(numstr, "%lld", (long long int)map->keys[i]); -+ nret = snprintf(numstr, MAX_NUM_STR_LEN, "%lld", (long long int)map->keys[i]); - if (nret < 0) { - if (!*err && asprintf(err, "Error to print string") < 0) { - *(err) = safe_strdup("error allocating memory"); -@@ -686,7 +686,7 @@ yajl_gen_status gen_json_map_int_string(void *ctx, json_map_int_string *map, str - for (i = 0; i < len; i++) { - char numstr[MAX_NUM_STR_LEN]; - int nret; -- nret = sprintf(numstr, "%lld", (long long int)map->keys[i]); -+ nret = snprintf(numstr, MAX_NUM_STR_LEN, "%lld", (long long int)map->keys[i]); - if (nret < 0) { - if (!*err && asprintf(err, "Error to print string") < 0) { - *(err) = safe_strdup("error allocating memory"); -@@ -1184,4 +1184,4 @@ int append_json_map_string_string(json_map_string_string *map, const char *key, - - map->len++; - return 0; --} -\ No newline at end of file -+} -diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index ede4c88..3b2c5af 100644 ---- a/src/lxc/lxccontainer.c -+++ b/src/lxc/lxccontainer.c -@@ -3196,7 +3196,11 @@ static bool container_destroy(struct lxc_container *c, - char msg[BUFSIZ] = { 0 }; - ERROR("Failed to destroy directory \"%s\" for \"%s\"", path, - c->name); -- sprintf(msg, "Failed to destroy directory \"%s\": %s", path, errno ? strerror(errno) : "error"); -+ ret = snprintf(msg, BUFSIZ, "Failed to destroy directory \"%s\": %s", path, errno ? strerror(errno) : "error"); -+ if (ret < 0) { -+ ERROR("Sprintf failed"); -+ goto out; -+ } - c->error_string = safe_strdup(msg); - goto out; - } -@@ -5278,7 +5282,7 @@ static int set_start_extral_configs(struct lxc_container *c) - return -1; - } - } -- if (sprintf(fpath, "%s/%s/%s", c->config_path, c->name, START_GENERATE_CONFIG) < 0) { -+ if (snprintf(fpath, PATH_MAX, "%s/%s/%s", c->config_path, c->name, START_GENERATE_CONFIG) < 0) { - fprintf(stderr, "Sprintf config path failed\n"); - return -1; - } -diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index 970db69..b9b65c6 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -241,13 +241,13 @@ static int lxc_terminal_rename_old_log_file(struct lxc_terminal *terminal) - char *rename_fname = NULL; - - for (i = terminal->log_rotate - 1; i > 1; i--) { -- ret = sprintf(tmp, "%s.%u", terminal->log_path, i); -+ ret = snprintf(tmp, PATH_MAX, "%s.%u", terminal->log_path, i); - if (ret < 0) { - return -EFBIG; - } - free(rename_fname); - rename_fname = safe_strdup(tmp); -- ret = sprintf(tmp, "%s.%u", terminal->log_path, (i - 1)); -+ ret = snprintf(tmp, PATH_MAX, "%s.%u", terminal->log_path, (i - 1)); - if (ret < 0) { - free(rename_fname); - return -EFBIG; -@@ -284,11 +284,21 @@ static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal) - } - - len = strlen(terminal->log_path) + sizeof(".1"); -- tmp = alloca(len); -+ tmp = malloc(len); -+ if (tmp == NULL) { -+ ERROR("Out of memory"); -+ return -1; -+ } -+ if (memset(tmp, 0, len) != NULL) { -+ ERROR("Memset failed"); -+ goto free_out; -+ } - - ret = snprintf(tmp, len, "%s.1", terminal->log_path); -- if (ret < 0 || (size_t)ret >= len) -- return -EFBIG; -+ if (ret < 0 || (size_t)ret >= len) { -+ ret = -EFBIG; -+ goto free_out; -+ } - - close(terminal->log_fd); - terminal->log_fd = -1; -@@ -297,7 +307,10 @@ static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal) - SYSERROR("Rename container log file failed"); - } - -- return lxc_terminal_create_log_file(terminal); -+ ret = lxc_terminal_create_log_file(terminal); -+free_out: -+ free(tmp); -+ return ret; - } - - static int lxc_terminal_rotate_write_data(struct lxc_terminal *terminal, const char *buf, -@@ -403,6 +416,7 @@ static bool get_time_buffer(struct timespec *timestamp, char *timebuffer, - struct tm tm_utc = { 0 }; - int32_t nanos = 0; - time_t seconds; -+ size_t len = 0; - - if (!timebuffer || !maxsize) { - return false; -@@ -413,7 +427,10 @@ static bool get_time_buffer(struct timespec *timestamp, char *timebuffer, - strftime(timebuffer, maxsize, "%Y-%m-%dT%H:%M:%S", &tm_utc); - - nanos = (int32_t)timestamp->tv_nsec; -- sprintf(timebuffer + strlen(timebuffer), ".%09dZ", nanos); -+ len = strlen(timebuffer); -+ if (snprintf(timebuffer + len, (maxsize - len), ".%09dZ", nanos) < 0) { -+ return false; -+ } - - return true; - } --- -1.8.3.1 - diff --git a/0113-Malloc-parameter-check-and-judgment.patch b/0113-Malloc-parameter-check-and-judgment.patch deleted file mode 100644 index 12fbfa35b573ae11be559228480f498836dc8342..0000000000000000000000000000000000000000 --- a/0113-Malloc-parameter-check-and-judgment.patch +++ /dev/null @@ -1,575 +0,0 @@ -From 3b2dff6c4d17c6adeba8304f30334e93db611233 Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Thu, 4 Jul 2019 12:08:17 +0800 -Subject: [PATCH 113/140] Malloc parameter check and judgment - -Signed-off-by: wujing -Signed-off-by: LiFeng ---- - src/lxc/attach.c | 2 +- - src/lxc/commands.c | 9 ++- - src/lxc/conf.c | 20 ++++-- - src/lxc/confile.c | 8 +-- - src/lxc/json/container_start_generate_config.c | 12 +++- - src/lxc/json/defs.c | 8 +++ - src/lxc/json/json_common.c | 97 +++++++++----------------- - src/lxc/json/logger_json_file.c | 6 +- - src/lxc/lxccontainer.c | 12 +++- - src/lxc/path.c | 8 ++- - src/lxc/start.c | 6 +- - src/lxc/terminal.c | 2 +- - src/lxc/utils.c | 4 +- - 13 files changed, 104 insertions(+), 90 deletions(-) - -diff --git a/src/lxc/attach.c b/src/lxc/attach.c -index d7b16e3..ac4bd39 100644 ---- a/src/lxc/attach.c -+++ b/src/lxc/attach.c -@@ -1188,7 +1188,7 @@ static int create_attach_timeout_thread(int64_t attach_timeout, pid_t pid) - struct attach_timeout_conf *timeout_conf = NULL; - - timeout_conf = malloc(sizeof(struct attach_timeout_conf)); -- if (!timeout_conf) { -+ if (timeout_conf == NULL) { - ERROR("Failed to malloc attach timeout conf"); - ret = -1; - goto out; -diff --git a/src/lxc/commands.c b/src/lxc/commands.c -index 0802a16..fa02a4b 100644 ---- a/src/lxc/commands.c -+++ b/src/lxc/commands.c -@@ -1075,11 +1075,16 @@ int lxc_cmd_set_terminal_fifos(const char *name, const char *lxcpath, const char - const char *cmd_out_fifo = out_fifo ? out_fifo : none_fifo_name; - const char *cmd_err_fifo = err_fifo ? err_fifo : none_fifo_name; - -+ if (len + strlen(cmd_in_fifo) + strlen(split) + strlen(cmd_out_fifo) + -+ strlen(split) + strlen(cmd_err_fifo) == SIZE_MAX) -+ return -1; - len += strlen(cmd_in_fifo) + strlen(split) + strlen(cmd_out_fifo) + strlen(split) + strlen(cmd_err_fifo) + 1; - tmp = malloc(len); -- if (!tmp) -+ if (tmp == NULL) -+ return -1; -+ ret = snprintf(tmp, len, "%s%s%s%s%s", cmd_in_fifo, split, cmd_out_fifo, split, cmd_err_fifo); -+ if (ret < 0) - return -1; -- snprintf(tmp, len, "%s%s%s%s%s", cmd_in_fifo, split, cmd_out_fifo, split, cmd_err_fifo); - - struct lxc_cmd_rr cmd = { - .req = { -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 996d267..3ecccbd 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4393,7 +4393,11 @@ int lxc_drop_caps(struct lxc_conf *conf) - - // caplist[i] is 1 if we keep capability i - caplist = malloc(numcaps * sizeof(int)); -- memset(caplist, 0, numcaps * sizeof(int)); -+ if (caplist == NULL) { -+ ERROR("Out of memory"); -+ return -1; -+ } -+ (void)memset(caplist, 0, numcaps * sizeof(int)); - - lxc_list_for_each(iterator, caps) { - -@@ -4488,8 +4492,8 @@ static char* generate_json_str(const char *name, const char *lxcpath, const char - cpid = "-1"; - } - -- if ((SIZE_MAX - strlen(name) - strlen(cpid) - strlen(rootfs) - strlen(lxcpath) - strlen(name)) < -- (strlen("{\"ociVersion\":\"\",\"id\":\"\",\"pid\":,\"root\":\"\",\"bundle\":\"\"}") + 1 + 1)) { -+ 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; -@@ -4499,7 +4503,7 @@ static char* generate_json_str(const char *name, const char *lxcpath, const char - size = strlen("{\"ociVersion\":\"\",\"id\":\"\",\"pid\":,\"root\":\"\",\"bundle\":\"\"}") + - strlen(name) + strlen(cpid) + strlen(rootfs) + strlen(lxcpath) + 1 + strlen(name) + 1; - inmsg = malloc(size); -- if (!inmsg) { -+ if (inmsg == NULL) { - ERROR("Out of memory"); - ret = -1; - goto out_free; -@@ -4531,9 +4535,11 @@ static char **merge_ocihook_env(char **oldenvs, size_t env_len, size_t *merge_en - }; - char *lxcenv_buf = NULL; - -+ if (result_len > SIZE_MAX - (sizeof(lxc_envs) / sizeof(char *)) - 1) -+ return NULL; - result_len += (sizeof(lxc_envs) / sizeof(char *)) + 1; - result = malloc(sizeof(char *) * result_len); -- if (!result) -+ if (result == NULL) - return NULL; - memset(result, 0, sizeof(char *) * result_len); - -@@ -4552,7 +4558,7 @@ static char **merge_ocihook_env(char **oldenvs, size_t env_len, size_t *merge_en - } - env_buf_len = ((strlen(tmpenv) + 1) + strlen(lxc_envs[j])) + 1; - lxcenv_buf = malloc(env_buf_len); -- if (!lxcenv_buf) { -+ if (lxcenv_buf == NULL) { - lxc_free_array((void **)result, free); - return NULL; - } -@@ -4759,7 +4765,7 @@ static int run_ocihook_buffer(struct oci_hook_conf *oconf, const char *inmsg) - } - - conf = malloc(sizeof(struct wait_conf)); -- if (!conf) { -+ if (conf == NULL) { - SYSERROR("Failed to malloc."); - goto on_error; - } -diff --git a/src/lxc/confile.c b/src/lxc/confile.c -index 8a082d5..a75e023 100644 ---- a/src/lxc/confile.c -+++ b/src/lxc/confile.c -@@ -2318,13 +2318,13 @@ static int set_config_populate_device(const char *key, const char *value, - - /* allocate list element */ - dev_list = malloc(sizeof(*dev_list)); -- if (!dev_list) -+ if (dev_list == NULL) - goto on_error; - - lxc_list_init(dev_list); - - dev_elem = malloc(sizeof(*dev_elem)); -- if (!dev_elem) -+ if (dev_elem == NULL) - goto on_error; - memset(dev_elem, 0, sizeof(*dev_elem)); - -@@ -2362,7 +2362,7 @@ static int set_config_rootfs_masked_paths(const char *key, const char *value, - return lxc_clear_rootfs_masked_paths(lxc_conf); - - list_item = malloc(sizeof(*list_item)); -- if (!list_item) -+ if (list_item == NULL) - goto on_error; - - list_item->elem = safe_strdup(value); -@@ -2387,7 +2387,7 @@ static int set_config_rootfs_ro_paths(const char *key, const char *value, - return lxc_clear_rootfs_ro_paths(lxc_conf); - - list_item = malloc(sizeof(*list_item)); -- if (!list_item) -+ if (list_item == NULL) - goto on_error; - - list_item->elem = safe_strdup(value); -diff --git a/src/lxc/json/container_start_generate_config.c b/src/lxc/json/container_start_generate_config.c -index 5ec8311..3748973 100644 ---- a/src/lxc/json/container_start_generate_config.c -+++ b/src/lxc/json/container_start_generate_config.c -@@ -41,6 +41,11 @@ container_start_generate_config *make_container_start_generate_config(yajl_val t - if (tmp != NULL && YAJL_GET_ARRAY(tmp) != NULL && YAJL_GET_ARRAY(tmp)->len > 0) { - size_t i; - ret->additional_gids_len = YAJL_GET_ARRAY(tmp)->len; -+ if (YAJL_GET_ARRAY(tmp)->len > SIZE_MAX / sizeof(*ret->additional_gids) - 1) { -+ *err = safe_strdup("invalid additional gids size"); -+ free_container_start_generate_config(ret); -+ return NULL; -+ } - ret->additional_gids = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->additional_gids)); - for (i = 0; i < YAJL_GET_ARRAY(tmp)->len; i++) { - yajl_val val = YAJL_GET_ARRAY(tmp)->values[i]; -@@ -233,8 +238,13 @@ char *container_start_generate_config_generate_json(container_start_generate_con - goto free_out; - } - -+ if (gen_len == SIZE_MAX) { -+ *err = safe_strdup("Invalid buffer length"); -+ goto free_out; -+ } -+ - json_buf = safe_malloc(gen_len + 1); -- (void)memcpy(json_buf, gen_buf, gen_len); -+ (void)memcpy(json_buf, gen_buf, gen_len); - json_buf[gen_len] = '\0'; - - free_out: -diff --git a/src/lxc/json/defs.c b/src/lxc/json/defs.c -index 8a052a8..4bf569a 100644 ---- a/src/lxc/json/defs.c -+++ b/src/lxc/json/defs.c -@@ -24,6 +24,10 @@ defs_hook *make_defs_hook(yajl_val tree, struct parser_context *ctx, parser_erro - if (tmp != NULL && YAJL_GET_ARRAY(tmp) != NULL && YAJL_GET_ARRAY(tmp)->len > 0) { - size_t i; - ret->args_len = YAJL_GET_ARRAY(tmp)->len; -+ if (YAJL_GET_ARRAY(tmp)->len > SIZE_MAX / sizeof(*ret->args) - 1) { -+ free_defs_hook(ret); -+ return NULL; -+ } - ret->args = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->args)); - for (i = 0; i < YAJL_GET_ARRAY(tmp)->len; i++) { - yajl_val val = YAJL_GET_ARRAY(tmp)->values[i]; -@@ -39,6 +43,10 @@ defs_hook *make_defs_hook(yajl_val tree, struct parser_context *ctx, parser_erro - if (tmp != NULL && YAJL_GET_ARRAY(tmp) != NULL && YAJL_GET_ARRAY(tmp)->len > 0) { - size_t i; - ret->env_len = YAJL_GET_ARRAY(tmp)->len; -+ if (YAJL_GET_ARRAY(tmp)->len > SIZE_MAX / sizeof(*ret->env) - 1) { -+ free_defs_hook(ret); -+ return NULL; -+ } - ret->env = safe_malloc((YAJL_GET_ARRAY(tmp)->len + 1) * sizeof(*ret->env)); - for (i = 0; i < YAJL_GET_ARRAY(tmp)->len; i++) { - yajl_val val = YAJL_GET_ARRAY(tmp)->values[i]; -diff --git a/src/lxc/json/json_common.c b/src/lxc/json/json_common.c -index 5da1e6d..ed2fe83 100755 ---- a/src/lxc/json/json_common.c -+++ b/src/lxc/json/json_common.c -@@ -445,6 +445,9 @@ json_map_int_int *make_json_map_int_int(yajl_val src, struct parser_context *ctx - if (src != NULL && YAJL_GET_OBJECT(src) != NULL) { - size_t i; - size_t len = YAJL_GET_OBJECT(src)->len; -+ if (len > SIZE_MAX / sizeof(int) - 1) { -+ return NULL; -+ } - ret = safe_malloc(sizeof(*ret)); - ret->len = len; - ret->keys = safe_malloc((len + 1) * sizeof(int)); -@@ -505,16 +508,8 @@ int append_json_map_int_int(json_map_int_int *map, int key, int val) { - vals = safe_malloc(len * sizeof(int)); - - if (map->len) { -- if (memcpy(keys, map->keys, map->len * sizeof(int)) != NULL) { -- free(keys); -- free(vals); -- return -1; -- } -- if (memcpy(vals, map->values, map->len * sizeof(int)) != NULL) { -- free(keys); -- free(vals); -- return -1; -- } -+ (void)memcpy(keys, map->keys, map->len * sizeof(int)); -+ (void)memcpy(vals, map->values, map->len * sizeof(int)); - } - free(map->keys); - map->keys = keys; -@@ -591,6 +586,9 @@ json_map_int_bool *make_json_map_int_bool(yajl_val src, struct parser_context *c - if (src != NULL && YAJL_GET_OBJECT(src) != NULL) { - size_t i; - size_t len = YAJL_GET_OBJECT(src)->len; -+ if (len > SIZE_MAX / sizeof(int) - 1) { -+ return NULL; -+ } - ret = safe_malloc(sizeof(*ret)); - ret->len = len; - ret->keys = safe_malloc((len + 1) * sizeof(int)); -@@ -646,16 +644,8 @@ int append_json_map_int_bool(json_map_int_bool *map, int key, bool val) { - vals = safe_malloc(len * sizeof(bool)); - - if (map->len) { -- if (memcpy(keys, map->keys, map->len * sizeof(int)) != NULL) { -- free(keys); -- free(vals); -- return -1; -- } -- if (memcpy(vals, map->values, map->len * sizeof(bool)) != NULL) { -- free(keys); -- free(vals); -- return -1; -- } -+ (void)memcpy(keys, map->keys, map->len * sizeof(int)); -+ (void)memcpy(vals, map->values, map->len * sizeof(bool)); - } - free(map->keys); - map->keys = keys; -@@ -733,6 +723,9 @@ json_map_int_string *make_json_map_int_string(yajl_val src, struct parser_contex - if (src != NULL && YAJL_GET_OBJECT(src) != NULL) { - size_t i; - size_t len = YAJL_GET_OBJECT(src)->len; -+ if (len > SIZE_MAX / sizeof(char *) - 1) { -+ return NULL; -+ } - ret = safe_malloc(sizeof(*ret)); - ret->len = len; - ret->keys = safe_malloc((len + 1) * sizeof(int)); -@@ -786,16 +779,8 @@ int append_json_map_int_string(json_map_int_string *map, int key, const char *va - vals = safe_malloc(len * sizeof(char *)); - - if (map->len) { -- if (memcpy(keys, map->keys, map->len * sizeof(int)) != NULL) { -- free(keys); -- free(vals); -- return -1; -- } -- if (memcpy(vals, map->values, map->len * sizeof(char *)) != NULL) { -- free(keys); -- free(vals); -- return -1; -- } -+ (void)memcpy(keys, map->keys, map->len * sizeof(int)); -+ (void)memcpy(vals, map->values, map->len * sizeof(char *)); - } - free(map->keys); - map->keys = keys; -@@ -864,6 +849,9 @@ json_map_string_int *make_json_map_string_int(yajl_val src, struct parser_contex - if (src != NULL && YAJL_GET_OBJECT(src) != NULL) { - size_t i; - size_t len = YAJL_GET_OBJECT(src)->len; -+ if (len > SIZE_MAX / sizeof(char *) - 1) { -+ return NULL; -+ } - ret = safe_malloc(sizeof(*ret)); - ret->len = len; - ret->keys = safe_malloc((len + 1) * sizeof(char *)); -@@ -913,16 +901,8 @@ int append_json_map_string_int(json_map_string_int *map, const char *key, int va - vals = safe_malloc(len * sizeof(int)); - - if (map->len) { -- if (memcpy(keys, map->keys, map->len * sizeof(char *)) != NULL) { -- free(keys); -- free(vals); -- return -1; -- } -- if (memcpy(vals, map->values, map->len * sizeof(int)) != NULL) { -- free(keys); -- free(vals); -- return -1; -- } -+ (void)memcpy(keys, map->keys, map->len * sizeof(char *)); -+ (void)memcpy(vals, map->values, map->len * sizeof(int)); - } - free(map->keys); - map->keys = keys; -@@ -991,6 +971,9 @@ json_map_string_bool *make_json_map_string_bool(yajl_val src, struct parser_cont - if (src != NULL && YAJL_GET_OBJECT(src) != NULL) { - size_t i; - size_t len = YAJL_GET_OBJECT(src)->len; -+ if (len > SIZE_MAX / sizeof(char *) - 1) { -+ return NULL; -+ } - ret = safe_malloc(sizeof(*ret)); - ret->len = len; - ret->keys = safe_malloc((len + 1) * sizeof(char *)); -@@ -1017,6 +1000,7 @@ json_map_string_bool *make_json_map_string_bool(yajl_val src, struct parser_cont - } - return ret; - } -+ - int append_json_map_string_bool(json_map_string_bool *map, const char *key, bool val) { - size_t len; - char **keys = NULL; -@@ -1035,16 +1019,8 @@ int append_json_map_string_bool(json_map_string_bool *map, const char *key, bool - vals = safe_malloc(len * sizeof(bool)); - - if (map->len) { -- if (memcpy(keys, map->keys, map->len * sizeof(char *)) != NULL) { -- free(keys); -- free(vals); -- return -1; -- } -- if (memcpy(vals, map->values, map->len * sizeof(bool)) != NULL) { -- free(keys); -- free(vals); -- return -1; -- } -+ (void)memcpy(keys, map->keys, map->len * sizeof(char *)); -+ (void)memcpy(vals, map->values, map->len * sizeof(bool)); - } - free(map->keys); - map->keys = keys; -@@ -1114,6 +1090,9 @@ json_map_string_string *make_json_map_string_string(yajl_val src, struct parser_ - if (src != NULL && YAJL_GET_OBJECT(src) != NULL) { - size_t i; - size_t len = YAJL_GET_OBJECT(src)->len; -+ if (len > SIZE_MAX / sizeof(char *) - 1) { -+ return NULL; -+ } - ret = safe_malloc(sizeof(*ret)); - ret->len = len; - ret->keys = safe_malloc((len + 1) * sizeof(char *)); -@@ -1149,9 +1128,9 @@ int append_json_map_string_string(json_map_string_string *map, const char *key, - - for (i = 0; i < map->len; i++) { - if (strcmp(map->keys[i], key) == 0) { -- free(map->values[i]); -- map->values[i] = safe_strdup(val ? val : ""); -- return 0; -+ free(map->values[i]); -+ map->values[i] = safe_strdup(val ? val : ""); -+ return 0; - } - } - -@@ -1164,16 +1143,8 @@ int append_json_map_string_string(json_map_string_string *map, const char *key, - vals = safe_malloc(len * sizeof(char *)); - - if (map->len) { -- if (memcpy(keys, map->keys, map->len * sizeof(char *)) != NULL) { -- free(keys); -- free(vals); -- return -1; -- } -- if (memcpy(vals, map->values, map->len * sizeof(char *)) != NULL) { -- free(keys); -- free(vals); -- return -1; -- } -+ (void)memcpy(keys, map->keys, map->len * sizeof(char *)); -+ (void)memcpy(vals, map->values, map->len * sizeof(char *)); - } - free(map->keys); - map->keys = keys; -diff --git a/src/lxc/json/logger_json_file.c b/src/lxc/json/logger_json_file.c -index 842d35b..6abeef4 100644 ---- a/src/lxc/json/logger_json_file.c -+++ b/src/lxc/json/logger_json_file.c -@@ -230,8 +230,12 @@ char *logger_json_file_generate_json(logger_json_file *ptr, struct parser_contex - goto free_out; - } - -+ if (gen_len == SIZE_MAX) { -+ *err = safe_strdup("Invalid buffer length"); -+ goto free_out; -+ } - json_buf = safe_malloc(gen_len + 1); -- memcpy(json_buf, gen_buf, gen_len); -+ (void)memcpy(json_buf, gen_buf, gen_len); - json_buf[gen_len] = '\0'; - - free_out: -diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index 3b2c5af..5a72483 100644 ---- a/src/lxc/lxccontainer.c -+++ b/src/lxc/lxccontainer.c -@@ -928,6 +928,9 @@ static char **use_init_args(char **init_argv, size_t init_args) - - do { - argv = malloc(sizeof(char *)); -+ if (argv == NULL) { -+ return NULL; -+ } - } while (!argv); - - argv[0] = NULL; -@@ -3378,9 +3381,12 @@ static bool set_oci_hook_config_filename(struct lxc_container *c) - return false; - - /* $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; -+ - newpath = malloc(len); -- if (!newpath) -+ if (newpath == NULL) - return false; - - ret = snprintf(newpath, len, "%s/%s/%s", c->config_path, c->name, OCI_HOOK_JSON_FILE_NAME); -@@ -5276,11 +5282,11 @@ static int set_start_extral_configs(struct lxc_container *c) - - if (lconf == NULL) { - c->lxc_conf = malloc(sizeof(struct lxc_conf)); -- lconf = c->lxc_conf; -- if (lconf == NULL) { -+ if (c->lxc_conf == NULL) { - fprintf(stderr, "Out of memory\n"); - return -1; - } -+ lconf = c->lxc_conf; - } - if (snprintf(fpath, PATH_MAX, "%s/%s/%s", c->config_path, c->name, START_GENERATE_CONFIG) < 0) { - fprintf(stderr, "Sprintf config path failed\n"); -diff --git a/src/lxc/path.c b/src/lxc/path.c -index c545887..df285f5 100644 ---- a/src/lxc/path.c -+++ b/src/lxc/path.c -@@ -58,7 +58,7 @@ char *preserve_trailing_dot_or_separator(const char *cleanedpath, - - len = strlen(cleanedpath) + 3; - respath = malloc(len); -- if (!respath) { -+ if (respath == NULL) { - ERROR("Out of memory"); - return NULL; - } -@@ -90,12 +90,16 @@ bool filepath_split(const char *path, char **dir, char **base) - size_t len; - - len = strlen(path); -+ if (len >= PATH_MAX) { -+ ERROR("Invalid path"); -+ return false; -+ } - i = len - 1; - while (i >= 0 && path[i] != '/') - i--; - - *dir = malloc(i + 2); -- if (!*dir) { -+ if (*dir == NULL) { - ERROR("Out of memory"); - return false; - } -diff --git a/src/lxc/start.c b/src/lxc/start.c -index d6c706e..00d478c 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -2383,7 +2383,7 @@ static int create_start_timeout_thread(struct lxc_conf *conf, unsigned int start - } - - timeout_conf = malloc(sizeof(struct start_timeout_conf)); -- if (!timeout_conf) { -+ if (timeout_conf == NULL) { - ERROR("Failed to malloc start timeout conf"); - ret = -1; - goto out; -@@ -2657,7 +2657,7 @@ static struct lxc_handler *lxc_init_clean_handler(char *name, char *lxcpath, str - struct lxc_handler *handler; - - handler = malloc(sizeof(*handler)); -- if (!handler) -+ if (handler == NULL) - return NULL; - - memset(handler, 0, sizeof(*handler)); -@@ -2707,7 +2707,7 @@ static struct lxc_handler *lxc_init_pids_handler(char *name, char *lxcpath, stru - struct lxc_handler *handler; - - handler = malloc(sizeof(*handler)); -- if (!handler) -+ if (handler == NULL) - return NULL; - - memset(handler, 0, sizeof(*handler)); -diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index b9b65c6..1fee651 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -1330,7 +1330,7 @@ static int lxc_terminal_set_fifo(struct lxc_terminal *console, const char *in, c - } - - fifo_elem = malloc(sizeof(*fifo_elem)); -- if (!fifo_elem) { -+ if (fifo_elem == NULL) { - if (fifofd_in >= 0) - close(fifofd_in); - if (fifofd_out >= 0) -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index e6e8905..656df4a 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -1945,9 +1945,9 @@ static proc_t *lxc_stat2proc(const char *S) - *tmp = '\0'; /* replace trailing ')' with NUL */ - - P = malloc(sizeof(proc_t)); -- if (!P) -+ if (P == NULL) - return NULL; -- memset(P, 0x00, sizeof(proc_t)); -+ (void)memset(P, 0x00, sizeof(proc_t)); - - /* parse these two strings separately, skipping the leading "(". */ - num = sscanf(S, "%d (%15c", &P->pid, P->cmd); /* comm[16] in kernel */ --- -1.8.3.1 - diff --git a/0114-lxc-fix-code-errors.patch b/0114-lxc-fix-code-errors.patch deleted file mode 100644 index 9e062dfa0dc93438c42eb32d15f6a0ca28718857..0000000000000000000000000000000000000000 --- a/0114-lxc-fix-code-errors.patch +++ /dev/null @@ -1,155 +0,0 @@ -From b51181f15bab3db7e4391b8eccad047221947baa Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Thu, 4 Jul 2019 05:10:00 -0400 -Subject: [PATCH 114/140] lxc: fix code errors - -Signed-off-by: LiFeng ---- - src/lxc/attach.c | 14 +++++--------- - src/lxc/conf.c | 11 ++++++----- - src/lxc/confile.c | 8 ++------ - src/lxc/terminal.c | 6 ++---- - 4 files changed, 15 insertions(+), 24 deletions(-) - -diff --git a/src/lxc/attach.c b/src/lxc/attach.c -index ac4bd39..1f14eb4 100644 ---- a/src/lxc/attach.c -+++ b/src/lxc/attach.c -@@ -841,7 +841,7 @@ static int attach_child_main(struct attach_clone_payload *payload) - } - - /* isulad: set workdir */ -- if (init_ctx && init_ctx->container && init_ctx->container->lxc_conf && init_ctx->container->lxc_conf->init_cwd) { -+ if (init_ctx->container->lxc_conf->init_cwd) { - char *init_cwd; - init_cwd = init_ctx->container->lxc_conf->init_cwd; - /* try to create workdir if not exist */ -@@ -933,8 +933,7 @@ static int attach_child_main(struct attach_clone_payload *payload) - goto on_error; - } - -- if ((init_ctx->container && init_ctx->container->lxc_conf && -- init_ctx->container->lxc_conf->no_new_privs) || -+ if ((init_ctx->container->lxc_conf->no_new_privs) || - (options->attach_flags & LXC_ATTACH_NO_NEW_PRIVS)) { - ret = prctl(PR_SET_NO_NEW_PRIVS, prctl_arg(1), prctl_arg(0), - prctl_arg(0), prctl_arg(0)); -@@ -958,8 +957,7 @@ static int attach_child_main(struct attach_clone_payload *payload) - TRACE("Set %s LSM label to \"%s\"", lsm_name(), init_ctx->lsm_label); - } - -- if (init_ctx->container && init_ctx->container->lxc_conf && -- init_ctx->container->lxc_conf->seccomp) { -+ if (init_ctx->container->lxc_conf->seccomp) { - ret = lxc_seccomp_load(init_ctx->container->lxc_conf); - if (ret < 0) - goto on_error; -@@ -1028,8 +1026,7 @@ static int attach_child_main(struct attach_clone_payload *payload) - goto on_error; - } - -- if (init_ctx->container && init_ctx->container->lxc_conf && -- !lxc_setgroups(init_ctx->container->lxc_conf->init_groups_len, -+ if (!lxc_setgroups(init_ctx->container->lxc_conf->init_groups_len, - init_ctx->container->lxc_conf->init_groups)) - goto on_error; - -@@ -1041,8 +1038,7 @@ static int attach_child_main(struct attach_clone_payload *payload) - goto on_error; - } - -- if (init_ctx->container && init_ctx->container->lxc_conf && -- lxc_drop_caps(init_ctx->container->lxc_conf) != 0) { -+ if (lxc_drop_caps(init_ctx->container->lxc_conf) != 0) { - ERROR("Failed to drop caps."); - goto on_error; - } -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 3ecccbd..e22e13e 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4790,6 +4790,7 @@ static int run_ocihook_buffer(struct oci_hook_conf *oconf, const char *inmsg) - err = pthread_create(&ptid, &attr, wait_ocihook_timeout, conf); - if (err != 0) { - ERROR("Create wait timeout thread failed"); -+ free(conf); - goto on_error; - } - -@@ -4804,17 +4805,17 @@ static int run_ocihook_buffer(struct oci_hook_conf *oconf, const char *inmsg) - goto print_hook; - } else if (WIFEXITED(ret) && WEXITSTATUS(ret) != 0) { - ERROR("Script exited with status %d. output: %s", WEXITSTATUS(ret), output); -- lxc_write_error_message(conf->errfd, "%s:%d: running %s hook caused \"error running hook: exit status %d, output: %s\".", -+ lxc_write_error_message(oconf->errfd, "%s:%d: running %s hook caused \"error running hook: exit status %d, output: %s\".", - __FILE__, __LINE__, -- (conf->which >= NUM_LXC_HOOKS) ? "invalid type" : lxchook_names[conf->which], -+ (oconf->which >= NUM_LXC_HOOKS) ? "invalid type" : lxchook_names[oconf->which], - WEXITSTATUS(ret), output); - - goto print_hook; - } else if (WIFSIGNALED(ret)) { - ERROR("Script terminated by signal %d.", WTERMSIG(ret)); -- lxc_write_error_message(conf->errfd, "%s:%d: running %s hook caused \"error running hook: Script terminated by signal %d\".", -+ lxc_write_error_message(oconf->errfd, "%s:%d: running %s hook caused \"error running hook: Script terminated by signal %d\".", - __FILE__, __LINE__, -- (conf->which >= NUM_LXC_HOOKS) ? "invalid type" : lxchook_names[conf->which], -+ (oconf->which >= NUM_LXC_HOOKS) ? "invalid type" : lxchook_names[oconf->which], - WTERMSIG(ret)); - - goto print_hook; -@@ -4836,7 +4837,7 @@ print_hook: - err_envs_msg = lxc_string_join(" ", (const char **)oconf->ocihook->env, false); - ERROR("Hook script command: \"%s\", args: \"%s\", envs: \"%s\", timeout: %d.", - buffer, err_args_msg ? err_args_msg : "", -- err_envs_msg ? err_envs_msg : "", conf->timeout); -+ err_envs_msg ? err_envs_msg : "", oconf->ocihook->timeout); - - free(err_args_msg); - free(err_envs_msg); -diff --git a/src/lxc/confile.c b/src/lxc/confile.c -index a75e023..0537ebc 100644 ---- a/src/lxc/confile.c -+++ b/src/lxc/confile.c -@@ -3828,9 +3828,7 @@ static int get_config_prlimit(const char *key, char *retv, int inlen, - struct lxc_limit *lim = it->elem; - - if (lim->limit.rlim_cur == RLIM_INFINITY) { -- if (memcpy(buf, "unlimited", STRLITERALLEN("unlimited") + 1) == NULL) { -- return -1; -- } -+ (void)memcpy(buf, "unlimited", STRLITERALLEN("unlimited") + 1); - partlen = STRLITERALLEN("unlimited"); - } else { - partlen = snprintf(buf, MAX_LIMIT_BUF_LEN, "%" PRIu64, (uint64_t)lim->limit.rlim_cur); -@@ -3841,9 +3839,7 @@ static int get_config_prlimit(const char *key, char *retv, int inlen, - - if (lim->limit.rlim_cur != lim->limit.rlim_max) { - if (lim->limit.rlim_max == RLIM_INFINITY) { -- if (memcpy(buf + partlen, ":unlimited", STRLITERALLEN(":unlimited") + 1) == NULL) { -- return -1; -- } -+ (void)memcpy(buf + partlen, ":unlimited", STRLITERALLEN(":unlimited") + 1); - } else { - nret = snprintf(buf + partlen, (MAX_LIMIT_BUF_LEN - partlen), ":%" PRIu64, (uint64_t)lim->limit.rlim_max); - if (nret < 0) { -diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index 1fee651..32c69a4 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -289,10 +289,8 @@ static int lxc_terminal_rotate_log_file(struct lxc_terminal *terminal) - ERROR("Out of memory"); - return -1; - } -- if (memset(tmp, 0, len) != NULL) { -- ERROR("Memset failed"); -- goto free_out; -- } -+ -+ (void)memset(tmp, 0, len); - - ret = snprintf(tmp, len, "%s.1", terminal->log_path); - if (ret < 0 || (size_t)ret >= len) { --- -1.8.3.1 - diff --git a/0115-fix-compile-error-on-ubuntu.patch b/0115-fix-compile-error-on-ubuntu.patch deleted file mode 100644 index 39387ffce8f13e6e4d71a21c737a429f30f8bcc7..0000000000000000000000000000000000000000 --- a/0115-fix-compile-error-on-ubuntu.patch +++ /dev/null @@ -1,371 +0,0 @@ -From 4a03b0c529c8e2cf915c2b374a47e62b48c2d4db Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Thu, 11 Jul 2019 17:42:00 +0800 -Subject: [PATCH 115/140] fix compile error on ubuntu - -fix compile error on ubuntu - -Signed-off-by: liuhao -Signed-off-by: LiFeng ---- - configure.ac | 1 - - src/lxc/Makefile.am | 10 ++++-- - src/lxc/conf.c | 2 +- - src/lxc/confile.c | 2 +- - src/lxc/isulad_utils.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++ - src/lxc/isulad_utils.h | 13 ++++++++ - src/lxc/path.c | 2 +- - src/lxc/utils.c | 82 +---------------------------------------------- - src/lxc/utils.h | 6 +--- - 9 files changed, 113 insertions(+), 92 deletions(-) - create mode 100644 src/lxc/isulad_utils.c - create mode 100644 src/lxc/isulad_utils.h - -diff --git a/configure.ac b/configure.ac -index 5963fab..dc85f74 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -706,7 +706,6 @@ AX_CHECK_LINK_FLAG([-z relro], [LDFLAGS="$LDFLAGS -z relro"],,[]) - AX_CHECK_LINK_FLAG([-z now], [LDFLAGS="$LDFLAGS -z now"],,[]) - AX_CHECK_LINK_FLAG([-z noexecstack], [LDFLAGS="$LDFLAGS -z noexecstack"],,[]) - --LDFLAGS="$LDFLAGS -fPIE -pie" - - CFLAGS="$CFLAGS -Wvla -std=gnu11 -D_FORTIFY_SOURCE=2 -Wall -fPIC -fPIE -pie" - if test "x$enable_werror" = "xyes"; then -diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am -index b24fcfd..27240cc 100644 ---- a/src/lxc/Makefile.am -+++ b/src/lxc/Makefile.am -@@ -50,6 +50,7 @@ noinst_HEADERS = attach.h \ - json/oci_runtime_spec.h \ - json/logger_json_file.h \ - json/read-file.h \ -+ isulad_utils.h \ - utils.h - - if IS_BIONIC -@@ -146,6 +147,7 @@ liblxc_la_SOURCES = af_unix.c af_unix.h \ - sync.c sync.h \ - syscall_wrappers.h \ - terminal.c \ -+ isulad_utils.c isulad_utils.h \ - utils.c utils.h \ - version.h \ - json/json_common.c json/json_common.h \ -@@ -232,14 +234,14 @@ AM_CFLAGS += -DUSE_CONFIGPATH_LOGS - endif - - # build the shared library --liblxc_la_CFLAGS = -fPIC \ -- -fPIE -pie \ -+liblxc_la_CFLAGS = \ - -DPIC \ - -D_FORTIFY_SOURCE=2 -Wall \ - $(AM_CFLAGS) \ - -pthread - - liblxc_la_LDFLAGS = -pthread \ -+ -fPIC \ - -Wl,-no-undefined \ - -Wl,-z,relro \ - -Wl,-z,now \ -@@ -375,6 +377,7 @@ lxc_monitord_SOURCES = cmd/lxc_monitord.c \ - mainloop.c mainloop.h \ - monitor.c monitor.h \ - raw_syscalls.c raw_syscalls.h \ -+ isulad_utils.c isulad_utils.h \ - utils.c utils.h - lxc_user_nic_SOURCES = cmd/lxc_user_nic.c \ - ../include/netns_ifaddrs.c ../include/netns_ifaddrs.h \ -@@ -391,6 +394,7 @@ lxc_usernsexec_SOURCES = cmd/lxc_usernsexec.c \ - file_utils.c file_utils.h \ - string_utils.c string_utils.h \ - syscall_wrappers.h \ -+ isulad_utils.c isulad_utils.h \ - utils.c utils.h - endif - -@@ -411,6 +415,8 @@ init_lxc_static_SOURCES = cmd/lxc_init.c \ - initutils.c initutils.h \ - file_utils.c file_utils.h \ - log.c log.h \ -+ path.c path.h \ -+ isulad_utils.c isulad_utils.h \ - macro.h \ - namespace.c namespace.h \ - string_utils.c string_utils.h -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index e22e13e..d9a7aae 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4934,7 +4934,7 @@ static int do_run_oci_hooks(const char *name, const char *lxcpath, struct lxc_co - 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 %ld failed, ContainerId: %s", i, name); -+ WARN("running poststart hook %zu failed, ContainerId: %s", i, name); - } - break; - case OCI_HOOK_POSTSTOP: -diff --git a/src/lxc/confile.c b/src/lxc/confile.c -index 0537ebc..01fc944 100644 ---- a/src/lxc/confile.c -+++ b/src/lxc/confile.c -@@ -2212,7 +2212,7 @@ static int set_config_init_args(const char *key, const char *value, - struct lxc_conf *lxc_conf, void *data) - { - int ret = 0; -- char *tmp = NULL; -+ void *tmp = NULL; - char *new_value = NULL; - - ret = set_config_string_item(&new_value, value); -diff --git a/src/lxc/isulad_utils.c b/src/lxc/isulad_utils.c -new file mode 100644 -index 0000000..66516a8 ---- /dev/null -+++ b/src/lxc/isulad_utils.c -@@ -0,0 +1,87 @@ -+#include -+#include -+ -+#include "isulad_utils.h" -+#include "log.h" -+#include "path.h" -+ -+lxc_log_define(isulad_utils, lxc); -+ -+void *lxc_common_calloc_s(size_t size) -+{ -+ if (size == 0 || size > SIZE_MAX) { -+ return NULL; -+ } -+ -+ return calloc((size_t)1, size); -+} -+ -+int lxc_mem_realloc(void **newptr, size_t newsize, void *oldptr, size_t oldsize) -+{ -+ void *tmp = NULL; -+ -+ if (newsize == 0) { -+ goto err_out; -+ } -+ -+ tmp = lxc_common_calloc_s(newsize); -+ if (tmp == NULL) { -+ ERROR("Failed to malloc memory"); -+ goto err_out; -+ } -+ -+ if (oldptr != NULL) { -+ memcpy(tmp, oldptr, (newsize < oldsize) ? newsize : oldsize); -+ -+ memset(oldptr, 0, oldsize); -+ -+ free(oldptr); -+ } -+ -+ *newptr = tmp; -+ return 0; -+ -+err_out: -+ return -1; -+} -+ -+char *safe_strdup(const char *src) -+{ -+ char *dst = NULL; -+ -+ if (src == NULL) { -+ return NULL; -+ } -+ -+ dst = strdup(src); -+ if (dst == NULL) { -+ abort(); -+ } -+ -+ return dst; -+} -+ -+int lxc_open(const char *filename, int flags, mode_t mode) -+{ -+ char rpath[PATH_MAX] = {0x00}; -+ -+ if (cleanpath(filename, rpath, sizeof(rpath)) == NULL) { -+ return -1; -+ } -+ if (mode) { -+ return open(rpath, (int)((unsigned int)flags | O_CLOEXEC), mode); -+ } else { -+ return open(rpath, (int)((unsigned int)flags | O_CLOEXEC)); -+ } -+} -+ -+FILE *lxc_fopen(const char *filename, const char *mode) -+{ -+ char rpath[PATH_MAX] = {0x00}; -+ -+ if (cleanpath(filename, rpath, sizeof(rpath)) == NULL) { -+ return NULL; -+ } -+ -+ return fopen_cloexec(rpath, mode); -+} -diff --git a/src/lxc/isulad_utils.h b/src/lxc/isulad_utils.h -new file mode 100644 -index 0000000..852d956 ---- /dev/null -+++ b/src/lxc/isulad_utils.h -@@ -0,0 +1,13 @@ -+#ifndef __LXC_MEM_UTILS_H -+#define __LXC_MEM_UTILS_H -+ -+#include -+ -+extern int lxc_mem_realloc(void **newptr, size_t newsize, void *oldptr, size_t oldsize); -+extern void *lxc_common_calloc_s(size_t size); -+extern char *safe_strdup(const char *src); -+ -+extern int lxc_open(const char *filename, int flags, mode_t mode); -+extern FILE *lxc_fopen(const char *filename, const char *mode); -+ -+#endif -diff --git a/src/lxc/path.c b/src/lxc/path.c -index df285f5..7a5dce9 100644 ---- a/src/lxc/path.c -+++ b/src/lxc/path.c -@@ -10,7 +10,7 @@ - - #include "path.h" - #include "log.h" --#include "utils.h" -+#include "isulad_utils.h" - - lxc_log_define(lxc_path_ui, lxc); - -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index 656df4a..1d2e9ee 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -57,6 +57,7 @@ - #include "syscall_wrappers.h" - #include "utils.h" - #include "path.h" -+#include "isulad_utils.h" - - #ifndef HAVE_STRLCPY - #include "include/strlcpy.h" -@@ -2092,84 +2093,3 @@ bool is_non_negative_num(const char *s) - } - return true; - } -- --void *lxc_common_calloc_s(size_t size) --{ -- if (size == 0 || size > SIZE_MAX) { -- return NULL; -- } -- -- return calloc((size_t)1, size); --} -- -- --int lxc_mem_realloc(void **newptr, size_t newsize, void *oldptr, size_t oldsize) --{ -- void *tmp = NULL; -- -- if (newsize == 0) { -- goto err_out; -- } -- -- tmp = lxc_common_calloc_s(newsize); -- if (tmp == NULL) { -- ERROR("Failed to malloc memory"); -- goto err_out; -- } -- -- if (oldptr != NULL) { -- memcpy(tmp, oldptr, (newsize < oldsize) ? newsize : oldsize); -- -- memset(oldptr, 0, oldsize); -- -- free(oldptr); -- } -- -- *newptr = tmp; -- return 0; -- --err_out: -- return -1; --} -- --int lxc_open(const char *filename, int flags, mode_t mode) --{ -- char rpath[PATH_MAX] = {0x00}; -- -- if (cleanpath(filename, rpath, sizeof(rpath)) == NULL) { -- return -1; -- } -- if (mode) { -- return open(rpath, (int)((unsigned int)flags | O_CLOEXEC), mode); -- } else { -- return open(rpath, (int)((unsigned int)flags | O_CLOEXEC)); -- } --} -- --FILE *lxc_fopen(const char *filename, const char *mode) --{ -- char rpath[PATH_MAX] = {0x00}; -- -- if (cleanpath(filename, rpath, sizeof(rpath)) == NULL) { -- return NULL; -- } -- -- return fopen_cloexec(rpath, mode); --} -- --char *safe_strdup(const char *src) --{ -- char *dst = NULL; -- -- if (src == NULL) { -- return NULL; -- } -- -- dst = strdup(src); -- if (dst == NULL) { -- abort(); -- } -- -- return dst; --} -- -diff --git a/src/lxc/utils.h b/src/lxc/utils.h -index 0b33f69..1c9bf41 100644 ---- a/src/lxc/utils.h -+++ b/src/lxc/utils.h -@@ -42,6 +42,7 @@ - #include "macro.h" - #include "raw_syscalls.h" - #include "string_utils.h" -+#include "isulad_utils.h" - - /* isulad: replace space with SPACE_MAGIC_STR */ - #define SPACE_MAGIC_STR "[#)" -@@ -324,10 +325,5 @@ extern bool lxc_process_alive(pid_t pid, unsigned long long start_time); - - extern bool is_non_negative_num(const char *s); - extern int lxc_file2str(const char *filename, char ret[], int cap); --extern int lxc_mem_realloc(void **newptr, size_t newsize, void *oldptr, size_t oldsize); --extern void *lxc_common_calloc_s(size_t size); --extern int lxc_open(const char *filename, int flags, mode_t mode); --extern FILE *lxc_fopen(const char *filename, const char *mode); --extern char *safe_strdup(const char *src); - - #endif /* __LXC_UTILS_H */ --- -1.8.3.1 - diff --git a/0116-lxc-set-base-cgroup-path-to.patch b/0116-lxc-set-base-cgroup-path-to.patch deleted file mode 100644 index 6a4cde4fb2e8248c8f5e6d706042142f5d82593c..0000000000000000000000000000000000000000 --- a/0116-lxc-set-base-cgroup-path-to.patch +++ /dev/null @@ -1,34 +0,0 @@ -From c12b2a69ceb8fcd13cd2210897a3dc4d1e695189 Mon Sep 17 00:00:00 2001 -From: liuhao -Date: Wed, 19 Jun 2019 16:48:50 +0800 -Subject: [PATCH 116/140] lxc: set base cgroup path to '/' - -reason:base cgroup may be started with /system.slice when cg_hybrid_init -read /proc/1/cgroup on host, and cgroup init will set all containers -cgroup path under /sys/fs/cgroup//system.slice/xxx/lxc -directory, this is not consistent with docker. The default cgroup path -should be under /sys/fs/cgroup//lxc directory. - -Signed-off-by: zhangsong -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgfsng.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index 46f13f4..7c92abe 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -2545,6 +2545,9 @@ static bool cg_hybrid_init(struct cgroup_ops *ops) - if (!writeable) - goto next; - */ -+ if (strlen(base_cgroup) > 1 && base_cgroup[0] == '/') { -+ base_cgroup[1] = '\0'; -+ } - if (type == CGROUP2_SUPER_MAGIC) { - char *cgv2_ctrl_path; - --- -1.8.3.1 - diff --git a/0117-pupulate-device-with-dir-mode-750-and-set-uid-gid.patch b/0117-pupulate-device-with-dir-mode-750-and-set-uid-gid.patch deleted file mode 100644 index 5165b7d101e88ba350957243a8938a5d920f6b28..0000000000000000000000000000000000000000 --- a/0117-pupulate-device-with-dir-mode-750-and-set-uid-gid.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 86c8493bcd073a1b4fdc2cabde005811771bc282 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Wed, 31 Jul 2019 05:24:11 -0400 -Subject: [PATCH 117/140] pupulate device with dir mode 750 and set uid/gid - -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 3 --- - src/lxc/confile.c | 2 ++ - 2 files changed, 2 insertions(+), 3 deletions(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index d9a7aae..0b10a2d 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4005,13 +4005,11 @@ static int setup_populate_devs(const struct lxc_rootfs *rootfs, struct lxc_list - int ret = 0; - char *pathdirname = NULL; - char path[MAXPATHLEN]; -- mode_t cmask; - mode_t file_mode = 0; - struct lxc_populate_devs *dev_elem = NULL; - struct lxc_list *it = NULL; - - INFO("Populating devices into container"); -- cmask = umask(S_IXUSR | S_IXGRP | S_IXOTH); - lxc_list_for_each(it, devs) { - dev_elem = it->elem; - -@@ -4072,7 +4070,6 @@ static int setup_populate_devs(const struct lxc_rootfs *rootfs, struct lxc_list - return -1; - } - } -- umask(cmask); - - INFO("Populated devices into container /dev"); - return 0; -diff --git a/src/lxc/confile.c b/src/lxc/confile.c -index 01fc944..3a02e09 100644 ---- a/src/lxc/confile.c -+++ b/src/lxc/confile.c -@@ -2335,6 +2335,8 @@ static int set_config_populate_device(const char *key, const char *value, - dev_elem->file_mode = filemode; - dev_elem->maj = major; - dev_elem->min = minor; -+ dev_elem->uid = (uid_t)uid; -+ dev_elem->gid = (gid_t)gid; - - lxc_list_add_elem(dev_list, dev_elem); - --- -1.8.3.1 - diff --git a/0118-fix-sscanf-return-value-check.patch b/0118-fix-sscanf-return-value-check.patch deleted file mode 100644 index 126f0948b345e96df2b7fd86e43132ea32008cb7..0000000000000000000000000000000000000000 --- a/0118-fix-sscanf-return-value-check.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 8a9eddf2b23d4fc3541670e1257e5e1619aba0a6 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Mon, 2 Sep 2019 06:24:07 -0400 -Subject: [PATCH 118/140] fix sscanf return value check - -Signed-off-by: LiFeng ---- - src/lxc/start.c | 2 +- - src/lxc/utils.c | 10 +++++++--- - 2 files changed, 8 insertions(+), 4 deletions(-) - -diff --git a/src/lxc/start.c b/src/lxc/start.c -index 00d478c..c1e0d5d 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -1904,7 +1904,7 @@ static int lxc_check_container_info(char *filename, pid_t pid, pid_t p_pid, unsi - } - - num = sscanf(sbuf, "%d %Lu %d %Lu", &saved_pid, &saved_start_time, &saved_ppid, &saved_pstart_time); -- if (num < 0) { -+ if (num != 4) { - SYSERROR("Call sscanf error"); - ret = -1; - goto out; -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index 1d2e9ee..c83c7a3 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -1952,8 +1952,8 @@ static proc_t *lxc_stat2proc(const char *S) - - /* parse these two strings separately, skipping the leading "(". */ - num = sscanf(S, "%d (%15c", &P->pid, P->cmd); /* comm[16] in kernel */ -- if (num < 0 && errno) { -- ERROR("Call sscanf error: %s", strerror(errno)); -+ if (num != 2) { -+ ERROR("Call sscanf error: %s", errno ? strerror(errno) : ""); - free(P); - return NULL; - } -@@ -1985,7 +1985,11 @@ static proc_t *lxc_stat2proc(const char *S) - &P->exit_signal, &P->processor, /* 2.2.1 ends with "exit_signal" */ - &P->rtprio, &P->sched /* both added to 2.5.18 */ - ); -- -+ if (num != 35) { -+ ERROR("Call sscanf error: %s", errno ? strerror(errno) : ""); -+ free(P); -+ return NULL; -+ } - if (P->tty == 0) - P->tty = -1; /* the old notty val, update elsewhere bef. moving to 0 */ - return P; --- -1.8.3.1 - diff --git a/0119-remove-unuse-binary.patch b/0119-remove-unuse-binary.patch deleted file mode 100644 index 85588b6ebbab1bfe91fe41636af66f340b618287..0000000000000000000000000000000000000000 --- a/0119-remove-unuse-binary.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 77c1a8421731f152a36a53147c7b66bd0e9f040f Mon Sep 17 00:00:00 2001 -From: LiuHao -Date: Wed, 4 Sep 2019 18:01:39 +0800 -Subject: [PATCH 119/140] remove unuse binary - -Signed-off-by: LiuHao ---- - hooks/Makefile.am | 11 ----------- - 1 file changed, 11 deletions(-) - -diff --git a/hooks/Makefile.am b/hooks/Makefile.am -index 5ae73d7..f55c4a9 100644 ---- a/hooks/Makefile.am -+++ b/hooks/Makefile.am -@@ -10,15 +10,4 @@ hooks_SCRIPTS = \ - squid-deb-proxy-client \ - nvidia - --binhooks_PROGRAMS = \ -- unmount-namespace -- --unmount_namespace_SOURCES = \ -- unmount-namespace.c -- --if IS_BIONIC --unmount_namespace_SOURCES += \ -- ../src/include/lxcmntent.c ../src/include/lxcmntent.h --endif -- - EXTRA_DIST=$(hooks_SCRIPTS) --- -1.8.3.1 - diff --git a/0120-remove-unuse-unmount-namespace.patch b/0120-remove-unuse-unmount-namespace.patch deleted file mode 100644 index 33ea319e4bbada7960a2680de760ea2622e0ea41..0000000000000000000000000000000000000000 --- a/0120-remove-unuse-unmount-namespace.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 15dfe27d172680e3abe25af07a9477ca75f8e1d4 Mon Sep 17 00:00:00 2001 -From: LiuHao -Date: Thu, 5 Sep 2019 11:48:57 +0800 -Subject: [PATCH 120/140] remove unuse unmount-namespace - -Signed-off-by: LiuHao ---- - lxc.spec.in | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/lxc.spec.in b/lxc.spec.in -index 7fcd811..2ca12fe 100644 ---- a/lxc.spec.in -+++ b/lxc.spec.in -@@ -259,7 +259,6 @@ fi - %{_libdir}/*.a - %{_libdir}/%{name} - %{_localstatedir}/* --%{_libexecdir}/%{name}/hooks/unmount-namespace - %{_libexecdir}/%{name}/lxc-apparmor-load - %{_libexecdir}/%{name}/lxc-monitord - %attr(4111,root,root) %{_libexecdir}/%{name}/lxc-user-nic --- -1.8.3.1 - diff --git a/0121-optimize-log-when-root-path-is-invalid.patch b/0121-optimize-log-when-root-path-is-invalid.patch deleted file mode 100644 index d61cc5f48eef088d13a636983786b214e002db9b..0000000000000000000000000000000000000000 --- a/0121-optimize-log-when-root-path-is-invalid.patch +++ /dev/null @@ -1,26 +0,0 @@ -From d4b8e904b6730f3eefa96878eca9e42219437c11 Mon Sep 17 00:00:00 2001 -From: TanYifeng -Date: Sat, 21 Sep 2019 06:19:25 -0400 -Subject: [PATCH 121/140] optimize log when root path is invalid - -Signed-off-by: TanYifeng ---- - src/lxc/conf.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 0b10a2d..5fd65e7 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4881,7 +4881,7 @@ static char *get_root_path(const char *path, const char *backend) - strcmp(backend, "loop") == 0) { - tmp = strrchr(path, ':'); - if (tmp == NULL) { -- ERROR("Out of memory"); -+ ERROR("Invalid root path format"); - return NULL; - } - tmp++; --- -1.8.3.1 - diff --git a/0122-lxc-fix-code-reivew-errors.patch b/0122-lxc-fix-code-reivew-errors.patch deleted file mode 100644 index 4e9b50b51a426d5eeb47d4d8b6ba5f167b8c5f13..0000000000000000000000000000000000000000 --- a/0122-lxc-fix-code-reivew-errors.patch +++ /dev/null @@ -1,210 +0,0 @@ -From cb3044f47a1823994ee8133055ca6662cbe56838 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Thu, 26 Sep 2019 07:47:19 -0400 -Subject: [PATCH 122/140] lxc: fix code reivew errors - -Signed-off-by: LiFeng ---- - src/lxc/commands.c | 2 +- - src/lxc/commands_utils.c | 2 +- - src/lxc/confile.c | 4 ++-- - src/lxc/json/json_common.c | 15 +++++---------- - src/lxc/lxccontainer.c | 6 ++++-- - src/lxc/terminal.c | 8 +++++--- - src/lxc/utils.c | 2 +- - 7 files changed, 19 insertions(+), 20 deletions(-) - -diff --git a/src/lxc/commands.c b/src/lxc/commands.c -index fa02a4b..7d6cf6f 100644 ---- a/src/lxc/commands.c -+++ b/src/lxc/commands.c -@@ -1083,7 +1083,7 @@ int lxc_cmd_set_terminal_fifos(const char *name, const char *lxcpath, const char - if (tmp == NULL) - return -1; - ret = snprintf(tmp, len, "%s%s%s%s%s", cmd_in_fifo, split, cmd_out_fifo, split, cmd_err_fifo); -- if (ret < 0) -+ if (ret < 0 || ret >= len) - return -1; - - struct lxc_cmd_rr cmd = { -diff --git a/src/lxc/commands_utils.c b/src/lxc/commands_utils.c -index f48f118..56ecce7 100644 ---- a/src/lxc/commands_utils.c -+++ b/src/lxc/commands_utils.c -@@ -144,7 +144,7 @@ int lxc_make_abstract_socket_name(char *path, size_t pathlen, - } - - ret = snprintf(offset, len, "%s/%s/%s", lxcpath, name, suffix); -- if (ret < 0) { -+ if (ret < 0 || ret >= len) { - ERROR("Failed to create abstract socket name"); - return -1; - } -diff --git a/src/lxc/confile.c b/src/lxc/confile.c -index 3a02e09..3eaae4a 100644 ---- a/src/lxc/confile.c -+++ b/src/lxc/confile.c -@@ -3834,7 +3834,7 @@ static int get_config_prlimit(const char *key, char *retv, int inlen, - partlen = STRLITERALLEN("unlimited"); - } else { - partlen = snprintf(buf, MAX_LIMIT_BUF_LEN, "%" PRIu64, (uint64_t)lim->limit.rlim_cur); -- if (partlen < 0) { -+ if (partlen < 0 || partlen >= MAX_LIMIT_BUF_LEN) { - return -1; - } - } -@@ -3844,7 +3844,7 @@ static int get_config_prlimit(const char *key, char *retv, int inlen, - (void)memcpy(buf + partlen, ":unlimited", STRLITERALLEN(":unlimited") + 1); - } else { - nret = snprintf(buf + partlen, (MAX_LIMIT_BUF_LEN - partlen), ":%" PRIu64, (uint64_t)lim->limit.rlim_max); -- if (nret < 0) { -+ if (nret < 0 || nret >= (MAX_LIMIT_BUF_LEN - partlen)) { - return -1; - } - } -diff --git a/src/lxc/json/json_common.c b/src/lxc/json/json_common.c -index ed2fe83..ec20c59 100755 ---- a/src/lxc/json/json_common.c -+++ b/src/lxc/json/json_common.c -@@ -17,7 +17,7 @@ yajl_gen_status reformat_uint(void *ctx, long long unsigned int num) { - int ret; - - ret = snprintf(numstr, MAX_NUM_STR_LEN, "%llu", num); -- if (ret < 0) { -+ if (ret < 0 || ret >= MAX_NUM_STR_LEN) { - return yajl_gen_in_error_state; - } - return reformat_number(ctx, (const char *)numstr, strlen(numstr)); -@@ -28,7 +28,7 @@ yajl_gen_status reformat_int(void *ctx, long long int num) { - int ret; - - ret = snprintf(numstr, MAX_NUM_STR_LEN, "%lld", num); -- if (ret < 0) { -+ if (ret < 0 || ret >= MAX_NUM_STR_LEN) { - return yajl_gen_in_error_state; - } - return reformat_number(ctx, (const char *)numstr, strlen(numstr)); -@@ -400,7 +400,7 @@ yajl_gen_status gen_json_map_int_int(void *ctx, json_map_int_int *map, struct pa - char numstr[MAX_NUM_STR_LEN]; - int nret; - nret = snprintf(numstr, MAX_NUM_STR_LEN, "%lld", (long long int)map->keys[i]); -- if (nret < 0) { -+ if (nret < 0 || nret >= MAX_NUM_STR_LEN) { - if (!*err && asprintf(err, "Error to print string") < 0) { - *(err) = safe_strdup("error allocating memory"); - } -@@ -541,7 +541,7 @@ yajl_gen_status gen_json_map_int_bool(void *ctx, json_map_int_bool *map, struct - char numstr[MAX_NUM_STR_LEN]; - int nret; - nret = snprintf(numstr, MAX_NUM_STR_LEN, "%lld", (long long int)map->keys[i]); -- if (nret < 0) { -+ if (nret < 0 || nret >= MAX_NUM_STR_LEN) { - if (!*err && asprintf(err, "Error to print string") < 0) { - *(err) = safe_strdup("error allocating memory"); - } -@@ -569,11 +569,6 @@ yajl_gen_status gen_json_map_int_bool(void *ctx, json_map_int_bool *map, struct - - void free_json_map_int_bool(json_map_int_bool *map) { - if (map != NULL) { -- size_t i; -- for (i = 0; i < map->len; i++) { -- // No need to free key for type int -- // No need to free value for type bool -- } - free(map->keys); - map->keys = NULL; - free(map->values); -@@ -677,7 +672,7 @@ yajl_gen_status gen_json_map_int_string(void *ctx, json_map_int_string *map, str - char numstr[MAX_NUM_STR_LEN]; - int nret; - nret = snprintf(numstr, MAX_NUM_STR_LEN, "%lld", (long long int)map->keys[i]); -- if (nret < 0) { -+ if (nret < 0 || nret >= MAX_NUM_STR_LEN) { - if (!*err && asprintf(err, "Error to print string") < 0) { - *(err) = safe_strdup("error allocating memory"); - } -diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index 5a72483..9f9cbfc 100644 ---- a/src/lxc/lxccontainer.c -+++ b/src/lxc/lxccontainer.c -@@ -3200,7 +3200,7 @@ static bool container_destroy(struct lxc_container *c, - ERROR("Failed to destroy directory \"%s\" for \"%s\"", path, - c->name); - ret = snprintf(msg, BUFSIZ, "Failed to destroy directory \"%s\": %s", path, errno ? strerror(errno) : "error"); -- if (ret < 0) { -+ if (ret < 0 || ret >= BUFSIZ) { - ERROR("Sprintf failed"); - goto out; - } -@@ -5276,6 +5276,7 @@ static int set_start_extral_configs(struct lxc_container *c) - char fpath[PATH_MAX] = {0}; - parser_error jerr = NULL; - int ret = -1; -+ int nret = 0; - container_start_generate_config *start_conf = NULL; - struct lxc_conf *lconf = c->lxc_conf; - size_t i = 0; -@@ -5288,7 +5289,8 @@ static int set_start_extral_configs(struct lxc_container *c) - } - lconf = c->lxc_conf; - } -- if (snprintf(fpath, PATH_MAX, "%s/%s/%s", c->config_path, c->name, START_GENERATE_CONFIG) < 0) { -+ nret = snprintf(fpath, PATH_MAX, "%s/%s/%s", c->config_path, c->name, START_GENERATE_CONFIG); -+ if (nret < 0 || nret >= PATH_MAX) { - fprintf(stderr, "Sprintf config path failed\n"); - return -1; - } -diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index 32c69a4..e81f57e 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -242,13 +242,13 @@ static int lxc_terminal_rename_old_log_file(struct lxc_terminal *terminal) - - for (i = terminal->log_rotate - 1; i > 1; i--) { - ret = snprintf(tmp, PATH_MAX, "%s.%u", terminal->log_path, i); -- if (ret < 0) { -+ if (ret < 0 || ret >= PATH_MAX) { - return -EFBIG; - } - free(rename_fname); - rename_fname = safe_strdup(tmp); - ret = snprintf(tmp, PATH_MAX, "%s.%u", terminal->log_path, (i - 1)); -- if (ret < 0) { -+ if (ret < 0 || ret >= PATH_MAX) { - free(rename_fname); - return -EFBIG; - } -@@ -415,6 +415,7 @@ static bool get_time_buffer(struct timespec *timestamp, char *timebuffer, - int32_t nanos = 0; - time_t seconds; - size_t len = 0; -+ int ret = 0; - - if (!timebuffer || !maxsize) { - return false; -@@ -426,7 +427,8 @@ static bool get_time_buffer(struct timespec *timestamp, char *timebuffer, - - nanos = (int32_t)timestamp->tv_nsec; - len = strlen(timebuffer); -- if (snprintf(timebuffer + len, (maxsize - len), ".%09dZ", nanos) < 0) { -+ ret = snprintf(timebuffer + len, (maxsize - len), ".%09dZ", nanos); -+ if (ret < 0 || ret >= (maxsize - len)) { - return false; - } - -diff --git a/src/lxc/utils.c b/src/lxc/utils.c -index c83c7a3..31bcac7 100644 ---- a/src/lxc/utils.c -+++ b/src/lxc/utils.c -@@ -2041,7 +2041,7 @@ void lxc_write_error_message(int errfd, const char *format, ...) - va_start(argp, format); - ret = vsnprintf(errbuf, BUFSIZ, format, argp); - va_end(argp); -- if (ret < 0) -+ if (ret < 0 || ret >= BUFSIZ) - SYSERROR("Failed to call vsnprintf"); - sret = write(errfd, errbuf, strlen(errbuf)); - if (sret < 0) --- -1.8.3.1 - diff --git a/0123-in-accordance-with-hook-spec-in-oci.patch b/0123-in-accordance-with-hook-spec-in-oci.patch deleted file mode 100644 index 0bfd9c78a77857e4155a58b5bb9c2d571f810d02..0000000000000000000000000000000000000000 --- a/0123-in-accordance-with-hook-spec-in-oci.patch +++ /dev/null @@ -1,81 +0,0 @@ -From b6c3d8631ce628d2f71b4c2ff699c0bdeaed97a8 Mon Sep 17 00:00:00 2001 -From: LiuHao -Date: Mon, 25 Nov 2019 21:15:40 +0800 -Subject: [PATCH 123/140] in accordance with hook spec in oci - -Signed-off-by: LiuHao ---- - src/lxc/cgroups/cgfsng.c | 4 ++-- - src/lxc/conf.c | 6 +++--- - src/lxc/start.c | 14 ++++---------- - 3 files changed, 9 insertions(+), 15 deletions(-) - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index 7c92abe..87b49b0 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -2013,8 +2013,8 @@ __cgfsng_ops static bool cgfsng_attach(struct cgroup_ops *ops, const char *name, - - path = lxc_cmd_get_cgroup_path(name, lxcpath, h->controllers[0]); - /* not running */ -- if (!path) -- continue; -+ if (path == NULL) -+ return false; - - fullpath = build_full_cgpath_from_monitorpath(h, path, "cgroup.procs"); - free(path); -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index 5fd65e7..21ec340 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4937,9 +4937,9 @@ static int do_run_oci_hooks(const char *name, const char *lxcpath, struct lxc_co - case OCI_HOOK_POSTSTOP: - for (i = 0; i < lc->ocihooks->poststop_len; i++) { - work_conf.ocihook = lc->ocihooks->poststop[i]; -- ret = run_ocihook_script_argv(name, "lxc", &work_conf, lxcpath, rootpath); -- if (ret != 0) -- break; -+ 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: -diff --git a/src/lxc/start.c b/src/lxc/start.c -index c1e0d5d..7246283 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -1185,14 +1185,11 @@ void lxc_fini(const char *name, struct lxc_handler *handler) - while (namespace_count--) - free(namespaces[namespace_count]); - -- // if we shared pid namespace with others, should kill all processes within container cgroup -- if (handler->conf->ns_share[LXC_NS_PID] != NULL) { -- TRACE("Trying to kill all subprocess"); -- signal_all_processes(handler); -- TRACE("Finished kill all subprocess"); -- } - retry: - if (!cgroup_ops->destroy(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++; -@@ -2851,10 +2848,7 @@ int do_lxcapi_clean_resource(char *name, char *lxcpath, struct lxc_conf *conf, p - ret = -1; - goto out; - } -- // if we shared pid namespace with others, should kill all processes within container cgroup -- if (handler->conf->ns_share[LXC_NS_PID] != NULL) { -- signal_all_processes(handler); -- } -+ signal_all_processes(handler); - - 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); --- -1.8.3.1 - diff --git a/0124-lxc-close-maincmd-fd-before-destroy-cgroup.patch b/0124-lxc-close-maincmd-fd-before-destroy-cgroup.patch deleted file mode 100644 index 170e7ef8e40fe18cb87e515f231d3348e83ef10d..0000000000000000000000000000000000000000 --- a/0124-lxc-close-maincmd-fd-before-destroy-cgroup.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 3478e45d5a8f25e0da6581004a6dc309cc47608d Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Wed, 27 Nov 2019 22:33:46 -0500 -Subject: [PATCH 124/140] lxc: close maincmd fd before destroy cgroup - -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgfsng.c | 6 ++++-- - src/lxc/start.c | 33 ++++++++++++++++++--------------- - 2 files changed, 22 insertions(+), 17 deletions(-) - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index 87b49b0..c96285e 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -2013,8 +2013,10 @@ __cgfsng_ops static bool cgfsng_attach(struct cgroup_ops *ops, const char *name, - - path = lxc_cmd_get_cgroup_path(name, lxcpath, h->controllers[0]); - /* not running */ -- if (path == NULL) -- return false; -+ if (path == NULL) { -+ ERROR("Failed to attach %d to cgroup of %s", (int)pid, name); -+ return false; -+ } - - fullpath = build_full_cgpath_from_monitorpath(h, path, "cgroup.procs"); - free(path); -diff --git a/src/lxc/start.c b/src/lxc/start.c -index 7246283..63be4e3 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -1185,19 +1185,6 @@ void lxc_fini(const char *name, struct lxc_handler *handler) - while (namespace_count--) - free(namespaces[namespace_count]); - --retry: -- if (!cgroup_ops->destroy(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); -- } -- - if (handler->conf->reboot == REBOOT_NONE) { - /* For all new state clients simply close the command socket. - * This will inform all state clients that the container is -@@ -1208,13 +1195,27 @@ retry: - lxc_abstract_unix_close(handler->conf->maincmd_fd); - handler->conf->maincmd_fd = -1; - TRACE("Closed command socket"); -+ } - -+retry: -+ if (!cgroup_ops->destroy(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); -+ } -+ -+ if (handler->conf->reboot == REBOOT_NONE) { - /* This function will try to connect to the legacy lxc-monitord - * state server and only exists for backwards compatibility. - */ - lxc_monitor_send_state(name, STOPPED, handler->lxcpath); - -- - /* isuald: write exit code to exit fifo */ - if (handler->conf->exit_fd >= 0) { - ret = write(handler->conf->exit_fd, &handler->exit_code, sizeof(int)); -@@ -2848,7 +2849,6 @@ int do_lxcapi_clean_resource(char *name, char *lxcpath, struct lxc_conf *conf, p - ret = -1; - goto out; - } -- signal_all_processes(handler); - - 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); -@@ -2857,6 +2857,9 @@ int do_lxcapi_clean_resource(char *name, char *lxcpath, struct lxc_conf *conf, p - - retry: - if (!handler->cgroup_ops->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++; --- -1.8.3.1 - diff --git a/0125-lxc-fix-strcat-bug-in-cleanpath.patch b/0125-lxc-fix-strcat-bug-in-cleanpath.patch deleted file mode 100644 index d28d50faa6e35bd457138909a3581bbc21df81a2..0000000000000000000000000000000000000000 --- a/0125-lxc-fix-strcat-bug-in-cleanpath.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 6693cc04916b6f270c3a5e0316700350a18eb4c2 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Fri, 29 Nov 2019 22:16:05 -0500 -Subject: [PATCH 125/140] lxc: fix strcat bug in cleanpath - -Signed-off-by: LiFeng ---- - src/lxc/path.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/lxc/path.c b/src/lxc/path.c -index 7a5dce9..083893e 100644 ---- a/src/lxc/path.c -+++ b/src/lxc/path.c -@@ -200,6 +200,10 @@ char *cleanpath(const char *path, char *realpath, size_t realpath_len) - ERROR("Failed to get the end of respath"); - goto error; - } -+ if (strlen(path) > (PATH_MAX - strlen(respath) - 1)) { -+ ERROR("Path is too long"); -+ goto error; -+ } - strcat(respath, path); - stpos = path; - } else { --- -1.8.3.1 - diff --git a/0126-add-user-option-for-lxc-attach.patch b/0126-add-user-option-for-lxc-attach.patch deleted file mode 100644 index dedcec8c2faa6b613ab88f81069d7613ee97b2a0..0000000000000000000000000000000000000000 --- a/0126-add-user-option-for-lxc-attach.patch +++ /dev/null @@ -1,134 +0,0 @@ -From 60006b967762c1d57ca41981388bf685773e3e17 Mon Sep 17 00:00:00 2001 -From: wujing -Date: Wed, 30 Oct 2019 18:41:02 +0800 -Subject: [PATCH 126/140] add user option for lxc-attach - -Signed-off-by: wujing ---- - src/lxc/tools/lxc_attach.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 75 insertions(+) - -diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c -index 7d51ad7..0d40155 100644 ---- a/src/lxc/tools/lxc_attach.c -+++ b/src/lxc/tools/lxc_attach.c -@@ -62,6 +62,8 @@ static char **extra_env; - static ssize_t extra_env_size; - static char **extra_keep; - static ssize_t extra_keep_size; -+static uid_t custom_uid = (uid_t)-1; -+static gid_t custom_gid = (gid_t)-1; - - static const struct option my_longopts[] = { - {"elevated-privileges", optional_argument, 0, 'e'}, -@@ -75,6 +77,7 @@ static const struct option my_longopts[] = { - {"set-var", required_argument, 0, 'v'}, - {"pty-log", required_argument, 0, 'L'}, - {"rcfile", required_argument, 0, 'f'}, -+ {"user", required_argument, 0, 'u'}, - {"in-fifo", required_argument, 0, OPT_INPUT_FIFO}, /* isulad add terminal fifos*/ - {"out-fifo", required_argument, 0, OPT_OUTPUT_FIFO}, - {"err-fifo", required_argument, 0, OPT_STDERR_FIFO}, -@@ -130,6 +133,7 @@ Options :\n\ - -f, --rcfile=FILE\n\ - Load configuration file FILE\n\ - --timeout Timeout in seconds (default: 0)\n\ -+ -u, --user User ID (format: UID[:GID])\n\ - ", - .options = my_longopts, - .parser = my_parser, -@@ -141,6 +145,69 @@ Options :\n\ - // isulad: send '128 + signal' if container is killed by signal. - #define ExitSignalOffset 128 - -+static int parse_user_id(const char *username, char **uid, char **gid, char **tmp_dup) -+{ -+ char *tmp = NULL; -+ char *pdot = NULL; -+ -+ if (uid == NULL || gid == NULL || tmp_dup == NULL) { -+ return -1; -+ } -+ -+ if (username != NULL) { -+ tmp = strdup(username); -+ if (tmp == NULL) { -+ ERROR("Failed to duplicate user name"); -+ return -1; -+ } -+ -+ // for free tmp in caller -+ *tmp_dup = tmp; -+ pdot = strstr(tmp, ":"); -+ if (pdot != NULL) { -+ *pdot = '\0'; -+ if (pdot != tmp) { -+ // uid found -+ *uid = tmp; -+ } -+ -+ if (*(pdot + 1) != '\0') { -+ // gid found -+ *gid = pdot + 1; -+ } -+ } else { -+ // No : found -+ if (*tmp != '\0') { -+ *uid = tmp; -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+static int get_attach_uid_gid(uid_t *user_id, gid_t *group_id, const char *username) -+{ -+ char *tmp = NULL; -+ char *uid = NULL; -+ char *gid = NULL; -+ -+ // parse uid and gid by username -+ if (parse_user_id(username, &uid, &gid, &tmp) != 0) { -+ return -1; -+ } -+ -+ if (uid != NULL) { -+ *user_id = (unsigned int)atoll(uid); -+ } -+ if (gid != NULL) { -+ *group_id = (unsigned int)atoll(gid); -+ } -+ -+ free(tmp); -+ return 0; -+} -+ - static int my_parser(struct lxc_arguments *args, int c, char *arg) - { - int ret; -@@ -198,6 +265,12 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) - case 'f': - args->rcfile = arg; - break; -+ case 'u': -+ if (get_attach_uid_gid(&custom_uid, &custom_gid, arg) != 0) { -+ ERROR("Failed to get attach user U/GID"); -+ return -1; -+ } -+ break; - case OPT_INPUT_FIFO: - args->terminal_fifos[0] = arg; - break; -@@ -488,6 +561,8 @@ int main(int argc, char *argv[]) - attach_options.extra_env_vars = extra_env; - attach_options.extra_keep_env = extra_keep; - attach_options.timeout = my_args.attach_timeout; -+ attach_options.uid = custom_uid; -+ attach_options.gid = custom_gid; - - if (my_args.argc > 0) { - command.program = my_args.argv[0]; --- -1.8.3.1 - diff --git a/0127-log-only-write-size-begin-if-buffer-is-full.patch b/0127-log-only-write-size-begin-if-buffer-is-full.patch deleted file mode 100644 index bf1da30716719a1b240dfea1907c4ec6a05ad881..0000000000000000000000000000000000000000 --- a/0127-log-only-write-size-begin-if-buffer-is-full.patch +++ /dev/null @@ -1,26 +0,0 @@ -From de46120969e9d164bb2d4926c16414daafa86063 Mon Sep 17 00:00:00 2001 -From: TanYifeng -Date: Tue, 3 Dec 2019 22:43:25 -0500 -Subject: [PATCH 127/140] log: only write (size - begin) if buffer is full - -Signed-off-by: TanYifeng ---- - src/lxc/terminal.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index e81f57e..b547013 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -538,7 +538,7 @@ static int lxc_terminal_write_log_file(struct lxc_terminal *terminal, const char - * noting that it's a partial log line. */ - if (buf == NULL || (begin == 0 && size == __BUF_CACHE_SIZE)) { - if (begin < size) { -- ret = lxc_logger_write(terminal, type, cache + begin, index - begin + 1); -+ ret = lxc_logger_write(terminal, type, cache + begin, size - begin); - if (ret < 0) { - WARN("Failed to log msg"); - } --- -1.8.3.1 - diff --git a/0129-cgfsng-add-retry-for-enter-cgroup.patch b/0129-cgfsng-add-retry-for-enter-cgroup.patch deleted file mode 100644 index e1a6ee6e5da6072e538ef2541721ce693036464c..0000000000000000000000000000000000000000 --- a/0129-cgfsng-add-retry-for-enter-cgroup.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 3a7ab52bf9def26650df4f47ade319a441a4dca7 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Tue, 10 Dec 2019 05:40:20 -0500 -Subject: [PATCH 129/140] cgfsng: add retry for enter cgroup - -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgfsng.c | 25 +++++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index c96285e..50bdc77 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -1300,11 +1300,23 @@ __cgfsng_ops static bool cgfsng_payload_enter(struct cgroup_ops *ops, pid_t pid) - for (int i = 0; ops->hierarchies[i]; i++) { - int ret; - char *fullpath; -+ int retry_count = 0; -+ int max_retry = 10; - - fullpath = must_make_path(ops->hierarchies[i]->container_full_path, - "cgroup.procs", NULL); -+retry: - ret = lxc_write_to_file(fullpath, pidstr, len, false, 0666); - if (ret != 0) { -+ if (errno == ENOENT) { -+ if (retry_count < max_retry) { -+ SYSERROR("Failed to enter cgroup \"%s\" with retry count:%d", fullpath, retry_count); -+ (void)mkdir_eexist_on_last(ops->hierarchies[i]->container_full_path, 0755); -+ usleep(100 * 1000); /* 100 millisecond */ -+ retry_count++; -+ goto retry; -+ } -+ } - SYSERROR("Failed to enter cgroup \"%s\"", fullpath); - free(fullpath); - return false; -@@ -2201,6 +2213,8 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, - struct hierarchy *h; - int ret = 0; - char *controller = NULL; -+ int retry_count = 0; -+ int max_retry = 10; - - len = strlen(filename); - controller = alloca(len + 1); -@@ -2228,8 +2242,19 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, - } - - fullpath = must_make_path(h->container_full_path, filename, NULL); -+ -+retry: - ret = lxc_write_to_file(fullpath, value, strlen(value), false, 0666); - if (ret) { -+ if (errno == ENOENT) { -+ if (retry_count < max_retry) { -+ SYSERROR("setting cgroup config for ready process caused \"failed to write %s to %s\".", value, fullpath); -+ (void)mkdir_eexist_on_last(h->container_full_path, 0755); -+ usleep(100 * 1000); /* 100 millisecond */ -+ retry_count++; -+ goto retry; -+ } -+ } - lxc_write_error_message(ops->errfd, - "%s:%d: setting cgroup config for ready process caused \"failed to write %s to %s: %s\".", - __FILE__, __LINE__, value, fullpath, strerror(errno)); --- -1.8.3.1 - diff --git a/0130-fix-snprintf-create-abstract-socket-name-bug.patch b/0130-fix-snprintf-create-abstract-socket-name-bug.patch deleted file mode 100644 index a28e1f5b0f2b96b91b4184b905f663bca8b7cf82..0000000000000000000000000000000000000000 --- a/0130-fix-snprintf-create-abstract-socket-name-bug.patch +++ /dev/null @@ -1,26 +0,0 @@ -From c315e6e595e6e5796c148c52ae18b8ba9b053e08 Mon Sep 17 00:00:00 2001 -From: wujing -Date: Tue, 17 Dec 2019 21:24:24 +0800 -Subject: [PATCH 130/140] fix snprintf create abstract socket name bug - -Signed-off-by: wujing ---- - src/lxc/commands_utils.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/lxc/commands_utils.c b/src/lxc/commands_utils.c -index 56ecce7..f48f118 100644 ---- a/src/lxc/commands_utils.c -+++ b/src/lxc/commands_utils.c -@@ -144,7 +144,7 @@ int lxc_make_abstract_socket_name(char *path, size_t pathlen, - } - - ret = snprintf(offset, len, "%s/%s/%s", lxcpath, name, suffix); -- if (ret < 0 || ret >= len) { -+ if (ret < 0) { - ERROR("Failed to create abstract socket name"); - return -1; - } --- -1.8.3.1 - diff --git a/0131-fix-commands-and-terminal-memory-leak-bug.patch b/0131-fix-commands-and-terminal-memory-leak-bug.patch deleted file mode 100644 index dfcf9f14a11b3f3d1c24d52feff44b0f38e11943..0000000000000000000000000000000000000000 --- a/0131-fix-commands-and-terminal-memory-leak-bug.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 720f6f1c128eaac5c37153cdc30f09e4b18785aa Mon Sep 17 00:00:00 2001 -From: wujing -Date: Wed, 18 Dec 2019 15:44:19 +0800 -Subject: [PATCH 131/140] fix commands and terminal memory leak bug - -Signed-off-by: wujing ---- - src/lxc/commands.c | 5 ++++- - src/lxc/terminal.c | 1 + - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/src/lxc/commands.c b/src/lxc/commands.c -index 7d6cf6f..b70564f 100644 ---- a/src/lxc/commands.c -+++ b/src/lxc/commands.c -@@ -1083,8 +1083,11 @@ int lxc_cmd_set_terminal_fifos(const char *name, const char *lxcpath, const char - if (tmp == NULL) - return -1; - ret = snprintf(tmp, len, "%s%s%s%s%s", cmd_in_fifo, split, cmd_out_fifo, split, cmd_err_fifo); -- if (ret < 0 || ret >= len) -+ if (ret < 0 || ret >= len) { -+ ERROR("Failed to snprintf in fifo of command"); -+ free(tmp); - return -1; -+ } - - struct lxc_cmd_rr cmd = { - .req = { -diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c -index b547013..bccc23d 100644 ---- a/src/lxc/terminal.c -+++ b/src/lxc/terminal.c -@@ -243,6 +243,7 @@ static int lxc_terminal_rename_old_log_file(struct lxc_terminal *terminal) - for (i = terminal->log_rotate - 1; i > 1; i--) { - ret = snprintf(tmp, PATH_MAX, "%s.%u", terminal->log_path, i); - if (ret < 0 || ret >= PATH_MAX) { -+ free(rename_fname); - return -EFBIG; - } - free(rename_fname); --- -1.8.3.1 - diff --git a/0132-lxc-fix-bug-in-cgroup-parent.patch b/0132-lxc-fix-bug-in-cgroup-parent.patch deleted file mode 100644 index 29afe33642ef667dd549ef7461eff9022af7cfc4..0000000000000000000000000000000000000000 --- a/0132-lxc-fix-bug-in-cgroup-parent.patch +++ /dev/null @@ -1,169 +0,0 @@ -From 293ee3f82a8236de0a3b66c818b957f0a71c30d7 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Wed, 18 Dec 2019 06:00:58 -0500 -Subject: [PATCH 132/140] lxc: fix bug in cgroup-parent - -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgfsng.c | 78 ++++++++++++++++++++++++++++-------------------- - 1 file changed, 46 insertions(+), 32 deletions(-) - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index 50bdc77..2f86a66 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -557,45 +557,24 @@ on_error: - return false; - } - --/* Initialize the cpuset hierarchy in first directory of @gname and set -- * cgroup.clone_children so that children inherit settings. Since the -- * h->base_path is populated by init or ourselves, we know it is already -- * initialized. -- */ --static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname) -+static bool build_sub_cpuset_cgroup_dir(char *cgpath) - { - int ret; - char v; -- char *cgpath, *clonechildrenpath, *slash; -- -- if (!string_in_list(h->controllers, "cpuset")) -- return true; -- -- if (*cgname == '/') -- cgname++; -- slash = strchr(cgname, '/'); -- if (slash) -- *slash = '\0'; -- -- cgpath = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL); -- if (slash) -- *slash = '/'; -+ char *clonechildrenpath = NULL; - - ret = mkdir_p(cgpath, 0755); - if (ret < 0) { - if (errno != EEXIST) { - SYSERROR("Failed to create directory \"%s\"", cgpath); -- free(cgpath); - return false; - } - } - -- clonechildrenpath = -- must_make_path(cgpath, "cgroup.clone_children", NULL); -+ clonechildrenpath = must_make_path(cgpath, "cgroup.clone_children", NULL); - /* unified hierarchy doesn't have clone_children */ - if (!file_exists(clonechildrenpath)) { - free(clonechildrenpath); -- free(cgpath); - return true; - } - -@@ -603,7 +582,6 @@ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname) - if (ret < 0) { - SYSERROR("Failed to read file \"%s\"", clonechildrenpath); - free(clonechildrenpath); -- free(cgpath); - return false; - } - -@@ -611,7 +589,6 @@ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname) - if (!cg_legacy_filter_and_set_cpus(cgpath, v == '1')) { - SYSERROR("Failed to remove isolated cpus"); - free(clonechildrenpath); -- free(cgpath); - return false; - } - -@@ -619,18 +596,15 @@ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname) - if (v == '1') { - DEBUG("\"cgroup.clone_children\" was already set to \"1\""); - free(clonechildrenpath); -- free(cgpath); - return true; - } - - /* copy parent's settings */ - if (!copy_parent_file(cgpath, "cpuset.mems")) { - SYSERROR("Failed to copy \"cpuset.mems\" settings"); -- free(cgpath); - free(clonechildrenpath); - return false; - } -- free(cgpath); - - ret = lxc_write_to_file(clonechildrenpath, "1", 1, false, 0666); - if (ret < 0) { -@@ -641,6 +615,48 @@ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname) - } - free(clonechildrenpath); - return true; -+ -+} -+ -+/* Initialize the cpuset hierarchy in first directory of @gname and set -+ * cgroup.clone_children so that children inherit settings. Since the -+ * h->base_path is populated by init or ourselves, we know it is already -+ * initialized. -+ */ -+static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname) -+{ -+ char *cgpath, *slash; -+ bool sub_mk_success = false; -+ -+ if (!string_in_list(h->controllers, "cpuset")) -+ return true; -+ -+ cgname += strspn(cgname, "/"); -+ -+ slash = strchr(cgname, '/'); -+ -+ if (slash != NULL) { -+ while (slash) { -+ *slash = '\0'; -+ cgpath = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL); -+ sub_mk_success = build_sub_cpuset_cgroup_dir(cgpath); -+ free(cgpath); -+ *slash = '/'; -+ if (!sub_mk_success) { -+ return false; -+ } -+ slash = strchr(slash + 1, '/'); -+ } -+ } else { -+ cgpath = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL); -+ sub_mk_success = build_sub_cpuset_cgroup_dir(cgpath); -+ free(cgpath); -+ if (!sub_mk_success) { -+ return false; -+ } -+ } -+ -+ return true; - } - - /* Given two null-terminated lists of strings, return true if any string is in -@@ -1207,9 +1223,7 @@ static int mkdir_eexist_on_last(const char *dir, mode_t mode) - { - const char *tmp = dir; - const char *orig = dir; -- size_t orig_len; - -- orig_len = strlen(dir); - do { - int ret; - size_t cur_len; -@@ -1226,7 +1240,7 @@ static int mkdir_eexist_on_last(const char *dir, mode_t mode) - - ret = mkdir(makeme, mode); - if (ret < 0) { -- if ((errno != EEXIST) || (orig_len == cur_len)) { -+ if (errno != EEXIST) { - SYSERROR("Failed to create directory \"%s\"", makeme); - free(makeme); - return -1; --- -1.8.3.1 - diff --git a/0133-lxc-fix-bug-in-cgfsng.patch b/0133-lxc-fix-bug-in-cgfsng.patch deleted file mode 100644 index 21810a064355d3f6e83516044d50b793f988d91f..0000000000000000000000000000000000000000 --- a/0133-lxc-fix-bug-in-cgfsng.patch +++ /dev/null @@ -1,179 +0,0 @@ -From 8b3ba34aad74f1bf204095a479c9d28436de2627 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Wed, 18 Dec 2019 09:01:25 -0500 -Subject: [PATCH 133/140] lxc: fix bug in cgfsng - -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgfsng.c | 100 +++++++++++++++++++++++------------------------ - 1 file changed, 50 insertions(+), 50 deletions(-) - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index 2f86a66..5908c31 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -387,14 +387,8 @@ static bool cg_legacy_filter_and_set_cpus(char *path, bool am_initialized) - char *cpulist = NULL, *isolcpus = NULL, *posscpus = NULL; - uint32_t *isolmask = NULL, *possmask = NULL; - bool bret = false, flipped_bit = false; -+ bool need_read_parent = false; - -- lastslash = strrchr(path, '/'); -- if (!lastslash) { -- ERROR("Failed to detect \"/\" in \"%s\"", path); -- return bret; -- } -- oldv = *lastslash; -- *lastslash = '\0'; - fpath = must_make_path(path, "cpuset.cpus", NULL); - posscpus = read_file(fpath); - if (!posscpus) { -@@ -402,6 +396,25 @@ static bool cg_legacy_filter_and_set_cpus(char *path, bool am_initialized) - goto on_error; - } - -+ if (strcmp(posscpus, "\n") == 0) { -+ need_read_parent = true; -+ free(fpath); -+ free(posscpus); -+ lastslash = strrchr(path, '/'); -+ if (!lastslash) { -+ ERROR("Failed to detect \"/\" in \"%s\"", path); -+ return bret; -+ } -+ oldv = *lastslash; -+ *lastslash = '\0'; -+ fpath = must_make_path(path, "cpuset.cpus", NULL); -+ posscpus = read_file(fpath); -+ if (!posscpus) { -+ SYSERROR("Failed to read file \"%s\"", fpath); -+ goto on_error; -+ } -+ } -+ - /* Get maximum number of cpus found in possible cpuset. */ - maxposs = get_max_cpus(posscpus); - if (maxposs < 0 || maxposs >= INT_MAX - 1) -@@ -489,7 +502,9 @@ static bool cg_legacy_filter_and_set_cpus(char *path, bool am_initialized) - } - - copy_parent: -- *lastslash = oldv; -+ if (need_read_parent) { -+ *lastslash = oldv; -+ } - free(fpath); - fpath = must_make_path(path, "cpuset.cpus", NULL); - ret = lxc_write_to_file(fpath, cpulist, strlen(cpulist), false, 0666); -@@ -522,6 +537,25 @@ static bool copy_parent_file(char *path, char *file) - char *fpath, *lastslash, oldv; - int len = 0; - char *value = NULL; -+ char *current = NULL; -+ -+ fpath = must_make_path(path, file, NULL); -+ current = read_file(fpath); -+ -+ if (current == NULL) { -+ SYSERROR("Failed to read file \"%s\"", fpath); -+ free(fpath); -+ return false; -+ } -+ -+ if (strcmp(current, "\n") != 0) { -+ free(fpath); -+ free(current); -+ return true; -+ } -+ -+ free(fpath); -+ free(current); - - lastslash = strrchr(path, '/'); - if (!lastslash) { -@@ -560,8 +594,6 @@ on_error: - static bool build_sub_cpuset_cgroup_dir(char *cgpath) - { - int ret; -- char v; -- char *clonechildrenpath = NULL; - - ret = mkdir_p(cgpath, 0755); - if (ret < 0) { -@@ -571,51 +603,19 @@ static bool build_sub_cpuset_cgroup_dir(char *cgpath) - } - } - -- clonechildrenpath = must_make_path(cgpath, "cgroup.clone_children", NULL); -- /* unified hierarchy doesn't have clone_children */ -- if (!file_exists(clonechildrenpath)) { -- free(clonechildrenpath); -- return true; -- } -- -- ret = lxc_read_from_file(clonechildrenpath, &v, 1); -- if (ret < 0) { -- SYSERROR("Failed to read file \"%s\"", clonechildrenpath); -- free(clonechildrenpath); -- return false; -- } -- - /* Make sure any isolated cpus are removed from cpuset.cpus. */ -- if (!cg_legacy_filter_and_set_cpus(cgpath, v == '1')) { -+ if (!cg_legacy_filter_and_set_cpus(cgpath, false)) { - SYSERROR("Failed to remove isolated cpus"); -- free(clonechildrenpath); - return false; - } - -- /* Already set for us by someone else. */ -- if (v == '1') { -- DEBUG("\"cgroup.clone_children\" was already set to \"1\""); -- free(clonechildrenpath); -- return true; -- } -- - /* copy parent's settings */ - if (!copy_parent_file(cgpath, "cpuset.mems")) { - SYSERROR("Failed to copy \"cpuset.mems\" settings"); -- free(clonechildrenpath); - return false; - } - -- ret = lxc_write_to_file(clonechildrenpath, "1", 1, false, 0666); -- if (ret < 0) { -- /* Set clone_children so children inherit our settings */ -- SYSERROR("Failed to write 1 to \"%s\"", clonechildrenpath); -- free(clonechildrenpath); -- return false; -- } -- free(clonechildrenpath); - return true; -- - } - - /* Initialize the cpuset hierarchy in first directory of @gname and set -@@ -647,13 +647,13 @@ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname) - } - slash = strchr(slash + 1, '/'); - } -- } else { -- cgpath = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL); -- sub_mk_success = build_sub_cpuset_cgroup_dir(cgpath); -- free(cgpath); -- if (!sub_mk_success) { -- return false; -- } -+ } -+ -+ cgpath = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL); -+ sub_mk_success = build_sub_cpuset_cgroup_dir(cgpath); -+ free(cgpath); -+ if (!sub_mk_success) { -+ return false; - } - - return true; --- -1.8.3.1 - diff --git a/0134-lxc-do-cpuset-same-as-runc.patch b/0134-lxc-do-cpuset-same-as-runc.patch deleted file mode 100644 index f68e92373f2c8f8a2805572a8da1ec368ee27a77..0000000000000000000000000000000000000000 --- a/0134-lxc-do-cpuset-same-as-runc.patch +++ /dev/null @@ -1,319 +0,0 @@ -From 646b70518ca8f512372996888f3c8b47577b59d5 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Wed, 18 Dec 2019 22:37:08 -0500 -Subject: [PATCH 134/140] lxc: do cpuset same as runc - -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgfsng.c | 288 +---------------------------------------------- - 1 file changed, 3 insertions(+), 285 deletions(-) - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index 5908c31..79fc5d3 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -248,288 +248,6 @@ static char *read_file(const char *fnam) - return buf; - } - --/* Taken over modified from the kernel sources. */ --#define NBITS 32 /* bits in uint32_t */ --#define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d)) --#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, NBITS) -- --static void set_bit(unsigned bit, uint32_t *bitarr) --{ -- bitarr[bit / NBITS] |= (1 << (bit % NBITS)); --} -- --static void clear_bit(unsigned bit, uint32_t *bitarr) --{ -- bitarr[bit / NBITS] &= ~(1 << (bit % NBITS)); --} -- --static bool is_set(unsigned bit, uint32_t *bitarr) --{ -- return (bitarr[bit / NBITS] & (1 << (bit % NBITS))) != 0; --} -- --/* Create cpumask from cpulist aka turn: -- * -- * 0,2-3 -- * -- * into bit array -- * -- * 1 0 1 1 -- */ --static uint32_t *lxc_cpumask(char *buf, size_t nbits) --{ -- char *token; -- size_t arrlen; -- uint32_t *bitarr; -- -- arrlen = BITS_TO_LONGS(nbits); -- bitarr = calloc(arrlen, sizeof(uint32_t)); -- if (!bitarr) -- return NULL; -- -- lxc_iterate_parts(token, buf, ",") { -- errno = 0; -- unsigned end, start; -- char *range; -- -- start = strtoul(token, NULL, 0); -- end = start; -- range = strchr(token, '-'); -- if (range) -- end = strtoul(range + 1, NULL, 0); -- -- if (!(start <= end)) { -- free(bitarr); -- return NULL; -- } -- -- if (end >= nbits) { -- free(bitarr); -- return NULL; -- } -- -- while (start <= end) -- set_bit(start++, bitarr); -- } -- -- return bitarr; --} -- --/* Turn cpumask into simple, comma-separated cpulist. */ --static char *lxc_cpumask_to_cpulist(uint32_t *bitarr, size_t nbits) --{ -- int ret; -- size_t i; -- char **cpulist = NULL; -- char numstr[INTTYPE_TO_STRLEN(size_t)] = {0}; -- -- for (i = 0; i <= nbits; i++) { -- if (!is_set(i, bitarr)) -- continue; -- -- ret = snprintf(numstr, sizeof(numstr), "%zu", i); -- if (ret < 0 || (size_t)ret >= sizeof(numstr)) { -- lxc_free_array((void **)cpulist, free); -- return NULL; -- } -- -- ret = lxc_append_string(&cpulist, numstr); -- if (ret < 0) { -- lxc_free_array((void **)cpulist, free); -- return NULL; -- } -- } -- -- if (!cpulist) -- return NULL; -- -- return lxc_string_join(",", (const char **)cpulist, false); --} -- --static ssize_t get_max_cpus(char *cpulist) --{ -- char *c1, *c2; -- char *maxcpus = cpulist; -- size_t cpus = 0; -- -- c1 = strrchr(maxcpus, ','); -- if (c1) -- c1++; -- -- c2 = strrchr(maxcpus, '-'); -- if (c2) -- c2++; -- -- if (!c1 && !c2) -- c1 = maxcpus; -- else if (c1 > c2) -- c2 = c1; -- else if (c1 < c2) -- c1 = c2; -- else if (!c1 && c2) -- c1 = c2; -- -- errno = 0; -- cpus = strtoul(c1, NULL, 0); -- if (errno != 0) -- return -1; -- -- return cpus; --} -- --#define __ISOL_CPUS "/sys/devices/system/cpu/isolated" --static bool cg_legacy_filter_and_set_cpus(char *path, bool am_initialized) --{ -- int ret; -- ssize_t i; -- char *lastslash, *fpath, oldv; -- ssize_t maxisol = 0, maxposs = 0; -- char *cpulist = NULL, *isolcpus = NULL, *posscpus = NULL; -- uint32_t *isolmask = NULL, *possmask = NULL; -- bool bret = false, flipped_bit = false; -- bool need_read_parent = false; -- -- fpath = must_make_path(path, "cpuset.cpus", NULL); -- posscpus = read_file(fpath); -- if (!posscpus) { -- SYSERROR("Failed to read file \"%s\"", fpath); -- goto on_error; -- } -- -- if (strcmp(posscpus, "\n") == 0) { -- need_read_parent = true; -- free(fpath); -- free(posscpus); -- lastslash = strrchr(path, '/'); -- if (!lastslash) { -- ERROR("Failed to detect \"/\" in \"%s\"", path); -- return bret; -- } -- oldv = *lastslash; -- *lastslash = '\0'; -- fpath = must_make_path(path, "cpuset.cpus", NULL); -- posscpus = read_file(fpath); -- if (!posscpus) { -- SYSERROR("Failed to read file \"%s\"", fpath); -- goto on_error; -- } -- } -- -- /* Get maximum number of cpus found in possible cpuset. */ -- maxposs = get_max_cpus(posscpus); -- if (maxposs < 0 || maxposs >= INT_MAX - 1) -- goto on_error; -- -- if (!file_exists(__ISOL_CPUS)) { -- /* This system doesn't expose isolated cpus. */ -- DEBUG("The path \""__ISOL_CPUS"\" to read isolated cpus from does not exist"); -- cpulist = posscpus; -- /* No isolated cpus but we weren't already initialized by -- * someone. We should simply copy the parents cpuset.cpus -- * values. -- */ -- if (!am_initialized) { -- DEBUG("Copying cpu settings of parent cgroup"); -- goto copy_parent; -- } -- /* No isolated cpus but we were already initialized by someone. -- * Nothing more to do for us. -- */ -- goto on_success; -- } -- -- isolcpus = read_file(__ISOL_CPUS); -- if (!isolcpus) { -- SYSERROR("Failed to read file \""__ISOL_CPUS"\""); -- goto on_error; -- } -- if (!isdigit(isolcpus[0])) { -- TRACE("No isolated cpus detected"); -- cpulist = posscpus; -- /* No isolated cpus but we weren't already initialized by -- * someone. We should simply copy the parents cpuset.cpus -- * values. -- */ -- if (!am_initialized) { -- DEBUG("Copying cpu settings of parent cgroup"); -- goto copy_parent; -- } -- /* No isolated cpus but we were already initialized by someone. -- * Nothing more to do for us. -- */ -- goto on_success; -- } -- -- /* Get maximum number of cpus found in isolated cpuset. */ -- maxisol = get_max_cpus(isolcpus); -- if (maxisol < 0 || maxisol >= INT_MAX - 1) -- goto on_error; -- -- if (maxposs < maxisol) -- maxposs = maxisol; -- maxposs++; -- -- possmask = lxc_cpumask(posscpus, maxposs); -- if (!possmask) { -- ERROR("Failed to create cpumask for possible cpus"); -- goto on_error; -- } -- -- isolmask = lxc_cpumask(isolcpus, maxposs); -- if (!isolmask) { -- ERROR("Failed to create cpumask for isolated cpus"); -- goto on_error; -- } -- -- for (i = 0; i <= maxposs; i++) { -- if (!is_set(i, isolmask) || !is_set(i, possmask)) -- continue; -- -- flipped_bit = true; -- clear_bit(i, possmask); -- } -- -- if (!flipped_bit) { -- DEBUG("No isolated cpus present in cpuset"); -- goto on_success; -- } -- DEBUG("Removed isolated cpus from cpuset"); -- -- cpulist = lxc_cpumask_to_cpulist(possmask, maxposs); -- if (!cpulist) { -- ERROR("Failed to create cpu list"); -- goto on_error; -- } -- --copy_parent: -- if (need_read_parent) { -- *lastslash = oldv; -- } -- free(fpath); -- fpath = must_make_path(path, "cpuset.cpus", NULL); -- ret = lxc_write_to_file(fpath, cpulist, strlen(cpulist), false, 0666); -- if (ret < 0) { -- SYSERROR("Failed to write cpu list to \"%s\"", fpath); -- goto on_error; -- } -- --on_success: -- bret = true; -- --on_error: -- free(fpath); -- -- free(isolcpus); -- free(isolmask); -- -- if (posscpus != cpulist) -- free(posscpus); -- free(possmask); -- -- free(cpulist); -- return bret; --} -- - /* Copy contents of parent(@path)/@file to @path/@file */ - static bool copy_parent_file(char *path, char *file) - { -@@ -603,9 +321,9 @@ static bool build_sub_cpuset_cgroup_dir(char *cgpath) - } - } - -- /* Make sure any isolated cpus are removed from cpuset.cpus. */ -- if (!cg_legacy_filter_and_set_cpus(cgpath, false)) { -- SYSERROR("Failed to remove isolated cpus"); -+ /* copy parent's settings */ -+ if (!copy_parent_file(cgpath, "cpuset.cpus")) { -+ SYSERROR("Failed to copy \"cpuset.cpus\" settings"); - return false; - } - --- -1.8.3.1 - diff --git a/0135-lxc-fix-code-warnings-for-cgfsng.c.patch b/0135-lxc-fix-code-warnings-for-cgfsng.c.patch deleted file mode 100644 index 8c002264f7f00db09ba60b93d8e6d00f90b4ad75..0000000000000000000000000000000000000000 --- a/0135-lxc-fix-code-warnings-for-cgfsng.c.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 5d7175b7d6ac7340c779c0102955f2099fc7b7e9 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Mon, 23 Dec 2019 03:20:14 -0500 -Subject: [PATCH 135/140] lxc: fix code warnings for cgfsng.c - -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgfsng.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index 79fc5d3..9f0bb69 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -252,10 +252,12 @@ static char *read_file(const char *fnam) - static bool copy_parent_file(char *path, char *file) - { - int ret; -- char *fpath, *lastslash, oldv; - int len = 0; - char *value = NULL; - char *current = NULL; -+ char *fpath = NULL; -+ char *lastslash = NULL; -+ char oldv; - - fpath = must_make_path(path, file, NULL); - current = read_file(fpath); -@@ -276,13 +278,14 @@ static bool copy_parent_file(char *path, char *file) - free(current); - - lastslash = strrchr(path, '/'); -- if (!lastslash) { -+ if (lastslash == NULL) { - ERROR("Failed to detect \"/\" in \"%s\"", path); - return false; - } - oldv = *lastslash; - *lastslash = '\0'; - fpath = must_make_path(path, file, NULL); -+ *lastslash = oldv; - len = lxc_read_from_file(fpath, NULL, 0); - if (len <= 0) - goto on_error; -@@ -293,7 +296,6 @@ static bool copy_parent_file(char *path, char *file) - goto on_error; - free(fpath); - -- *lastslash = oldv; - fpath = must_make_path(path, file, NULL); - ret = lxc_write_to_file(fpath, value, len, false, 0666); - if (ret < 0) --- -1.8.3.1 - diff --git a/0136-lxc-fix-retry-bug-in-cgroup.patch b/0136-lxc-fix-retry-bug-in-cgroup.patch deleted file mode 100644 index 22c9d1cf2724b9d15e388ff42ed65dd1c37bb2ed..0000000000000000000000000000000000000000 --- a/0136-lxc-fix-retry-bug-in-cgroup.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 8f8184392cd877ae05e6f02529135b1900424812 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Sat, 28 Dec 2019 20:12:57 -0500 -Subject: [PATCH 136/140] lxc: fix retry bug in cgroup - -Signed-off-by: LiFeng ---- - src/lxc/cgroups/cgfsng.c | 34 +++++++++++++++++----------------- - 1 file changed, 17 insertions(+), 17 deletions(-) - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index 9f0bb69..ed08f10 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -1025,6 +1025,7 @@ __cgfsng_ops static bool cgfsng_payload_create(struct cgroup_ops *ops, - __cgfsng_ops static bool cgfsng_payload_enter(struct cgroup_ops *ops, pid_t pid) - { - int len; -+ char *container_cgroup = ops->container_cgroup; - char pidstr[INTTYPE_TO_STRLEN(pid_t)]; - - len = snprintf(pidstr, sizeof(pidstr), "%d", pid); -@@ -1042,14 +1043,13 @@ __cgfsng_ops static bool cgfsng_payload_enter(struct cgroup_ops *ops, pid_t pid) - retry: - ret = lxc_write_to_file(fullpath, pidstr, len, false, 0666); - if (ret != 0) { -- if (errno == ENOENT) { -- if (retry_count < max_retry) { -- SYSERROR("Failed to enter cgroup \"%s\" with retry count:%d", fullpath, retry_count); -- (void)mkdir_eexist_on_last(ops->hierarchies[i]->container_full_path, 0755); -- usleep(100 * 1000); /* 100 millisecond */ -- retry_count++; -- goto retry; -- } -+ if (retry_count < max_retry) { -+ SYSERROR("Failed to enter cgroup \"%s\" with retry count:%d", fullpath, retry_count); -+ (void)cg_legacy_handle_cpuset_hierarchy(ops->hierarchies[i], container_cgroup); -+ (void)mkdir_eexist_on_last(ops->hierarchies[i]->container_full_path, 0755); -+ usleep(100 * 1000); /* 100 millisecond */ -+ retry_count++; -+ goto retry; - } - SYSERROR("Failed to enter cgroup \"%s\"", fullpath); - free(fullpath); -@@ -1949,6 +1949,7 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, - char *controller = NULL; - int retry_count = 0; - int max_retry = 10; -+ char *container_cgroup = ops->container_cgroup; - - len = strlen(filename); - controller = alloca(len + 1); -@@ -1979,15 +1980,14 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, - - retry: - ret = lxc_write_to_file(fullpath, value, strlen(value), false, 0666); -- if (ret) { -- if (errno == ENOENT) { -- if (retry_count < max_retry) { -- SYSERROR("setting cgroup config for ready process caused \"failed to write %s to %s\".", value, fullpath); -- (void)mkdir_eexist_on_last(h->container_full_path, 0755); -- usleep(100 * 1000); /* 100 millisecond */ -- retry_count++; -- goto retry; -- } -+ if (ret != 0) { -+ if (retry_count < max_retry) { -+ SYSERROR("setting cgroup config for ready process caused \"failed to write %s to %s\".", value, fullpath); -+ (void)cg_legacy_handle_cpuset_hierarchy(h, container_cgroup); -+ (void)mkdir_eexist_on_last(h->container_full_path, 0755); -+ usleep(100 * 1000); /* 100 millisecond */ -+ retry_count++; -+ goto retry; - } - lxc_write_error_message(ops->errfd, - "%s:%d: setting cgroup config for ready process caused \"failed to write %s to %s: %s\".", --- -1.8.3.1 - diff --git a/0137-lxc-fix-bug-in-read-proc.patch b/0137-lxc-fix-bug-in-read-proc.patch deleted file mode 100644 index 5f23daf9b2cb5152d72963914d5fdc6fdda4b929..0000000000000000000000000000000000000000 --- a/0137-lxc-fix-bug-in-read-proc.patch +++ /dev/null @@ -1,43 +0,0 @@ -From e80ccf614ff53e8fa6afe894bd167873b410adc4 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Mon, 30 Dec 2019 04:50:28 -0500 -Subject: [PATCH 137/140] lxc: fix bug in read proc - -Signed-off-by: LiFeng ---- - src/lxc/start.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/src/lxc/start.c b/src/lxc/start.c -index 63be4e3..c9bae65 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -998,7 +998,7 @@ static int _recursive_read_cgroup_procs(const char *dirpath, pid_t **pids, size_ - char pathname[PATH_MAX]; - - dir = opendir(dirpath); -- if (!dir && errno != ENOENT) { -+ if (dir == NULL) { - WARN("Failed to open \"%s\"", dirpath); - return 0; - } -@@ -1049,15 +1049,13 @@ static int _recursive_read_cgroup_procs(const char *dirpath, pid_t **pids, size_ - int get_all_pids(struct cgroup_ops *cg_ops, pid_t **pids, size_t *len) - { - const char *devices_path = NULL; -- int ret; - - devices_path = cg_ops->get_cgroup(cg_ops, "devices", false); - if (!file_exists(devices_path)) { - return 0; - } - -- ret = _recursive_read_cgroup_procs(devices_path, pids, len); -- return ret; -+ return _recursive_read_cgroup_procs(devices_path, pids, len); - } - - static int set_cgroup_freezer(struct cgroup_ops *cg_ops, const char *value) --- -1.8.3.1 - diff --git a/0139-lxc-fix-get-cgroup-path-by-config-instead-of-cmd.patch b/0139-lxc-fix-get-cgroup-path-by-config-instead-of-cmd.patch deleted file mode 100644 index f90d66ed9b8a24206d1a7f0ec97ad206cb10197d..0000000000000000000000000000000000000000 --- a/0139-lxc-fix-get-cgroup-path-by-config-instead-of-cmd.patch +++ /dev/null @@ -1,318 +0,0 @@ -From ee58496252e6b6874cbd09191fc8bec5216c95be Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Wed, 15 Jan 2020 03:55:27 -0500 -Subject: [PATCH 139/140] lxc: fix get cgroup path by config instead of cmd - -Signed-off-by: LiFeng ---- - src/lxc/attach.c | 2 +- - src/lxc/cgroups/cgfsng.c | 26 +++++++++++++------------- - src/lxc/cgroups/cgroup.c | 6 +++--- - src/lxc/cgroups/cgroup.h | 4 ++-- - src/lxc/criu.c | 4 ++-- - src/lxc/freezer.c | 12 ++++++------ - src/lxc/lxc.h | 4 ++-- - src/lxc/lxccontainer.c | 8 ++++---- - src/lxc/start.c | 6 +++--- - src/tests/cgpath.c | 2 +- - 10 files changed, 37 insertions(+), 37 deletions(-) - -diff --git a/src/lxc/attach.c b/src/lxc/attach.c -index 03a7646..2061b96 100644 ---- a/src/lxc/attach.c -+++ b/src/lxc/attach.c -@@ -1477,7 +1477,7 @@ int lxc_attach(const char *name, const char *lxcpath, const char *suffix, - if (options->attach_flags & LXC_ATTACH_MOVE_TO_CGROUP) { - struct cgroup_ops *cgroup_ops; - -- cgroup_ops = cgroup_init(NULL); -+ cgroup_ops = cgroup_init(conf); - if (!cgroup_ops) - goto on_error; - -diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c -index ed08f10..ae15449 100644 ---- a/src/lxc/cgroups/cgfsng.c -+++ b/src/lxc/cgroups/cgfsng.c -@@ -1799,10 +1799,12 @@ __cgfsng_ops static int cgfsng_get(struct cgroup_ops *ops, const char *filename, - if (p) - *p = '\0'; - -- path = lxc_cmd_get_cgroup_path(name, lxcpath, controller); -- /* not running */ -- if (!path) -+ const char *ori_path = ops->get_cgroup(ops, controller, true); -+ if (ori_path == NULL) { -+ ERROR("Failed to get cgroup path:%s", controller); - return -1; -+ } -+ path = safe_strdup(ori_path); - - h = get_hierarchy(ops, controller); - if (h) { -@@ -1838,10 +1840,12 @@ __cgfsng_ops static int cgfsng_set(struct cgroup_ops *ops, - if (p) - *p = '\0'; - -- path = lxc_cmd_get_cgroup_path(name, lxcpath, controller); -- /* not running */ -- if (!path) -+ const char *ori_path = ops->get_cgroup(ops, controller, true); -+ if (ori_path == NULL) { -+ ERROR("Failed to get cgroup path:%s", controller); - return -1; -+ } -+ path = safe_strdup(ori_path); - - h = get_hierarchy(ops, controller); - if (h) { -@@ -2484,17 +2488,13 @@ static bool cg_init(struct cgroup_ops *ops) - return cg_hybrid_init(ops); - } - --__cgfsng_ops static bool cgfsng_data_init(struct cgroup_ops *ops, struct lxc_handler *handler) -+__cgfsng_ops static bool cgfsng_data_init(struct cgroup_ops *ops, struct lxc_conf *conf) - { - const char *cgroup_pattern = NULL; - char *container_cgroup = NULL; - char *tmp = NULL; -- struct lxc_conf *conf = NULL; - size_t len; - -- if (handler) -- conf = handler->conf; -- - /* copy system-wide cgroup information */ - cgroup_pattern = lxc_global_config_value("lxc.cgroup.pattern"); - if (!cgroup_pattern) { -@@ -2508,10 +2508,10 @@ __cgfsng_ops static bool cgfsng_data_init(struct cgroup_ops *ops, struct lxc_han - if (conf) { - if (conf->cgroup_meta.dir) - tmp = lxc_string_join("/", (const char *[]) { -- conf->cgroup_meta.dir, handler->name, NULL -+ conf->cgroup_meta.dir, conf->name, NULL - }, false); - else -- tmp = lxc_string_replace("%n", handler->name, ops->cgroup_pattern); -+ tmp = lxc_string_replace("%n", conf->name, ops->cgroup_pattern); - if (!tmp) { - ERROR("Failed expanding cgroup name pattern"); - return false; -diff --git a/src/lxc/cgroups/cgroup.c b/src/lxc/cgroups/cgroup.c -index 8d559be..bca00d5 100644 ---- a/src/lxc/cgroups/cgroup.c -+++ b/src/lxc/cgroups/cgroup.c -@@ -40,17 +40,17 @@ lxc_log_define(cgroup, lxc); - - extern struct cgroup_ops *cgfsng_ops_init(int errfd); - --struct cgroup_ops *cgroup_init(struct lxc_handler *handler) -+struct cgroup_ops *cgroup_init(struct lxc_conf *conf) - { - struct cgroup_ops *cgroup_ops; - -- cgroup_ops = cgfsng_ops_init(handler ? handler->conf->errpipe[1] : -1); -+ cgroup_ops = cgfsng_ops_init(conf ? conf->errpipe[1] : -1); - if (!cgroup_ops) { - ERROR("Failed to initialize cgroup driver"); - return NULL; - } - -- if (!cgroup_ops->data_init(cgroup_ops, handler)) -+ if (!cgroup_ops->data_init(cgroup_ops, conf)) - return NULL; - - TRACE("Initialized cgroup driver %s", cgroup_ops->driver); -diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h -index edbb1e3..935b4d3 100644 ---- a/src/lxc/cgroups/cgroup.h -+++ b/src/lxc/cgroups/cgroup.h -@@ -125,7 +125,7 @@ struct cgroup_ops { - */ - cgroup_layout_t cgroup_layout; - -- bool (*data_init)(struct cgroup_ops *ops, struct lxc_handler *handler); -+ bool (*data_init)(struct cgroup_ops *ops, struct lxc_conf *conf); - bool (*destroy)(struct cgroup_ops *ops, struct lxc_handler *handler); - bool (*payload_create)(struct cgroup_ops *ops, struct lxc_handler *handler); - bool (*payload_enter)(struct cgroup_ops *ops, pid_t pid); -@@ -148,7 +148,7 @@ struct cgroup_ops { - int (*nrtasks)(struct cgroup_ops *ops); - }; - --extern struct cgroup_ops *cgroup_init(struct lxc_handler *handler); -+extern struct cgroup_ops *cgroup_init(struct lxc_conf *conf); - extern void cgroup_exit(struct cgroup_ops *ops); - - extern void prune_init_scope(char *cg); -diff --git a/src/lxc/criu.c b/src/lxc/criu.c -index 5c77979..700a3e4 100644 ---- a/src/lxc/criu.c -+++ b/src/lxc/criu.c -@@ -970,7 +970,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_ - if (lxc_init(c->name, handler) < 0) - goto out; - -- cgroup_ops = cgroup_init(NULL); -+ cgroup_ops = cgroup_init(c->lxc_conf); - if (!cgroup_ops) - goto out_fini_handler; - handler->cgroup_ops = cgroup_ops; -@@ -1270,7 +1270,7 @@ static bool do_dump(struct lxc_container *c, char *mode, struct migrate_opts *op - - close(criuout[0]); - -- cgroup_ops = cgroup_init(NULL); -+ cgroup_ops = cgroup_init(c->lxc_conf); - if (!cgroup_ops) { - ERROR("failed to cgroup_init()"); - _exit(EXIT_FAILURE); -diff --git a/src/lxc/freezer.c b/src/lxc/freezer.c -index fc3622a..d5fad75 100644 ---- a/src/lxc/freezer.c -+++ b/src/lxc/freezer.c -@@ -45,7 +45,7 @@ - - lxc_log_define(freezer, lxc); - --static int do_freeze_thaw(bool freeze, const char *name, const char *lxcpath) -+static int do_freeze_thaw(bool freeze, struct lxc_conf *conf, const char *name, const char *lxcpath) - { - int ret; - char v[100]; -@@ -54,7 +54,7 @@ static int do_freeze_thaw(bool freeze, const char *name, const char *lxcpath) - size_t state_len = 6; - lxc_state_t new_state = freeze ? FROZEN : THAWED; - -- cgroup_ops = cgroup_init(NULL); -+ cgroup_ops = cgroup_init(conf); - if (!cgroup_ops) - return -1; - -@@ -88,14 +88,14 @@ static int do_freeze_thaw(bool freeze, const char *name, const char *lxcpath) - } - } - --int lxc_freeze(const char *name, const char *lxcpath) -+int lxc_freeze(struct lxc_conf *conf, const char *name, const char *lxcpath) - { - lxc_cmd_serve_state_clients(name, lxcpath, FREEZING); - lxc_monitor_send_state(name, FREEZING, lxcpath); -- return do_freeze_thaw(true, name, lxcpath); -+ return do_freeze_thaw(true, conf, name, lxcpath); - } - --int lxc_unfreeze(const char *name, const char *lxcpath) -+int lxc_unfreeze(struct lxc_conf *conf, const char *name, const char *lxcpath) - { -- return do_freeze_thaw(false, name, lxcpath); -+ return do_freeze_thaw(false, conf, name, lxcpath); - } -diff --git a/src/lxc/lxc.h b/src/lxc/lxc.h -index 5df5080..bd0d373 100644 ---- a/src/lxc/lxc.h -+++ b/src/lxc/lxc.h -@@ -82,14 +82,14 @@ extern int lxc_monitor_close(int fd); - * @name : the container name - * Returns 0 on success, < 0 otherwise - */ --extern int lxc_freeze(const char *name, const char *lxcpath); -+extern int lxc_freeze(struct lxc_conf *conf, const char *name, const char *lxcpath); - - /* - * Unfreeze all previously frozen tasks. - * @name : the name of the container - * Return 0 on success, < 0 otherwise - */ --extern int lxc_unfreeze(const char *name, const char *lxcpath); -+extern int lxc_unfreeze(struct lxc_conf *conf, const char *name, const char *lxcpath); - - /* - * Retrieve the container state -diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index 7ef57f0..e5a82f3 100644 ---- a/src/lxc/lxccontainer.c -+++ b/src/lxc/lxccontainer.c -@@ -516,7 +516,7 @@ static bool do_lxcapi_freeze(struct lxc_container *c) - if (!c) - return false; - -- ret = lxc_freeze(c->name, c->config_path); -+ ret = lxc_freeze(c->lxc_conf, c->name, c->config_path); - if (ret < 0) - return false; - -@@ -532,7 +532,7 @@ static bool do_lxcapi_unfreeze(struct lxc_container *c) - if (!c) - return false; - -- ret = lxc_unfreeze(c->name, c->config_path); -+ ret = lxc_unfreeze(c->lxc_conf, c->name, c->config_path); - if (ret < 0) - return false; - -@@ -3455,7 +3455,7 @@ static bool do_lxcapi_set_cgroup_item(struct lxc_container *c, const char *subsy - if (is_stopped(c)) - return false; - -- cgroup_ops = cgroup_init(NULL); -+ cgroup_ops = cgroup_init(c->lxc_conf); - if (!cgroup_ops) - return false; - -@@ -3479,7 +3479,7 @@ static int do_lxcapi_get_cgroup_item(struct lxc_container *c, const char *subsys - if (is_stopped(c)) - return -1; - -- cgroup_ops = cgroup_init(NULL); -+ cgroup_ops = cgroup_init(c->lxc_conf); - if (!cgroup_ops) - return -1; - -diff --git a/src/lxc/start.c b/src/lxc/start.c -index c9bae65..0af2e92 100644 ---- a/src/lxc/start.c -+++ b/src/lxc/start.c -@@ -919,7 +919,7 @@ int lxc_init(const char *name, struct lxc_handler *handler) - } - TRACE("Chowned console"); - -- handler->cgroup_ops = cgroup_init(handler); -+ handler->cgroup_ops = cgroup_init(conf); - if (!handler->cgroup_ops) { - ERROR("Failed to initialize cgroup driver"); - goto out_delete_terminal; -@@ -2680,7 +2680,7 @@ static struct lxc_handler *lxc_init_clean_handler(char *name, char *lxcpath, str - handler->name = name; - handler->exit_code = -1; /* isulad: record exit code of container */ - -- handler->cgroup_ops = cgroup_init(handler); -+ handler->cgroup_ops = cgroup_init(conf); - if (!handler->cgroup_ops) { - ERROR("Failed to initialize cgroup driver"); - goto on_error; -@@ -2729,7 +2729,7 @@ static struct lxc_handler *lxc_init_pids_handler(char *name, char *lxcpath, stru - handler->name = name; - handler->exit_code = -1; /* isulad: record exit code of container */ - -- handler->cgroup_ops = cgroup_init(handler); -+ handler->cgroup_ops = cgroup_init(conf); - if (!handler->cgroup_ops) { - ERROR("Failed to initialize cgroup driver"); - goto on_error; -diff --git a/src/tests/cgpath.c b/src/tests/cgpath.c -index fa8d476..8f4c19f 100644 ---- a/src/tests/cgpath.c -+++ b/src/tests/cgpath.c -@@ -80,7 +80,7 @@ static int test_running_container(const char *lxcpath, - goto err3; - } - -- cgroup_ops = cgroup_init(NULL); -+ cgroup_ops = cgroup_init(c->lxc_conf); - if (!cgroup_ops) - goto err3; - --- -1.8.3.1 - diff --git a/0140-lxc-remove-umask-when-populate-devices.patch b/0140-lxc-remove-umask-when-populate-devices.patch deleted file mode 100644 index 6d3efdc43de5519e1bfd32131f9f494b6ae58f5a..0000000000000000000000000000000000000000 --- a/0140-lxc-remove-umask-when-populate-devices.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 22613294ae751f47409cfac03a7fd28cf9222031 Mon Sep 17 00:00:00 2001 -From: LiFeng -Date: Fri, 28 Feb 2020 22:59:05 -0500 -Subject: [PATCH 140/140] lxc: remove umask when populate devices - -Signed-off-by: LiFeng ---- - src/lxc/conf.c | 38 ++++++++++++++++++++++++++------------ - 1 file changed, 26 insertions(+), 12 deletions(-) - -diff --git a/src/lxc/conf.c b/src/lxc/conf.c -index b66e7bc..65b33ea 100644 ---- a/src/lxc/conf.c -+++ b/src/lxc/conf.c -@@ -4008,23 +4008,28 @@ static int setup_populate_devs(const struct lxc_rootfs *rootfs, struct lxc_list - mode_t file_mode = 0; - struct lxc_populate_devs *dev_elem = NULL; - struct lxc_list *it = NULL; -+ mode_t cur_mask; - - INFO("Populating devices into container"); -+ cur_mask = umask(0000); - lxc_list_for_each(it, devs) { - dev_elem = it->elem; - - ret = snprintf(path, MAXPATHLEN, "%s/%s", rootfs->path ? rootfs->mount : "", dev_elem->name); -- if (ret < 0 || ret >= MAXPATHLEN) -- return -1; -+ if (ret < 0 || ret >= MAXPATHLEN) { -+ ret = -1; -+ goto reset_umask; -+ } - - /* create any missing directories */ - pathdirname = safe_strdup(path); - pathdirname = dirname(pathdirname); -- ret = mkdir_p(pathdirname, 0750); -+ ret = mkdir_p(pathdirname, 0755); - free(pathdirname); - if (ret < 0) { - WARN("Failed to create target directory"); -- return -1; -+ ret = -1; -+ goto reset_umask; - } - - if (!strcmp(dev_elem->type, "c")) { -@@ -4033,7 +4038,8 @@ static int setup_populate_devs(const struct lxc_rootfs *rootfs, struct lxc_list - file_mode = dev_elem->file_mode | S_IFBLK; - } else { - ERROR("Failed to parse devices type '%s'", dev_elem->type); -- return -1; -+ ret = -1; -+ goto reset_umask; - } - - DEBUG("Try to mknod '%s':'%d':'%d':'%d'\n", path, -@@ -4045,34 +4051,42 @@ static int setup_populate_devs(const struct lxc_rootfs *rootfs, struct lxc_list - file_mode, dev_elem->maj, dev_elem->min); - - char hostpath[MAXPATHLEN]; -- FILE *pathfile; -+ FILE *pathfile = NULL; - - // Unprivileged containers cannot create devices, so - // try to bind mount the device from the host - ret = snprintf(hostpath, MAXPATHLEN, "/dev/%s", dev_elem->name); -- if (ret < 0 || ret >= MAXPATHLEN) -- return -1; -+ if (ret < 0 || ret >= MAXPATHLEN) { -+ ret = -1; -+ goto reset_umask; -+ } - pathfile = lxc_fopen(path, "wb"); - if (!pathfile) { - SYSERROR("Failed to create device mount target '%s'", path); -- return -1; -+ ret = -1; -+ goto reset_umask; - } - fclose(pathfile); - if (safe_mount(hostpath, path, 0, MS_BIND, NULL, - rootfs->path ? rootfs->mount : NULL) != 0) { - SYSERROR("Failed bind mounting device %s from host into container", - dev_elem->name); -- return -1; -+ ret = -1; -+ goto reset_umask; - } - } - if (chown(path, dev_elem->uid, dev_elem->gid) < 0) { - ERROR("Error chowning %s", path); -- return -1; -+ ret = -1; -+ goto reset_umask; - } - } - -+reset_umask: -+ (void)umask(cur_mask); -+ - INFO("Populated devices into container /dev"); -- return 0; -+ return ret; - } - - // isulad: setup rootfs mountopts --- -1.8.3.1 - diff --git a/apply-patches b/apply-patches index 074071d13a21d8dd01c34509210febe579d05b4e..bae161f8f51aa7c7e890bfd62c789c094ccc26b8 100755 --- a/apply-patches +++ b/apply-patches @@ -16,9 +16,9 @@ set -ex -pkg=lxc-3.0.3 +pkg=lxc-4.0.1 cwd=$PWD -src=$cwd/lxc-3.0.3 +src=$cwd/lxc-4.0.1 tar -xzvf $pkg.tar.gz diff --git a/lxc-3.0.3.tar.gz b/lxc-3.0.3.tar.gz deleted file mode 100644 index 46ba17b1315fe4ca36638e8246030bb858396114..0000000000000000000000000000000000000000 Binary files a/lxc-3.0.3.tar.gz and /dev/null differ diff --git a/lxc-4.0.1.tar.gz b/lxc-4.0.1.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..e8b8d4ddd06a9b512cbc4c47ecd7599c6e58571f Binary files /dev/null and b/lxc-4.0.1.tar.gz differ diff --git a/lxc-CVE-2019-5736-runC-rexec-callers-as-memfd.patch b/lxc-CVE-2019-5736-runC-rexec-callers-as-memfd.patch deleted file mode 100644 index 833386e15cccd4e43f85743c7e4a82945954e5bc..0000000000000000000000000000000000000000 --- a/lxc-CVE-2019-5736-runC-rexec-callers-as-memfd.patch +++ /dev/null @@ -1,401 +0,0 @@ -From 113a0557d7651385d30e181a23c8e68e696ad67f Mon Sep 17 00:00:00 2001 -From: Christian Brauner -Date: Sat, 26 Jan 2019 01:19:29 +0100 -Subject: [PATCH] CVE-2019-5736 (runC): rexec callers as memfd -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Adam Iwaniuk and Borys Popławski discovered that an attacker can compromise the -runC host binary from inside a privileged runC container. As a result, this -could be exploited to gain root access on the host. runC is used as the default -runtime for containers with Docker, containerd, Podman, and CRI-O. - -The attack can be made when attaching to a running container or when starting a -container running a specially crafted image. For example, when runC attaches -to a container the attacker can trick it into executing itself. This could be -done by replacing the target binary inside the container with a custom binary -pointing back at the runC binary itself. As an example, if the target binary -was /bin/bash, this could be replaced with an executable script specifying the -interpreter path #!/proc/self/exe (/proc/self/exec is a symbolic link created -by the kernel for every process which points to the binary that was executed -for that process). As such when /bin/bash is executed inside the container, -instead the target of /proc/self/exe will be executed - which will point to the -runc binary on the host. The attacker can then proceed to write to the target -of /proc/self/exe to try and overwrite the runC binary on the host. However in -general, this will not succeed as the kernel will not permit it to be -overwritten whilst runC is executing. To overcome this, the attacker can -instead open a file descriptor to /proc/self/exe using the O_PATH flag and then -proceed to reopen the binary as O_WRONLY through /proc/self/fd/ and try to -write to it in a busy loop from a separate process. Ultimately it will succeed -when the runC binary exits. After this the runC binary is compromised and can -be used to attack other containers or the host itself. - -This attack is only possible with privileged containers since it requires root -privilege on the host to overwrite the runC binary. Unprivileged containers -with a non-identity ID mapping do not have the permission to write to the host -binary and therefore are unaffected by this attack. - -LXC is also impacted in a similar manner by this vulnerability, however as the -LXC project considers privileged containers to be unsafe no CVE has been -assigned for this issue for LXC. Quoting from the -https://linuxcontainers.org/lxc/security/ project's Security information page: - -"As privileged containers are considered unsafe, we typically will not consider -new container escape exploits to be security issues worthy of a CVE and quick -fix. We will however try to mitigate those issues so that accidental damage to -the host is prevented." - -To prevent this attack, LXC has been patched to create a temporary copy of the -calling binary itself when it starts or attaches to containers. To do this LXC -creates an anonymous, in-memory file using the memfd_create() system call and -copies itself into the temporary in-memory file, which is then sealed to -prevent further modifications. LXC then executes this sealed, in-memory file -instead of the original on-disk binary. Any compromising write operations from -a privileged container to the host LXC binary will then write to the temporary -in-memory binary and not to the host binary on-disk, preserving the integrity -of the host LXC binary. Also as the temporary, in-memory LXC binary is sealed, -writes to this will also fail. - -Note: memfd_create() was added to the Linux kernel in the 3.17 release. - -Signed-off-by: Christian Brauner -Co-Developed-by: Aleksa Sarai -Acked-by: Serge Hallyn ---- - configure.ac | 12 +++ - src/lxc/Makefile.am | 4 + - src/lxc/file_utils.c | 41 +++++++++- - src/lxc/file_utils.h | 1 + - src/lxc/rexec.c | 181 +++++++++++++++++++++++++++++++++++++++++++++ - src/lxc/syscall_wrappers.h | 14 ++++ - 6 files changed, 252 insertions(+), 1 deletion(-) - create mode 100644 src/lxc/rexec.c - -diff --git a/configure.ac b/configure.ac -index 950c8dd..631e607 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -706,6 +706,17 @@ AC_ARG_ENABLE([thread-safety], - [], [enable_thread_safety=yes]) - AM_CONDITIONAL([ENFORCE_THREAD_SAFETY], [test "x$enable_thread_safety" = "xyes"]) - -+AC_ARG_ENABLE([memfd-rexec], -+ [AC_HELP_STRING([--enable-memfd-rexec], [enforce liblxc as a memfd to protect against certain symlink attacks [default=yes]])], -+ [], [enable_memfd_rexec=yes]) -+AM_CONDITIONAL([ENFORCE_MEMFD_REXEC], [test "x$enable_memfd_rexec" = "xyes"]) -+if test "x$enable_memfd_rexec" = "xyes"; then -+ AC_DEFINE([ENFORCE_MEMFD_REXEC], 1, [Rexec liblxc as memfd]) -+ AC_MSG_RESULT([yes]) -+else -+ AC_MSG_RESULT([no]) -+fi -+ - # Files requiring some variable expansion - AC_CONFIG_FILES([ - Makefile -@@ -934,6 +945,7 @@ Security features: - - Linux capabilities: $enable_capabilities - - seccomp: $enable_seccomp - - SELinux: $enable_selinux -+ - memfd rexec: $enable_memfd_rexec - - PAM: - - PAM module: $enable_pam -diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am -index 08e2fab..8bbfdaf 100644 ---- a/src/lxc/Makefile.am -+++ b/src/lxc/Makefile.am -@@ -173,6 +173,10 @@ if !HAVE_STRLCAT - liblxc_la_SOURCES += ../include/strlcat.c ../include/strlcat.h - endif - -+if ENFORCE_MEMFD_REXEC -+liblxc_la_SOURCES += rexec.c -+endif -+ - AM_CFLAGS = -DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \ - -DLXCPATH=\"$(LXCPATH)\" \ - -DLXC_GLOBAL_CONF=\"$(LXC_GLOBAL_CONF)\" \ -diff --git a/src/lxc/file_utils.c b/src/lxc/file_utils.c -index f89aa63..930fd73 100644 ---- a/src/lxc/file_utils.c -+++ b/src/lxc/file_utils.c -@@ -31,7 +31,7 @@ - #include "config.h" - #include "file_utils.h" - #include "macro.h" --#include "string.h" -+#include "string_utils.h" - - int lxc_write_to_file(const char *filename, const void *buf, size_t count, - bool add_newline, mode_t mode) -@@ -327,3 +327,42 @@ again: - - return ret; - } -+ -+char *file_to_buf(char *path, size_t *length) -+{ -+ int fd; -+ char buf[PATH_MAX]; -+ char *copy = NULL; -+ -+ if (!length) -+ return NULL; -+ -+ fd = open(path, O_RDONLY | O_CLOEXEC); -+ if (fd < 0) -+ return NULL; -+ -+ *length = 0; -+ for (;;) { -+ int n; -+ char *old = copy; -+ -+ n = lxc_read_nointr(fd, buf, sizeof(buf)); -+ if (n < 0) -+ goto on_error; -+ if (!n) -+ break; -+ -+ copy = must_realloc(old, (*length + n) * sizeof(*old)); -+ memcpy(copy + *length, buf, n); -+ *length += n; -+ } -+ -+ close(fd); -+ return copy; -+ -+on_error: -+ close(fd); -+ free(copy); -+ -+ return NULL; -+} -diff --git a/src/lxc/file_utils.h b/src/lxc/file_utils.h -index 6361557..518a61a 100644 ---- a/src/lxc/file_utils.h -+++ b/src/lxc/file_utils.h -@@ -55,5 +55,6 @@ extern bool is_fs_type(const struct statfs *fs, fs_type_magic magic_val); - extern FILE *fopen_cloexec(const char *path, const char *mode); - extern ssize_t lxc_sendfile_nointr(int out_fd, int in_fd, off_t *offset, - size_t count); -+extern char *file_to_buf(char *path, size_t *length); - - #endif /* __LXC_FILE_UTILS_H */ -diff --git a/src/lxc/rexec.c b/src/lxc/rexec.c -new file mode 100644 -index 0000000..396bd61 ---- /dev/null -+++ b/src/lxc/rexec.c -@@ -0,0 +1,181 @@ -+/* liblxcapi -+ * -+ * Copyright © 2019 Christian Brauner . -+ * Copyright © 2019 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+#include -+#include -+#include -+#include -+ -+#include "config.h" -+#include "file_utils.h" -+#include "raw_syscalls.h" -+#include "string_utils.h" -+#include "syscall_wrappers.h" -+ -+#define LXC_MEMFD_REXEC_SEALS \ -+ (F_SEAL_SEAL | F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE) -+ -+static int push_vargs(char *data, int data_length, char ***output) -+{ -+ int num = 0; -+ char *cur = data; -+ -+ if (!data || *output) -+ return -1; -+ -+ *output = must_realloc(NULL, sizeof(**output)); -+ -+ while (cur < data + data_length) { -+ num++; -+ *output = must_realloc(*output, (num + 1) * sizeof(**output)); -+ -+ (*output)[num - 1] = cur; -+ cur += strlen(cur) + 1; -+ } -+ (*output)[num] = NULL; -+ return num; -+} -+ -+static int parse_exec_params(char ***argv, char ***envp) -+{ -+ int ret; -+ char *cmdline = NULL, *env = NULL; -+ size_t cmdline_size, env_size; -+ -+ cmdline = file_to_buf("/proc/self/cmdline", &cmdline_size); -+ if (!cmdline) -+ goto on_error; -+ -+ env = file_to_buf("/proc/self/environ", &env_size); -+ if (!env) -+ goto on_error; -+ -+ ret = push_vargs(cmdline, cmdline_size, argv); -+ if (ret <= 0) -+ goto on_error; -+ -+ ret = push_vargs(env, env_size, envp); -+ if (ret <= 0) -+ goto on_error; -+ -+ return 0; -+ -+on_error: -+ free(env); -+ free(cmdline); -+ -+ return -1; -+} -+ -+static int is_memfd(void) -+{ -+ int fd, saved_errno, seals; -+ -+ fd = open("/proc/self/exe", O_RDONLY | O_CLOEXEC); -+ if (fd < 0) -+ return -ENOTRECOVERABLE; -+ -+ seals = fcntl(fd, F_GET_SEALS); -+ saved_errno = errno; -+ close(fd); -+ errno = saved_errno; -+ if (seals < 0) -+ return -EINVAL; -+ -+ return seals == LXC_MEMFD_REXEC_SEALS; -+} -+ -+static void lxc_rexec_as_memfd(char **argv, char **envp, const char *memfd_name) -+{ -+ int saved_errno; -+ ssize_t bytes_sent; -+ int fd = -1, memfd = -1; -+ -+ memfd = memfd_create(memfd_name, MFD_ALLOW_SEALING | MFD_CLOEXEC); -+ if (memfd < 0) -+ return; -+ -+ fd = open("/proc/self/exe", O_RDONLY | O_CLOEXEC); -+ if (fd < 0) -+ goto on_error; -+ -+ /* sendfile() handles up to 2GB. */ -+ bytes_sent = lxc_sendfile_nointr(memfd, fd, NULL, LXC_SENDFILE_MAX); -+ saved_errno = errno; -+ close(fd); -+ errno = saved_errno; -+ if (bytes_sent < 0) -+ goto on_error; -+ -+ if (fcntl(memfd, F_ADD_SEALS, LXC_MEMFD_REXEC_SEALS)) -+ goto on_error; -+ -+ fexecve(memfd, argv, envp); -+ -+on_error: -+ saved_errno = errno; -+ close(memfd); -+ errno = saved_errno; -+} -+ -+static int lxc_rexec(const char *memfd_name) -+{ -+ int ret; -+ char **argv = NULL, **envp = NULL; -+ -+ ret = is_memfd(); -+ if (ret < 0 && ret == -ENOTRECOVERABLE) { -+ fprintf(stderr, -+ "%s - Failed to determine whether this is a memfd\n", -+ strerror(errno)); -+ return -1; -+ } else if (ret > 0) { -+ return 0; -+ } -+ -+ ret = parse_exec_params(&argv, &envp); -+ if (ret < 0) { -+ fprintf(stderr, -+ "%s - Failed to parse command line parameters\n", -+ strerror(errno)); -+ return -1; -+ } -+ -+ lxc_rexec_as_memfd(argv, envp, memfd_name); -+ fprintf(stderr, "%s - Failed to rexec as memfd\n", strerror(errno)); -+ return -1; -+} -+ -+/** -+ * This function will copy any binary that calls liblxc into a memory file and -+ * will use the memfd to rexecute the binary. This is done to prevent attacks -+ * through the /proc/self/exe symlink to corrupt the host binary when host and -+ * container are in the same user namespace or have set up an identity id -+ * mapping: CVE-2019-5736. -+ */ -+__attribute__((constructor)) static void liblxc_rexec(void) -+{ -+ if (lxc_rexec("liblxc")) { -+ fprintf(stderr, "Failed to re-execute liblxc via memory file descriptor\n"); -+ _exit(EXIT_FAILURE); -+ } -+} -diff --git a/src/lxc/syscall_wrappers.h b/src/lxc/syscall_wrappers.h -index 42d94db..dca4d15 100644 ---- a/src/lxc/syscall_wrappers.h -+++ b/src/lxc/syscall_wrappers.h -@@ -58,6 +58,20 @@ static inline long __keyctl(int cmd, unsigned long arg2, unsigned long arg3, - #define keyctl __keyctl - #endif - -+#ifndef F_LINUX_SPECIFIC_BASE -+#define F_LINUX_SPECIFIC_BASE 1024 -+#endif -+#ifndef F_ADD_SEALS -+#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9) -+#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10) -+#endif -+#ifndef F_SEAL_SEAL -+#define F_SEAL_SEAL 0x0001 -+#define F_SEAL_SHRINK 0x0002 -+#define F_SEAL_GROW 0x0004 -+#define F_SEAL_WRITE 0x0008 -+#endif -+ - #ifndef HAVE_MEMFD_CREATE - static inline int memfd_create(const char *name, unsigned int flags) { - #ifndef __NR_memfd_create --- -1.8.3.1 - diff --git a/lxc.spec b/lxc.spec index 20ab8b0c6e24aee9a85a7a450eb1e4df9cd3bb6b..5cd4d9967dcd1078e5c028b6c6e85dd38ff1d2d2 100644 --- a/lxc.spec +++ b/lxc.spec @@ -1,161 +1,77 @@ -%global _release 2020040801 +%global _release 2020042302 %global debug_package %{nil} Name: lxc -Version: 3.0.3 +Version: 4.0.1 Release: %{_release} Summary: Linux Containers userspace tools License: LGPLv2+ URL: http://linuxcontainers.org -Source0: lxc-3.0.3.tar.gz -Patch6000: lxc-CVE-2019-5736-runC-rexec-callers-as-memfd.patch -Patch9003: 0001-confile-add-lxc.isulad.init.args-config-interface.patch -Patch9004: 0002-namespace-add-support-share-namespace-by-path.patch -Patch9005: 0003-confile-add-lxc.isulad.populate.device-interface.patch -Patch9006: 0004-support-isulad-fifo-log.patch -Patch9007: 0005-auto-mount-cgroup-sys-and-proc.patch -Patch9008: 0006-conf.c-fix-bug-when-set-no-ro-mount-mount-propagatio.patch -Patch9009: 0007-use-isulad-log-format.patch -Patch9010: 0008-isulad-modify-exit-code-and-stop-signal.patch -Patch9011: 0009-lxc_start-add-default-terminal-fifos.patch -Patch9012: 0010-Save-pid-ppid-info-into-file-for-isulad.patch -Patch9013: 0011-Add-exit-FIFO-to-monitor-state-of-lxc-monitor.patch -Patch9014: 0012-Init-fifos-in-lxc_attach_terminal.patch -Patch9015: 0013-isulad-set-env-home-in-container.patch -Patch9016: 0014-support-rotate-for-container-log-file.patch -Patch9017: 0015-fix-high-gcc-compile-bug.patch -Patch9018: 0016-add-masked-paths-and-ro-paths.patch -Patch9019: 0017-isulad-check-cgroup-cpu.shares-after-setted.patch -Patch9020: 0018-lxc-attach-add-support-terminal-fifos.patch -Patch9021: 0019-remount-cgroup-readonly-and-make-soft-link-of-subcgr.patch -Patch9022: 0020-fix-log-error-when-symlink-subcgroup.patch -Patch9023: 0021-lxc-attch-add-error-message.patch -Patch9024: 0022-support-rootfs-mount-propagation.patch -Patch9025: 0023-attach.c-change-uid-and-gid-from-lxc-container-confi.patch -Patch9026: 0024-isulad-support-symlink-in-mount-entry-and-not-permit.patch -Patch9027: 0025-support-oci-hooks.patch -Patch9028: 0026-remove-filelock-and-do-not-destroy-directory-when-de.patch -Patch9029: 0027-fix-bug-of-memory-leak.patch -Patch9030: 0028-support-rootfs-for-container.patch -Patch9031: 0029-add-start-timeout-to-limit-start-time.patch -Patch9032: 0030-support-block-device-as-rootfs.patch -Patch9033: 0031-clean-add-clean-resources-api.patch -Patch9034: 0032-Drop-all-caps-when-cap.keep-ISULAD_KEEP_NONE.patch -Patch9035: 0033-support-mount-squashfs-in-mount-entry.patch -Patch9036: 0034-some-small-bugfix.patch -Patch9037: 0035-lxc-fixup-builds-with-newer-glibc.patch -Patch9038: 0036-drop_caps-add-drop-caps-of-current-process.patch -Patch9039: 0037-restore-default-signal-handlers-and-set-umask-0027.patch -Patch9040: 0038-make-the-given-terminal-as-controlling-terminal.patch -Patch9041: 0039-print-error-message-when-container-start-failed.patch -Patch9042: 0040-add-timeout-200ms-for-cmds-send-to-lxc-monitor.patch -Patch9043: 0041-return-1-when-_lxc_start-fails.patch -Patch9044: 0042-lxc-seccomp-adopt-to-lxc3.0.patch -Patch9045: 0043-check-null-pointer-of-handler-to-fix-coredump-of-att.patch -Patch9046: 0044-support-space-in-volume-mount-and-env.patch -Patch9047: 0045-add_terminal_fifos-Add-terminal-fifos-dynamically.patch -Patch9048: 0046-Do-not-test-cgroup-writeable.patch -Patch9049: 0047-Fix-memory-leak-in-lxc_global_config_value.patch -Patch9050: 0048-clear-ONLCR-flag-from-master-of-terminal.patch -Patch9051: 0049-Add-100ms-timeout-for-console-epoll.patch -Patch9052: 0050-seccomp-add-rules-for-specified-architecture-only.patch -Patch9053: 0051-if-ocihook-is-empty.patch -Patch9054: 0052-Fix-seccomp-fail-when-all-specified-in-config.patch -Patch9055: 0053-destroy-empty-cgroup-path-return-ture.patch -Patch9056: 0054-fix-invalid-log-message.patch -Patch9057: 0055-Fix-compile-error.patch -Patch9058: 0056-caps-use-_LINUX_CAPABILITY_VERSION_3-to-set-cap.patch -Patch9059: 0057-confile-add-support-umask.patch -Patch9060: 0058-do-not-check-ppid-when-set-death-signal.patch -Patch9061: 0059-delete-unused-variable-ppid.patch -Patch9062: 0060-using-json-file-to-write-console-log-of-container.patch -Patch9063: 0061-Fix-hook-use-the-path-args-envs-execvp-dirctory.patch -Patch9064: 0062-setup-sysctls-before-set-read-only-path-and-masked-p.patch -Patch9065: 0063-lxc-ignore-systemcall-load-failure-error.patch -Patch9066: 0064-lxc-Reduce-seccomp-processing-log-level.patch -Patch9067: 0065-Storage-return-true-if-storage_init-init-fail.patch -Patch9068: 0066-lxc-Pids-limit-does-not-report-an-error-after-execut.patch -Patch9069: 0067-lxc-report-error-when-remove-directory-failed.patch -Patch9070: 0068-support-record-stdout-stderr-log-of-container-consol.patch -Patch9071: 0069-lxc-killall-processes-if-container-shared-pid-namesp.patch -Patch9072: 0070-lxc-signal-all-process-for-shared-container-when-con.patch -Patch9073: 0071-lxc-get-cgroup-path-according-to-cgroup-mountpoint.patch -Patch9074: 0072-lxc-adapt-to-docker-18.09.patch -Patch9075: 0073-lxc-support-set-additional-groups.patch -Patch9076: 0074-lxc-only-add-valid-fd-to-mainloop.patch -Patch9077: 0075-lxc-add-timeout-for-attach.patch -Patch9078: 0076-lxc-delete-unused-variable.patch -Patch9079: 0077-lxc-set-negative-files.limit-to-max-and-fix-bug-of-s.patch -Patch9080: 0078-Run-pre-start-hook-before-chroot.patch -Patch9081: 0079-inherid-env-from-parent-in-oci-hooks.patch -Patch9082: 0080-lxc-fix-compile-error.patch -Patch9083: 0081-lxc-Change-the-range-of-attach-timeout.patch -Patch9084: 0082-lxc-fix-memory-leak-cause-by-setenv.patch -Patch9085: 0083-lxc-free-lxc-handler.patch -Patch9086: 0084-lxc-memory-leak-of-lxc_grow_array.patch -Patch9087: 0085-lxc-update-json-file-from-isulad.patch -Patch9088: 0086-confile-add-support-systemd.patch -Patch9089: 0087-lxc-adapt-to-spec-of-oci-hook.patch -Patch9090: 0088-fix-lxc-build-error.patch -Patch9091: 0089-lxc-add-get-container-processes-pids-func.patch -Patch9092: 0090-lxc-remove-unused-variable.patch -Patch9093: 0091-lxc-support-namespaced-kernel-params-can-be-changed-.patch -Patch9094: 0092-lxc-add-output-error-when-create-unified-cgroup.patch -Patch9095: 0093-optimize-isulad_kit-operator.patch -Patch9096: 0094-exec-load-uid-gid-and-groups.patch -Patch9097: 0095-lxc-don-t-use-the-unified-hierarchy-for-the-systemd-.patch -Patch9098: 0096-close-inherited-fd-in-hook-process.patch -Patch9099: 0097-lxc-report-error-when-fork-exec-error-for-hooks.patch -Patch9100: 0098-lxc-make-dev-bind-mount-from-host-tmpfs-for-system-c.patch -Patch9101: 0099-terminal-do-not-close-the-master-fd-of-pty.patch -Patch9102: 0100-start-add-check-save-pid-info-file.patch -Patch9103: 0101-lxc-fix-code-error.patch -Patch9104: 0102-lxc-fix-compile-warnings.patch -Patch9105: 0103-lxc-fix-code-error-in-conf.c.patch -Patch9106: 0104-lxc-fix-code-error.patch -Patch9107: 0105-lxc-fix-code-error-warnings.patch -Patch9108: 0106-set-timeout-to-1s-for-cmds-send-to-lxc-monitor.patch -Patch9109: 0107-add-log-for-failure-of-rename-file.patch -Patch9110: 0108-check-calloc-input-valid.patch -Patch9111: 0109-add-secure-compile-flags-to-lxc.patch -Patch9112: 0110-add-doc-for-lxc.patch -Patch9113: 0111-lxc-use-safe_strdup-instead-of-strdup.patch -Patch9114: 0112-fix-secure-errors.patch -Patch9115: 0113-Malloc-parameter-check-and-judgment.patch -Patch9116: 0114-lxc-fix-code-errors.patch -Patch9117: 0115-fix-compile-error-on-ubuntu.patch -Patch9118: 0116-lxc-set-base-cgroup-path-to.patch -Patch9119: 0117-pupulate-device-with-dir-mode-750-and-set-uid-gid.patch -Patch9120: 0118-fix-sscanf-return-value-check.patch -Patch9121: 0119-remove-unuse-binary.patch -Patch9122: 0120-remove-unuse-unmount-namespace.patch -Patch9123: 0121-optimize-log-when-root-path-is-invalid.patch -Patch9124: 0122-lxc-fix-code-reivew-errors.patch -Patch9125: 0123-in-accordance-with-hook-spec-in-oci.patch -Patch9126: 0124-lxc-close-maincmd-fd-before-destroy-cgroup.patch -Patch9127: 0125-lxc-fix-strcat-bug-in-cleanpath.patch -Patch9128: 0126-add-user-option-for-lxc-attach.patch -Patch9129: 0127-log-only-write-size-begin-if-buffer-is-full.patch -Patch9130: 0128-link-proc-mounts-to-etc-mtab.patch -Patch9131: 0129-cgfsng-add-retry-for-enter-cgroup.patch -Patch9132: 0130-fix-snprintf-create-abstract-socket-name-bug.patch -Patch9133: 0131-fix-commands-and-terminal-memory-leak-bug.patch -Patch9134: 0132-lxc-fix-bug-in-cgroup-parent.patch -Patch9135: 0133-lxc-fix-bug-in-cgfsng.patch -Patch9136: 0134-lxc-do-cpuset-same-as-runc.patch -Patch9137: 0135-lxc-fix-code-warnings-for-cgfsng.c.patch -Patch9138: 0136-lxc-fix-retry-bug-in-cgroup.patch -Patch9139: 0137-lxc-fix-bug-in-read-proc.patch -Patch9140: 0138-resize-implement-resize-function-in-exec-start.patch -Patch9141: 0139-lxc-fix-get-cgroup-path-by-config-instead-of-cmd.patch -Patch9142: 0140-lxc-remove-umask-when-populate-devices.patch +Source0: lxc-4.0.1.tar.gz +Patch9000: 0001-iSulad-add-HAVE_ISULAD-macro.patch +Patch9001: 0002-confile-add-lxc.isulad.init.args-config-interface.patch +Patch9002: 0003-confile-add-lxc.isulad.populate.device-interface.patch +Patch9003: 0004-confile-add-support-umask.patch +Patch9004: 0005-cgroup-refact-cgroup-implemt.patch +Patch9005: 0006-modify-container-exit-code-and-stop-signal.patch +Patch9006: 0007-check-and-save-pid-info-file.patch +Patch9007: 0008-support-block-device-as-rootfs.patch +Patch9008: 0009-support-mount-squashfs-in-mount-entry.patch +Patch9009: 0010-IO-refact-terminal-progress.patch +Patch9010: 0011-add-exit-fifo-to-monitor-state-of-lxc-monitor.patch +Patch9011: 0012-Adapt-to-isulad-log.patch +Patch9012: 0013-set-env-in-container.patch +Patch9013: 0014-exec-refact-attach-progress.patch +Patch9014: 0015-add-masked-paths-and-readonly-paths.patch +Patch9015: 0016-start-separate-i-and-t.patch +Patch9016: 0017-attach-add_terminal_fifos-Add-terminal-fifos-dynamic.patch +Patch9017: 0018-pty-setup-pty-after-setup-rootfs-mount-options.patch +Patch9018: 0019-resize-implement-resize-function-in-exec-start.patch +Patch9019: 0020-confile-decode-escape-charactors-in-config.patch +Patch9020: 0021-cgroup-add-retry-for-destory-cgroups.patch +Patch9021: 0022-support-terminal-log.patch +Patch9022: 0023-Supporting-rootfs-mount-propagation.patch +Patch9023: 0024-start-do-not-check-ppid-when-set-death-signal.patch +Patch9024: 0025-support-oci-hooks.patch +Patch9025: 0026-Supporting-UID-GID-configuration.patch +Patch9026: 0027-Capabilites-security-feature-enhanced.patch +Patch9027: 0028-Supporting-workdir-configuration.patch +Patch9028: 0029-Supporting-additional-groups-configuration.patch +Patch9029: 0030-set-negative-files.limit-value-to-max.patch +Patch9030: 0031-head-file-remove-macro-HAVE_ISULAD-in-installed-head.patch +Patch9031: 0032-link-proc-mounts-to-etc-mtab.patch +Patch9032: 0033-build-add-secure-build-flags.patch +Patch9033: 0034-support-timeout.patch +Patch9034: 0035-Seccomp-security-feature-enhanced.patch +Patch9035: 0036-Security-coding-modification.patch +Patch9036: 0037-cgfsng-fix-build-error-device_cgroup_rule_parse.patch +Patch9037: 0038-Ignore-errors-when-loading-rules-fail.patch +Patch9038: 0039-net-adapt-to-isulad.patch +Patch9039: 0040-cgfsng-make-container-full-path-in-cgfsng_get_cgroup.patch +Patch9040: 0041-build-fix-some-bug-in-free-memory.patch +Patch9041: 0042-cgfsng-make-container-full-path-in-destory-cgroup.patch +Patch9042: 0043-support-error-report.patch +Patch9043: 0044-remove-filelock-in-destroy-dir.patch +Patch9044: 0045-restore-default-signal-handler.patch +Patch9045: 0046-add-support-systemd.patch +Patch9046: 0047-support-namespaced-kernel-params-can-be-changed-in-s.patch +Patch9047: 0048-don-t-use-the-unified-hierarchy-for-the-systemd-cgro.patch +Patch9048: 0049-make-dev-bind-mount-from-host-tmpfs-for-system-conta.patch +Patch9049: 0050-clean-add-init-fd-in-lxc_init_clean_handler.patch +Patch9050: 0051-init-pids-add-init-fd-in-lxc_init_pids_handler.patch +Patch9051: 0052-setupdev-add-judge-whether-have-mount-dev-entry.patch +Patch9052: 0053-attach-seprate-i-and-t-flags.patch +Patch9053: 0054-start-do-not-check-pid-die-when-lxc_poll-exit.patch +Patch9054: 0055-terminal-not-close-pipe-when-lxc_poll-exit.patch +Patch9055: 0056-attach-add-sigfd-to-monitor-the-exit-of-pid.patch +Patch9056: 0057-attach-add-read-data-from-attach-sigfd.patch BuildRequires: systemd-units git libtool graphviz docbook2X doxygen chrpath BuildRequires: pkgconfig(libseccomp) BuildRequires: libcap libcap-devel libselinux-devel yajl yajl-devel BuildRequires: pkgconfig(bash-completion) -Requires: lxc-libs = 3.0.3-%{release} +Requires: lxc-libs = 4.0.1-%{release} %package libs Summary: Runtime library files for %{name} @@ -173,7 +89,7 @@ overhead of full virtualization. The %{name}-libs package contains libraries for running %{name} applications. -%{!?_pkgdocdir: %global _pkgdocdir %{_docdir}/lxc-3.0.3} +%{!?_pkgdocdir: %global _pkgdocdir %{_docdir}/lxc-4.0.1} %description Containers are insulated areas inside a system, which have their own namespace @@ -187,7 +103,7 @@ boot an entire "containerized" system, and to manage and debug your containers. %package devel Summary: Development files for lxc -Requires: lxc = 3.0.3-%{release} +Requires: lxc = 4.0.1-%{release} Requires: pkgconfig %description devel @@ -203,7 +119,7 @@ BuildArch: noarch This package contains documentation for lxc for creating containers. %prep -%autosetup -n lxc-3.0.3 -Sgit -p1 +%autosetup -n lxc-4.0.1 -Sgit -p1 %build %configure --enable-doc --enable-api-docs \ @@ -324,13 +240,8 @@ make check %{_mandir}/*/man7/%{name}* %changelog -* Thu Apr 08 2020 openEuler Buildteam - 3.0.3-2020040801 -- fix source0 -* Tue Mar 10 2020 openEuler Buildteam - 3.0.3-2020031002 -- add /etc/sysconfig/ -* Tue Mar 10 2020 openEuler Buildteam - 3.0.3-2020031001 -- Correct release field -* Thu Feb 14 2020 openEuler Buildteam - 3.0.3-20200214 -- make lxc-libs package -* Thu Dec 19 2019 openEuler Buildteam - 3.0.3-20191218 -- Package init +* Mon Apr 20 2020 openEuler Buildteam - 4.0.1-2020042001 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC: update lxc to 4.0.1 diff --git a/series.conf b/series.conf index f3901a6f1774d4e5e9fc5d17df8cfd3834b4be45..21e500b9a53e454ac8c1d2c1a8ebeed963175f1a 100644 --- a/series.conf +++ b/series.conf @@ -1,140 +1,58 @@ -lxc-CVE-2019-5736-runC-rexec-callers-as-memfd.patch -0001-confile-add-lxc.isulad.init.args-config-interface.patch -0002-namespace-add-support-share-namespace-by-path.patch +0001-iSulad-add-HAVE_ISULAD-macro.patch +0002-confile-add-lxc.isulad.init.args-config-interface.patch 0003-confile-add-lxc.isulad.populate.device-interface.patch -0004-support-isulad-fifo-log.patch -0005-auto-mount-cgroup-sys-and-proc.patch -0006-conf.c-fix-bug-when-set-no-ro-mount-mount-propagatio.patch -0007-use-isulad-log-format.patch -0008-isulad-modify-exit-code-and-stop-signal.patch -0009-lxc_start-add-default-terminal-fifos.patch -0010-Save-pid-ppid-info-into-file-for-isulad.patch -0011-Add-exit-FIFO-to-monitor-state-of-lxc-monitor.patch -0012-Init-fifos-in-lxc_attach_terminal.patch -0013-isulad-set-env-home-in-container.patch -0014-support-rotate-for-container-log-file.patch -0015-fix-high-gcc-compile-bug.patch -0016-add-masked-paths-and-ro-paths.patch -0017-isulad-check-cgroup-cpu.shares-after-setted.patch -0018-lxc-attach-add-support-terminal-fifos.patch -0019-remount-cgroup-readonly-and-make-soft-link-of-subcgr.patch -0020-fix-log-error-when-symlink-subcgroup.patch -0021-lxc-attch-add-error-message.patch -0022-support-rootfs-mount-propagation.patch -0023-attach.c-change-uid-and-gid-from-lxc-container-confi.patch -0024-isulad-support-symlink-in-mount-entry-and-not-permit.patch +0004-confile-add-support-umask.patch +0005-cgroup-refact-cgroup-implemt.patch +0006-modify-container-exit-code-and-stop-signal.patch +0007-check-and-save-pid-info-file.patch +0008-support-block-device-as-rootfs.patch +0009-support-mount-squashfs-in-mount-entry.patch +0010-IO-refact-terminal-progress.patch +0011-add-exit-fifo-to-monitor-state-of-lxc-monitor.patch +0012-Adapt-to-isulad-log.patch +0013-set-env-in-container.patch +0014-exec-refact-attach-progress.patch +0015-add-masked-paths-and-readonly-paths.patch +0016-start-separate-i-and-t.patch +0017-attach-add_terminal_fifos-Add-terminal-fifos-dynamic.patch +0018-pty-setup-pty-after-setup-rootfs-mount-options.patch +0019-resize-implement-resize-function-in-exec-start.patch +0020-confile-decode-escape-charactors-in-config.patch +0021-cgroup-add-retry-for-destory-cgroups.patch +0022-support-terminal-log.patch +0023-Supporting-rootfs-mount-propagation.patch +0024-start-do-not-check-ppid-when-set-death-signal.patch 0025-support-oci-hooks.patch -0026-remove-filelock-and-do-not-destroy-directory-when-de.patch -0027-fix-bug-of-memory-leak.patch -0028-support-rootfs-for-container.patch -0029-add-start-timeout-to-limit-start-time.patch -0030-support-block-device-as-rootfs.patch -0031-clean-add-clean-resources-api.patch -0032-Drop-all-caps-when-cap.keep-ISULAD_KEEP_NONE.patch -0033-support-mount-squashfs-in-mount-entry.patch -0034-some-small-bugfix.patch -0035-lxc-fixup-builds-with-newer-glibc.patch -0036-drop_caps-add-drop-caps-of-current-process.patch -0037-restore-default-signal-handlers-and-set-umask-0027.patch -0038-make-the-given-terminal-as-controlling-terminal.patch -0039-print-error-message-when-container-start-failed.patch -0040-add-timeout-200ms-for-cmds-send-to-lxc-monitor.patch -0041-return-1-when-_lxc_start-fails.patch -0042-lxc-seccomp-adopt-to-lxc3.0.patch -0043-check-null-pointer-of-handler-to-fix-coredump-of-att.patch -0044-support-space-in-volume-mount-and-env.patch -0045-add_terminal_fifos-Add-terminal-fifos-dynamically.patch -0046-Do-not-test-cgroup-writeable.patch -0047-Fix-memory-leak-in-lxc_global_config_value.patch -0048-clear-ONLCR-flag-from-master-of-terminal.patch -0049-Add-100ms-timeout-for-console-epoll.patch -0050-seccomp-add-rules-for-specified-architecture-only.patch -0051-if-ocihook-is-empty.patch -0052-Fix-seccomp-fail-when-all-specified-in-config.patch -0053-destroy-empty-cgroup-path-return-ture.patch -0054-fix-invalid-log-message.patch -0055-Fix-compile-error.patch -0056-caps-use-_LINUX_CAPABILITY_VERSION_3-to-set-cap.patch -0057-confile-add-support-umask.patch -0058-do-not-check-ppid-when-set-death-signal.patch -0059-delete-unused-variable-ppid.patch -0060-using-json-file-to-write-console-log-of-container.patch -0061-Fix-hook-use-the-path-args-envs-execvp-dirctory.patch -0062-setup-sysctls-before-set-read-only-path-and-masked-p.patch -0063-lxc-ignore-systemcall-load-failure-error.patch -0064-lxc-Reduce-seccomp-processing-log-level.patch -0065-Storage-return-true-if-storage_init-init-fail.patch -0066-lxc-Pids-limit-does-not-report-an-error-after-execut.patch -0067-lxc-report-error-when-remove-directory-failed.patch -0068-support-record-stdout-stderr-log-of-container-consol.patch -0069-lxc-killall-processes-if-container-shared-pid-namesp.patch -0070-lxc-signal-all-process-for-shared-container-when-con.patch -0071-lxc-get-cgroup-path-according-to-cgroup-mountpoint.patch -0072-lxc-adapt-to-docker-18.09.patch -0073-lxc-support-set-additional-groups.patch -0074-lxc-only-add-valid-fd-to-mainloop.patch -0075-lxc-add-timeout-for-attach.patch -0076-lxc-delete-unused-variable.patch -0077-lxc-set-negative-files.limit-to-max-and-fix-bug-of-s.patch -0078-Run-pre-start-hook-before-chroot.patch -0079-inherid-env-from-parent-in-oci-hooks.patch -0080-lxc-fix-compile-error.patch -0081-lxc-Change-the-range-of-attach-timeout.patch -0082-lxc-fix-memory-leak-cause-by-setenv.patch -0083-lxc-free-lxc-handler.patch -0084-lxc-memory-leak-of-lxc_grow_array.patch -0085-lxc-update-json-file-from-isulad.patch -0086-confile-add-support-systemd.patch -0087-lxc-adapt-to-spec-of-oci-hook.patch -0088-fix-lxc-build-error.patch -0089-lxc-add-get-container-processes-pids-func.patch -0090-lxc-remove-unused-variable.patch -0091-lxc-support-namespaced-kernel-params-can-be-changed-.patch -0092-lxc-add-output-error-when-create-unified-cgroup.patch -0093-optimize-isulad_kit-operator.patch -0094-exec-load-uid-gid-and-groups.patch -0095-lxc-don-t-use-the-unified-hierarchy-for-the-systemd-.patch -0096-close-inherited-fd-in-hook-process.patch -0097-lxc-report-error-when-fork-exec-error-for-hooks.patch -0098-lxc-make-dev-bind-mount-from-host-tmpfs-for-system-c.patch -0099-terminal-do-not-close-the-master-fd-of-pty.patch -0100-start-add-check-save-pid-info-file.patch -0101-lxc-fix-code-error.patch -0102-lxc-fix-compile-warnings.patch -0103-lxc-fix-code-error-in-conf.c.patch -0104-lxc-fix-code-error.patch -0105-lxc-fix-code-error-warnings.patch -0106-set-timeout-to-1s-for-cmds-send-to-lxc-monitor.patch -0107-add-log-for-failure-of-rename-file.patch -0108-check-calloc-input-valid.patch -0109-add-secure-compile-flags-to-lxc.patch -0110-add-doc-for-lxc.patch -0111-lxc-use-safe_strdup-instead-of-strdup.patch -0112-fix-secure-errors.patch -0113-Malloc-parameter-check-and-judgment.patch -0114-lxc-fix-code-errors.patch -0115-fix-compile-error-on-ubuntu.patch -0116-lxc-set-base-cgroup-path-to.patch -0117-pupulate-device-with-dir-mode-750-and-set-uid-gid.patch -0118-fix-sscanf-return-value-check.patch -0119-remove-unuse-binary.patch -0120-remove-unuse-unmount-namespace.patch -0121-optimize-log-when-root-path-is-invalid.patch -0122-lxc-fix-code-reivew-errors.patch -0123-in-accordance-with-hook-spec-in-oci.patch -0124-lxc-close-maincmd-fd-before-destroy-cgroup.patch -0125-lxc-fix-strcat-bug-in-cleanpath.patch -0126-add-user-option-for-lxc-attach.patch -0127-log-only-write-size-begin-if-buffer-is-full.patch -0128-link-proc-mounts-to-etc-mtab.patch -0129-cgfsng-add-retry-for-enter-cgroup.patch -0130-fix-snprintf-create-abstract-socket-name-bug.patch -0131-fix-commands-and-terminal-memory-leak-bug.patch -0132-lxc-fix-bug-in-cgroup-parent.patch -0133-lxc-fix-bug-in-cgfsng.patch -0134-lxc-do-cpuset-same-as-runc.patch -0135-lxc-fix-code-warnings-for-cgfsng.c.patch -0136-lxc-fix-retry-bug-in-cgroup.patch -0137-lxc-fix-bug-in-read-proc.patch -0138-resize-implement-resize-function-in-exec-start.patch -0139-lxc-fix-get-cgroup-path-by-config-instead-of-cmd.patch +0026-Supporting-UID-GID-configuration.patch +0027-Capabilites-security-feature-enhanced.patch +0028-Supporting-workdir-configuration.patch +0029-Supporting-additional-groups-configuration.patch +0030-set-negative-files.limit-value-to-max.patch +0031-head-file-remove-macro-HAVE_ISULAD-in-installed-head.patch +0032-link-proc-mounts-to-etc-mtab.patch +0033-build-add-secure-build-flags.patch +0034-support-timeout.patch +0035-Seccomp-security-feature-enhanced.patch +0036-Security-coding-modification.patch +0037-cgfsng-fix-build-error-device_cgroup_rule_parse.patch +0038-Ignore-errors-when-loading-rules-fail.patch +0039-net-adapt-to-isulad.patch +0040-cgfsng-make-container-full-path-in-cgfsng_get_cgroup.patch +0041-build-fix-some-bug-in-free-memory.patch +0042-cgfsng-make-container-full-path-in-destory-cgroup.patch +0043-support-error-report.patch +0044-remove-filelock-in-destroy-dir.patch +0045-restore-default-signal-handler.patch +0046-add-support-systemd.patch +0047-support-namespaced-kernel-params-can-be-changed-in-s.patch +0048-don-t-use-the-unified-hierarchy-for-the-systemd-cgro.patch +0049-make-dev-bind-mount-from-host-tmpfs-for-system-conta.patch +0050-clean-add-init-fd-in-lxc_init_clean_handler.patch +0051-init-pids-add-init-fd-in-lxc_init_pids_handler.patch +0052-setupdev-add-judge-whether-have-mount-dev-entry.patch +0053-attach-seprate-i-and-t-flags.patch +0054-start-do-not-check-pid-die-when-lxc_poll-exit.patch +0055-terminal-not-close-pipe-when-lxc_poll-exit.patch +0056-attach-add-sigfd-to-monitor-the-exit-of-pid.patch +0057-attach-add-read-data-from-attach-sigfd.patch +0058-support-syslog-for-console.patch