summaryrefslogtreecommitdiff
path: root/hw/9pfs
diff options
context:
space:
mode:
authorGreg Kurz <groug@kaod.org>2018-02-01 21:21:28 +0100
committerGreg Kurz <groug@kaod.org>2018-02-02 11:11:55 +0100
commit357e2f7f4e4dc68f01d5b81f5cd669874314e14a (patch)
tree77a200e760142625271e2b69c79e510eb25f6f9f /hw/9pfs
parentbe3a6781605803b2c48a48135002869ed2c73cf1 (diff)
downloadqemu-357e2f7f4e4dc68f01d5b81f5cd669874314e14a.tar.gz
tests: virtio-9p: add FLUSH operation test
The idea is to send a victim request that will possibly block in the server and to send a flush request to cancel the victim request. This patch adds two test to verifiy that: - the server does not reply to a victim request that was actually cancelled - the server replies to the flush request after replying to the victim request if it could not cancel it 9p request cancellation reference: http://man.cat-v.org/plan_9/5/flush Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> (groug, change the test to only write a single byte to avoid any alignment or endianess consideration)
Diffstat (limited to 'hw/9pfs')
-rw-r--r--hw/9pfs/9p-synth.c20
-rw-r--r--hw/9pfs/9p-synth.h7
-rw-r--r--hw/9pfs/9p.c1
3 files changed, 28 insertions, 0 deletions
diff --git a/hw/9pfs/9p-synth.c b/hw/9pfs/9p-synth.c
index ade3460706..18082dffe8 100644
--- a/hw/9pfs/9p-synth.c
+++ b/hw/9pfs/9p-synth.c
@@ -521,6 +521,20 @@ static ssize_t v9fs_synth_qtest_write(void *buf, int len, off_t offset,
return 1;
}
+static ssize_t v9fs_synth_qtest_flush_write(void *buf, int len, off_t offset,
+ void *arg)
+{
+ bool should_block = !!*(uint8_t *)buf;
+
+ if (should_block) {
+ /* This will cause the server to call us again until we're cancelled */
+ errno = EINTR;
+ return -1;
+ }
+
+ return 1;
+}
+
static int synth_init(FsContext *ctx, Error **errp)
{
QLIST_INIT(&synth_root.child);
@@ -557,6 +571,12 @@ static int synth_init(FsContext *ctx, Error **errp)
ret = qemu_v9fs_synth_add_file(NULL, 0, QTEST_V9FS_SYNTH_WRITE_FILE,
NULL, v9fs_synth_qtest_write, ctx);
assert(!ret);
+
+ /* File for FLUSH test */
+ ret = qemu_v9fs_synth_add_file(NULL, 0, QTEST_V9FS_SYNTH_FLUSH_FILE,
+ NULL, v9fs_synth_qtest_flush_write,
+ ctx);
+ assert(!ret);
}
return 0;
diff --git a/hw/9pfs/9p-synth.h b/hw/9pfs/9p-synth.h
index a74032d7bd..af7a993a1e 100644
--- a/hw/9pfs/9p-synth.h
+++ b/hw/9pfs/9p-synth.h
@@ -55,4 +55,11 @@ int qemu_v9fs_synth_add_file(V9fsSynthNode *parent, int mode,
#define QTEST_V9FS_SYNTH_LOPEN_FILE "LOPEN"
#define QTEST_V9FS_SYNTH_WRITE_FILE "WRITE"
+/* Any write to the "FLUSH" file is handled one byte at a time by the
+ * backend. If the byte is zero, the backend returns success (ie, 1),
+ * otherwise it forces the server to try again forever. Thus allowing
+ * the client to cancel the request.
+ */
+#define QTEST_V9FS_SYNTH_FLUSH_FILE "FLUSH"
+
#endif
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index e88bb50f13..85a1ed8171 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -24,6 +24,7 @@
#include "coth.h"
#include "trace.h"
#include "migration/blocker.h"
+#include "sysemu/qtest.h"
int open_fd_hw;
int total_open_fd;