Package init

This commit is contained in:
overweight 2019-09-30 11:03:07 -04:00
commit 85d35cce63
127 changed files with 33795 additions and 0 deletions

View File

@ -0,0 +1,222 @@
From a6f57fc8bbe7b0e2d2d77f300c3c84a2956634b6 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Thu, 10 Jan 2019 06:54:37 -0500
Subject: [PATCH 001/122] 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 <lifeng68@huawei.com>
---
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(+)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index d95bc4c..f20d629 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -4014,6 +4014,18 @@ void lxc_clear_includes(struct lxc_conf *conf)
}
}
+/*isulad clear init args*/
+int lxc_clear_init_args(struct lxc_conf *lxc_conf)
+{
+ int i;
+
+ for (i = 0; i < lxc_conf->init_argc; i++)
+ free(lxc_conf->init_argv[i]);
+ free(lxc_conf->init_argv);
+
+ 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);
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 41f67cf..95c3027 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -376,6 +376,10 @@ struct lxc_conf {
/* procs */
struct lxc_list procs;
+
+ /* isulad add: init args used to repalce init_cmd*/
+ char **init_argv;
+ size_t init_argc;
};
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 */
+int lxc_clear_init_args(struct lxc_conf *lxc_conf);
+/* isulad add end */
+
#endif /* __LXC_CONF_H */
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index 05c6823..7297b35 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -150,6 +150,10 @@ lxc_config_define(tty_dir);
lxc_config_define(uts_name);
lxc_config_define(sysctl);
lxc_config_define(proc);
+/*isulad add begin*/
+lxc_config_define(init_args);
+/*isulad add end*/
+
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[] = {
{ "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, },
+
+ /*isulad add begin*/
+ { "lxc.isulad.init.args", set_config_init_args, get_config_init_args, clr_config_init_args, },
+ /*isulad add end*/
};
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);
}
+/* 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)
+{
+ int ret = 0;
+ char *tmp = NULL;
+ char *new_value = NULL;
+
+ ret = set_config_string_item(&new_value, value);
+ if (ret || !new_value)
+ return ret;
+
+ tmp = realloc(lxc_conf->init_argv, (lxc_conf->init_argc + 1) * sizeof(char *));
+ if (!tmp) {
+ ERROR("Out of memory");
+ free(new_value);
+ return -1;
+ }
+
+ lxc_conf->init_argv = (char **)tmp;
+
+ lxc_conf->init_argv[lxc_conf->init_argc] = new_value;
+ lxc_conf->init_argc++;
+
+ 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)
+{
+ int i, len, fulllen = 0;
+ struct lxc_list *it;
+
+ if (!retv)
+ inlen = 0;
+ else
+ memset(retv, 0, inlen);
+
+ for (i = 0; i < c->init_argc; i++) {
+ strprint(retv, inlen, "%s", c->init_argv[i]);
+ }
+
+ 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)
{
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index ad70886..b4cacce 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)
return true;
}
+/* isulad: use init argv as init cmd */
+static char **use_init_args(char **init_argv, size_t init_args)
+{
+ size_t i;
+ int nargs = 0;
+ char **argv;
+
+ if (!init_argv)
+ return NULL;
+
+ do {
+ argv = malloc(sizeof(char *));
+ } while (!argv);
+
+ argv[0] = NULL;
+ for (i = 0; i < init_args; i++)
+ push_arg(&argv, init_argv[i], &nargs);
+
+ if (nargs == 0) {
+ free(argv);
+ return NULL;
+ }
+ return argv;
+}
+
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
argv = init_cmd = split_init_cmd(conf->init_cmd);
}
+ /* isulad: use init argv as init cmd */
+ if (!argv) {
+ argv = init_cmd = use_init_args(conf->init_argv, conf->init_argc);
+ }
+
/* ... otherwise use default_args. */
if (!argv) {
if (useinit) {
--
1.8.3.1

View File

@ -0,0 +1,35 @@
From d1e8ab945fadac5ee11eb150b1cdfb6aeec407c2 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Thu, 10 Jan 2019 08:42:19 -0500
Subject: [PATCH 002/122] namespace: add support share namespace by path
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,406 @@
From 8a8f3a04e8a6f3494a072ffe0cc9124049c5ba63 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Fri, 11 Jan 2019 01:51:25 -0500
Subject: [PATCH 003/122] confile: add lxc.isulad.populate.device interface
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
src/lxc/conf.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++---
src/lxc/conf.h | 28 +++++++++++-
src/lxc/confile.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 269 insertions(+), 8 deletions(-)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index f20d629..20b7aba 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));
memset(&new->ns_share, 0, sizeof(char *) * LXC_NS_MAX);
+ /* isulad add begin */
+ lxc_list_init(&new->populate_devs);
+ /* isulad add end */
+
return new;
}
@@ -3487,6 +3491,85 @@ static bool execveat_supported(void)
return true;
}
+/* 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;
+ char path[MAXPATHLEN];
+ mode_t cmask;
+ mode_t file_mode = 0;
+ struct lxc_populate_devs *dev_elem;
+ struct lxc_list *it;
+
+ INFO("Populating devices into container");
+ cmask = umask(S_IXUSR | S_IXGRP | S_IXOTH);
+ 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;
+
+ /* create any missing directories */
+ pathdirname = strdup(path);
+ pathdirname = dirname(pathdirname);
+ ret = mkdir_p(pathdirname, 0750);
+ free(pathdirname);
+ if (ret < 0) {
+ WARN("Failed to create target directory");
+ return -1;
+ }
+
+ if (!strcmp(dev_elem->type, "c")) {
+ file_mode = dev_elem->file_mode | S_IFCHR;
+ } else if (!strcmp(dev_elem->type, "b")) {
+ file_mode = dev_elem->file_mode | S_IFBLK;
+ } else {
+ ERROR("Failed to parse devices type '%s'", dev_elem->type);
+ return -1;
+ }
+
+ DEBUG("Try to mknod '%s':'%d':'%d':'%d'\n", path,
+ 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);
+
+ char hostpath[MAXPATHLEN];
+ FILE *pathfile;
+
+ // 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 (!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) {
+ SYSERROR("Failed bind mounting device %s from host into container",
+ dev_elem->name);
+ return -1;
+ }
+ }
+ if (chown(path, dev_elem->uid, dev_elem->gid) < 0) {
+ ERROR("Error chowning %s", path);
+ return -1;
+ }
+ }
+ umask(cmask);
+
+ INFO("Populated devices into container /dev");
+ return 0;
+}
+
int lxc_setup(struct lxc_handler *handler)
{
int ret;
@@ -3584,6 +3667,16 @@ int lxc_setup(struct lxc_handler *handler)
return -1;
}
+ /*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;
+ }
+ }
+
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;;
}
}
@@ -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;
+
+ lxc_list_for_each_safe(it, &c->populate_devs, next) {
+ struct lxc_populate_devs *dev_elem = it->elem;
+ lxc_list_del(it);
+ free(dev_elem->name);
+ free(dev_elem->type);
+ free(dev_elem);
+ free(it);
+ }
+ 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);
}
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 95c3027..cced868 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -171,6 +171,26 @@ struct lxc_rootfs {
};
/*
+ * iSulad: Defines a structure to store the devices which will
+ * be attached in container
+ * @name : the target device name in container
+ * @type : the type of target device "c" or "b"
+ * @mode : file mode for the device
+ * @maj : major number for the device
+ * @min : minor number for the device
+ */
+struct lxc_populate_devs {
+ char *name;
+ char *type;
+ mode_t file_mode;
+ int maj;
+ int min;
+ uid_t uid;
+ gid_t gid;
+};
+
+
+/*
* 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*/
char **init_argv;
size_t init_argc;
+ /* populate devices*/
+ struct lxc_list populate_devs;
+ /* isulad add end */
};
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 */
int lxc_clear_init_args(struct lxc_conf *lxc_conf);
+int lxc_clear_populate_devices(struct lxc_conf *c);
+
/* isulad add end */
#endif /* __LXC_CONF_H */
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index 7297b35..e3212d3 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -152,6 +152,7 @@ lxc_config_define(sysctl);
lxc_config_define(proc);
/*isulad add begin*/
lxc_config_define(init_args);
+lxc_config_define(populate_device);
/*isulad add end*/
@@ -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*/
};
@@ -2219,6 +2221,93 @@ static int set_config_init_args(const char *key, const char *value,
return 0;
}
+/* isulad: set config for init args */
+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;
+
+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)
+{
+ int len;
+ struct lxc_list *it;
+ int fulllen = 0;
+
+ if (!retv)
+ inlen = 0;
+ else
+ memset(retv, 0, 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);
+ }
+
+ 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)
+{
+ 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)
{
--
1.8.3.1

View File

@ -0,0 +1,96 @@
From e5e1a628b279c604fe5eaf0cc6646e6510dfe6f7 Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Fri, 11 Jan 2019 16:11:34 +0800
Subject: [PATCH 004/122] support isulad fifo log
support isulad fifo log in lxc3.0
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,80 @@
From f3c5a99c7bd1ecef02051489a97cbe0a1def254f Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Thu, 10 Jan 2019 20:40:19 +0800
Subject: [PATCH 005/122] auto mount cgroup sys and proc
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,39 @@
From 32f9ca00819b53c1f3bc933da8d489b3766c184d Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Fri, 11 Jan 2019 16:55:01 +0800
Subject: [PATCH 006/122] conf.c: fix bug when set no ro mount, mount
propagation will be skipped
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,74 @@
From efd10df536bcbfa56369c82bda4adc77b0ea7240 Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Fri, 11 Jan 2019 17:00:48 +0800
Subject: [PATCH 007/122] use isulad log format
use isulad log format
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,106 @@
From a5754c856857cee09e307e4e8459e8e99167e46a Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Fri, 11 Jan 2019 17:44:53 +0800
Subject: [PATCH 008/122] isulad: modify 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 <lifeng68@huawei.com>
---
src/lxc/lxccontainer.c | 6 ++----
src/lxc/start.c | 33 ++++++++++++++++-----------------
2 files changed, 18 insertions(+), 21 deletions(-)
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index b4cacce..1d7f5be 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)
{
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;
lxc_state_t states[MAX_STATE] = {0};
if (!c)
@@ -2082,11 +2083,8 @@ 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);
/* Add a new state client before sending the shutdown signal so that we
* don't miss a state.
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 72e2de2..d64bdac 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -1893,11 +1893,14 @@ out_abort:
return -1;
}
+// isulad: send '128 + signal' if container is killed by signal.
+#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)
{
- int ret, status;
+ int ret, status, exit_code;
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,
* reboot. This should mean it was an lxc-execute which simply exited.
* In any case, treat it as a 'halt'.
*/
+ // 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;
- }
+ int signal = WTERMSIG(status);
+ signal = WTERMSIG(status);
+ exit_code = ExitSignalOffset + signal;
+ ERROR("Container \"%s\" init exited with signal %d", name, signal);
+ } else if (WIFEXITED(status)) {
+ exit_code = WEXITSTATUS(status);
+ ERROR("Container \"%s\" init exited with status %d", name, exit_code);
+ } else {
+ exit_code = -1;
+ ERROR("Container \"%s\" init exited with unknown status", name);
}
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;
}
- lxc_monitor_send_exit_code(name, status, handler->lxcpath);
+ lxc_monitor_send_exit_code(name, exit_code, handler->lxcpath);
lxc_error_set_and_log(handler->pid, status);
if (error_num)
*error_num = handler->exit_status;
--
1.8.3.1

View File

@ -0,0 +1,538 @@
From ca1b4a1738d4c409ddabbc5e75b8da7438b2792f Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Fri, 11 Jan 2019 21:52:11 -0500
Subject: [PATCH 009/122] lxc_start: add default terminal fifos
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,453 @@
From 25c94a75d742ee2c66d431ebf73c9cd0fc2e4f42 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Fri, 11 Jan 2019 22:53:56 -0500
Subject: [PATCH 010/122] Save pid/ppid info into file for isulad
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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(+)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 7b7f95b..0b4b63b 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 */
lxc_clear_init_args(conf);
lxc_clear_populate_devices(conf);
+ free(conf->container_info_file);
/* isulad add end */
free(conf);
}
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index cced868..e0954f9 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -403,6 +403,8 @@ struct lxc_conf {
size_t init_argc;
/* populate devices*/
struct lxc_list populate_devs;
+
+ char *container_info_file;
/* isulad add end */
};
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 318c71e..5679b9b 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
WRAP_API_2(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;
+
+ if (!c || !c->lxc_conf || !info_file)
+ return false;
+ if (container_mem_lock(c)) {
+ ERROR("Error getting mem lock");
+ return false;
+ }
+
+ conf = c->lxc_conf;
+ if (conf->container_info_file)
+ free(conf->container_info_file);
+ conf->container_info_file = strdup(info_file);
+
+ container_mem_unlock(c);
+ return true;
+}
+
+WRAP_API_1(bool, lxcapi_set_container_info_file, const char *)
+
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;
+ c->set_container_info_file = lxcapi_set_container_info_file;
/* isulad add end */
return c;
diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h
index 486531e..3c845fe 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.
*/
bool (*set_terminal_init_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.
+ * \param info_file Value of the path of info file.
+ *
+ * \return \c true on success, else \c false.
+ */
+ bool (*set_container_info_file) (struct lxc_container *c, const char *info_file);
};
/*!
diff --git a/src/lxc/start.c b/src/lxc/start.c
index d64bdac..9d71dd7 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -1553,6 +1553,39 @@ 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)
+{
+ 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) {
+ 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;
+ goto out;
+ }
+out:
+ if (pid_fp)
+ fclose(pid_fp);
+ pid_fp = NULL;
+ 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
@@ -1683,6 +1716,14 @@ 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);
diff --git a/src/lxc/tools/arguments.h b/src/lxc/tools/arguments.h
index b7af2b5..b6df23f 100644
--- a/src/lxc/tools/arguments.h
+++ b/src/lxc/tools/arguments.h
@@ -63,6 +63,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 */
+ const char *container_info; /* isulad: file used to store pid and ppid info of container */
/* 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*/
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 8f03f11..2f94d67 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[] = {
{"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},
+ {"container-pidfile", required_argument, 0, OPT_CONTAINER_INFO},
+ /* isulad add end */
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;
break;
+ case OPT_CONTAINER_INFO:
+ args->container_info = arg;
+ break;
}
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[] = {
"/sbin/init",
NULL,
@@ -313,6 +320,18 @@ int main(int argc, char *argv[])
goto out;
}
+ /* 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) {
+ ERROR("Failed to ensure container's piddile '%s'", my_args.container_info);
+ goto out;
+ }
+ if (!c->set_container_info_file(c, container_info_file)) {
+ ERROR("Failed to set container's piddile '%s'", container_info_file);
+ goto out;
+ }
+ }
+
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[])
out:
lxc_container_put(c);
+ free(container_info_file);
exit(err);
}
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index 67c3b3e..4728284 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -1828,3 +1828,117 @@ int lxc_setup_keyring(void)
return ret;
}
+
+/* isulad: read file to buffer */
+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*/
+ 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);
+
+ return num_read;
+}
+
+/* isuald: lxc_stat2proc() makes sure it can handle arbitrary executable file basenames
+ * for `cmd', i.e. those with embedded whitespace or embedded ')'s.
+ * 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)
+{
+ int num;
+ proc_t *P = NULL;
+ char *tmp = NULL;
+
+ if (!S)
+ return NULL;/*lint !e960*/
+
+ tmp = strrchr(S, ')'); /* split into "PID (cmd" and "<rest>" *//*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;
+}
+
+/* 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;
+out:
+ free(pid_info);
+ return startat;
+}
+
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index 2d38178..8e4ed89 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -56,6 +56,71 @@ 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,
+*/
+
+/* Basic data structure which holds all information we can get about a process.
+ * (unless otherwise specified, fields are read from /proc/#/stat)
+ *
+ * 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 */
+} proc_t;
+
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);
extern int fd_nonblock(int fd);
+extern int unsigned long long lxc_get_process_startat(pid_t pid);
#endif /* __LXC_UTILS_H */
--
1.8.3.1

View File

@ -0,0 +1,261 @@
From dab4938915c64b201434719712dd5222a11b9dcf Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Sat, 12 Jan 2019 02:07:15 -0500
Subject: [PATCH 011/122] Add exit FIFO to monitor state of [lxc monitor]
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
src/lxc/conf.c | 3 +++
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(-)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 0b4b63b..bc45e44 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -2759,6 +2759,7 @@ struct lxc_conf *lxc_conf_init(void)
/* 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);
free(conf->container_info_file);
+ if (conf->exit_fd != -1)
+ close(conf->exit_fd);
/* isulad add end */
free(conf);
}
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index e0954f9..2d939cd 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -405,6 +405,8 @@ struct lxc_conf {
struct lxc_list populate_devs;
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, },
- /*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
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -295,6 +295,10 @@ static void lxc_container_free(struct lxc_container *c)
free(c->config_path);
c->config_path = NULL;
+ /* isulad: free exit fifo */
+ free(c->exit_fifo);
+ c->exit_fifo = NULL;
+
free(c);
}
@@ -882,7 +886,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
NULL,
};
char **init_cmd = NULL;
- int keepfds[3] = {-1, -1, -1};
+ int keepfds[4] = {-1, -1, -1, -1};
/* container does exist */
if (!c)
@@ -1077,6 +1081,16 @@ 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);
+ if (conf->exit_fd < 0) {
+ ERROR("Failed to open exit fifo %s: %s.", c->exit_fifo, strerror(errno));
+ ret = 1;
+ goto on_error;
+ }
+ }
+
conf->reboot = REBOOT_NONE;
/* Unshare the mount namespace if requested */
@@ -1111,6 +1125,10 @@ 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 */
+ if (conf->exit_fd >= 0) {
+ keepfds[3] = conf->exit_fd;
+ }
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
--- a/src/lxc/lxccontainer.h
+++ b/src/lxc/lxccontainer.h
@@ -81,6 +81,12 @@ struct lxc_container {
*/
char *pidfile;
+ /*! isulad:
+ * \private
+ * exit FIFO File to open used monitor the state of lxc monitor process.
+ */
+ char *exit_fifo;
+
/*!
* \private
* Container semaphore lock.
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 9d71dd7..9365d11 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;
handler->name = name;
+ 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)
*/
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));
+ if (ret != sizeof(int))
+ SYSERROR("Failed to write to exit code to exit fifo.");
+ }
+
/* 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,
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:
lxc_delete_network(handler);
diff --git a/src/lxc/start.h b/src/lxc/start.h
index df987dc..f59bf54 100644
--- a/src/lxc/start.h
+++ b/src/lxc/start.h
@@ -133,6 +133,8 @@ struct lxc_handler {
int exit_status;
struct cgroup_ops *cgroup_ops;
+
+ int exit_code;/* isulad: record the exit code of container */
};
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
--- 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 */
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 */
/* 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
--- 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},
{"container-pidfile", required_argument, 0, OPT_CONTAINER_INFO},
+ {"exit-fifo", required_argument, 0, OPT_EXIT_FIFO},
/* isulad add end */
LXC_COMMON_OPTIONS
};
@@ -154,6 +155,9 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg)
case OPT_CONTAINER_INFO:
args->container_info = arg;
break;
+ case OPT_EXIT_FIFO:
+ args->exit_monitor_fifo = arg;
+ break;
}
return 0;
}
@@ -332,6 +336,11 @@ 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);
+ }
+
if (my_args.console)
if (!c->set_config_item(c, "lxc.console.path", my_args.console))
goto out;
--
1.8.3.1

View File

@ -0,0 +1,28 @@
From 1ea4f8a2c3d3070fa9aafd9f055bed3b9018198b Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Sat, 12 Jan 2019 03:23:53 -0500
Subject: [PATCH 012/122] Init fifos in lxc_attach_terminal
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,139 @@
From 4fad66dc56b5863b3e272408b265eddf244434ef Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Sat, 12 Jan 2019 14:42:27 +0800
Subject: [PATCH 013/122] isulad: set env home in container
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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(-)
diff --git a/src/lxc/attach.c b/src/lxc/attach.c
index e7ba705..2bbf1eb 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)
else
new_gid = ns_root_gid;
+ // isulad: set env home in container
+ if (lxc_setup_env_home(new_uid) < 0) {
+ goto on_error;
+ }
+
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
--- 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;
+ // isulad: set env home in container
+ if (lxc_setup_env_home(new_uid) < 0)
+ goto out_warn_father;
+
/* Avoid unnecessary syscalls. */
if (new_uid == nsuid)
new_uid = LXC_INVALID_UID;
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index 4728284..74e74a1 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -45,6 +45,7 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
+#include <pwd.h>
#include "config.h"
#include "log.h"
@@ -1829,6 +1830,34 @@ int lxc_setup_keyring(void)
return ret;
}
+// 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;
+ 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;
+ }
+
+ // if we didn't configure HOME, set it based on uid
+ if (setenv("HOME", homedir, 0) < 0) {
+ SYSERROR("Unable to set env 'HOME'");
+ return -1;
+ }
+
+ NOTICE("Setted env 'HOME' to %s", homedir);
+ return 0;
+}
+
+
/* isulad: read file to buffer */
static int lxc_file2str(const char *filename, char ret[], int cap)
{
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index 8e4ed89..364bf67 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);
extern int unsigned long long lxc_get_process_startat(pid_t pid);
--
1.8.3.1

View File

@ -0,0 +1,93 @@
From e30d1a025a5f74c90a60a36fb6b61ccce18b88cf Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Sat, 12 Jan 2019 15:29:56 +0800
Subject: [PATCH 014/122] support rotate for container log file
support rotate for container log file
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,41 @@
From d4c2a04690f61c6d42c69f53b96cc039e94d5256 Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Sat, 12 Jan 2019 16:28:41 +0800
Subject: [PATCH 015/122] fix high gcc compile bug
fix high gcc compile bug
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,381 @@
From 478dfb4eadd6812bd63fc0d37cf1acad21a58e6a Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Sat, 12 Jan 2019 15:55:52 +0800
Subject: [PATCH 016/122] add masked paths and ro paths
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
src/lxc/conf.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/lxc/conf.h | 8 ++++
src/lxc/confile.c | 113 ++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 255 insertions(+), 1 deletion(-)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 5065e69..537f956 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -1343,6 +1343,95 @@ static int lxc_mount_rootfs(struct lxc_conf *conf)
return 0;
}
+
+// 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 ).
+static bool mask_path(const char *path)
+{
+ int ret;
+
+ if (!path)
+ return true;
+
+ ret = mount("/dev/null", path, "", MS_BIND, "");
+ if (ret < 0 && errno != ENOENT) {
+ if (errno == ENOTDIR) {
+ ret = mount("tmpfs", path, "tmpfs", MS_RDONLY, "");
+ if (ret < 0)
+ goto error;
+ return true;
+ }
+ goto error;
+ }
+ return true;
+
+error:
+ SYSERROR("Failed to mask path \"%s\": %s", path, strerror(errno));
+ return false;
+}
+
+// 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;
+
+ if (!path)
+ return true;
+
+ for (i = 0; i < 5; i++) {
+ ret = mount("", path, "", MS_REMOUNT | MS_RDONLY, "");
+ if (ret < 0 && errno != ENOENT) {
+ if (errno == EINVAL) {
+ // Probably not a mountpoint, use bind-mount
+ ret = mount(path, path, "", MS_BIND, "");
+ if (ret < 0)
+ goto on_error;
+ ret = mount(path, path, "", MS_BIND | MS_REMOUNT | MS_RDONLY | MS_REC | \
+ MS_NOEXEC | MS_NOSUID | MS_NODEV, "");
+ if (ret < 0)
+ goto on_error;
+ } else if (errno == EBUSY) {
+ DEBUG("Try to mount \"%s\" to readonly after 100ms.", path);
+ usleep(100 * 1000);
+ continue;
+ } else {
+ goto on_error;
+ }
+ }
+ return true;
+ }
+
+on_error:
+ SYSERROR("Unable to mount \"%s\" to readonly", path);
+ return false;
+}
+
+// isulad: setup rootfs masked paths
+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;
+ }
+
+ return 0;
+}
+// isulad: setup rootfs ro paths
+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;
+ }
+
+ return 0;
+}
+
int lxc_chroot(const struct lxc_rootfs *rootfs)
{
int i, ret;
@@ -2759,6 +2848,8 @@ struct lxc_conf *lxc_conf_init(void)
/* 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 */
@@ -3759,6 +3850,22 @@ int lxc_setup(struct lxc_handler *handler)
if (ret < 0)
return -1;
+ //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;
+ }
+ }
+
+ // 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;
+ }
+ }
+
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)
return 0;
}
+/*isulad: clear rootfs masked paths*/
+int lxc_clear_rootfs_masked_paths(struct lxc_conf *c)
+{
+ struct lxc_list *it,*next;
+
+ lxc_list_for_each_safe(it, &c->rootfs.maskedpaths, next) {
+ lxc_list_del(it);
+ free(it->elem);
+ free(it);
+ }
+ return 0;
+}
+
+/*isulad: clear rootfs ro paths*/
+int lxc_clear_rootfs_ro_paths(struct lxc_conf *c)
+{
+ struct lxc_list *it,*next;
+
+ lxc_list_for_each_safe(it, &c->rootfs.ropaths, next) {
+ lxc_list_del(it);
+ free(it->elem);
+ free(it);
+ }
+ 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);
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 2d939cd..7927812 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -160,6 +160,8 @@ struct lxc_tty_info {
* @options : mount options
* @mountflags : the portion of @options that are flags
* @data : the portion of @options that are not flags
+ * @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;
unsigned long mountflags;
char *data;
+ /* isulad: maskedpaths */
+ struct lxc_list maskedpaths;
+ /* isulad: ropaths */
+ struct lxc_list ropaths;
};
/*
@@ -477,6 +483,8 @@ extern int lxc_clear_procs(struct lxc_conf *c, const char *key);
/* isulad add begin */
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 */
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index e782211..e199965 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);
+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*/
{ "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, },
/*isulad add end*/
};
@@ -2224,7 +2228,7 @@ static int set_config_init_args(const char *key, const char *value,
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_list *list_item = NULL;
+
+ if (lxc_config_value_empty(value))
+ return lxc_clear_rootfs_masked_paths(lxc_conf);
+
+ list_item = malloc(sizeof(*list_item));
+ if (!list_item)
+ goto on_error;
+
+ list_item->elem = strdup(value);
+
+ if (!list_item->elem)
+ goto on_error;
+
+ lxc_list_add_tail(&lxc_conf->rootfs.maskedpaths, list_item);
+
+ return 0;
+
+on_error:
+ free(list_item);
+
+ return -1;
+}
+
+/* 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_list *list_item = NULL;
+
+ if (lxc_config_value_empty(value))
+ return lxc_clear_rootfs_ro_paths(lxc_conf);
+
+ list_item = malloc(sizeof(*list_item));
+ if (!list_item)
+ goto on_error;
+
+ list_item->elem = strdup(value);
+
+ if (!list_item->elem)
+ goto on_error;
+
+ lxc_list_add_tail(&lxc_conf->rootfs.ropaths, list_item);
+
+ return 0;
+
+on_error:
+ 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)
+{
+ int len, fulllen = 0;
+ struct lxc_list *it;
+
+ if (!retv)
+ inlen = 0;
+ else
+ memset(retv, 0, inlen);
+
+ lxc_list_for_each(it, &c->rootfs.ropaths) {
+ strprint(retv, inlen, "%s\n", (char *)it->elem);
+ }
+
+ 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)
+{
+ 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)
+{
+ 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)
{
--
1.8.3.1

View File

@ -0,0 +1,99 @@
From b4cf90f64f23198555372e4d1ca1a1a7ea0ee81f Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Mon, 14 Jan 2019 11:03:03 +0800
Subject: [PATCH 017/122] isulad: check cgroup cpu.shares after setted
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,410 @@
From d6a38c35cb5986f1263e3dd1b6206217e34a2ec8 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Mon, 14 Jan 2019 02:18:26 -0500
Subject: [PATCH 018/122] lxc-attach: add support terminal fifos
1. support terminal fifos to redirect terminal
2. support lxc-attach run in background
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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(-)
diff --git a/src/lxc/attach.c b/src/lxc/attach.c
index 2bbf1eb..1886bde 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,
}
if (pid == 0) {
- if (options->attach_flags & LXC_ATTACH_TERMINAL) {
+ if (options->attach_flags & LXC_ATTACH_TERMINAL && terminal.tty_state) {
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
--- a/src/lxc/attach_options.h
+++ b/src/lxc/attach_options.h
@@ -135,6 +135,8 @@ typedef struct lxc_attach_options_t {
/*! File descriptor to log output. */
int log_fd;
+
+ char *init_fifo[2]; /* isulad: default fifos for the start */
} lxc_attach_options_t;
/*! Default attach options to use */
@@ -153,6 +155,7 @@ typedef struct lxc_attach_options_t {
/* .stdout_fd = */ 1, \
/* .stderr_fd = */ 2, \
/* .log_fd = */ -EBADF, \
+ /* .init_fifo = */ {NULL, NULL}, \
}
/*!
diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c
index 7aa4730..ee3aef2 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;
if (terminal->path)
path = terminal->path;
- else
- path = "/dev/tty";
+
+ /* isulad: if no console was given, try current controlling terminal, there
+ * won't be one if we were started as a daemon (-d)
+ */
+ if (!path && !access("/dev/tty", F_OK)) {
+ int fd;
+ fd = open("/dev/tty", O_RDWR);
+ if (fd >= 0) {
+ close(fd);
+ path = "/dev/tty";
+ }
+ }
+
+ if (!path) {
+ DEBUG("Not have a controlling terminal");
+ return 0;
+ }
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)
if (ret < 0)
return -1;
- ret = lxc_terminal_set_stdfds(fd);
+ ret = set_stdfds(fd);
if (ret < 0)
return -1;
diff --git a/src/lxc/tools/arguments.h b/src/lxc/tools/arguments.h
index 61f4a0a..047e9f1 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 */
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 */
diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c
index 8c8e7d3..6d0ffe5 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'},
{"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},
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;
break;
+ case OPT_INPUT_FIFO:
+ args->terminal_fifos[0] = arg;
+ break;
+ case OPT_OUTPUT_FIFO:
+ args->terminal_fifos[1] = arg;
+ break;
}
return 0;
@@ -253,10 +264,143 @@ static int lxc_attach_create_log_file(const char *log_file)
return fd;
}
+/*isulad: attach with terminal*/
+static int do_attach_foreground(struct lxc_container *c, lxc_attach_command_t *command,
+ lxc_attach_options_t *attach_options,
+ char **errmsg)
+{
+ int ret = 0;
+ pid_t pid;
+ int wexit = -1;
+ int signal;
+
+ if (command->program)
+ ret = c->attach(c, lxc_attach_run_command, command, attach_options, &pid);
+ else
+ ret = c->attach(c, lxc_attach_run_shell, NULL, attach_options, &pid);
+ if (ret < 0)
+ goto out;
+
+ ret = lxc_wait_for_pid_status(pid);
+ if (ret < 0)
+ goto out;
+
+ if (WIFEXITED(ret))
+ wexit = WEXITSTATUS(ret);
+ else
+ wexit = -1;
+
+ if (WIFSIGNALED(ret)) {
+ signal = WTERMSIG(ret);
+ wexit = ExitSignalOffset + signal;
+ }
+out:
+ //if (c->lxc_conf->errmsg)
+ // *errmsg = strdup(c->lxc_conf->errmsg);
+ return wexit;
+}
+
+static void close_msg_pipe(int *errpipe)
+{
+ if (errpipe[0] >= 0) {
+ close(errpipe[0]);
+ errpipe[0] = -1;
+ }
+ if (errpipe[1] >= 0) {
+ close(errpipe[1]);
+ errpipe[1] = -1;
+ }
+}
+
+/*isulad: attach without terminal in background */
+static int do_attach_background(struct lxc_container *c, lxc_attach_command_t *command,
+ lxc_attach_options_t *attach_options,
+ char **errmsg)
+{
+ int ret = 0;
+ int msgpipe[2];
+ pid_t pid = 0;
+ ssize_t size_read;
+ char msgbuf[BUFSIZ + 1] = {0};
+
+ //pipdfd for get error message of child or grandchild process.
+ if (pipe2(msgpipe, O_CLOEXEC) != 0) {
+ SYSERROR("Failed to init msgpipe");
+ return -1;
+ }
+
+ pid = fork();
+ if (pid < 0) {
+ close_msg_pipe(msgpipe);
+ return -1;
+ }
+
+ if (pid != 0) {
+ close(msgpipe[1]);
+ msgpipe[1] = -1;
+ size_read = read(msgpipe[0], msgbuf, BUFSIZ);
+ if (size_read > 0) {
+ *errmsg = strdup(msgbuf);
+ ret = -1;
+ }
+
+ close(msgpipe[0]);
+ msgpipe[0] = -1;
+
+ return ret;
+ }
+
+ /* second fork to be reparented by init */
+ pid = fork();
+ if (pid < 0) {
+ SYSERROR("Error doing dual-fork");
+ close_msg_pipe(msgpipe);
+ exit(1);
+ }
+ if (pid != 0) {
+ close_msg_pipe(msgpipe);
+ exit(0);
+ }
+
+ close(msgpipe[0]);
+ msgpipe[0] = -1;
+
+ if (null_stdfds() < 0) {
+ ERROR("failed to close fds");
+ exit(1);
+ }
+ setsid();
+
+ if (command->program)
+ ret = c->attach(c, lxc_attach_run_command, command, attach_options, &pid);
+ 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);
+ close(msgpipe[1]);
+ msgpipe[1] = -1;
+ ret = -1;
+ goto out;
+ }
+
+ close(msgpipe[1]);
+ msgpipe[1] = -1;
+
+ ret = wait_for_pid(pid);
+out:
+ lxc_container_put(c);
+ if (ret)
+ exit(EXIT_FAILURE);
+ else
+ exit(0);
+}
+
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;
@@ -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]) {
+ attach_options.init_fifo[0] = my_args.terminal_fifos[0];
+ attach_options.init_fifo[1] = my_args.terminal_fifos[1];
+ attach_options.attach_flags |= LXC_ATTACH_TERMINAL;
+ } else if (stdfd_is_pty()) {
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;
+ 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);
+ /* 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;
+ 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)
+ if (wexit >= 0)
exit(wexit);
exit(EXIT_FAILURE);
--
1.8.3.1

View File

@ -0,0 +1,87 @@
From bd056022ef54a8dc6a859495f0edde96471bd7e5 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Mon, 14 Jan 2019 13:51:01 +0800
Subject: [PATCH 019/122] remount cgroup readonly and make soft link of
subcgroup
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,44 @@
From ab9da60c84c2b37049e514d7a597fc8747dbc52f Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Mon, 14 Jan 2019 15:33:12 +0800
Subject: [PATCH 020/122] fix log error when symlink subcgroup
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,374 @@
From 54f592ec7a2a79b7e5ecdec5b9bf484536e90438 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Mon, 14 Jan 2019 04:29:40 -0500
Subject: [PATCH 021/122] lxc-attch: add error message
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,507 @@
From daa98c9452fcebe022bd6dcad29633719ef6917e Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Mon, 14 Jan 2019 17:02:02 +0800
Subject: [PATCH 022/122] support rootfs mount propagation
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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(-)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 8d8230f..55d1e45 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)
return 0;
}
+static void null_endofword(char *word)
+{
+ while (*word && *word != ' ' && *word != '\t')
+ word++;
+ *word = '\0';
+}
+
+/* skip @nfields spaces in @src */
+static char *get_field(char *src, int nfields)
+{
+ int i;
+ char *p = src;
+
+ for (i = 0; i < nfields; i++) {
+ while (*p && *p != ' ' && *p != '\t')
+ p++;
+
+ if (!*p)
+ break;
+
+ p++;
+ }
+
+ return p;
+}
+
+static int rootfs_parent_mount_private(char *rootfs)
+{
+ /* walk /proc/self/mountinfo and change parent of rootfs to private */
+ FILE *f = fopen("/proc/self/mountinfo", "r");
+ char *line = NULL;
+ char *parent = NULL, *options = NULL;
+ size_t len = 0;
+ int ret = 0;
+
+ if (!f) {
+ SYSERROR("Failed to open /proc/self/mountinfo to make parent of rootfs to private");
+ return -1;
+ }
+
+ while (getline(&line, &len, f) != -1) {
+ char *target, *opts, *tmptarget;
+ target = get_field(line, 4);
+ if (!target)
+ continue;
+ tmptarget = strdup(target);
+ if (!tmptarget)
+ continue;
+ null_endofword(tmptarget);
+ if (!strstr(rootfs, tmptarget)) {
+ free(tmptarget);
+ continue;
+ }
+ if (!parent || strlen(tmptarget) > strlen(parent)) {
+ free(parent);
+ parent = tmptarget;
+ } else {
+ free(tmptarget);
+ continue;
+ }
+ opts = get_field(target, 2);
+ if (!opts)
+ continue;
+ null_endofword(opts);
+ free(options);
+ options = strdup(opts);
+ if (!options)
+ continue;
+ }
+
+ if (!parent || !options) {
+ ERROR("Could not find parent mount of %s", rootfs);
+ ret = -1;
+ } else {
+ if (strstr(options, "shared")) {
+ if (mount(NULL, parent, NULL, MS_PRIVATE, NULL)) {
+ SYSERROR("Failed to make %s private", parent);
+ ret = -1;
+ }
+ DEBUG("Mounted parent %s of rootfs %s to private", parent, rootfs);
+ }
+ }
+ free(parent);
+ free(options);
+ fclose(f);
+ free(line);
+ return ret;
+}
+
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;
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 (parse_mntopts(conf->rootfs.options, &mntflags, &pflags, &mntdata) < 0) {
+ free(mntdata);
+ return -1;
+ }
+ free(mntdata);
+
+ flags = MS_SLAVE | MS_REC;
+ if (pflags)
+ flags = pflags;
+
+ /* Mount propagation inside container can not greater than host.
+ * So we must change propagation of root according to flags, default is rslave.
+ * That means shared propagation inside container is disabled by default.
+ */
+ ret = mount("", "/", NULL, flags, NULL);
+ if (ret < 0) {
+ SYSERROR("Failed to make / to propagation flags %lu.", flags);
+ return -1;
+ }
+
+ /* Make parent mount private to make sure following bind mount does
+ * not propagate in other namespaces. Also it will help with kernel
+ * check pass in pivot_root. (IS_SHARED(new_mnt->mnt_parent))
+ */
+ 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;
+ }
+
+ 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
+
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,
return lxc_setup_ttydir_console(rootfs, console, ttydir);
}
-static void parse_mntopt(char *opt, unsigned long *flags, char **data, size_t size)
+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;
+ *mflags &= ~mo->flag;
else
- *flags |= mo->flag;
+ *mflags |= mo->flag;
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)
+ continue;
+
+ if (mo->clear)
+ *pflags &= ~mo->flag;
+ else
+ *pflags |= mo->flag;
+
+ return;
+ }
+
if (strlen(*data))
(void)strlcat(*data, ",", size);
(void)strlcat(*data, opt, size);
}
-int parse_mntopts(const char *mntopts, unsigned long *mntflags, char **mntdata)
+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;
+ *pflags = 0L;
if (!mntopts)
return 0;
@@ -2007,7 +2150,7 @@ int parse_mntopts(const char *mntopts, unsigned long *mntflags, char **mntdata)
*data = 0;
lxc_iterate_parts(p, s, ",")
- parse_mntopt(p, mntflags, &data, size);
+ parse_mntopt(p, mntflags, pflags, &data, size);
if (*data)
*mntdata = data;
@@ -2018,71 +2161,6 @@ int parse_mntopts(const char *mntopts, unsigned long *mntflags, char **mntdata)
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')
- word++;
- *word = '\0';
-}
-
-/* skip @nfields spaces in @src */
-static char *get_field(char *src, int nfields)
-{
- int i;
- char *p = src;
-
- for (i = 0; i < nfields; i++) {
- while (*p && *p != ' ' && *p != '\t')
- p++;
-
- if (!*p)
- break;
-
- p++;
- }
-
- return 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,
@@ -2289,10 +2367,9 @@ static inline int mount_entry_on_generic(struct mntent *mntent,
const char *lxc_path)
{
int ret;
- unsigned long mntflags;
+ unsigned long mntflags, pflags;
char *mntdata;
bool dev, optional, relative;
- unsigned long pflags = 0;
char *rootfs_path = NULL;
optional = hasmntopt(mntent, "optional") != NULL;
@@ -2312,11 +2389,7 @@ 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);
+ ret = parse_mntopts(mntent->mnt_opts, &mntflags, &pflags, &mntdata);
if (ret < 0)
return -1;
@@ -3544,7 +3617,8 @@ int lxc_setup_rootfs_prepare_root(struct lxc_conf *conf, const char *name,
return 0;
}
- remount_all_slave();
+ if (!conf->rootfs.options)
+ remount_all_slave();
ret = run_lxc_hooks(name, "pre-mount", conf, NULL);
if (ret < 0) {
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index db474e1..7393dbf 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,
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,
- 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);
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index e199965..db63b55 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;
struct lxc_rootfs *rootfs = &lxc_conf->rootfs;
- ret = parse_mntopts(value, &mflags, &mdata);
+ ret = parse_mntopts(value, &mflags, &pflags, &mdata);
if (ret < 0)
return -EINVAL;
- 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
--- 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;
char arg[2 * PATH_MAX + 2];
- unsigned long flags;
+ unsigned long flags, pflags;
- if (parse_mntopts(mntent.mnt_opts, &flags, &mntdata) < 0)
+ if (parse_mntopts(mntent.mnt_opts, &flags, &pflags, &mntdata) < 0)
goto err;
free(mntdata);
diff --git a/src/lxc/storage/btrfs.c b/src/lxc/storage/btrfs.c
index bbfce61..a02c215 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;
const char *src;
int ret;
@@ -223,7 +223,7 @@ int btrfs_mount(struct lxc_storage *bdev)
if (!bdev->src || !bdev->dest)
return -22;
- if (parse_mntopts(bdev->mntopts, &mntflags, &mntdata) < 0) {
+ if (parse_mntopts(bdev->mntopts, &mntflags, &pflags, &mntdata) < 0) {
free(mntdata);
return -22;
}
diff --git a/src/lxc/storage/dir.c b/src/lxc/storage/dir.c
index 79b6469..c7b5ee2 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;
- ret = parse_mntopts(bdev->mntopts, &mntflags, &mntdata);
+ ret = parse_mntopts(bdev->mntopts, &mntflags, &pflags, &mntdata);
if (ret < 0) {
ERROR("Failed to parse mount options \"%s\"", bdev->mntopts);
free(mntdata);
return -EINVAL;
}
- 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);
ret = mount(src, bdev->dest, "bind", MS_BIND | MS_REC | mntflags | pflags, mntdata);
diff --git a/src/lxc/storage/overlay.c b/src/lxc/storage/overlay.c
index 01546b1..90408a3 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;
size_t len, len2;
- unsigned long mntflags;
+ unsigned long mntflags, pflags;
char *mntdata;
int ret, ret2;
@@ -575,7 +575,7 @@ int ovl_mount(struct lxc_storage *bdev)
memcpy(work + lastslashidx, "olwork", STRLITERALLEN("olwork"));
work[lastslashidx + STRLITERALLEN("olwork")] = '\0';
- ret = parse_mntopts(bdev->mntopts, &mntflags, &mntdata);
+ ret = parse_mntopts(bdev->mntopts, &mntflags, &pflags, &mntdata);
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
--- 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;
@@ -411,7 +411,7 @@ 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) {
+ if (parse_mntopts(cbarg->options, &mntflags, &pflags, &mntdata) < 0) {
free(mntdata);
return 0;
}
diff --git a/src/lxc/storage/zfs.c b/src/lxc/storage/zfs.c
index ba104da..752b0c5 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;
const char *src;
- unsigned long mntflags;
+ unsigned long mntflags, pflags;
char cmd_output[PATH_MAX] = {0};
if (strcmp(bdev->type, "zfs"))
@@ -193,7 +193,7 @@ int zfs_mount(struct lxc_storage *bdev)
if (!bdev->src || !bdev->dest)
return -22;
- ret = parse_mntopts(bdev->mntopts, &mntflags, &mntdata);
+ ret = parse_mntopts(bdev->mntopts, &mntflags, &pflags, &mntdata);
if (ret < 0) {
ERROR("Failed to parse mount options");
free(mntdata);
--
1.8.3.1

View File

@ -0,0 +1,31 @@
From 37203bfbe3ff71fb158175bb436e0748e84415ef Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Mon, 14 Jan 2019 17:09:57 +0800
Subject: [PATCH 023/122] attach.c: change uid and gid from lxc container
config
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,821 @@
From 205213bbf95886772aa0b8974507741d5012dd45 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Mon, 14 Jan 2019 20:12:06 +0800
Subject: [PATCH 024/122] isulad: support symlink in mount entry, and not
permit mount to /proc
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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 <unistd.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <libgen.h>
+
+#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 <stdbool.h>
+
+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

3087
0025-support-oci-hooks.patch Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,132 @@
From 693b1ab25741606299037bc660387a5d109f238c Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Mon, 14 Jan 2019 21:13:00 +0800
Subject: [PATCH 026/122] remove filelock and do not destroy directory when
destroy container
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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(-)
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 68134d8..81c0ec3 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -2996,8 +2996,14 @@ static bool container_destroy(struct lxc_container *c,
bool bret = false;
int ret = 0;
- if (!c || !do_lxcapi_is_defined(c))
+ if (!c)
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;
+ }
conf = c->lxc_conf;
if (container_disk_lock(c))
@@ -3124,12 +3130,16 @@ out:
free(path);
container_disk_unlock(c);
+ if (bret) {
+ if (container_disk_removelock(c))
+ bret = false;
+ }
return bret;
}
static bool do_lxcapi_destroy(struct lxc_container *c)
{
- if (!c || !lxcapi_is_defined(c))
+ if (!c)
return false;
if (has_snapshots(c)) {
diff --git a/src/lxc/lxclock.c b/src/lxc/lxclock.c
index e3d4654..8890968 100644
--- a/src/lxc/lxclock.c
+++ b/src/lxc/lxclock.c
@@ -198,6 +198,21 @@ on_error:
return l;
}
+static int lxc_removelock(struct lxc_lock *l)
+{
+ int ret = 0;
+
+ if (l->type == LXC_LOCK_FLOCK) {
+ ret = unlink(l->u.f.fname);
+ if (ret && errno != ENOENT) {
+ SYSERROR("Error unlink %s", l->u.f.fname);
+ return ret;
+ }
+ }
+
+ 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)
+{
+ int ret;
+
+ ret = lxc_removelock(c->slock);
+ if (ret)
+ return ret;
+ return lxc_removelock(c->privlock);
+}
diff --git a/src/lxc/lxclock.h b/src/lxc/lxclock.h
index 364a71b..e86bc34 100644
--- a/src/lxc/lxclock.h
+++ b/src/lxc/lxclock.h
@@ -174,4 +174,9 @@ 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.
+ */
+int container_disk_removelock(struct lxc_container *c);
+
#endif
diff --git a/src/lxc/storage/dir.c b/src/lxc/storage/dir.c
index c7b5ee2..deeecec 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,
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;
- }
-
+ // isulad: do not destroy rootfs for directory, it should be managed by caller
return 0;
}
--
1.8.3.1

View File

@ -0,0 +1,78 @@
From 4f4a8726feb02b846d9602feac517fc4dfbe1ede Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Mon, 14 Jan 2019 21:24:25 +0800
Subject: [PATCH 027/122] fix bug of memory leak
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,123 @@
From 53fa77bebc3e896396036cb3a482f75f138da788 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Tue, 15 Jan 2019 09:45:44 +0800
Subject: [PATCH 028/122] support rootfs / for container
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,436 @@
From 96dc86e154cd49f9a999409e4fb679ed78e16af6 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Mon, 14 Jan 2019 21:38:07 -0500
Subject: [PATCH 029/122] add start timeout to limit start time
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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(-)
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/execute.c b/src/lxc/execute.c
index 45ca67e..d388e63 100644
--- a/src/lxc/execute.c
+++ b/src/lxc/execute.c
@@ -111,12 +111,12 @@ static struct lxc_operations execute_start_ops = {
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)
{
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);
+ daemonize, error_num, start_timeout);
}
diff --git a/src/lxc/lxc.h b/src/lxc/lxc.h
index 22e3509..687b4b2 100644
--- a/src/lxc/lxc.h
+++ b/src/lxc/lxc.h
@@ -55,7 +55,7 @@ struct lxc_handler;
*/
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);
/*
* Start the specified command inside an application container
@@ -66,9 +66,9 @@ extern int lxc_start(const char *name, char *const argv[],
* @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);
/*
* Close the fd associated with the monitoring
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index e6272fc..beae459 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -1169,10 +1169,10 @@ reboot:
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);
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 *)
+/* isulad add start timeout */
+static bool do_lxcapi_set_start_timeout(struct lxc_container *c, unsigned int start_timeout)
+{
+ if (!c || !c->lxc_conf)
+ return false;
+ if (container_mem_lock(c)) {
+ ERROR("Error getting mem lock");
+ return false;
+ }
+ c->start_timeout = start_timeout;
+ container_mem_unlock(c);
+ return true;
+}
+
+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;
+ c->set_start_timeout = lxcapi_set_start_timeout;
/* isulad add end */
return c;
diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h
index 5d23cc7..77de704 100644
--- a/src/lxc/lxccontainer.h
+++ b/src/lxc/lxccontainer.h
@@ -94,6 +94,12 @@ struct lxc_container {
*/
char *exit_fifo;
+ /*! isulad:
+ * \private
+ * start_timeout.
+ */
+ unsigned int start_timeout;
+
/*!
* \private
* Container semaphore lock.
@@ -880,6 +886,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);
+
+ /*! isulad add
+ * \brief An API call to set start timeout
+ *
+ * \param c Container.
+ * \param start_timeout Value of start timeout.
+ *
+ * \return \c true on success, else \c false.
+ */
+ bool (*set_start_timeout)(struct lxc_container *c, unsigned int start_timeout);
};
/*!
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 63f5af8..f7be9e4 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);
+
+/* isulad: start timeout thread */
+typedef enum {
+ START_INIT,
+ START_TIMEOUT,
+ START_MAX,
+} start_timeout_t;
+
+static start_timeout_t global_timeout_state = START_INIT;
+static sem_t global_timeout_sem;
+
+struct start_timeout_conf {
+ unsigned int timeout;
+ int errfd;
+};
static void print_top_failing_dir(const char *path)
{
@@ -1897,6 +1912,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);
+ 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) {
ERROR("Failed to run oci poststart hooks");
- goto out_delete_net;
+ goto out_abort;
+ }
+
+ if (START_TIMEOUT == global_timeout_state) {
+ //lxc_write_error_message(conf->errpipe[1], "Starting the container \"%s\" timeout.", name);
+ ERROR("Starting the container \"%s\" timeout.", name);
+ goto out_abort;
}
ret = lxc_set_state(name, handler, RUNNING);
@@ -1964,12 +1991,71 @@ out_abort:
return -1;
}
+/* isulad: start timeout thread function */
+static void* wait_start_timeout(void *arg)
+{
+ struct start_timeout_conf *conf = (struct start_timeout_conf *)arg;
+
+ sem_post(&global_timeout_sem);
+
+ if (!conf || conf->timeout < 1)
+ goto out;
+
+ sleep(conf->timeout);
+
+ global_timeout_state = START_TIMEOUT;
+
+out:
+ free(conf);
+ return ((void *)0);
+}
+
+/* isulad: create start timeout thread */
+static int create_start_timeout_thread(struct lxc_conf *conf, unsigned int start_timeout)
+{
+ int ret = 0;
+ pthread_t ptid;
+ pthread_attr_t attr;
+ struct start_timeout_conf *timeout_conf = NULL;
+
+ if (sem_init(&global_timeout_sem, 0, 0)) {
+ ERROR("Failed to init start timeout semaphore");/*lint !e613*/
+ ret = -1;
+ return ret;
+ }
+
+ timeout_conf = malloc(sizeof(struct start_timeout_conf));
+ if (!timeout_conf) {
+ ERROR("Failed to malloc start timeout conf");
+ ret = -1;
+ goto out;
+ }
+
+ memset(timeout_conf, 0, sizeof(struct start_timeout_conf));
+ timeout_conf->errfd = conf->errpipe[1];
+ timeout_conf->timeout = start_timeout;
+
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ ret = pthread_create(&ptid, &attr, wait_start_timeout, timeout_conf);
+ if (ret != 0) {
+ ERROR("Create start wait timeout thread failed");
+ free(timeout_conf);
+ goto out;
+ }
+
+ sem_wait(&global_timeout_sem);
+out:
+ sem_destroy(&global_timeout_sem);
+ return ret;
+}
+
// isulad: send '128 + signal' if container is killed by signal.
#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)
+ bool daemonize, int *error_num, unsigned int start_timeout)
{
int ret, status, exit_code;
struct lxc_conf *conf = handler->conf;
@@ -1983,8 +2069,18 @@ int __lxc_start(const char *name, struct lxc_handler *handler,
handler->data = data;
handler->daemonize = daemonize;
+ /* 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;
+ }
+ }
+
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 = {
};
int lxc_start(const char *name, 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)
{
struct start_args start_arg = {
.argv = argv,
};
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);
}
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
--- 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);
*/
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,
+ struct lxc_operations* ops, void *data, const char *lxcpath,
+ bool daemonize, int *error_num, unsigned int start_timeout);
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
--- 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 */
+ unsigned int start_timeout; /* isulad: Seconds for waiting on a container to start before it is killed*/
/* 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_start.c b/src/lxc/tools/lxc_start.c
index 60c7d70..f37f8a6 100644
--- a/src/lxc/tools/lxc_start.c
+++ b/src/lxc/tools/lxc_start.c
@@ -40,6 +40,7 @@
#include <sys/types.h>
#include <sys/utsname.h>
#include <unistd.h>
+#include <ctype.h>
#include <lxc/lxccontainer.h>
@@ -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},
+ {"start-timeout", required_argument, 0, OPT_START_TIMEOUT},
/* isulad add end */
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;
break;
+ case OPT_START_TIMEOUT:
+ if(!is_non_negative_num(arg)) {
+ fprintf(stderr, "Error start timeout parameter:%s.\n", arg);
+ return -1;
+ }
+ args->start_timeout = (unsigned int)atoi(arg);
+ break;
}
return 0;
}
@@ -341,6 +362,11 @@ int main(int argc, char *argv[])
c->exit_fifo = strdup(my_args.exit_monitor_fifo);
}
+ /* isulad: add start timeout */
+ if(my_args.start_timeout) {
+ c->set_start_timeout(c, my_args.start_timeout);
+ }
+
if (my_args.console)
if (!c->set_config_item(c, "lxc.console.path", my_args.console))
goto out;
--
1.8.3.1

View File

@ -0,0 +1,287 @@
From 3d30577047030ebf63101324509f1d1ecfb837b8 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Tue, 15 Jan 2019 16:00:30 +0800
Subject: [PATCH 030/122] support block device as rootfs
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
src/lxc/Makefile.am | 1 +
src/lxc/conf.c | 10 ++---
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(-)
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
--- a/src/lxc/Makefile.am
+++ b/src/lxc/Makefile.am
@@ -130,6 +130,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 \
+ storage/block.c storage/block.h \
storage/loop.c storage/loop.h \
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
--- 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;
+ 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)
+ if(!rootfs || !rootfs->options)
return 0;
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);
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;
}
diff --git a/src/lxc/storage/block.c b/src/lxc/storage/block.c
new file mode 100644
index 0000000..eb75e70
--- /dev/null
+++ b/src/lxc/storage/block.c
@@ -0,0 +1,86 @@
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2008
+ *
+ * Authors:
+ * Daniel Lezcano <daniel.lezcano at free.fr>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 <stdint.h>
+#include <string.h>
+
+#include "config.h"
+#include "log.h"
+#include "storage.h"
+#include "storage_utils.h"
+#include "utils.h"
+
+lxc_log_define(blk, lxc);
+
+int blk_destroy(struct lxc_storage *orig)
+{
+ return 0;
+}
+
+bool blk_detect(const char *path)
+{
+ struct stat statbuf;
+ int ret;
+
+ if (!strncmp(path, "blk:", 4))
+ return true;
+
+ ret = stat(path, &statbuf);
+ if (ret == -1 && errno == EPERM) {
+ SYSERROR("blk_detect: failed to look at \"%s\"", path);
+ return false;
+ }
+
+ if (ret == 0 && S_ISBLK(statbuf.st_mode))
+ return true;
+
+ return false;
+}
+
+int blk_mount(struct lxc_storage *bdev)
+{
+ const char *src;
+ if (strcmp(bdev->type, "blk"))
+ return -22;
+
+ if (!bdev->src || !bdev->dest)
+ return -22;
+
+ src = lxc_storage_get_path(bdev->src, bdev->type);
+
+ return mount_unknown_fs(src, bdev->dest, bdev->mntopts);
+}
+
+int blk_umount(struct lxc_storage *bdev)
+{
+ if (strcmp(bdev->type, "blk"))
+ return -22;
+
+ if (!bdev->src || !bdev->dest)
+ return -22;
+
+ return umount(bdev->dest);
+}
diff --git a/src/lxc/storage/block.h b/src/lxc/storage/block.h
new file mode 100644
index 0000000..2fa7565
--- /dev/null
+++ b/src/lxc/storage/block.h
@@ -0,0 +1,41 @@
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2008
+ *
+ * Authors:
+ * Daniel Lezcano <daniel.lezcano at free.fr>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __LXC_BLK_H
+#define __LXC_BLK_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+struct lxc_storage;
+
+struct bdev_specs;
+
+struct lxc_conf;
+
+extern int blk_destroy(struct lxc_storage *orig);
+extern bool blk_detect(const char *path);
+extern int blk_mount(struct lxc_storage *bdev);
+extern int blk_umount(struct lxc_storage *bdev);
+
+#endif /* __LXC_BLK_H */
diff --git a/src/lxc/storage/dir.c b/src/lxc/storage/dir.c
index deeecec..2b548d0 100644
--- a/src/lxc/storage/dir.c
+++ b/src/lxc/storage/dir.c
@@ -150,7 +150,7 @@ bool dir_detect(const char *path)
int dir_mount(struct lxc_storage *bdev)
{
int ret;
- unsigned long mflags = 0, mntflags = 0, pflags = 0;
+ unsigned long mntflags = 0, pflags = 0;
char *mntdata;
const char *src;
@@ -169,13 +169,7 @@ 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);
- }
+ ret = mount(src, bdev->dest, "bind", MS_BIND | MS_REC | (mntflags & ~MS_RDONLY) | pflags, mntdata);
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
--- a/src/lxc/storage/storage.c
+++ b/src/lxc/storage/storage.c
@@ -61,6 +61,7 @@
#include "storage_utils.h"
#include "utils.h"
#include "zfs.h"
+#include "block.h"
#ifndef HAVE_STRLCPY
#include "include/strlcpy.h"
@@ -114,6 +115,21 @@ static const struct lxc_storage_ops loop_ops = {
.can_backup = true,
};
+/* block */
+static const struct lxc_storage_ops blk_ops = {
+ .detect = &blk_detect,
+ .mount = &blk_mount,
+ .umount = &blk_umount,
+ .clone_paths = NULL,
+ .destroy = &blk_destroy,
+ .create = NULL,
+ .copy = NULL,
+ .snapshot = NULL,
+ .can_snapshot = false,
+ .can_backup = true,
+};
+
+
/* lvm */
static const struct lxc_storage_ops lvm_ops = {
.detect = &lvm_detect,
@@ -199,6 +215,8 @@ static const struct lxc_storage_type bdevs[] = {
{ .name = "overlayfs", .ops = &ovl_ops, },
{ .name = "loop", .ops = &loop_ops, },
{ .name = "nbd", .ops = &nbd_ops, },
+ //isulad: block device
+ { .name = "blk", .ops = &blk_ops, }
};
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
--- 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)
return 0;
}
- if (mount(cbarg->rootfs, cbarg->target, fstype, mntflags, mntdata)) {
+ if (mount(cbarg->rootfs, cbarg->target, fstype, (mntflags & ~MS_RDONLY), mntdata)) {
SYSDEBUG("Failed to mount");
free(mntdata);
return 0;
--
1.8.3.1

View File

@ -0,0 +1,488 @@
From 37d787b93122a6b61d99a3d71f6101f405031a95 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Tue, 15 Jan 2019 04:20:57 -0500
Subject: [PATCH 031/122] clean: add clean resources api
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,33 @@
From 37c5a4630e798ff4a24f1336560c41b2b8fec01b Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Tue, 15 Jan 2019 05:39:39 -0500
Subject: [PATCH 032/122] Drop all caps when cap.keep=ISULAD_KEEP_NONE
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,369 @@
From e7f83b7c8b21942051e86e094d867cc79ff93524 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Tue, 15 Jan 2019 19:54:13 +0800
Subject: [PATCH 033/122] support mount squashfs in mount entry
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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/utils.h | 1 +
5 files changed, 181 insertions(+), 13 deletions(-)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 54b967b..fea0f59 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -78,6 +78,7 @@
#include "storage/overlay.h"
#include "syscall_wrappers.h"
#include "terminal.h"
+#include "loop.h"
#include "path.h"
#include "utils.h"
@@ -2444,6 +2445,82 @@ static int mount_entry_create_dir_file(const struct mntent *mntent,
return 0;
}
+static int mount_entry_with_loop_dev(const char *src, const char *dest, const char *fstype,
+ 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/<fd>
+ const char *mntsrc = src;
+ int max_retry = 5;
+ struct lxc_storage loop;
+
+ if (!rootfs)
+ rootfs = "";
+
+ /* todo - allow symlinks for relative paths if 'allowsymlinks' option is passed */
+ if (src && src[0] != '/') {
+ INFO("this is a relative mount");
+ srcfd = open_without_symlink(src, NULL);
+ if (srcfd < 0)
+ return srcfd;
+ ret = snprintf(srcbuf, sizeof(srcbuf), "/proc/self/fd/%d", srcfd);
+ if (ret < 0 || ret > sizeof(srcbuf)) {
+ close(srcfd);
+ ERROR("Failed to print string");
+ return -EINVAL;
+ }
+ mntsrc = srcbuf;
+ }
+
+ destfd = open_without_symlink(dest, rootfs);
+ if (destfd < 0) {
+ if (srcfd != -1) {
+ saved_errno = errno;
+ close(srcfd);
+ errno = saved_errno;
+ }
+ return destfd;
+ }
+
+ ret = snprintf(destbuf, sizeof(destbuf), "/proc/self/fd/%d", destfd);
+ if (ret < 0 || ret > sizeof(destbuf)) {
+ if (srcfd != -1)
+ close(srcfd);
+ close(destfd);
+ ERROR("Out of memory");
+ return -EINVAL;
+ }
+
+retry:
+ loop.src = (char *)mntsrc;
+ loop.dest = destbuf;
+ loop.mntopts = mnt_opts;
+ loop.type = "loop";
+ loop.lofd = -1;
+ ret = loop_mount(&loop);
+ if (ret < 0) {
+ /* If loop is used by other program, mount may fail. So
+ * we do retry to ensure mount ok */
+ if (max_retry > 0) {
+ max_retry--;
+ DEBUG("mount entry with loop dev failed, retry mount."
+ "retry count left %d", max_retry);
+ goto retry;
+ }
+ }
+ if (loop.lofd != -1)
+ close(loop.lofd);
+ if (srcfd != -1)
+ close(srcfd);
+ close(destfd);
+ if (ret < 0) {
+ SYSERROR("Failed to mount %s onto %s", src, dest);
+ return ret;
+ }
+
+ return 0;
+}
+
/* 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;
}
- ret = mount_entry(mntent->mnt_fsname, dest, mntent->mnt_type, mntflags,
- pflags, mntdata, optional, dev, relative, rootfs_path);
+ // 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;
}
-
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
--- a/src/lxc/storage/loop.c
+++ b/src/lxc/storage/loop.c
@@ -41,6 +41,7 @@
#include "loop.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)
int loop_mount(struct lxc_storage *bdev)
{
- int ret, loopfd;
+ int ret = 0;
+ int loopfd, lret;
char loname[PATH_MAX];
const char *src;
+ struct lxc_lock *l = NULL;
if (strcmp(bdev->type, "loop"))
return -22;
@@ -246,13 +249,29 @@ int loop_mount(struct lxc_storage *bdev)
if (!bdev->src || !bdev->dest)
return -22;
+ /* isulad: do lock before mount, so we can avoid use loop which is used by
+ * other starting contianers */
+ l = lxc_newlock("mount_lock", "mount_lock");
+ if (!l) {
+ SYSERROR("create file lock error when mount fs");
+ return -1;
+ }
+
+ lret = lxclock(l, 0);
+ if (lret) {
+ SYSERROR("try to lock failed when mount fs");
+ ret = -1;
+ goto out;
+ }
+
/* skip prefix */
src = lxc_storage_get_path(bdev->src, bdev->type);
loopfd = lxc_prepare_loop_dev(src, loname, LO_FLAGS_AUTOCLEAR);
if (loopfd < 0) {
ERROR("Failed to prepare loop device for loop file \"%s\"", src);
- return -1;
+ ret = -1;
+ goto out;
}
DEBUG("Prepared loop device \"%s\"", loname);
@@ -261,14 +280,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);
- return -1;
+ ret = -1;
+ goto out;
}
bdev->lofd = loopfd;
DEBUG("Mounted rootfs \"%s\" on \"%s\" via loop device \"%s\"",
bdev->src, bdev->dest, loname);
-
- return 0;
+out:
+ lret = lxcunlock(l);
+ if (lret) {
+ SYSERROR("try to unlock failed when mount fs");
+ ret = -1;
+ }
+ lxc_putlock(l);
+ return ret;
}
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
--- 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)
return 0;
}
+// isulad: recored error
+static char **mount_errors = NULL;
+
int mount_unknown_fs(const char *rootfs, const char *target,
const char *options)
{
size_t i;
+ char *errs = NULL;
int ret;
struct cbarg {
const char *rootfs;
@@ -371,15 +375,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]);
+ lxc_free_array((void**)mount_errors, free);
+ mount_errors = NULL;
return -1;
}
- if (ret)
+ if (ret) {
+ lxc_free_array((void**)mount_errors, free);
+ mount_errors = NULL;
return 0;
+ }
+ }
+
+ if (mount_errors != NULL) {
+ errs = lxc_string_join("\n", (const char **)mount_errors, false);
+ if (errs == NULL) {
+ ERROR("failed to join mount errors");
+ }
}
- ERROR("Failed to determine FSType for \"%s\"", rootfs);
+ ERROR("Failed to determine FSType for \"%s\": %s", rootfs, errs ? errs : "unknown reason");
+ free(errs);
+ lxc_free_array((void**)mount_errors, free);
+ mount_errors = NULL;
return -1;
}
@@ -399,6 +418,8 @@ int find_fstype_cb(char *buffer, void *data)
unsigned long mntflags, pflags;
char *mntdata;
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)) {
SYSDEBUG("Failed to mount");
free(mntdata);
+ // isulad: recored error
+ ret = snprintf(mount_err, BUFSIZ, "\t\tmount %s onto %s with FSType %s failed: %s",
+ cbarg->rootfs, cbarg->target, fstype, strerror(errno));
+ if (ret < 0 || (size_t)ret >= BUFSIZ) {
+ ERROR("failed to format output mount error");
+ return 0;
+ }
+
+ if (lxc_append_string(&mount_errors, mount_err) < 0) {
+ ERROR("failed to append mount error");
+ }
return 0;
}
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index d1a22f7..120a13d 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)
*
* Return an open fd for the path, or <0 on error.
*/
-static int open_without_symlink(const char *target, const char *prefix_skip)
+int open_without_symlink(const char *target, const char *prefix_skip)
{
int curlen = 0, dirfd, fulllen, i;
char *dup;
@@ -1473,6 +1473,9 @@ static int lxc_get_unused_loop_dev(char *name_loop)
{
int loop_nr, ret;
int fd_ctl = -1, fd_tmp = -1;
+ // isulad: retry and try mknod
+ int max_retry = 200;
+ bool try_mknod = true;
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)
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) {
+ /* 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) {
+ /* Do not check result of mknod because LOOP_CTL_GET_FREE
+ * alse do mknod, so this mknod may fail as node already
+ * exist. If we can open the node without error, we can
+ * say that it's be created successfully.
+ *
+ * note: 7 is the major device number of loopback devices
+ * in kernel.
+ */
+ mknod(name_loop, S_IFBLK | 0640, makedev(7, loop_nr));
+ try_mknod = false;
+ goto retry;
+ }
+ /* we need to wait some time to make sure it's ready for open if
+ * it can't open even if we have already try to make node by ourself. */
+ if (max_retry > 0) {
+ max_retry--;
+ usleep(5000); /* 5 millisecond */
+ goto retry;
+ }
SYSERROR("Failed to open loop \"%s\"", name_loop);
+ goto on_error;
+ }
on_error:
close(fd_ctl);
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index abc88ca..4313942 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -224,6 +224,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);
+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);
--
1.8.3.1

View File

@ -0,0 +1,155 @@
From 8e7742314071cbb163c1fc6ab4eb96bffd6bc64a Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Tue, 15 Jan 2019 20:39:11 +0800
Subject: [PATCH 034/122] some small bugfix
1. support new container without load config to save time
2. try to create workdir if not exist
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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(-)
diff --git a/src/lxc/attach.c b/src/lxc/attach.c
index e6e4b0d..8cbbf96 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)
TRACE("Dropped capabilities");
}
+ /* isulad: set workdir */
+ if (init_ctx && init_ctx->container && init_ctx->container->lxc_conf && 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) {
+ SYSERROR("Try to create directory \"%s\" as workdir failed when attach", init_cwd);
+ goto on_error;
+ }
+ if (chdir(init_cwd)) {
+ SYSERROR("Could not change directory to \"%s\" when attach", init_cwd);
+ goto on_error;
+ }
+ }
+
/* 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
--- 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);
extern struct lxc_container *lxc_container_new(const char *name, const char *configpath);
/*
+ * Create a new container without loading config.
+ */
+extern struct lxc_container *lxc_container_without_config_new(const char *name, const char *configpath);
+
+/*
* 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
--- 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
WRAP_API_1(bool, lxcapi_clean_container_resource, pid_t)
-struct lxc_container *lxc_container_new(const char *name, const char *configpath)
+static struct lxc_container *do_lxc_container_new(const char *name, const char *configpath, bool load_config)
{
struct lxc_container *c;
size_t len;
@@ -5190,9 +5190,11 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
goto err;
}
- 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)) {
+ fprintf(stderr, "Failed to load config for %s\n", name);
+ goto err;
+ }
}
if (ongoing_create(c) == 2) {
@@ -5274,6 +5276,17 @@ err:
return NULL;
}
+// isulad: new container without load config to save time
+struct lxc_container *lxc_container_without_config_new(const char *name, const char *configpath)
+{
+ return do_lxc_container_new(name, configpath, false);
+}
+
+struct lxc_container *lxc_container_new(const char *name, const char *configpath)
+{
+ return do_lxc_container_new(name, configpath, true);
+}
+
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
--- a/src/lxc/lxccontainer.h
+++ b/src/lxc/lxccontainer.h
@@ -1040,6 +1040,18 @@ struct lxc_console_log {
struct lxc_container *lxc_container_new(const char *name, const char *configpath);
/*!
+ * \brief Create a new container without loading config.
+ *
+ * \param name Name to use for container.
+ * \param configpath Full path to configuration file to use.
+ *
+ * \return Newly-allocated container, or \c NULL on error.
+ *
+ * \note This function can only used for listing container.
+ */
+struct lxc_container *lxc_container_without_config_new(const char *name, const char *configpath);
+
+/*!
* \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
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -1364,10 +1364,14 @@ static int do_start(void *data)
setsid();
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 */
+ 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);
+ 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;
}
}
--
1.8.3.1

View File

@ -0,0 +1,25 @@
From b84e0641198d562f8da88dcf98e24f55358523c7 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Wed, 16 Jan 2019 20:53:25 +0800
Subject: [PATCH 035/122] lxc: fixup builds with newer glibc
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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 <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <sys/sysmacros.h>
#include <unistd.h>
#include <pwd.h>
--
1.8.3.1

View File

@ -0,0 +1,256 @@
From 191cff886b75864a9304eb5e56fa29662978ffec Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Tue, 15 Jan 2019 22:55:06 -0500
Subject: [PATCH 036/122] drop_caps: add drop caps of current process
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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(-)
diff --git a/src/lxc/attach.c b/src/lxc/attach.c
index 8cbbf96..3f60fe1 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");
}
- close(payload->ipc_socket);
- payload->ipc_socket = -EBADF;
- lxc_proc_put_context_info(init_ctx);
- payload->init_ctx = NULL;
-
/* 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)
new_gid = LXC_INVALID_GID;
+ if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
+ SYSERROR("Failed to keep permitted capabilities");
+ goto on_error;
+ }
+
if (!lxc_switch_uid_gid(new_uid, new_gid))
goto on_error;
+ 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) {
+ ERROR("Failed to drop caps.");
+ goto on_error;
+ }
+
+ close(payload->ipc_socket);
+ payload->ipc_socket = -EBADF;
+ lxc_proc_put_context_info(init_ctx);
+ payload->init_ctx = NULL;
+
/* 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;
}
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index fea0f59..6134ed3 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -4220,6 +4220,85 @@ int lxc_setup(struct lxc_handler *handler)
return 0;
}
+/* 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;
+ struct lxc_list *caps = NULL;
+
+ if (lxc_list_empty(&conf->keepcaps))
+ return 0;
+
+ caps = &conf->keepcaps;
+
+ if (numcaps <= 0 || numcaps > 200)
+ return -1;
+
+ // caplist[i] is 1 if we keep capability i
+ int *caplist = alloca(numcaps * sizeof(int));
+ memset(caplist, 0, numcaps * sizeof(int));
+
+ 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;
+
+ if (capid < 0) {
+ ERROR("unknown capability %s", keep_entry);
+ return -1;
+ }
+
+ DEBUG("keep capability '%s' (%d)", keep_entry, capid);
+
+ caplist[capid] = 1;
+ }
+
+ struct __user_cap_header_struct cap_header_data;
+ struct __user_cap_data_struct cap_data_data[2];
+
+ 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_data, 0, sizeof(struct __user_cap_data_struct) * 2);
+
+ cap_header->pid = 0;
+ cap_header->version = _LINUX_CAPABILITY_VERSION;
+
+ 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);
+ }
+ }
+
+ if (capset(cap_header, cap_data)) {
+ SYSERROR("Failed to set capabilitys");
+ return -1;
+ }
+
+#endif
+ return 0;
+}
+
struct oci_hook_conf {
defs_hook *ocihook;
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 44feb98..b92c48e 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);
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 */
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 040909c..357e81d 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -1411,6 +1411,11 @@ static int do_start(void *data)
}
}
+ if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
+ SYSERROR("Failed to keep permitted capabilities");
+ goto out_warn_father;
+ }
+
/* The container has been setup. We can now switch to an unprivileged
* uid/gid.
*/
@@ -1448,6 +1453,17 @@ static int do_start(void *data)
goto out_warn_father;
}
+ /* isulad: drop the cap of current process */
+ if (prctl(PR_SET_KEEPCAPS, 0) < 0) {
+ SYSERROR("Failed to clear permitted capabilities");
+ goto out_warn_father;
+ }
+
+ if (lxc_drop_caps(handler->conf)) {
+ SYSERROR("Failed to drop caps");
+ goto out_warn_father;
+ }
+
/* After this call, we are in error because this ops should not return
* as it execs.
*/
--
1.8.3.1

View File

@ -0,0 +1,113 @@
From 9eadf4f23de1863de62710b08b624a468048a773 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Tue, 15 Jan 2019 23:14:14 -0500
Subject: [PATCH 037/122] restore default signal handlers and set umask 0027
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
src/lxc/attach.c | 22 +++++++++++++++++++++-
src/lxc/conf.c | 3 +++
src/lxc/start.c | 18 +++++++++++++++++-
3 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/src/lxc/attach.c b/src/lxc/attach.c
index 3f60fe1..4ccdd74 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) &&
init_ctx->lsm_label;
+ 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: restore default signal handlers and unblock all signals*/
+ for (i = 1; i < NSIG; i++)
+ signal(i, SIG_DFL);
+
+ ret = sigfillset(&mask);
+ if (ret < 0) {
+ SYSERROR("Failed to fill signal mask");
+ goto on_error;;
+ }
+ ret = sigprocmask(SIG_UNBLOCK, &mask, NULL);
+ if (ret < 0) {
+ SYSERROR("Failed to set signal mask");
+ goto on_error;
+ }
+
/* 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)
}
}
+ /*isulad: set system umask 0027 for safe control*/
+ umask(0027);
+
ret = setup_personality(lxc_conf->personality);
if (ret < 0) {
ERROR("Failed to set personality");
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 357e81d..708ab7f 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;
lxc_sync_fini_parent(handler);
+ /*isulad: restore default signal handlers and unblock all signals*/
+ for (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;;
+ }
+ ret = sigprocmask(SIG_UNBLOCK, &mask, NULL);
+ if (ret < 0) {
+ SYSERROR("Failed to set signal mask");
+ goto out_warn_father;
+ }
+
/* 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
--
1.8.3.1

View File

@ -0,0 +1,46 @@
From 05bdc32a321530e46325ca7fe8f67f9195f54962 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Tue, 15 Jan 2019 23:24:21 -0500
Subject: [PATCH 038/122] 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 <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,816 @@
From b8925094ceb77cc94c8305725aae4877636c13c1 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Wed, 16 Jan 2019 14:38:38 +0800
Subject: [PATCH 039/122] print error message when container start failed
Signed-off-by: tanyifeng <tanyifeng1@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,107 @@
From a03cf6d594d7b310138b898fd1c49ce031322e48 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Wed, 16 Jan 2019 02:22:13 -0500
Subject: [PATCH 040/122] add timeout(200ms) for cmds send to [lxc monitor]
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,25 @@
From ea7fe5755309e9054ac06542b8fc0abb25039b7e Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Wed, 16 Jan 2019 05:53:36 -0500
Subject: [PATCH 041/122] return -1 when _lxc_start fails
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
src/lxc/start.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 3e6854f..7bbcb00 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,
if (!handler->init_died && handler->pid > 0) {
ERROR("Child process is not killed");
+ ret = -1;
goto out_abort;
}
--
1.8.3.1

View File

@ -0,0 +1,169 @@
From 6beb5e3a4afe7fede796fc547a29c6175512f024 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Thu, 17 Jan 2019 03:09:00 +0800
Subject: [PATCH 042/122] lxc: seccomp adopt to lxc3.0
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,28 @@
From 7be24baf1379d45651d10f63cb7e1cb59bdc733c Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Thu, 17 Jan 2019 10:19:37 +0800
Subject: [PATCH 043/122] check null pointer of handler to fix coredump of
attach
Signed-off-by: tanyifeng <tanyifeng1@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,118 @@
From baabb2596394fecf89c610e2473d8b930595f3aa Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Thu, 17 Jan 2019 10:18:23 +0800
Subject: [PATCH 044/122] support space in --volume, --mount and --env
Signed-off-by: tanyifeng <tanyifeng1@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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 <time.h>
#include <unistd.h>
#include <pthread.h>
+#include <linux/fs.h>
#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 <sched.h>
#include <unistd.h>
#include <sys/syscall.h>
+#include <sys/types.h>
#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

View File

@ -0,0 +1,254 @@
From 698f04aa780eed16e70f96f3405596e98f3828a2 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Thu, 17 Jan 2019 02:18:14 -0500
Subject: [PATCH 045/122] add_terminal_fifos: Add terminal fifos dynamically
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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(+)
diff --git a/src/lxc/commands.c b/src/lxc/commands.c
index 47a824a..46b2805 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",
};
if (cmd >= LXC_CMD_MAX)
@@ -1056,6 +1057,66 @@ reap_client_fd:
return 1;
}
+/*
+ * isulad: lxc_cmd_set_terminal_fifos: Set the fifos used for the container as terminal input/output
+ *
+ * @hashed_sock_name: hashed socket name
+ *
+ * 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 ret = 0, stopped = 0;
+ int len = 0;
+ char *tmp = NULL;
+
+ if (!in_fifo || !out_fifo) {
+ return -1;
+ }
+
+ len = strlen(in_fifo) + strlen("&&&&") + strlen(out_fifo) + 1;
+ tmp = malloc(len);
+ if (!tmp)
+ return -1;
+ snprintf(tmp, len, "%s%s%s", in_fifo, "&&&&", out_fifo);
+
+ struct lxc_cmd_rr cmd = {
+ .req = {
+ .cmd = LXC_CMD_SET_TERMINAL_FIFOS,
+ .datalen = strlen(tmp)+1,
+ .data = tmp,
+ },
+ };
+
+ ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
+ if (ret < 0) {
+ ERROR("Failed to send command to container");
+ free(tmp);
+ return -1;
+ }
+
+ if (cmd.rsp.ret != 0) {
+ ERROR("Command response error:%d", cmd.rsp.ret);
+ free(tmp);
+ return -1;
+ }
+
+ free(tmp);
+ return 0;
+}
+
+static int lxc_cmd_set_terminal_fifos_callback(int fd, struct lxc_cmd_req *req,
+ struct lxc_handler *handler)
+{
+ struct lxc_cmd_rsp rsp;
+ memset(&rsp, 0, sizeof(rsp));
+
+ rsp.ret = lxc_terminal_add_fifos(handler->conf, req->data);;
+
+ return lxc_cmd_rsp_send(fd, &rsp);
+
+}
+
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,
};
if (req->cmd >= LXC_CMD_MAX) {
diff --git a/src/lxc/commands.h b/src/lxc/commands.h
index 2c024b6..0c64544 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,
+ LXC_CMD_SET_TERMINAL_FIFOS,
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);
+extern int lxc_cmd_set_terminal_fifos(const char *name, const char *lxcpath,
+ const char *in_fifo, const char *out_fifo);
+
#endif /* __commands_h */
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index d641851..bfbf223 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)
+/* isulad add clean resources */
+static bool do_lxcapi_add_terminal_fifo(struct lxc_container *c, const char *in_fifo, const char *out_fifo)
+{
+ bool ret = true;
+
+ if (!c || !c->lxc_conf || !in_fifo || !out_fifo)
+ 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)) {
+ ERROR("Error set console fifos");
+ ret = false;
+ }
+
+ container_mem_unlock(c);
+ 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 *
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->add_terminal_fifos = lxcapi_add_terminal_fifo;
/* isulad add end */
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
--- 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;
}
+
+/* isulad: add fifos dynamic*/
+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;
+
+ tmp = strdup(fifonames);
+ if (!tmp) {
+ ret = -1;
+ goto free_out;
+ }
+
+ in = strtok_r(tmp, "&&&&", &saveptr);
+ if (!in) {
+ ret = -1;
+ goto free_out;
+ }
+ out = strtok_r(NULL, "&&&&", &saveptr);
+ if (!out) {
+ ret = -1;
+ goto free_out;
+ }
+
+ fifofd_in = lxc_terminal_set_fifo(terminal, in, out);
+ if (fifofd_in < 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)) {
+ ERROR("console fifo not added to mainloop");
+ lxc_terminal_delete_fifo(fifofd_in, &terminal->fifos);
+ ret = -1;
+ goto free_out;
+ }
+
+free_out:
+ if (tmp)
+ free(tmp);
+ return ret;
+}
+
diff --git a/src/lxc/terminal.h b/src/lxc/terminal.h
index d25da65..d006b80 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);
#endif /* __LXC_TERMINAL_H */
--
1.8.3.1

View File

@ -0,0 +1,48 @@
From 623f6fbd09a7694546ca7c57a564d984261c4f82 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Thu, 17 Jan 2019 03:49:16 -0500
Subject: [PATCH 046/122] 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 <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,44 @@
From ec20a5a0e68d0b70ec0014d3f34385cdd3c44370 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Thu, 17 Jan 2019 07:43:23 -0500
Subject: [PATCH 047/122] Fix memory leak in lxc_global_config_value
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,59 @@
From 26125894df9e3297f34c02d62ae5271b5ec88348 Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Thu, 17 Jan 2019 20:46:33 +0800
Subject: [PATCH 048/122] clear ONLCR flag from master of terminal
clear ONLCR flag from master of terminal
Signed-off-by: liuhao <liuhao27@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,28 @@
From 81e84198f02323caabcab2200f2bedf9212a87d7 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Sat, 19 Jan 2019 02:05:17 -0500
Subject: [PATCH 049/122] Add 100ms timeout for console epoll
add 100ms timeout for console epoll to avoid lose console
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,408 @@
From 043d4a1b634a850a201bd835ee59061cbbdbd030 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Fri, 18 Jan 2019 02:11:11 -0500
Subject: [PATCH 050/122] seccomp: add rules for specified architecture only
LXC MR: https://github.com/lxc/lxc/pull/2786
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,34 @@
From 4fc938241a649307d87700e90dc380651da4c550 Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Tue, 22 Jan 2019 11:25:45 +0800
Subject: [PATCH 051/122] if ocihook is empty
return success
Signed-off-by: liuhao <liuhao27@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,192 @@
From bbefc33a969a7cf0d4f671d96030fb044593a71a Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Mon, 21 Jan 2019 23:28:43 -0500
Subject: [PATCH 052/122] Fix seccomp fail when [all] specified in config
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,31 @@
From d1ae3bc538d21355947a1d1695c22690bb9a68ae Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Tue, 22 Jan 2019 14:45:54 +0800
Subject: [PATCH 053/122] destroy empty cgroup path return ture
destroy empty cgroup path return ture
Signed-off-by: liuhao <liuhao27@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,42 @@
From d423289dd6f287b66d62538d9bdedd745a939c50 Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Tue, 22 Jan 2019 20:14:53 +0800
Subject: [PATCH 054/122] fix invalid log message
fix invalid log message
Signed-off-by: liuhao <liuhao27@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,229 @@
From 9e3eb0c5c5258c6d8e658129ef87ae7ff3ffe64f Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Thu, 24 Jan 2019 05:14:24 -0500
Subject: [PATCH 055/122] Fix compile error
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,48 @@
From 65b5764a98f751e885ba8596b2b92c4e7a3e0310 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Sat, 26 Jan 2019 02:22:48 -0500
Subject: [PATCH 056/122] [caps]: use _LINUX_CAPABILITY_VERSION_3 to set cap
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,146 @@
From b35461f2219dba74b2a51c576ec667f8912632d1 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Wed, 30 Jan 2019 03:39:42 -0500
Subject: [PATCH 057/122] 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 <lifeng68@huawei.com>
---
src/lxc/attach.c | 4 ++--
src/lxc/conf.c | 5 +++--
src/lxc/conf.h | 1 +
src/lxc/confile.c | 38 ++++++++++++++++++++++++++++++++++++++
4 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/src/lxc/attach.c b/src/lxc/attach.c
index b44ea74..9768897 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;
- /*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++)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 0c6aa28..67beefe 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;
+ new->umask = 0027; /*default umask 0027*/
/* isulad add end */
return new;
@@ -4216,8 +4217,8 @@ int lxc_setup(struct lxc_handler *handler)
}
}
- /*isulad: set system umask 0027 for safe control*/
- umask(0027);
+ /*isulad: set system umask */
+ umask(lxc_conf->umask);
ret = setup_personality(lxc_conf->personality);
if (ret < 0) {
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 88f5b41..93cf15d 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.
+ mode_t umask; //umask value
/* isulad add end */
};
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index f66d01b..3940b32 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -155,6 +155,7 @@ lxc_config_define(proc);
/*isulad add begin*/
lxc_config_define(init_args);
lxc_config_define(populate_device);
+lxc_config_define(umask);
/*isulad add end*/
@@ -247,6 +248,7 @@ static struct lxc_config_t config_jump_table[] = {
{ "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*/
};
@@ -2371,6 +2373,27 @@ 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)
+{
+ if (lxc_config_value_empty(value)) {
+ ERROR("Empty umask");
+ return -1;
+ }
+
+ if (strcmp(value, "normal") == 0) {
+ lxc_conf->umask = 0022;
+ return 0;
+ } else if (strcmp(value, "secure") == 0) {
+ lxc_conf->umask = 0027;
+ return 0;
+ } else {
+ ERROR("Invalid native umask: %s", value);
+ return -1;
+ }
+}
+
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)
+{
+ 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)
+{
+ c->umask = 0027;
+ return 0;
+}
+
static int get_config_includefiles(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
--
1.8.3.1

View File

@ -0,0 +1,36 @@
From 920c4a399b121ade499482cae1768f995576b547 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Tue, 12 Feb 2019 14:00:47 +0800
Subject: [PATCH 058/122] do not check ppid when set death signal
ppid will not be 0 if we shared host pid
Signed-off-by: tanyifeng <tanyifeng1@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,27 @@
From 897a0999c48453547cd8631a622defe233804be1 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Tue, 12 Feb 2019 14:36:35 +0800
Subject: [PATCH 059/122] delete unused variable ppid
Signed-off-by: tanyifeng <tanyifeng1@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,610 @@
From 1e1274c4202cb8aac8395586f163d6b27b31ff28 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Wed, 30 Jan 2019 17:44:19 +0800
Subject: [PATCH 060/122] using json-file to write console log of container
Signed-off-by: tanyifeng <tanyifeng1@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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 <string.h>
+#include <read-file.h>
+#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 <sys/types.h>
+#include <stdint.h>
+#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

View File

@ -0,0 +1,50 @@
From c9dc04b4237ac01155a8ce37beae9db4ea7c2b1a Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Thu, 21 Feb 2019 05:37:05 -0500
Subject: [PATCH 061/122] Fix hook: use the path, args, envs execvp dirctory
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,74 @@
From e0c8855867b71eb0106a312e84389389cee395d7 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Tue, 26 Feb 2019 17:21:18 +0800
Subject: [PATCH 062/122] setup sysctls before set read-only path and masked
path
Signed-off-by: tanyifeng <tanyifeng1@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,27 @@
From aa6af28e14e024cfc31b8d77516df9899eb480c8 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Sat, 9 Mar 2019 03:10:06 +0800
Subject: [PATCH 063/122] lxc: ignore systemcall load failure error
Signed-off-by: wujing <wujing50@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
src/lxc/seccomp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lxc/seccomp.c b/src/lxc/seccomp.c
index 4a5b3d0..26eac90 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;
SYSERROR("Failed loading rule for %s (nr %d action %d (%s))",
line, nr, rule->action, get_action_name(rule->action));
- return false;
+ return true;
}
return true;
--
1.8.3.1

View File

@ -0,0 +1,46 @@
From ec896c711806cad0fa852ea1695361441e840132 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Sun, 10 Mar 2019 00:47:05 +0800
Subject: [PATCH 064/122] lxc: Reduce seccomp processing log level
Signed-off-by: wujing <wujing50@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,30 @@
From d771f62e77e5d122178b171a06a821af4103e48d Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Mon, 11 Mar 2019 23:26:27 -0400
Subject: [PATCH 065/122] Storage: return true if storage_init init fail
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,28 @@
From 5c96085ffd6f219f92bc210c057e9d964c75cd84 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Fri, 15 Mar 2019 10:11:10 +0800
Subject: [PATCH 066/122] lxc: Pids limit does not report an error after
executing the limit in the background
Signed-off-by: wujing <wujing50@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,72 @@
From 6942bba7a61f9fe55d5d819ffd817ea4b028d040 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Sat, 16 Mar 2019 10:06:13 +0800
Subject: [PATCH 067/122] lxc: report error when remove directory failed
Signed-off-by: tanyifeng <tanyifeng1@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,207 @@
From f6877ff5a4ca2bb0e7556b0b17690290888021f5 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Thu, 21 Mar 2019 15:48:02 +0800
Subject: [PATCH 069/122] lxc: killall processes if container shared pid
namespace
Signed-off-by: tanyifeng <tanyifeng1@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,400 @@
From 44f3d99c562ab88670f1fe91a1d16474da8adb98 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Thu, 21 Mar 2019 17:21:44 +0800
Subject: [PATCH 070/122] lxc: signal all process for shared container when
container init exited
Signed-off-by: tanyifeng <tanyifeng1@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
src/lxc/cgroups/cgfsng.c | 2 +-
src/lxc/start.c | 332 +++++++++++++++++++++++++----------------------
2 files changed, 175 insertions(+), 159 deletions(-)
diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
index ab7ca35..5ceb06b 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) {
- SYSERROR("Failed to destroy \"%s\"", h->container_full_path);
+ SYSWARN("Failed to destroy \"%s\"", h->container_full_path);
return -1;
}
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 1c9eb0a..b14e46f 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -941,6 +941,162 @@ out_close_maincmd_fd:
return -1;
}
+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);
+}
+
void lxc_fini(const char *name, 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;
/* 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]);
- 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");
+ }
+retry:
+ if (!cgroup_ops->destroy(cgroup_ops, handler)) {
+ 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.
@@ -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;
}
--
1.8.3.1

View File

@ -0,0 +1,126 @@
From 5c369714d1a1d74606e6ee44a3df4e1d159ee702 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Thu, 21 Mar 2019 22:05:09 +0800
Subject: [PATCH 071/122] lxc: get cgroup path according to cgroup mountpoint
Signed-off-by: tanyifeng <tanyifeng1@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,66 @@
From de35b7df30fbdbf10c0d55523b7fa3a15eb17623 Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Mon, 25 Mar 2019 18:03:23 +0800
Subject: [PATCH 072/122] lxc: adapt to docker-18.09
1. adapt to docker-18.09
2. fix strlcpy bug
Signed-off-by: liuhao <liuhao27@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,247 @@
From 5c599c0a93b66eea1633f54ac61bcd99142758e3 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Mon, 25 Mar 2019 17:17:00 +0800
Subject: [PATCH 073/122] lxc: support set additional groups
Signed-off-by: tanyifeng <tanyifeng1@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,28 @@
From df20c5c153b342c2aa49ebafbef8c1e334668e9a Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Tue, 26 Mar 2019 16:11:13 +0800
Subject: [PATCH 074/122] lxc: only add valid fd to mainloop
Signed-off-by: tanyifeng <tanyifeng1@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,278 @@
From d108c60ea9bf1c0a257659d07531e50d09897e48 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Wed, 3 Apr 2019 19:54:36 +0800
Subject: [PATCH 075/122] lxc: add timeout for attach
Signed-off-by: wujing <wujing50@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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 <sys/personality.h>
#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

View File

@ -0,0 +1,26 @@
From 5a3c172215974dccf41e456b39c8174aaa580cc8 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Thu, 4 Apr 2019 11:19:48 +0800
Subject: [PATCH 076/122] lxc: delete unused variable
Signed-off-by: wujing <wujing50@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,117 @@
From fe7032c4ed978c38beb00804abb46ad691c0a83c Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Tue, 2 Apr 2019 23:59:20 -0400
Subject: [PATCH 077/122] lxc: set negative files.limit to max and fix bug of
setting homedir
Signed-off-by: tanyifeng <tanyifeng1@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,70 @@
From ca1c7f86ddadd194c2347e2ccd6b216f1403e273 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Wed, 3 Apr 2019 23:36:04 -0400
Subject: [PATCH 078/122] Run pre-start hook before chroot
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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 <sys/mkdev.h>
@@ -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

View File

@ -0,0 +1,29 @@
From b19fca11de19c05c4035fd98842810dfb102aa7b Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Thu, 4 Apr 2019 17:21:56 +0800
Subject: [PATCH 079/122] inherid env from parent in oci hooks
env: LD_LIBRAY_PAHT and PATH
Signed-off-by: liuhao <liuhao27@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,35 @@
From ff3a4e1e01afe4cabd6dfae8400b3bfa5803567d Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Mon, 8 Apr 2019 08:29:46 -0400
Subject: [PATCH 080/122] lxc: fix compile error
Signed-off-by: tanyifeng <tanyifeng1@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,78 @@
From d2711e184061fd4c03413667e4e9b44ae741d901 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Mon, 8 Apr 2019 16:42:43 +0800
Subject: [PATCH 081/122] lxc: Change the range of attach timeout
Signed-off-by: wujing <wujing50@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,150 @@
From 767d1b2f9bb323de16658a080b314c5f8feaec67 Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Thu, 11 Apr 2019 15:27:31 +0800
Subject: [PATCH 082/122] 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 <liuhao27@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,41 @@
From 6688394517b79adc2ea1b2d65c66cf9af29ba251 Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Thu, 11 Apr 2019 20:34:51 +0800
Subject: [PATCH 083/122] lxc: free lxc-handler
free handler if failed
Signed-off-by: liuhao <liuhao27@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,28 @@
From fd9efbdd077e8cc2a7b825e6f632b5bf4a3473e1 Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Thu, 11 Apr 2019 22:36:42 +0800
Subject: [PATCH 084/122] lxc: memory leak of lxc_grow_array
fix memory leak of lxc_grow_array
Signed-off-by: liuhao <liuhao27@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,150 @@
From 196510dd784d195dfc131b56249a5aac0b9eab54 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Sat, 20 Apr 2019 22:40:18 +0800
Subject: [PATCH 086/122] confile: add support systemd
lxc.isulad.systemd=true remount systemd cgroup path to rw
Signed-off-by: zhangsong <zhangsong34@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
src/lxc/cgroups/cgfsng.c | 16 ++++++++++++++++
src/lxc/conf.c | 1 +
src/lxc/conf.h | 1 +
src/lxc/confile.c | 30 ++++++++++++++++++++++++++++++
4 files changed, 48 insertions(+)
diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
index cc08737..b1f56b0 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,
{
int i, ret;
char *tmpfspath = NULL;
+ char *systemdpath = NULL;
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;
}
}
+
+ // 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);
+ 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);
+ }
lxc_free_array((void **)merged, free);
return retval;
}
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 20eb840..8cdccf1 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)
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 */
};
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index 60e6c46..93936cc 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);
lxc_config_define(umask);
+lxc_config_define(systemd);
/*isulad add end*/
@@ -251,6 +252,7 @@ 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.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*/
};
@@ -2433,6 +2435,18 @@ 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)
+{
+ if (lxc_config_value_empty(value)) {
+ ERROR("Empty umask");
+ return -1;
+ }
+ lxc_conf->systemd = strdup(value);
+ 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)
+{
+ 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)
+{
+ free(c->systemd);
+ c->systemd = NULL;
+ return 0;
+}
+
static int get_config_includefiles(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
--
1.8.3.1

View File

@ -0,0 +1,41 @@
From 917a306cfab2e0cef3a666b23bf7c788bcf466d3 Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Wed, 24 Apr 2019 22:22:55 +0800
Subject: [PATCH 087/122] lxc: adapt to spec of oci hook
poststart failed do not cause run failed
Signed-off-by: liuhao <liuhao27@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,29 @@
From f6ddc6eb341b7eca5616be1ffd6b403db1b83b11 Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Thu, 25 Apr 2019 10:12:16 +0800
Subject: [PATCH 088/122] fix lxc build error
cause by invalid print format
Signed-off-by: liuhao <liuhao27@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,177 @@
From 4241f51abad788017ca5a0da5946ccc2672bdc3b Mon Sep 17 00:00:00 2001
From: maoweiyong <maoweiyong@huawei.com>
Date: Tue, 23 Apr 2019 12:12:55 +0800
Subject: [PATCH 089/122] lxc:add get container processes pids func
Signed-off-by: maoweiyong <maoweiyong@huawei.com>
---
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

View File

@ -0,0 +1,26 @@
From 83136d88470202915844a0bb0413af70fcd18efc Mon Sep 17 00:00:00 2001
From: maoweiyong <maoweiyong@huawei.com>
Date: Thu, 25 Apr 2019 21:21:12 +0800
Subject: [PATCH 090/122] lxc: remove unused variable
Signed-off-by: maoweiyong <maoweiyong@huawei.com>
---
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

View File

@ -0,0 +1,118 @@
From 639248d8b9bcbaabe789f7d12f28191a4e65752f Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Fri, 26 Apr 2019 07:13:53 +0800
Subject: [PATCH 091/122] lxc: support namespaced kernel params can be changed
in system container
support namespaced kernel params can be changed in system container
Signed-off-by: yangchenliang <yangchenliang@huawei.com>
---
src/lxc/conf.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 77 insertions(+)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 14d5d80..0f227aa 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -1516,6 +1516,66 @@ error:
return false;
}
+static bool remount_readwrite(const char *path)
+{
+ int ret, i;
+
+ if (!path)
+ return true;
+
+ for (i = 0; i < 5; i++) {
+ ret = mount("", path, "", MS_REMOUNT, "");
+ if (ret < 0 && errno != ENOENT) {
+ if (errno == EINVAL) {
+ // Probably not a mountpoint, use bind-mount
+ ret = mount(path, path, "", MS_BIND, "");
+ if (ret < 0)
+ goto on_error;
+ ret = mount(path, path, "", MS_BIND | MS_REMOUNT | MS_REC | \
+ MS_NOEXEC | MS_NOSUID | MS_NODEV, "");
+ if (ret < 0)
+ goto on_error;
+ } else if (errno == EBUSY) {
+ DEBUG("Try to mount \"%s\" to readonly after 100ms.", path);
+ usleep(100 * 1000);
+ continue;
+ } else {
+ goto on_error;
+ }
+ }
+ return true;
+ }
+
+on_error:
+ SYSERROR("Unable to mount \"%s\" to readwrite", path);
+ return false;
+}
+
+static int remount_proc_sys_mount_entries(struct lxc_list *mount_list)
+{
+ char buf[4096];
+ FILE *file;
+ struct mntent mntent;
+
+ file = make_anonymous_mount_file(mount_list);
+ if (!file)
+ return -1;
+
+ while (getmntent_r(file, &mntent, buf, sizeof(buf))) {
+ if (strstr(mntent.mnt_dir, "proc/sys") == NULL) {
+ continue;
+ }
+
+ if (!remount_readwrite((const char*)mntent.mnt_dir)) {
+ fclose(file);
+ return -1;
+ }
+ }
+
+ fclose(file);
+ return 0;
+}
+
// 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)
}
}
+ //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 (!lxc_list_empty(&lxc_conf->keepcaps)) {
if (!lxc_list_empty(&lxc_conf->caps)) {
ERROR("Container requests lxc.cap.drop and "
--
1.8.3.1

View File

@ -0,0 +1,45 @@
From 548054179d5e5b43368491822ebed803c9a03a36 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Mon, 29 Apr 2019 04:13:52 -0400
Subject: [PATCH 092/122] lxc: add output error when create unified cgroup
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,424 @@
From d37fe422dc56c4904c138fdcb2c721a3cca2f0a8 Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Thu, 2 May 2019 11:23:50 +0800
Subject: [PATCH 093/122] optimize isulad_kit operator
parse group add start container
Signed-off-by: liuhao <liuhao27@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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 <string.h>
+#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 <sys/types.h>
+#include <stdint.h>
+#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

View File

@ -0,0 +1,197 @@
From 900c2f8fe30d4ffdaef93f2c01d711705ab8cff9 Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Tue, 7 May 2019 12:55:03 +0800
Subject: [PATCH 094/122] exec load uid gid and groups
exec load uid gid and groups
Signed-off-by: liuhao <liuhao27@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,56 @@
From 92dfbde544492386418f02469af5380d7d5e7c00 Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Fri, 10 May 2019 11:05:42 +0800
Subject: [PATCH 095/122] lxc: don't use the unified hierarchy for the systemd
cgroup
reason:don't use the unified hierarchy for the systemd cgroup
Signed-off-by: zhangsong <zhangsong34@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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
--- 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,
int i, ret;
char *tmpfspath = NULL;
char *systemdpath = NULL;
+ char *unifiedpath = NULL;
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,
// 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);
@@ -1734,6 +1745,9 @@ on_error:
if (systemdpath != NULL) {
free(systemdpath);
}
+ if (unifiedpath != NULL) {
+ free(unifiedpath);
+ }
lxc_free_array((void **)merged, free);
return retval;
}
--
1.8.3.1

View File

@ -0,0 +1,34 @@
From 7f4352c61de6732d41285f6f949199708e459ac0 Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Mon, 13 May 2019 16:45:50 +0800
Subject: [PATCH 096/122] close inherited fd in hook process
close inherited fd in hook process
Signed-off-by: liuhao <liuhao27@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,72 @@
From 474a63f9c72ace7d1d49d58f6b844dc18f2b6456 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Wed, 15 May 2019 00:53:49 -0400
Subject: [PATCH 097/122] lxc: report error when fork/exec error for hooks
Signed-off-by: tanyifeng <tanyifeng1@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,67 @@
From 94b3ad110dc17ecad2f86ef166065293cb278295 Mon Sep 17 00:00:00 2001
From: tanyifeng <tanyifeng1@huawei.com>
Date: Wed, 15 May 2019 12:42:08 +0800
Subject: [PATCH 098/122] 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 <zhangsong34@huawei.com>
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,28 @@
From d5d48aa449d782dce754ee87c6a3ee1706c1f967 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Tue, 21 May 2019 04:53:16 -0400
Subject: [PATCH 099/122] terminal: do not close the master fd of pty
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

View File

@ -0,0 +1,139 @@
From 5f9953ea9fffa99ca3838e3b59ab3ee170e62795 Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Wed, 22 May 2019 23:00:17 -0400
Subject: [PATCH 100/122] start: add check save pid info file
Signed-off-by: LiFeng <lifeng68@huawei.com>
---
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

Some files were not shown because too many files have changed in this diff Show More