[CRIU] [PATCH 1/2] tty: Add restoration of locked/exclusive ptys
Pavel Emelyanov
xemul at parallels.com
Wed Sep 5 12:47:47 EDT 2012
On 09/05/2012 02:50 PM, Cyrill Gorcunov wrote:
> Since opening locked/exclusive ptys do return
> different error code we can figure out what
> exactly tty flag the peer has.
>
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
> include/tty.h | 3 ++
> protobuf/tty.proto | 6 ++++
> tty.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++-----
> 3 files changed, 77 insertions(+), 8 deletions(-)
>
> diff --git a/include/tty.h b/include/tty.h
> index 8457270..8a06bad 100644
> --- a/include/tty.h
> +++ b/include/tty.h
> @@ -13,6 +13,9 @@
> #endif
> #define PTS_FMT "/dev/pts/%d"
>
> +#define TTY_LOCKED (1 << 0)
> +#define TTY_EXCLUSIVE (1 << 1)
> +
> extern int dump_tty(struct fd_parms *p, int lfd, const struct cr_fdset *set);
> extern int collect_tty(void);
> extern int tty_is_master(struct fdinfo_list_entry *le);
> diff --git a/protobuf/tty.proto b/protobuf/tty.proto
> index 8f497dc..38adab2 100644
> --- a/protobuf/tty.proto
> +++ b/protobuf/tty.proto
> @@ -31,6 +31,12 @@ message tty_file_entry {
> required uint64 pos = 5;
> required uint64 rdev = 6;
> required fown_entry fown = 7;
> +
> + /*
> + * Bits
> + * 0 - locked
> + * 1 - exclusive
> + */
> required uint32 tty_flags = 8;
Better make it
required bool locked;
required bool exclusive;
>
> enum Type {
> diff --git a/tty.c b/tty.c
> index b4e89bc..8ac61f7 100644
> --- a/tty.c
> +++ b/tty.c
> @@ -81,9 +81,6 @@
> * restore the master end might be already closed for any reason so
> * to resolve such problem we open a fake master peer with proper index
> * and hook a slave on it, then we close master peer.
> - *
> - * - Find a way to fetch tty flags from the kernel (locked/exclusive)
> - * and save it in tty_flags.
> */
>
> #undef LOG_PREFIX
> @@ -259,11 +256,6 @@ static int pty_open_ptmx_index(int flags, int index)
> return ret;
> }
>
> -/*
> - * FIXME Need to find a way to figure out if master
> - * is in locked state when being dumped. If so, need
> - * to re-lock it on restore.
> - */
> static int unlock_pty_master(int master)
> {
> const int lock = 0;
> @@ -281,6 +273,58 @@ static int unlock_pty_master(int master)
> return 0;
> }
>
> +static int lock_pty_master(int master)
> +{
> + const int lock = 1;
> +
> + if (ioctl(master, TIOCSPTLCK, &lock)) {
> + pr_err("Unable to lock pty master device %d\n", master);
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +static int set_exclusive_pty_master(int master)
> +{
> + if (ioctl(master, TIOCEXCL)) {
> + pr_err("Unable to make pty master exclusive %d\n", master);
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +static int get_pty_flags(int index, unsigned int *flags)
> +{
> + char pts_name[64];
> + int ret = 0, fd;
> +
> + *flags = 0;
> +
> + snprintf(pts_name, sizeof(pts_name), PTS_FMT, index);
> +
> + fd = open(pts_name, O_RDONLY);
> + if (fd < 0) {
> + switch (errno) {
> + case EIO:
> + *flags |= TTY_LOCKED;
> + break;
> + case EBUSY:
> + *flags |= TTY_EXCLUSIVE;
> + break;
Hm... This is VERY nice, but we need to add crtools check checker for this
being true.
> + default:
> + pr_perror("Can't open %s to obtain flags",
> + pts_name);
> + ret = -1;
> + break;
> + }
> + } else
> + close(fd);
> +
> + return ret;
> +}
> +
> static int tty_get_sid(int fd)
> {
> int sid, ret;
> @@ -498,6 +542,11 @@ static int pty_open_ptmx(struct tty_file_info *info)
> if (pty_open_slaves(info))
> goto err;
>
> + if (info->tfe->tty_flags & TTY_LOCKED)
> + lock_pty_master(master);
> + else if (info->tfe->tty_flags & TTY_EXCLUSIVE)
> + set_exclusive_pty_master(master);
Can't they be set simultaneously?
> +
> return master;
> err:
> close_safe(&master);
> @@ -676,6 +725,7 @@ static int dump_control_pty(int index, pid_t sid, pid_t prgp)
> pr_info("Dump control terminal for %d\n", sid);
>
> snprintf(path, sizeof(path), "/dev/pts/%d", index);
> +
Huh?
> fd = open(path, O_RDONLY);
> if (fd < 0) {
> pr_err("Can't open terminal %s\n", path);
> @@ -760,9 +810,19 @@ static int __dump_one_pty(int lfd, u32 id, const struct fd_parms *p, pid_t sid,
> if (sid < 0 || prgp < 0)
> return -1;
>
> + /*
> + * Also figure out the flags master pty has.
> + */
Stupid comment, don't you think?
> + if (get_pty_flags(pty.index, &e.tty_flags))
> + return -1;
> +
> if (sid) {
> + if (e.tty_flags & TTY_LOCKED)
> + unlock_pty_master(lfd);
What for?
> if (dump_control_pty(pty.index, sid, prgp))
> return -1;
> + if (e.tty_flags & TTY_LOCKED)
> + lock_pty_master(lfd);
> }
> }
>
More information about the CRIU
mailing list