[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