[CRIU] [PATCH 1/2] tty: Add restoration of locked/exclusive ptys

Cyrill Gorcunov gorcunov at openvz.org
Wed Sep 5 06:50:04 EDT 2012


Since opening locked/exclusive ptys do return
different error code we can figure out what
exactly tty flag the peer has.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 include/tty.h      |    3 ++
 protobuf/tty.proto |    6 ++++
 tty.c              |   76 ++++++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 77 insertions(+), 8 deletions(-)

diff --git a/include/tty.h b/include/tty.h
index 8457270..8a06bad 100644
--- a/include/tty.h
+++ b/include/tty.h
@@ -13,6 +13,9 @@
 #endif
 #define PTS_FMT		"/dev/pts/%d"
 
+#define TTY_LOCKED	(1 << 0)
+#define TTY_EXCLUSIVE	(1 << 1)
+
 extern int dump_tty(struct fd_parms *p, int lfd, const struct cr_fdset *set);
 extern int collect_tty(void);
 extern int tty_is_master(struct fdinfo_list_entry *le);
diff --git a/protobuf/tty.proto b/protobuf/tty.proto
index 8f497dc..38adab2 100644
--- a/protobuf/tty.proto
+++ b/protobuf/tty.proto
@@ -31,6 +31,12 @@ message tty_file_entry {
 	required uint64			pos		=  5;
 	required uint64			rdev		=  6;
 	required fown_entry		fown		=  7;
+
+	/*
+	 * Bits
+	 *  0 - locked
+	 *  1 - exclusive
+	 */
 	required uint32			tty_flags	=  8;
 
 	enum Type {
diff --git a/tty.c b/tty.c
index b4e89bc..8ac61f7 100644
--- a/tty.c
+++ b/tty.c
@@ -81,9 +81,6 @@
  *   restore the master end might be already closed for any reason so
  *   to resolve such problem we open a fake master peer with proper index
  *   and hook a slave on it, then we close master peer.
- *
- * - Find a way to fetch tty flags from the kernel (locked/exclusive)
- *   and save it in tty_flags.
  */
 
 #undef	LOG_PREFIX
@@ -259,11 +256,6 @@ static int pty_open_ptmx_index(int flags, int index)
 	return ret;
 }
 
-/*
- * FIXME Need to find a way to figure out if master
- * is in locked state when being dumped. If so, need
- * to re-lock it on restore.
- */
 static int unlock_pty_master(int master)
 {
 	const int lock = 0;
@@ -281,6 +273,58 @@ static int unlock_pty_master(int master)
 	return 0;
 }
 
+static int lock_pty_master(int master)
+{
+	const int lock = 1;
+
+	if (ioctl(master, TIOCSPTLCK, &lock)) {
+		pr_err("Unable to lock pty master device %d\n", master);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int set_exclusive_pty_master(int master)
+{
+	if (ioctl(master, TIOCEXCL)) {
+		pr_err("Unable to make pty master exclusive %d\n", master);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int get_pty_flags(int index, unsigned int *flags)
+{
+	char pts_name[64];
+	int ret = 0, fd;
+
+	*flags = 0;
+
+	snprintf(pts_name, sizeof(pts_name), PTS_FMT, index);
+
+	fd = open(pts_name, O_RDONLY);
+	if (fd < 0) {
+		switch (errno) {
+		case EIO:
+			*flags |= TTY_LOCKED;
+			break;
+		case EBUSY:
+			*flags |= TTY_EXCLUSIVE;
+			break;
+		default:
+			pr_perror("Can't open %s to obtain flags",
+				  pts_name);
+			ret = -1;
+			break;
+		}
+	} else
+		close(fd);
+
+	return ret;
+}
+
 static int tty_get_sid(int fd)
 {
 	int sid, ret;
@@ -498,6 +542,11 @@ static int pty_open_ptmx(struct tty_file_info *info)
 	if (pty_open_slaves(info))
 		goto err;
 
+	if (info->tfe->tty_flags & TTY_LOCKED)
+		lock_pty_master(master);
+	else if (info->tfe->tty_flags & TTY_EXCLUSIVE)
+		set_exclusive_pty_master(master);
+
 	return master;
 err:
 	close_safe(&master);
@@ -676,6 +725,7 @@ static int dump_control_pty(int index, pid_t sid, pid_t prgp)
 	pr_info("Dump control terminal for %d\n", sid);
 
 	snprintf(path, sizeof(path), "/dev/pts/%d", index);
+
 	fd = open(path, O_RDONLY);
 	if (fd < 0) {
 		pr_err("Can't open terminal %s\n", path);
@@ -760,9 +810,19 @@ static int __dump_one_pty(int lfd, u32 id, const struct fd_parms *p, pid_t sid,
 		if (sid < 0 || prgp < 0)
 			return -1;
 
+		/*
+		 * Also figure out the flags master pty has.
+		 */
+		if (get_pty_flags(pty.index, &e.tty_flags))
+			return -1;
+
 		if (sid) {
+			if (e.tty_flags & TTY_LOCKED)
+				unlock_pty_master(lfd);
 			if (dump_control_pty(pty.index, sid, prgp))
 				return -1;
+			if (e.tty_flags & TTY_LOCKED)
+				lock_pty_master(lfd);
 		}
 	}
 
-- 
1.7.7.6



More information about the CRIU mailing list