[CRIU] [PATCH 1/2] tty: Restore controlling terminal via master peer if slave present
Cyrill Gorcunov
gorcunov at openvz.org
Tue Mar 19 09:00:23 EDT 2013
In case if there both master/slave peers do have SIDs present prefer the
master peer to be used as a carry for service controlling terminal. This is
more correct because master peers are to be created earlier than slaves.
Reported-by: Andrey Vagin <avagin at openvz.org>
Inspired-by: Andrey Vagin <avagin at openvz.org>
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
Andrew, could you please check if it does a trick for you too.
tty.c | 46 ++++++++++++++++++++++++++++++++++++++++------
1 file changed, 40 insertions(+), 6 deletions(-)
diff --git a/tty.c b/tty.c
index 251930b..c77a82a 100644
--- a/tty.c
+++ b/tty.c
@@ -401,9 +401,14 @@ static bool pty_is_hung(struct tty_info *info)
return info->tie->termios == NULL;
}
+static int tty_peer_id_offset(struct tty_info *info)
+{
+ return pty_is_master(info) ? -1 : + 1;
+}
+
static bool tty_has_active_pair(struct tty_info *info)
{
- int d = pty_is_master(info) ? -1 : + 1;
+ int d = tty_peer_id_offset(info);
return test_bit(info->tfe->tty_info_id + d,
tty_active_pairs);
@@ -689,6 +694,25 @@ static struct pstree_item *find_first_sid(int sid)
return NULL;
}
+static struct tty_info *find_peer_by_id(struct tty_info *info)
+{
+ struct tty_info *i, *m;
+ int id;
+
+ id = info->tfe->tty_info_id + tty_peer_id_offset(info);
+
+ list_for_each_entry(i, &all_ttys, list) {
+ if (i->tfe->tty_info_id == id)
+ return i;
+ list_for_each_entry(m, &info->sibling, sibling) {
+ if (m->tfe->tty_info_id == id)
+ return m;
+ }
+ }
+
+ return NULL;
+}
+
static int tty_find_restoring_task(struct tty_info *info)
{
struct pstree_item *item;
@@ -701,9 +725,9 @@ static int tty_find_restoring_task(struct tty_info *info)
* SID is present on a peer
* ------------------------
*
- * - if it's master peer and we have as well a slave
+ * - if it's slave peer and we have as well a master
* peer then prefer restore controlling terminal
- * via slave peer
+ * via master peer
*
* - if it's master peer without slave, there must be
* a SID leader who will be restoring the peer
@@ -731,9 +755,19 @@ static int tty_find_restoring_task(struct tty_info *info)
}
if (info->tie->sid) {
- if (pty_is_master(info)) {
- if (tty_has_active_pair(info))
- return 0;
+ /*
+ * Prefer master peer to restore a session.
+ */
+ if (!pty_is_master(info)) {
+ struct tty_info *peer;
+
+ if (tty_has_active_pair(info)) {
+ peer = find_peer_by_id(info);
+ BUG_ON(!peer);
+
+ if (peer->tie->sid)
+ return 0;
+ }
}
/*
--
1.8.1.4
More information about the CRIU
mailing list