[CRIU] [PATCH 11/11] tty: Use regular files engine to save paths to the peers

Tycho Andersen tycho.andersen at canonical.com
Tue Oct 7 07:11:24 PDT 2014


Hi Cyrill,

On Mon, Oct 06, 2014 at 11:01:08PM +0400, Cyrill Gorcunov wrote:
> On Mon, Oct 06, 2014 at 05:15:50PM +0400, Cyrill Gorcunov wrote:
> > Currently we're using predefined format for master/slave pty peers:
> > masters are always /dev/ptmx, while slaves are /dev/pts/$index,
> > where $index is the peer number.
> 
> Tycho, could you please apply first 10 patches from this series, but
> insted of 11 use this one attached.

Sorry for the delay, should I take the other two patches instead of
this one?

Tycho

> From ff3b0a42ba7defc323dd608fc7629e4dc51b3f89 Mon Sep 17 00:00:00 2001
> From: Cyrill Gorcunov <gorcunov at openvz.org>
> Date: Mon, 6 Oct 2014 21:30:04 +0400
> Subject: [PATCH] tty: Save pty peers paths in image
> 
> Currently we're using predefined format for master/slave pty peers:
> masters are always /dev/ptmx, while slaves are /dev/pts/$index,
> where $index is the peer number.
> 
> While fitting most of distros this is not always correct and slave peers
> might be mounted to an arbitrary place, so that we need to somehow
> carry paths with ourself in image.
> 
> Thus save paths to the pty peers in the image itself. Moreover
> reserve place for @mnt_id and @dev_sb as well it will be needed
> to support multiple pty instances.
> 
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
>  protobuf/tty.proto |   4 ++
>  tty.c              | 164 ++++++++++++++++++++++++++++++++++++++++++++---------
>  2 files changed, 140 insertions(+), 28 deletions(-)
> 
> diff --git a/protobuf/tty.proto b/protobuf/tty.proto
> index 8942965c580b..c3bfacfe5244 100644
> --- a/protobuf/tty.proto
> +++ b/protobuf/tty.proto
> @@ -64,4 +64,8 @@ message tty_file_entry {
>  
>  	required uint32			flags		= 3;
>  	required fown_entry		fown		= 4;
> +
> +	optional uint32			mnt_id		= 5;
> +	optional uint32			dev_sb		= 6;
> +	optional string			path		= 7;
>  }
> diff --git a/tty.c b/tty.c
> index edbe85e7505a..34c9aeaab51d 100644
> --- a/tty.c
> +++ b/tty.c
> @@ -24,6 +24,7 @@
>  #include "util.h"
>  #include "log.h"
>  #include "list.h"
> +#include "mount.h"
>  #include "util-pie.h"
>  #include "proc_parse.h"
>  #include "file-ids.h"
> @@ -86,6 +87,7 @@ struct tty_info {
>  	struct list_head		sibling;
>  	int				major;
>  	int				minor;
> +	char				*path;
>  
>  	bool				create;
>  	bool				inherit;
> @@ -123,6 +125,10 @@ static DECLARE_BITMAP(tty_active_pairs, (MAX_TTYS << 1));
>   */
>  static mutex_t *tty_mutex;
>  
> +static char *pty_alloc_path(struct tty_info *info, bool master);
> +#define pty_alloc_path_master(info)	pty_alloc_path(info, true)
> +#define pty_alloc_path_slave(info)	pty_alloc_path(info, false)
> +
>  int prepare_shared_tty(void)
>  {
>  	tty_mutex = shmalloc(sizeof(*tty_mutex));
> @@ -245,7 +251,7 @@ static int tty_test_and_set(int bit, unsigned long *bitmap)
>  	return ret;
>  }
>  
> -static int pty_open_ptmx_index(int flags, int index)
> +static int pty_open_ptmx_index(char *path, int flags, int index)
>  {
>  	int fds[32], i, ret = -1, cur_idx;
>  
> @@ -254,14 +260,14 @@ static int pty_open_ptmx_index(int flags, int index)
>  	mutex_lock(tty_mutex);
>  
>  	for (i = 0; i < ARRAY_SIZE(fds); i++) {
> -		fds[i] = open(PTMX_PATH, flags);
> +		fds[i] = open(path, flags);
>  		if (fds[i] < 0) {
> -			pr_perror("Can't open %s", PTMX_PATH);
> +			pr_perror("Can't open %s", path);
>  			break;
>  		}
>  
>  		if (ioctl(fds[i], TIOCGPTN, &cur_idx)) {
> -			pr_perror("Can't obtain current index on %s", PTMX_PATH);
> +			pr_perror("Can't obtain current index on %s", path);
>  			break;
>  		}
>  
> @@ -281,7 +287,7 @@ static int pty_open_ptmx_index(int flags, int index)
>  		if (cur_idx < index && (index - cur_idx) < ARRAY_SIZE(fds))
>  			continue;
>  
> -		pr_err("Unable to open %s with specified index %d\n", PTMX_PATH, index);
> +		pr_err("Unable to open %s with specified index %d\n", path, index);
>  		break;
>  	}
>  
> @@ -347,15 +353,18 @@ static int tty_restore_ctl_terminal(struct file_desc *d, int fd)
>  {
>  	struct tty_info *info = container_of(d, struct tty_info, d);
>  	int slave, ret = -1;
> -	char pts_name[64];
> +	char *pts_path;
>  
>  	if (!is_service_fd(fd, CTL_TTY_OFF))
>  		return 0;
>  
> -	snprintf(pts_name, sizeof(pts_name), PTS_FMT, info->tie->pty->index);
> -	slave = open(pts_name, O_RDONLY);
> +	pts_path = pty_alloc_path_slave(info);
> +	if (!pts_path)
> +		return -1;
> +	slave = open(pts_path, O_RDONLY);
>  	if (slave < 0) {
> -		pr_perror("Can't open %s", pts_name);
> +		pr_perror("Can't open %s", pts_path);
> +		xfree(pts_path);
>  		return -1;
>  	}
>  
> @@ -367,6 +376,7 @@ static int tty_restore_ctl_terminal(struct file_desc *d, int fd)
>  	if (!ret)
>  		ret = tty_set_prgp(slave, info->tie->pgrp);
>  
> +	xfree(pts_path);
>  	close(slave);
>  	close(fd);
>  
> @@ -458,9 +468,7 @@ static int pty_open_slaves(struct tty_info *info)
>  	int sock = -1, fd = -1, ret = -1;
>  	struct fdinfo_list_entry *fle;
>  	struct tty_info *slave;
> -	char pts_name[64];
> -
> -	snprintf(pts_name, sizeof(pts_name), PTS_FMT, info->tie->pty->index);
> +	char *pts_path = NULL;
>  
>  	sock = socket(PF_UNIX, SOCK_DGRAM, 0);
>  	if (sock < 0) {
> @@ -468,12 +476,16 @@ static int pty_open_slaves(struct tty_info *info)
>  		goto err;
>  	}
>  
> +	pts_path = pty_alloc_path_slave(info);
> +	if (!pts_path)
> +		return -1;
> +
>  	list_for_each_entry(slave, &info->sibling, sibling) {
>  		BUG_ON(tty_is_master(slave));
>  
> -		fd = open(pts_name, slave->tfe->flags | O_NOCTTY);
> +		fd = open(pts_path, slave->tfe->flags | O_NOCTTY);
>  		if (fd < 0) {
> -			pr_perror("Can't open slave %s", pts_name);
> +			pr_perror("Can't open slave %s", pts_path);
>  			goto err;
>  		}
>  
> @@ -483,7 +495,7 @@ static int pty_open_slaves(struct tty_info *info)
>  		fle = file_master(&slave->d);
>  
>  		pr_debug("send slave %#x fd %d connected on %s (pid %d)\n",
> -			 slave->tfe->id, fd, pts_name, fle->pid);
> +			 slave->tfe->id, fd, pts_path, fle->pid);
>  
>  		if (send_fd_to_peer(fd, fle, sock)) {
>  			pr_perror("Can't send file descriptor");
> @@ -496,6 +508,7 @@ static int pty_open_slaves(struct tty_info *info)
>  	ret = 0;
>  
>  err:
> +	xfree(pts_path);
>  	close_safe(&fd);
>  	close_safe(&sock);
>  	return ret;
> @@ -525,6 +538,7 @@ static int receive_tty(struct tty_info *info)
>  static int pty_open_unpaired_slave(struct file_desc *d, struct tty_info *slave)
>  {
>  	int master = -1, ret = -1, fd = -1;
> +	char *ptmx_path = NULL;
>  
>  	/*
>  	 * We may have 2 cases here: the slave either need to
> @@ -540,22 +554,25 @@ static int pty_open_unpaired_slave(struct file_desc *d, struct tty_info *slave)
>  		pr_info("Migrated slave peer %x -> to fd %d\n",
>  			slave->tfe->id, fd);
>  	} else {
> -		char pts_name[64];
> -
> -		snprintf(pts_name, sizeof(pts_name), PTS_FMT, slave->tie->pty->index);
> +		ptmx_path = pty_alloc_path_master(slave);
> +		if (!ptmx_path)
> +			goto err;
>  
> -		master = pty_open_ptmx_index(O_RDONLY, slave->tie->pty->index);
> +		master = pty_open_ptmx_index(ptmx_path,
> +					     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;
> +			pr_perror("Can't open fake %s (id %#x index %d)",
> +				  ptmx_path, slave->tfe->id,
> +				  slave->tie->pty->index);
> +			goto err;
>  		}
>  
>  		unlock_pty(master);
>  
> -		fd = open(pts_name, slave->tfe->flags | O_NOCTTY);
> +		fd = open(slave->path, slave->tfe->flags | O_NOCTTY);
>  		if (fd < 0) {
> -			pr_perror("Can't open slave %s", pts_name);
> +			pr_perror("Can't open slave %s", slave->path);
>  			goto err;
>  		}
>  
> @@ -597,18 +614,26 @@ static int pty_open_unpaired_slave(struct file_desc *d, struct tty_info *slave)
>  err:
>  	close_safe(&master);
>  	close_safe(&fd);
> +	xfree(ptmx_path);
>  	return ret;
>  }
>  
>  static int pty_open_ptmx(struct tty_info *info)
>  {
> +	char *ptmx_path = NULL;
>  	int master = -1;
>  
> -	master = pty_open_ptmx_index(info->tfe->flags, info->tie->pty->index);
> -	if (master < 0) {
> -		pr_perror("Can't open %x (index %d)",
> -			  info->tfe->id, info->tie->pty->index);
> +	ptmx_path = pty_alloc_path_master(info);
> +	if (!ptmx_path)
>  		return -1;
> +
> +	master = pty_open_ptmx_index(ptmx_path,
> +				     info->tfe->flags,
> +				     info->tie->pty->index);
> +	if (master < 0) {
> +		pr_perror("Can't open %s (id %#x index %d)",
> +			  ptmx_path, info->tfe->id, info->tie->pty->index);
> +		goto err;
>  	}
>  
>  	unlock_pty(master);
> @@ -635,9 +660,11 @@ static int pty_open_ptmx(struct tty_info *info)
>  	if (info->tie->locked)
>  		lock_pty(master);
>  
> +	xfree(ptmx_path);
>  	return master;
>  err:
>  	close_safe(&master);
> +	xfree(ptmx_path);
>  	return -1;
>  }
>  
> @@ -951,6 +978,66 @@ struct collect_image_info tty_info_cinfo = {
>  	.flags		= COLLECT_OPTIONAL,
>  };
>  
> +static int tty_make_path(struct tty_info *info)
> +{
> +	if (info->tfe->path) {
> +		info->path = &info->tfe->path[1];
> +		return 0;
> +	}
> +
> +	if (tty_is_master(info))
> +		info->path = xstrdup("/dev/ptmx");
> +	else {
> +		info->path = xmalloc(64);
> +		if (info->path) {
> +			snprintf(info->path, 64, "/dev/pts/%u",
> +				 info->tie->pty->index);
> +		}
> +	}
> +
> +	if (!info->path)
> +		return -1;
> +	return 0;
> +}
> +
> +static char *pty_alloc_path(struct tty_info *info, bool master)
> +{
> +	char *pos, *path;
> +	size_t len, slash_at;
> +
> +	if ((tty_is_master(info) && master) ||
> +	    (!tty_is_master(info) && !master))
> +		return xstrdup(info->path);
> +
> +	len = strlen(info->path) + 1;
> +	pos = strrchr(info->path, '/');
> +	slash_at = pos - info->path;
> +
> +	if (!pos) {
> +		pr_err("Malformed path %s for %#x\n",
> +		       info->path, info->tfe->id);
> +		return NULL;
> +	}
> +
> +	path = xmalloc(len + 32);
> +	if (!path)
> +		return NULL;
> +
> +	memcpy(path, info->path, slash_at);
> +	if (master) {
> +		strcat(path, "ptmx");
> +	} else {
> +		if (slash_at >= 4 && strcmp(&path[slash_at - 4], "pts"))
> +			snprintf(&path[slash_at], 10,
> +				 "/pts/%u", info->tie->pty->index);
> +		else
> +			snprintf(&path[slash_at], 10,
> +				 "/%u", info->tie->pty->index);
> +	}
> +
> +	return path;
> +}
> +
>  static int collect_one_tty(void *obj, ProtobufCMessage *msg)
>  {
>  	struct tty_info *info = obj;
> @@ -973,6 +1060,9 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg)
>  	if (verify_info(info))
>  		return -1;
>  
> +	if (tty_make_path(info))
> +		return -1;
> +
>  	/*
>  	 * The tty peers which have no @termios are hung up,
>  	 * so don't mark them as active, we create them with
> @@ -1174,6 +1264,24 @@ static int dump_one_pty(int lfd, u32 id, const struct fd_parms *p, int major, in
>  	e.flags		= p->flags;
>  	e.fown		= (FownEntry *)&p->fown;
>  
> +	e.has_dev_sb	= true;
> +	e.dev_sb	= p->stat.st_dev;
> +	e.path		= p->link->name;
> +
> +	e.has_mnt_id	= true;
> +	if (p->mnt_id != -1) {
> +		e.mnt_id = p->mnt_id;
> +	} else {
> +		struct mount_info *m = lookup_mnt_sdev(p->stat.st_dev);
> +		if (!m) {
> +			pr_err("Can't find mount with st_dev %#x\n",
> +			       (int)p->stat.st_dev);
> +			return -1;
> +		}
> +
> +		e.mnt_id = m->mnt_id;
> +	}
> +
>  	/*
>  	 * FIXME
>  	 *
> -- 
> 1.9.3
> 



More information about the CRIU mailing list