[CRIU] [PATCH 3/7] tty: Save mount ids for terminals into image
Cyrill Gorcunov
gorcunov at openvz.org
Thu Feb 2 00:02:05 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.
Because one tty_info_entry may be mapped from
several different tty_file_entry (say someone
opens /dev/pts/X several times) we need @mnt_id
to be in both image entries.
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/tty.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++---
images/tty.proto | 6 ++++++
2 files changed, 55 insertions(+), 3 deletions(-)
diff --git a/criu/tty.c b/criu/tty.c
index 45c9293fe66d..2c0c56c57515 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;
@@ -1479,6 +1481,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) {
@@ -1523,6 +1530,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",
@@ -1611,6 +1623,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);
@@ -1682,7 +1699,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;
@@ -1719,6 +1737,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);
@@ -1750,6 +1769,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;
@@ -1818,7 +1840,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);
@@ -1842,6 +1864,28 @@ 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 {
+ /*
+ * Strictly speaking at moment there is
+ * no strong need to keep @mnt_id for non-PTY
+ * terminals, but having them here is suitable
+ * for debug purpose and might be needed in
+ * future when these devices will be virtualized.
+ * After all having unified scheme for all terminals
+ * is a big win.
+ */
+ mnt_id = p->mnt_id;
+ }
+
+ e.has_mnt_id = true;
+ e.mnt_id = mnt_id;
+
/*
* FIXME
*
@@ -1863,7 +1907,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);
@@ -1963,6 +2007,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