mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Cyrill Gorcunov <gorcunov@gmail.com>
To: LKML <linux-kernel@vger.kernel.org>
Cc: Andrey Vagin <avagin@openvz.org>,
	Pavel Emelyanov <xemul@virtuozzo.com>,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Jiri Slaby <jslaby@suse.com>, "H. Peter Anvin" <hpa@zytor.com>,
	Andrew Morton <akpm@linuxfoundation.org>
Subject: [RFC] tty: pty -- Add ability to setup next pty number for ptmx open
Date: Fri, 17 Mar 2017 13:56:54 +0300	[thread overview]
Message-ID: <20170317105653.GB29364@uranus.lan> (raw)

When we restore PTY terminals we do iterate over open() calls to reach
the index used at checkpoint time (say application opened a number of
terminals, then closed all other except last one) which of course very
inconvenient.

The problem get more notable in scope of controlling terminal represented
by /dev/tty device: current CRIU restore scheme is lazy, we don't open
files immedeately after the forks but rather defer until the whole
process tree is created, then every process opens own files in async
way and in result /dev/tty is not propagated into children because
it is not yet opened.

Both problems can be solved via criu itself but will require very
much efforts. So I would be very happy if we can open desired PTY
peer with index needed in one call instead. Which would allow us:

 - open a sole control terminal right after the fork and
   propagate it automatically into children

 - drop out our open(/dev/ptmx) sequence to reach index needed,
   improving performance and shrinking code

The API in the patch is trivial -- one have to open(/dev/ptmx)
and automatically get index 0, then simply do
ioctl(fd, TIOCSPTN, index) and next open(/dev/ptmx)
will return pair with point number requested.

CC: Andrey Vagin <avagin@openvz.org>
CC: Pavel Emelyanov <xemul@virtuozzo.com>
CC: "Eric W. Biederman" <ebiederm@xmission.com>
CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
CC: Jiri Slaby <jslaby@suse.com>
CC: "H. Peter Anvin" <hpa@zytor.com>
CC: Andrew Morton <akpm@linuxfoundation.org>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
---
 drivers/tty/pty.c                 |   14 ++++++++++++++
 fs/devpts/inode.c                 |   22 ++++++++++++++++++++--
 include/linux/devpts_fs.h         |    1 +
 include/uapi/asm-generic/ioctls.h |    1 +
 4 files changed, 36 insertions(+), 2 deletions(-)

Index: linux-ml.git/drivers/tty/pty.c
===================================================================
--- linux-ml.git.orig/drivers/tty/pty.c
+++ linux-ml.git/drivers/tty/pty.c
@@ -593,6 +593,18 @@ static inline void legacy_pty_init(void)
 
 static struct cdev ptmx_cdev;
 
+static int pty_set_next_ptn(struct tty_struct *tty, int next_ptn)
+{
+	if (tty->driver->subtype == PTY_TYPE_MASTER) {
+		struct pts_fs_info *fsi;
+
+		fsi = tty->driver_data;
+		return devpts_set_next_index(fsi, next_ptn);
+	}
+
+	return -ENOIOCTLCMD;
+}
+
 static int pty_unix98_ioctl(struct tty_struct *tty,
 			    unsigned int cmd, unsigned long arg)
 {
@@ -607,6 +619,8 @@ static int pty_unix98_ioctl(struct tty_s
 		return pty_get_pktmode(tty, (int __user *)arg);
 	case TIOCGPTN: /* Get PT Number */
 		return put_user(tty->index, (unsigned int __user *)arg);
+	case TIOCSPTN:
+		return pty_set_next_ptn(tty, (unsigned int)arg);
 	case TIOCSIG:    /* Send signal to other side of pty */
 		return pty_signal(tty, (int) arg);
 	}
Index: linux-ml.git/fs/devpts/inode.c
===================================================================
--- linux-ml.git.orig/fs/devpts/inode.c
+++ linux-ml.git/fs/devpts/inode.c
@@ -126,6 +126,7 @@ struct pts_fs_info {
 	struct pts_mount_opts mount_opts;
 	struct super_block *sb;
 	struct dentry *ptmx_dentry;
+	int pty_next_idx;
 };
 
 static inline struct pts_fs_info *DEVPTS_SB(struct super_block *sb)
@@ -486,7 +487,8 @@ retry:
 		return -ENOSPC;
 	}
 
-	ida_ret = ida_get_new(&fsi->allocated_ptys, &index);
+	ida_ret = ida_get_new_above(&fsi->allocated_ptys,
+				    fsi->pty_next_idx, &index);
 	if (ida_ret < 0) {
 		mutex_unlock(&allocated_ptys_lock);
 		if (ida_ret == -EAGAIN)
@@ -494,7 +496,9 @@ retry:
 		return -EIO;
 	}
 
-	if (index >= fsi->mount_opts.max) {
+	if (index >= fsi->mount_opts.max ||
+	    (fsi->pty_next_idx &&
+	     fsi->pty_next_idx != index)) {
 		ida_remove(&fsi->allocated_ptys, index);
 		mutex_unlock(&allocated_ptys_lock);
 		return -ENOSPC;
@@ -512,6 +516,20 @@ void devpts_kill_index(struct pts_fs_inf
 	mutex_unlock(&allocated_ptys_lock);
 }
 
+int devpts_set_next_index(struct pts_fs_info *fsi, int next_idx)
+{
+	int ret = 0;
+
+	mutex_lock(&allocated_ptys_lock);
+	if (fsi->mount_opts.max > next_idx && next_idx >= 0)
+		fsi->pty_next_idx = next_idx;
+	else
+		ret = -ENOSPC;
+	mutex_unlock(&allocated_ptys_lock);
+
+	return ret;
+}
+
 /**
  * devpts_pty_new -- create a new inode in /dev/pts/
  * @ptmx_inode: inode of the master
Index: linux-ml.git/include/linux/devpts_fs.h
===================================================================
--- linux-ml.git.orig/include/linux/devpts_fs.h
+++ linux-ml.git/include/linux/devpts_fs.h
@@ -24,6 +24,7 @@ void devpts_release(struct pts_fs_info *
 
 int devpts_new_index(struct pts_fs_info *);
 void devpts_kill_index(struct pts_fs_info *, int);
+int devpts_set_next_index(struct pts_fs_info *, int);
 
 /* mknod in devpts */
 struct dentry *devpts_pty_new(struct pts_fs_info *, int, void *);
Index: linux-ml.git/include/uapi/asm-generic/ioctls.h
===================================================================
--- linux-ml.git.orig/include/uapi/asm-generic/ioctls.h
+++ linux-ml.git/include/uapi/asm-generic/ioctls.h
@@ -68,6 +68,7 @@
 #define TIOCGPTN	_IOR('T', 0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
 #define TIOCSPTLCK	_IOW('T', 0x31, int)  /* Lock/unlock Pty */
 #define TIOCGDEV	_IOR('T', 0x32, unsigned int) /* Get primary device node of /dev/console */
+#define TIOCSPTN	_IOW('T', 0x33, unsigned int) /* Set next Pty Number (of pty-mux device) */
 #define TCGETX		0x5432 /* SYS5 TCGETX compatibility */
 #define TCSETX		0x5433
 #define TCSETXF		0x5434

             reply	other threads:[~2017-03-17 10:56 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-17 10:56 Cyrill Gorcunov [this message]
2017-04-27  9:20 ` Cyrill Gorcunov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170317105653.GB29364@uranus.lan \
    --to=gorcunov@gmail.com \
    --cc=akpm@linuxfoundation.org \
    --cc=avagin@openvz.org \
    --cc=ebiederm@xmission.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=hpa@zytor.com \
    --cc=jslaby@suse.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=xemul@virtuozzo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®