[CRIU] [PATCH 5/7] tty: Save mount ids for terminals into image

Pavel Emelyanov xemul at virtuozzo.com
Tue Jan 31 03:32:55 PST 2017


On 01/21/2017 04:11 PM, Cyrill Gorcunov wrote:
> Since we're gonna to handle several devpts instance
> each terminal need a second key to separate same
> named pairs in different mounts. For this sake
> each tty assigned with mount id.
> 
> Note to restore them properly we need per mount
> bitmaps to track pairs and indices, which will be
> addressed in next patch.
> 
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
>  criu/mount.c     | 16 ++++++++++++++--
>  criu/tty.c       | 42 +++++++++++++++++++++++++++++++++++++++---
>  images/tty.proto |  6 ++++++
>  3 files changed, 59 insertions(+), 5 deletions(-)
> 
> diff --git a/criu/mount.c b/criu/mount.c
> index 2f3f25d19845..44c2d89ab78a 100644
> --- a/criu/mount.c
> +++ b/criu/mount.c
> @@ -234,6 +234,18 @@ struct mount_info *lookup_mnt_sdev(unsigned int s_dev)
>  	return NULL;
>  }
>  
> +static struct mount_info *lookup_mnt_sdev_on_root(unsigned int s_dev)
> +{
> +	struct mount_info *m;
> +
> +	for (m = mntinfo; m != NULL; m = m->next)
> +		if (m->s_dev == s_dev &&
> +		    is_root(m->root))

Why is is_root() check needed?

> +			return m;
> +
> +	return NULL;
> +}
> +
>  static struct mount_info *mount_resolve_path(struct mount_info *mntinfo_tree, const char *path)
>  {
>  	size_t pathlen = strlen(path);
> @@ -278,7 +290,7 @@ int mount_resolve_devpts_mnt_id(int s_dev)
>  {
>  	struct mount_info *mi;
>  
> -	mi = lookup_mnt_sdev(s_dev);
> +	mi = lookup_mnt_sdev_on_root(s_dev);
>  	if (!mi) {
>  		pr_err("No devpts mount point found for s_dev %#x\n", s_dev);
>  		return -1;
> @@ -289,7 +301,7 @@ int mount_resolve_devpts_mnt_id(int s_dev)
>  	} else if (mi->fstype->code == FSTYPE__DEVTMPFS) {
>  		char path[PATH_MAX];
>  
> -		snprintf(path, sizeof(path), "%s/pts", mi->mountpoint + 1);
> +		snprintf(path, sizeof(path), "%s/pts/ptmx", mi->mountpoint + 1);

Runaway from patch #4?

>  		mi = mount_resolve_path(mi, path);
>  		if (!mi) {
>  			pr_err("Can't resolve %s\n", path);
> diff --git a/criu/tty.c b/criu/tty.c
> index ef0a19b0000b..bbdb3ca2e071 100644
> --- a/criu/tty.c
> +++ b/criu/tty.c
> @@ -28,6 +28,7 @@
>  #include "files-reg.h"
>  #include "namespaces.h"
>  #include "external.h"
> +#include "mount.h"
>  
>  #include "protobuf.h"
>  #include "util.h"
> @@ -107,6 +108,7 @@ struct tty_dump_info {
>  	struct list_head		list;
>  
>  	u32				id;
> +	int				mnt_id;
>  	pid_t				sid;
>  	pid_t				pgrp;
>  	int				fd;
> @@ -1460,6 +1462,11 @@ static int collect_one_tty_info_entry(void *obj, ProtobufCMessage *msg, struct c
>  
>  	info->tie = pb_msg(msg, TtyInfoEntry);
>  
> +	if (!info->tie->has_mnt_id) {
> +		info->tie->has_mnt_id = true;
> +		info->tie->mnt_id = 0;
> +	}
> +
>  	switch (info->tie->type) {
>  	case TTY_TYPE__PTY:
>  		if (!info->tie->pty) {
> @@ -1504,6 +1511,11 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg, struct cr_img *i)
>  
>  	info->tfe = pb_msg(msg, TtyFileEntry);
>  
> +	if (!info->tfe->has_mnt_id) {
> +		info->tfe->has_mnt_id = true;
> +		info->tfe->mnt_id = 0;
> +	}
> +
>  	info->tie = lookup_tty_info_entry(info->tfe->tty_info_id);
>  	if (!info->tie) {
>  		pr_err("No tty-info-id %#x found on id %#x\n",
> @@ -1592,6 +1604,11 @@ static int collect_one_tty_data(void *obj, ProtobufCMessage *msg, struct cr_img
>  	struct tty_info *info;
>  
>  	tdo->tde = pb_msg(msg, TtyDataEntry);
> +	if (!tdo->tde->has_mnt_id) {
> +		tdo->tde->has_mnt_id = true;
> +		tdo->tde->mnt_id = 0;
> +	}
> +
>  	pr_debug("Collected data for id %#x (size %zu bytes)\n",
>  		 tdo->tde->tty_id, (size_t)tdo->tde->data.len);
>  
> @@ -1663,7 +1680,8 @@ int dump_verify_tty_sids(void)
>  	return ret;
>  }
>  
> -static int dump_tty_info(int lfd, u32 id, const struct fd_parms *p, struct tty_driver *driver, int index)
> +static int dump_tty_info(int lfd, u32 id, const struct fd_parms *p, int mnt_id,
> +			 struct tty_driver *driver, int index)
>  {
>  	TtyInfoEntry info		= TTY_INFO_ENTRY__INIT;
>  	TermiosEntry termios		= TERMIOS_ENTRY__INIT;
> @@ -1700,6 +1718,7 @@ static int dump_tty_info(int lfd, u32 id, const struct fd_parms *p, struct tty_d
>  	dinfo->fd		= p->fd;
>  	dinfo->driver		= driver;
>  	dinfo->flags		= p->flags;
> +	dinfo->mnt_id		= mnt_id;
>  
>  	if (is_pty(driver)) {
>  		dinfo->lfd = dup(lfd);
> @@ -1731,6 +1750,9 @@ static int dump_tty_info(int lfd, u32 id, const struct fd_parms *p, struct tty_d
>  	info.has_gid		= true;
>  	info.gid		= userns_gid(p->stat.st_gid);
>  
> +	info.has_mnt_id		= true;
> +	info.mnt_id		= mnt_id;
> +
>  	info.type = driver->type;
>  	if (info.type == TTY_TYPE__PTY) {
>  		info.pty	= &pty;
> @@ -1799,7 +1821,7 @@ out:
>  static int dump_one_tty(int lfd, u32 id, const struct fd_parms *p)
>  {
>  	TtyFileEntry e = TTY_FILE_ENTRY__INIT;
> -	int ret = 0, index = -1;
> +	int ret = 0, index = -1, mnt_id;
>  	struct tty_driver *driver;
>  
>  	pr_info("Dumping tty %d with id %#x\n", lfd, id);
> @@ -1823,6 +1845,18 @@ static int dump_one_tty(int lfd, u32 id, const struct fd_parms *p)
>  	e.flags		= p->flags;
>  	e.fown		= (FownEntry *)&p->fown;
>  
> +	if (is_pty(driver)) {
> +		mnt_id = mount_resolve_devpts_mnt_id(p->stat.st_dev);
> +		if (mnt_id < 0) {
> +			pr_info("Can't obtain mnt_id on tty %d id %#x\n", lfd, id);
> +			return -1;
> +		}
> +	} else
> +		mnt_id = p->mnt_id;

Is it needed for non-ptys?

> +
> +	e.has_mnt_id	= true;
> +	e.mnt_id	= mnt_id;
> +
>  	/*
>  	 * FIXME
>  	 *
> @@ -1844,7 +1878,7 @@ static int dump_one_tty(int lfd, u32 id, const struct fd_parms *p)
>  	 */
>  
>  	if (!tty_test_and_set(e.tty_info_id, tty_bitmap))
> -		ret = dump_tty_info(lfd, e.tty_info_id, p, driver, index);
> +		ret = dump_tty_info(lfd, e.tty_info_id, p, mnt_id, driver, index);
>  
>  	if (!ret)
>  		ret = pb_write_one(img_from_set(glob_imgset, CR_FD_TTY_FILES), &e, PB_TTY_FILE);
> @@ -1944,6 +1978,8 @@ static int tty_do_dump_queued_data(struct tty_dump_info *dinfo)
>  		e.tty_id	= dinfo->id;
>  		e.data.data	= (void *)buf;
>  		e.data.len	= off;
> +		e.has_mnt_id	= true;
> +		e.mnt_id	= dinfo->mnt_id;
>  
>  		ret = pb_write_one(img_from_set(glob_imgset, CR_FD_TTY_DATA),
>  				   &e, PB_TTY_DATA);
> diff --git a/images/tty.proto b/images/tty.proto
> index 739a4ffedfff..4b36ef7c005e 100644
> --- a/images/tty.proto
> +++ b/images/tty.proto
> @@ -39,6 +39,8 @@ enum TtyType {
>  message tty_data_entry {
>  	required uint32			tty_id		= 1;
>  	required bytes			data		= 2;
> +
> +	optional sint32			mnt_id		= 3 [default = 0];
>  }
>  
>  message tty_info_entry {
> @@ -73,6 +75,8 @@ message tty_info_entry {
>  
>  	optional uint32			uid		= 14;
>  	optional uint32			gid		= 15;
> +
> +	optional sint32			mnt_id		= 16 [default = 0];
>  };
>  
>  message tty_file_entry {
> @@ -81,4 +85,6 @@ message tty_file_entry {
>  
>  	required uint32			flags		= 3 [(criu).hex = true];
>  	required fown_entry		fown		= 4;
> +
> +	optional sint32			mnt_id		= 5 [default = 0];

O_o  do we _really_ need mnt_id for all three?

>  }
> 



More information about the CRIU mailing list