[CRIU] [PATCH 3/3] tty: Restore unread data from the image
Cyrill Gorcunov
gorcunov at openvz.org
Tue Apr 12 15:08:40 PDT 2016
Just read it from the image and write into appropriate peer.
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
criu/cr-restore.c | 1 +
criu/include/tty.h | 1 +
criu/tty.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 82 insertions(+)
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 93dc5c91b197..f3c1566f5d18 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -178,6 +178,7 @@ static struct collect_image_info *cinfos[] = {
&fanotify_mark_cinfo,
&tty_info_cinfo,
&tty_cinfo,
+ &tty_cdata,
&tunfile_cinfo,
&ext_file_cinfo,
&timerfd_cinfo,
diff --git a/criu/include/tty.h b/criu/include/tty.h
index 0db3b764e585..7ed0895e7168 100644
--- a/criu/include/tty.h
+++ b/criu/include/tty.h
@@ -22,6 +22,7 @@ extern int tty_post_dump(int ret);
extern int dump_verify_tty_sids(void);
extern struct collect_image_info tty_info_cinfo;
extern struct collect_image_info tty_cinfo;
+extern struct collect_image_info tty_cdata;
extern int prepare_shared_tty(void);
extern int tty_verify_active_pairs(void);
diff --git a/criu/tty.c b/criu/tty.c
index 42d218858923..8cb4570e65dc 100644
--- a/criu/tty.c
+++ b/criu/tty.c
@@ -78,6 +78,11 @@ struct tty_info_entry {
TtyInfoEntry *tie;
};
+struct tty_data_entry {
+ struct list_head list;
+ TtyDataEntry *tde;
+};
+
struct tty_info {
struct list_head list;
struct file_desc d;
@@ -94,6 +99,8 @@ struct tty_info {
bool inherit;
struct tty_info *ctl_tty;
+ struct tty_info *link;
+ struct tty_data_entry *tty_data;
};
struct tty_dump_info {
@@ -112,6 +119,7 @@ struct tty_dump_info {
size_t size;
};
+static LIST_HEAD(all_tty_data_entries);
static LIST_HEAD(all_tty_info_entries);
static LIST_HEAD(all_ttys);
@@ -829,6 +837,14 @@ static int pty_open_slaves(struct tty_info *info)
goto err;
}
+ if (slave->link && slave->link->tty_data) {
+ ProtobufCBinaryData bd = slave->link->tty_data->tde->data;
+
+ pr_debug("restore queued data on master %#x (%zu bytes)\n",
+ slave->link->tfe->id, (size_t)bd.len);
+ write(fd, bd.data, bd.len);
+ }
+
close(fd);
fd = -1;
}
@@ -966,6 +982,15 @@ static int pty_open_ptmx(struct tty_info *info)
}
}
+ if (info->link && info->link->tty_data) {
+ ProtobufCBinaryData bd = info->link->tty_data->tde->data;
+
+ pr_debug("restore queued data on slave %#x (%zu bytes)\n",
+ info->link->tfe->id, (size_t)bd.len);
+
+ write(master, bd.data, bd.len);
+ }
+
if (pty_open_slaves(info))
goto err;
@@ -1228,11 +1253,46 @@ static int tty_setup_orphan_slavery(void)
return 0;
}
+static struct tty_data_entry *tty_lookup_data(struct tty_info *info)
+{
+ struct tty_data_entry *td;
+
+ list_for_each_entry(td, &all_tty_data_entries, list) {
+ if (td->tde->tty_id == info->tie->id)
+ return td;
+ }
+
+ return NULL;
+}
+
static int tty_setup_slavery(void * unused)
{
struct tty_info *info, *peer, *m;
/*
+ * Setup links for PTY terminal pairs.
+ */
+ list_for_each_entry(info, &all_ttys, list) {
+ if (!is_pty(info->driver) || info->link)
+ continue;
+ peer = info;
+ list_for_each_entry_continue(peer, &all_ttys, list) {
+ if (!is_pty(peer->driver) || peer->link)
+ continue;
+ if (peer->tie->pty->index == info->tie->pty->index) {
+ info->link = peer;
+ peer->link = info;
+
+ pr_debug("Link PTYs (%#x)\n", info->tfe->id);
+
+ info->tty_data = tty_lookup_data(info);
+ peer->tty_data = tty_lookup_data(peer);
+ break;
+ }
+ }
+ }
+
+ /*
* The image may carry several terminals opened
* belonging to the same session, so choose the
* leader which gonna be setting up the controlling
@@ -1423,6 +1483,8 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg, struct cr_img *i)
info->create = tty_is_master(info);
info->inherit = false;
info->ctl_tty = NULL;
+ info->tty_data = NULL;
+ info->link = NULL;
if (verify_info(info))
return -1;
@@ -1479,6 +1541,24 @@ struct collect_image_info tty_cinfo = {
.collect = collect_one_tty,
};
+static int collect_one_tty_data(void *obj, ProtobufCMessage *msg, struct cr_img *i)
+{
+ struct tty_data_entry *tdo = obj;
+
+ tdo->tde = pb_msg(msg, TtyDataEntry);
+ list_add(&tdo->list, &all_tty_data_entries);
+ pr_debug("Collected data for id %#x (size %zu bytes)\n",
+ tdo->tde->tty_id, (size_t)tdo->tde->data.len);
+ return 0;
+}
+
+struct collect_image_info tty_cdata = {
+ .fd_type = CR_FD_TTY_DATA,
+ .pb_type = PB_TTY_DATA,
+ .priv_size = sizeof(struct tty_data_entry),
+ .collect = collect_one_tty_data,
+};
+
/* Make sure the ttys we're dumping do belong our process tree */
int dump_verify_tty_sids(void)
{
--
2.5.5
More information about the CRIU
mailing list