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

Andrew Vagin avagin at parallels.com
Wed Sep 26 09:30:37 EDT 2012


On Wed, Sep 26, 2012 at 05:05:47PM +0400, Cyrill Gorcunov wrote:
> 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"

I don't like /dev/tty, because in this case we can make dump/restore
only once. Pavel suggested to get terminal from crtools. If you don't
like this idea, you can get a current tty by the same way as "ps".

$ ps axf
 1697 pts/0    Ss+    0:00  |   \_ -bash
 1739 pts/0    T      0:03  |       \_ vim mount.c

>  
>  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);
I don't understand this part. Is this terminal external? If it's true,
why do we need to call prepare_ctl_tty() in this case?
>  }
>  
>  static void tty_setup_orphan_slavery(void)
> -- 
> 1.7.7.6
> 


More information about the CRIU mailing list