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

Andrew Vagin avagin at virtuozzo.com
Thu Nov 26 07:30:55 PST 2015


On Thu, Nov 26, 2015 at 05:01:20PM +0300, Cyrill Gorcunov wrote:
> 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?

Pls, read Pavel's comment for the first patch.
We don't know how we will restore this terminal. We just tell criu that
it doesn't need to worry about it.

> 
> (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?

Sure, we can use @type.
> 
> >  
> >  #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?

Will fix. Thanks.

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