[CRIU] [PATCH 1/5] tty: Change the order of collection

Pavel Emelyanov xemul at virtuozzo.com
Wed Jul 19 14:19:48 MSK 2017


There are two object for TTY files -- the file itself and tty_info.
The latter is effectively an inode image. Right now we collect infos
before files, so that latter can find former and attach to it.

In order to move tty files on generic file entry we need to collect
files very early, much earlier, that infos. So here's the patch that
changes the order of tty file vs info collection.

The general idea is -- when collecting files put them in a list and
when an info arrives it walks that list and attaches ttys to self.
Next patches will also add some optimization available with that
scheme.

Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
 criu/cr-restore.c |  2 +-
 criu/tty.c        | 69 +++++++++++++++++++++++++------------------------------
 2 files changed, 32 insertions(+), 39 deletions(-)

diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index e14fa06..74a1b9f 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -289,8 +289,8 @@ static struct collect_image_info *cinfos_files[] = {
 
 /* These images are requered to restore namespaces */
 static struct collect_image_info *before_ns_cinfos[] = {
-	&tty_info_cinfo, /* Restore devpts content */
 	&tty_cinfo,
+	&tty_info_cinfo, /* Restore devpts content */
 	&tty_cdata,
 };
 
diff --git a/criu/tty.c b/criu/tty.c
index f674f25..6ce3eb6 100644
--- a/criu/tty.c
+++ b/criu/tty.c
@@ -76,11 +76,6 @@
 #undef	LOG_PREFIX
 #define LOG_PREFIX "tty: "
 
-struct tty_info_entry {
-	struct list_head		list;
-	TtyInfoEntry			*tie;
-};
-
 struct tty_data_entry {
 	struct list_head		list;
 	TtyDataEntry			*tde;
@@ -128,7 +123,7 @@ struct tty_dump_info {
 };
 
 static bool stdin_isatty = false;
-static LIST_HEAD(all_tty_info_entries);
+static LIST_HEAD(collected_ttys);
 static LIST_HEAD(all_ttys);
 
 /*
@@ -1514,29 +1509,19 @@ static int verify_info(struct tty_info *info)
 	return 0;
 }
 
-static TtyInfoEntry *lookup_tty_info_entry(u32 id)
-{
-	struct tty_info_entry *e;
-
-	list_for_each_entry(e, &all_tty_info_entries, list) {
-		if (e->tie->id == id)
-			return e->tie;
-	}
-
-	return NULL;
-}
+static int tty_info_setup(struct tty_info *info);
 
 static int collect_one_tty_info_entry(void *obj, ProtobufCMessage *msg, struct cr_img *i)
 {
-	struct tty_info_entry *info = obj;
+	struct tty_info *info, *n;
+	TtyInfoEntry *tie;
 
-	info->tie = pb_msg(msg, TtyInfoEntry);
+	tie = pb_msg(msg, TtyInfoEntry);
 
-	switch (info->tie->type) {
+	switch (tie->type) {
 	case TTY_TYPE__PTY:
-		if (!info->tie->pty) {
-			pr_err("No PTY data found (id %#x), corrupted image?\n",
-			       info->tie->id);
+		if (!tie->pty) {
+			pr_err("No PTY data found (id %#x), corrupted image?\n", tie->id);
 			return -1;
 		}
 		break;
@@ -1545,20 +1530,26 @@ static int collect_one_tty_info_entry(void *obj, ProtobufCMessage *msg, struct c
 	case TTY_TYPE__SERIAL:
 	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);
+		if (tie->pty) {
+			pr_err("PTY data found (id %#x), corrupted image?\n", tie->id);
 			return -1;
 		}
 		break;
 	default:
-		pr_err("Unexpected TTY type %d (id %#x)\n",
-		       info->tie->type, info->tie->id);
+		pr_err("Unexpected TTY type %d (id %#x)\n", tie->type, tie->id);
 		return -1;
 	}
 
-	INIT_LIST_HEAD(&info->list);
-	list_add(&info->list, &all_tty_info_entries);
+	list_for_each_entry_safe(info, n, &collected_ttys, list) {
+		if (info->tfe->tty_info_id != tie->id)
+			continue;
+
+		info->tie = tie;
+		list_move_tail(&info->list, &all_ttys);
+
+		if (tty_info_setup(info))
+			return -1;
+	}
 
 	return 0;
 }
@@ -1566,12 +1557,16 @@ static int collect_one_tty_info_entry(void *obj, ProtobufCMessage *msg, struct c
 struct collect_image_info tty_info_cinfo = {
 	.fd_type	= CR_FD_TTY_INFO,
 	.pb_type	= PB_TTY_INFO,
-	.priv_size	= sizeof(struct tty_info_entry),
 	.collect	= collect_one_tty_info_entry,
+	.flags		= COLLECT_NOFREE,
 };
 
 static int prep_tty_restore_cb(struct pprep_head *ph)
 {
+	if (!list_empty(&collected_ttys)) {
+		pr_err("Not all TTYs got its infos\n");
+		return -1;
+	}
 	if (tty_verify_active_pairs())
 		return -1;
 	if (tty_setup_slavery())
@@ -1586,14 +1581,13 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg, struct cr_img *i)
 	struct tty_info *info = obj;
 
 	info->tfe = pb_msg(msg, TtyFileEntry);
+	list_add_tail(&info->list, &collected_ttys);
 
-	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",
-		       info->tfe->tty_info_id, info->tfe->id);
-		return -1;
-	}
+	return 0;
+}
 
+static int tty_info_setup(struct tty_info *info)
+{
 	INIT_LIST_HEAD(&info->sibling);
 	info->driver = get_tty_driver(info->tie->rdev, info->tie->dev);
 	if (info->driver == NULL) {
@@ -1661,7 +1655,6 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg, struct cr_img *i)
 		return -1;
 
 	info->fdstore_id = -1;
-	list_add(&info->list, &all_ttys);
 	return file_desc_add(&info->d, info->tfe->id, &tty_desc_ops);
 }
 
-- 
2.1.4



More information about the CRIU mailing list