diff options
author | Tim Prouty <tprouty@samba.org> | 2009-12-03 13:46:11 -0800 |
---|---|---|
committer | Tim Prouty <tprouty@samba.org> | 2009-12-03 18:54:52 -0800 |
commit | 15e1c610273766a548a28b4d8731c6e9bad4496e (patch) | |
tree | 3a1fb3461555946e19b8a5b0f1af870acc3049c3 /source4/torture | |
parent | 8f7e5732ef3accd833906276f4a13891bac26726 (diff) | |
download | samba-15e1c610273766a548a28b4d8731c6e9bad4496e.tar.gz samba-15e1c610273766a548a28b4d8731c6e9bad4496e.tar.bz2 samba-15e1c610273766a548a28b4d8731c6e9bad4496e.zip |
s4 torture: Add a new RAW-OPLOCK test: BATCH26
Try a rename with a wide-open share mode on an already open file
and the there is still share mode contention. For the reason why
see:
http://social.msdn.microsoft.com/Forums/en-US/os_fileservices/thread/3ca14dc9-da1f-4786-a8f7-a86e9903db0c
Msft's anser:
After further review, The reason for server to fail with sharing
violation is that the windows server that executes a path-based
rename request opens the file for DELETE access, but only with
FILE_SHARED_READ as ShareAccess . Therefore, the existing
open(frame 76), which has shared read/write/delete , is compatible
with the Windows servers access mode (DELETE), but Windows servers
open is not compatible with access mode in existing open.
Note that it is correct to state that the logic in Windows server
could have been written to allow shared read/write/delete in which
case it would succeed as you mention. The behavior here is
historical based on the existing implementation.
Diffstat (limited to 'source4/torture')
-rw-r--r-- | source4/torture/raw/oplock.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/source4/torture/raw/oplock.c b/source4/torture/raw/oplock.c index d35445c7eb..78987e3121 100644 --- a/source4/torture/raw/oplock.c +++ b/source4/torture/raw/oplock.c @@ -2969,6 +2969,113 @@ done: return ret; } +/** + * Similar to batch17/18, but test with open share mode rather than + * share_none. + */ +static bool test_raw_oplock_batch26(struct torture_context *tctx, + struct smbcli_state *cli1, struct smbcli_state *cli2) +{ + const char *fname1 = BASEDIR "\\test_batch26_1.dat"; + const char *fname2 = BASEDIR "\\test_batch26_2.dat"; + NTSTATUS status; + bool ret = true; + union smb_open io; + union smb_rename rn; + uint16_t fnum=0; + + if (!torture_setup_dir(cli1, BASEDIR)) { + return false; + } + + /* cleanup */ + smbcli_unlink(cli1->tree, fname1); + smbcli_unlink(cli1->tree, fname2); + + smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, + cli1->tree); + + /* + base ntcreatex parms + */ + io.generic.level = RAW_OPEN_NTCREATEX; + io.ntcreatex.in.root_fid.fnum = 0; + io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + io.ntcreatex.in.create_options = 0; + io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io.ntcreatex.in.security_flags = 0; + io.ntcreatex.in.fname = fname1; + + torture_comment(tctx, "BATCH26: open a file with an batch oplock " + "(share mode: none)\n"); + + ZERO_STRUCT(break_info); + io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | + NTCREATEX_FLAGS_REQUEST_OPLOCK | + NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK; + + + status = smb_raw_open(cli1->tree, tctx, &io); + CHECK_STATUS(tctx, status, NT_STATUS_OK); + fnum = io.ntcreatex.out.file.fnum; + CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN); + + torture_comment(tctx, "rename should trigger a break\n"); + ZERO_STRUCT(rn); + rn.generic.level = RAW_RENAME_RENAME; + rn.rename.in.pattern1 = fname1; + rn.rename.in.pattern2 = fname2; + rn.rename.in.attrib = 0; + + torture_comment(tctx, "trying rename while first file open\n"); + status = smb_raw_rename(cli2->tree, &rn); + CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION); + + torture_wait_for_oplock_break(tctx); + CHECK_VAL(break_info.count, 1); + CHECK_VAL(break_info.failures, 0); + CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II); + + /* Close and reopen with batch again. */ + smbcli_close(cli1->tree, fnum); + ZERO_STRUCT(break_info); + + status = smb_raw_open(cli1->tree, tctx, &io); + CHECK_STATUS(tctx, status, NT_STATUS_OK); + fnum = io.ntcreatex.out.file.fnum; + CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN); + + /* Now try ntrename. */ + torture_comment(tctx, "ntrename should trigger a break\n"); + ZERO_STRUCT(rn); + rn.generic.level = RAW_RENAME_NTRENAME; + rn.ntrename.in.attrib = 0; + rn.ntrename.in.flags = RENAME_FLAG_RENAME; + rn.ntrename.in.old_name = fname1; + rn.ntrename.in.new_name = fname2; + torture_comment(tctx, "trying rename while first file open\n"); + status = smb_raw_rename(cli2->tree, &rn); + CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION); + + torture_wait_for_oplock_break(tctx); + CHECK_VAL(break_info.count, 1); + CHECK_VAL(break_info.failures, 0); + CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II); + + smbcli_close(cli1->tree, fnum); + +done: + smb_raw_exit(cli1->session); + smb_raw_exit(cli2->session); + smbcli_deltree(cli1->tree, BASEDIR); + return ret; +} + /* Test how oplocks work on streams. */ static bool test_raw_oplock_stream1(struct torture_context *tctx, struct smbcli_state *cli1, @@ -3557,6 +3664,7 @@ struct torture_suite *torture_raw_oplock(TALLOC_CTX *mem_ctx) torture_suite_add_2smb_test(suite, "BATCH23", test_raw_oplock_batch23); torture_suite_add_2smb_test(suite, "BATCH24", test_raw_oplock_batch24); torture_suite_add_2smb_test(suite, "BATCH25", test_raw_oplock_batch25); + torture_suite_add_2smb_test(suite, "BATCH26", test_raw_oplock_batch26); torture_suite_add_2smb_test(suite, "STREAM1", test_raw_oplock_stream1); torture_suite_add_1smb_test(suite, "DOC1", test_raw_oplock_doc); torture_suite_add_2smb_test(suite, "BRL1", test_raw_oplock_brl1); |