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

Cyrill Gorcunov gorcunov at gmail.com
Fri Nov 6 05:07:43 PST 2015


On Thu, Nov 05, 2015 at 08:06:48PM +0300, Cyrill Gorcunov wrote:
> 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.
> 

An updated variant attached.
-------------- next part --------------
>From 64eafbd295f2e907793f81e3c7bff4904b5342c0 Mon Sep 17 00:00:00 2001
From: Cyrill Gorcunov <gorcunov at openvz.org>
Date: Thu, 5 Nov 2015 20:05:41 +0300
Subject: [PATCH v2] tty: Restore controlling terminal once per session

There might be several same terminals opened (say
tty6 or whatever) which gonna look as separate
files but actually pointing to the 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 a peer.

Instead lets do a simple trick first: choose a leader
from a 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 | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/tty.c b/tty.c
index 63a6ba24eb73..3f1bc18be664 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 {
@@ -1080,6 +1082,14 @@ static int tty_find_restoring_task(struct tty_info *info)
 		}
 
 		/*
+		 * Restoring via leader only. All files
+		 * opened over same real tty get propagated
+		 * automatically by kernel itself.
+		 */
+		if (info->ctl_tty != info)
+			return 0;
+
+		/*
 		 * Find out the task which is session leader
 		 * and it can restore the controlling terminal
 		 * for us.
@@ -1159,6 +1169,31 @@ 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 ||
+		    info->driver->type == TTY_TYPE__CTTY)
+			continue;
+
+		info->ctl_tty = info;
+		pr_debug("ctl tty leader %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 ||
+			    peer->driver->type == TTY_TYPE__CTTY)
+				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 +1351,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