Bug 624628

Summary: read from virtio-serial returns if the host side is not connect to pipe
Product: Red Hat Enterprise Linux 6 Reporter: Gal Hammer <ghammer>
Component: kernelAssignee: Amit Shah <amit.shah>
Status: CLOSED ERRATA QA Contact: Virtualization Bugs <virt-bugs>
Severity: medium Docs Contact:
Priority: high    
Version: 6.0CC: bazulay, cpelland, dhoward, gyue, llim, mkenneth, plyons, tburke, virt-maint, vrozenfe
Target Milestone: rcKeywords: ZStream
Target Release: 6.1   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: kernel-2.6.32-85.el6 Doc Type: Bug Fix
Doc Text:
Prior to this update, a guest could use the poll() function to find out whether the host-side connection was open or closed. However, with a SIGIO signal, this can be done asynchronously, without having to explicitly poll each port. With this update, a SIGIO signal is sent for any host connect/disconnect events. Once the SIGIO signal is received, the open/close status of virtio-serial ports can be obtained using the poll() system call.
Story Points: ---
Clone Of:
: 636053 (view as bug list) Environment:
Last Closed: 2011-05-19 12:54:13 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 580954, 636053, 652720    

Description Gal Hammer 2010-08-17 09:59:58 UTC
Read from virtio-serial should block if data is available even if no one is connected to the pipe on the host side. Without it application running inside the guest is entering a busy-loop while reading nothing.

How reproducible:

Host: $ nc -U rhel6-virtio.org.linux-kvm.port.0

Guest: $ cat < /dev/vport0p0

Host: (close nc)

Guest: (exit cat and return to command prompt)

Comment 2 Amit Shah 2010-08-18 06:30:31 UTC
(In reply to comment #0)
> Read from virtio-serial should block if data is available even if no one is
> connected to the pipe on the host side. Without it application running inside
> the guest is entering a busy-loop while reading nothing.

You should use 'poll' inside the guest app to await data for read (POLLIN) instead of busy-looping.

There's nothing wrong with returning 0 (EOF) when the host-side connection of the pipe is closed.

This isn't really a bug.

I'll close this if there's no objection.

Comment 3 Gal Hammer 2010-08-18 07:22:22 UTC
(In reply to comment #2)

> You should use 'poll' inside the guest app to await data for read (POLLIN)
> instead of busy-looping.

I'm not sure 'poll' is supported when working with Python on Windows platform. Will 'poll' will block until the host is connected and wrote something to the pipe?
 
> There's nothing wrong with returning 0 (EOF) when the host-side connection of
> the pipe is closed.

What value will you return if the host-side connection is a socket? You might not be aware to the fact that no one is connected, right?
 
> I'll close this if there's no objection.

You have my objection, but since I open the bug I'm not really objective :-).

Comment 4 Amit Shah 2010-08-18 07:54:05 UTC
(In reply to comment #3)
> (In reply to comment #2)
> 
> > You should use 'poll' inside the guest app to await data for read (POLLIN)
> > instead of busy-looping.
> 
> I'm not sure 'poll' is supported when working with Python on Windows platform.
> Will 'poll' will block until the host is connected and wrote something to the
> pipe?

poll (or even read or write) will block only if host is connected. If host is disconnected, there's no blocking, since you've reached EOF.

If it doesn't work this way, it's either a bug in the virtio-serial Windows guest driver or the way your program works with python.

> > There's nothing wrong with returning 0 (EOF) when the host-side connection of
> > the pipe is closed.
> 
> What value will you return if the host-side connection is a socket? You might
> not be aware to the fact that no one is connected, right?

We're always aware. We (qemu) get to know when a host-side agent is connected or disconnected (well, there's a bug in the disconnect state, but it's a bug, not something we can't know about).

> > I'll close this if there's no objection.
> 
> You have my objection, but since I open the bug I'm not really objective :-).

Well, as far as I can see, things are working just the way they're supposed to.

Comment 5 Gal Hammer 2010-08-18 08:04:31 UTC
(In reply to comment #4)

> poll (or even read or write) will block only if host is connected. If host is
> disconnected, there's no blocking, since you've reached EOF.

So we're back to busy-waiting. If I can't block on either read (or poll) I can't tell from guest side when the host is connected to the virtio channel.
 
> If it doesn't work this way, it's either a bug in the virtio-serial Windows
> guest driver or the way your program works with python.

The behavior is the same when running Linux guest.
 
> We're always aware. We (qemu) get to know when a host-side agent is connected
> or disconnected (well, there's a bug in the disconnect state, but it's a bug,
> not something we can't know about).

I'll take a another look in the 'write' behavior.
 
> Well, as far as I can see, things are working just the way they're supposed to.

They are not working as I expect. :-P

Comment 6 Amit Shah 2010-08-18 09:01:29 UTC
(In reply to comment #5)
> (In reply to comment #4)
> 
> > poll (or even read or write) will block only if host is connected. If host is
> > disconnected, there's no blocking, since you've reached EOF.
> 
> So we're back to busy-waiting. If I can't block on either read (or poll) I
> can't tell from guest side when the host is connected to the virtio channel.

OK; I can do a couple of things, as they're done for TCP sockets:
- send a SIGIO when the host-side connection is opened/closed
- allow poll to block even if the host-side connection is closed and return POLLIN when the connection is established.

The second option mentioned above only works for async IO on TCP sockets, but since we don't have a connect()-like call, we can extend poll() to return POLLIN on peer connection.

Comment 7 Dor Laor 2010-08-18 10:22:44 UTC
How about a new verb like accept/connect() ?
Amit, I think we need to provide full documentation for usage of virtio-serial, both from the guest and from the host as well as all the semantics and test cases (that should follow for each of them).

Comment 8 Amit Shah 2010-08-26 04:48:37 UTC
I've added SIGIO support for ports in the guest: you should install a SIGIO handler and set the O_ASYNC flag via fcntl() for the port you are interested in receiving connect/disconnect events.

Once you get a SIGIO signal, you can poll() all your ports in the signal handler to find out which port got opened or closed.

You will also receive a SIGIO when input becomes available, so you need not poll() for POLLIN.

poll() will still return POLLHUP for unconnected hosts since that's the only way of knowing whether a host-side connection is up or down.

The patch will be posted upstream in a bit and will be proposed for 6.1.

To see how to enable this functionality in a guest app, see

http://fedorapeople.org/gitweb?p=amitshah/public_git/test-virtserial.git;a=commitdiff;h=fa6dce3c8cfe718a0ed54e08d6ae384c5185ca6c

For more tests relating to the new SIGIO signal, see

http://fedorapeople.org/gitweb?p=amitshah/public_git/test-virtserial.git;a=commitdiff;h=af6f49a6cf54cdf76531eba26e605a9a1503d185

http://fedorapeople.org/gitweb?p=amitshah/public_git/test-virtserial.git;a=commitdiff;h=5c468270518dac6fd083f7527ae3a9992d154f0f

Comment 11 RHEL Program Management 2010-10-08 07:40:16 UTC
This request was evaluated by Red Hat Product Management for inclusion
in a Red Hat Enterprise Linux maintenance release. Product Management has 
requested further review of this request by Red Hat Engineering, for potential
inclusion in a Red Hat Enterprise Linux Update release for currently deployed 
products. This request is not yet committed for inclusion in an Update release.

Comment 12 Barak 2010-10-08 21:02:27 UTC
Was it tested also on windows guest?

Comment 19 Aristeu Rozanski 2010-12-13 15:14:28 UTC
Patch(es) available on kernel-2.6.32-89.el6

Comment 23 Amit Shah 2011-01-19 09:27:36 UTC
(In reply to comment #22)
> Hi Amit,
> 
> Can you please provide the steps to verify?

See comment 8 for what was done and how to verify.

Comment 25 Martin Prpič 2011-02-23 15:04:00 UTC
    Technical note added. If any revisions are required, please edit the "Technical Notes" field
    accordingly. All revisions will be proofread by the Engineering Content Services team.
    
    New Contents:
Prior to this update, a guest could use the poll() function to find out whether the host-side connection was open or closed. However, with a SIGIO signal, this can be done asynchronously, without having to explicitly poll each port. With this update, a SIGIO signal is sent for any host connect/disconnect events. Once the SIGIO signal is received, the open/close status of virtio-serial ports can be obtained using the poll() system call.

Comment 26 errata-xmlrpc 2011-05-19 12:54:13 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on therefore solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHSA-2011-0542.html