[CRIU] [PATCH] tty: add vt support

Ruslan Kuprieiev kupruser at gmail.com
Thu Dec 4 15:44:22 PST 2014


/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;
 	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;
+	}
 	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;
+
+	switch (info->type) {
+	case TTY_TYPE_CONSOLE:
+		index = CONSOLE_INDEX;
+		break;
+	case TTY_TYPE_VT:
+		index = VT_INDEX;
+		break;
+	default:
+		index = info->tie->pty->index;
+	}
+
 	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);
 
 	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();
 	}
-- 
1.9.3



More information about the CRIU mailing list