[CRIU] [PATCH 3/3] tty: allow to dump and restore external terminals
Andrey Vagin
avagin at openvz.org
Thu Nov 26 01:32:47 PST 2015
From: Andrew Vagin <avagin at virtuozzo.com>
Now we can use the --inherit-fd option to mark external terminals on dump
and to tell which file desdriptors should be used to restore these terminals.
Here is an example how it works:
$ setsid sleep 1000
$ ipython
In [1]: import os
In [2]: st = os.stat("/proc/self/fd/0")
In [3]: print "tty:[%x:%x]" % (st.st_rdev, st.st_dev)
tty:[8800:d]
$ps -C sleep
PID TTY TIME CMD
4109 ? 00:00:00 sleep
$ ./criu dump --inherit-fd 'fd:tty:[8800:d]' -D imgs -v4 -t 4109
$ ./criu restore --inherit-fd 'fd[1]:tty:[8800:d]' -D imgs -v4
Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
---
protobuf/tty.proto | 1 +
tty.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 52 insertions(+), 3 deletions(-)
diff --git a/protobuf/tty.proto b/protobuf/tty.proto
index fce5e79..4b5a70c 100644
--- a/protobuf/tty.proto
+++ b/protobuf/tty.proto
@@ -30,6 +30,7 @@ enum TtyType {
CONSOLE = 2;
VT = 3;
CTTY = 4;
+ EXT_TTY = 5;
}
message tty_info_entry {
diff --git a/tty.c b/tty.c
index b745483..7fb3ed4 100644
--- a/tty.c
+++ b/tty.c
@@ -142,6 +142,7 @@ struct tty_driver {
int (*fd_get_index)(int fd, const struct fd_parms *p);
int (*img_get_index)(struct tty_info *ti);
int (*open)(struct tty_info *ti);
+ bool non_file;
};
#define TTY_SUBTYPE_MASTER 0x0001
@@ -203,6 +204,15 @@ static struct tty_driver vt_driver = {
.open = open_simple_tty,
};
+static int open_ext_tty(struct tty_info *info);
+static struct tty_driver ext_driver = {
+ .type = TTY_TYPE__EXT_TTY,
+ .name = "ext",
+ .open = open_ext_tty,
+ .non_file = true,
+};
+
+
static int pts_fd_get_index(int fd, const struct fd_parms *p)
{
int index;
@@ -235,6 +245,11 @@ static struct tty_driver pts_driver = {
struct tty_driver *get_tty_driver(dev_t rdev, dev_t dev)
{
int major, minor;
+ char id[42];
+
+ snprintf(id, sizeof(id), "tty:[%lx:%lx]", rdev, dev);
+ if (inherit_fd_lookup_id(id) >= 0)
+ return &ext_driver;
major = major(rdev);
minor = minor(rdev);
@@ -652,6 +667,8 @@ static bool tty_is_master(struct tty_info *info)
case TTY_TYPE__VT:
if (!opts.shell_job)
return true;
+ case TTY_TYPE__EXT_TTY:
+ return true;
}
return false;
@@ -970,6 +987,21 @@ err:
return -1;
}
+static int open_ext_tty(struct tty_info *info)
+{
+ int fd = -1;
+
+ if (!inherited_fd(&info->d, &fd) && fd < 0)
+ return -1;
+
+ if (restore_tty_params(fd, info)) {
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+}
+
static int tty_open(struct file_desc *d)
{
struct tty_info *info = container_of(d, struct tty_info, d);
@@ -1013,12 +1045,22 @@ static void tty_collect_fd(struct file_desc *d, struct fdinfo_list_entry *fle,
list_add_tail(&fle->ps_list, tgt);
}
+static char *tty_d_name(struct file_desc *d, char *buf, size_t s)
+{
+ struct tty_info *info = container_of(d, struct tty_info, d);
+
+ snprintf(buf, s, "tty:[%x:%x]", info->tie->rdev, info->tie->dev);
+
+ return buf;
+}
+
static struct file_desc_ops tty_desc_ops = {
.type = FD_TYPES__TTY,
.open = tty_open,
.post_open = tty_restore_ctl_terminal,
.want_transport = tty_transport,
.collect_fd = tty_collect_fd,
+ .name = tty_d_name,
};
static struct pstree_item *find_first_sid(int sid)
@@ -1319,6 +1361,7 @@ static int collect_one_tty_info_entry(void *obj, ProtobufCMessage *msg)
case TTY_TYPE__CTTY:
case TTY_TYPE__CONSOLE:
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);
@@ -1359,6 +1402,10 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg)
INIT_LIST_HEAD(&info->sibling);
info->driver = get_tty_driver(info->tie->rdev, info->tie->dev);
+ if (info->driver == NULL) {
+ pr_err("Unable to find a tty driver\n");
+ return -1;
+ }
info->create = tty_is_master(info);
info->inherit = false;
info->ctl_tty = NULL;
@@ -1380,6 +1427,7 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg)
info->tfe->id);
return -1;
}
+ } if (info->driver->non_file) {
} else {
pr_err("No reg_d descriptor for id %#x\n", info->tfe->id);
return -1;
@@ -1582,9 +1630,6 @@ static int dump_one_tty(int lfd, u32 id, const struct fd_parms *p)
pr_info("Dumping tty %d with id %#x\n", lfd, id);
- if (dump_one_reg_file(lfd, id, p))
- return -1;
-
driver = get_tty_driver(p->stat.st_rdev, p->stat.st_dev);
if (driver->fd_get_index)
index = driver->fd_get_index(lfd, p);
@@ -1596,6 +1641,9 @@ static int dump_one_tty(int lfd, u32 id, const struct fd_parms *p)
return -1;
}
+ if (!driver->non_file && dump_one_reg_file(lfd, id, p))
+ return -1;
+
e.id = id;
e.tty_info_id = tty_gen_id(driver, index);
e.flags = p->flags;
--
2.4.3
More information about the CRIU
mailing list