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

Cyrill Gorcunov gorcunov at openvz.org
Sat Jan 21 05:11:25 PST 2017


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))
+			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);
 		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;
+
+	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];
 }
-- 
2.7.4



More information about the CRIU mailing list