When there are several files opened on /dev/console from inside of a container and noone hooked on master peer, any close called cause master peer to be freed with TTY_CLOSING bit set. So that next "vzctl console $ctid $ttynum" call force kernel to allocate new vtty pair and in result we can't login into the container.
We've woraround master close when there is an active slave assigned but I miss the scenario when several fd = open(/dev/console) done and then one calls for close(fd). Lets test if master peer is about to close while there are still active slave (and move it into vtty_release helper). https://jira.sw.ru/browse/PSBM-41985 https://jira.sw.ru/browse/PSBM-41672 Signed-off-by: Cyrill Gorcunov <gorcu...@virtuozzo.com> Reviewed-by: Vladimir Davydov <vdavy...@virtuozzo.com> +++ ve/vtty: fix mixed declarations and code in vtty_release() Compilation error fixed: drivers/tty/pty.c: In function 'vtty_release': drivers/tty/pty.c:1266:2: error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement] int pty_master; ^ Signed-off-by: Konstantin Khorenko <khore...@virtuozzo.com> https://jira.sw.ru/browse/PSBM-132299 (cherry-picked from b682fbd16b58e3a6c9f83ab8118c3c9845553dfa) Signed-off-by: Valeriy Vdovin <valeriy.vdo...@virtuozzo.com> --- drivers/tty/pty.c | 27 +++++++++++++++++++++++++++ drivers/tty/tty_io.c | 8 ++++++++ include/linux/ve.h | 6 +++++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 12f4d41e92ed..78408b7eb15a 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -940,6 +940,33 @@ struct tty_driver *vtty_driver(dev_t dev, int *index) return NULL; } +void vtty_release(struct tty_struct *tty, struct tty_struct *o_tty, + int *tty_closing, int *o_tty_closing) +{ + int pty_master; + lockdep_assert_held(&tty_mutex); + + if (tty->driver != vttym_driver && + tty->driver != vttys_driver) + return; + + pty_master = (tty->driver == vttym_driver); + + /* + * Do not close master while slave is active. + */ + if (!*o_tty_closing && pty_master) + *tty_closing = 0; + + /* + * Do not close master if we've closing + * not the last slave even if there is no + * readers on the master. + */ + if (*o_tty_closing && !*tty_closing && !pty_master) + *o_tty_closing = 0; +} + static void ve_vtty_fini(void *data) { struct ve_struct *ve = data; diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 05aeee7be09a..b41ee2d7b33e 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1798,6 +1798,14 @@ int tty_release(struct inode *inode, struct file *filp) */ while (1) { do_sleep = 0; + /* + * FIXME: Need to figure out how to prevent closing + * peers when one is still active, unlike traditional + * PTYs we don't close master if slave is closed. + */ +#if 0 + vtty_release(tty, o_tty, &tty_closing, &o_tty_closing); +#endif if (tty->count <= 1) { if (waitqueue_active(&tty->read_wait)) { diff --git a/include/linux/ve.h b/include/linux/ve.h index 91ee80b58ecf..ffe068ec5fe7 100644 --- a/include/linux/ve.h +++ b/include/linux/ve.h @@ -12,10 +12,12 @@ #include <linux/types.h> #include <linux/ve_proto.h> +#include <linux/vzstat.h> #include <linux/cgroup.h> #include <linux/kmapset.h> #include <linux/kthread.h> -#include <linux/vzstat.h> +#include <linux/binfmts.h> +#include <linux/tty_driver.h> #include <asm/vdso.h> #include <linux/time_namespace.h> #include <linux/binfmts.h> @@ -171,6 +173,8 @@ struct user_namespace *ve_init_user_ns(void); extern struct tty_driver *vtty_driver(dev_t dev, int *index); extern struct tty_driver *vtty_console_driver(int *index); extern int vtty_open_master(envid_t veid, int idx); +extern void vtty_release(struct tty_struct *tty, struct tty_struct *o_tty, + int *tty_closing, int *o_tty_closing); extern bool vtty_is_master(struct tty_struct *tty); #endif /* CONFIG_TTY */ -- 2.31.1 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel