summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/torture/torture.c128
1 files changed, 96 insertions, 32 deletions
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index a28078fe9d..f2fad4988c 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -3577,21 +3577,21 @@ static bool run_oplock3(int dummy)
/* What are we looking for here? What's sucess and what's FAILURE? */
}
-/* handler for oplock 4 tests */
-bool *oplock4_shared_correct;
+struct oplock4_state {
+ struct tevent_context *ev;
+ struct cli_state *cli;
+ bool *got_break;
+ uint16_t *fnum2;
+};
-static NTSTATUS oplock4_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
-{
- printf("got oplock break fnum=%d level=%d\n",
- fnum, level);
- *oplock4_shared_correct = true;
- cli_oplock_ack(cli, fnum, level);
- return NT_STATUS_UNSUCCESSFUL; /* Cause cli_receive_smb to return. */
-}
+static void oplock4_got_break(struct tevent_req *req);
+static void oplock4_got_open(struct tevent_req *req);
static bool run_oplock4(int dummy)
{
+ struct tevent_context *ev;
struct cli_state *cli1, *cli2;
+ struct tevent_req *oplock_req, *open_req;
const char *fname = "\\lockt4.lck";
const char *fname_ln = "\\lockt4_ln.lck";
uint16_t fnum1, fnum2;
@@ -3599,8 +3599,9 @@ static bool run_oplock4(int dummy)
NTSTATUS status;
bool correct = true;
- oplock4_shared_correct = (bool *)shm_setup(sizeof(bool));
- *oplock4_shared_correct = false;
+ bool got_break;
+
+ struct oplock4_state *state;
printf("starting oplock test 4\n");
@@ -3675,36 +3676,62 @@ static bool run_oplock4(int dummy)
cli2->use_oplocks = true;
cli2->use_level_II_oplocks = true;
- cli_oplock_handler(cli1, oplock4_handler);
-
status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
if (!NT_STATUS_IS_OK(status)) {
printf("open of %s failed (%s)\n", fname, nt_errstr(status));
return false;
}
- if (fork() == 0) {
- /* Child code */
- status = cli_open(cli2, fname_ln, O_RDWR, DENY_NONE, &fnum2);
- if (!NT_STATUS_IS_OK(status)) {
- printf("open of %s failed (%s)\n", fname_ln, nt_errstr(status));
- *oplock4_shared_correct = false;
- exit(0);
- }
+ ev = tevent_context_init(talloc_tos());
+ if (ev == NULL) {
+ printf("tevent_req_create failed\n");
+ return false;
+ }
- status = cli_close(cli2, fnum2);
- if (!NT_STATUS_IS_OK(status)) {
- printf("close2 failed (%s)\n", nt_errstr(status));
- *oplock4_shared_correct = false;
- }
+ state = talloc(ev, struct oplock4_state);
+ if (state == NULL) {
+ printf("talloc failed\n");
+ return false;
+ }
+ state->ev = ev;
+ state->cli = cli1;
+ state->got_break = &got_break;
+ state->fnum2 = &fnum2;
+
+ oplock_req = cli_smb_oplock_break_waiter_send(
+ talloc_tos(), ev, cli1);
+ if (oplock_req == NULL) {
+ printf("cli_smb_oplock_break_waiter_send failed\n");
+ return false;
+ }
+ tevent_req_set_callback(oplock_req, oplock4_got_break, state);
- exit(0);
+ open_req = cli_open_send(
+ talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
+ if (oplock_req == NULL) {
+ printf("cli_open_send failed\n");
+ return false;
}
+ tevent_req_set_callback(open_req, oplock4_got_open, state);
- sleep(2);
+ got_break = false;
+ fnum2 = 0xffff;
- /* Process the oplock break. */
- cli_receive_smb(cli1);
+ while (!got_break || fnum2 == 0xffff) {
+ int ret;
+ ret = tevent_loop_once(ev);
+ if (ret == -1) {
+ printf("tevent_loop_once failed: %s\n",
+ strerror(errno));
+ return false;
+ }
+ }
+
+ status = cli_close(cli2, fnum2);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("close2 failed (%s)\n", nt_errstr(status));
+ correct = false;
+ }
status = cli_close(cli1, fnum1);
if (!NT_STATUS_IS_OK(status)) {
@@ -3728,7 +3755,7 @@ static bool run_oplock4(int dummy)
correct = false;
}
- if (!*oplock4_shared_correct) {
+ if (!got_break) {
correct = false;
}
@@ -3737,6 +3764,43 @@ static bool run_oplock4(int dummy)
return correct;
}
+static void oplock4_got_break(struct tevent_req *req)
+{
+ struct oplock4_state *state = tevent_req_callback_data(
+ req, struct oplock4_state);
+ uint16_t fnum;
+ uint8_t level;
+ NTSTATUS status;
+
+ status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
+ TALLOC_FREE(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_smb_oplock_break_waiter_recv returned %s\n",
+ nt_errstr(status));
+ return;
+ }
+ *state->got_break = true;
+
+ req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
+ NO_OPLOCK);
+ if (req == NULL) {
+ printf("cli_oplock_ack_send failed\n");
+ return;
+ }
+}
+
+static void oplock4_got_open(struct tevent_req *req)
+{
+ struct oplock4_state *state = tevent_req_callback_data(
+ req, struct oplock4_state);
+ NTSTATUS status;
+
+ status = cli_open_recv(req, state->fnum2);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_open_recv returned %s\n", nt_errstr(status));
+ *state->fnum2 = 0xffff;
+ }
+}
/*
Test delete on close semantics.