From e37ff8c5fe18d400e378bf2591e209b30473d9f9 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Sun, 28 Oct 2018 19:29:26 +0100 Subject: [PATCH] s4:torture/smb2/read: add test for cancelling SMB aio Bug: https://bugzilla.samba.org/show_bug.cgi?id=13667 Signed-off-by: Ralph Boehme Reviewed-by: Volker Lendecke Reviewed-by: Jeremy Allison --- selftest/knownfail.d/samba3.smb2 | 1 + selftest/target/Samba3.pm | 6 ++ source3/selftest/tests.py | 2 + source4/selftest/tests.py | 1 + source4/torture/smb2/read.c | 116 +++++++++++++++++++++++++++++++++++++++ source4/torture/smb2/smb2.c | 1 + 6 files changed, 127 insertions(+) create mode 100644 selftest/knownfail.d/samba3.smb2 diff --git a/selftest/knownfail.d/samba3.smb2 b/selftest/knownfail.d/samba3.smb2 new file mode 100644 index 00000000000..f4e2ecf3da4 --- /dev/null +++ b/selftest/knownfail.d/samba3.smb2 @@ -0,0 +1 @@ +^samba3.smb2.aio_delay.aio_cancel\(nt4_dc\) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index f7957cf3a7d..f8fda35366b 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -2250,6 +2250,12 @@ sub provision($$$$$$$$$) kernel oplocks = no posix locking = no include = $libdir/delay_inject.conf + +[aio_delay_inject] + copy = tmp + vfs objects = delay_inject + delay_inject:pread_send = 2000 + delay_inject:pwrite_send = 2000 "; close(CONF); diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 08395c1c096..ae569258a78 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -620,6 +620,8 @@ for t in tests: plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD') plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD') plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/streams_xattr -U$USERNAME%$PASSWORD', 'streams_xattr') + elif t == "smb2.aio_delay": + plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/aio_delay_inject -U$USERNAME%$PASSWORD') else: plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD') plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD') diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 24817e40fb5..3737efbd6c4 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -331,6 +331,7 @@ smb2_s3only = [ "smb2.credits", "smb2.kernel-oplocks", "smb2.durable-v2-delay", + "smb2.aio_delay", ] smb2 = [x for x in smbtorture4_testsuites("smb2.") if x not in smb2_s3only] diff --git a/source4/torture/smb2/read.c b/source4/torture/smb2/read.c index 4bf3bb74be0..b26bc18ddac 100644 --- a/source4/torture/smb2/read.c +++ b/source4/torture/smb2/read.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" +#include #include "torture/torture.h" #include "torture/smb2/proto.h" @@ -317,3 +318,118 @@ struct torture_suite *torture_smb2_read_init(TALLOC_CTX *ctx) return suite; } +static bool test_aio_cancel(struct torture_context *tctx, + struct smb2_tree *tree) +{ + struct smb2_handle h; + uint8_t buf[64 * 1024]; + struct smb2_read r; + struct smb2_request *req = NULL; + int rc; + NTSTATUS status; + bool ret = true; + + ZERO_STRUCT(buf); + + smb2_util_unlink(tree, FNAME); + + status = torture_smb2_testfile(tree, FNAME, &h); + torture_assert_ntstatus_ok_goto( + tctx, + status, + ret, + done, + "torture_smb2_testfile failed\n"); + + status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf)); + torture_assert_ntstatus_ok_goto( + tctx, + status, + ret, + done, + "smb2_util_write failed\n"); + + status = smb2_util_close(tree, h); + torture_assert_ntstatus_ok_goto( + tctx, + status, + ret, + done, + "smb2_util_close failed\n"); + + status = torture_smb2_testfile_access( + tree, FNAME, &h, SEC_RIGHTS_FILE_ALL); + torture_assert_ntstatus_ok_goto( + tctx, + status, + ret, + done, + "torture_smb2_testfile_access failed\n"); + + r = (struct smb2_read) { + .in.file.handle = h, + .in.length = 1, + .in.offset = 0, + .in.min_count = 1, + }; + + req = smb2_read_send(tree, &r); + torture_assert_goto( + tctx, + req != NULL, + ret, + done, + "smb2_read_send failed\n"); + + while (!req->cancel.can_cancel) { + rc = tevent_loop_once(tctx->ev); + torture_assert_goto( + tctx, + rc == 0, + ret, + done, + "tevent_loop_once failed\n"); + } + + status = smb2_cancel(req); + torture_assert_ntstatus_ok_goto( + tctx, + status, + ret, + done, + "smb2_cancel failed\n"); + + status = smb2_read_recv(req, tree, &r); + torture_assert_ntstatus_ok_goto( + tctx, + status, + ret, + done, + "smb2_read_recv failed\n"); + + status = smb2_util_close(tree, h); + torture_assert_ntstatus_ok_goto( + tctx, + status, + ret, + done, + "smb2_util_close failed\n"); + +done: + smb2_util_unlink(tree, FNAME); + return ret; +} + +/* + * aio testing against share with VFS module "delay_inject" + */ +struct torture_suite *torture_smb2_aio_delay_init(TALLOC_CTX *ctx) +{ + struct torture_suite *suite = torture_suite_create(ctx, "aio_delay"); + + torture_suite_add_1smb2_test(suite, "aio_cancel", test_aio_cancel); + + suite->description = talloc_strdup(suite, "SMB2 delayed aio tests"); + + return suite; +} diff --git a/source4/torture/smb2/smb2.c b/source4/torture/smb2/smb2.c index 12f7edf8f86..6f9884e3c27 100644 --- a/source4/torture/smb2/smb2.c +++ b/source4/torture/smb2/smb2.c @@ -152,6 +152,7 @@ NTSTATUS torture_smb2_init(TALLOC_CTX *ctx) torture_suite_add_simple_test(suite, "setinfo", torture_smb2_setinfo); torture_suite_add_suite(suite, torture_smb2_lock_init(suite)); torture_suite_add_suite(suite, torture_smb2_read_init(suite)); + torture_suite_add_suite(suite, torture_smb2_aio_delay_init(suite)); torture_suite_add_suite(suite, torture_smb2_create_init(suite)); torture_suite_add_suite(suite, torture_smb2_acls_init(suite)); torture_suite_add_suite(suite, torture_smb2_notify_init(suite)); -- 2.11.4.GIT