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

Cyrill Gorcunov gorcunov at gmail.com
Thu Nov 26 06:01:20 PST 2015


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

Lets make it somehow similar to fd[N] syntax?
Say --inherit-ds 'fd[1]:tty[8800:d]', otherwise it looks
like there too many colons, no?

(No strong opinions from my side though)

> 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;
>  }

Maybe it would worth if we use INHERIT here?
Because for say external mounts we run plugins
and such, so at least for "inherit" terminals
we would know that the only thing we're doing
is taking existing peer. Sounds reasonable?

(as result the helpers might named with
 inherit_ prefix or something)

>  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;
>  };

May not we somehow eliminate this @non_file member?
The @type wont be enough?

>  
>  #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;

No break?

> +	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
> 

	Cyrill


More information about the CRIU mailing list