[Devel] [PATCH RHEL7 COMMIT] ve/vtty: Don't close unread master peer if slave is nonzero
Konstantin Khorenko
khorenko at virtuozzo.com
Mon Dec 28 05:32:04 PST 2015
The commit is pushed to "branch-rh7-3.10.0-229.7.2.vz7.9.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-229.7.2.vz7.9.18
------>
commit 26d58a8eea6eabd19406627f647e414a8de84722
Author: Cyrill Gorcunov <gorcunov at virtuozzo.com>
Date: Mon Dec 28 17:32:03 2015 +0400
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>
---
drivers/tty/pty.c | 27 +++++++++++++++++++++++++++
drivers/tty/tty_io.c | 7 ++-----
include/linux/ve.h | 2 ++
3 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
index 93ab642..f11333c 100644
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -1259,6 +1259,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)
+{
+ lockdep_assert_held(&tty_mutex);
+ int pty_master;
+
+ 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 fc80ccb..4bdee1bc 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -1756,11 +1756,8 @@ int tty_release(struct inode *inode, struct file *filp)
(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);
diff --git a/include/linux/ve.h b/include/linux/ve.h
index ee299e3..b9374a1 100644
--- a/include/linux/ve.h
+++ b/include/linux/ve.h
@@ -230,6 +230,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 */
static inline int ve_mount_allowed(void)
More information about the Devel
mailing list