s3: Convert the OPEN4 test to async oplock handling
authorVolker Lendecke <vl@samba.org>
Sun, 22 May 2011 16:50:16 +0000 (18:50 +0200)
committerVolker Lendecke <vl@samba.org>
Sun, 22 May 2011 19:07:40 +0000 (21:07 +0200)
This removes a caller of cli_receive_smb

source3/torture/torture.c

index a28078f..f2fad49 100644 (file)
@@ -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.