]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
virtio-console: Fix failure on unconnected pty
authorChristian Borntraeger <borntraeger@de.ibm.com>
Thu, 29 Dec 2011 12:47:43 +0000 (13:47 +0100)
committerAmit Shah <amit.shah@redhat.com>
Fri, 30 Dec 2011 05:40:10 +0000 (11:10 +0530)
when I tried qemu with -virtio-console pty the guest hangs and attaching
on /dev/pts/<x> does not return anything if the attachment is too late.

This results in pty_chr_write() returning 0, which causes the port to
get throttled. This results in the guest getting frozen as the
guest->host virtio_console writes don't return until the host releases
the vq element back to the guest.

For the virtio-serial use case we don't want to lose data but for the
console case we better drop data instead of "killing" the guest
console. If we get chardev->frontend notification and a better behaving
virtio-console we can revert this fix.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
hw/virtio-serial-bus.c

index fe0233f6f1c88ef7657178eae6ba324844d95794..3a9004a9b8d515db46ced5b2fb31f4e8d773cf9a 100644 (file)
@@ -163,7 +163,19 @@ static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
                 abort();
             }
             if (ret == -EAGAIN || (ret >= 0 && ret < buf_size)) {
-                virtio_serial_throttle_port(port, true);
+               /*
+                 * this is a temporary check until chardevs can signal to
+                 * frontends that they are writable again. This prevents
+                 * the console from going into throttled mode (forever)
+                 * if virtio-console is connected to a pty without a
+                 * listener. Otherwise the guest spins forever.
+                 * We can revert this if
+                 * 1: chardevs can notify frondends
+                 * 2: the guest driver does not spin in these cases
+                 */
+                if (!info->is_console) {
+                    virtio_serial_throttle_port(port, true);
+                }
                 port->iov_idx = i;
                 if (ret > 0) {
                     port->iov_offset += ret;