diff options
Diffstat (limited to 'lib9p/tests')
-rw-r--r-- | lib9p/tests/test_server/CMakeLists.txt | 2 | ||||
-rw-r--r-- | lib9p/tests/test_server/config/config.h | 2 | ||||
-rw-r--r-- | lib9p/tests/test_server/fs_flush.c | 136 | ||||
-rw-r--r-- | lib9p/tests/test_server/fs_flush.h | 27 | ||||
-rw-r--r-- | lib9p/tests/test_server/fs_slowread.c | 116 | ||||
-rw-r--r-- | lib9p/tests/test_server/fs_slowread.h | 22 | ||||
-rw-r--r-- | lib9p/tests/test_server/main.c | 11 | ||||
-rwxr-xr-x | lib9p/tests/testclient-p9p | 7 | ||||
-rw-r--r-- | lib9p/tests/testclient-p9p.explog | 4 | ||||
-rw-r--r-- | lib9p/tests/testclient-sess.c | 45 | ||||
-rw-r--r-- | lib9p/tests/testclient-sess.explog | 59 |
11 files changed, 264 insertions, 167 deletions
diff --git a/lib9p/tests/test_server/CMakeLists.txt b/lib9p/tests/test_server/CMakeLists.txt index b659373..c61d344 100644 --- a/lib9p/tests/test_server/CMakeLists.txt +++ b/lib9p/tests/test_server/CMakeLists.txt @@ -9,8 +9,8 @@ if (PICO_PLATFORM STREQUAL "host") add_library(test_server_objs OBJECT main.c + fs_flush.c fs_shutdown.c - fs_slowread.c fs_whoami.c ) target_include_directories(test_server_objs PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/config) diff --git a/lib9p/tests/test_server/config/config.h b/lib9p/tests/test_server/config/config.h index acaa3da..f49894b 100644 --- a/lib9p/tests/test_server/config/config.h +++ b/lib9p/tests/test_server/config/config.h @@ -22,6 +22,8 @@ /* 9P_SRV *********************************************************************/ +#define CONFIG_9P_SRV_DEBUG 1 /* bool */ + /** * This max-msg-size is sized so that a Twrite message can return * 8KiB of data. diff --git a/lib9p/tests/test_server/fs_flush.c b/lib9p/tests/test_server/fs_flush.c new file mode 100644 index 0000000..779eb91 --- /dev/null +++ b/lib9p/tests/test_server/fs_flush.c @@ -0,0 +1,136 @@ +/* lib9p/tests/test_server/fs_flush.c - flush-* API endpoints + * + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include <libmisc/alloc.h> + +#define IMPLEMENTATION_FOR_LIB9P_SRV_H YES /* for ctx->flush_ch */ +#include "fs_flush.h" + +LO_IMPLEMENTATION_C(lib9p_srv_file, struct flush_file, flush_file, static); + +struct flush_fio { + struct flush_file *parent; +}; +LO_IMPLEMENTATION_H(lib9p_srv_fio, struct flush_fio, flush_fio); +LO_IMPLEMENTATION_C(lib9p_srv_fio, struct flush_fio, flush_fio, static); + +/* srv_file *******************************************************************/ + +static void flush_file_free(struct flush_file *self) { + assert(self); +} +static struct lib9p_qid flush_file_qid(struct flush_file *self) { + assert(self); + return (struct lib9p_qid){ + .type = LIB9P_QT_FILE, + .vers = 1, + .path = self->pathnum, + }; +} + +static struct lib9p_stat flush_file_stat(struct flush_file *self, struct lib9p_srv_ctx *ctx) { + assert(self); + assert(ctx); + return (struct lib9p_stat){ + .kern_type = 0, + .kern_dev = 0, + .file_qid = flush_file_qid(self), + .file_mode = 0444, + .file_atime = UTIL9P_ATIME, + .file_mtime = UTIL9P_MTIME, + .file_size = 6, + .file_name = lib9p_str(self->name), + .file_owner_uid = lib9p_str("root"), + .file_owner_gid = lib9p_str("root"), + .file_last_modified_uid = lib9p_str("root"), + .file_extension = lib9p_str(NULL), + .file_owner_n_uid = 0, + .file_owner_n_gid = 0, + .file_last_modified_n_uid = 0, + }; +} +static void flush_file_wstat(struct flush_file *self, struct lib9p_srv_ctx *ctx, struct lib9p_stat) { + assert(self); + assert(ctx); + lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "cannot wstat API file"); +} +static void flush_file_remove(struct flush_file *self, struct lib9p_srv_ctx *ctx) { + assert(self); + assert(ctx); + lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "cannot remove API file"); +} + +LIB9P_SRV_NOTDIR(struct flush_file, flush_file) + +static lo_interface lib9p_srv_fio flush_file_fopen(struct flush_file *self, struct lib9p_srv_ctx *ctx, bool, bool, bool) { + assert(self); + assert(ctx); + + struct flush_fio *ret = heap_alloc(1, struct flush_fio); + ret->parent = self; + + return lo_box_flush_fio_as_lib9p_srv_fio(ret); +} + +/* srv_fio ********************************************************************/ + +static void flush_fio_iofree(struct flush_fio *self) { + assert(self); + free(self); +} + +static struct lib9p_qid flush_fio_qid(struct flush_fio *self) { + assert(self); + return flush_file_qid(self->parent); +} + +static uint32_t flush_fio_iounit(struct flush_fio *self) { + assert(self); + return 0; +} + +static uint32_t flush_fio_pwrite(struct flush_fio *LM_UNUSED(self), + struct lib9p_srv_ctx *LM_UNUSED(ctx), + void *LM_UNUSED(buf), uint32_t LM_UNUSED(byte_count), + uint64_t LM_UNUSED(offset)) { + assert_notreached("not writable"); +} + +static void flush_fio_pread(struct flush_fio *self, struct lib9p_srv_ctx *ctx, + uint32_t byte_count, uint64_t LM_UNUSED(byte_offset), + struct iovec *ret) { + assert(self); + assert(ctx); + assert(ret); + + /* Wait for first Tflush */ + while (!lib9p_srv_flush_requested(ctx)) + cr_yield(); + + /* Wait for the specified number of Tflush (may be higher *or* + * lower than 1; lower would mean that the first Tflush needs + * to be flushed itself). */ + while (cr_chan_num_waiters(&ctx->flush_ch) != self->parent->flush_cnt) + cr_yield(); + + /* Return */ + switch (self->parent->flush_behavior) { + case FLUSH_READ: + *ret = (struct iovec){ + .iov_base = "Sloth\n", + .iov_len = 6 < byte_count ? 6 : byte_count, + }; + break; + case FLUSH_ERROR: + lib9p_srv_acknowledge_flush(ctx); + lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_ECANCELED, "request canceled by flush"); + break; + case FLUSH_SILENT: + lib9p_srv_acknowledge_flush(ctx); + break; + } + cr_yield(); +} diff --git a/lib9p/tests/test_server/fs_flush.h b/lib9p/tests/test_server/fs_flush.h new file mode 100644 index 0000000..a509c4a --- /dev/null +++ b/lib9p/tests/test_server/fs_flush.h @@ -0,0 +1,27 @@ +/* lib9p/tests/test_server/fs_flush.h - flush-* API endpoints + * + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#ifndef _LIB9P_TESTS_TEST_SERVER_FS_FLUSH_H_ +#define _LIB9P_TESTS_TEST_SERVER_FS_FLUSH_H_ + +#include <util9p/static.h> +#include <libhw/host_net.h> + +struct flush_file { + char *name; + uint64_t pathnum; + + unsigned int flush_cnt; + enum { + FLUSH_READ, + FLUSH_ERROR, + FLUSH_SILENT, + } flush_behavior; +}; +LO_IMPLEMENTATION_H(lib9p_srv_file, struct flush_file, flush_file); +#define lo_box_flush_file_as_lib9p_srv_file(obj) util9p_box(flush_file, obj) + +#endif /* _LIB9P_TESTS_TEST_SERVER_FS_FLUSH_H_ */ diff --git a/lib9p/tests/test_server/fs_slowread.c b/lib9p/tests/test_server/fs_slowread.c deleted file mode 100644 index 4567fef..0000000 --- a/lib9p/tests/test_server/fs_slowread.c +++ /dev/null @@ -1,116 +0,0 @@ -/* lib9p/tests/test_server/fs_slowread.c - slowread API endpoint - * - * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -#include <libmisc/alloc.h> - -#include "fs_slowread.h" - -LO_IMPLEMENTATION_C(lib9p_srv_file, struct slowread_file, slowread_file, static); - -struct slowread_fio { - struct slowread_file *parent; -}; -LO_IMPLEMENTATION_H(lib9p_srv_fio, struct slowread_fio, slowread_fio); -LO_IMPLEMENTATION_C(lib9p_srv_fio, struct slowread_fio, slowread_fio, static); - -/* srv_file *******************************************************************/ - -static void slowread_file_free(struct slowread_file *self) { - assert(self); -} -static struct lib9p_qid slowread_file_qid(struct slowread_file *self) { - assert(self); - return (struct lib9p_qid){ - .type = LIB9P_QT_FILE, - .vers = 1, - .path = self->pathnum, - }; -} - -static struct lib9p_stat slowread_file_stat(struct slowread_file *self, struct lib9p_srv_ctx *ctx) { - assert(self); - assert(ctx); - return (struct lib9p_stat){ - .kern_type = 0, - .kern_dev = 0, - .file_qid = slowread_file_qid(self), - .file_mode = 0444, - .file_atime = UTIL9P_ATIME, - .file_mtime = UTIL9P_MTIME, - .file_size = 6, - .file_name = lib9p_str(self->name), - .file_owner_uid = lib9p_str("root"), - .file_owner_gid = lib9p_str("root"), - .file_last_modified_uid = lib9p_str("root"), - .file_extension = lib9p_str(NULL), - .file_owner_n_uid = 0, - .file_owner_n_gid = 0, - .file_last_modified_n_uid = 0, - }; -} -static void slowread_file_wstat(struct slowread_file *self, struct lib9p_srv_ctx *ctx, struct lib9p_stat) { - assert(self); - assert(ctx); - lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "cannot wstat API file"); -} -static void slowread_file_remove(struct slowread_file *self, struct lib9p_srv_ctx *ctx) { - assert(self); - assert(ctx); - lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "cannot remove API file"); -} - -LIB9P_SRV_NOTDIR(struct slowread_file, slowread_file) - -static lo_interface lib9p_srv_fio slowread_file_fopen(struct slowread_file *self, struct lib9p_srv_ctx *ctx, bool, bool, bool) { - assert(self); - assert(ctx); - - struct slowread_fio *ret = heap_alloc(1, struct slowread_fio); - ret->parent = self; - - return lo_box_slowread_fio_as_lib9p_srv_fio(ret); -} - -/* srv_fio ********************************************************************/ - -static void slowread_fio_iofree(struct slowread_fio *self) { - assert(self); - free(self); -} - -static struct lib9p_qid slowread_fio_qid(struct slowread_fio *self) { - assert(self); - return slowread_file_qid(self->parent); -} - -static uint32_t slowread_fio_iounit(struct slowread_fio *self) { - assert(self); - return 0; -} - -static uint32_t slowread_fio_pwrite(struct slowread_fio *LM_UNUSED(self), - struct lib9p_srv_ctx *LM_UNUSED(ctx), - void *LM_UNUSED(buf), uint32_t LM_UNUSED(byte_count), - uint64_t LM_UNUSED(offset)) { - assert_notreached("not writable"); -} -static void slowread_fio_pread(struct slowread_fio *self, struct lib9p_srv_ctx *ctx, - uint32_t byte_count, uint64_t LM_UNUSED(byte_offset), - struct iovec *ret) { - assert(self); - assert(ctx); - assert(ret); - - while (!lib9p_srv_flush_requested(ctx)) - cr_yield(); - if (self->parent->flushable) - lib9p_srv_acknowledge_flush(ctx); - else - *ret = (struct iovec){ - .iov_base = "Sloth\n", - .iov_len = 6 < byte_count ? 6 : byte_count, - }; -} diff --git a/lib9p/tests/test_server/fs_slowread.h b/lib9p/tests/test_server/fs_slowread.h deleted file mode 100644 index ef4b65f..0000000 --- a/lib9p/tests/test_server/fs_slowread.h +++ /dev/null @@ -1,22 +0,0 @@ -/* lib9p/tests/test_server/fs_slowread.h - slowread API endpoint - * - * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -#ifndef _LIB9P_TESTS_TEST_SERVER_FS_SLOWREAD_H_ -#define _LIB9P_TESTS_TEST_SERVER_FS_SLOWREAD_H_ - -#include <util9p/static.h> -#include <libhw/host_net.h> - -struct slowread_file { - char *name; - uint64_t pathnum; - - bool flushable; -}; -LO_IMPLEMENTATION_H(lib9p_srv_file, struct slowread_file, slowread_file); -#define lo_box_slowread_file_as_lib9p_srv_file(obj) util9p_box(slowread_file, obj) - -#endif /* _LIB9P_TESTS_TEST_SERVER_FS_SLOWREAD_H_ */ diff --git a/lib9p/tests/test_server/main.c b/lib9p/tests/test_server/main.c index 0705747..d7819eb 100644 --- a/lib9p/tests/test_server/main.c +++ b/lib9p/tests/test_server/main.c @@ -19,8 +19,8 @@ #include <util9p/static.h> #include "static.h" +#include "fs_flush.h" #include "fs_shutdown.h" -#include "fs_slowread.h" #include "fs_whoami.h" /* configuration **************************************************************/ @@ -76,11 +76,12 @@ struct lib9p_srv_file root = API_FILE(5, "shutdown", shutdown, .listeners = globals.listeners, .nlisteners = LM_ARRAY_LEN(globals.listeners)), - API_FILE(6, "slowread", slowread, - .flushable = false), - API_FILE(7, "slowread-flushable", slowread, - .flushable = true), API_FILE(8, "whoami", whoami), + API_FILE(9, "flush-read", flush, .flush_cnt=1, .flush_behavior=FLUSH_READ), + API_FILE(10, "flush-error", flush, .flush_cnt=1, .flush_behavior=FLUSH_ERROR), + API_FILE(11, "flush-silent", flush, .flush_cnt=1, .flush_behavior=FLUSH_SILENT), + API_FILE(12, "flush-slowsilent", flush, .flush_cnt=2, .flush_behavior=FLUSH_SILENT), + API_FILE(13, "flush-slowread", flush, .flush_cnt=0, .flush_behavior=FLUSH_READ), ); static lo_interface lib9p_srv_file get_root(struct lib9p_srv_ctx *LM_UNUSED(ctx), struct lib9p_s LM_UNUSED(treename)) { diff --git a/lib9p/tests/testclient-p9p b/lib9p/tests/testclient-p9p index 9c9fb5e..9c9f9f2 100755 --- a/lib9p/tests/testclient-p9p +++ b/lib9p/tests/testclient-p9p @@ -25,9 +25,12 @@ out=$("${client[@]}" ls -l '') expect_lines \ 'd-r-xr-xr-x M 0 root root 0 Oct 7 2024 Documentation' \ '--r--r--r-- M 0 root root 166 Oct 7 2024 README.md' \ + '--r--r--r-- M 0 root root 6 Oct 7 2024 flush-error' \ + '--r--r--r-- M 0 root root 6 Oct 7 2024 flush-read' \ + '--r--r--r-- M 0 root root 6 Oct 7 2024 flush-silent' \ + '--r--r--r-- M 0 root root 6 Oct 7 2024 flush-slowread' \ + '--r--r--r-- M 0 root root 6 Oct 7 2024 flush-slowsilent' \ '---w--w--w- M 0 root root 0 Oct 7 2024 shutdown' \ - '--r--r--r-- M 0 root root 6 Oct 7 2024 slowread' \ - '--r--r--r-- M 0 root root 6 Oct 7 2024 slowread-flushable' \ '--r--r--r-- M 0 root root 9 Oct 7 2024 whoami' out=$("${client[@]}" ls -l 'Documentation/') diff --git a/lib9p/tests/testclient-p9p.explog b/lib9p/tests/testclient-p9p.explog index e5901d2..7f3953d 100644 --- a/lib9p/tests/testclient-p9p.explog +++ b/lib9p/tests/testclient-p9p.explog @@ -19,8 +19,8 @@ > Topen { tag=0 fid=1 mode=(MODE_READ) } < Ropen { tag=0 qid={ type=(DIR) vers=1 path=1 } iounit=0 } > Tread { tag=0 fid=1 offset=0 count=4096 } -< Rread { tag=0 count=428 data=<bytedata> } -> Tread { tag=0 fid=1 offset=428 count=4096 } +< Rread { tag=0 count=648 data=<bytedata> } +> Tread { tag=0 fid=1 offset=648 count=4096 } < Rread { tag=0 count=0 data="" } > Tclunk { tag=0 fid=1 } < Rclunk { tag=0 } diff --git a/lib9p/tests/testclient-sess.c b/lib9p/tests/testclient-sess.c index ded70d1..561c0c9 100644 --- a/lib9p/tests/testclient-sess.c +++ b/lib9p/tests/testclient-sess.c @@ -170,29 +170,62 @@ int main(int argc, char *argv[]) { recv9p(); /* Rattach */ /* flush, but original response comes back first */ - wname[0] = lib9p_str("slowread"); send9p(Twalk, .tag=0, .fid=0, .newfid=1, .nwname=1, .wname=wname); + wname[0] = lib9p_str("flush-read"); send9p(Twalk, .tag=0, .fid=0, .newfid=1, .nwname=1, .wname=wname); recv9p(); /* Rwalk */ send9p(Topen, .tag=0, .fid=1, .mode=LIB9P_O_MODE_READ); recv9p(); /* Ropen */ - send9p(Tread, .tag=1, .fid=1, .offset=0, .count=6); - send9p(Tflush, .tag=2, .oldtag=1); + send9p(Tread, .tag=0, .fid=1, .offset=0, .count=10); + send9p(Tflush, .tag=1, .oldtag=0); recv9p(); /* Rread */ recv9p(); /* Rflush */ /* flush, original request is aborted with error */ - wname[0] = lib9p_str("slowread-flushable"); send9p(Twalk, .tag=1, .fid=0, .newfid=2, .nwname=1, .wname=wname); + wname[0] = lib9p_str("flush-error"); send9p(Twalk, .tag=0, .fid=0, .newfid=2, .nwname=1, .wname=wname); recv9p(); /* Rwalk */ send9p(Topen, .tag=0, .fid=2, .mode=LIB9P_O_MODE_READ); recv9p(); /* Ropen */ - send9p(Tread, .tag=1, .fid=2, .offset=0, .count=6); - send9p(Tflush, .tag=2, .oldtag=1); + send9p(Tread, .tag=0, .fid=2, .offset=0, .count=10); + send9p(Tflush, .tag=1, .oldtag=0); recv9p(); /* Rerror */ recv9p(); /* Rflush */ + /* flush, original request is aborted without error */ + wname[0] = lib9p_str("flush-silent"); send9p(Twalk, .tag=0, .fid=0, .newfid=3, .nwname=1, .wname=wname); + recv9p(); /* Rwalk */ + send9p(Topen, .tag=0, .fid=3, .mode=LIB9P_O_MODE_READ); + recv9p(); /* Ropen */ + send9p(Tread, .tag=0, .fid=3, .offset=0, .count=10); + send9p(Tflush, .tag=1, .oldtag=0); + recv9p(); /* Rflush */ + + /* multiflush, original request is aborted without error */ + wname[0] = lib9p_str("flush-slowsilent"); send9p(Twalk, .tag=0, .fid=0, .newfid=4, .nwname=1, .wname=wname); + recv9p(); /* Rwalk */ + send9p(Topen, .tag=0, .fid=4, .mode=LIB9P_O_MODE_READ); + recv9p(); /* Ropen */ + send9p(Tread, .tag=0, .fid=4, .offset=0, .count=10); + send9p(Tflush, .tag=1, .oldtag=0); + send9p(Tflush, .tag=2, .oldtag=0); + recv9p(); /* Rflush */ + + /* flush, but flush is flushed */ + wname[0] = lib9p_str("flush-slowread"); send9p(Twalk, .tag=0, .fid=0, .newfid=5, .nwname=1, .wname=wname); + recv9p(); /* Rwalk */ + send9p(Topen, .tag=0, .fid=5, .mode=LIB9P_O_MODE_READ); + recv9p(); /* Ropen */ + send9p(Tread, .tag=0, .fid=5, .offset=0, .count=10); + send9p(Tflush, .tag=1, .oldtag=0); + send9p(Tflush, .tag=2, .oldtag=1); + recv9p(); /* Rflush */ + recv9p(); /* Rread */ + /* flush, unknown tag */ send9p(Tflush, .tag=0, .oldtag=99); recv9p(); /* Rflush */ + /* flushed by Tversion */ + send9p(Tread, .tag=0, .fid=3, .offset=0, .count=10); + /* shutdown ***********************************************************/ send9p(Tversion, .tag=0, .max_msg_size=(8*1024), .version=lib9p_str("9P2000")); recv9p(); /* Rversion */ diff --git a/lib9p/tests/testclient-sess.explog b/lib9p/tests/testclient-sess.explog index 3e2209a..74a2cd7 100644 --- a/lib9p/tests/testclient-sess.explog +++ b/lib9p/tests/testclient-sess.explog @@ -87,29 +87,62 @@ < Rattach { tag=0 qid={ type=(DIR) vers=1 path=1 } } # flush, but original response comes back first -> Twalk { tag=0 fid=0 newfid=1 nwname=1 wname=[ "slowread" ] } -< Rwalk { tag=0 nwqid=1 wqid=[ { type=(0) vers=1 path=6 } ] } +> Twalk { tag=0 fid=0 newfid=1 nwname=1 wname=[ "flush-read" ] } +< Rwalk { tag=0 nwqid=1 wqid=[ { type=(0) vers=1 path=9 } ] } > Topen { tag=0 fid=1 mode=(MODE_READ) } -< Ropen { tag=0 qid={ type=(0) vers=1 path=6 } iounit=0 } -> Tread { tag=1 fid=1 offset=0 count=6 } -> Tflush { tag=2 oldtag=1 } -< Rread { tag=1 count=6 data="Sloth\n" } +< Ropen { tag=0 qid={ type=(0) vers=1 path=9 } iounit=0 } +> Tread { tag=0 fid=1 offset=0 count=10 } +> Tflush { tag=1 oldtag=0 } +< Rread { tag=0 count=6 data="Sloth\n" } +< Rflush { tag=1 } + +# flush, original request is aborted with error +> Twalk { tag=0 fid=0 newfid=2 nwname=1 wname=[ "flush-error" ] } +< Rwalk { tag=0 nwqid=1 wqid=[ { type=(0) vers=1 path=10 } ] } +> Topen { tag=0 fid=2 mode=(MODE_READ) } +< Ropen { tag=0 qid={ type=(0) vers=1 path=10 } iounit=0 } +> Tread { tag=0 fid=2 offset=0 count=10 } +> Tflush { tag=1 oldtag=0 } +< Rerror { tag=0 errstr="request canceled by flush" errnum=L_ECANCELED } +< Rflush { tag=1 } + +# flush, original request is aborted without error +> Twalk { tag=0 fid=0 newfid=3 nwname=1 wname=[ "flush-silent" ] } +< Rwalk { tag=0 nwqid=1 wqid=[ { type=(0) vers=1 path=11 } ] } +> Topen { tag=0 fid=3 mode=(MODE_READ) } +< Ropen { tag=0 qid={ type=(0) vers=1 path=11 } iounit=0 } +> Tread { tag=0 fid=3 offset=0 count=10 } +> Tflush { tag=1 oldtag=0 } +< Rflush { tag=1 } + +# multiflush, original request is aborted without error +> Twalk { tag=0 fid=0 newfid=4 nwname=1 wname=[ "flush-slowsilent" ] } +< Rwalk { tag=0 nwqid=1 wqid=[ { type=(0) vers=1 path=12 } ] } +> Topen { tag=0 fid=4 mode=(MODE_READ) } +< Ropen { tag=0 qid={ type=(0) vers=1 path=12 } iounit=0 } +> Tread { tag=0 fid=4 offset=0 count=10 } +> Tflush { tag=1 oldtag=0 } +> Tflush { tag=2 oldtag=0 } < Rflush { tag=2 } -# flush, succeeds -> Twalk { tag=1 fid=0 newfid=2 nwname=1 wname=[ "slowread-flushable" ] } -< Rwalk { tag=1 nwqid=1 wqid=[ { type=(0) vers=1 path=7 } ] } -> Topen { tag=0 fid=2 mode=(MODE_READ) } -< Ropen { tag=0 qid={ type=(0) vers=1 path=7 } iounit=0 } -> Tread { tag=1 fid=2 offset=0 count=6 } +# flush, but flush is flushed +> Twalk { tag=0 fid=0 newfid=5 nwname=1 wname=[ "flush-slowread" ] } +< Rwalk { tag=0 nwqid=1 wqid=[ { type=(0) vers=1 path=13 } ] } +> Topen { tag=0 fid=5 mode=(MODE_READ) } +< Ropen { tag=0 qid={ type=(0) vers=1 path=13 } iounit=0 } +> Tread { tag=0 fid=5 offset=0 count=10 } +> Tflush { tag=1 oldtag=0 } > Tflush { tag=2 oldtag=1 } < Rflush { tag=2 } -< Rerror { tag=1 errstr="request canceled by flush" errnum=L_ECANCELED } +< Rread { tag=0 count=6 data="Sloth\n" } # flush, unknown tag > Tflush { tag=0 oldtag=99 } < Rflush { tag=0 } +# flushed by Tversion +> Tread { tag=0 fid=3 offset=0 count=10 } + # shutdown ##################################################################### > Tversion { tag=0 max_msg_size=8192 version="9P2000" } < Rversion { tag=0 max_msg_size=4120 version="9P2000" } |