On Mon, Dec 28, 2015 at 05:23:21PM +0300, Konstantin Khorenko wrote: > On 12/05/2015 08:21 PM, Cyrill Gorcunov wrote: > >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> > >CC: Vladimir Davydov <vdavy...@virtuozzo.com> > >CC: Konstantin Khorenko <khore...@virtuozzo.com>
For some reason gcc didn't compline. Update attached.
From: Cyrill Gorcunov <gorcu...@virtuozzo.com> Subject: [PATCH rh7] vtty: Don't close unread master peer if slave is nonzero 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> CC: Vladimir Davydov <vdavy...@virtuozzo.com> CC: Konstantin Khorenko <khore...@virtuozzo.com> --- drivers/tty/pty.c | 28 ++++++++++++++++++++++++++++ drivers/tty/tty_io.c | 7 ++----- include/linux/ve.h | 2 ++ 3 files changed, 32 insertions(+), 5 deletions(-) Index: linux-pcs7.git/drivers/tty/pty.c =================================================================== --- linux-pcs7.git.orig/drivers/tty/pty.c +++ linux-pcs7.git/drivers/tty/pty.c @@ -1259,6 +1259,34 @@ struct tty_driver *vtty_driver(dev_t dev 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; Index: linux-pcs7.git/drivers/tty/tty_io.c =================================================================== --- linux-pcs7.git.orig/drivers/tty/tty_io.c +++ linux-pcs7.git/drivers/tty/tty_io.c @@ -1756,11 +1756,8 @@ int tty_release(struct inode *inode, str (o_tty->count <= (pty_master ? 1 : 0)); do_sleep = 0; -#ifdef CONFIG_VE - if (!o_tty_closing && - test_bit(TTY_PINNED_BY_OTHER, &tty->flags)) - tty_closing = 0; -#endif + vtty_release(tty, o_tty, &tty_closing, &o_tty_closing); + if (tty_closing) { if (waitqueue_active(&tty->read_wait)) { wake_up_poll(&tty->read_wait, POLLIN); Index: linux-pcs7.git/include/linux/ve.h =================================================================== --- linux-pcs7.git.orig/include/linux/ve.h +++ linux-pcs7.git/include/linux/ve.h @@ -224,6 +224,8 @@ struct user_namespace *ve_init_user_ns(v 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); #endif /* CONFIG_TTY */ #else /* CONFIG_VE */
_______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel