[CRIU] [PATCH 5/7] tty: Save mount ids for terminals into image
Pavel Emelyanov
xemul at virtuozzo.com
Tue Jan 31 03:32:55 PST 2017
On 01/21/2017 04:11 PM, Cyrill Gorcunov wrote:
> 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))
Why is is_root() check needed?
> + 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);
Runaway from patch #4?
> 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;
Is it needed for non-ptys?
> +
> + 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];
O_o do we _really_ need mnt_id for all three?
> }
>
More information about the CRIU
mailing list