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

Submitted by Pavel Emelianov on July 19, 2017, 11:19 a.m.

Details

Message ID 02db60be-b11c-02b9-c3bd-21cf0716c932@virtuozzo.com
State Accepted
Series "Merge tty files into files image"
Headers show

Commit Message

Pavel Emelianov July 19, 2017, 11:19 a.m.
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@virtuozzo.com>
---
 criu/cr-restore.c |  2 +-
 criu/tty.c        | 69 +++++++++++++++++++++++++------------------------------
 2 files changed, 32 insertions(+), 39 deletions(-)

Patch hide | download patch | download mbox

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