Commit 1ace2570 authored by Ruslan Kuprieiev's avatar Ruslan Kuprieiev Committed by Pavel Emelyanov

tty: add vt support, v2

/dev/ttyN are the virtual terminals which are provided
by the system with major 4 and minor 1..63.
You can run some program on ttyN by pressing alt+ctrl+FN
and running it manualy or by using open(openvt nowadays).

This patch also allows us to run all our tests from a vt.

v2, style fix + using linux/vt.h for constants
Signed-off-by: 's avatarRuslan Kuprieiev <kupruser@gmail.com>
Reviewed-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent dfeccadd
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define __CR_TTY_H__ #define __CR_TTY_H__
#include <linux/major.h> #include <linux/major.h>
#include <linux/vt.h>
#include "files.h" #include "files.h"
...@@ -13,6 +14,7 @@ enum { ...@@ -13,6 +14,7 @@ enum {
TTY_TYPE_PTM = 1, TTY_TYPE_PTM = 1,
TTY_TYPE_PTS = 2, TTY_TYPE_PTS = 2,
TTY_TYPE_CONSOLE = 3, TTY_TYPE_CONSOLE = 3,
TTY_TYPE_VT = 4,
TTY_TYPE_MAX TTY_TYPE_MAX
}; };
...@@ -34,6 +36,14 @@ static inline int tty_type(int major, int minor) ...@@ -34,6 +36,14 @@ static inline int tty_type(int major, int minor)
else if (minor == 1) else if (minor == 1)
return TTY_TYPE_CONSOLE; return TTY_TYPE_CONSOLE;
break; break;
case TTY_MAJOR:
if (minor > MIN_NR_CONSOLES && minor < MAX_NR_CONSOLES)
/*
* Minors [MIN_NR_CONSOLES; MAX_NR_CONSOLES] stand
* for consoles (virtual terminals, VT in terms
* of kernel).
*/
return TTY_TYPE_VT;
case UNIX98_PTY_MASTER_MAJOR ... (UNIX98_PTY_MASTER_MAJOR + UNIX98_PTY_MAJOR_COUNT - 1): case UNIX98_PTY_MASTER_MAJOR ... (UNIX98_PTY_MASTER_MAJOR + UNIX98_PTY_MAJOR_COUNT - 1):
return TTY_TYPE_PTM; return TTY_TYPE_PTM;
case UNIX98_PTY_SLAVE_MAJOR: case UNIX98_PTY_SLAVE_MAJOR:
......
...@@ -27,6 +27,7 @@ enum TtyType { ...@@ -27,6 +27,7 @@ enum TtyType {
UNKNOWN = 0; UNKNOWN = 0;
PTY = 1; PTY = 1;
CONSOLE = 2; CONSOLE = 2;
VT = 3;
} }
message tty_info_entry { message tty_info_entry {
......
...@@ -118,6 +118,7 @@ static LIST_HEAD(all_ttys); ...@@ -118,6 +118,7 @@ static LIST_HEAD(all_ttys);
#define MAX_TTYS 1024 #define MAX_TTYS 1024
#define MAX_PTY_INDEX 1000 #define MAX_PTY_INDEX 1000
#define CONSOLE_INDEX 1002 #define CONSOLE_INDEX 1002
#define VT_INDEX 1004
static DECLARE_BITMAP(tty_bitmap, (MAX_TTYS << 1)); static DECLARE_BITMAP(tty_bitmap, (MAX_TTYS << 1));
static DECLARE_BITMAP(tty_active_pairs, (MAX_TTYS << 1)); static DECLARE_BITMAP(tty_active_pairs, (MAX_TTYS << 1));
...@@ -235,11 +236,16 @@ static int parse_tty_index(u32 id, int lfd, const struct fd_parms *p, int type) ...@@ -235,11 +236,16 @@ static int parse_tty_index(u32 id, int lfd, const struct fd_parms *p, int type)
case TTY_TYPE_CONSOLE: case TTY_TYPE_CONSOLE:
index = CONSOLE_INDEX; index = CONSOLE_INDEX;
break; break;
case TTY_TYPE_VT:
index = VT_INDEX;
break;
default: default:
BUG(); BUG();
} }
if (type != TTY_TYPE_CONSOLE && if (type != TTY_TYPE_CONSOLE &&
type != TTY_TYPE_VT &&
index > MAX_PTY_INDEX) { index > MAX_PTY_INDEX) {
pr_err("Index %d on tty %x is too big\n", index, id); pr_err("Index %d on tty %x is too big\n", index, id);
return -1; return -1;
...@@ -508,6 +514,13 @@ static int tty_restore_ctl_terminal(struct file_desc *d, int fd) ...@@ -508,6 +514,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)); pr_perror("Can't open %s", path_from_reg(info->reg_d));
goto err; 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 } else
BUG(); BUG();
...@@ -534,13 +547,21 @@ static char *tty_name(int type) ...@@ -534,13 +547,21 @@ static char *tty_name(int type)
return "pts"; return "pts";
case TTY_TYPE_CONSOLE: case TTY_TYPE_CONSOLE:
return "console"; return "console";
case TTY_TYPE_VT:
return "tty";
} }
return "unknown"; return "unknown";
} }
static bool tty_is_master(struct tty_info *info) 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) static bool tty_is_hung(struct tty_info *info)
...@@ -558,9 +579,23 @@ static bool tty_has_active_pair(struct tty_info *info) ...@@ -558,9 +579,23 @@ 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)
{ {
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;
}
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_name(info->type), info->tfe->id, prefix, tty_name(info->type), info->tfe->id, index,
info->type == TTY_TYPE_CONSOLE ? CONSOLE_INDEX : 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);
} }
...@@ -788,13 +823,14 @@ err: ...@@ -788,13 +823,14 @@ err:
return -1; return -1;
} }
static int open_console(struct tty_info *info) static int open_simple_tty(struct tty_info *info)
{ {
int fd = -1; int fd = -1;
fd = open_pty_reg(info->reg_d, info->tfe->flags); fd = open_pty_reg(info->reg_d, info->tfe->flags);
if (fd < 0) { if (fd < 0) {
pr_perror("Can't open console %x", pr_perror("Can't open %s %x",
info->type == TTY_TYPE_CONSOLE ? "console" : "virtual terminal",
info->tfe->id); info->tfe->id);
return -1; return -1;
} }
...@@ -820,8 +856,8 @@ static int tty_open(struct file_desc *d) ...@@ -820,8 +856,8 @@ static int tty_open(struct file_desc *d)
if (!tty_is_master(info)) if (!tty_is_master(info))
return pty_open_unpaired_slave(d, info); return pty_open_unpaired_slave(d, info);
if (info->type == TTY_TYPE_CONSOLE) if (info->type == TTY_TYPE_CONSOLE || info->type == TTY_TYPE_VT)
return open_console(info); return open_simple_tty(info);
return pty_open_ptmx(info); return pty_open_ptmx(info);
} }
...@@ -1002,12 +1038,12 @@ int tty_setup_slavery(void) ...@@ -1002,12 +1038,12 @@ int tty_setup_slavery(void)
list_for_each_entry(info, &all_ttys, list) { list_for_each_entry(info, &all_ttys, list) {
if (tty_find_restoring_task(info)) if (tty_find_restoring_task(info))
return -1; return -1;
if (info->type == TTY_TYPE_CONSOLE) if (info->type == TTY_TYPE_CONSOLE || info->type == TTY_TYPE_VT)
continue; continue;
peer = info; peer = info;
list_for_each_entry_safe_continue(peer, m, &all_ttys, list) { 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; continue;
if (peer->tie->pty->index != info->tie->pty->index) if (peer->tie->pty->index != info->tie->pty->index)
continue; continue;
...@@ -1057,7 +1093,8 @@ static int verify_info(struct tty_info *info) ...@@ -1057,7 +1093,8 @@ static int verify_info(struct tty_info *info)
{ {
if (info->type != TTY_TYPE_PTM && if (info->type != TTY_TYPE_PTM &&
info->type != TTY_TYPE_PTS && 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", pr_err("Unknown type %d master peer %x\n",
info->type, info->tfe->id); info->type, info->tfe->id);
return -1; return -1;
...@@ -1115,6 +1152,7 @@ static int collect_one_tty_info_entry(void *obj, ProtobufCMessage *msg) ...@@ -1115,6 +1152,7 @@ static int collect_one_tty_info_entry(void *obj, ProtobufCMessage *msg)
} }
break; break;
case TTY_TYPE__CONSOLE: case TTY_TYPE__CONSOLE:
case TTY_TYPE__VT:
if (info->tie->pty) { if (info->tie->pty) {
pr_err("PTY data found (id %x), corrupted image?\n", pr_err("PTY data found (id %x), corrupted image?\n",
info->tie->id); info->tie->id);
...@@ -1312,6 +1350,9 @@ static int dump_tty_info(int lfd, u32 id, const struct fd_parms *p, int type, in ...@@ -1312,6 +1350,9 @@ static int dump_tty_info(int lfd, u32 id, const struct fd_parms *p, int type, in
case TTY_TYPE_CONSOLE: case TTY_TYPE_CONSOLE:
info.type = TTY_TYPE__CONSOLE; info.type = TTY_TYPE__CONSOLE;
break; break;
case TTY_TYPE_VT:
info.type = TTY_TYPE__VT;
break;
default: default:
BUG(); BUG();
} }
......
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