[Devel] [PATCH RHEL8 COMMIT] ve/vtty: Don't close unread master peer if slave is nonzero

Konstantin Khorenko khorenko at virtuozzo.com
Mon Jul 26 20:15:27 MSK 2021


The commit is pushed to "branch-rh8-4.18.0-305.3.1.vz8.7.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-305.3.1.el8
------>
commit 80bd801e427dac64132c07f95ea3d4252d417dcd
Author: Cyrill Gorcunov <gorcunov at virtuozzo.com>
Date:   Mon Jul 26 20:15:26 2021 +0300

    ve/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 <gorcunov at virtuozzo.com>
    
    Reviewed-by: Vladimir Davydov <vdavydov at 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;
      ^
    
    mFixes commit 26d58a8eea6ea ("ve/vtty: Don't close unread master peer if slave is nonzero")
    
    Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
    
    https://jira.sw.ru/browse/PSBM-132299
    
    (cherry-picked from b682fbd16b58e3a6c9f83ab8118c3c9845553dfa)
    Signed-off-by: Valeriy Vdovin <valeriy.vdovin at virtuozzo.com>
---
 drivers/tty/pty.c    | 27 +++++++++++++++++++++++++++
 drivers/tty/tty_io.c |  8 ++++++++
 include/linux/ve.h   |  3 +++
 3 files changed, 38 insertions(+)

diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
index 2a8ed5151655..78ab6562e4d8 100644
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -946,6 +946,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 fcb4139b4d83..5c4e68758c97 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -1690,6 +1690,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 df4a0077212b..73a7216e7246 100644
--- a/include/linux/ve.h
+++ b/include/linux/ve.h
@@ -17,6 +17,7 @@
 #include <linux/kmapset.h>
 #include <linux/kthread.h>
 #include <linux/binfmts.h>
+#include <linux/tty_driver.h>
 #include <asm/vdso.h>
 
 struct nsproxy;
@@ -207,6 +208,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);
 #endif /* CONFIG_TTY */
 
 extern struct cgroup *cgroup_get_ve_root1(struct cgroup *cgrp);


More information about the Devel mailing list