[CRIU] [PATCH 11/11] tty: Use regular files engine to save paths to the peers
Tycho Andersen
tycho.andersen at canonical.com
Tue Oct 7 07:11:24 PDT 2014
Hi Cyrill,
On Mon, Oct 06, 2014 at 11:01:08PM +0400, Cyrill Gorcunov wrote:
> On Mon, Oct 06, 2014 at 05:15:50PM +0400, Cyrill Gorcunov wrote:
> > Currently we're using predefined format for master/slave pty peers:
> > masters are always /dev/ptmx, while slaves are /dev/pts/$index,
> > where $index is the peer number.
>
> Tycho, could you please apply first 10 patches from this series, but
> insted of 11 use this one attached.
Sorry for the delay, should I take the other two patches instead of
this one?
Tycho
> From ff3b0a42ba7defc323dd608fc7629e4dc51b3f89 Mon Sep 17 00:00:00 2001
> From: Cyrill Gorcunov <gorcunov at openvz.org>
> Date: Mon, 6 Oct 2014 21:30:04 +0400
> Subject: [PATCH] tty: Save pty peers paths in image
>
> Currently we're using predefined format for master/slave pty peers:
> masters are always /dev/ptmx, while slaves are /dev/pts/$index,
> where $index is the peer number.
>
> While fitting most of distros this is not always correct and slave peers
> might be mounted to an arbitrary place, so that we need to somehow
> carry paths with ourself in image.
>
> Thus save paths to the pty peers in the image itself. Moreover
> reserve place for @mnt_id and @dev_sb as well it will be needed
> to support multiple pty instances.
>
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
> protobuf/tty.proto | 4 ++
> tty.c | 164 ++++++++++++++++++++++++++++++++++++++++++++---------
> 2 files changed, 140 insertions(+), 28 deletions(-)
>
> diff --git a/protobuf/tty.proto b/protobuf/tty.proto
> index 8942965c580b..c3bfacfe5244 100644
> --- a/protobuf/tty.proto
> +++ b/protobuf/tty.proto
> @@ -64,4 +64,8 @@ message tty_file_entry {
>
> required uint32 flags = 3;
> required fown_entry fown = 4;
> +
> + optional uint32 mnt_id = 5;
> + optional uint32 dev_sb = 6;
> + optional string path = 7;
> }
> diff --git a/tty.c b/tty.c
> index edbe85e7505a..34c9aeaab51d 100644
> --- a/tty.c
> +++ b/tty.c
> @@ -24,6 +24,7 @@
> #include "util.h"
> #include "log.h"
> #include "list.h"
> +#include "mount.h"
> #include "util-pie.h"
> #include "proc_parse.h"
> #include "file-ids.h"
> @@ -86,6 +87,7 @@ struct tty_info {
> struct list_head sibling;
> int major;
> int minor;
> + char *path;
>
> bool create;
> bool inherit;
> @@ -123,6 +125,10 @@ static DECLARE_BITMAP(tty_active_pairs, (MAX_TTYS << 1));
> */
> static mutex_t *tty_mutex;
>
> +static char *pty_alloc_path(struct tty_info *info, bool master);
> +#define pty_alloc_path_master(info) pty_alloc_path(info, true)
> +#define pty_alloc_path_slave(info) pty_alloc_path(info, false)
> +
> int prepare_shared_tty(void)
> {
> tty_mutex = shmalloc(sizeof(*tty_mutex));
> @@ -245,7 +251,7 @@ static int tty_test_and_set(int bit, unsigned long *bitmap)
> return ret;
> }
>
> -static int pty_open_ptmx_index(int flags, int index)
> +static int pty_open_ptmx_index(char *path, int flags, int index)
> {
> int fds[32], i, ret = -1, cur_idx;
>
> @@ -254,14 +260,14 @@ static int pty_open_ptmx_index(int flags, int index)
> mutex_lock(tty_mutex);
>
> for (i = 0; i < ARRAY_SIZE(fds); i++) {
> - fds[i] = open(PTMX_PATH, flags);
> + fds[i] = open(path, flags);
> if (fds[i] < 0) {
> - pr_perror("Can't open %s", PTMX_PATH);
> + pr_perror("Can't open %s", path);
> break;
> }
>
> if (ioctl(fds[i], TIOCGPTN, &cur_idx)) {
> - pr_perror("Can't obtain current index on %s", PTMX_PATH);
> + pr_perror("Can't obtain current index on %s", path);
> break;
> }
>
> @@ -281,7 +287,7 @@ static int pty_open_ptmx_index(int flags, int index)
> if (cur_idx < index && (index - cur_idx) < ARRAY_SIZE(fds))
> continue;
>
> - pr_err("Unable to open %s with specified index %d\n", PTMX_PATH, index);
> + pr_err("Unable to open %s with specified index %d\n", path, index);
> break;
> }
>
> @@ -347,15 +353,18 @@ static int tty_restore_ctl_terminal(struct file_desc *d, int fd)
> {
> struct tty_info *info = container_of(d, struct tty_info, d);
> int slave, ret = -1;
> - char pts_name[64];
> + char *pts_path;
>
> if (!is_service_fd(fd, CTL_TTY_OFF))
> return 0;
>
> - snprintf(pts_name, sizeof(pts_name), PTS_FMT, info->tie->pty->index);
> - slave = open(pts_name, O_RDONLY);
> + pts_path = pty_alloc_path_slave(info);
> + if (!pts_path)
> + return -1;
> + slave = open(pts_path, O_RDONLY);
> if (slave < 0) {
> - pr_perror("Can't open %s", pts_name);
> + pr_perror("Can't open %s", pts_path);
> + xfree(pts_path);
> return -1;
> }
>
> @@ -367,6 +376,7 @@ static int tty_restore_ctl_terminal(struct file_desc *d, int fd)
> if (!ret)
> ret = tty_set_prgp(slave, info->tie->pgrp);
>
> + xfree(pts_path);
> close(slave);
> close(fd);
>
> @@ -458,9 +468,7 @@ static int pty_open_slaves(struct tty_info *info)
> int sock = -1, fd = -1, ret = -1;
> struct fdinfo_list_entry *fle;
> struct tty_info *slave;
> - char pts_name[64];
> -
> - snprintf(pts_name, sizeof(pts_name), PTS_FMT, info->tie->pty->index);
> + char *pts_path = NULL;
>
> sock = socket(PF_UNIX, SOCK_DGRAM, 0);
> if (sock < 0) {
> @@ -468,12 +476,16 @@ static int pty_open_slaves(struct tty_info *info)
> goto err;
> }
>
> + pts_path = pty_alloc_path_slave(info);
> + if (!pts_path)
> + return -1;
> +
> list_for_each_entry(slave, &info->sibling, sibling) {
> BUG_ON(tty_is_master(slave));
>
> - fd = open(pts_name, slave->tfe->flags | O_NOCTTY);
> + fd = open(pts_path, slave->tfe->flags | O_NOCTTY);
> if (fd < 0) {
> - pr_perror("Can't open slave %s", pts_name);
> + pr_perror("Can't open slave %s", pts_path);
> goto err;
> }
>
> @@ -483,7 +495,7 @@ static int pty_open_slaves(struct tty_info *info)
> fle = file_master(&slave->d);
>
> pr_debug("send slave %#x fd %d connected on %s (pid %d)\n",
> - slave->tfe->id, fd, pts_name, fle->pid);
> + slave->tfe->id, fd, pts_path, fle->pid);
>
> if (send_fd_to_peer(fd, fle, sock)) {
> pr_perror("Can't send file descriptor");
> @@ -496,6 +508,7 @@ static int pty_open_slaves(struct tty_info *info)
> ret = 0;
>
> err:
> + xfree(pts_path);
> close_safe(&fd);
> close_safe(&sock);
> return ret;
> @@ -525,6 +538,7 @@ static int receive_tty(struct tty_info *info)
> static int pty_open_unpaired_slave(struct file_desc *d, struct tty_info *slave)
> {
> int master = -1, ret = -1, fd = -1;
> + char *ptmx_path = NULL;
>
> /*
> * We may have 2 cases here: the slave either need to
> @@ -540,22 +554,25 @@ static int pty_open_unpaired_slave(struct file_desc *d, struct tty_info *slave)
> pr_info("Migrated slave peer %x -> to fd %d\n",
> slave->tfe->id, fd);
> } else {
> - char pts_name[64];
> -
> - snprintf(pts_name, sizeof(pts_name), PTS_FMT, slave->tie->pty->index);
> + ptmx_path = pty_alloc_path_master(slave);
> + if (!ptmx_path)
> + goto err;
>
> - master = pty_open_ptmx_index(O_RDONLY, slave->tie->pty->index);
> + master = pty_open_ptmx_index(ptmx_path,
> + O_RDONLY,
> + slave->tie->pty->index);
> if (master < 0) {
> - pr_perror("Can't open fale %x (index %d)",
> - slave->tfe->id, slave->tie->pty->index);
> - return -1;
> + pr_perror("Can't open fake %s (id %#x index %d)",
> + ptmx_path, slave->tfe->id,
> + slave->tie->pty->index);
> + goto err;
> }
>
> unlock_pty(master);
>
> - fd = open(pts_name, slave->tfe->flags | O_NOCTTY);
> + fd = open(slave->path, slave->tfe->flags | O_NOCTTY);
> if (fd < 0) {
> - pr_perror("Can't open slave %s", pts_name);
> + pr_perror("Can't open slave %s", slave->path);
> goto err;
> }
>
> @@ -597,18 +614,26 @@ static int pty_open_unpaired_slave(struct file_desc *d, struct tty_info *slave)
> err:
> close_safe(&master);
> close_safe(&fd);
> + xfree(ptmx_path);
> return ret;
> }
>
> static int pty_open_ptmx(struct tty_info *info)
> {
> + char *ptmx_path = NULL;
> int master = -1;
>
> - master = pty_open_ptmx_index(info->tfe->flags, info->tie->pty->index);
> - if (master < 0) {
> - pr_perror("Can't open %x (index %d)",
> - info->tfe->id, info->tie->pty->index);
> + ptmx_path = pty_alloc_path_master(info);
> + if (!ptmx_path)
> return -1;
> +
> + master = pty_open_ptmx_index(ptmx_path,
> + info->tfe->flags,
> + info->tie->pty->index);
> + if (master < 0) {
> + pr_perror("Can't open %s (id %#x index %d)",
> + ptmx_path, info->tfe->id, info->tie->pty->index);
> + goto err;
> }
>
> unlock_pty(master);
> @@ -635,9 +660,11 @@ static int pty_open_ptmx(struct tty_info *info)
> if (info->tie->locked)
> lock_pty(master);
>
> + xfree(ptmx_path);
> return master;
> err:
> close_safe(&master);
> + xfree(ptmx_path);
> return -1;
> }
>
> @@ -951,6 +978,66 @@ struct collect_image_info tty_info_cinfo = {
> .flags = COLLECT_OPTIONAL,
> };
>
> +static int tty_make_path(struct tty_info *info)
> +{
> + if (info->tfe->path) {
> + info->path = &info->tfe->path[1];
> + return 0;
> + }
> +
> + if (tty_is_master(info))
> + info->path = xstrdup("/dev/ptmx");
> + else {
> + info->path = xmalloc(64);
> + if (info->path) {
> + snprintf(info->path, 64, "/dev/pts/%u",
> + info->tie->pty->index);
> + }
> + }
> +
> + if (!info->path)
> + return -1;
> + return 0;
> +}
> +
> +static char *pty_alloc_path(struct tty_info *info, bool master)
> +{
> + char *pos, *path;
> + size_t len, slash_at;
> +
> + if ((tty_is_master(info) && master) ||
> + (!tty_is_master(info) && !master))
> + return xstrdup(info->path);
> +
> + len = strlen(info->path) + 1;
> + pos = strrchr(info->path, '/');
> + slash_at = pos - info->path;
> +
> + if (!pos) {
> + pr_err("Malformed path %s for %#x\n",
> + info->path, info->tfe->id);
> + return NULL;
> + }
> +
> + path = xmalloc(len + 32);
> + if (!path)
> + return NULL;
> +
> + memcpy(path, info->path, slash_at);
> + if (master) {
> + strcat(path, "ptmx");
> + } else {
> + if (slash_at >= 4 && strcmp(&path[slash_at - 4], "pts"))
> + snprintf(&path[slash_at], 10,
> + "/pts/%u", info->tie->pty->index);
> + else
> + snprintf(&path[slash_at], 10,
> + "/%u", info->tie->pty->index);
> + }
> +
> + return path;
> +}
> +
> static int collect_one_tty(void *obj, ProtobufCMessage *msg)
> {
> struct tty_info *info = obj;
> @@ -973,6 +1060,9 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg)
> if (verify_info(info))
> return -1;
>
> + if (tty_make_path(info))
> + return -1;
> +
> /*
> * The tty peers which have no @termios are hung up,
> * so don't mark them as active, we create them with
> @@ -1174,6 +1264,24 @@ static int dump_one_pty(int lfd, u32 id, const struct fd_parms *p, int major, in
> e.flags = p->flags;
> e.fown = (FownEntry *)&p->fown;
>
> + e.has_dev_sb = true;
> + e.dev_sb = p->stat.st_dev;
> + e.path = p->link->name;
> +
> + e.has_mnt_id = true;
> + if (p->mnt_id != -1) {
> + e.mnt_id = p->mnt_id;
> + } else {
> + struct mount_info *m = lookup_mnt_sdev(p->stat.st_dev);
> + if (!m) {
> + pr_err("Can't find mount with st_dev %#x\n",
> + (int)p->stat.st_dev);
> + return -1;
> + }
> +
> + e.mnt_id = m->mnt_id;
> + }
> +
> /*
> * FIXME
> *
> --
> 1.9.3
>
More information about the CRIU
mailing list