[CRIU] [PATCH] tty: Restore controlling terminal once per session

Cyrill Gorcunov gorcunov at openvz.org
Thu Nov 5 09:06:48 PST 2015


There might be several same terminals opened (say
tty6 or whatever) which gonna look as a seaprate
files but actually pointing into same tty kernel
instance. Moreover if it's a controlling terminal
we will be trying to restore it as many times as
find non zero sid on the peer.

Instead lets do a simple trick first: choose a leader
from the terminal group and use it only for controlling
terminal restoration.

https://jira.sw.ru/browse/PSBM-40969

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 tty.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/tty.c b/tty.c
index 63a6ba24eb73..6d239548248e 100644
--- a/tty.c
+++ b/tty.c
@@ -92,6 +92,8 @@ struct tty_info {
 
 	bool				create;
 	bool				inherit;
+
+	struct tty_info			*ctl_tty;
 };
 
 struct tty_dump_info {
@@ -1072,6 +1074,8 @@ static int tty_find_restoring_task(struct tty_info *info)
 		return 0;
 
 	if (info->tie->sid) {
+		if (info->ctl_tty != info)
+			return 0;
 		if (!tty_is_master(info)) {
 			if (tty_has_active_pair(info))
 				return 0;
@@ -1159,6 +1163,29 @@ int tty_setup_slavery(void)
 {
 	struct tty_info *info, *peer, *m;
 
+	/*
+	 * The image may carry several terminals opened
+	 * belonging to the same session, so choose the
+	 * leader which gonna be setting up the controlling
+	 * terminal.
+	 */
+	list_for_each_entry(info, &all_ttys, list) {
+		if (!info->tie->sid || info->ctl_tty)
+			continue;
+
+		info->ctl_tty = info;
+		pr_debug("ctl tty master %x\n", info->tfe->id);
+		peer = info;
+		list_for_each_entry_safe_continue(peer, m, &all_ttys, list) {
+			if (!peer->tie->sid || peer->ctl_tty)
+				continue;
+			if (peer->tie->sid == info->tie->sid) {
+				pr_debug(" `- slave %x\n", peer->tfe->id);
+				peer->ctl_tty = info;
+			}
+		}
+	}
+
 	list_for_each_entry(info, &all_ttys, list) {
 		if (tty_find_restoring_task(info))
 			return -1;
@@ -1316,6 +1343,7 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg)
 	info->driver = get_tty_driver(major(info->tie->rdev), minor(info->tie->rdev));
 	info->create = tty_is_master(info);
 	info->inherit = false;
+	info->ctl_tty = NULL;
 
 	if (verify_info(info))
 		return -1;
-- 
2.4.3



More information about the CRIU mailing list