s4-torture: handle NT_STATUS_CONNECTION_RESET
[ira/wip.git] / source4 / torture / raw / lockbench.c
index ea570e5bf50458f960adbcc3ca3d1501d39597fa..98ca5f37a474ddee0bb923018e532c490454a0c6 100644 (file)
@@ -20,8 +20,8 @@
 */
 
 #include "includes.h"
-#include "torture/torture.h"
 #include "libcli/raw/libcliraw.h"
+#include "libcli/raw/raw_proto.h"
 #include "system/time.h"
 #include "system/filesys.h"
 #include "libcli/libcli.h"
@@ -44,7 +44,7 @@ enum lock_stage {LOCK_INITIAL, LOCK_LOCK, LOCK_UNLOCK};
 
 struct benchlock_state {
        struct torture_context *tctx;
-       struct event_context *ev;
+       struct tevent_context *ev;
        struct smbcli_tree *tree;
        TALLOC_CTX *mem_ctx;
        int client_num;
@@ -56,7 +56,7 @@ struct benchlock_state {
        int lastcount;
        struct smbcli_request *req;
        struct smb_composite_connect reconnect;
-       struct timed_event *te;
+       struct tevent_timer *te;
 
        /* these are used for reconnections */
        const char **dest_ports;
@@ -111,15 +111,15 @@ static void lock_send(struct benchlock_state *state)
                DEBUG(0,("Failed to setup lock\n"));
                lock_failed++;
        }
-       state->req->async.private = state;
+       state->req->async.private_data = state;
        state->req->async.fn      = lock_completion;
 }
 
-static void reopen_connection(struct event_context *ev, struct timed_event *te, 
+static void reopen_connection(struct tevent_context *ev, struct tevent_timer *te, 
                              struct timeval t, void *private_data);
 
 
-static void reopen_file(struct event_context *ev, struct timed_event *te, 
+static void reopen_file(struct tevent_context *ev, struct tevent_timer *te, 
                                      struct timeval t, void *private_data)
 {
        struct benchlock_state *state = (struct benchlock_state *)private_data;
@@ -170,7 +170,7 @@ static void reopen_connection_complete(struct composite_context *ctx)
 /*
   reopen a connection
  */
-static void reopen_connection(struct event_context *ev, struct timed_event *te, 
+static void reopen_connection(struct tevent_context *ev, struct tevent_timer *te, 
                              struct timeval t, void *private_data)
 {
        struct benchlock_state *state = (struct benchlock_state *)private_data;
@@ -187,18 +187,17 @@ static void reopen_connection(struct event_context *ev, struct timed_event *te,
 
        io->in.dest_host    = state->dest_host;
        io->in.dest_ports   = state->dest_ports;
+       io->in.gensec_settings = lp_gensec_settings(state->mem_ctx, state->tctx->lp_ctx);
+       io->in.socket_options = lp_socket_options(state->tctx->lp_ctx);
        io->in.called_name  = state->called_name;
        io->in.service      = share;
        io->in.service_type = state->service_type;
        io->in.credentials  = cmdline_credentials;
        io->in.fallback_to_anonymous = false;
        io->in.workgroup    = lp_workgroup(state->tctx->lp_ctx);
-       io->in.max_xmit = lp_max_xmit(state->tctx->lp_ctx);
-       io->in.max_mux = lp_maxmux(state->tctx->lp_ctx);
-       io->in.ntstatus_support = lp_nt_status_support(state->tctx->lp_ctx);
-       io->in.max_protocol = lp_cli_maxprotocol(state->tctx->lp_ctx);
-       io->in.unicode = lp_unicode(state->tctx->lp_ctx);
-       io->in.use_spnego = lp_use_spnego(state->tctx->lp_ctx) && lp_nt_status_support(state->tctx->lp_ctx);
+       io->in.iconv_convenience = lp_iconv_convenience(state->tctx->lp_ctx);
+       lp_smbcli_options(state->tctx->lp_ctx, &io->in.options);
+       lp_smbcli_session_options(state->tctx->lp_ctx, &io->in.session_options);
 
        /* kill off the remnants of the old connection */
        talloc_free(state->tree);
@@ -222,12 +221,13 @@ static void reopen_connection(struct event_context *ev, struct timed_event *te,
 */
 static void lock_completion(struct smbcli_request *req)
 {
-       struct benchlock_state *state = (struct benchlock_state *)req->async.private;
+       struct benchlock_state *state = (struct benchlock_state *)req->async.private_data;
        NTSTATUS status = smbcli_request_simple_recv(req);
        state->req = NULL;
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE) ||
-                   NT_STATUS_EQUAL(status, NT_STATUS_LOCAL_DISCONNECT)) {
+                   NT_STATUS_EQUAL(status, NT_STATUS_LOCAL_DISCONNECT) ||
+                   NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET)) {
                        talloc_free(state->tree);
                        state->tree = NULL;
                        num_connected--;        
@@ -262,10 +262,11 @@ static void lock_completion(struct smbcli_request *req)
 
 static void echo_completion(struct smbcli_request *req)
 {
-       struct benchlock_state *state = (struct benchlock_state *)req->async.private;
+       struct benchlock_state *state = (struct benchlock_state *)req->async.private_data;
        NTSTATUS status = smbcli_request_simple_recv(req);
        if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE) ||
-           NT_STATUS_EQUAL(status, NT_STATUS_LOCAL_DISCONNECT)) {
+           NT_STATUS_EQUAL(status, NT_STATUS_LOCAL_DISCONNECT) ||
+           NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET)) {
                talloc_free(state->tree);
                state->tree = NULL;
                num_connected--;        
@@ -277,7 +278,7 @@ static void echo_completion(struct smbcli_request *req)
        }
 }
 
-static void report_rate(struct event_context *ev, struct timed_event *te, 
+static void report_rate(struct tevent_context *ev, struct tevent_timer *te, 
                        struct timeval t, void *private_data)
 {
        struct benchlock_state *state = talloc_get_type(private_data, 
@@ -305,7 +306,7 @@ static void report_rate(struct event_context *ev, struct timed_event *te,
                p.in.size = 0;
                p.in.data = NULL;
                req = smb_raw_echo_send(state[i].tree->session->transport, &p);
-               req->async.private = &state[i];
+               req->async.private_data = &state[i];
                req->async.fn      = echo_completion;
        }
 }
@@ -317,14 +318,15 @@ bool torture_bench_lock(struct torture_context *torture)
 {
        bool ret = true;
        TALLOC_CTX *mem_ctx = talloc_new(torture);
-       int i;
+       int i, j;
        int timelimit = torture_setting_int(torture, "timelimit", 10);
        struct timeval tv;
-       struct event_context *ev = event_context_find(mem_ctx);
        struct benchlock_state *state;
        int total = 0, minops=0;
        struct smbcli_state *cli;
        bool progress;
+       off_t offset;
+       int initial_locks = torture_setting_int(torture, "initial_locks", 0);
 
        progress = torture_setting_bool(torture, "progress", true);
 
@@ -337,8 +339,8 @@ bool torture_bench_lock(struct torture_context *torture)
                state[i].tctx = torture;
                state[i].mem_ctx = talloc_new(state);
                state[i].client_num = i;
-               state[i].ev = ev;
-               if (!torture_open_connection_ev(&cli, i, torture, ev)) {
+               state[i].ev = torture->ev;
+               if (!torture_open_connection_ev(&cli, i, torture, torture->ev)) {
                        return false;
                }
                talloc_steal(mem_ctx, state);
@@ -372,6 +374,21 @@ bool torture_bench_lock(struct torture_context *torture)
                        goto failed;
                }
 
+               /* Optionally, lock initial_locks for each proc beforehand. */
+               if (i == 0 && initial_locks > 0) {
+                       printf("Initializing %d locks on each proc.\n",
+                           initial_locks);
+               }
+
+               for (j = 0; j < initial_locks; j++) {
+                       offset = (0xFFFFFED8LLU * (i+2)) + j;
+                       if (!NT_STATUS_IS_OK(smbcli_lock64(state[i].tree,
+                           state[i].fnum, offset, 1, 0, WRITE_LOCK))) {
+                               printf("Failed initializing, lock=%d\n", j);
+                               goto failed;
+                       }
+               }
+
                state[i].stage = LOCK_INITIAL;
                lock_send(&state[i]);
        }
@@ -379,12 +396,12 @@ bool torture_bench_lock(struct torture_context *torture)
        tv = timeval_current(); 
 
        if (progress) {
-               event_add_timed(ev, state, timeval_current_ofs(1, 0), report_rate, state);
+               event_add_timed(torture->ev, state, timeval_current_ofs(1, 0), report_rate, state);
        }
 
        printf("Running for %d seconds\n", timelimit);
        while (timeval_elapsed(&tv) < timelimit) {
-               event_loop_once(ev);
+               event_loop_once(torture->ev);
 
                if (lock_failed) {
                        DEBUG(0,("locking failed\n"));
@@ -414,6 +431,7 @@ bool torture_bench_lock(struct torture_context *torture)
        return ret;
 
 failed:
+       smbcli_deltree(state[0].tree, BASEDIR);
        talloc_free(mem_ctx);
        return false;
 }