[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