[CRIU] [PATCH 3/3] tty: allow to dump and restore external terminals

Tycho Andersen tycho.andersen at canonical.com
Tue Dec 1 06:50:47 PST 2015


Hi Andrey,

On Thu, Nov 26, 2015 at 12:32:47PM +0300, Andrey Vagin wrote:
> From: Andrew Vagin <avagin at virtuozzo.com>
> 
> Now we can use the --inherit-fd option to mark external terminals on dump
> and to tell which file desdriptors should be used to restore these terminals.
> 
> Here is an example how it works:
> $ setsid sleep 1000
> 
> $ ipython
> In [1]: import os
> In [2]: st = os.stat("/proc/self/fd/0")
> In [3]: print "tty:[%x:%x]" % (st.st_rdev, st.st_dev)
> tty:[8800:d]
> 
> $ps -C sleep
>   PID TTY          TIME CMD
>  4109 ?        00:00:00 sleep
> 
> $ ./criu dump --inherit-fd 'fd:tty:[8800:d]' -D imgs -v4 -t 4109
> $ ./criu restore --inherit-fd 'fd[1]:tty:[8800:d]' -D imgs -v4

I guess this fd[1] here could be fd[0] or fd[2] since they're all
linked to the same console in the interactive case?

Anyway, thanks, looks like a useful set. It will let us get rid of
some goop in liblxc :)

Tycho

> Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
> ---
>  protobuf/tty.proto |  1 +
>  tty.c              | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++---
>  2 files changed, 52 insertions(+), 3 deletions(-)
> 
> diff --git a/protobuf/tty.proto b/protobuf/tty.proto
> index fce5e79..4b5a70c 100644
> --- a/protobuf/tty.proto
> +++ b/protobuf/tty.proto
> @@ -30,6 +30,7 @@ enum TtyType {
>  	CONSOLE		= 2;
>  	VT		= 3;
>  	CTTY		= 4;
> +	EXT_TTY		= 5;
>  }
>  
>  message tty_info_entry {
> diff --git a/tty.c b/tty.c
> index b745483..7fb3ed4 100644
> --- a/tty.c
> +++ b/tty.c
> @@ -142,6 +142,7 @@ struct tty_driver {
>  	int				(*fd_get_index)(int fd, const struct fd_parms *p);
>  	int				(*img_get_index)(struct tty_info *ti);
>  	int				(*open)(struct tty_info *ti);
> +	bool				non_file;
>  };
>  
>  #define TTY_SUBTYPE_MASTER			0x0001
> @@ -203,6 +204,15 @@ static struct tty_driver vt_driver = {
>  	.open			= open_simple_tty,
>  };
>  
> +static int open_ext_tty(struct tty_info *info);
> +static struct tty_driver ext_driver = {
> +	.type			= TTY_TYPE__EXT_TTY,
> +	.name			= "ext",
> +	.open			= open_ext_tty,
> +	.non_file		= true,
> +};
> +
> +
>  static int pts_fd_get_index(int fd, const struct fd_parms *p)
>  {
>  	int index;
> @@ -235,6 +245,11 @@ static struct tty_driver pts_driver = {
>  struct tty_driver *get_tty_driver(dev_t rdev, dev_t dev)
>  {
>  	int major, minor;
> +	char id[42];
> +
> +	snprintf(id, sizeof(id), "tty:[%lx:%lx]", rdev, dev);
> +	if (inherit_fd_lookup_id(id) >= 0)
> +		return &ext_driver;
>  
>  	major = major(rdev);
>  	minor = minor(rdev);
> @@ -652,6 +667,8 @@ static bool tty_is_master(struct tty_info *info)
>  	case TTY_TYPE__VT:
>  		if (!opts.shell_job)
>  			return true;
> +	case TTY_TYPE__EXT_TTY:
> +		return true;
>  	}
>  
>  	return false;
> @@ -970,6 +987,21 @@ err:
>  	return -1;
>  }
>  
> +static int open_ext_tty(struct tty_info *info)
> +{
> +	int fd = -1;
> +
> +	if (!inherited_fd(&info->d, &fd) && fd < 0)
> +		return -1;
> +
> +	if (restore_tty_params(fd, info)) {
> +		close(fd);
> +		return -1;
> +	}
> +
> +	return fd;
> +}
> +
>  static int tty_open(struct file_desc *d)
>  {
>  	struct tty_info *info = container_of(d, struct tty_info, d);
> @@ -1013,12 +1045,22 @@ static void tty_collect_fd(struct file_desc *d, struct fdinfo_list_entry *fle,
>  	list_add_tail(&fle->ps_list, tgt);
>  }
>  
> +static char *tty_d_name(struct file_desc *d, char *buf, size_t s)
> +{
> +	struct tty_info *info = container_of(d, struct tty_info, d);
> +
> +	snprintf(buf, s, "tty:[%x:%x]", info->tie->rdev, info->tie->dev);
> +
> +	return buf;
> +}
> +
>  static struct file_desc_ops tty_desc_ops = {
>  	.type		= FD_TYPES__TTY,
>  	.open		= tty_open,
>  	.post_open	= tty_restore_ctl_terminal,
>  	.want_transport = tty_transport,
>  	.collect_fd	= tty_collect_fd,
> +	.name		= tty_d_name,
>  };
>  
>  static struct pstree_item *find_first_sid(int sid)
> @@ -1319,6 +1361,7 @@ static int collect_one_tty_info_entry(void *obj, ProtobufCMessage *msg)
>  	case TTY_TYPE__CTTY:
>  	case TTY_TYPE__CONSOLE:
>  	case TTY_TYPE__VT:
> +	case TTY_TYPE__EXT_TTY:
>  		if (info->tie->pty) {
>  			pr_err("PTY data found (id %x), corrupted image?\n",
>  			       info->tie->id);
> @@ -1359,6 +1402,10 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg)
>  
>  	INIT_LIST_HEAD(&info->sibling);
>  	info->driver = get_tty_driver(info->tie->rdev, info->tie->dev);
> +	if (info->driver == NULL) {
> +		pr_err("Unable to find a tty driver\n");
> +		return -1;
> +	}
>  	info->create = tty_is_master(info);
>  	info->inherit = false;
>  	info->ctl_tty = NULL;
> @@ -1380,6 +1427,7 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg)
>  				       info->tfe->id);
>  				return -1;
>  			}
> +		} if (info->driver->non_file) {
>  		} else {
>  			pr_err("No reg_d descriptor for id %#x\n", info->tfe->id);
>  			return -1;
> @@ -1582,9 +1630,6 @@ static int dump_one_tty(int lfd, u32 id, const struct fd_parms *p)
>  
>  	pr_info("Dumping tty %d with id %#x\n", lfd, id);
>  
> -	if (dump_one_reg_file(lfd, id, p))
> -		return -1;
> -
>  	driver = get_tty_driver(p->stat.st_rdev, p->stat.st_dev);
>  	if (driver->fd_get_index)
>  		index = driver->fd_get_index(lfd, p);
> @@ -1596,6 +1641,9 @@ static int dump_one_tty(int lfd, u32 id, const struct fd_parms *p)
>  		return -1;
>  	}
>  
> +	if (!driver->non_file && dump_one_reg_file(lfd, id, p))
> +		return -1;
> +
>  	e.id		= id;
>  	e.tty_info_id	= tty_gen_id(driver, index);
>  	e.flags		= p->flags;
> -- 
> 2.4.3
> 
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu


More information about the CRIU mailing list