[CRIU] [PATCH 3/3] tty: allow to dump and restore external terminals
Cyrill Gorcunov
gorcunov at gmail.com
Thu Nov 26 06:01:20 PST 2015
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
Lets make it somehow similar to fd[N] syntax?
Say --inherit-ds 'fd[1]:tty[8800:d]', otherwise it looks
like there too many colons, no?
(No strong opinions from my side though)
> 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;
> }
Maybe it would worth if we use INHERIT here?
Because for say external mounts we run plugins
and such, so at least for "inherit" terminals
we would know that the only thing we're doing
is taking existing peer. Sounds reasonable?
(as result the helpers might named with
inherit_ prefix or something)
> 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;
> };
May not we somehow eliminate this @non_file member?
The @type wont be enough?
>
> #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;
No break?
> + 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
>
Cyrill
More information about the CRIU
mailing list