lxc/0008-bugfix-for-system-container-and-stream.patch
zhangxiaoyu f2dfd761bc bugfix for system container and stream
Signed-off-by: zhangxiaoyu <zhangxiaoyu58@huawei.com>
2023-12-06 10:34:43 +08:00

491 lines
15 KiB
Diff

From 4cdfab3356a95e7bd7063adcb54604c8f1f4c439 Mon Sep 17 00:00:00 2001
From: zhangxiaoyu <zhangxiaoyu58@huawei.com>
Date: Tue, 7 Nov 2023 16:24:53 +0800
Subject: [PATCH] bugfix for system container and stream
Signed-off-by: zhangxiaoyu <zhangxiaoyu58@huawei.com>
---
src/lxc/attach.c | 6 +--
src/lxc/cgroups/cgfsng.c | 4 +-
src/lxc/conf.c | 65 ++++++++++++++++------------
src/lxc/confile.c | 9 +++-
src/lxc/start.c | 78 ++++++++++++++++++----------------
src/lxc/storage/dir.c | 4 ++
src/lxc/terminal.c | 92 +++++++++++++++++++++++++---------------
7 files changed, 150 insertions(+), 108 deletions(-)
diff --git a/src/lxc/attach.c b/src/lxc/attach.c
index ae12da3..9550e6d 100644
--- a/src/lxc/attach.c
+++ b/src/lxc/attach.c
@@ -1453,7 +1453,7 @@ __noreturn static void do_attach(struct attach_payload *ap)
SYSERROR("Failed to prepare terminal file pipes");
goto on_error;
}
- } else {
+ } else if (ap->terminal_pts_fd >= 0) {
#endif
ret = lxc_terminal_prepare_login(ap->terminal_pts_fd);
if (ret < 0) {
@@ -2009,11 +2009,7 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function,
.terminal = &terminal,
#endif
};
-#ifdef HAVE_ISULAD
- if (options->attach_flags & LXC_ATTACH_TERMINAL && terminal.tty_state) {
-#else
if (options->attach_flags & LXC_ATTACH_TERMINAL) {
-#endif
ret = lxc_terminal_signal_sigmask_safe_blocked(&terminal);
if (ret < 0) {
SYSERROR("Failed to reset signal mask");
diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
index 0aaafa8..a9a8f2c 100644
--- a/src/lxc/cgroups/cgfsng.c
+++ b/src/lxc/cgroups/cgfsng.c
@@ -612,7 +612,7 @@ __cgfsng_ops static void cgfsng_payload_destroy(struct cgroup_ops *ops,
if (ret < 0)
SYSWARN("Failed to destroy cgroups");
#ifdef HAVE_ISULAD
- return ret >= 0;
+ return ret == 0;
#endif
}
@@ -3370,8 +3370,6 @@ static bool isulad_cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *
if (!string_in_list(h->controllers, "cpuset"))
return true;
- cgname += strspn(cgname, "/");
-
slash = strchr(cgname, '/');
if (slash != NULL) {
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index ff5cefc..7a70bca 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -1281,7 +1281,13 @@ static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs,
#ifdef HAVE_ISULAD
if (systemd != NULL && !strcmp(systemd, "true")) {
- ret = mount(path, path, "", MS_BIND, NULL);
+ __do_free char *fallback_path = NULL;
+ if (path) {
+ fallback_path = must_make_path(path, "/dev", NULL);
+ } else {
+ fallback_path = must_make_path("dev", NULL);
+ }
+ ret = mount(fallback_path, fallback_path, "", MS_BIND, NULL);
#else
if (can_use_mount_api()) {
fd_fs = fs_prepare("tmpfs", -EBADF, "", 0, 0);
@@ -2349,7 +2355,18 @@ static int lxc_setup_console(const struct lxc_handler *handler,
* setup on its console ie. the pty allocated in lxc_terminal_setup() so
* make sure that that pty is stdin,stdout,stderr.
*/
+#ifdef HAVE_ISULAD
+ setsid();
+ if (!handler->disable_pty && handler->conf->console.pty >= 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.pty, TIOCSCTTY, NULL) < 0) {
+ return syserror("Faild to make the given terminal the controlling terminal of the calling process");
+ }
+#else
if (console->pty >= 0) {
+#endif
if (handler->daemonize || !handler->conf->is_execute)
ret = set_stdfds(console->pty);
else
@@ -4678,20 +4695,21 @@ int lxc_setup(struct lxc_handler *handler)
#endif
ret = lxc_rootfs_prepare_child(handler);
+ if (ret < 0)
+ return syserror("Failed to prepare rootfs");
+
+
+ ret = lxc_setup_rootfs_prepare_root(lxc_conf, name, lxcpath);
if (ret < 0)
#ifdef HAVE_ISULAD
{
lxc_write_error_message(lxc_conf->errpipe[1], "%s:%d: failed to setup rootfs %s.",
__FILE__, __LINE__, lxc_conf->rootfs.path);
- return syserror("Failed to prepare rootfs");
+ return log_error(-1, "Failed to setup rootfs");
}
#else
- return syserror("Failed to prepare rootfs");
-#endif
-
- ret = lxc_setup_rootfs_prepare_root(lxc_conf, name, lxcpath);
- if (ret < 0)
return log_error(-1, "Failed to setup rootfs");
+#endif
if (handler->nsfd[LXC_NS_UTS] == -EBADF) {
ret = setup_utsname(lxc_conf->utsname);
@@ -4820,9 +4838,6 @@ int lxc_setup(struct lxc_handler *handler)
return log_error(-1, "Failed to mount transient procfs instance for LSMs");
}
- if (setup_rootfs_mountopts(&lxc_conf->rootfs)) {
- return log_error(-1, "failed to set rootfs for '%s'", name);
- }
if (lxc_conf->rootfs.path != NULL && setup_dev) {
ret = lxc_setup_devpts_child(handler);
if (ret < 0) {
@@ -4866,6 +4881,12 @@ int lxc_setup(struct lxc_handler *handler)
if (ret < 0)
return log_error(-1, "Failed to pivot root into rootfs");
+#ifdef HAVE_ISULAD
+ if (setup_rootfs_mountopts(&lxc_conf->rootfs)) {
+ return log_error(-1, "failed to set rootfs for '%s'", name);
+ }
+#endif
+
ret = make_shmount_dependent_mount(lxc_conf);
if (ret < 0)
return log_error(-1, "Failed to turn mount tunnel \"%s\" into dependent mount",
@@ -6926,28 +6947,18 @@ int parse_propagationopts(const char *mntopts, unsigned long *pflags)
// isulad: setup rootfs mountopts
static int setup_rootfs_mountopts(const struct lxc_rootfs *rootfs)
{
- unsigned long mflags, mntflags, pflags;
- __do_free char *mntdata = NULL;
+ unsigned long mflags;
- if(!rootfs || !rootfs->mnt_opts.raw_options)
+ if(!rootfs || !(rootfs->mnt_opts.mnt_flags & MS_RDONLY))
return 0;
- if (parse_mntopts_legacy(rootfs->mnt_opts.raw_options, &mntflags, &mntdata) < 0) {
+ mflags = add_required_remount_flags("/", NULL, MS_BIND | MS_REC | rootfs->mnt_opts.mnt_flags |
+ rootfs->mnt_opts.prop_flags | MS_REMOUNT);
+ DEBUG("remounting / as readonly");
+ if (mount("/", "/", NULL, mflags, 0) < 0) {
+ SYSERROR("Failed to make / readonly.");
return -1;
}
-
- if (parse_propagationopts(rootfs->mnt_opts.raw_options, &pflags) < 0) {
- return -EINVAL;
- }
-
- 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, mflags, 0) < 0) {
- SYSERROR("Failed to make / readonly.");
- return -1;
- }
- }
return 0;
}
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index ae1a264..aa5c790 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -2010,14 +2010,19 @@ static int set_config_cgroup_dir(const char *key, const char *value,
if (lxc_config_value_empty(value))
return clr_config_cgroup_dir(key, lxc_conf, NULL);
-#ifndef HAVE_ISULAD
+
+#ifdef HAVE_ISULAD
+ // convert value from "/isulad" to "isulad"
+ return set_config_path_item(&lxc_conf->cgroup_meta.dir, value + strspn(value, "/"));
+#else
if (abspath(value))
return syserror_set(-EINVAL, "%s paths may not be absolute", key);
if (dotdot(value))
return syserror_set(-EINVAL, "%s paths may not walk upwards via \"../\"", key);
-#endif
+
return set_config_path_item(&lxc_conf->cgroup_meta.dir, value);
+#endif
}
static int set_config_cgroup_monitor_dir(const char *key, const char *value,
diff --git a/src/lxc/start.c b/src/lxc/start.c
index a7bc2e6..b1ccdcb 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -1566,43 +1566,6 @@ static int do_start(void *data)
DEBUG("Set PR_SET_NO_NEW_PRIVS to block execve() gainable privileges");
}
-#ifdef HAVE_ISULAD
- /* isulad: dup2 pipe[0][0] to container stdin, pipe[1][1] to container stdout, pipe[2][1] to container stderr */
- if (handler->disable_pty) {
- if (handler->conf->console.pipes[0][1] >= 0) {
- close(handler->conf->console.pipes[0][1]);
- handler->conf->console.pipes[0][1] = -1;
- }
-
- if (handler->conf->console.pipes[0][0] >= 0) {
- ret = dup2(handler->conf->console.pipes[0][0], STDIN_FILENO);
- if (ret < 0)
- goto out_warn_father;
- }
-
- if (handler->conf->console.pipes[1][0] >= 0) {
- close(handler->conf->console.pipes[1][0]);
- handler->conf->console.pipes[1][0] = -1;
- }
-
- if (handler->conf->console.pipes[1][1] >= 0) {
- ret = dup2(handler->conf->console.pipes[1][1], STDOUT_FILENO);
- if (ret < 0)
- goto out_warn_father;
- }
- if (handler->conf->console.pipes[2][0] >= 0) {
- close(handler->conf->console.pipes[2][0]);
- handler->conf->console.pipes[2][0] = -1;
- }
-
- if (handler->conf->console.pipes[2][1] >= 0) {
- ret = dup2(handler->conf->console.pipes[2][1], STDERR_FILENO);
- if (ret < 0)
- goto out_warn_father;
- }
- }
-#endif
-
/* If we mounted a temporary proc, then unmount it now. */
tmp_proc_unmount(handler->conf);
@@ -1639,7 +1602,10 @@ static int do_start(void *data)
close_prot_errno_disarm(devnull_fd);
+#ifndef HAVE_ISULAD
+ // setsid in lxc_setup() -> lxc_setup_console()
setsid();
+#endif
if (handler->conf->init_cwd) {
#ifdef HAVE_ISULAD
@@ -1669,6 +1635,44 @@ static int do_start(void *data)
goto out_warn_father;
}
+#ifdef HAVE_ISULAD
+ /* close pipes after sync fds */
+ /* isulad: dup2 pipe[0][0] to container stdin, pipe[1][1] to container stdout, pipe[2][1] to container stderr */
+ if (handler->disable_pty) {
+ if (handler->conf->console.pipes[0][1] >= 0) {
+ close(handler->conf->console.pipes[0][1]);
+ handler->conf->console.pipes[0][1] = -1;
+ }
+
+ if (handler->conf->console.pipes[0][0] >= 0) {
+ ret = dup2(handler->conf->console.pipes[0][0], STDIN_FILENO);
+ if (ret < 0)
+ goto out_warn_father;
+ }
+
+ if (handler->conf->console.pipes[1][0] >= 0) {
+ close(handler->conf->console.pipes[1][0]);
+ handler->conf->console.pipes[1][0] = -1;
+ }
+
+ if (handler->conf->console.pipes[1][1] >= 0) {
+ ret = dup2(handler->conf->console.pipes[1][1], STDOUT_FILENO);
+ if (ret < 0)
+ goto out_warn_father;
+ }
+ if (handler->conf->console.pipes[2][0] >= 0) {
+ close(handler->conf->console.pipes[2][0]);
+ handler->conf->console.pipes[2][0] = -1;
+ }
+
+ if (handler->conf->console.pipes[2][1] >= 0) {
+ ret = dup2(handler->conf->console.pipes[2][1], STDERR_FILENO);
+ if (ret < 0)
+ goto out_warn_father;
+ }
+ }
+#endif
+
if (!lxc_sync_wait_parent(handler, START_SYNC_READY_START))
goto out_warn_father;
diff --git a/src/lxc/storage/dir.c b/src/lxc/storage/dir.c
index 09e08ad..57e0f04 100644
--- a/src/lxc/storage/dir.c
+++ b/src/lxc/storage/dir.c
@@ -178,6 +178,9 @@ int dir_mount(struct lxc_storage *bdev)
true);
}
} else {
+#ifdef HAVE_ISULAD
+ ret = mount(source, target, "bind", MS_BIND | MS_REC | (mnt_opts->mnt_flags & ~MS_RDONLY) | mnt_opts->prop_flags, mnt_opts->data);
+#else
ret = mount(source, target, "bind", MS_BIND | MS_REC | mnt_opts->mnt_flags | mnt_opts->prop_flags, mnt_opts->data);
if (!ret && (mnt_opts->mnt_flags & MS_RDONLY)) {
unsigned long mflags;
@@ -194,6 +197,7 @@ int dir_mount(struct lxc_storage *bdev)
else
TRACE("Remounted \"%s\" on \"%s\" read-only", source, target);
}
+#endif
}
if (ret < 0)
return syserror_set(ret, "Failed to mount \"%s\" onto \"%s\"", source, target);
diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c
index de7ea4f..acf6785 100644
--- a/src/lxc/terminal.c
+++ b/src/lxc/terminal.c
@@ -673,8 +673,10 @@ static int do_isulad_io(int fd, struct lxc_terminal *terminal)
TRACE("closed stdin pipe of container stdin");
} else {
// other fd should break io loop
+ close(fd);
return -1;
}
+ close(fd);
return 0;
}
@@ -863,7 +865,8 @@ static int lxc_terminal_ptx_io(struct lxc_terminal *terminal)
#ifdef HAVE_ISULAD
/* isulad: forward data to fifos */
- lxc_forward_data_to_fifo(&terminal->fifos, fd == terminal->pipes[2][0], buf, r);
+ /* fd is terminal->ptx and cannot be the err_fd */
+ lxc_forward_data_to_fifo(&terminal->fifos, false, buf, r);
#endif
/* write to terminal ringbuffer */
@@ -1768,7 +1771,7 @@ int lxc_terminal_add_fifos(struct lxc_conf *conf, const char *fifonames)
}
if (lxc_mainloop_add_handler(terminal->descr, fifofd_in,
- lxc_terminal_ptx_cb, default_cleanup_handler, terminal, "fifofd_in")) {
+ isulad_io_handler, default_cleanup_handler, terminal, "isulad_io_handler")) {
ERROR("console fifo not added to mainloop");
lxc_terminal_delete_fifo(fifofd_in, &terminal->fifos);
ret = -1;
@@ -1933,6 +1936,41 @@ int lxc_devpts_terminal(int devpts_fd, int *ret_ptx, int *ret_pty,
return 0;
}
+#ifdef HAVE_ISULAD
+static int lxc_terminal_create_default(struct lxc_conf *conf, struct lxc_terminal *terminal)
+{
+ int ret;
+ /* isulad: open default fifos */
+ ret = lxc_terminal_fifo_default(terminal);
+ if (ret < 0) {
+ ERROR("Failed to allocate fifo terminal");
+ return -ENODEV;
+ }
+
+ if (terminal->disable_pty) {
+ /* isulad: create 3 pipes */
+ /* for stdin */
+ if (pipe2(terminal->pipes[0], O_CLOEXEC)) {
+ ERROR("Failed to create stdin pipe");
+ return -ENODEV;
+ }
+
+ /* for stdout */
+ if (pipe2(terminal->pipes[1], O_CLOEXEC)) {
+ ERROR("Failed to create stdout pipe");
+ return -ENODEV;
+ }
+ /* for stderr */
+ if (pipe2(terminal->pipes[2], O_CLOEXEC)) {
+ ERROR("Failed to create stderr pipe");
+ return -ENODEV;
+ }
+
+ }
+ return 0;
+}
+#endif
+
int lxc_terminal_parent(struct lxc_conf *conf)
{
struct lxc_terminal *console = &conf->console;
@@ -1941,6 +1979,13 @@ int lxc_terminal_parent(struct lxc_conf *conf)
if (!wants_console(&conf->console))
return 0;
+#ifdef HAVE_ISULAD
+ ret = lxc_terminal_create_default(conf, console);
+ if (ret < 0) {
+ return ret;
+ }
+#endif
+
/* Allocate console from the container's devpts. */
if (conf->pty_max > 1)
return 0;
@@ -1993,45 +2038,24 @@ static int lxc_terminal_create_native(const char *name, const char *lxcpath,
int lxc_terminal_create(const char *name, const char *lxcpath,
struct lxc_conf *conf, struct lxc_terminal *terminal)
{
-#ifndef HAVE_ISULAD
- if (!lxc_terminal_create_native(name, lxcpath, terminal))
- return 0;
-#else
- int ret;
- /* isulad: open default fifos */
- ret = lxc_terminal_fifo_default(terminal);
- if (ret < 0) {
- ERROR("Failed to allocate fifo terminal");
+#ifdef HAVE_ISULAD
+ int ret = lxc_terminal_create_default(conf, terminal);
+ if (ret != 0) {
lxc_terminal_delete(terminal);
- return -ENODEV;
+ return ret;
}
- if (terminal->disable_pty) {
- /* isulad: create 3 pipes */
- /* for stdin */
- if (pipe2(terminal->pipes[0], O_CLOEXEC)) {
- ERROR("Failed to create stdin pipe");
- lxc_terminal_delete(terminal);
- return -ENODEV;
- }
+ if (!terminal->disable_pty) {
+ return lxc_terminal_create_foreign(conf, terminal);
+ }
- /* for stdout */
- if (pipe2(terminal->pipes[1], O_CLOEXEC)) {
- ERROR("Failed to create stdout pipe");
- lxc_terminal_delete(terminal);
- return -ENODEV;
- }
- /* for stderr */
- if (pipe2(terminal->pipes[2], O_CLOEXEC)) {
- ERROR("Failed to create stderr pipe");
- lxc_terminal_delete(terminal);
- return -ENODEV;
- }
+ return 0;
+#else
+ if (!lxc_terminal_create_native(name, lxcpath, terminal))
return 0;
- }
-#endif
return lxc_terminal_create_foreign(conf, terminal);
+#endif
}
int lxc_terminal_setup(struct lxc_conf *conf)
--
2.25.1