qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
@ 2008-07-18 13:24 Ian Jackson
  2008-07-23  1:26 ` Anthony Liguori
  0 siblings, 1 reply; 44+ messages in thread
From: Ian Jackson @ 2008-07-18 13:24 UTC (permalink / raw)
  To: qemu-devel

The rest of qemu assumes that IO operations on a CharDriverState do
not block.  Currently there are a couple of cases where such a driver
was set up but the calls to set nonblocking mode were missing:
 * qemu_chr_open_pty
 * qemu_chr_open_pipe
 * qemu_chr_open_stdio

This is fixed by adding two calls to socket_set_nonblock to
qemu_chr_open_fd.

Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 vl.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/vl.c b/vl.c
index 4f31288..c428c7e 100644
--- a/vl.c
+++ b/vl.c
@@ -2090,6 +2090,9 @@ static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
     CharDriverState *chr;
     FDCharDriver *s;
 
+    socket_set_nonblock(fd_in);
+    socket_set_nonblock(fd_out);
+
     chr = qemu_mallocz(sizeof(CharDriverState));
     if (!chr)
         return NULL;
-- 
1.4.4.4

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-18 13:24 [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd Ian Jackson
@ 2008-07-23  1:26 ` Anthony Liguori
  2008-07-23  8:24   ` Daniel P. Berrange
  2008-07-23  9:34   ` [Qemu-devel] " Kevin Wolf
  0 siblings, 2 replies; 44+ messages in thread
From: Anthony Liguori @ 2008-07-23  1:26 UTC (permalink / raw)
  To: qemu-devel

Hi,

Ian Jackson wrote:
> The rest of qemu assumes that IO operations on a CharDriverState do
> not block.  Currently there are a couple of cases where such a driver
> was set up but the calls to set nonblocking mode were missing:
>  * qemu_chr_open_pty
>  * qemu_chr_open_pipe
>  * qemu_chr_open_stdio
>
> This is fixed by adding two calls to socket_set_nonblock to
> qemu_chr_open_fd.
>   

This changes semantics a bit.  Previously, using a pty would guarantee 
that data is always written as qemu_chr_write does not perform any sort 
of buffering.

Now, that data will be silently dropped instead of causing QEMU to 
block.  I don't think it's perfectly clear that one behaviour is clearly 
better than the other.

Regards,

Anthony Liguori

> Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
> ---
>  vl.c |    3 +++
>  1 files changed, 3 insertions(+), 0 deletions(-)
>
> diff --git a/vl.c b/vl.c
> index 4f31288..c428c7e 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -2090,6 +2090,9 @@ static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
>      CharDriverState *chr;
>      FDCharDriver *s;
>  
> +    socket_set_nonblock(fd_in);
> +    socket_set_nonblock(fd_out);
> +
>      chr = qemu_mallocz(sizeof(CharDriverState));
>      if (!chr)
>          return NULL;
>   

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23  1:26 ` Anthony Liguori
@ 2008-07-23  8:24   ` Daniel P. Berrange
  2008-07-23 11:48     ` Gerd Hoffmann
  2008-07-23  9:34   ` [Qemu-devel] " Kevin Wolf
  1 sibling, 1 reply; 44+ messages in thread
From: Daniel P. Berrange @ 2008-07-23  8:24 UTC (permalink / raw)
  To: qemu-devel

On Tue, Jul 22, 2008 at 08:26:59PM -0500, Anthony Liguori wrote:
> Hi,
> 
> Ian Jackson wrote:
> >The rest of qemu assumes that IO operations on a CharDriverState do
> >not block.  Currently there are a couple of cases where such a driver
> >was set up but the calls to set nonblocking mode were missing:
> > * qemu_chr_open_pty
> > * qemu_chr_open_pipe
> > * qemu_chr_open_stdio
> >
> >This is fixed by adding two calls to socket_set_nonblock to
> >qemu_chr_open_fd.
> >  
> 
> This changes semantics a bit.  Previously, using a pty would guarantee 
> that data is always written as qemu_chr_write does not perform any sort 
> of buffering.
> 
> Now, that data will be silently dropped instead of causing QEMU to 
> block.  I don't think it's perfectly clear that one behaviour is clearly 
> better than the other.

In the case of the PTY backend, the only time I'd expect data to be dropped
is if there was no active slave open. If an application has the PTY open
and is interacting, then I'd want to get all data.  

My use case is that all VMs started will have a serial port configured
with '-serial pty'. The guest OS should not be blocked when writing to
the serial port if no one has the PTY open on the host, but if someone
attaches to it with 'virsh console' then I want to be guartenteed to 
get all data.

Daniel.
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23  1:26 ` Anthony Liguori
  2008-07-23  8:24   ` Daniel P. Berrange
@ 2008-07-23  9:34   ` Kevin Wolf
  2008-07-23 10:17     ` Ian Jackson
  2008-07-23 12:04     ` Gerd Hoffmann
  1 sibling, 2 replies; 44+ messages in thread
From: Kevin Wolf @ 2008-07-23  9:34 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 633 bytes --]

Anthony Liguori schrieb:
> This changes semantics a bit.  Previously, using a pty would guarantee
> that data is always written as qemu_chr_write does not perform any sort
> of buffering.
> 
> Now, that data will be silently dropped instead of causing QEMU to
> block.  I don't think it's perfectly clear that one behaviour is clearly
> better than the other.

Then we need both.

Add an option to specify non-blocking mode for stdio, pty and pipe in
qemu_chr_open.  Blocking mode is used by default (maintaining current
semantics), non-blocking mode if the name is prefixed with nonblock:

Signed-off-by: Kevin Wolf <kwolf@suse.de>

[-- Attachment #2: nonblock.patch --]
[-- Type: text/x-patch, Size: 3980 bytes --]

Index: vl.c
===================================================================
--- vl.c.orig
+++ vl.c
@@ -2227,11 +2227,16 @@ static void fd_chr_close(struct CharDriv
 }
 
 /* open a character device to a unix fd */
-static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
+static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out, int block)
 {
     CharDriverState *chr;
     FDCharDriver *s;
 
+    if (!block) {
+        socket_set_nonblock(fd_in);
+        socket_set_nonblock(fd_out);
+    }
+
     chr = qemu_mallocz(sizeof(CharDriverState));
     if (!chr)
         return NULL;
@@ -2259,10 +2264,10 @@ static CharDriverState *qemu_chr_open_fi
     TFR(fd_out = open(file_out, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));
     if (fd_out < 0)
         return NULL;
-    return qemu_chr_open_fd(-1, fd_out);
+    return qemu_chr_open_fd(-1, fd_out, 0);
 }
 
-static CharDriverState *qemu_chr_open_pipe(const char *filename)
+static CharDriverState *qemu_chr_open_pipe(const char *filename, int block)
 {
     int fd_in, fd_out;
     char filename_in[256], filename_out[256];
@@ -2280,7 +2285,7 @@ static CharDriverState *qemu_chr_open_pi
         if (fd_in < 0)
             return NULL;
     }
-    return qemu_chr_open_fd(fd_in, fd_out);
+    return qemu_chr_open_fd(fd_in, fd_out, block);
 }
 
 
@@ -2376,13 +2381,13 @@ static void qemu_chr_close_stdio(struct
     fd_chr_close(chr);
 }
 
-static CharDriverState *qemu_chr_open_stdio(void)
+static CharDriverState *qemu_chr_open_stdio(int block)
 {
     CharDriverState *chr;
 
     if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
         return NULL;
-    chr = qemu_chr_open_fd(0, 1);
+    chr = qemu_chr_open_fd(0, 1, block);
     chr->chr_close = qemu_chr_close_stdio;
     qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, chr);
     stdio_nb_clients++;
@@ -2449,7 +2454,7 @@ void cfmakeraw (struct termios *termios_
 #endif
 
 #if defined(__linux__) || defined(__sun__)
-static CharDriverState *qemu_chr_open_pty(void)
+static CharDriverState *qemu_chr_open_pty(int block)
 {
     struct termios tty;
     int master_fd, slave_fd;
@@ -2463,7 +2468,7 @@ static CharDriverState *qemu_chr_open_pt
     tcsetattr(slave_fd, TCSAFLUSH, &tty);
 
     fprintf(stderr, "char device redirected to %s\n", ptsname(master_fd));
-    return qemu_chr_open_fd(master_fd, master_fd);
+    return qemu_chr_open_fd(master_fd, master_fd, block);
 }
 
 static void tty_serial_init(int fd, int speed,
@@ -2578,7 +2583,7 @@ static CharDriverState *qemu_chr_open_tt
 
     TFR(fd = open(filename, O_RDWR | O_NONBLOCK));
     tty_serial_init(fd, 115200, 'N', 8, 1);
-    chr = qemu_chr_open_fd(fd, fd);
+    chr = qemu_chr_open_fd(fd, fd, 0);
     if (!chr) {
         close(fd);
         return NULL;
@@ -2588,7 +2593,7 @@ static CharDriverState *qemu_chr_open_tt
     return chr;
 }
 #else  /* ! __linux__ && ! __sun__ */
-static CharDriverState *qemu_chr_open_pty(void)
+static CharDriverState *qemu_chr_open_pty(int block)
 {
     return NULL;
 }
@@ -3582,6 +3587,10 @@ static CharDriverState *qemu_chr_open_tc
 CharDriverState *qemu_chr_open(const char *filename)
 {
     const char *p;
+    int block = 1;
+
+    if (strstart(filename, "nonblock:", &filename))
+        block = 0;
 
     if (!strcmp(filename, "vc")) {
         return text_console_init(&display_state, 0);
@@ -3615,11 +3624,11 @@ CharDriverState *qemu_chr_open(const cha
     } else if (strstart(filename, "file:", &p)) {
         return qemu_chr_open_file_out(p);
     } else if (strstart(filename, "pipe:", &p)) {
-        return qemu_chr_open_pipe(p);
+        return qemu_chr_open_pipe(p, block);
     } else if (!strcmp(filename, "pty")) {
-        return qemu_chr_open_pty();
+        return qemu_chr_open_pty(block);
     } else if (!strcmp(filename, "stdio")) {
-        return qemu_chr_open_stdio();
+        return qemu_chr_open_stdio(block);
     } else
 #if defined(__linux__)
     if (strstart(filename, "/dev/parport", NULL)) {

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23  9:34   ` [Qemu-devel] " Kevin Wolf
@ 2008-07-23 10:17     ` Ian Jackson
  2008-07-23 11:43       ` Kevin Wolf
  2008-07-23 12:04     ` Gerd Hoffmann
  1 sibling, 1 reply; 44+ messages in thread
From: Ian Jackson @ 2008-07-23 10:17 UTC (permalink / raw)
  To: qemu-devel

Anthony Liguori writes ("Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd."):
> This changes semantics a bit.  Previously, using a pty would guarantee 
> that data is always written as qemu_chr_write does not perform any sort 
> of buffering.

That depends on what the caller (that is, the internal device model
which is using the char driver) does.

In the case of the serial driver in our tree, the emulated serial port
does not empty its simulated transmit shift register until the data
has been accepted by the char driver - ie, actually delivered to
whereever it is going.

That is, the flow control is communicated back to the guest - perhaps
not in the most optimal way, since perhaps it would be better to
simulate modem flow control lines rather than playing games with
making virtual time run slowly.  But no data will be lost unless the
guest chooses to throw it away - and the guest can get on with the
rest of its life in the meantime.

I'm afraid that this change (which is part of a general improvement to
the flow control handling in hw/serial.c) hasn't made it upstream yet.

But regardless, I think having the whole qemu process block while
writing to a `slow' device like a pty (or a network connection for
that matter) is generally wrong.

I haven't searched for other callers, but if they don't offer a way to
prevent the guest from attempting to write too much then I think that
is a bug in that driver.

Kevin Wolf writes ("Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for	qemu_chr_open_fd."):
> +    if (strstart(filename, "nonblock:", &filename))
> +        block = 0;

This is definitely wrong, because the need for (non)blocking behaviour
is determined statically by the code which is using the driver.

Perhaps there should be two writing interfaces, qemu_chr_write and
qemu_chr_write_(non)block.

qemu_chr_write_block_fd would have to contain a select() or poll()
loop since the fd needs to be in nonblocking mode for the reads to
work correctly without races.

Ian.

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 10:17     ` Ian Jackson
@ 2008-07-23 11:43       ` Kevin Wolf
  0 siblings, 0 replies; 44+ messages in thread
From: Kevin Wolf @ 2008-07-23 11:43 UTC (permalink / raw)
  To: qemu-devel

Ian Jackson schrieb:
> Kevin Wolf writes ("Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for	qemu_chr_open_fd."):
>> +    if (strstart(filename, "nonblock:", &filename))
>> +        block = 0;
> 
> This is definitely wrong, because the need for (non)blocking behaviour
> is determined statically by the code which is using the driver.

It is better than what we have today because I can set non-blocking mode
if I don't want to open the pty immediately and I can set blocking mode
whenever I don't want to lose data and I'm sure to attach to the pty.
This is a decision which your code cannot make statically but one which
is influenced by which behaviour the user wants to have.

Of course, you can always say "we can do even better". But as long as
you don't provide code for non-blocking mode where all data is
guaranteed to be delivered (and still works with a limited buffer...),
it is reasonable to let the user decide.

> Perhaps there should be two writing interfaces, qemu_chr_write and
> qemu_chr_write_(non)block.

And which one will be used if you don't want the user to decide?

Kevin

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23  8:24   ` Daniel P. Berrange
@ 2008-07-23 11:48     ` Gerd Hoffmann
  2008-07-23 12:15       ` Daniel P. Berrange
  0 siblings, 1 reply; 44+ messages in thread
From: Gerd Hoffmann @ 2008-07-23 11:48 UTC (permalink / raw)
  To: Daniel P. Berrange, qemu-devel

Daniel P. Berrange wrote:

> In the case of the PTY backend, the only time I'd expect data to be dropped
> is if there was no active slave open. If an application has the PTY open
> and is interacting, then I'd want to get all data.  

Yep, that would be most useful (and also matches what is done for tcp
for example).  Now the interesting question is:  How can qemu figure (in
a portable way) whenever there is some process listening on the slave side?

> My use case is that all VMs started will have a serial port configured
> with '-serial pty'. The guest OS should not be blocked when writing to
> the serial port if no one has the PTY open on the host, but if someone
> attaches to it with 'virsh console' then I want to be guartenteed to 
> get all data.

/me too.

cheers,
  Gerd

-- 
http://kraxel.fedorapeople.org/xenner/

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23  9:34   ` [Qemu-devel] " Kevin Wolf
  2008-07-23 10:17     ` Ian Jackson
@ 2008-07-23 12:04     ` Gerd Hoffmann
  2008-07-23 12:18       ` Paul Brook
  1 sibling, 1 reply; 44+ messages in thread
From: Gerd Hoffmann @ 2008-07-23 12:04 UTC (permalink / raw)
  To: qemu-devel

Kevin Wolf wrote:
> Anthony Liguori schrieb:
>> This changes semantics a bit.  Previously, using a pty would guarantee
>> that data is always written as qemu_chr_write does not perform any sort
>> of buffering.
>>
>> Now, that data will be silently dropped instead of causing QEMU to
>> block.  I don't think it's perfectly clear that one behaviour is clearly
>> better than the other.
> 
> Then we need both.
> 
> Add an option to specify non-blocking mode for stdio, pty and pipe in
> qemu_chr_open.  Blocking mode is used by default (maintaining current
> semantics), non-blocking mode if the name is prefixed with nonblock:

Doing that as config option is pusing the problem to the user and a
quite lame way to address the problem.

The IMHO best solution is to send data only if someone is connected to
the slave device (assuming we find a way to figure that).

Independant of that I think the char devices should move to non-blocking
operation.  That depends on the callers being able to handle
qemu_chr_write() doing partial writes and -EAGAIN failures though.
xenconsole code is doing fine here for example, but others probably
depend on the current behavior.  So it should probably the device
emulation code which decides whenever it can run in non-blocking mode or
not.

cheers,
  Gerd

-- 
http://kraxel.fedorapeople.org/xenner/

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 11:48     ` Gerd Hoffmann
@ 2008-07-23 12:15       ` Daniel P. Berrange
  2008-07-23 12:52         ` Gerd Hoffmann
  0 siblings, 1 reply; 44+ messages in thread
From: Daniel P. Berrange @ 2008-07-23 12:15 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

On Wed, Jul 23, 2008 at 01:48:14PM +0200, Gerd Hoffmann wrote:
> Daniel P. Berrange wrote:
> 
> > In the case of the PTY backend, the only time I'd expect data to be dropped
> > is if there was no active slave open. If an application has the PTY open
> > and is interacting, then I'd want to get all data.  
> 
> Yep, that would be most useful (and also matches what is done for tcp
> for example).  Now the interesting question is:  How can qemu figure (in
> a portable way) whenever there is some process listening on the slave side?

Well you get SIGHUP when the slave side closes, but the problem is then
detecting the re-connect. If you keep polling on the master PTY you'll just
spin getting SIGHUP all the time. On Linux you can deal with this by using
epoll() in edge-triggered mode instead of poll which is level-triggered.
Unfortunately epoll is Linux specific, so you'd need to have alternate
impls of the guts of the QEMU event loop for every OS :-(

According to epoll(2), on FreeBSD you can use kqueue and on Solaris
you can use /dev/poll. The PTY code isn't supported on Windows so
that wouldn't neccessarily be a show stopper.

Daniel
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 12:04     ` Gerd Hoffmann
@ 2008-07-23 12:18       ` Paul Brook
  0 siblings, 0 replies; 44+ messages in thread
From: Paul Brook @ 2008-07-23 12:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

> >> This changes semantics a bit.  Previously, using a pty would guarantee
> >> that data is always written as qemu_chr_write does not perform any sort
> >> of buffering.
> >>
> >> Now, that data will be silently dropped instead of causing QEMU to
> >> block.  I don't think it's perfectly clear that one behaviour is clearly
> >> better than the other.
> >
> > Then we need both.
> >
> > Add an option to specify non-blocking mode for stdio, pty and pipe in
> > qemu_chr_open.  Blocking mode is used by default (maintaining current
> > semantics), non-blocking mode if the name is prefixed with nonblock:
>
> Doing that as config option is pusing the problem to the user and a
> quite lame way to address the problem.

I agree. Char devices should never drop data when a user is connected. If we 
can't tell whether a user is connected we should never drop data at all, and 
it's the user's responsibility to ensure data doesn't back up.

Paul

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 12:15       ` Daniel P. Berrange
@ 2008-07-23 12:52         ` Gerd Hoffmann
  2008-07-23 12:59           ` Daniel P. Berrange
  2008-07-23 14:24           ` Gerd Hoffmann
  0 siblings, 2 replies; 44+ messages in thread
From: Gerd Hoffmann @ 2008-07-23 12:52 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

Daniel P. Berrange wrote:
> On Wed, Jul 23, 2008 at 01:48:14PM +0200, Gerd Hoffmann wrote:
>> Daniel P. Berrange wrote:
>>
>>> In the case of the PTY backend, the only time I'd expect data to be dropped
>>> is if there was no active slave open. If an application has the PTY open
>>> and is interacting, then I'd want to get all data.  
>> Yep, that would be most useful (and also matches what is done for tcp
>> for example).  Now the interesting question is:  How can qemu figure (in
>> a portable way) whenever there is some process listening on the slave side?
> 
> Well you get SIGHUP when the slave side closes, but the problem is then
> detecting the re-connect.

I don't see a SIGHUP.

Played around a bit with it (on linux) and found:

The write() syscall doesn't show different behavior.  It just queues up
data and either blocks or returns -EAGAIN when the buffer is full.  No
matter whenever someone is connected or not.

The read() syscall blocks or returns -EAGAIN when connected.  It returns
-EIO when unconnected (and flagged ready by select/poll).  So we can
detect disconnects that way.

> If you keep polling on the master PTY you'll just
> spin getting SIGHUP all the time.

Yep.  Well, I've seen it spinning getting -EIO, but thats pretty much
the same issue.

> On Linux you can deal with this by using
> epoll() in edge-triggered mode instead of poll which is level-triggered.
> Unfortunately epoll is Linux specific, so you'd need to have alternate
> impls of the guts of the QEMU event loop for every OS :-(

It is probably easier take the fd out of the polling loop and check now
and then using a timer.  Not perfect, but IMHO better that maintaining
three different poll implementations.

Which means we need our own code for ptys and can't use the generic fd
functions.  I'll go trying cooking up a patch ...

cheers,
  Gerd

-- 
http://kraxel.fedorapeople.org/xenner/

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 12:52         ` Gerd Hoffmann
@ 2008-07-23 12:59           ` Daniel P. Berrange
  2008-07-23 14:24           ` Gerd Hoffmann
  1 sibling, 0 replies; 44+ messages in thread
From: Daniel P. Berrange @ 2008-07-23 12:59 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

On Wed, Jul 23, 2008 at 02:52:09PM +0200, Gerd Hoffmann wrote:
> Daniel P. Berrange wrote:
> > On Wed, Jul 23, 2008 at 01:48:14PM +0200, Gerd Hoffmann wrote:
> >> Daniel P. Berrange wrote:
> >>
> >>> In the case of the PTY backend, the only time I'd expect data to be dropped
> >>> is if there was no active slave open. If an application has the PTY open
> >>> and is interacting, then I'd want to get all data.  
> >> Yep, that would be most useful (and also matches what is done for tcp
> >> for example).  Now the interesting question is:  How can qemu figure (in
> >> a portable way) whenever there is some process listening on the slave side?
> > 
> > Well you get SIGHUP when the slave side closes, but the problem is then
> > detecting the re-connect.
> 
> I don't see a SIGHUP.

Of course I meant POLLHUP not SIGHUP ...

Daniel
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 12:52         ` Gerd Hoffmann
  2008-07-23 12:59           ` Daniel P. Berrange
@ 2008-07-23 14:24           ` Gerd Hoffmann
  2008-07-23 15:24             ` Anthony Liguori
  2008-07-24 15:37             ` [Qemu-devel] " Anthony Liguori
  1 sibling, 2 replies; 44+ messages in thread
From: Gerd Hoffmann @ 2008-07-23 14:24 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 215 bytes --]

  Hi,

> Which means we need our own code for ptys and can't use the generic fd
> functions.  I'll go trying cooking up a patch ...

Comments on this one?

cheers,
  Gerd

-- 
http://kraxel.fedorapeople.org/xenner/

[-- Attachment #2: qemu-pty.diff --]
[-- Type: text/x-patch, Size: 4062 bytes --]

diff --git a/vl.c b/vl.c
index 1af6d10..23d92e5 100644
--- a/vl.c
+++ b/vl.c
@@ -2454,21 +2454,153 @@ void cfmakeraw (struct termios *termios_p)
 #endif
 
 #if defined(__linux__) || defined(__sun__)
+
+typedef struct {
+    int fd;
+    int connected;
+    int polling;
+    int read_bytes;
+    int interval;
+    QEMUTimer *timer;
+} PtyCharDriver;
+
+static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
+{
+    PtyCharDriver *s = chr->opaque;
+    if (!s->connected)
+	return 0;
+    return unix_write(s->fd, buf, len);
+}
+
+static void pty_chr_state(CharDriverState *chr, int connected)
+{
+    PtyCharDriver *s = chr->opaque;
+
+    if (s->connected == connected)
+	return;
+    if (connected) {
+	fprintf(stderr,"%s: %s connected\n", __FUNCTION__, ptsname(s->fd));
+	s->connected = 1;
+	qemu_chr_reset(chr);
+    } else {
+	fprintf(stderr,"%s: %s disconnected\n", __FUNCTION__, ptsname(s->fd));
+	s->connected = 0;
+	qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + s->interval);
+    }
+}
+
+static int pty_chr_read_poll(void *opaque)
+{
+    CharDriverState *chr = opaque;
+    PtyCharDriver *s = chr->opaque;
+
+    s->read_bytes = qemu_chr_can_read(chr);
+    return s->read_bytes;
+}
+
+static void pty_chr_read(void *opaque)
+{
+    CharDriverState *chr = opaque;
+    PtyCharDriver *s = chr->opaque;
+    int size, len;
+    uint8_t buf[1024];
+
+    len = sizeof(buf);
+    if (len > s->read_bytes)
+        len = s->read_bytes;
+    if (len == 0)
+        return;
+    size = read(s->fd, buf, len);
+    if ((size == -1 && EIO == errno) ||
+	(size == 0)) {
+	qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+	s->polling = 0;
+	pty_chr_state(chr, 0);
+        return;
+    }
+    if (size > 0) {
+	pty_chr_state(chr, 1);
+        qemu_chr_read(chr, buf, size);
+    }
+}
+
+static void pty_chr_update_read_handler(CharDriverState *chr)
+{
+    PtyCharDriver *s = chr->opaque;
+
+    qemu_set_fd_handler2(s->fd, pty_chr_read_poll,
+			 pty_chr_read, NULL, chr);
+    s->polling = 1;
+    qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + s->interval);
+}
+
+void pty_chr_timer(void *opaque)
+{
+    struct CharDriverState *chr = opaque;    
+    PtyCharDriver *s = chr->opaque;
+
+    if (s->connected) {
+	/* All fine, nothing to do. */
+	return;
+    }
+    if (s->polling) {
+	/* Ran for a while without getting EIO for reads,
+	 * probably someone connected to the slave pty. */
+	pty_chr_state(chr, 1);
+	return;
+    }
+    /* Try reading again ... */
+#if 0
+    fprintf(stderr,"%s: %s checking ...\n", __FUNCTION__, ptsname(s->fd));
+#endif
+    pty_chr_update_read_handler(chr);
+}
+
+static void pty_chr_close(struct CharDriverState *chr)
+{
+    PtyCharDriver *s = chr->opaque;
+
+    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+    close(s->fd);
+    qemu_free(s);
+}
+
 static CharDriverState *qemu_chr_open_pty(void)
 {
+    CharDriverState *chr;
+    PtyCharDriver *s;
     struct termios tty;
-    int master_fd, slave_fd;
+    int slave_fd;
+    
+    chr = qemu_mallocz(sizeof(CharDriverState));
+    if (!chr)
+        return NULL;
+    s = qemu_mallocz(sizeof(PtyCharDriver));
+    if (!s) {
+        free(chr);
+        return NULL;
+    }
 
-    if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) < 0) {
+    if (openpty(&s->fd, &slave_fd, NULL, NULL, NULL) < 0) {
         return NULL;
     }
 
     /* Set raw attributes on the pty. */
     cfmakeraw(&tty);
     tcsetattr(slave_fd, TCSAFLUSH, &tty);
+    close(slave_fd);
+    
+    fprintf(stderr, "char device redirected to %s\n", ptsname(s->fd));
+    
+    chr->opaque = s;
+    chr->chr_write = pty_chr_write;
+    chr->chr_update_read_handler = pty_chr_update_read_handler;
+    chr->chr_close = pty_chr_close;
 
-    fprintf(stderr, "char device redirected to %s\n", ptsname(master_fd));
-    return qemu_chr_open_fd(master_fd, master_fd);
+    s->interval = 100; /* miliseconds */
+    s->timer = qemu_new_timer(rt_clock, pty_chr_timer, chr);
+    
+    return chr;
 }
 
 static void tty_serial_init(int fd, int speed,

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 14:24           ` Gerd Hoffmann
@ 2008-07-23 15:24             ` Anthony Liguori
  2008-07-23 15:31               ` Daniel P. Berrange
  2008-07-23 16:11               ` Gerd Hoffmann
  2008-07-24 15:37             ` [Qemu-devel] " Anthony Liguori
  1 sibling, 2 replies; 44+ messages in thread
From: Anthony Liguori @ 2008-07-23 15:24 UTC (permalink / raw)
  To: qemu-devel

Gerd Hoffmann wrote:
>   Hi,
>
>   
>> Which means we need our own code for ptys and can't use the generic fd
>> functions.  I'll go trying cooking up a patch ...
>>     
>
> Comments on this one?
>   

Checking every 100ms for every pty device really makes me cringe.

Why is libvirt using ptys in the first place?  Why not use unix 
sockets?  They don't have these problems with state tracking.

Regards,

Anthony Liguori

> cheers,
>   Gerd
>
>   

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 15:24             ` Anthony Liguori
@ 2008-07-23 15:31               ` Daniel P. Berrange
  2008-07-23 15:32                 ` Anthony Liguori
  2008-07-23 16:11               ` Gerd Hoffmann
  1 sibling, 1 reply; 44+ messages in thread
From: Daniel P. Berrange @ 2008-07-23 15:31 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

On Wed, Jul 23, 2008 at 10:24:58AM -0500, Anthony Liguori wrote:
> Gerd Hoffmann wrote:
> >  
> >>Which means we need our own code for ptys and can't use the generic fd
> >>functions.  I'll go trying cooking up a patch ...
> >
> >Comments on this one?
> >  
> 
> Checking every 100ms for every pty device really makes me cringe.
> 
> Why is libvirt using ptys in the first place?  Why not use unix 
> sockets?  They don't have these problems with state tracking.

The application using libvirt chooses to use PTYs - we're merely
exposing the capability. The virt-console program for interacting
with serial ports uses PTYs because its a configuration that historically
works with both Xen and KVM. It could equally use UNIX sockets, but it'd
still be desirable for PTYs to work better

Daniel
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 15:31               ` Daniel P. Berrange
@ 2008-07-23 15:32                 ` Anthony Liguori
  2008-07-23 16:17                   ` Gerd Hoffmann
  0 siblings, 1 reply; 44+ messages in thread
From: Anthony Liguori @ 2008-07-23 15:32 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

Daniel P. Berrange wrote:
> On Wed, Jul 23, 2008 at 10:24:58AM -0500, Anthony Liguori wrote:
>   
>> Gerd Hoffmann wrote:
>>     
>>>  
>>>       
>>>> Which means we need our own code for ptys and can't use the generic fd
>>>> functions.  I'll go trying cooking up a patch ...
>>>>         
>>> Comments on this one?
>>>  
>>>       
>> Checking every 100ms for every pty device really makes me cringe.
>>
>> Why is libvirt using ptys in the first place?  Why not use unix 
>> sockets?  They don't have these problems with state tracking.
>>     
>
> The application using libvirt chooses to use PTYs - we're merely
> exposing the capability. The virt-console program for interacting
> with serial ports uses PTYs because its a configuration that historically
> works with both Xen and KVM. It could equally use UNIX sockets, but it'd
> still be desirable for PTYs to work better
>   

Okay, I'd strongly suggest migrating to something other than ptys.

Regards,

Anthony Liguori

> Daniel
>   

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 15:24             ` Anthony Liguori
  2008-07-23 15:31               ` Daniel P. Berrange
@ 2008-07-23 16:11               ` Gerd Hoffmann
  2008-07-23 16:31                 ` Anthony Liguori
  2008-07-23 16:44                 ` Paul Brook
  1 sibling, 2 replies; 44+ messages in thread
From: Gerd Hoffmann @ 2008-07-23 16:11 UTC (permalink / raw)
  To: qemu-devel

Anthony Liguori wrote:
> Gerd Hoffmann wrote:
>>
>> Comments on this one?
> 
> Checking every 100ms for every pty device really makes me cringe.

Only when unconnected, and the interval can be changed.
And I'm certainly open for better ideas ...

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 15:32                 ` Anthony Liguori
@ 2008-07-23 16:17                   ` Gerd Hoffmann
  2008-07-23 16:33                     ` Anthony Liguori
  0 siblings, 1 reply; 44+ messages in thread
From: Gerd Hoffmann @ 2008-07-23 16:17 UTC (permalink / raw)
  To: qemu-devel

Anthony Liguori wrote:
> 
> Okay, I'd strongly suggest migrating to something other than ptys.
> 

Granted.  That still leaves the question open what to do about the
existing pty support.  Try to fix?  Leave it broken?  Drop from qemu?

cheers,
  Gerd

-- 
http://kraxel.fedorapeople.org/xenner/

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 16:11               ` Gerd Hoffmann
@ 2008-07-23 16:31                 ` Anthony Liguori
  2008-07-24  8:35                   ` Daniel P. Berrange
  2008-07-23 16:44                 ` Paul Brook
  1 sibling, 1 reply; 44+ messages in thread
From: Anthony Liguori @ 2008-07-23 16:31 UTC (permalink / raw)
  To: qemu-devel

Gerd Hoffmann wrote:
> Anthony Liguori wrote:
>   
>> Gerd Hoffmann wrote:
>>     
>>> Comments on this one?
>>>       
>> Checking every 100ms for every pty device really makes me cringe.
>>     
>
> Only when unconnected, and the interval can be changed.
> And I'm certainly open for better ideas ...
>   

I don't have one.  In xenconsoled, once a pty disconnected, it creates a 
new pty specifically because I don't think there's any sane way to 
detect reconnection.

Regards,

Anthony Liguori

> cheers,
>   Gerd
>
>
>
>   

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 16:17                   ` Gerd Hoffmann
@ 2008-07-23 16:33                     ` Anthony Liguori
  2008-07-23 19:08                       ` Jamie Lokier
  2008-07-24  7:54                       ` Gerd Hoffmann
  0 siblings, 2 replies; 44+ messages in thread
From: Anthony Liguori @ 2008-07-23 16:33 UTC (permalink / raw)
  To: qemu-devel

Gerd Hoffmann wrote:
> Anthony Liguori wrote:
>   
>> Okay, I'd strongly suggest migrating to something other than ptys.
>>
>>     
>
> Granted.  That still leaves the question open what to do about the
> existing pty support.  Try to fix?  Leave it broken?  Drop from qemu?
>   

I really don't like introducing polling.  I think we should be trying to 
reduce the overall number of wake ups in QEMU, not add more.

I'm inclined to say that we simply declare that reconnecting to a PTY is 
broken/unsupported and strongly encourage the use of something else 
(like unix sockets).  That's always been my understanding FWIW.

Regards,

Anthony Liguori

> cheers,
>   Gerd
>
>   

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 16:11               ` Gerd Hoffmann
  2008-07-23 16:31                 ` Anthony Liguori
@ 2008-07-23 16:44                 ` Paul Brook
  2008-07-24 17:37                   ` Anthony Liguori
  2008-07-25  7:15                   ` Gerd Hoffmann
  1 sibling, 2 replies; 44+ messages in thread
From: Paul Brook @ 2008-07-23 16:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

On Wednesday 23 July 2008, Gerd Hoffmann wrote:
> Anthony Liguori wrote:
> > Gerd Hoffmann wrote:
> >> Comments on this one?
> >
> > Checking every 100ms for every pty device really makes me cringe.
>
> Only when unconnected, and the interval can be changed.
> And I'm certainly open for better ideas ...

Anything that requires periodic polling is almost certainly wrong.

If it's unconnected then why do we need to poll at all? If we're discarding 
data then we aren't going to retry, so it should be sufficient to check 
whenever we send data.

Paul

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 16:33                     ` Anthony Liguori
@ 2008-07-23 19:08                       ` Jamie Lokier
  2008-07-24  7:24                         ` Gerd Hoffmann
  2008-07-24  7:54                       ` Gerd Hoffmann
  1 sibling, 1 reply; 44+ messages in thread
From: Jamie Lokier @ 2008-07-23 19:08 UTC (permalink / raw)
  To: qemu-devel

Anthony Liguori wrote:
> I'm inclined to say that we simply declare that reconnecting to a PTY is 
> broken/unsupported and strongly encourage the use of something else 
> (like unix sockets).  That's always been my understanding FWIW.

As fas as I know, the usual way to use ptys is a program opens the
pty/tty pair, then it forks/execs a process which will use the tty
half.  The child might be the one to open the tty, but it is still
done so the parent knows the tty is open before it tries to use the
pty.

So it's not usual to have a pty open and _wait_ for the tty to open.

That said, a long time ago X11 used to use ptys and did something like
that.  I think it had a main pty, accessed exclusively, for initial
connection - and then allocated a pty/tty pair per individual
connection, freeing up the main one for another client.

To create a pty, and wait without polling for another process to
connect to the tty, this might work:

    1. Open the pty and tty _pair_, in the usual way.
       (openpt, grantpt, unlockpt etc.)
       Make sure the tty doesn't become controlling terminal - TIOCNOTTY.

    2. Keep the tty open, so you poll the pty for I/O as usual.
       Ignore the tty, just keep it open.

    3. Write whatever intro message appears on the pty, same way as
       with a socket.  No need to wait, the message is queued anyway.

    4. When the other process opens the tty, it will read the
       intro message.  When it writes something, QEMU will get read
       availability on the pty and process monitor commands as usual.

    5. If you want to support reconnects, close the tty in QEMU after
       read availabilty on the pty, so you receive EIO/POLLHUP from the pty
       when the other process is finished, or if it calls vhangup().
       Then reopen the tty with TIOCNOTTY, send another intro again.

       This seems like it won't handle a process which connects and
       sends nothing.  You might be able to use TIOCPKT to detect when
       the other process reads any of the intro message, I'm not sure.
       This would be better.

       Actually, if TIOCPKT works maybe you don't need to separately
       open the tty...

I'm not sure if this is complicated by controlling terminals,
sessions, process groups and SIGTTOU/SIGTTINs sent to the other
process, or if it just works out provided the tty descriptor in step 1
is opened with TIOCNOTTY.

-- Jamie

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 19:08                       ` Jamie Lokier
@ 2008-07-24  7:24                         ` Gerd Hoffmann
  0 siblings, 0 replies; 44+ messages in thread
From: Gerd Hoffmann @ 2008-07-24  7:24 UTC (permalink / raw)
  To: qemu-devel

Jamie Lokier wrote:
> As fas as I know, the usual way to use ptys is a program opens the
> pty/tty pair, then it forks/execs a process which will use the tty
> half.  The child might be the one to open the tty, but it is still
> done so the parent knows the tty is open before it tries to use the
> pty.

Yep, that is what they are designed for (i.e. terminal emulators like
screen or xterm keep the pty and hand over the tty to the shell or
whatever process they are going to run in the virtual terminal).

> To create a pty, and wait without polling for another process to
> connect to the tty, this might work:
> 
>     1. Open the pty and tty _pair_, in the usual way.

[ ... cut ... ]

That would work for the monitor.

The problematic corner case are virtual serial lines though.  If nobody
is connected we don't want to send out data (pretty much like a
unconnected socket), so we don't block forever once the output buffer is
full.  If somebody is listening we want him get all the data (and
eventually block in case the reader is slow).

cheers,
  Gerd

-- 
http://kraxel.fedorapeople.org/xenner/

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 16:33                     ` Anthony Liguori
  2008-07-23 19:08                       ` Jamie Lokier
@ 2008-07-24  7:54                       ` Gerd Hoffmann
  2008-07-24  8:31                         ` Daniel P. Berrange
  2008-07-24  9:24                         ` Jamie Lokier
  1 sibling, 2 replies; 44+ messages in thread
From: Gerd Hoffmann @ 2008-07-24  7:54 UTC (permalink / raw)
  To: qemu-devel

Anthony Liguori wrote:
> I really don't like introducing polling.  I think we should be trying to
> reduce the overall number of wake ups in QEMU, not add more.

Right now qemu wakes up quite often anyway, so it doesn't become worse
(bad excuse, I know).

> I'm inclined to say that we simply declare that reconnecting to a PTY is
> broken/unsupported and strongly encourage the use of something else
> (like unix sockets).  That's always been my understanding FWIW.

It's not only reconnects, its also the initial connect.

Right now qemu simply blocks once the pty output buffer is full.  With
nobody reading this effectively means qemu blocks forever and doesn't
responds any more to anything.  It can't stay that way IMO.

I think we have three options here:

  (1) Detect whenever someone is connected.  Drawback: needs polling
      (unless someone comes up with a better patch).
  (2) Run ptys in non-blocking mode.  Drawback: we risk loosing data
      in case the pty reader is slow (also when nobody is connected of
      course, but that is intentional ...).
  (3) Drop pty support.  Drawback: we break existing setups.

Comments?  Other suggestions?

cheers,
  Gerd

-- 
http://kraxel.fedorapeople.org/xenner/

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-24  7:54                       ` Gerd Hoffmann
@ 2008-07-24  8:31                         ` Daniel P. Berrange
  2008-07-24  9:24                         ` Jamie Lokier
  1 sibling, 0 replies; 44+ messages in thread
From: Daniel P. Berrange @ 2008-07-24  8:31 UTC (permalink / raw)
  To: qemu-devel

On Thu, Jul 24, 2008 at 09:54:43AM +0200, Gerd Hoffmann wrote:
> Anthony Liguori wrote:
> > I really don't like introducing polling.  I think we should be trying to
> > reduce the overall number of wake ups in QEMU, not add more.
> 
> Right now qemu wakes up quite often anyway, so it doesn't become worse
> (bad excuse, I know).
> 
> > I'm inclined to say that we simply declare that reconnecting to a PTY is
> > broken/unsupported and strongly encourage the use of something else
> > (like unix sockets).  That's always been my understanding FWIW.
> 
> It's not only reconnects, its also the initial connect.
> 
> Right now qemu simply blocks once the pty output buffer is full.  With
> nobody reading this effectively means qemu blocks forever and doesn't
> responds any more to anything.  It can't stay that way IMO.
> 
> I think we have three options here:
> 
>   (1) Detect whenever someone is connected.  Drawback: needs polling
>       (unless someone comes up with a better patch).
>   (2) Run ptys in non-blocking mode.  Drawback: we risk loosing data
>       in case the pty reader is slow (also when nobody is connected of
>       course, but that is intentional ...).
>   (3) Drop pty support.  Drawback: we break existing setups.

NACK to that last option - I'd rather keep existing blocking behaviour,
than break existing applications using PTYs.

Daniel.
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 16:31                 ` Anthony Liguori
@ 2008-07-24  8:35                   ` Daniel P. Berrange
  2008-07-24 14:23                     ` Anthony Liguori
  0 siblings, 1 reply; 44+ messages in thread
From: Daniel P. Berrange @ 2008-07-24  8:35 UTC (permalink / raw)
  To: qemu-devel

On Wed, Jul 23, 2008 at 11:31:42AM -0500, Anthony Liguori wrote:
> Gerd Hoffmann wrote:
> >Anthony Liguori wrote:
> >  
> >>Gerd Hoffmann wrote:
> >>    
> >>>Comments on this one?
> >>>      
> >>Checking every 100ms for every pty device really makes me cringe.
> >>    
> >
> >Only when unconnected, and the interval can be changed.
> >And I'm certainly open for better ideas ...
> >  
> 
> I don't have one.  In xenconsoled, once a pty disconnected, it creates a 
> new pty specifically because I don't think there's any sane way to 
> detect reconnection.

The only guarenteed reliable way I know of is using epoll(), but as I
mentioned before that's Linux specific, so not immediately useful unless
we're willing to drop in an alternate epoll() based main loop for Linux
only, and say other OS have to use PTYs in blocking mode.

Daniel
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-24  7:54                       ` Gerd Hoffmann
  2008-07-24  8:31                         ` Daniel P. Berrange
@ 2008-07-24  9:24                         ` Jamie Lokier
  2008-07-24  9:33                           ` Samuel Thibault
  1 sibling, 1 reply; 44+ messages in thread
From: Jamie Lokier @ 2008-07-24  9:24 UTC (permalink / raw)
  To: qemu-devel

Gerd Hoffmann wrote:
>   (2) Run ptys in non-blocking mode.  Drawback: we risk loosing data
>       in case the pty reader is slow (also when nobody is connected of
>       course, but that is intentional ...).

(4) Run ptys in non-blocking mode, but use a small output buffer in
    QEMU so nothing is lost.  It's not that hard.

-- Jamie

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-24  9:24                         ` Jamie Lokier
@ 2008-07-24  9:33                           ` Samuel Thibault
  2008-07-24 11:18                             ` Gerd Hoffmann
  0 siblings, 1 reply; 44+ messages in thread
From: Samuel Thibault @ 2008-07-24  9:33 UTC (permalink / raw)
  To: qemu-devel

Jamie Lokier, le Thu 24 Jul 2008 10:24:03 +0100, a écrit :
> Gerd Hoffmann wrote:
> >   (2) Run ptys in non-blocking mode.  Drawback: we risk loosing data
> >       in case the pty reader is slow (also when nobody is connected of
> >       course, but that is intentional ...).
> 
> (4) Run ptys in non-blocking mode, but use a small output buffer in
>     QEMU so nothing is lost.  It's not that hard.

Err, there's _already_ a small buffer in the kernel pty layer :)

Samuel

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-24  9:33                           ` Samuel Thibault
@ 2008-07-24 11:18                             ` Gerd Hoffmann
  0 siblings, 0 replies; 44+ messages in thread
From: Gerd Hoffmann @ 2008-07-24 11:18 UTC (permalink / raw)
  To: qemu-devel

Samuel Thibault wrote:
> Jamie Lokier, le Thu 24 Jul 2008 10:24:03 +0100, a écrit :
>> Gerd Hoffmann wrote:
>>>   (2) Run ptys in non-blocking mode.  Drawback: we risk loosing data
>>>       in case the pty reader is slow (also when nobody is connected of
>>>       course, but that is intentional ...).
>> (4) Run ptys in non-blocking mode, but use a small output buffer in
>>     QEMU so nothing is lost.  It's not that hard.
> 
> Err, there's _already_ a small buffer in the kernel pty layer :)

Yep, one page (aka 4k on x86) in size.  Of course we can buffer in qemu
too.  That doesn't solve the fundamental issue though (unless we don't
limit the buffer size, which would be insane IMHO).

cheers,
  Gerd

-- 
http://kraxel.fedorapeople.org/xenner/

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-24  8:35                   ` Daniel P. Berrange
@ 2008-07-24 14:23                     ` Anthony Liguori
  2008-07-24 15:07                       ` Jamie Lokier
  0 siblings, 1 reply; 44+ messages in thread
From: Anthony Liguori @ 2008-07-24 14:23 UTC (permalink / raw)
  To: Daniel P. Berrange, qemu-devel

Daniel P. Berrange wrote:
> On Wed, Jul 23, 2008 at 11:31:42AM -0500, Anthony Liguori wrote:
>   
>
> The only guarenteed reliable way I know of is using epoll(), but as I
> mentioned before that's Linux specific, so not immediately useful unless
> we're willing to drop in an alternate epoll() based main loop for Linux
> only, and say other OS have to use PTYs in blocking mode.
>   

So far, this sounds like the best option to me.

Regards,

Anthony Liguori

> Daniel
>   

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-24 15:07                       ` Jamie Lokier
@ 2008-07-24 14:53                         ` Gerd Hoffmann
  0 siblings, 0 replies; 44+ messages in thread
From: Gerd Hoffmann @ 2008-07-24 14:53 UTC (permalink / raw)
  To: qemu-devel

Jamie Lokier wrote:
> I'm surprised it works.  You shouldn't be able to get any more
> information out of epoll() than poll() - they're supposed to be
> exactly equivalent informationally, except for details and performance.

I was thinking just the same ...

poll/epoll says the file handle is readable.  It does that in two cases:

  (1) there is data to read
  (2) pty is unconnected and read() wants to give you an -EIO.

And I think you can't keep those two cases apart using only the
information given by poll/epoll ...

cheers,
  Gerd

-- 
http://kraxel.fedorapeople.org/xenner/

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-24 14:23                     ` Anthony Liguori
@ 2008-07-24 15:07                       ` Jamie Lokier
  2008-07-24 14:53                         ` Gerd Hoffmann
  0 siblings, 1 reply; 44+ messages in thread
From: Jamie Lokier @ 2008-07-24 15:07 UTC (permalink / raw)
  To: qemu-devel

Anthony Liguori wrote:
> >The only guarenteed reliable way I know of is using epoll(), but as I
> >mentioned before that's Linux specific, so not immediately useful unless
> >we're willing to drop in an alternate epoll() based main loop for Linux
> >only, and say other OS have to use PTYs in blocking mode.
> >  
> 
> So far, this sounds like the best option to me.

I'm surprised it works.  You shouldn't be able to get any more
information out of epoll() than poll() - they're supposed to be
exactly equivalent informationally, except for details and performance.

Which suggests to me if it works now, it might get... fixed.

So what are you doing with epoll + pty that works?

Btw, you don't need an epoll main loop.  You can just put the pty into
epoll, and put the _epoll_'s file descriptor into the main loop.
You'll get a ready-to-read when there's a message from epoll.

epoll supports its descriptor being used by other pollers, even
another epoll.

-- Jamie

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [Qemu-devel] Re: [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 14:24           ` Gerd Hoffmann
  2008-07-23 15:24             ` Anthony Liguori
@ 2008-07-24 15:37             ` Anthony Liguori
  2008-07-25 11:42               ` Gerd Hoffmann
  1 sibling, 1 reply; 44+ messages in thread
From: Anthony Liguori @ 2008-07-24 15:37 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Gerd Hoffmann wrote:
>   Hi,
> 
>> Which means we need our own code for ptys and can't use the generic fd
>> functions.  I'll go trying cooking up a patch ...
> 
> Comments on this one?

If this is the best we can do (and I certainly hope we can do better), 
then I would at least like to see the interval bumped up to a second. 
I'd also like to see the qemu_mod_timer API extended to accept timeouts 
in milliseconds or seconds such that the later can be coalesced into a 
single wake-up.

An alternative implementation would be to use one timer for all PTY 
devices but I think adding a qemu_mod_timer_sec() is a more useful 
general thing to do.

Regards,

Anthony Liguori

> cheers,
>   Gerd
> 
> 

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 16:44                 ` Paul Brook
@ 2008-07-24 17:37                   ` Anthony Liguori
  2008-07-25  7:15                   ` Gerd Hoffmann
  1 sibling, 0 replies; 44+ messages in thread
From: Anthony Liguori @ 2008-07-24 17:37 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Paul Brook wrote:
> On Wednesday 23 July 2008, Gerd Hoffmann wrote:
>   
>> Anthony Liguori wrote:
>>     
>>> Gerd Hoffmann wrote:
>>>       
>>>> Comments on this one?
>>>>         
>>> Checking every 100ms for every pty device really makes me cringe.
>>>       
>> Only when unconnected, and the interval can be changed.
>> And I'm certainly open for better ideas ...
>>     
>
> Anything that requires periodic polling is almost certainly wrong.
>
> If it's unconnected then why do we need to poll at all? If we're discarding 
> data then we aren't going to retry, so it should be sufficient to check 
> whenever we send data.
>   

There's no way to determine if someone reconnected without trying to do 
a read().  pty's just aren't designed for this sort of thing.

Regards,

Anthony Liguori

> Paul
>
>
>   

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-23 16:44                 ` Paul Brook
  2008-07-24 17:37                   ` Anthony Liguori
@ 2008-07-25  7:15                   ` Gerd Hoffmann
  2008-07-25 16:17                     ` Jamie Lokier
  1 sibling, 1 reply; 44+ messages in thread
From: Gerd Hoffmann @ 2008-07-25  7:15 UTC (permalink / raw)
  To: Paul Brook; +Cc: qemu-devel

Paul Brook wrote:
> On Wednesday 23 July 2008, Gerd Hoffmann wrote:
>> Anthony Liguori wrote:
>>> Gerd Hoffmann wrote:
>>>> Comments on this one?
>>> Checking every 100ms for every pty device really makes me cringe.
>> Only when unconnected, and the interval can be changed.
>> And I'm certainly open for better ideas ...
> 
> Anything that requires periodic polling is almost certainly wrong.
> 
> If it's unconnected then why do we need to poll at all? If we're discarding 
> data then we aren't going to retry, so it should be sufficient to check 
> whenever we send data.

Fundamental problem is there is no easy way to figure whenever we are
connected or not.  Well, detecting the "connected -> disconnected"
transition is easy, as read() starts giving us -EIO then.  The
problematic case is the "(initial state | disconnected) ->
(re-)connected" transition.  We have to try read() now and then to check
whenever we still get -EIO or not.

Doing the read() check in the write path is an good idea.  Alone it
still doesn't solve the problem because we would depend on the guest
writing stuff to the serial line to detect a (re-)connect then.  But it
 makes large poll intervalls suck less.  I'll go send an updated patch
later today.

cheers,
  Gerd

-- 
http://kraxel.fedorapeople.org/xenner/

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [Qemu-devel] Re: [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-24 15:37             ` [Qemu-devel] " Anthony Liguori
@ 2008-07-25 11:42               ` Gerd Hoffmann
  2008-07-25 15:04                 ` Anthony Liguori
  0 siblings, 1 reply; 44+ messages in thread
From: Gerd Hoffmann @ 2008-07-25 11:42 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, Paul Brook

[-- Attachment #1: Type: text/plain, Size: 550 bytes --]

Anthony Liguori wrote:
> Gerd Hoffmann wrote:
>>   Hi,
>>
>>> Which means we need our own code for ptys and can't use the generic fd
>>> functions.  I'll go trying cooking up a patch ...
>>
>> Comments on this one?
> 
> If this is the best we can do (and I certainly hope we can do better),
> then I would at least like to see the interval bumped up to a second.

Done.  Also implemented Pauls idea to check the status on guest writes.
 Added a bunch of comments for the state tracking.

Comments?

  Gerd

-- 
http://kraxel.fedorapeople.org/xenner/

[-- Attachment #2: 0003-Attempt-to-detect-unconnected-ptys.patch --]
[-- Type: text/x-patch, Size: 6107 bytes --]

>From 076b5cff55b57a64e5f8daf32186d924945f78b4 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Wed, 23 Jul 2008 16:35:40 +0200
Subject: [PATCH 03/21] Attempt to detect unconnected ptys.

This patch moves the pty char device imlementation away from the generic
filehandle code.  It tries to detect as good as possible whenever there
is someone connected to the slave pty device and only send data down the
road in case someone is listening.  Unfortunaly we have to poll via
timer once in a while to check the status because we have to use read()
on the master pty to figure the status (returns -EIO when unconnected).

Poll intervall for an idle guest is one second, when the guest sends
data to the virtual device linked to the pty we check more frequently.

The point for all of this is to avoid qemu blocking and not responding
any more.  Writing to the master pty handle succeeds even when nobody is
connected to (and reading from) to the slave end of the pty.  The kernel
just bufferes the writes.  And as soon as the kernel buffer is full the
write() call blocks forever ...

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 vl.c |  158 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 154 insertions(+), 4 deletions(-)

diff --git a/vl.c b/vl.c
index 23b5243..faf7b95 100644
--- a/vl.c
+++ b/vl.c
@@ -2474,21 +2474,171 @@ void cfmakeraw (struct termios *termios_p)
 #endif
 
 #if defined(__linux__) || defined(__sun__)
+
+typedef struct {
+    int fd;
+    int connected;
+    int polling;
+    int read_bytes;
+    QEMUTimer *timer;
+} PtyCharDriver;
+
+static void pty_chr_update_read_handler(CharDriverState *chr);
+static void pty_chr_state(CharDriverState *chr, int connected);
+
+static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
+{
+    PtyCharDriver *s = chr->opaque;
+
+    if (!s->connected) {
+	/* guest sends data, check for (re-)connect */
+	pty_chr_update_read_handler(chr);
+	return 0;
+    }
+    return unix_write(s->fd, buf, len);
+}
+
+static int pty_chr_read_poll(void *opaque)
+{
+    CharDriverState *chr = opaque;
+    PtyCharDriver *s = chr->opaque;
+
+    s->read_bytes = qemu_chr_can_read(chr);
+    return s->read_bytes;
+}
+
+static void pty_chr_read(void *opaque)
+{
+    CharDriverState *chr = opaque;
+    PtyCharDriver *s = chr->opaque;
+    int size, len;
+    uint8_t buf[1024];
+
+    len = sizeof(buf);
+    if (len > s->read_bytes)
+        len = s->read_bytes;
+    if (len == 0)
+        return;
+    size = read(s->fd, buf, len);
+    if ((size == -1 && EIO == errno) ||
+	(size == 0)) {
+	qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+	s->polling = 0;
+	pty_chr_state(chr, 0);
+        return;
+    }
+    if (size > 0) {
+	pty_chr_state(chr, 1);
+        qemu_chr_read(chr, buf, size);
+    }
+}
+
+static void pty_chr_update_read_handler(CharDriverState *chr)
+{
+    PtyCharDriver *s = chr->opaque;
+
+    qemu_set_fd_handler2(s->fd, pty_chr_read_poll,
+			 pty_chr_read, NULL, chr);
+    s->polling = 1;
+    /*
+     * Short timeout here: just need wait long enougth that qemu makes
+     * it through the poll loop once.  When reconnected we want a
+     * short timeout so we notice it almost instantly.  Otherwise
+     * read() gives us -EIO instantly, making pty_chr_state() reset the
+     * timeout to the normal (much longer) poll interval before the
+     * timer triggers.
+     */
+    qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 10);
+}
+
+static void pty_chr_state(CharDriverState *chr, int connected)
+{
+    PtyCharDriver *s = chr->opaque;
+
+    if (!connected) {
+	if (s->connected) {
+	    fprintf(stderr,"%s: %s disconnected\n", __FUNCTION__, ptsname(s->fd));
+	    s->connected = 0;
+	}
+	/* (re-)connect poll interval for idle guests: once per second.
+	 * We check more frequently in case the guests sends data to
+	 * the virtual device linked to our pty. */
+	qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 1000);
+    } else {
+	if (!s->connected) {
+	    fprintf(stderr,"%s: %s connected\n", __FUNCTION__, ptsname(s->fd));
+	    s->connected = 1;
+	    qemu_chr_reset(chr);
+	}
+    }
+}
+
+void pty_chr_timer(void *opaque)
+{
+    struct CharDriverState *chr = opaque;    
+    PtyCharDriver *s = chr->opaque;
+
+    if (s->connected) {
+	/* All fine, nothing to do. */
+	return;
+    }
+    if (s->polling) {
+	/* Ran for a while without getting EIO for reads,
+	 * probably someone connected to the slave pty. */
+	pty_chr_state(chr, 1);
+	return;
+    }
+    /* Try reading again ... */
+#if 0
+    fprintf(stderr,"%s: %s checking ...\n", __FUNCTION__, ptsname(s->fd));
+#endif
+    pty_chr_update_read_handler(chr);
+}
+
+static void pty_chr_close(struct CharDriverState *chr)
+{
+    PtyCharDriver *s = chr->opaque;
+
+    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+    close(s->fd);
+    qemu_free(s);
+}
+
 static CharDriverState *qemu_chr_open_pty(void)
 {
+    CharDriverState *chr;
+    PtyCharDriver *s;
     struct termios tty;
-    int master_fd, slave_fd;
+    int slave_fd;
+    
+    chr = qemu_mallocz(sizeof(CharDriverState));
+    if (!chr)
+        return NULL;
+    s = qemu_mallocz(sizeof(PtyCharDriver));
+    if (!s) {
+        free(chr);
+        return NULL;
+    }
 
-    if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) < 0) {
+    if (openpty(&s->fd, &slave_fd, NULL, NULL, NULL) < 0) {
         return NULL;
     }
 
     /* Set raw attributes on the pty. */
     cfmakeraw(&tty);
     tcsetattr(slave_fd, TCSAFLUSH, &tty);
+    close(slave_fd);
+    
+    fprintf(stderr, "char device redirected to %s\n", ptsname(s->fd));
+    
+    chr->opaque = s;
+    chr->chr_write = pty_chr_write;
+    chr->chr_update_read_handler = pty_chr_update_read_handler;
+    chr->chr_close = pty_chr_close;
 
-    fprintf(stderr, "char device redirected to %s\n", ptsname(master_fd));
-    return qemu_chr_open_fd(master_fd, master_fd);
+    s->timer = qemu_new_timer(rt_clock, pty_chr_timer, chr);
+    
+    return chr;
 }
 
 static void tty_serial_init(int fd, int speed,
-- 
1.5.4.1


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [Qemu-devel] Re: [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-25 11:42               ` Gerd Hoffmann
@ 2008-07-25 15:04                 ` Anthony Liguori
  2008-07-28  9:59                   ` Gerd Hoffmann
  0 siblings, 1 reply; 44+ messages in thread
From: Anthony Liguori @ 2008-07-25 15:04 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel, Paul Brook

Gerd Hoffmann wrote:
> From 076b5cff55b57a64e5f8daf32186d924945f78b4 Mon Sep 17 00:00:00 2001
> From: Gerd Hoffmann <kraxel@redhat.com>
> Date: Wed, 23 Jul 2008 16:35:40 +0200
> Subject: [PATCH 03/21] Attempt to detect unconnected ptys.
>
> This patch moves the pty char device imlementation away from the generic
> filehandle code.  It tries to detect as good as possible whenever there
> is someone connected to the slave pty device and only send data down the
> road in case someone is listening.  Unfortunaly we have to poll via
> timer once in a while to check the status because we have to use read()
> on the master pty to figure the status (returns -EIO when unconnected).
>
> Poll intervall for an idle guest is one second, when the guest sends
> data to the virtual device linked to the pty we check more frequently.
>
> The point for all of this is to avoid qemu blocking and not responding
> any more.  Writing to the master pty handle succeeds even when nobody is
> connected to (and reading from) to the slave end of the pty.  The kernel
> just bufferes the writes.  And as soon as the kernel buffer is full the
> write() call blocks forever ...
>   

You've got whitespace damage.  You're mixing tabs and spaces.  Please 
only use spaces.

> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  vl.c |  158 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 files changed, 154 insertions(+), 4 deletions(-)
>
> diff --git a/vl.c b/vl.c
> index 23b5243..faf7b95 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -2474,21 +2474,171 @@ void cfmakeraw (struct termios *termios_p)
>  #endif
>  
>  #if defined(__linux__) || defined(__sun__)
> +
> +typedef struct {
> +    int fd;
> +    int connected;
> +    int polling;
> +    int read_bytes;
> +    QEMUTimer *timer;
> +} PtyCharDriver;
> +
> +static void pty_chr_update_read_handler(CharDriverState *chr);
> +static void pty_chr_state(CharDriverState *chr, int connected);
> +
> +static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
> +{
> +    PtyCharDriver *s = chr->opaque;
> +
> +    if (!s->connected) {
> +	/* guest sends data, check for (re-)connect */
> +	pty_chr_update_read_handler(chr);
> +	return 0;
> +    }
> +    return unix_write(s->fd, buf, len);
> +}
> +
> +static int pty_chr_read_poll(void *opaque)
> +{
> +    CharDriverState *chr = opaque;
> +    PtyCharDriver *s = chr->opaque;
> +
> +    s->read_bytes = qemu_chr_can_read(chr);
> +    return s->read_bytes;
> +}
> +
> +static void pty_chr_read(void *opaque)
> +{
> +    CharDriverState *chr = opaque;
> +    PtyCharDriver *s = chr->opaque;
> +    int size, len;
> +    uint8_t buf[1024];
> +
> +    len = sizeof(buf);
> +    if (len > s->read_bytes)
> +        len = s->read_bytes;
> +    if (len == 0)
> +        return;
> +    size = read(s->fd, buf, len);
> +    if ((size == -1 && EIO == errno) ||
> +	(size == 0)) {
>   

errno == EIO

> +	qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
> +	s->polling = 0;
> +	pty_chr_state(chr, 0);
> +        return;
> +    }
> +    if (size > 0) {
> +	pty_chr_state(chr, 1);
> +        qemu_chr_read(chr, buf, size);
> +    }
> +}
> +
> +static void pty_chr_update_read_handler(CharDriverState *chr)
> +{
> +    PtyCharDriver *s = chr->opaque;
> +
> +    qemu_set_fd_handler2(s->fd, pty_chr_read_poll,
> +			 pty_chr_read, NULL, chr);
> +    s->polling = 1;
> +    /*
> +     * Short timeout here: just need wait long enougth that qemu makes
> +     * it through the poll loop once.  When reconnected we want a
> +     * short timeout so we notice it almost instantly.  Otherwise
> +     * read() gives us -EIO instantly, making pty_chr_state() reset the
> +     * timeout to the normal (much longer) poll interval before the
> +     * timer triggers.
> +     */
> +    qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 10);
>   

Perhaps what you really want here is a bottom half?

> +}
> +
> +static void pty_chr_state(CharDriverState *chr, int connected)
> +{
> +    PtyCharDriver *s = chr->opaque;
> +
> +    if (!connected) {
> +	if (s->connected) {
> +	    fprintf(stderr,"%s: %s disconnected\n", __FUNCTION__, ptsname(s->fd));
>   

Obviously this debugging has to go.

> +	    s->connected = 0;
> +	}
> +	/* (re-)connect poll interval for idle guests: once per second.
> +	 * We check more frequently in case the guests sends data to
> +	 * the virtual device linked to our pty. */
> +	qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 1000);
> +    } else {
> +	if (!s->connected) {
> +	    fprintf(stderr,"%s: %s connected\n", __FUNCTION__, ptsname(s->fd));
> +	    s->connected = 1;
> +	    qemu_chr_reset(chr);
> +	}
> +    }
> +}
> +
> +void pty_chr_timer(void *opaque)
> +{
> +    struct CharDriverState *chr = opaque;    
> +    PtyCharDriver *s = chr->opaque;
> +
> +    if (s->connected) {
> +	/* All fine, nothing to do. */
> +	return;
> +    }
> +    if (s->polling) {
> +	/* Ran for a while without getting EIO for reads,
> +	 * probably someone connected to the slave pty. */
> +	pty_chr_state(chr, 1);
> +	return;
> +    }
> +    /* Try reading again ... */
> +#if 0
> +    fprintf(stderr,"%s: %s checking ...\n", __FUNCTION__, ptsname(s->fd));
> +#endif
> +    pty_chr_update_read_handler(chr);
> +}
> +
> +static void pty_chr_close(struct CharDriverState *chr)
> +{
> +    PtyCharDriver *s = chr->opaque;
> +
> +    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
> +    close(s->fd);
> +    qemu_free(s);
> +}
> +
>  static CharDriverState *qemu_chr_open_pty(void)
>  {
> +    CharDriverState *chr;
> +    PtyCharDriver *s;
>      struct termios tty;
> -    int master_fd, slave_fd;
> +    int slave_fd;
> +    
> +    chr = qemu_mallocz(sizeof(CharDriverState));
> +    if (!chr)
> +        return NULL;
> +    s = qemu_mallocz(sizeof(PtyCharDriver));
> +    if (!s) {
> +        free(chr);
>   

qemu_free()

Regards,

Anthony Liguori

> +        return NULL;
> +    }
>  
> -    if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) < 0) {
> +    if (openpty(&s->fd, &slave_fd, NULL, NULL, NULL) < 0) {
>          return NULL;
>      }
>  
>      /* Set raw attributes on the pty. */
>      cfmakeraw(&tty);
>      tcsetattr(slave_fd, TCSAFLUSH, &tty);
> +    close(slave_fd);
> +    
> +    fprintf(stderr, "char device redirected to %s\n", ptsname(s->fd));
> +    
> +    chr->opaque = s;
> +    chr->chr_write = pty_chr_write;
> +    chr->chr_update_read_handler = pty_chr_update_read_handler;
> +    chr->chr_close = pty_chr_close;
>  
> -    fprintf(stderr, "char device redirected to %s\n", ptsname(master_fd));
> -    return qemu_chr_open_fd(master_fd, master_fd);
> +    s->timer = qemu_new_timer(rt_clock, pty_chr_timer, chr);
> +    
> +    return chr;
>  }
>  
>  static void tty_serial_init(int fd, int speed,
> -- 1.5.4.1

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-25  7:15                   ` Gerd Hoffmann
@ 2008-07-25 16:17                     ` Jamie Lokier
  2008-07-28  8:49                       ` Gerd Hoffmann
  0 siblings, 1 reply; 44+ messages in thread
From: Jamie Lokier @ 2008-07-25 16:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paul Brook

Gerd Hoffmann wrote:
> Fundamental problem is there is no easy way to figure whenever we are
> connected or not.  Well, detecting the "connected -> disconnected"
> transition is easy, as read() starts giving us -EIO then.  The
> problematic case is the "(initial state | disconnected) ->
> (re-)connected" transition.  We have to try read() now and then to check
> whenever we still get -EIO or not.

Btw, I've just tested.  In the initial state, the tty side never
opened, read() blocks and poll/select report that it's not ready for
read.

So the initial state is no problem, it doesn't need polling.

Only disconnected -> reconnected is a problem.

-- Jamie

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-25 16:17                     ` Jamie Lokier
@ 2008-07-28  8:49                       ` Gerd Hoffmann
  2008-07-28 11:59                         ` Jamie Lokier
  0 siblings, 1 reply; 44+ messages in thread
From: Gerd Hoffmann @ 2008-07-28  8:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paul Brook

Jamie Lokier wrote:
> Gerd Hoffmann wrote:
>> Fundamental problem is there is no easy way to figure whenever we are
>> connected or not.  Well, detecting the "connected -> disconnected"
>> transition is easy, as read() starts giving us -EIO then.  The
>> problematic case is the "(initial state | disconnected) ->
>> (re-)connected" transition.  We have to try read() now and then to check
>> whenever we still get -EIO or not.
> 
> Btw, I've just tested.  In the initial state, the tty side never
> opened, read() blocks and poll/select report that it's not ready for
> read.

You still don't know whenever someone is connected or not.  And thus you
still don't know whenever the stuff you write to the tty is read out by
someone or you risk to block when the kernel buffer is full.

Also note that openpty() which is used by qemu gives you an open file
handle for the tty side, so there is no "tty never opened" state.

cheers,
  Gerd

-- 
http://kraxel.fedorapeople.org/xenner/

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [Qemu-devel] Re: [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-25 15:04                 ` Anthony Liguori
@ 2008-07-28  9:59                   ` Gerd Hoffmann
  2008-07-28 18:55                     ` Anthony Liguori
  0 siblings, 1 reply; 44+ messages in thread
From: Gerd Hoffmann @ 2008-07-28  9:59 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, Paul Brook

[-- Attachment #1: Type: text/plain, Size: 1370 bytes --]

> You've got whitespace damage.  You're mixing tabs and spaces.  Please
> only use spaces.

Fixed.

>> +    if ((size == -1 && EIO == errno) ||
>> +    (size == 0)) {
>>   
> 
> errno == EIO

Fixed.

>> +    /*
>> +     * Short timeout here: just need wait long enougth that qemu makes
>> +     * it through the poll loop once.  When reconnected we want a
>> +     * short timeout so we notice it almost instantly.  Otherwise
>> +     * read() gives us -EIO instantly, making pty_chr_state() reset the
>> +     * timeout to the normal (much longer) poll interval before the
>> +     * timer triggers.
>> +     */
>> +    qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 10);
>>   
> 
> Perhaps what you really want here is a bottom half?

Looked promising, tried, doesn't work.  bh is called *before* the pty
file handle is checked at least once for being readable.

>> +    if (s->connected) {
>> +        fprintf(stderr,"%s: %s disconnected\n", __FUNCTION__,
>> ptsname(s->fd));
>>   
> 
> Obviously this debugging has to go.

Dropped.

>> +    /* Try reading again ... */
>> +#if 0
>> +    fprintf(stderr,"%s: %s checking ...\n", __FUNCTION__,
>> ptsname(s->fd));
>> +#endif

... this too while being at it ;)

>> +    if (!s) {
>> +        free(chr);
>>   
> 
> qemu_free()

Fixed.

New patch attached.

cheers,
  Gerd

-- 
http://kraxel.fedorapeople.org/xenner/

[-- Attachment #2: 0003-Attempt-to-detect-unconnected-ptys.patch --]
[-- Type: text/x-patch, Size: 5938 bytes --]

>From 4362b66782ac68d8e1efb04fea1befeb20587677 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Wed, 23 Jul 2008 16:35:40 +0200
Subject: [PATCH 03/23] Attempt to detect unconnected ptys.

This patch moves the pty char device imlementation away from the generic
filehandle code.  It tries to detect as good as possible whenever there
is someone connected to the slave pty device and only send data down the
road in case someone is listening.  Unfortunaly we have to poll via
timer once in a while to check the status because we have to use read()
on the master pty to figure the status (returns -EIO when unconnected).

Poll intervall for an idle guest is one second, when the guest sends
data to the virtual device linked to the pty we check more frequently.

The point for all of this is to avoid qemu blocking and not responding
any more.  Writing to the master pty handle succeeds even when nobody is
connected to (and reading from) to the slave end of the pty.  The kernel
just bufferes the writes.  And as soon as the kernel buffer is full the
write() call blocks forever ...

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 vl.c |  149 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 145 insertions(+), 4 deletions(-)

diff --git a/vl.c b/vl.c
index 23b5243..8801615 100644
--- a/vl.c
+++ b/vl.c
@@ -2474,21 +2474,162 @@ void cfmakeraw (struct termios *termios_p)
 #endif
 
 #if defined(__linux__) || defined(__sun__)
+
+typedef struct {
+    int fd;
+    int connected;
+    int polling;
+    int read_bytes;
+    QEMUTimer *timer;
+} PtyCharDriver;
+
+static void pty_chr_update_read_handler(CharDriverState *chr);
+static void pty_chr_state(CharDriverState *chr, int connected);
+
+static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
+{
+    PtyCharDriver *s = chr->opaque;
+
+    if (!s->connected) {
+        /* guest sends data, check for (re-)connect */
+        pty_chr_update_read_handler(chr);
+        return 0;
+    }
+    return unix_write(s->fd, buf, len);
+}
+
+static int pty_chr_read_poll(void *opaque)
+{
+    CharDriverState *chr = opaque;
+    PtyCharDriver *s = chr->opaque;
+
+    s->read_bytes = qemu_chr_can_read(chr);
+    return s->read_bytes;
+}
+
+static void pty_chr_read(void *opaque)
+{
+    CharDriverState *chr = opaque;
+    PtyCharDriver *s = chr->opaque;
+    int size, len;
+    uint8_t buf[1024];
+
+    len = sizeof(buf);
+    if (len > s->read_bytes)
+        len = s->read_bytes;
+    if (len == 0)
+        return;
+    size = read(s->fd, buf, len);
+    if ((size == -1 && errno == EIO) ||
+        (size == 0)) {
+        pty_chr_state(chr, 0);
+        return;
+    }
+    if (size > 0) {
+        pty_chr_state(chr, 1);
+        qemu_chr_read(chr, buf, size);
+    }
+}
+
+static void pty_chr_update_read_handler(CharDriverState *chr)
+{
+    PtyCharDriver *s = chr->opaque;
+
+    qemu_set_fd_handler2(s->fd, pty_chr_read_poll,
+                         pty_chr_read, NULL, chr);
+    s->polling = 1;
+    /*
+     * Short timeout here: just need wait long enougth that qemu makes
+     * it through the poll loop once.  When reconnected we want a
+     * short timeout so we notice it almost instantly.  Otherwise
+     * read() gives us -EIO instantly, making pty_chr_state() reset the
+     * timeout to the normal (much longer) poll interval before the
+     * timer triggers.
+     */
+    qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 10);
+}
+
+static void pty_chr_state(CharDriverState *chr, int connected)
+{
+    PtyCharDriver *s = chr->opaque;
+
+    if (!connected) {
+        qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+        s->connected = 0;
+        s->polling = 0;
+        /* (re-)connect poll interval for idle guests: once per second.
+         * We check more frequently in case the guests sends data to
+         * the virtual device linked to our pty. */
+        qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 1000);
+    } else {
+        if (!s->connected)
+            qemu_chr_reset(chr);
+        s->connected = 1;
+    }
+}
+
+void pty_chr_timer(void *opaque)
+{
+    struct CharDriverState *chr = opaque;
+    PtyCharDriver *s = chr->opaque;
+
+    if (s->connected)
+        return;
+    if (s->polling) {
+        /* If we arrive here without polling being cleared due
+         * read returning -EIO, then we are (re-)connected */
+        pty_chr_state(chr, 1);
+        return;
+    }
+
+    /* Next poll ... */
+    pty_chr_update_read_handler(chr);
+}
+
+static void pty_chr_close(struct CharDriverState *chr)
+{
+    PtyCharDriver *s = chr->opaque;
+
+    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+    close(s->fd);
+    qemu_free(s);
+}
+
 static CharDriverState *qemu_chr_open_pty(void)
 {
+    CharDriverState *chr;
+    PtyCharDriver *s;
     struct termios tty;
-    int master_fd, slave_fd;
+    int slave_fd;
 
-    if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) < 0) {
+    chr = qemu_mallocz(sizeof(CharDriverState));
+    if (!chr)
+        return NULL;
+    s = qemu_mallocz(sizeof(PtyCharDriver));
+    if (!s) {
+        qemu_free(chr);
+        return NULL;
+    }
+
+    if (openpty(&s->fd, &slave_fd, NULL, NULL, NULL) < 0) {
         return NULL;
     }
 
     /* Set raw attributes on the pty. */
     cfmakeraw(&tty);
     tcsetattr(slave_fd, TCSAFLUSH, &tty);
+    close(slave_fd);
+
+    fprintf(stderr, "char device redirected to %s\n", ptsname(s->fd));
 
-    fprintf(stderr, "char device redirected to %s\n", ptsname(master_fd));
-    return qemu_chr_open_fd(master_fd, master_fd);
+    chr->opaque = s;
+    chr->chr_write = pty_chr_write;
+    chr->chr_update_read_handler = pty_chr_update_read_handler;
+    chr->chr_close = pty_chr_close;
+
+    s->timer = qemu_new_timer(rt_clock, pty_chr_timer, chr);
+
+    return chr;
 }
 
 static void tty_serial_init(int fd, int speed,
-- 
1.5.4.1


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-28  8:49                       ` Gerd Hoffmann
@ 2008-07-28 11:59                         ` Jamie Lokier
  2008-07-28 12:20                           ` Gerd Hoffmann
  0 siblings, 1 reply; 44+ messages in thread
From: Jamie Lokier @ 2008-07-28 11:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paul Brook

Gerd Hoffmann wrote:
> > Btw, I've just tested.  In the initial state, the tty side never
> > opened, read() blocks and poll/select report that it's not ready for
> > read.
> 
> You still don't know whenever someone is connected or not.
> And thus you still don't know whenever the stuff you write to the
> tty is read out by someone or you risk to block when the kernel
> buffer is full.

That's no different from someone connected to the tty and not reading.

Is the problem that you want qemu to block when they do that?

> Also note that openpty() which is used by qemu gives you an open file
> handle for the tty side, so there is no "tty never opened" state.

Sure, but it's easy enough to use openpt(), grantpt() and unlockpt()
instead, as described in the Glibc manual.

-- Jamie

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-28 11:59                         ` Jamie Lokier
@ 2008-07-28 12:20                           ` Gerd Hoffmann
  2017-02-01 12:33                             ` David Woodhouse
  0 siblings, 1 reply; 44+ messages in thread
From: Gerd Hoffmann @ 2008-07-28 12:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paul Brook

Jamie Lokier wrote:
> Gerd Hoffmann wrote:
>>> Btw, I've just tested.  In the initial state, the tty side never
>>> opened, read() blocks and poll/select report that it's not ready for
>>> read.
>> You still don't know whenever someone is connected or not.
>> And thus you still don't know whenever the stuff you write to the
>> tty is read out by someone or you risk to block when the kernel
>> buffer is full.
> 
> That's no different from someone connected to the tty and not reading.

Yes.

> Is the problem that you want qemu to block when they do that?

I want ptys behave as close as possible to tcp/unix sockets:

 * when nobody is connected, then don't send data.  Because we will
   block forever once the kernel buffer is full, which is bad.
 * when someone is connected, we want him get all data.  If the reader
   is too slow to keep up, that means we will block now and then, yes.
   Sockets do that too.

Additionally we can also try to drive the ptys / sockets / whatever
filehandles in non-blocking mode and try propagating the state back to
the guest so it stops writing.  That is a different issue, although
related.  IIRC the xen guys have some bits for that ...

cheers,
  Gerd

-- 
http://kraxel.fedorapeople.org/xenner/

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [Qemu-devel] Re: [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-28  9:59                   ` Gerd Hoffmann
@ 2008-07-28 18:55                     ` Anthony Liguori
  0 siblings, 0 replies; 44+ messages in thread
From: Anthony Liguori @ 2008-07-28 18:55 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel, Paul Brook

Gerd Hoffmann wrote:
> Fixed.
>
> New patch attached.
>   

Applied.   Thanks.

In the future, please post new patches as top-level posts.  It makes it 
less likely to miss them.

Regards,

Anthony Liguori

> cheers,
>   Gerd
>
>   

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd.
  2008-07-28 12:20                           ` Gerd Hoffmann
@ 2017-02-01 12:33                             ` David Woodhouse
  0 siblings, 0 replies; 44+ messages in thread
From: David Woodhouse @ 2017-02-01 12:33 UTC (permalink / raw)
  To: qemu-devel, Gerd Hoffmann; +Cc: Paul Brook

[-- Attachment #1: Type: text/plain, Size: 2447 bytes --]

(very old thread)

On Mon, 2008-07-28 at 14:20 +0200, Gerd Hoffmann wrote:
> Jamie Lokier wrote:
> > Is the problem that you want qemu to block when they do that?
> I want ptys behave as close as possible to tcp/unix sockets:
> 
>  * when nobody is connected, then don't send data.  Because we will
>    block forever once the kernel buffer is full, which is bad.
>  * when someone is connected, we want him get all data.  If the reader
>    is too slow to keep up, that means we will block now and then, yes.
>    Sockets do that too.

Hm? Sockets operate in O_NONBLOCK mode, don't they? 

If the other end stops consuming data and the kernel buffers fill up,
the serial driver ignores the resulting -EAGAIN and drops the byte.

And although it's "lossy", it's sane behaviour. It's exactly what you
get on a real RS232 serial line too; if the other end doesn't keep up
with reading the data out of its end, *it* is going to miss bytes.
That's always been the case, and I don't think we need to worry about
it.

We *certainly* shouldn't be blocking the whole guest CPU in the outb
instruction, waiting for ever for the other end to consume data. Which
is what we seem to do at the moment for PTYs.

> Additionally we can also try to drive the ptys / sockets / whatever
> filehandles in non-blocking mode and try propagating the state back to
> the guest so it stops writing.  That is a different issue, although
> related.  IIRC the xen guys have some bits for that ...

We *could*, I suppose, although as noted I'm not sure it's necessary. A
relatively easy answer might be for the serial driver to spot the
-EAGAIN and keep the byte in the transmit FIFO/register, and refrain
from reasserting THRE/TEMT until it's actually managed to send the
byte.

If we really wanted to support fully lossless serial communication, a
better option might be to implement the hardware flow control lines,
and assert CTS only when the (pty/socket/etc.) file descriptor is
writable. Then *if* the guest chooses to use hardware flow control,
that ought to work.

But I still don't think it's necessary. Can't we just make the PTY file
descriptor non-blocking, and then perhaps the monitoring logic added in
commit 279e694bc ("Attempt to detect unconnected ptys (Gerd Hoffman)")
can get simpler because it only has to poll an active device for
connectivity in the case where the write() fails.

[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 4938 bytes --]

^ permalink raw reply	[flat|nested] 44+ messages in thread

end of thread, other threads:[~2017-02-01 12:35 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-18 13:24 [Qemu-devel] [PATCH 2/3] Always use nonblocking mode for qemu_chr_open_fd Ian Jackson
2008-07-23  1:26 ` Anthony Liguori
2008-07-23  8:24   ` Daniel P. Berrange
2008-07-23 11:48     ` Gerd Hoffmann
2008-07-23 12:15       ` Daniel P. Berrange
2008-07-23 12:52         ` Gerd Hoffmann
2008-07-23 12:59           ` Daniel P. Berrange
2008-07-23 14:24           ` Gerd Hoffmann
2008-07-23 15:24             ` Anthony Liguori
2008-07-23 15:31               ` Daniel P. Berrange
2008-07-23 15:32                 ` Anthony Liguori
2008-07-23 16:17                   ` Gerd Hoffmann
2008-07-23 16:33                     ` Anthony Liguori
2008-07-23 19:08                       ` Jamie Lokier
2008-07-24  7:24                         ` Gerd Hoffmann
2008-07-24  7:54                       ` Gerd Hoffmann
2008-07-24  8:31                         ` Daniel P. Berrange
2008-07-24  9:24                         ` Jamie Lokier
2008-07-24  9:33                           ` Samuel Thibault
2008-07-24 11:18                             ` Gerd Hoffmann
2008-07-23 16:11               ` Gerd Hoffmann
2008-07-23 16:31                 ` Anthony Liguori
2008-07-24  8:35                   ` Daniel P. Berrange
2008-07-24 14:23                     ` Anthony Liguori
2008-07-24 15:07                       ` Jamie Lokier
2008-07-24 14:53                         ` Gerd Hoffmann
2008-07-23 16:44                 ` Paul Brook
2008-07-24 17:37                   ` Anthony Liguori
2008-07-25  7:15                   ` Gerd Hoffmann
2008-07-25 16:17                     ` Jamie Lokier
2008-07-28  8:49                       ` Gerd Hoffmann
2008-07-28 11:59                         ` Jamie Lokier
2008-07-28 12:20                           ` Gerd Hoffmann
2017-02-01 12:33                             ` David Woodhouse
2008-07-24 15:37             ` [Qemu-devel] " Anthony Liguori
2008-07-25 11:42               ` Gerd Hoffmann
2008-07-25 15:04                 ` Anthony Liguori
2008-07-28  9:59                   ` Gerd Hoffmann
2008-07-28 18:55                     ` Anthony Liguori
2008-07-23  9:34   ` [Qemu-devel] " Kevin Wolf
2008-07-23 10:17     ` Ian Jackson
2008-07-23 11:43       ` Kevin Wolf
2008-07-23 12:04     ` Gerd Hoffmann
2008-07-23 12:18       ` Paul Brook

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).