summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmit Shah <amit.shah@redhat.com>2010-10-20 11:33:23 +0530
committerAmit Shah <amit.shah@redhat.com>2010-10-20 11:33:23 +0530
commite5cbe2be47ca7cf5fce86da694869fc8e922d41c (patch)
tree9771554ad1f80db9c519a96ced56dde292117904
parent1565d95ef9a9256c3067cc8e8da96d2f4415b5b5 (diff)
downloadtest-virtserial-e5cbe2be47ca7cf5fce86da694869fc8e922d41c.tar.gz
test-virtserial-e5cbe2be47ca7cf5fce86da694869fc8e922d41c.tar.xz
test-virtserial-e5cbe2be47ca7cf5fce86da694869fc8e922d41c.zip
auto-test: Add test for blocking write case
This testcase writes out lots of stuff to the host without reading anything out on the host. The guest should just go wait while the host clears out all the buffers. (Some badness caused the whole guest to freeze in this case, but a patch that should make it to stable kernels do just what's required.) This testcase is very similar to the nonblocking write testcase, as they check similar things. Signed-off-by: Amit Shah <amit.shah@redhat.com>
-rw-r--r--auto-virtserial.c62
1 files changed, 61 insertions, 1 deletions
diff --git a/auto-virtserial.c b/auto-virtserial.c
index 4b346f6..df0efd6 100644
--- a/auto-virtserial.c
+++ b/auto-virtserial.c
@@ -568,9 +568,69 @@ out:
return err;
}
+/*
+ * Similar to test_nonblocking_write(): open guest port, write
+ * lots of data. We should be put to sleep once the host
+ * can't accept any more data. Then read some data from host,
+ * we should be writable again.
+ */
static int test_blocking_write(int nr)
{
- return 0;
+ void *buf;
+ unsigned int i;
+ int err, ret;
+
+ ret = guest_open_port(nr);
+ err = result(__func__, true, "guest open", ret, -1, -1, OP_GT, false);
+ if (err)
+ return err;
+
+ host_connect_chardev(nr);
+
+ /*
+ * We currently have 128 buffers in a virtqueue --
+ * hw/virtio-serial-bus.c, so this while loop should stop when
+ * i is 128. However, the loop actually stops when i is 158
+ * -- the qemu chardev itself can buffer some data.
+ */
+ for (i = 0; i < 200; i++) {
+ ret = guest_poll(nr, 0, 0);
+ if (i && ret == 0) {
+ /* vq full. Next write will block. */
+ break;
+ }
+ err = result(__func__, true, "guest poll", ret,
+ POLLOUT, POLLOUT, OP_EQ, false);
+ if (err)
+ goto out;
+
+ ret = guest_write(nr, BUF_LENGTH);
+ err = result(__func__, true, "guest write",
+ ret, BUF_LENGTH, BUF_LENGTH, OP_EQ, false);
+ if (err)
+ goto out;
+ }
+
+ buf = malloc(BUF_LENGTH);
+ for (i = 0; i < 32; i++) {
+ /*
+ * One last thing: read out some buffers from host
+ * (more than the qemu-chardev buffer limit). See if
+ * guest gets POLLOUT set.
+ */
+ read(chardevs[nr].sock, buf, BUF_LENGTH);
+ }
+ free(buf);
+
+ sleep(2);
+
+ ret = guest_poll(nr, 0, 0);
+ err = result(__func__, true, "read-poll",
+ ret, POLLOUT, POLLOUT, OP_EQ, true);
+out:
+ host_close_chardev(nr);
+ guest_close_port(nr);
+ return err;
}
static int test_nonblocking_write(int nr)