Commit bcc1f4eb authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Pavel Emelyanov

tty: Introduce tty types

Instead of calling case() with majors all over the places lets
introduce own enum for tty types and use it instead.

Because we're using not @major numbers now but taking @minors
into account as well, this brings more strict check of which
kind of terminals we can dump now thus it's potentially should
fix the cases when we're trying to c/r terminals which we don't
understand yet (in particular /dev/console [5:1]).
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Acked-by: 's avatarTycho Andersen <tycho.andersen@canonical.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 9498609f
...@@ -273,11 +273,6 @@ static int dump_chrdev(struct fd_parms *p, int lfd, struct cr_img *img) ...@@ -273,11 +273,6 @@ static int dump_chrdev(struct fd_parms *p, int lfd, struct cr_img *img)
case MEM_MAJOR: case MEM_MAJOR:
ops = &regfile_dump_ops; ops = &regfile_dump_ops;
break; break;
case TTYAUX_MAJOR:
case UNIX98_PTY_MASTER_MAJOR ... (UNIX98_PTY_MASTER_MAJOR + UNIX98_PTY_MAJOR_COUNT - 1):
case UNIX98_PTY_SLAVE_MAJOR:
ops = &tty_dump_ops;
break;
case MISC_MAJOR: case MISC_MAJOR:
ops = get_misc_dev_ops(minor(p->stat.st_rdev)); ops = get_misc_dev_ops(minor(p->stat.st_rdev));
if (ops) if (ops)
...@@ -286,6 +281,11 @@ static int dump_chrdev(struct fd_parms *p, int lfd, struct cr_img *img) ...@@ -286,6 +281,11 @@ static int dump_chrdev(struct fd_parms *p, int lfd, struct cr_img *img)
default: { default: {
char more[32]; char more[32];
if (is_tty(maj, minor(p->stat.st_rdev))) {
ops = &tty_dump_ops;
break;
}
sprintf(more, "%d:%d", maj, minor(p->stat.st_rdev)); sprintf(more, "%d:%d", maj, minor(p->stat.st_rdev));
return dump_unsupp_fd(p, lfd, img, "chr", more); return dump_unsupp_fd(p, lfd, img, "chr", more);
} }
......
#ifndef __CR_TTY_H__ #ifndef __CR_TTY_H__
#define __CR_TTY_H__ #define __CR_TTY_H__
#include <linux/major.h>
#include "files.h" #include "files.h"
/* Kernel's limit */ /* Kernel's limit */
#define TERMIOS_NCC 19 #define TERMIOS_NCC 19
enum {
TTY_TYPE_UNKNOWN = 0,
TTY_TYPE_PTM = 1,
TTY_TYPE_PTS = 2,
TTY_TYPE_MAX
};
#define PTMX_PATH "/dev/ptmx" #define PTMX_PATH "/dev/ptmx"
#ifndef PTMX_MINOR #ifndef PTMX_MINOR
# define PTMX_MINOR 2 # define PTMX_MINOR 2
...@@ -13,6 +23,27 @@ ...@@ -13,6 +23,27 @@
#define PTS_FMT "/dev/pts/%d" #define PTS_FMT "/dev/pts/%d"
extern const struct fdtype_ops tty_dump_ops; extern const struct fdtype_ops tty_dump_ops;
static inline int tty_type(int major, int minor)
{
switch (major) {
case TTYAUX_MAJOR:
if (minor == 0 || minor == 2)
return TTY_TYPE_PTM;
break;
case UNIX98_PTY_MASTER_MAJOR ... (UNIX98_PTY_MASTER_MAJOR + UNIX98_PTY_MAJOR_COUNT - 1):
return TTY_TYPE_PTM;
case UNIX98_PTY_SLAVE_MAJOR:
return TTY_TYPE_PTS;
}
return TTY_TYPE_UNKNOWN;
}
static inline int is_tty(int major, int minor)
{
return tty_type(major, minor) != TTY_TYPE_UNKNOWN;
}
extern int dump_verify_tty_sids(void); extern int dump_verify_tty_sids(void);
extern struct collect_image_info tty_info_cinfo; extern struct collect_image_info tty_info_cinfo;
extern struct collect_image_info tty_cinfo; extern struct collect_image_info tty_cinfo;
......
...@@ -84,7 +84,7 @@ struct tty_info { ...@@ -84,7 +84,7 @@ struct tty_info {
TtyInfoEntry *tie; TtyInfoEntry *tie;
struct list_head sibling; struct list_head sibling;
int major; int type;
bool create; bool create;
bool inherit; bool inherit;
...@@ -97,7 +97,7 @@ struct tty_dump_info { ...@@ -97,7 +97,7 @@ struct tty_dump_info {
pid_t sid; pid_t sid;
pid_t pgrp; pid_t pgrp;
int fd; int fd;
int major; int type;
}; };
static LIST_HEAD(all_tty_info_entries); static LIST_HEAD(all_tty_info_entries);
...@@ -156,9 +156,9 @@ int prepare_shared_tty(void) ...@@ -156,9 +156,9 @@ int prepare_shared_tty(void)
ASSIGN_MEMBER((d),(s), c_line); \ ASSIGN_MEMBER((d),(s), c_line); \
} while (0) } while (0)
static int tty_gen_id(int major, int index) static int tty_gen_id(int type, int index)
{ {
return (index << 1) + (major == TTYAUX_MAJOR); return (index << 1) + (type == TTY_TYPE_PTM);
} }
static int tty_get_index(u32 id) static int tty_get_index(u32 id)
...@@ -199,19 +199,19 @@ int tty_verify_active_pairs(void) ...@@ -199,19 +199,19 @@ int tty_verify_active_pairs(void)
return 0; return 0;
} }
static int parse_pty_index(u32 id, int lfd, int major) static int parse_pty_index(u32 id, int lfd, int type)
{ {
int index = -1; int index = -1;
switch (major) { switch (type) {
case TTYAUX_MAJOR: case TTY_TYPE_PTM:
if (ioctl(lfd, TIOCGPTN, &index)) { if (ioctl(lfd, TIOCGPTN, &index)) {
pr_perror("Can't obtain ptmx index"); pr_perror("Can't obtain ptmx index");
return -1; return -1;
} }
break; break;
case UNIX98_PTY_SLAVE_MAJOR: { case TTY_TYPE_PTS: {
char path[PATH_MAX]; char path[PATH_MAX];
char link[32]; char link[32];
int len; int len;
...@@ -378,26 +378,20 @@ static int tty_restore_ctl_terminal(struct file_desc *d, int fd) ...@@ -378,26 +378,20 @@ static int tty_restore_ctl_terminal(struct file_desc *d, int fd)
return ret; return ret;
} }
static char *tty_type(int major) static char *tty_name(int type)
{ {
static char *tty_types[] = { switch (type) {
[UNIX98_PTY_SLAVE_MAJOR] = "pts", case TTY_TYPE_PTM:
[TTYAUX_MAJOR] = "ptmx", return "ptmx";
}; case TTY_TYPE_PTS:
static char tty_unknown[] = "unknown"; return "pts";
switch (major) {
case UNIX98_PTY_SLAVE_MAJOR:
case TTYAUX_MAJOR:
return tty_types[major];
} }
return "unknown";
return tty_unknown;
} }
static bool tty_is_master(struct tty_info *info) static bool tty_is_master(struct tty_info *info)
{ {
return info->major == TTYAUX_MAJOR; return info->type == TTY_TYPE_PTM;
} }
static bool tty_is_hung(struct tty_info *info) static bool tty_is_hung(struct tty_info *info)
...@@ -416,7 +410,7 @@ static bool tty_has_active_pair(struct tty_info *info) ...@@ -416,7 +410,7 @@ static bool tty_has_active_pair(struct tty_info *info)
static void tty_show_pty_info(char *prefix, struct tty_info *info) static void tty_show_pty_info(char *prefix, struct tty_info *info)
{ {
pr_info("%s type %s id %#x index %d (master %d sid %d pgrp %d inherit %d)\n", pr_info("%s type %s id %#x index %d (master %d sid %d pgrp %d inherit %d)\n",
prefix, tty_type(info->major), info->tfe->id, info->tie->pty->index, prefix, tty_name(info->type), info->tfe->id, info->tie->pty->index,
tty_is_master(info), info->tie->sid, info->tie->pgrp, info->inherit); tty_is_master(info), info->tie->sid, info->tie->pgrp, info->inherit);
} }
...@@ -890,6 +884,13 @@ static int verify_termios(u32 id, TermiosEntry *e) ...@@ -890,6 +884,13 @@ static int verify_termios(u32 id, TermiosEntry *e)
static int verify_info(struct tty_info *info) 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, info->tfe->id);
return -1;
}
/* /*
* Master peer must have all parameters present, * Master peer must have all parameters present,
* while slave peer must have either all parameters present * while slave peer must have either all parameters present
...@@ -973,7 +974,7 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg) ...@@ -973,7 +974,7 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg)
} }
INIT_LIST_HEAD(&info->sibling); INIT_LIST_HEAD(&info->sibling);
info->major = major(info->tie->rdev); info->type = tty_type(major(info->tie->rdev), minor(info->tie->rdev));
info->create = tty_is_master(info); info->create = tty_is_master(info);
info->inherit = false; info->inherit = false;
...@@ -1036,7 +1037,7 @@ int dump_verify_tty_sids(void) ...@@ -1036,7 +1037,7 @@ int dump_verify_tty_sids(void)
if (!opts.shell_job) { if (!opts.shell_job) {
pr_err("Found dangling tty with sid %d pgid %d (%s) on peer fd %d.\n", pr_err("Found dangling tty with sid %d pgid %d (%s) on peer fd %d.\n",
dinfo->sid, dinfo->pgrp, dinfo->sid, dinfo->pgrp,
tty_type(dinfo->major), tty_name(dinfo->type),
dinfo->fd); dinfo->fd);
/* /*
* First thing people do with criu is dump smth * First thing people do with criu is dump smth
...@@ -1056,7 +1057,7 @@ int dump_verify_tty_sids(void) ...@@ -1056,7 +1057,7 @@ int dump_verify_tty_sids(void)
return ret; return ret;
} }
static int dump_pty_info(int lfd, u32 id, const struct fd_parms *p, int major, int index) static int dump_pty_info(int lfd, u32 id, const struct fd_parms *p, int type, int index)
{ {
TtyInfoEntry info = TTY_INFO_ENTRY__INIT; TtyInfoEntry info = TTY_INFO_ENTRY__INIT;
TermiosEntry termios = TERMIOS_ENTRY__INIT; TermiosEntry termios = TERMIOS_ENTRY__INIT;
...@@ -1091,7 +1092,7 @@ static int dump_pty_info(int lfd, u32 id, const struct fd_parms *p, int major, i ...@@ -1091,7 +1092,7 @@ static int dump_pty_info(int lfd, u32 id, const struct fd_parms *p, int major, i
dinfo->sid = pti->sid; dinfo->sid = pti->sid;
dinfo->pgrp = pti->pgrp; dinfo->pgrp = pti->pgrp;
dinfo->fd = p->fd; dinfo->fd = p->fd;
dinfo->major = major; dinfo->type = type;
list_add_tail(&dinfo->list, &all_ttys); list_add_tail(&dinfo->list, &all_ttys);
...@@ -1169,17 +1170,17 @@ out: ...@@ -1169,17 +1170,17 @@ out:
static int dump_one_pty(int lfd, u32 id, const struct fd_parms *p) static int dump_one_pty(int lfd, u32 id, const struct fd_parms *p)
{ {
TtyFileEntry e = TTY_FILE_ENTRY__INIT; TtyFileEntry e = TTY_FILE_ENTRY__INIT;
int ret = 0, major, index; int ret = 0, type, index;
pr_info("Dumping tty %d with id %#x\n", lfd, id); pr_info("Dumping tty %d with id %#x\n", lfd, id);
major = major(p->stat.st_rdev); type = tty_type(major(p->stat.st_rdev), minor(p->stat.st_rdev));
index = parse_pty_index(id, lfd, major); index = parse_pty_index(id, lfd, type);
if (index < 0) if (index < 0)
return -1; return -1;
e.id = id; e.id = id;
e.tty_info_id = tty_gen_id(major, index); e.tty_info_id = tty_gen_id(type, index);
e.flags = p->flags; e.flags = p->flags;
e.fown = (FownEntry *)&p->fown; e.fown = (FownEntry *)&p->fown;
...@@ -1204,7 +1205,7 @@ static int dump_one_pty(int lfd, u32 id, const struct fd_parms *p) ...@@ -1204,7 +1205,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)) if (!tty_test_and_set(e.tty_info_id, tty_bitmap))
ret = dump_pty_info(lfd, e.tty_info_id, p, major, index); ret = dump_pty_info(lfd, e.tty_info_id, p, type, index);
if (!ret) if (!ret)
ret = pb_write_one(img_from_set(glob_imgset, CR_FD_TTY_FILES), &e, PB_TTY_FILE); ret = pb_write_one(img_from_set(glob_imgset, CR_FD_TTY_FILES), &e, PB_TTY_FILE);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment