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

Reply via email to