[CRIU] [RFC] tty: Add support of system console (/dev/console)
Tycho Andersen
tycho.andersen at canonical.com
Wed Oct 15 05:10:46 PDT 2014
Hi Cyrill,
On Wed, Oct 15, 2014 at 01:27:49PM +0400, Cyrill Gorcunov wrote:
> /dev/console is a system console which provided
> by the system with major 5 and minor 1. It's usually
> configured on system startup with console= option
> and underlied driver is resposible to deliver messages
> to the console user.
>
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
>
> This patch is on top of previous
>
> [PATCH 0/5] tty: Use reg-files engine to save paths to tty peers
I tried to apply both the above branch and this patch, but my git
apply failed against current master. Can you send a github branch
that I can pull?
Tycho
> please take a look.
>
> include/tty.h | 1 +
> protobuf/tty.proto | 1 +
> tty.c | 165 +++++++++++++++++++++++++++++++++++++++--------------
> 3 files changed, 124 insertions(+), 43 deletions(-)
>
> diff --git a/include/tty.h b/include/tty.h
> index 7181cdd00e6c..658981304466 100644
> --- a/include/tty.h
> +++ b/include/tty.h
> @@ -10,6 +10,7 @@ enum {
> TTY_TYPE_UNKNOWN = 0,
> TTY_TYPE_PTM = 1,
> TTY_TYPE_PTS = 2,
> + TTY_TYPE_CONSOLE = 3,
>
> TTY_TYPE_MAX
> };
> diff --git a/protobuf/tty.proto b/protobuf/tty.proto
> index 8942965c580b..18470a9af0b7 100644
> --- a/protobuf/tty.proto
> +++ b/protobuf/tty.proto
> @@ -26,6 +26,7 @@ message tty_pty_entry {
> enum TtyType {
> UNKNOWN = 0;
> PTY = 1;
> + CONSOLE = 2;
> }
>
> message tty_info_entry {
> diff --git a/tty.c b/tty.c
> index e5e64878a736..63b3b810bcfe 100644
> --- a/tty.c
> +++ b/tty.c
> @@ -114,7 +114,10 @@ static LIST_HEAD(all_ttys);
> * This particular bitmap requires 256 bytes of memory.
> * Pretty acceptable trade off in a sake of simplicity.
> */
> -#define MAX_TTYS 1024
> +#define MAX_TTYS 1024
> +#define MAX_PTY_INDEX 1000
> +#define CONSOLE_INDEX 1002
> +
> static DECLARE_BITMAP(tty_bitmap, (MAX_TTYS << 1));
> static DECLARE_BITMAP(tty_active_pairs, (MAX_TTYS << 1));
>
> @@ -229,7 +232,7 @@ static int parse_pty_index(u32 id, int lfd, const struct fd_parms *p, int type)
> }
> }
>
> - if (index > MAX_TTYS) {
> + if (index > MAX_PTY_INDEX) {
> pr_err("Index %d on tty %x is too big\n", index, id);
> return -1;
> }
> @@ -296,6 +299,7 @@ static struct tty_info *pty_alloc_fake(struct tty_info *info, int type)
> info->tfe->id, info->reg_d);
>
> BUG_ON(!info->reg_d);
> + BUG_ON((type != TTY_TYPE_PTM) && (type != TTY_TYPE_PTS));
> orig = container_of(info->reg_d, struct reg_file_info, d);
>
> p = xzalloc(sizeof(*p) +
> @@ -512,20 +516,29 @@ static int tty_set_prgp(int fd, int group)
> static int tty_restore_ctl_terminal(struct file_desc *d, int fd)
> {
> struct tty_info *info = container_of(d, struct tty_info, d);
> - struct tty_info *fake;
> - int slave, ret = -1;
> + struct tty_info *fake = NULL;
> + int slave = -1, ret = -1;
>
> if (!is_service_fd(fd, CTL_TTY_OFF))
> return 0;
>
> - fake = pty_alloc_fake_slave(info);
> - if (!fake)
> - goto err;
> - slave = open_pty_reg(fake, O_RDONLY);
> - if (slave < 0) {
> - pr_perror("Can't open %s", path_from_reg(fake->reg_d));
> - goto err;
> - }
> + if (info->type == TTY_TYPE_PTM || info->type == TTY_TYPE_PTS) {
> + fake = pty_alloc_fake_slave(info);
> + if (!fake)
> + goto err;
> + slave = open_pty_reg(fake, O_RDONLY);
> + if (slave < 0) {
> + pr_perror("Can't open %s", path_from_reg(fake->reg_d));
> + goto err;
> + }
> + } else if (info->type == TTY_TYPE_CONSOLE) {
> + slave = open_pty_reg(info, O_RDONLY);
> + if (slave < 0) {
> + pr_perror("Can't open %s", path_from_reg(info->reg_d));
> + goto err;
> + }
> + } else
> + BUG();
>
> pr_info("Restore session %d by %d tty (index %d)\n",
> info->tie->sid, (int)getpid(),
> @@ -548,6 +561,8 @@ int tty_type(int major, int minor)
> case TTYAUX_MAJOR:
> if (minor == 0 || minor == 2)
> return TTY_TYPE_PTM;
> + else if (minor == 1)
> + return TTY_TYPE_CONSOLE;
> break;
> case UNIX98_PTY_MASTER_MAJOR ... (UNIX98_PTY_MASTER_MAJOR + UNIX98_PTY_MAJOR_COUNT - 1):
> return TTY_TYPE_PTM;
> @@ -564,13 +579,16 @@ static char *tty_name(int type)
> return "ptmx";
> case TTY_TYPE_PTS:
> return "pts";
> + case TTY_TYPE_CONSOLE:
> + return "console";
> }
> return "unknown";
> }
>
> static bool tty_is_master(struct tty_info *info)
> {
> - return info->type == TTY_TYPE_PTM;
> + return info->type == TTY_TYPE_PTM ||
> + info->type == TTY_TYPE_CONSOLE;
> }
>
> static bool tty_is_hung(struct tty_info *info)
> @@ -816,6 +834,26 @@ err:
> return -1;
> }
>
> +static int open_console(struct tty_info *info)
> +{
> + int fd = -1;
> +
> + fd = open_pty_reg(info, info->tfe->flags);
> + if (fd < 0) {
> + pr_perror("Can't open console %x",
> + info->tfe->id);
> + return -1;
> + }
> +
> + if (restore_tty_params(fd, info))
> + goto err;
> +
> + return fd;
> +err:
> + close_safe(&fd);
> + return -1;
> +}
> +
> static int tty_open(struct file_desc *d)
> {
> struct tty_info *info = container_of(d, struct tty_info, d);
> @@ -828,8 +866,10 @@ static int tty_open(struct file_desc *d)
> if (!tty_is_master(info))
> return pty_open_unpaired_slave(d, info);
>
> - return pty_open_ptmx(info);
> -
> + if (info->type == TTY_TYPE_CONSOLE)
> + return open_console(info);
> + else
> + return pty_open_ptmx(info);
> }
>
> static int tty_transport(FdinfoEntry *fe, struct file_desc *d)
> @@ -1058,8 +1098,9 @@ static int verify_termios(u32 id, TermiosEntry *e)
> static int verify_info(struct tty_info *info)
> {
> if (info->type != TTY_TYPE_PTM &&
> - info->type != TTY_TYPE_PTS) {
> - pr_err("Unknown type %d master peer %x\n",
> + info->type != TTY_TYPE_PTS &&
> + info->type != TTY_TYPE_CONSOLE) {
> + pr_err("Unknown type %d peer %x\n",
> info->type, info->tfe->id);
> return -1;
> }
> @@ -1107,18 +1148,27 @@ static int collect_one_tty_info_entry(void *obj, ProtobufCMessage *msg)
>
> info->tie = pb_msg(msg, TtyInfoEntry);
>
> - if (info->tie->type != TTY_TYPE__PTY) {
> + switch (info->tie->type) {
> + case TTY_TYPE__PTY:
> + if (!info->tie->pty) {
> + pr_err("No PTY data found (id %x), corrupted image?\n",
> + info->tie->id);
> + return -1;
> + }
> + break;
> + case TTY_TYPE__CONSOLE:
> + if (info->tie->pty) {
> + pr_err("PTY data found (id %x), corrupted image?\n",
> + info->tie->id);
> + return -1;
> + }
> + break;
> + default:
> pr_err("Unexpected TTY type %d (id %x)\n",
> info->tie->type, info->tie->id);
> return -1;
> }
>
> - if (!info->tie->pty) {
> - pr_err("No PTY data found (id %x), corrupted image?\n",
> - info->tie->id);
> - return -1;
> - }
> -
> INIT_LIST_HEAD(&info->list);
> list_add(&info->list, &all_tty_info_entries);
>
> @@ -1171,10 +1221,16 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg)
>
> info->reg_d = find_file_desc_raw(FD_TYPES__REG, info->tfe->id);
> if (!info->reg_d) {
> - info->reg_d = pty_alloc_fake_reg_d(info, true);
> - if (!info->reg_d) {
> - pr_err("Can't generate new reg_d descriptor for id %#x\n",
> - info->tfe->id);
> + if (info->type == TTY_TYPE_PTM ||
> + info->type == TTY_TYPE_PTS) {
> + info->reg_d = pty_alloc_fake_reg_d(info, true);
> + if (!info->reg_d) {
> + pr_err("Can't generate new reg_d descriptor for id %#x\n",
> + info->tfe->id);
> + return -1;
> + }
> + } else {
> + pr_err("No reg_d descriptor for id %#x\n", info->tfe->id);
> return -1;
> }
> }
> @@ -1195,8 +1251,10 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg)
> * can't be used. Most likely they appear if a user has
> * dumped program when it was closing a peer.
> */
> - if (info->tie->termios)
> - tty_test_and_set(info->tfe->tty_info_id, tty_active_pairs);
> + if (info->type == TTY_TYPE_PTM || info->type == TTY_TYPE_PTS) {
> + if (info->tie->termios)
> + tty_test_and_set(info->tfe->tty_info_id, tty_active_pairs);
> + }
>
> pr_info("Collected tty ID %#x\n", info->tfe->id);
>
> @@ -1264,7 +1322,7 @@ int dump_verify_tty_sids(void)
> return ret;
> }
>
> -static int dump_pty_info(int lfd, u32 id, const struct fd_parms *p, int type, int index)
> +static int dump_tty_info(int lfd, u32 id, const struct fd_parms *p, int type, int index)
> {
> TtyInfoEntry info = TTY_INFO_ENTRY__INIT;
> TermiosEntry termios = TERMIOS_ENTRY__INIT;
> @@ -1304,18 +1362,28 @@ static int dump_pty_info(int lfd, u32 id, const struct fd_parms *p, int type, in
> list_add_tail(&dinfo->list, &all_ttys);
>
> info.id = id;
> - info.type = TTY_TYPE__PTY;
> info.sid = pti->sid;
> info.pgrp = pti->pgrp;
> info.rdev = p->stat.st_rdev;
> - info.pty = &pty;
> +
> + switch (type) {
> + case TTY_TYPE_PTM:
> + case TTY_TYPE_PTS:
> + info.type = TTY_TYPE__PTY;
> + info.pty = &pty;
> + pty.index = index;
> + break;
> + case TTY_TYPE_CONSOLE:
> + info.type = TTY_TYPE__CONSOLE;
> + break;
> + default:
> + BUG();
> + }
>
> info.locked = pti->st_lock;
> info.exclusive = pti->st_excl;
> info.packet_mode = pti->st_pckt;
>
> - pty.index = index;
> -
> /*
> * Nothing we can do on hanging up terminal,
> * just write out minimum information we can
> @@ -1331,7 +1399,8 @@ static int dump_pty_info(int lfd, u32 id, const struct fd_parms *p, int type, in
> * not yet supported by our tool and better to
> * inform a user about such situation.
> */
> - tty_test_and_set(id, tty_active_pairs);
> + if (type == TTY_TYPE_PTM || type == TTY_TYPE_PTS)
> + tty_test_and_set(id, tty_active_pairs);
>
> info.termios = &termios;
> info.termios_locked = &termios_locked;
> @@ -1374,10 +1443,10 @@ out:
> return ret;
> }
>
> -static int dump_one_pty(int lfd, u32 id, const struct fd_parms *p)
> +static int dump_one_tty(int lfd, u32 id, const struct fd_parms *p)
> {
> TtyFileEntry e = TTY_FILE_ENTRY__INIT;
> - int ret = 0, type, index;
> + int ret = 0, type, index = -1;
>
> pr_info("Dumping tty %d with id %#x\n", lfd, id);
>
> @@ -1385,9 +1454,19 @@ static int dump_one_pty(int lfd, u32 id, const struct fd_parms *p)
> return -1;
>
> type = tty_type(major(p->stat.st_rdev), minor(p->stat.st_rdev));
> - index = parse_pty_index(id, lfd, p, type);
> - if (index < 0)
> - return -1;
> + switch (type) {
> + case TTY_TYPE_PTM:
> + case TTY_TYPE_PTS:
> + index = parse_pty_index(id, lfd, p, type);
> + if (index < 0)
> + return -1;
> + break;
> + case TTY_TYPE_CONSOLE:
> + index = CONSOLE_INDEX;
> + break;
> + default:
> + BUG();
> + }
>
> e.id = id;
> e.tty_info_id = tty_gen_id(type, index);
> @@ -1415,7 +1494,7 @@ static int dump_one_pty(int lfd, u32 id, const struct fd_parms *p)
> */
>
> if (!tty_test_and_set(e.tty_info_id, tty_bitmap))
> - ret = dump_pty_info(lfd, e.tty_info_id, p, type, index);
> + ret = dump_tty_info(lfd, e.tty_info_id, p, type, index);
>
> if (!ret)
> ret = pb_write_one(img_from_set(glob_imgset, CR_FD_TTY_FILES), &e, PB_TTY_FILE);
> @@ -1424,7 +1503,7 @@ static int dump_one_pty(int lfd, u32 id, const struct fd_parms *p)
>
> const struct fdtype_ops tty_dump_ops = {
> .type = FD_TYPES__TTY,
> - .dump = dump_one_pty,
> + .dump = dump_one_tty,
> };
>
> int tty_prep_fds(void)
> --
> 1.9.3
>
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
More information about the CRIU
mailing list