2
0
mirror of git://github.com/lxc/lxc synced 2025-08-30 21:50:07 +00:00

conf: allow for tty allocation even when container did not request separate devpts instance

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
Christian Brauner
2021-08-17 11:38:11 +02:00
parent b081cb55e4
commit 03585adc0e

View File

@@ -1666,10 +1666,12 @@ static int lxc_setup_devpts_child(struct lxc_handler *handler)
__do_close int devpts_fd = -EBADF, fd_fs = -EBADF; __do_close int devpts_fd = -EBADF, fd_fs = -EBADF;
struct lxc_conf *conf = handler->conf; struct lxc_conf *conf = handler->conf;
struct lxc_rootfs *rootfs = &conf->rootfs; struct lxc_rootfs *rootfs = &conf->rootfs;
size_t pty_max = conf->pty_max;
int ret; int ret;
if (conf->pty_max <= 0) pty_max += conf->ttys.max;
return log_debug(0, "No new devpts instance will be mounted since no pts devices are requested"); if (pty_max <= 0)
return log_debug(0, "No new devpts instance will be mounted since no pts devices are required");
ret = strnprintf(rootfs->buf, sizeof(rootfs->buf), ret = strnprintf(rootfs->buf, sizeof(rootfs->buf),
"/proc/self/fd/%d/pts", rootfs->dfd_dev); "/proc/self/fd/%d/pts", rootfs->dfd_dev);
@@ -1708,7 +1710,7 @@ static int lxc_setup_devpts_child(struct lxc_handler *handler)
if (ret < 0) if (ret < 0)
return syserror("Failed to set \"mode=0620\" property on devpts filesystem context %d", fd_fs); return syserror("Failed to set \"mode=0620\" property on devpts filesystem context %d", fd_fs);
ret = fs_set_property(fd_fs, "max", fdstr(conf->pty_max)); ret = fs_set_property(fd_fs, "max", fdstr(pty_max));
if (ret < 0) if (ret < 0)
return syserror("Failed to set \"max=%zu\" property on devpts filesystem context %d", conf->pty_max, fd_fs); return syserror("Failed to set \"max=%zu\" property on devpts filesystem context %d", conf->pty_max, fd_fs);
@@ -1738,7 +1740,7 @@ static int lxc_setup_devpts_child(struct lxc_handler *handler)
*/ */
ret = strnprintf(devpts_mntopts, sizeof(devpts_mntopts), "%s,max=%zu", ret = strnprintf(devpts_mntopts, sizeof(devpts_mntopts), "%s,max=%zu",
default_devpts_mntopts, conf->pty_max); default_devpts_mntopts, pty_max);
if (ret < 0) if (ret < 0)
return -1; return -1;
@@ -1781,8 +1783,23 @@ static int lxc_setup_devpts_child(struct lxc_handler *handler)
DEBUG("Mounted new devpts instance with options \"%s\"", *opts); DEBUG("Mounted new devpts instance with options \"%s\"", *opts);
} }
handler->conf->devpts_fd = move_fd(devpts_fd); handler->conf->devpts_fd = move_fd(devpts_fd);
/*
* In order to allocate terminal devices the devpts filesystem will
* have to be attached to the filesystem at least ones in the new mount
* api. The reason is lengthy but the gist is that until the new mount
* has been attached to the filesystem it is a detached mount with an
* anonymous mount mamespace attached to it for which the kernel
* refuses certain operations.
* We end up here if the user has requested to allocate tty devices
* while not requestig pty devices be made available to the container.
* We only need the devpts_fd to allocate tty devices.
*/
if (conf->pty_max <= 0)
return 0;
/* Remove any pre-existing /dev/ptmx file. */ /* Remove any pre-existing /dev/ptmx file. */
ret = unlinkat(rootfs->dfd_dev, "ptmx", 0); ret = unlinkat(rootfs->dfd_dev, "ptmx", 0);
if (ret < 0) { if (ret < 0) {
@@ -1822,6 +1839,30 @@ static int lxc_setup_devpts_child(struct lxc_handler *handler)
return 0; return 0;
} }
static int lxc_finish_devpts_child(struct lxc_handler *handler)
{
struct lxc_conf *conf = handler->conf;
struct lxc_rootfs *rootfs = &conf->rootfs;
int ret;
if (conf->pty_max > 0)
return 0;
/*
* We end up here if the user has requested to allocate tty devices
* while not requestig pty devices be made available to the container.
* This means we can unmount the devpts instance. We only need the
* devpts_fd to allocate tty devices.
*/
ret = strnprintf(rootfs->buf, sizeof(rootfs->buf),
"/proc/self/fd/%d/pts", rootfs->dfd_dev);
if (ret < 0)
return syserror("Failed to create path");
close_prot_errno_disarm(conf->devpts_fd);
return umount2(rootfs->buf, MNT_DETACH);
}
static int lxc_send_devpts_to_parent(struct lxc_handler *handler) static int lxc_send_devpts_to_parent(struct lxc_handler *handler)
{ {
int ret; int ret;
@@ -4347,6 +4388,10 @@ int lxc_setup(struct lxc_handler *handler)
if (ret < 0) if (ret < 0)
return log_error(-1, "Failed to prepare new devpts instance"); return log_error(-1, "Failed to prepare new devpts instance");
ret = lxc_finish_devpts_child(handler);
if (ret < 0)
return log_error(-1, "Failed to finish devpts setup");
ret = lxc_setup_console(handler, &lxc_conf->rootfs, &lxc_conf->console, ret = lxc_setup_console(handler, &lxc_conf->rootfs, &lxc_conf->console,
lxc_conf->ttys.dir); lxc_conf->ttys.dir);
if (ret < 0) if (ret < 0)