2
0
mirror of git://github.com/lxc/lxc synced 2025-08-31 16:01:03 +00:00

conf: support console setup on containers without rootfs

This depends on the new mount api.

Closes #3164.
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
Christian Brauner
2020-05-04 13:26:43 +02:00
parent 234998b4f2
commit cf68ffd9e2
5 changed files with 111 additions and 20 deletions

View File

@@ -622,7 +622,7 @@ AC_CHECK_HEADER([ifaddrs.h],
AC_HEADER_MAJOR
# Check for some syscalls functions
AC_CHECK_FUNCS([setns pivot_root sethostname unshare rand_r confstr faccessat gettid memfd_create])
AC_CHECK_FUNCS([setns pivot_root sethostname unshare rand_r confstr faccessat gettid memfd_create move_mount open_tree])
# Check for strerror_r() support. Defines:
# - HAVE_STRERROR_R if available

View File

@@ -1576,7 +1576,8 @@ static int setup_personality(int persona)
}
static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs,
const struct lxc_terminal *console)
const struct lxc_terminal *console,
int pts_mnt_fd)
{
int ret;
char path[PATH_MAX];
@@ -1589,7 +1590,8 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs,
if (ret < 0 || (size_t)ret >= sizeof(path))
return -1;
/* When we are asked to setup a console we remove any previous
/*
* When we are asked to setup a console we remove any previous
* /dev/console bind-mounts.
*/
if (file_exists(path)) {
@@ -1600,7 +1602,8 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs,
DEBUG("Cleared all (%d) mounts from \"%s\"", ret, path);
}
/* For unprivileged containers autodev or automounts will already have
/*
* For unprivileged containers autodev or automounts will already have
* taken care of creating /dev/console.
*/
ret = mknod(path, S_IFREG | 0000, 0);
@@ -1611,17 +1614,20 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs,
if (ret < 0)
return log_error_errno(-errno, errno, "Failed to set mode \"0%o\" to \"%s\"", S_IXUSR | S_IXGRP, console->name);
ret = safe_mount(console->name, path, "none", MS_BIND, 0, rootfs_path);
if (pts_mnt_fd >= 0)
ret = move_mount(pts_mnt_fd, "", -EBADF, path, MOVE_MOUNT_F_EMPTY_PATH);
else
ret = safe_mount(console->name, path, "none", MS_BIND, 0, rootfs_path);
if (ret < 0)
return log_error_errno(-1, errno, "Failed to mount \"%s\" on \"%s\"", console->name, path);
return log_error_errno(-1, errno, "Failed to mount %d(%s) on \"%s\"", pts_mnt_fd, console->name, path);
DEBUG("Mounted pts device \"%s\" onto \"%s\"", console->name, path);
DEBUG("Mounted pts device %d(%s) onto \"%s\"", pts_mnt_fd, console->name, path);
return 0;
}
static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs,
const struct lxc_terminal *console,
char *ttydir)
char *ttydir, int pts_mnt_fd)
{
int ret;
char path[PATH_MAX], lxcpath[PATH_MAX];
@@ -1669,9 +1675,12 @@ static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs,
return log_error_errno(-errno, errno, "Failed to set mode \"0%o\" to \"%s\"", S_IXUSR | S_IXGRP, console->name);
/* bind mount console->name to '/dev/<ttydir>/console' */
ret = safe_mount(console->name, lxcpath, "none", MS_BIND, 0, rootfs_path);
if (pts_mnt_fd >= 0)
ret = move_mount(pts_mnt_fd, "", -EBADF, path, MOVE_MOUNT_F_EMPTY_PATH);
else
ret = safe_mount(console->name, lxcpath, "none", MS_BIND, 0, rootfs_path);
if (ret < 0)
return log_error_errno(-1, errno, "Failed to mount \"%s\" on \"%s\"", console->name, lxcpath);
return log_error_errno(-1, errno, "Failed to mount %d(%s) on \"%s\"", pts_mnt_fd, console->name, lxcpath);
DEBUG("Mounted \"%s\" onto \"%s\"", console->name, lxcpath);
/* bind mount '/dev/<ttydir>/console' to '/dev/console' */
@@ -1685,13 +1694,14 @@ static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs,
}
static int lxc_setup_console(const struct lxc_rootfs *rootfs,
const struct lxc_terminal *console, char *ttydir)
const struct lxc_terminal *console, char *ttydir,
int pts_mnt_fd)
{
if (!ttydir)
return lxc_setup_dev_console(rootfs, console);
return lxc_setup_dev_console(rootfs, console, pts_mnt_fd);
return lxc_setup_ttydir_console(rootfs, console, ttydir);
return lxc_setup_ttydir_console(rootfs, console, ttydir, pts_mnt_fd);
}
static int parse_mntopt(char *opt, unsigned long *flags, char **data, size_t size)
@@ -3267,6 +3277,7 @@ static int lxc_setup_boot_id(void)
int lxc_setup(struct lxc_handler *handler)
{
__do_close int pts_mnt_fd = -EBADF;
int ret;
const char *lxcpath = handler->lxcpath, *name = handler->name;
struct lxc_conf *lxc_conf = handler->conf;
@@ -3305,6 +3316,12 @@ int lxc_setup(struct lxc_handler *handler)
return log_error(-1, "Failed to send network device names and ifindices to parent");
}
pts_mnt_fd = open_tree(-EBADF, lxc_conf->console.name,
OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC | AT_EMPTY_PATH);
if (pts_mnt_fd < 0)
SYSTRACE("Failed to create detached mount for container's console \"%s\"",
lxc_conf->console.name);
if (lxc_conf->autodev > 0) {
ret = mount_autodev(name, &lxc_conf->rootfs, lxc_conf->autodevtmpfssize, lxcpath);
if (ret < 0)
@@ -3377,8 +3394,12 @@ int lxc_setup(struct lxc_handler *handler)
if (!verify_start_hooks(lxc_conf))
return log_error(-1, "Failed to verify start hooks");
ret = lxc_create_tmp_proc_mount(lxc_conf);
if (ret < 0)
return log_error(-1, "Failed to \"/proc\" LSMs");
ret = lxc_setup_console(&lxc_conf->rootfs, &lxc_conf->console,
lxc_conf->ttys.dir);
lxc_conf->ttys.dir, pts_mnt_fd);
if (ret < 0)
return log_error(-1, "Failed to setup console");
@@ -3386,10 +3407,6 @@ int lxc_setup(struct lxc_handler *handler)
if (ret < 0)
return log_error(-1, "Failed to setup \"/dev\" symlinks");
ret = lxc_create_tmp_proc_mount(lxc_conf);
if (ret < 0)
return log_error(-1, "Failed to \"/proc\" LSMs");
ret = lxc_setup_rootfs_switch_root(&lxc_conf->rootfs);
if (ret < 0)
return log_error(-1, "Failed to pivot root into rootfs");
@@ -4476,8 +4493,8 @@ int userns_exec_mapped_root(const char *path, int path_fd,
if (!gid_valid(container_host_gid))
return log_error(-1, "No gid mapping for container root");
if (path) {
fd = open(path, O_RDWR | O_CLOEXEC | O_NOCTTY);
if (path_fd < 0) {
fd = open(path, O_RDWR | O_CLOEXEC | O_NOCTTY | O_PATH);
if (fd < 0)
return log_error_errno(-errno, errno, "Failed to open \"%s\"", path);
target_fd = fd;

View File

@@ -57,6 +57,20 @@
#define CAP_SETGID 6
#endif
/* move_mount */
#ifndef MOVE_MOUNT_F_EMPTY_PATH
#define MOVE_MOUNT_F_EMPTY_PATH 0x00000004 /* Empty from path permitted */
#endif
/* open_tree */
#ifndef OPEN_TREE_CLONE
#define OPEN_TREE_CLONE 1 /* Clone the target tree and attach the clone */
#endif
#ifndef OPEN_TREE_CLOEXEC
#define OPEN_TREE_CLOEXEC O_CLOEXEC /* Close the file on execve() */
#endif
/* prctl */
#ifndef PR_CAPBSET_READ
#define PR_CAPBSET_READ 23

View File

@@ -501,4 +501,40 @@
#endif
#endif
#ifndef __NR_move_mount
#if defined __alpha__
#define __NR_move_mount 539
#elif defined _MIPS_SIM
#if _MIPS_SIM == _MIPS_SIM_ABI32 /* o32 */
#define __NR_move_mount 4429
#endif
#if _MIPS_SIM == _MIPS_SIM_NABI32 /* n32 */
#define __NR_move_mount 6429
#endif
#if _MIPS_SIM == _MIPS_SIM_ABI64 /* n64 */
#define __NR_move_mount 5429
#endif
#else
#define __NR_move_mount 429
#endif
#endif
#ifndef __NR_open_tree
#if defined __alpha__
#define __NR_open_tree 538
#elif defined _MIPS_SIM
#if _MIPS_SIM == _MIPS_SIM_ABI32 /* o32 */
#define __NR_open_tree 4428
#endif
#if _MIPS_SIM == _MIPS_SIM_NABI32 /* n32 */
#define __NR_open_tree 6428
#endif
#if _MIPS_SIM == _MIPS_SIM_ABI64 /* n64 */
#define __NR_open_tree 5428
#endif
#else
#define __NR_open_tree 428
#endif
#endif
#endif /* __LXC_SYSCALL_NUMBERS_H */

View File

@@ -137,4 +137,28 @@ static int faccessat(int __fd, const char *__file, int __type, int __flag)
}
#endif
#ifndef HAVE_MOVE_MOUNT
static inline int move_mount_lxc(int from_dfd, const char *from_pathname,
int to_dfd, const char *to_pathname,
unsigned int flags)
{
return syscall(__NR_move_mount, from_dfd, from_pathname, to_dfd,
to_pathname, flags);
}
#define move_mount move_mount_lxc
#else
extern int move_mount(int from_dfd, const char *from_pathname, int to_dfd,
const char *to_pathname, unsigned int flags);
#endif
#ifndef HAVE_OPEN_TREE
static inline int open_tree_lxc(int dfd, const char *filename, unsigned int flags)
{
return syscall(__NR_open_tree, dfd, filename, flags);
}
#define open_tree open_tree_lxc
#else
extern int open_tree(int dfd, const char *filename, unsigned int flags);
#endif
#endif /* __LXC_SYSCALL_WRAPPER_H */