Features/ChardevFlowControl: Difference between revisions
(→Testing: Add named-pipe backend testing instructions) |
|||
Line 12: | Line 12: | ||
To reproduce a guest freeze on releases without the patches for this feature, invoke QEMU and perform the tests as noted in the two cases below. The examples use the unix backend, but other backends, like udp, tcp, pty exhibit similar behaviour, and should be tested as well. | To reproduce a guest freeze on releases without the patches for this feature, invoke QEMU and perform the tests as noted in the two cases below. The examples use the unix backend, but other backends, like udp, tcp, pty exhibit similar behaviour, and should be tested as well. | ||
=== Start QEMU with chardev in server mode === | === Start QEMU with UNIX chardev in server mode === | ||
<pre> | <pre> | ||
Line 42: | Line 42: | ||
</pre> | </pre> | ||
=== Start QEMU with chardev in client mode === | === Start QEMU with UNIX chardev in client mode === | ||
<pre> | <pre> | ||
Line 60: | Line 60: | ||
<pre> | <pre> | ||
# echo foo > /dev/virtio-ports/test0 | # echo foo > /dev/virtio-ports/test0 | ||
</pre> | |||
=== Named pipe backend === | |||
* Create named pipe | |||
<pre> | |||
[host]# mkfifo /tmp/serial0 | |||
</pre> | |||
* Boot up a single-CPU guest with a virtio-serial device and named-pipe chardev backend | |||
<pre> | |||
[host]# qemu-kvm -enable-kvm -m 1024 -nographic \ | |||
-device virtio-serial-pci -chardev pipe,id=ch0,path=/tmp/serial0 | |||
-device virtserialport,chardev=ch0,name=serial0 \ | |||
-drive file=disk.img,if=virtio,boot=on | |||
</pre> | |||
* Run a background work on the guest | |||
<pre> | |||
[guest]# while :;do sleep 1; date; done & | |||
</pre> | |||
* Write lots of data to the virtio-serial port; the guest should not freeze. | |||
<pre> | |||
[guest]# cat /proc/kallsyms > /dev/virtio-ports/serial0 | |||
</pre> | |||
* Confirm the guest does not freeze even if there's no reader process in the host | |||
* Read the named-pipe file on the host | |||
<pre> | |||
[host]# cat /tmp/serial0 | |||
</pre> | </pre> | ||
Revision as of 06:22, 26 February 2013
Summary
The chardev layer in QEMU did not have any mechanism for flow-control. This meant that a fast guest could pump data to the host (via virtio-serial, for example), and if the host-side reader was slow to consume data, or didn't consume data at all, the guest would freeze. This is resolved by converting the char layer to use the GLib IO loop.
Status
Patches are still under review and discussion, but intended to be merged for the 1.5 release. The main code exists in Anthony's 'char-flow' branches (latest is v3): https://github.com/aliguori/qemu/commits/char-flow.3.
Testing
To reproduce a guest freeze on releases without the patches for this feature, invoke QEMU and perform the tests as noted in the two cases below. The examples use the unix backend, but other backends, like udp, tcp, pty exhibit similar behaviour, and should be tested as well.
Start QEMU with UNIX chardev in server mode
./x86_64-softmmu/qemu-system-x86_64 -m 512 \ /guests/f14-nolvm.qcow2 -snapshot -enable-kvm \ -chardev socket,path=/tmp/foo,server,nowait,id=foo \ -device virtio-serial -device virtserialport,chardev=foo,id=test0,nr=2 \ -monitor stdio
On the host, open the chardev but don't read from it, e.g.
$ python Python 2.7.3 (default, Aug 9 2012, 17:23:57) [GCC 4.7.1 20120720 (Red Hat 4.7.1-5)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import socket >>> >>> sock = socket.socket(socket.AF_UNIX) >>> sock.connect("/tmp/foo") >>>
and in the guest, write to the virtio-serial port, e.g.
# dd if=/dev/zero of=/dev/virtio-ports/test0
Start QEMU with UNIX chardev in client mode
./x86_64-softmmu/qemu-system-x86_64 -m 512 /guests/f14-nolvm.qcow2 \ -snapshot -enable-kvm -chardev socket,path=/tmp/foo,id=foo \ -device virtio-serial -device virtserialport,chardev=foo,id=test0,nr=2 \ -monitor stdio
on the host, start a listening process, like:
$ socat UNIX-LISTEN:/tmp/foo -
and in the guest,
# echo foo > /dev/virtio-ports/test0
Named pipe backend
- Create named pipe
[host]# mkfifo /tmp/serial0
- Boot up a single-CPU guest with a virtio-serial device and named-pipe chardev backend
[host]# qemu-kvm -enable-kvm -m 1024 -nographic \ -device virtio-serial-pci -chardev pipe,id=ch0,path=/tmp/serial0 -device virtserialport,chardev=ch0,name=serial0 \ -drive file=disk.img,if=virtio,boot=on
- Run a background work on the guest
[guest]# while :;do sleep 1; date; done &
- Write lots of data to the virtio-serial port; the guest should not freeze.
[guest]# cat /proc/kallsyms > /dev/virtio-ports/serial0
- Confirm the guest does not freeze even if there's no reader process in the host
- Read the named-pipe file on the host
[host]# cat /tmp/serial0
Known bugs
These are the bugs in the implementation known so far:
- QEMU doesn't catch -EPIPE for short-lived guest processes and disconnected host chardevs. This is also described in https://bugzilla.redhat.com/show_bug.cgi?id=621484. To reproduce this issue, use the following steps:
- start qemu, boot guest
- connect netcat to the unix socket
- echo some chars to /dev/virtio-ports/$name
- watch them appear in netcat
- stop netcat, restart it
- echo some chars again
- watch them *not* appear
- Gerd's open-write-close test:
for seq in $(seq 1 100); do echo "test $seq" > /dev/virtio-ports/org.kraxel.test; sleep 1; done
- Gerd's keep-device-open test:
(for seq in $(seq 1 100); do echo "test $seq"; sleep 1; done) > /dev/virtio-ports/org.kraxel.test
- The bug triggers only with open-write-close.