[CRIU] [PATCH 3/3] tty: allow to dump and restore external terminals
Tycho Andersen
tycho.andersen at canonical.com
Tue Dec 1 06:50:47 PST 2015
Hi Andrey,
On Thu, Nov 26, 2015 at 12:32:47PM +0300, Andrey Vagin wrote:
> 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
I guess this fd[1] here could be fd[0] or fd[2] since they're all
linked to the same console in the interactive case?
Anyway, thanks, looks like a useful set. It will let us get rid of
some goop in liblxc :)
Tycho
> 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
>
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
More information about the CRIU
mailing list