summaryrefslogtreecommitdiff
path: root/source4/torture/raw
diff options
context:
space:
mode:
authorSteven Danneman <steven.danneman@isilon.com>2009-09-25 16:44:51 -0700
committerSteven Danneman <steven.danneman@isilon.com>2009-09-29 19:04:36 -0700
commit8c0d239317167f127324a58c593a2c5357548ec5 (patch)
tree66458b614018356c0625490184963c49815daf03 /source4/torture/raw
parent6e4bf59d802e72f84d5fc972af6d9c28f334ca93 (diff)
downloadsamba-8c0d239317167f127324a58c593a2c5357548ec5.tar.gz
samba-8c0d239317167f127324a58c593a2c5357548ec5.tar.bz2
samba-8c0d239317167f127324a58c593a2c5357548ec5.zip
s4/torture: Allow receiving of oplock break requests in any order
Previously, the oplock torture tests, being single threaded, required the server to return oplock break requests, and other SMB packets in a specific order for us to verify "correctness". Of course, in several cases the protocol allows the break packets, especially breaks to levelII to come back in any order. With tevent we're now able to wait for oplock breaks in the middle of a torture test. I've added a helper to do this, and modified all oplock tests to allow returning of oplock breaks in any order.
Diffstat (limited to 'source4/torture/raw')
-rw-r--r--source4/torture/raw/oplock.c247
1 files changed, 159 insertions, 88 deletions
diff --git a/source4/torture/raw/oplock.c b/source4/torture/raw/oplock.c
index 581b8cdc00..6070a0a6ee 100644
--- a/source4/torture/raw/oplock.c
+++ b/source4/torture/raw/oplock.c
@@ -204,6 +204,60 @@ static bool open_connection_no_level2_oplocks(struct torture_context *tctx,
return true;
}
+/*
+ Timer handler function notifies the registering function that time is up
+*/
+static void timeout_cb(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval current_time,
+ void *private_data)
+{
+ bool *timesup = (bool *)private_data;
+ *timesup = true;
+ return;
+}
+
+/*
+ Wait a short period of time to receive a single oplock break request
+*/
+static void torture_wait_for_oplock_break(struct torture_context *tctx)
+{
+ TALLOC_CTX *tmp_ctx = talloc_new(NULL);
+ struct tevent_timer *te = NULL;
+ struct timeval ne;
+ bool timesup = false;
+ int old_count = break_info.count;
+
+ /* Wait .1 seconds for an oplock break */
+ ne = tevent_timeval_current_ofs(0, 100000);
+
+ if ((te = event_add_timed(tctx->ev, tmp_ctx, ne, timeout_cb, &timesup))
+ == NULL)
+ {
+ torture_comment(tctx, "Failed to wait for an oplock break. "
+ "test results may not be accurate.");
+ goto done;
+ }
+
+ while (!timesup && break_info.count < old_count + 1) {
+ if (event_loop_once(tctx->ev) != 0) {
+ torture_comment(tctx, "Failed to wait for an oplock "
+ "break. test results may not be "
+ "accurate.");
+ goto done;
+ }
+ }
+
+done:
+ /* We don't know if the timed event fired and was freed, we received
+ * our oplock break, or some other event triggered the loop. Thus,
+ * we create a tmp_ctx to be able to safely free/remove the timed
+ * event in all 3 cases. */
+ talloc_free(tmp_ctx);
+
+ return;
+}
+
static bool test_raw_oplock_exclusive1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
{
const char *fname = BASEDIR "\\test_exclusive1.dat";
@@ -249,6 +303,7 @@ static bool test_raw_oplock_exclusive1(struct torture_context *tctx, struct smbc
torture_comment(tctx, "a 2nd open should not cause a break\n");
status = smb_raw_open(cli2->tree, tctx, &io);
CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
CHECK_VAL(break_info.failures, 0);
@@ -257,6 +312,7 @@ static bool test_raw_oplock_exclusive1(struct torture_context *tctx, struct smbc
unl.unlink.in.attrib = 0;
status = smb_raw_unlink(cli2->tree, &unl);
CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
CHECK_VAL(break_info.failures, 0);
@@ -318,6 +374,7 @@ static bool test_raw_oplock_exclusive2(struct torture_context *tctx, struct smbc
status = smb_raw_open(cli2->tree, tctx, &io);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
fnum2 = io.ntcreatex.out.file.fnum;
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.fnum, fnum);
@@ -331,6 +388,7 @@ static bool test_raw_oplock_exclusive2(struct torture_context *tctx, struct smbc
unl.unlink.in.attrib = 0;
status = smb_raw_unlink(cli2->tree, &unl);
CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
CHECK_VAL(break_info.failures, 0);
@@ -342,10 +400,11 @@ static bool test_raw_oplock_exclusive2(struct torture_context *tctx, struct smbc
unl.unlink.in.attrib = 0;
status = smb_raw_unlink(cli2->tree, &unl);
CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
CHECK_VAL(break_info.failures, 0);
- torture_comment(tctx, "close 1st handle\n");
+ torture_comment(tctx, "close 2nd handle\n");
smbcli_close(cli2->tree, fnum2);
torture_comment(tctx, "unlink it\n");
@@ -353,6 +412,7 @@ static bool test_raw_oplock_exclusive2(struct torture_context *tctx, struct smbc
unl.unlink.in.attrib = 0;
status = smb_raw_unlink(cli2->tree, &unl);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
CHECK_VAL(break_info.failures, 0);
@@ -415,6 +475,7 @@ static bool test_raw_oplock_exclusive3(struct torture_context *tctx, struct smbc
status = smb_raw_setpathinfo(cli2->tree, &sfi);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
+ 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_NONE);
@@ -479,6 +540,7 @@ static bool test_raw_oplock_exclusive4(struct torture_context *tctx, struct smbc
CHECK_STATUS(tctx, status, NT_STATUS_OK);
fnum2 = io.ntcreatex.out.file.fnum;
CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
CHECK_VAL(break_info.failures, 0);
@@ -550,6 +612,7 @@ static bool test_raw_oplock_exclusive5(struct torture_context *tctx, struct smbc
CHECK_STATUS(tctx, status, NT_STATUS_OK);
fnum2 = io.ntcreatex.out.file.fnum;
CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.failures, 0);
@@ -620,6 +683,7 @@ static bool test_raw_oplock_exclusive6(struct torture_context *tctx, struct smbc
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, 0);
CHECK_VAL(break_info.failures, 0);
@@ -685,6 +749,7 @@ static bool test_raw_oplock_batch1(struct torture_context *tctx, struct smbcli_s
status = smb_raw_unlink(cli2->tree, &unl);
CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.fnum, fnum);
CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
@@ -695,13 +760,14 @@ static bool test_raw_oplock_batch1(struct torture_context *tctx, struct smbcli_s
status = smb_raw_unlink(cli2->tree, &unl);
CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
torture_comment(tctx, "writing should generate a self break to none\n");
smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
- msleep(100);
- smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
+ torture_wait_for_oplock_break(tctx);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.fnum, fnum);
CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
@@ -767,6 +833,7 @@ static bool test_raw_oplock_batch2(struct torture_context *tctx, struct smbcli_s
status = smb_raw_unlink(cli2->tree, &unl);
CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.fnum, fnum);
CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
@@ -777,13 +844,13 @@ static bool test_raw_oplock_batch2(struct torture_context *tctx, struct smbcli_s
status = smb_raw_unlink(cli2->tree, &unl);
CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
torture_comment(tctx, "writing should not generate a break\n");
smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
- msleep(100);
- smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
smbcli_close(cli1->tree, fnum);
@@ -845,6 +912,7 @@ static bool test_raw_oplock_batch3(struct torture_context *tctx, struct smbcli_s
status = smb_raw_unlink(cli2->tree, &unl);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.fnum, fnum);
CHECK_VAL(break_info.level, 1);
@@ -911,6 +979,7 @@ static bool test_raw_oplock_batch4(struct torture_context *tctx, struct smbcli_s
rd.read.in.remaining = 0;
status = smb_raw_read(cli1->tree, &rd);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
CHECK_VAL(break_info.failures, 0);
@@ -973,6 +1042,7 @@ static bool test_raw_oplock_batch5(struct torture_context *tctx, struct smbcli_s
status = smb_raw_open(cli2->tree, tctx, &io);
CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.fnum, fnum);
CHECK_VAL(break_info.level, 1);
@@ -1004,6 +1074,7 @@ static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_s
smbcli_unlink(cli1->tree, fname);
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
+ smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
/*
base ntcreatex parms
@@ -1022,8 +1093,6 @@ static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_s
torture_comment(tctx, "BATCH6: a 2nd open should give a break to level II if the first open allowed shared read\n");
ZERO_STRUCT(break_info);
- smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
- smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
@@ -1042,6 +1111,7 @@ static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_s
fnum2 = io.ntcreatex.out.file.fnum;
CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
+ //torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.fnum, fnum);
CHECK_VAL(break_info.level, 1);
@@ -1050,8 +1120,10 @@ static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_s
torture_comment(tctx, "write should trigger a break to none on both\n");
smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
- msleep(100);
- smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
+
+ /* We expect two breaks */
+ torture_wait_for_oplock_break(tctx);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 2);
CHECK_VAL(break_info.level, 0);
@@ -1060,7 +1132,6 @@ static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_s
smbcli_close(cli1->tree, fnum);
smbcli_close(cli2->tree, fnum2);
-
done:
smb_raw_exit(cli1->session);
smb_raw_exit(cli2->session);
@@ -1124,11 +1195,12 @@ static bool test_raw_oplock_batch7(struct torture_context *tctx, struct smbcli_s
fnum = io.ntcreatex.out.file.fnum;
CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.fnum, fnum2);
CHECK_VAL(break_info.level, 1);
CHECK_VAL(break_info.failures, 0);
-
+
smbcli_close(cli2->tree, fnum);
done:
@@ -1193,6 +1265,7 @@ static bool test_raw_oplock_batch8(struct torture_context *tctx, struct smbcli_s
CHECK_STATUS(tctx, status, NT_STATUS_OK);
fnum2 = io.ntcreatex.out.file.fnum;
CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
CHECK_VAL(break_info.failures, 0);
@@ -1264,6 +1337,7 @@ static bool test_raw_oplock_batch9(struct torture_context *tctx, struct smbcli_s
status = smb_raw_open(cli2->tree, tctx, &io);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
fnum2 = io.ntcreatex.out.file.fnum;
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.fnum, fnum);
CHECK_VAL(break_info.failures, 0);
@@ -1283,6 +1357,7 @@ static bool test_raw_oplock_batch9(struct torture_context *tctx, struct smbcli_s
status = smb_raw_open(cli2->tree, tctx, &io);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
fnum2 = io.ntcreatex.out.file.fnum;
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
CHECK_VAL(break_info.failures, 0);
CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
@@ -1292,11 +1367,9 @@ static bool test_raw_oplock_batch9(struct torture_context *tctx, struct smbcli_s
torture_comment(tctx, "write should trigger a break to none on both\n");
smbcli_write(cli2->tree, fnum2, 0, &c, 0, 1);
- /* Now the oplock break request comes in. But right now we can't
- * answer it. Do another write */
-
- msleep(100);
- smbcli_write(cli2->tree, fnum2, 0, &c, 1, 1);
+ /* We expect two breaks */
+ torture_wait_for_oplock_break(tctx);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 2);
CHECK_VAL(break_info.level, 0);
@@ -1354,6 +1427,7 @@ static bool test_raw_oplock_batch10(struct torture_context *tctx, struct smbcli_
status = smb_raw_open(cli1->tree, tctx, &io);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
fnum = io.ntcreatex.out.file.fnum;
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
CHECK_VAL(break_info.failures, 0);
CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
@@ -1371,6 +1445,7 @@ static bool test_raw_oplock_batch10(struct torture_context *tctx, struct smbcli_
status = smb_raw_open(cli2->tree, tctx, &io);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
fnum2 = io.ntcreatex.out.file.fnum;
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
CHECK_VAL(break_info.failures, 0);
CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
@@ -1388,22 +1463,7 @@ static bool test_raw_oplock_batch10(struct torture_context *tctx, struct smbcli_
CHECK_STATUS(tctx, status, NT_STATUS_OK);
}
- /* Now the oplock break request comes in. But right now we can't
- * answer it. Do another write */
-
- msleep(100);
-
- {
- union smb_write wr;
- wr.write.level = RAW_WRITE_WRITE;
- wr.write.in.file.fnum = fnum;
- wr.write.in.count = 1;
- wr.write.in.offset = 0;
- wr.write.in.remaining = 0;
- wr.write.in.data = (const uint8_t *)"x";
- status = smb_raw_write(cli1->tree, &wr);
- CHECK_STATUS(tctx, status, NT_STATUS_OK);
- }
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.fnum, fnum2);
@@ -1457,10 +1517,9 @@ static bool test_raw_oplock_batch11(struct torture_context *tctx, struct smbcli_
torture_comment(tctx, "BATCH11: Test if setpathinfo set EOF breaks oplocks.\n");
ZERO_STRUCT(break_info);
- smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
- NTCREATEX_FLAGS_REQUEST_OPLOCK |
+ NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
@@ -1470,18 +1529,20 @@ static bool test_raw_oplock_batch11(struct torture_context *tctx, struct smbcli_
status = smb_raw_open(cli1->tree, tctx, &io);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
fnum = io.ntcreatex.out.file.fnum;
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
CHECK_VAL(break_info.failures, 0);
CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
-
+
ZERO_STRUCT(sfi);
sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
sfi.generic.in.file.path = fname;
sfi.end_of_file_info.in.size = 100;
status = smb_raw_setpathinfo(cli2->tree, &sfi);
-
CHECK_STATUS(tctx, status, NT_STATUS_OK);
+
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.failures, 0);
CHECK_VAL(break_info.level, 0);
@@ -1535,7 +1596,7 @@ static bool test_raw_oplock_batch12(struct torture_context *tctx, struct smbcli_
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
- NTCREATEX_FLAGS_REQUEST_OPLOCK |
+ NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
@@ -1545,18 +1606,20 @@ static bool test_raw_oplock_batch12(struct torture_context *tctx, struct smbcli_
status = smb_raw_open(cli1->tree, tctx, &io);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
fnum = io.ntcreatex.out.file.fnum;
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
CHECK_VAL(break_info.failures, 0);
CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
-
+
ZERO_STRUCT(sfi);
sfi.generic.level = SMB_SFILEINFO_ALLOCATION_INFORMATION;
sfi.generic.in.file.path = fname;
sfi.allocation_info.in.alloc_size = 65536 * 8;
status = smb_raw_setpathinfo(cli2->tree, &sfi);
-
CHECK_STATUS(tctx, status, NT_STATUS_OK);
+
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.failures, 0);
CHECK_VAL(break_info.level, 0);
@@ -1605,8 +1668,6 @@ static bool test_raw_oplock_batch13(struct torture_context *tctx, struct smbcli_
torture_comment(tctx, "BATCH13: open with batch oplock\n");
ZERO_STRUCT(break_info);
- smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
-
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
@@ -1634,6 +1695,7 @@ static bool test_raw_oplock_batch13(struct torture_context *tctx, struct smbcli_
status = smb_raw_open(cli2->tree, tctx, &io);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
fnum2 = io.ntcreatex.out.file.fnum;
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.failures, 0);
@@ -1682,7 +1744,6 @@ static bool test_raw_oplock_batch14(struct torture_context *tctx, struct smbcli_
torture_comment(tctx, "BATCH14: open with batch oplock\n");
ZERO_STRUCT(break_info);
- smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
@@ -1711,6 +1772,8 @@ static bool test_raw_oplock_batch14(struct torture_context *tctx, struct smbcli_
CHECK_STATUS(tctx, status, NT_STATUS_OK);
fnum2 = io.ntcreatex.out.file.fnum;
CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
+
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.failures, 0);
@@ -1760,7 +1823,6 @@ static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_
torture_comment(tctx, "BATCH15: Test if qpathinfo all info breaks a batch oplock (should not).\n");
ZERO_STRUCT(break_info);
- smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
@@ -1774,6 +1836,8 @@ static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_
status = smb_raw_open(cli1->tree, tctx, &io);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
fnum = io.ntcreatex.out.file.fnum;
+
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
CHECK_VAL(break_info.failures, 0);
CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
@@ -1783,8 +1847,9 @@ static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_
qfi.generic.in.file.path = fname;
status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
-
CHECK_STATUS(tctx, status, NT_STATUS_OK);
+
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
smbcli_close(cli1->tree, fnum);
@@ -1831,8 +1896,6 @@ static bool test_raw_oplock_batch16(struct torture_context *tctx, struct smbcli_
torture_comment(tctx, "BATCH16: open with batch oplock\n");
ZERO_STRUCT(break_info);
- smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
-
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
@@ -1861,6 +1924,8 @@ static bool test_raw_oplock_batch16(struct torture_context *tctx, struct smbcli_
CHECK_STATUS(tctx, status, NT_STATUS_OK);
fnum2 = io.ntcreatex.out.file.fnum;
CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
+
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.failures, 0);
@@ -1930,8 +1995,9 @@ static bool test_raw_oplock_batch17(struct torture_context *tctx, struct smbcli_
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);
@@ -2001,8 +2067,9 @@ static bool test_raw_oplock_batch18(struct torture_context *tctx, struct smbcli_
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);
@@ -2073,8 +2140,9 @@ static bool test_raw_oplock_batch19(struct torture_context *tctx, struct smbcli_
sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
status = smb_raw_setpathinfo(cli2->tree, &sfi);
-
CHECK_STATUS(tctx, status, NT_STATUS_OK);
+
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
ZERO_STRUCT(qfi);
@@ -2095,6 +2163,8 @@ static bool test_raw_oplock_batch19(struct torture_context *tctx, struct smbcli_
status = smb_raw_setfileinfo(cli1->tree, &sfi);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
+
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
ZERO_STRUCT(qfi);
@@ -2177,6 +2247,8 @@ bool test_trans2rename(struct torture_context *tctx, struct smbcli_state *cli1,
status = smb_raw_setpathinfo(cli2->tree, &sfi);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
+
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
ZERO_STRUCT(qfi);
@@ -2197,6 +2269,8 @@ bool test_trans2rename(struct torture_context *tctx, struct smbcli_state *cli1,
status = smb_raw_setfileinfo(cli1->tree, &sfi);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
+
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
ZERO_STRUCT(qfi);
@@ -2274,8 +2348,9 @@ bool test_nttransrename(struct torture_context *tctx, struct smbcli_state *cli1)
rn.nttrans.in.new_name = fname2+strlen(BASEDIR)+1;
status = smb_raw_rename(cli1->tree, &rn);
-
CHECK_STATUS(tctx, status, NT_STATUS_OK);
+
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
/* w2k3 does nothing, it doesn't rename the file */
@@ -2400,8 +2475,9 @@ static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_
sfi.rename_information.in.new_name = fname2+strlen(BASEDIR)+1;
status = smb_raw_setpathinfo(cli2->tree, &sfi);
-
CHECK_STATUS(tctx, status, NT_STATUS_OK);
+
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
ZERO_STRUCT(qfi);
@@ -2425,6 +2501,8 @@ static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_
CHECK_STATUS(tctx, status, NT_STATUS_OK);
fnum2 = io.ntcreatex.out.file.fnum;
CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
+
+ 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);
@@ -2439,6 +2517,8 @@ static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_
status = smb_raw_setfileinfo(cli1->tree, &sfi);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
+
+ 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);
@@ -2526,6 +2606,7 @@ static bool test_raw_oplock_batch21(struct torture_context *tctx, struct smbcli_
status = smb_raw_echo(cli1->transport, &e);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
smbcli_close(cli1->tree, fnum);
@@ -2598,6 +2679,7 @@ static bool test_raw_oplock_batch22(struct torture_context *tctx, struct smbcli_
smbcli_oplock_handler(cli1->transport, oplock_handler_timeout, cli1->tree);
status = smb_raw_open(cli1->tree, tctx, &io);
CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
+ torture_wait_for_oplock_break(tctx);
te = (int)timeval_elapsed(&tv);
CHECK_RANGE(te, timeout - 1, timeout + 15);
@@ -2614,6 +2696,7 @@ static bool test_raw_oplock_batch22(struct torture_context *tctx, struct smbcli_
status = smb_raw_open(cli1->tree, tctx, &io);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
+ torture_wait_for_oplock_break(tctx);
te = (int)timeval_elapsed(&tv);
/* it should come in without delay */
CHECK_RANGE(te+1, 0, timeout);
@@ -2647,11 +2730,13 @@ static bool test_raw_oplock_batch23(struct torture_context *tctx, struct smbcli_
/* cleanup */
smbcli_unlink(cli1->tree, fname);
- smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
-
ret = open_connection_no_level2_oplocks(tctx, &cli3);
CHECK_VAL(ret, true);
+ smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
+ smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
+ smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
+
/*
base ntcreatex parms
*/
@@ -2669,9 +2754,6 @@ static bool test_raw_oplock_batch23(struct torture_context *tctx, struct smbcli_
torture_comment(tctx, "BATCH23: a open and ask for a batch oplock\n");
ZERO_STRUCT(break_info);
- smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
- smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
- smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
@@ -2691,6 +2773,7 @@ static bool test_raw_oplock_batch23(struct torture_context *tctx, struct smbcli_
fnum3 = io.ntcreatex.out.file.fnum;
CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.fnum, fnum);
CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
@@ -2704,6 +2787,7 @@ static bool test_raw_oplock_batch23(struct torture_context *tctx, struct smbcli_
fnum2 = io.ntcreatex.out.file.fnum;
CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
smbcli_close(cli1->tree, fnum);
@@ -2734,11 +2818,13 @@ static bool test_raw_oplock_batch24(struct torture_context *tctx, struct smbcli_
/* cleanup */
smbcli_unlink(cli1->tree, fname);
- smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
-
ret = open_connection_no_level2_oplocks(tctx, &cli3);
CHECK_VAL(ret, true);
+ smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
+ smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
+ smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
+
/*
base ntcreatex parms
*/
@@ -2756,9 +2842,6 @@ static bool test_raw_oplock_batch24(struct torture_context *tctx, struct smbcli_
torture_comment(tctx, "BATCH24: a open without level support and ask for a batch oplock\n");
ZERO_STRUCT(break_info);
- smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
- smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
- smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
@@ -2778,6 +2861,7 @@ static bool test_raw_oplock_batch24(struct torture_context *tctx, struct smbcli_
fnum2 = io.ntcreatex.out.file.fnum;
CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.fnum, fnum3);
CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
@@ -2850,8 +2934,9 @@ static bool test_raw_oplock_batch25(struct torture_context *tctx,
sfi.setattr.in.write_time = 0;
status = smb_raw_setpathinfo(cli2->tree, &sfi);
-
CHECK_STATUS(tctx, status, NT_STATUS_OK);
+
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
smbcli_close(cli1->tree, fnum);
@@ -2920,8 +3005,8 @@ static bool test_raw_oplock_stream1(struct torture_context *tctx,
}
smbcli_unlink(cli1->tree, fname_base);
- smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
+ smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
/* Setup generic open parameters. */
io.generic.level = RAW_OPEN_NTCREATEX;
@@ -3006,6 +3091,7 @@ static bool test_raw_oplock_stream1(struct torture_context *tctx,
BATCH_OPLOCK_RETURN);
smbcli_close(cli2->tree, io.ntcreatex.out.file.fnum);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
CHECK_VAL(break_info.failures, 0);
@@ -3021,6 +3107,7 @@ static bool test_raw_oplock_stream1(struct torture_context *tctx,
LEVEL_II_OPLOCK_RETURN);
smbcli_close(cli2->tree, io.ntcreatex.out.file.fnum);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
CHECK_VAL(break_info.failures, 0);
@@ -3162,8 +3249,6 @@ static bool test_raw_oplock_brl1(struct torture_context *tctx,
torture_comment(tctx, "a 2nd open should give a break\n");
ZERO_STRUCT(break_info);
- smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
- cli1->tree);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
status = smb_raw_open(cli2->tree, tctx, &io);
@@ -3175,19 +3260,13 @@ static bool test_raw_oplock_brl1(struct torture_context *tctx,
CHECK_VAL(break_info.fnum, fnum);
ZERO_STRUCT(break_info);
- smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
- cli1->tree);
- torture_comment(tctx, "attempt BRL test\n");
+ torture_comment(tctx, "a self BRL acquisition should break to none\n");
status = smbcli_lock(cli1->tree, fnum, 0, 4, 0, WRITE_LOCK);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
- /*
- * Even though level 2 oplock breaks are asynchronous, with self
- * contention we'll always break the oplock before the contending
- * operation's response is sent.
- */
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
CHECK_VAL(break_info.fnum, fnum);
@@ -3198,6 +3277,7 @@ static bool test_raw_oplock_brl1(struct torture_context *tctx,
status = smbcli_lock(cli1->tree, fnum, 2, 4, 0, WRITE_LOCK);
CHECK_STATUS(tctx, status, NT_STATUS_LOCK_NOT_GRANTED);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
CHECK_VAL(break_info.level, 0);
CHECK_VAL(break_info.fnum, 0);
@@ -3280,10 +3360,8 @@ static bool test_raw_oplock_brl2(struct torture_context *tctx, struct smbcli_sta
goto done;
}
- smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
- cli1->tree);
-
- torture_comment(tctx, "attempt BRL test\n");
+ torture_comment(tctx, "a self BRL acquisition should not break to "
+ "none\n");
status = smbcli_lock(cli1->tree, fnum, 0, 4, 0, WRITE_LOCK);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
@@ -3294,6 +3372,7 @@ static bool test_raw_oplock_brl2(struct torture_context *tctx, struct smbcli_sta
/* With one file handle open a BRL should not contend our oplock.
* Thus, no oplock break will be received and the entire break_info
* struct will be 0 */
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.fnum, 0);
CHECK_VAL(break_info.count, 0);
CHECK_VAL(break_info.level, 0);
@@ -3375,8 +3454,6 @@ static bool test_raw_oplock_brl3(struct torture_context *tctx,
torture_comment(tctx, "a 2nd open should give a break\n");
ZERO_STRUCT(break_info);
- smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
- cli1->tree);
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
status = smb_raw_open(cli1->tree, tctx, &io);
@@ -3388,19 +3465,13 @@ static bool test_raw_oplock_brl3(struct torture_context *tctx,
CHECK_VAL(break_info.fnum, fnum);
ZERO_STRUCT(break_info);
- smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given,
- cli1->tree);
- torture_comment(tctx, "attempt BRL test\n");
+ torture_comment(tctx, "a self BRL acquisition should break to none\n");
status = smbcli_lock(cli1->tree, fnum, 0, 4, 0, WRITE_LOCK);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
- /*
- * Even though level 2 oplock breaks are asynchrounous, with self
- * contention we'll always break the oplock before the contending
- * operation's response is sent.
- */
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 1);
CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
CHECK_VAL(break_info.fnum, fnum);
@@ -3411,6 +3482,7 @@ static bool test_raw_oplock_brl3(struct torture_context *tctx,
status = smbcli_lock(cli1->tree, fnum, 2, 4, 0, WRITE_LOCK);
CHECK_STATUS(tctx, status, NT_STATUS_LOCK_NOT_GRANTED);
+ torture_wait_for_oplock_break(tctx);
CHECK_VAL(break_info.count, 0);
CHECK_VAL(break_info.level, 0);
CHECK_VAL(break_info.fnum, 0);
@@ -3423,7 +3495,6 @@ done:
smb_raw_exit(cli1->session);
smbcli_deltree(cli1->tree, BASEDIR);
return ret;
-
}
/*