[CRIU] [PATCH 6/6] tty: Migrate tty slave peer connections

Cyrill Gorcunov gorcunov at openvz.org
Wed Sep 26 09:05:47 EDT 2012


In case if we've dumped a slave peer only (say
a user dumps `top' application) we should migrate
it on current active terminal.

Also if --const-tty is passed we don't do that but
try to restore slave connection assuming the master
peer does exist.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 include/tty.h |    1 +
 tty.c         |   58 +++++++++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/include/tty.h b/include/tty.h
index 982bffb..6e12ccb 100644
--- a/include/tty.h
+++ b/include/tty.h
@@ -12,6 +12,7 @@
 # define PTMX_MINOR 2
 #endif
 #define PTS_FMT		"/dev/pts/%d"
+#define PTS_CURRENT	"/dev/tty"
 
 extern int dump_tty(struct fd_parms *p, int lfd, const struct cr_fdset *set);
 extern int collect_tty(void);
diff --git a/tty.c b/tty.c
index 1ee1b9b..ac2b57e 100644
--- a/tty.c
+++ b/tty.c
@@ -546,21 +546,32 @@ static int receive_tty(struct tty_info *info)
 	return fd;
 }
 
-static int pty_open_fake_ptmx(struct tty_info *slave)
+static int pty_open_slave(struct tty_info *slave)
 {
 	int master = -1, ret = -1, fd = -1;
 	char pts_name[64];
 
-	snprintf(pts_name, sizeof(pts_name), PTS_FMT, slave->tie->pty->index);
+	/*
+	 * If we were asked to not migrate tty connections,
+	 * we try to connect on existing slave interface. It's
+	 * hard to think who might need it, but we are to provide
+	 * such way.
+	 */
+	if (likely(!opts.const_tty))
+		strncpy(pts_name, PTS_CURRENT, sizeof(pts_name));
+	else
+		snprintf(pts_name, sizeof(pts_name), PTS_FMT, slave->tie->pty->index);
 
-	master = pty_open_ptmx_index(O_RDONLY, slave->tie->pty->index);
-	if (master < 0) {
-		pr_perror("Can't open fale %x (index %d)",
-			  slave->tfe->id, slave->tie->pty->index);
-		return -1;
-	}
+	if (!slave->tie->termios) {
+		master = pty_open_ptmx_index(O_RDONLY, slave->tie->pty->index);
+		if (master < 0) {
+			pr_perror("Can't open fale %x (index %d)",
+				  slave->tfe->id, slave->tie->pty->index);
+			return -1;
+		}
 
-	unlock_pty(master);
+		unlock_pty(master);
+	}
 
 	fd = open(pts_name, slave->tfe->flags);
 	if (fd < 0) {
@@ -571,6 +582,15 @@ static int pty_open_fake_ptmx(struct tty_info *slave)
 	if (restore_tty_params(fd, slave))
 		goto err;
 
+	/*
+	 * If tty is migrated we need to restore its group
+	 * as well, otherwise key press won't be handled.
+	 */
+	if (likely(!opts.const_tty)) {
+		if (tty_set_prgp(fd, getpgrp()))
+			goto err;
+	}
+
 	if (pty_open_slaves(slave))
 		goto err;
 
@@ -633,7 +653,7 @@ static int tty_open(struct file_desc *d)
 		return receive_tty(info);
 
 	if (!pty_is_master(info))
-		return pty_open_fake_ptmx(info);
+		return pty_open_slave(info);
 
 	return pty_open_ptmx(info);
 
@@ -679,8 +699,22 @@ static int tty_find_restoring_task(struct tty_info *info)
 		if (item->sid == info->tie->sid)
 			return prepare_ctl_tty(item->pid.virt, item->rst, info->tfe->id);
 
-	pr_err("No task found with sid %d\n", info->tie->sid);
-	return -1;
+	/*
+	 * OK, no proper SID found, this means we were dumped as
+	 * a part of some other session and can't restore the session
+	 * needed back.
+	 *
+	 * To workaround this just reset SID to the process root SID,
+	 * there nothing else we can do.
+	 */
+
+	pr_warn("No task found with sid %d, reset constrol terminal to sid %d\n",
+		info->tie->sid, root_item->sid);
+
+	info->tie->sid = root_item->sid;
+	info->tie->pgrp = root_item->pgid;
+
+	return prepare_ctl_tty(root_item->pid.virt, item->rst, info->tfe->id);
 }
 
 static void tty_setup_orphan_slavery(void)
-- 
1.7.7.6



More information about the CRIU mailing list