[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