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:
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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 */
|
||||
|
@@ -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 */
|
||||
|
Reference in New Issue
Block a user