[CRIU] [PATCH 1/2] tty: Add restoration of locked/exclusive ptys

Pavel Emelyanov xemul at parallels.com
Wed Sep 5 12:47:47 EDT 2012


On 09/05/2012 02:50 PM, Cyrill Gorcunov wrote:
> Since opening locked/exclusive ptys do return
> different error code we can figure out what
> exactly tty flag the peer has.
> 
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
>  include/tty.h      |    3 ++
>  protobuf/tty.proto |    6 ++++
>  tty.c              |   76 ++++++++++++++++++++++++++++++++++++++++++++++-----
>  3 files changed, 77 insertions(+), 8 deletions(-)
> 
> diff --git a/include/tty.h b/include/tty.h
> index 8457270..8a06bad 100644
> --- a/include/tty.h
> +++ b/include/tty.h
> @@ -13,6 +13,9 @@
>  #endif
>  #define PTS_FMT		"/dev/pts/%d"
>  
> +#define TTY_LOCKED	(1 << 0)
> +#define TTY_EXCLUSIVE	(1 << 1)
> +
>  extern int dump_tty(struct fd_parms *p, int lfd, const struct cr_fdset *set);
>  extern int collect_tty(void);
>  extern int tty_is_master(struct fdinfo_list_entry *le);
> diff --git a/protobuf/tty.proto b/protobuf/tty.proto
> index 8f497dc..38adab2 100644
> --- a/protobuf/tty.proto
> +++ b/protobuf/tty.proto
> @@ -31,6 +31,12 @@ message tty_file_entry {
>  	required uint64			pos		=  5;
>  	required uint64			rdev		=  6;
>  	required fown_entry		fown		=  7;
> +
> +	/*
> +	 * Bits
> +	 *  0 - locked
> +	 *  1 - exclusive
> +	 */
>  	required uint32			tty_flags	=  8;

Better make it

required bool locked;
required bool exclusive;

>  
>  	enum Type {
> diff --git a/tty.c b/tty.c
> index b4e89bc..8ac61f7 100644
> --- a/tty.c
> +++ b/tty.c
> @@ -81,9 +81,6 @@
>   *   restore the master end might be already closed for any reason so
>   *   to resolve such problem we open a fake master peer with proper index
>   *   and hook a slave on it, then we close master peer.
> - *
> - * - Find a way to fetch tty flags from the kernel (locked/exclusive)
> - *   and save it in tty_flags.
>   */
>  
>  #undef	LOG_PREFIX
> @@ -259,11 +256,6 @@ static int pty_open_ptmx_index(int flags, int index)
>  	return ret;
>  }
>  
> -/*
> - * FIXME Need to find a way to figure out if master
> - * is in locked state when being dumped. If so, need
> - * to re-lock it on restore.
> - */
>  static int unlock_pty_master(int master)
>  {
>  	const int lock = 0;
> @@ -281,6 +273,58 @@ static int unlock_pty_master(int master)
>  	return 0;
>  }
>  
> +static int lock_pty_master(int master)
> +{
> +	const int lock = 1;
> +
> +	if (ioctl(master, TIOCSPTLCK, &lock)) {
> +		pr_err("Unable to lock pty master device %d\n", master);
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int set_exclusive_pty_master(int master)
> +{
> +	if (ioctl(master, TIOCEXCL)) {
> +		pr_err("Unable to make pty master exclusive %d\n", master);
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int get_pty_flags(int index, unsigned int *flags)
> +{
> +	char pts_name[64];
> +	int ret = 0, fd;
> +
> +	*flags = 0;
> +
> +	snprintf(pts_name, sizeof(pts_name), PTS_FMT, index);
> +
> +	fd = open(pts_name, O_RDONLY);
> +	if (fd < 0) {
> +		switch (errno) {
> +		case EIO:
> +			*flags |= TTY_LOCKED;
> +			break;
> +		case EBUSY:
> +			*flags |= TTY_EXCLUSIVE;
> +			break;

Hm... This is VERY nice, but we need to add crtools check checker for this
being true.

> +		default:
> +			pr_perror("Can't open %s to obtain flags",
> +				  pts_name);
> +			ret = -1;
> +			break;
> +		}
> +	} else
> +		close(fd);
> +
> +	return ret;
> +}
> +
>  static int tty_get_sid(int fd)
>  {
>  	int sid, ret;
> @@ -498,6 +542,11 @@ static int pty_open_ptmx(struct tty_file_info *info)
>  	if (pty_open_slaves(info))
>  		goto err;
>  
> +	if (info->tfe->tty_flags & TTY_LOCKED)
> +		lock_pty_master(master);
> +	else if (info->tfe->tty_flags & TTY_EXCLUSIVE)
> +		set_exclusive_pty_master(master);

Can't they be set simultaneously?

> +
>  	return master;
>  err:
>  	close_safe(&master);
> @@ -676,6 +725,7 @@ static int dump_control_pty(int index, pid_t sid, pid_t prgp)
>  	pr_info("Dump control terminal for %d\n", sid);
>  
>  	snprintf(path, sizeof(path), "/dev/pts/%d", index);
> +

Huh?

>  	fd = open(path, O_RDONLY);
>  	if (fd < 0) {
>  		pr_err("Can't open terminal %s\n", path);
> @@ -760,9 +810,19 @@ static int __dump_one_pty(int lfd, u32 id, const struct fd_parms *p, pid_t sid,
>  		if (sid < 0 || prgp < 0)
>  			return -1;
>  
> +		/*
> +		 * Also figure out the flags master pty has.
> +		 */

Stupid comment, don't you think?

> +		if (get_pty_flags(pty.index, &e.tty_flags))
> +			return -1;
> +
>  		if (sid) {
> +			if (e.tty_flags & TTY_LOCKED)
> +				unlock_pty_master(lfd);

What for?

>  			if (dump_control_pty(pty.index, sid, prgp))
>  				return -1;
> +			if (e.tty_flags & TTY_LOCKED)
> +				lock_pty_master(lfd);
>  		}
>  	}
>  



More information about the CRIU mailing list