[CRIU] [PATCH] tty: add vt support
Cyrill Gorcunov
gorcunov at gmail.com
Fri Dec 5 01:05:39 PST 2014
On Fri, Dec 05, 2014 at 01:44:22AM +0200, Ruslan Kuprieiev wrote:
> /dev/ttyN are the virtual terminals which are provided
> by the system with major 4 and minor 0..63.
> You can run some program on ttyN by pressing alt+ctrl+FN
> and running it manualy or by using open(openvt nowadays).
>
> Signed-off-by: Ruslan Kuprieiev <kupruser at gmail.com>
> ---
> include/tty.h | 9 ++++++++
> protobuf/tty.proto | 1 +
> tty.c | 62 ++++++++++++++++++++++++++++++++++++++++++++----------
> 3 files changed, 61 insertions(+), 11 deletions(-)
>
> diff --git a/include/tty.h b/include/tty.h
> index a3026f6..5019dcf 100644
> --- a/include/tty.h
> +++ b/include/tty.h
> @@ -13,6 +13,7 @@ enum {
> TTY_TYPE_PTM = 1,
> TTY_TYPE_PTS = 2,
> TTY_TYPE_CONSOLE = 3,
> + TTY_TYPE_VT = 4,
>
> TTY_TYPE_MAX
> };
> @@ -34,6 +35,14 @@ static inline int tty_type(int major, int minor)
> else if (minor == 1)
> return TTY_TYPE_CONSOLE;
> break;
> + case TTY_MAJOR:
> + if (minor < 64)
> + /*
> + * Beyond 63 are the serial devices.
> + * Not sure how to handle them, so lets
> + * leave them till someone requests.
> + */
> + return TTY_TYPE_VT;
This should be something like that
/*
* Minors [1; MAX_NR_CONSOLES] stand for
* consoles (virtual terminals, VT in terms
* of kernel).
*/
Also MAX_NR_CONSOLES is defined in uapi/vt.h thus we should inlcude it
directly
#include <linux/vt.h>
or (if this is a problem for some reason -- predefine own MAX_NR_CONSOLES).
> case UNIX98_PTY_MASTER_MAJOR ... (UNIX98_PTY_MASTER_MAJOR + UNIX98_PTY_MAJOR_COUNT - 1):
> return TTY_TYPE_PTM;
> case UNIX98_PTY_SLAVE_MAJOR:
> diff --git a/protobuf/tty.proto b/protobuf/tty.proto
> index 18470a9..0e67e85 100644
> --- a/protobuf/tty.proto
> +++ b/protobuf/tty.proto
> @@ -27,6 +27,7 @@ enum TtyType {
> UNKNOWN = 0;
> PTY = 1;
> CONSOLE = 2;
> + VT = 3;
> }
>
> message tty_info_entry {
> diff --git a/tty.c b/tty.c
> index b076f06..5886dff 100644
> --- a/tty.c
> +++ b/tty.c
> @@ -118,6 +118,7 @@ static LIST_HEAD(all_ttys);
> #define MAX_TTYS 1024
> #define MAX_PTY_INDEX 1000
> #define CONSOLE_INDEX 1002
> +#define VT_INDEX 1004
>
> static DECLARE_BITMAP(tty_bitmap, (MAX_TTYS << 1));
> static DECLARE_BITMAP(tty_active_pairs, (MAX_TTYS << 1));
> @@ -235,11 +236,17 @@ static int parse_tty_index(u32 id, int lfd, const struct fd_parms *p, int type)
> case TTY_TYPE_CONSOLE:
> index = CONSOLE_INDEX;
> break;
> +
> + case TTY_TYPE_VT: {
> + index = VT_INDEX;
> + break;
> + }
Redundant { } here
> default:
> BUG();
> }
>
> if (type != TTY_TYPE_CONSOLE &&
> + type != TTY_TYPE_VT &&
> index > MAX_PTY_INDEX) {
> pr_err("Index %d on tty %x is too big\n", index, id);
> return -1;
> @@ -508,6 +515,13 @@ static int tty_restore_ctl_terminal(struct file_desc *d, int fd)
> pr_perror("Can't open %s", path_from_reg(info->reg_d));
> goto err;
> }
> + } else if (info->type == TTY_TYPE_VT) {
> + slave = open_pty_reg(info->reg_d, O_RDONLY);
> + index = VT_INDEX;
> + if (slave < 0) {
> + pr_perror("Can't open %s", path_from_reg(info->reg_d));
> + goto err;
> + }
> } else
> BUG();
>
> @@ -534,13 +548,21 @@ static char *tty_name(int type)
> return "pts";
> case TTY_TYPE_CONSOLE:
> return "console";
> + case TTY_TYPE_VT:
> + return "tty";
> }
> return "unknown";
> }
>
> static bool tty_is_master(struct tty_info *info)
> {
> - return info->type == TTY_TYPE_PTM || info->type == TTY_TYPE_CONSOLE;
> + if (info->type == TTY_TYPE_PTM || info->type == TTY_TYPE_CONSOLE)
> + return true;
> +
> + if (info->type == TTY_TYPE_VT && !opts.shell_job)
> + return true;
> +
> + return false;
> }
>
> static bool tty_is_hung(struct tty_info *info)
> @@ -558,9 +580,21 @@ static bool tty_has_active_pair(struct tty_info *info)
>
> static void tty_show_pty_info(char *prefix, struct tty_info *info)
> {
> + int index;
int index = -1;
> +
> + switch (info->type) {
> + case TTY_TYPE_CONSOLE:
> + index = CONSOLE_INDEX;
> + break;
> + case TTY_TYPE_VT:
> + index = VT_INDEX;
> + break;
case TTY_TYPE_PTM:
case TTY_TYPE_PTS:
index = info->tie->pty->index;
break;
> + default:
> + index = info->tie->pty->index;
> + }
drop this "default"
> +
> pr_info("%s type %s id %#x index %d (master %d sid %d pgrp %d inherit %d)\n",
> - prefix, tty_name(info->type), info->tfe->id,
> - info->type == TTY_TYPE_CONSOLE ? CONSOLE_INDEX : info->tie->pty->index,
> + prefix, tty_name(info->type), info->tfe->id, index,
> tty_is_master(info), info->tie->sid, info->tie->pgrp, info->inherit);
> }
>
> @@ -788,14 +822,15 @@ err:
> return -1;
> }
>
> -static int open_console(struct tty_info *info)
> +static int open_simple_tty(struct tty_info *info)
> {
> int fd = -1;
>
> fd = open_pty_reg(info->reg_d, info->tfe->flags);
> if (fd < 0) {
> - pr_perror("Can't open console %x",
> - info->tfe->id);
> + pr_perror("Can't open %s %x",
> + info->type == TTY_TYPE_CONSOLE ? "console" : "virtual terminal",
> + info->tfe->id);
> return -1;
> }
>
> @@ -820,8 +855,8 @@ static int tty_open(struct file_desc *d)
> if (!tty_is_master(info))
> return pty_open_unpaired_slave(d, info);
>
> - if (info->type == TTY_TYPE_CONSOLE)
> - return open_console(info);
> + if (info->type == TTY_TYPE_CONSOLE || info->type == TTY_TYPE_VT)
> + return open_simple_tty(info);
This should be somehow cleaned up, I'll think on it, but lets leave it as
in patch for now
>
> return pty_open_ptmx(info);
> }
> @@ -1002,12 +1037,12 @@ int tty_setup_slavery(void)
> list_for_each_entry(info, &all_ttys, list) {
> if (tty_find_restoring_task(info))
> return -1;
> - if (info->type == TTY_TYPE_CONSOLE)
> + if (info->type == TTY_TYPE_CONSOLE || info->type == TTY_TYPE_VT)
> continue;
>
> peer = info;
> list_for_each_entry_safe_continue(peer, m, &all_ttys, list) {
> - if (peer->type == TTY_TYPE_CONSOLE)
> + if (peer->type == TTY_TYPE_CONSOLE || info->type == TTY_TYPE_VT)
> continue;
> if (peer->tie->pty->index != info->tie->pty->index)
> continue;
> @@ -1057,7 +1092,8 @@ static int verify_info(struct tty_info *info)
> {
> if (info->type != TTY_TYPE_PTM &&
> info->type != TTY_TYPE_PTS &&
> - info->type != TTY_TYPE_CONSOLE) {
> + info->type != TTY_TYPE_CONSOLE &&
> + info->type != TTY_TYPE_VT) {
> pr_err("Unknown type %d master peer %x\n",
> info->type, info->tfe->id);
> return -1;
> @@ -1115,6 +1151,7 @@ static int collect_one_tty_info_entry(void *obj, ProtobufCMessage *msg)
> }
> break;
> case TTY_TYPE__CONSOLE:
> + case TTY_TYPE__VT:
> if (info->tie->pty) {
> pr_err("PTY data found (id %x), corrupted image?\n",
> info->tie->id);
> @@ -1312,6 +1349,9 @@ static int dump_tty_info(int lfd, u32 id, const struct fd_parms *p, int type, in
> case TTY_TYPE_CONSOLE:
> info.type = TTY_TYPE__CONSOLE;
> break;
> + case TTY_TYPE_VT:
> + info.type = TTY_TYPE__VT;
> + break;
> default:
> BUG();
> }
The rest looks good to me, hopefully it works as needed (some zdtm tests?).
But I didn't look into kernel implementatio so might be missing something.
Cyrill
More information about the CRIU
mailing list