From fd03420c4f59d3248b80d07a302d1404ce78b09f Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 1 Mar 2017 18:13:35 +0100 Subject: [PATCH] s4/torture: some tests for kernel oplocks Bug: https://bugzilla.samba.org/show_bug.cgi?id=7537 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison --- selftest/target/Samba3.pm | 5 ++ source3/selftest/tests.py | 4 + source4/selftest/tests.py | 2 +- source4/torture/smb2/oplock.c | 140 ++++++++++++++++++++++++++++++++++ source4/torture/smb2/smb2.c | 1 + 5 files changed, 151 insertions(+), 1 deletion(-) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 775dc16207e..d754b5f9ac1 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -1860,6 +1860,11 @@ sub provision($$$$$$$$) [mangle_illegal] copy = tmp mangled names = illegal + +[kernel_oplocks] + copy = tmp + kernel oplocks = yes + vfs objects = streams_xattr xattr_tdb "; close(CONF); diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index e673bdee4ec..e386b1f8fd4 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -55,6 +55,7 @@ finally: f.close() have_libarchive = ("HAVE_LIBARCHIVE" in config_hash) +have_linux_kernel_oplocks = ("HAVE_KERNEL_OPLOCKS_LINUX" in config_hash) plantestsuite("samba3.blackbox.success", "nt4_dc:local", [os.path.join(samba3srcdir, "script/tests/test_success.sh")]) plantestsuite("samba3.blackbox.failure", "nt4_dc:local", [os.path.join(samba3srcdir, "script/tests/test_failure.sh")]) @@ -441,6 +442,9 @@ for t in tests: plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD --signing=required') elif t == "smb2.dosmode": plansmbtorture4testsuite(t, "simpleserver", '//$SERVER/dosmode -U$USERNAME%$PASSWORD') + elif t == "smb2.kernel-oplocks": + if have_linux_kernel_oplocks: + plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER/kernel_oplocks -U$USERNAME%$PASSWORD') elif t == "vfs.acl_xattr": plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD') else: diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index ac601f5f217..3786f735dd7 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -303,7 +303,7 @@ for t in nbt_tests: ntvfsargs = ["--option=torture:sharedelay=100000", "--option=torture:oplocktimeout=3", "--option=torture:writetimeupdatedelay=500000"] # Filter smb2 tests that should not run against ad_dc_ntvfs -smb2_s3only = ["smb2.change_notify_disabled", "smb2.dosmode", "smb2.credits"] +smb2_s3only = ["smb2.change_notify_disabled", "smb2.dosmode", "smb2.credits", "smb2.kernel-oplocks"] smb2 = [x for x in smbtorture4_testsuites("smb2.") if x not in smb2_s3only] #The QFILEINFO-IPC test needs to be on ipc$ diff --git a/source4/torture/smb2/oplock.c b/source4/torture/smb2/oplock.c index ead341d0eb1..53a6c18f693 100644 --- a/source4/torture/smb2/oplock.c +++ b/source4/torture/smb2/oplock.c @@ -4204,3 +4204,143 @@ bool test_smb2_hold_oplock(struct torture_context *tctx, talloc_free(mem_ctx); return true; } + + +static bool test_smb2_kernel_oplocks1(struct torture_context *tctx, + struct smb2_tree *tree) +{ + const char *fname = "test_kernel_oplock1.dat"; + NTSTATUS status; + bool ret = true; + struct smb2_create create; + struct smb2_handle h1 = {{0}}, h2 = {{0}}; + + smb2_util_unlink(tree, fname); + + tree->session->transport->oplock.handler = torture_oplock_handler; + tree->session->transport->oplock.private_data = tree; + ZERO_STRUCT(break_info); + + ZERO_STRUCT(create); + create.in.desired_access = SEC_RIGHTS_FILE_ALL; + create.in.file_attributes = FILE_ATTRIBUTE_NORMAL; + create.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + create.in.create_disposition = NTCREATEX_DISP_OPEN_IF; + create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS; + create.in.fname = fname; + create.in.oplock_level = SMB2_OPLOCK_LEVEL_EXCLUSIVE; + + status = smb2_create(tree, tctx, &create); + torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "Error opening the file\n"); + h1 = create.out.file.handle; + + torture_assert_goto(tctx, create.out.oplock_level == SMB2_OPLOCK_LEVEL_EXCLUSIVE, ret, done, + "Oplock level is not SMB2_OPLOCK_LEVEL_EXCLUSIVE\n"); + + ZERO_STRUCT(create); + create.in.desired_access = SEC_RIGHTS_FILE_ALL; + create.in.file_attributes = FILE_ATTRIBUTE_NORMAL; + create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK; + create.in.create_disposition = NTCREATEX_DISP_OPEN_IF; + create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS; + create.in.fname = fname; + + status = smb2_create(tree, tctx, &create); + torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_SHARING_VIOLATION, ret, done, + "Open didn't return NT_STATUS_SHARING_VIOLATION\n"); + h2 = create.out.file.handle; + + torture_wait_for_oplock_break(tctx); + if (break_info.count != 0) { + torture_warning(tctx, "Open caused oplock break\n"); + } + + smb2_util_close(tree, h1); + smb2_util_close(tree, h2); + +done: + if (!smb2_util_handle_empty(h1)) { + smb2_util_close(tree, h1); + } + if (!smb2_util_handle_empty(h2)) { + smb2_util_close(tree, h2); + } + smb2_util_unlink(tree, fname); + return ret; +} + +static bool test_smb2_kernel_oplocks2(struct torture_context *tctx, + struct smb2_tree *tree) +{ + const char *fname = "test_kernel_oplock2.dat"; + const char *sname = "test_kernel_oplock2.dat:foo"; + NTSTATUS status; + bool ret = true; + struct smb2_create create; + struct smb2_handle h1 = {{0}}, h2 = {{0}}; + + smb2_util_unlink(tree, fname); + + tree->session->transport->oplock.handler = torture_oplock_handler; + tree->session->transport->oplock.private_data = tree; + ZERO_STRUCT(break_info); + + ZERO_STRUCT(create); + create.in.desired_access = SEC_RIGHTS_FILE_ALL; + create.in.file_attributes = FILE_ATTRIBUTE_NORMAL; + create.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + create.in.create_disposition = NTCREATEX_DISP_OPEN_IF; + create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS; + create.in.fname = fname; + create.in.oplock_level = SMB2_OPLOCK_LEVEL_EXCLUSIVE; + + status = smb2_create(tree, tctx, &create); + torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "Error opening the file\n"); + h1 = create.out.file.handle; + + torture_assert_goto(tctx, create.out.oplock_level == SMB2_OPLOCK_LEVEL_EXCLUSIVE, ret, done, + "Oplock level is not SMB2_OPLOCK_LEVEL_EXCLUSIVE\n"); + + ZERO_STRUCT(create); + create.in.desired_access = SEC_RIGHTS_FILE_ALL; + create.in.file_attributes = FILE_ATTRIBUTE_NORMAL; + create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK; + create.in.create_disposition = NTCREATEX_DISP_OPEN_IF; + create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS; + create.in.fname = sname; + + status = smb2_create(tree, tctx, &create); + torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "Error opening the file\n"); + h2 = create.out.file.handle; + + torture_wait_for_oplock_break(tctx); + if (break_info.count != 0) { + torture_warning(tctx, "Stream open caused oplock break\n"); + } + + smb2_util_close(tree, h1); + smb2_util_close(tree, h2); + +done: + if (!smb2_util_handle_empty(h1)) { + smb2_util_close(tree, h1); + } + if (!smb2_util_handle_empty(h2)) { + smb2_util_close(tree, h2); + } + smb2_util_unlink(tree, fname); + return ret; +} + +struct torture_suite *torture_smb2_kernel_oplocks_init(void) +{ + struct torture_suite *suite = + torture_suite_create(talloc_autofree_context(), "kernel-oplocks"); + + torture_suite_add_1smb2_test(suite, "kernel_oplocks1", test_smb2_kernel_oplocks1); + torture_suite_add_1smb2_test(suite, "kernel_oplocks2", test_smb2_kernel_oplocks2); + + suite->description = talloc_strdup(suite, "SMB2-KERNEL-OPLOCK tests"); + + return suite; +} diff --git a/source4/torture/smb2/smb2.c b/source4/torture/smb2/smb2.c index 9f0f6b3be9e..9f8cbe73b05 100644 --- a/source4/torture/smb2/smb2.c +++ b/source4/torture/smb2/smb2.c @@ -163,6 +163,7 @@ NTSTATUS torture_smb2_init(void) torture_suite_add_suite(suite, torture_smb2_lease_init()); torture_suite_add_suite(suite, torture_smb2_compound_init()); torture_suite_add_suite(suite, torture_smb2_oplocks_init()); + torture_suite_add_suite(suite, torture_smb2_kernel_oplocks_init()); torture_suite_add_suite(suite, torture_smb2_streams_init()); torture_suite_add_suite(suite, torture_smb2_ioctl_init()); torture_suite_add_suite(suite, torture_smb2_rename_init()); -- 2.47.3