public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Peter Hurley <peter@hurleysoftware.com>
To: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: LKML <linux-kernel@vger.kernel.org>, Jiri Slaby <jslaby@suse.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Andrey Vagin <avagin@virtuozzo.com>,
	Pavel Emelianov <xemul@virtuozzo.com>,
	Vladimir Davydov <vdavydov@virtuozzo.com>,
	Konstantin Khorenko <khorenko@virtuozzo.com>
Subject: Re: [RFC] tty: n_tty -- Add new TIOCPEEKRAW ioctl to peek unread data
Date: Wed, 16 Mar 2016 21:05:06 -0700	[thread overview]
Message-ID: <56EA2CF2.8090801@hurleysoftware.com> (raw)
In-Reply-To: <20160312141830.GM1989@uranus.lan>

Hi Cyrill,

On 03/12/2016 06:18 AM, Cyrill Gorcunov wrote:
> Currently when we checkpoint PTY connections we ignore data queued inside
> read buffer of ldisk, such data us barely lost after the restore. So we
> would like to improve the situation and being able to dump and restore
> it as well.
> 
> Here is a new ioctl code which simply copies data from read buffer
> into the userspace without any additional processing (just like
> terminal is sitting in a raw mode).

Maybe I'm overlooking something obvious, but why not do just that;
ie., save the termios, reset termios to raw mode and read the entire
ldisc read buffer?

Note that saving and resetting termios to raw mode is only necessary
for the slave side, as the master side is always in raw mode.

Then, two options for restore are:
1) set termios to raw mode, write to peer, restore the saved termios; or
2) restore the saved termios and write to peer.

option 1 will preserve the contents as read but not preserve the line
termination state; ie., it will be possible to read multiple lines
with a single canonical read.

option 2 will preserve the line termination state (for the most part)
but not necessarily the contents which might be re-interpreted.

These two options are not necessarily exclusive; it may be possible
to construct a mixed mode for restore based on the original saved
termios that reconstitutes both line termination state and read buffer
contents.

One thing not accounted for is the column position.

Regards,
Peter Hurley

> The idea behind is when we checkpointing PTY pair we peek
> this unread data into images on disk and on restore phase
> we find the linked peer and write it back thus reading
> peer will obtain it then.
> 
> I tried several approaches (including simply reuse of
> canon_copy_from_read_buf and copy_from_read_buf) but
> it not always do the trick: for example if data queued
> doesn't have \n symbol the input_available_p helper
> returns false and I shouldn't call for the helpers
> above.
> 
> Another proposal was to try to implement something
> like sys_tee but for tty layer (proposed by xemul@)
> but I drop this idea because it will require a lot
> of rework as far as I can say (including moving
> read buffer outside of the n_tty_data structure
> and such).
> 
> Still this ioctl looks somewhat ugly to me so
> if someone has better idea how to fetch queued
> data from ldisk this would be awesome, please
> share. _Any_ comments are highly appreciated.
> 
> Signed-off-by: Cyrill Gorcunov <gorcunov@virtuozzo.com>
> CC: Jiri Slaby <jslaby@suse.com>
> CC: Peter Hurley <peter@hurleysoftware.com>
> CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> CC: Andrey Vagin <avagin@virtuozzo.com>
> CC: Pavel Emelianov <xemul@virtuozzo.com>
> CC: Vladimir Davydov <vdavydov@virtuozzo.com>
> CC: Konstantin Khorenko <khorenko@virtuozzo.com>
> ---
>  drivers/tty/n_tty.c               |   22 ++++++++++++++++++++++
>  include/uapi/asm-generic/ioctls.h |    1 +
>  2 files changed, 23 insertions(+)
> 
> Index: linux-ml.git/drivers/tty/n_tty.c
> ===================================================================
> --- linux-ml.git.orig/drivers/tty/n_tty.c
> +++ linux-ml.git/drivers/tty/n_tty.c
> @@ -2485,6 +2485,26 @@ static unsigned long inq_canon(struct n_
>  	return nr;
>  }
>  
> +static ssize_t n_tty_peek_raw(struct tty_struct *tty, unsigned char __user *buf)
> +{
> +	struct n_tty_data *ldata = tty->disc_data;
> +	ssize_t retval;
> +
> +	if (!mutex_trylock(&ldata->atomic_read_lock))
> +		return -EAGAIN;
> +
> +	down_read(&tty->termios_rwsem);
> +	retval = read_cnt(ldata);
> +	if (retval) {
> +		const unsigned char *from = read_buf_addr(ldata, ldata->read_tail);
> +		if (copy_to_user(buf, from, retval))
> +			retval = -EFAULT;
> +	}
> +	up_read(&tty->termios_rwsem);
> +	mutex_unlock(&ldata->atomic_read_lock);
> +	return retval;
> +}
> +
>  static int n_tty_ioctl(struct tty_struct *tty, struct file *file,
>  		       unsigned int cmd, unsigned long arg)
>  {
> @@ -2502,6 +2522,8 @@ static int n_tty_ioctl(struct tty_struct
>  			retval = read_cnt(ldata);
>  		up_write(&tty->termios_rwsem);
>  		return put_user(retval, (unsigned int __user *) arg);
> +	case TIOCPEEKRAW:
> +		return n_tty_peek_raw(tty, (unsigned char __user *) arg);
>  	default:
>  		return n_tty_ioctl_helper(tty, file, cmd, arg);
>  	}
> 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
> @@ -77,6 +77,7 @@
>  #define TIOCGPKT	_IOR('T', 0x38, int) /* Get packet mode state */
>  #define TIOCGPTLCK	_IOR('T', 0x39, int) /* Get Pty lock state */
>  #define TIOCGEXCL	_IOR('T', 0x40, int) /* Get exclusive mode state */
> +#define TIOCPEEKRAW	_IOR('T', 0x41, void *)
>  
>  #define FIONCLEX	0x5450
>  #define FIOCLEX		0x5451
> 

  parent reply	other threads:[~2016-03-17  4:05 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-12 14:18 [RFC] tty: n_tty -- Add new TIOCPEEKRAW ioctl to peek unread data Cyrill Gorcunov
2016-03-13 10:14 ` Jiri Slaby
2016-03-13 10:35   ` Cyrill Gorcunov
2016-03-16  9:48     ` [PATCH v2] " Cyrill Gorcunov
2016-03-17  4:05 ` Peter Hurley [this message]
2016-03-17  7:32   ` [RFC] " Cyrill Gorcunov
2016-03-22 11:00     ` 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=56EA2CF2.8090801@hurleysoftware.com \
    --to=peter@hurleysoftware.com \
    --cc=avagin@virtuozzo.com \
    --cc=gorcunov@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jslaby@suse.com \
    --cc=khorenko@virtuozzo.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=vdavydov@virtuozzo.com \
    --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