Commit 04f7131a authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Pavel Emelyanov

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-40969Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Reviewed-by: 's avatarAndrew Vagin <avagin@odin.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 8796b18e
......@@ -92,6 +92,8 @@ struct tty_info {
bool create;
bool inherit;
struct tty_info *ctl_tty;
};
struct tty_dump_info {
......@@ -1079,6 +1081,14 @@ static int tty_find_restoring_task(struct tty_info *info)
goto shell_job;
}
/*
* 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
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment