diff options
author | Andrew Tridgell <tridge@samba.org> | 2007-05-14 03:49:42 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 14:52:23 -0500 |
commit | 0f6b62072e673887d354bccd7a15d4188b5c4fca (patch) | |
tree | dbf0a9fa12d1d4b3adaf335615e6e6c846c62beb /source4/torture/raw | |
parent | ba0424fddbfe4f38663dd5c7f7252f443c601489 (diff) | |
download | samba-0f6b62072e673887d354bccd7a15d4188b5c4fca.tar.gz samba-0f6b62072e673887d354bccd7a15d4188b5c4fca.tar.bz2 samba-0f6b62072e673887d354bccd7a15d4188b5c4fca.zip |
r22837: make RAW-BENCH-LOCK reconnect asynchronously when one of its servers
goges away
(This used to be commit cf0cdf5171d4e0ca01b697155ceb04ffc2863231)
Diffstat (limited to 'source4/torture/raw')
-rw-r--r-- | source4/torture/raw/lockbench.c | 138 |
1 files changed, 110 insertions, 28 deletions
diff --git a/source4/torture/raw/lockbench.c b/source4/torture/raw/lockbench.c index 1621139aa7..705ab4d691 100644 --- a/source4/torture/raw/lockbench.c +++ b/source4/torture/raw/lockbench.c @@ -29,6 +29,8 @@ #include "torture/util.h" #include "lib/events/events.h" #include "lib/cmdline/popt_common.h" +#include "libcli/composite/composite.h" +#include "libcli/smb_composite/smb_composite.h" #define CHECK_STATUS(status, correct) do { \ if (!NT_STATUS_EQUAL(status, correct)) { \ @@ -45,7 +47,8 @@ static int lock_failed; struct benchlock_state { struct event_context *ev; - struct smbcli_state *cli; + struct smbcli_tree *tree; + TALLOC_CTX *mem_ctx; int client_num; int fnum; int offset; @@ -53,6 +56,13 @@ struct benchlock_state { union smb_lock io; struct smb_lock_entry lock[2]; struct smbcli_request *req; + struct smb_composite_connect reconnect; + + /* these are used for reconnections */ + int dest_port; + const char *dest_host; + const char *called_name; + const char *service_type; }; static void lock_completion(struct smbcli_request *); @@ -64,11 +74,11 @@ static void lock_send(struct benchlock_state *state) { state->io.lockx.in.file.fnum = state->fnum; state->io.lockx.in.ulock_cnt = 1; - state->lock[0].pid = state->cli->session->pid; - state->lock[1].pid = state->cli->session->pid; + state->lock[0].pid = state->tree->session->pid; + state->lock[1].pid = state->tree->session->pid; state->lock[0].offset = state->offset; state->lock[1].offset = (state->offset+1)%nprocs; - state->req = smb_raw_lock_send(state->cli->tree, &state->io); + state->req = smb_raw_lock_send(state->tree, &state->io); if (state->req == NULL) { DEBUG(0,("Failed to setup lock\n")); lock_failed++; @@ -78,24 +88,26 @@ static void lock_send(struct benchlock_state *state) state->offset = (state->offset+1)%nprocs; } -/* - reopen dead connections - */ -static void reopen_connection(struct benchlock_state *state) +static void reopen_connection(struct benchlock_state *state); + + +static void reopen_file(struct event_context *ev, struct timed_event *te, + struct timeval t, void *private_data) { - do { - DEBUG(0,("reopening connection %u\n", state->client_num)); - } while (!torture_open_connection_ev(&state->cli, state->client_num, state->ev)); - - state->fnum = smbcli_open(state->cli->tree, FNAME, O_RDWR|O_CREAT, DENY_NONE); + struct benchlock_state *state = (struct benchlock_state *)private_data; + + /* reestablish our open file */ + state->fnum = smbcli_open(state->tree, FNAME, O_RDWR|O_CREAT, DENY_NONE); if (state->fnum == -1) { printf("Failed to open %s on connection %d\n", FNAME, state->client_num); exit(1); } + /* reestablish one lock, preparing for the async lock loop */ state->lock[0].offset = state->offset; state->io.lockx.in.ulock_cnt = 0; - state->req = smb_raw_lock_send(state->cli->tree, &state->io); + state->io.lockx.in.file.fnum = state->fnum; + state->req = smb_raw_lock_send(state->tree, &state->io); if (state->req == NULL) { DEBUG(0,("Failed to setup lock\n")); lock_failed++; @@ -106,6 +118,70 @@ static void reopen_connection(struct benchlock_state *state) } /* + complete an async reconnect + */ +static void reopen_connection_complete(struct composite_context *ctx) +{ + struct benchlock_state *state = (struct benchlock_state *)ctx->async.private_data; + NTSTATUS status; + struct smb_composite_connect *io = &state->reconnect; + + status = smb_composite_connect_recv(ctx, state->mem_ctx); + if (!NT_STATUS_IS_OK(status)) { + reopen_connection(state); + return; + } + + talloc_free(state->tree); + state->tree = io->out.tree; + + /* do the reopen as a separate event */ + event_add_timed(state->ev, state->mem_ctx, timeval_zero(), reopen_file, state); +} + + + +/* + reopen dead connections + */ +static void reopen_connection(struct benchlock_state *state) +{ + struct composite_context *ctx; + struct smb_composite_connect *io = &state->reconnect; + char *host, *share; + + if (!torture_get_conn_index(state->client_num, state->mem_ctx, &host, &share)) { + DEBUG(0,("Can't find host/share for reconnect?!\n")); + exit(1); + } + + io->in.dest_host = state->dest_host; + io->in.port = state->dest_port; + 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(); + + DEBUG(0,("reopening connection to //%s/%s\n", host, share)); + + /* kill off the remnants of the old connection */ + talloc_free(state->tree); + state->tree = NULL; + + ctx = smb_composite_connect_send(io, state->mem_ctx, state->ev); + if (ctx == NULL) { + DEBUG(0,("Failed to setup async reconnect\n")); + exit(1); + } + + ctx->async.fn = reopen_connection_complete; + ctx->async.private_data = state; +} + + +/* called when a lock completes */ static void lock_completion(struct smbcli_request *req) @@ -114,10 +190,11 @@ static void lock_completion(struct smbcli_request *req) NTSTATUS status = smbcli_request_simple_recv(req); state->req = NULL; if (!NT_STATUS_IS_OK(status)) { - lock_failed++; - DEBUG(0,("Lock failed - %s\n", nt_errstr(status))); if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { reopen_connection(state); + } else { + DEBUG(0,("Lock failed - %s\n", nt_errstr(status))); + lock_failed++; } } else { state->count++; @@ -139,6 +216,7 @@ BOOL torture_bench_lock(struct torture_context *torture) struct benchlock_state *state; int total = 0, loops=0, minops=0; NTSTATUS status; + struct smbcli_state *cli; nprocs = lp_parm_int(-1, "torture", "nprocs", 4); @@ -146,20 +224,29 @@ BOOL torture_bench_lock(struct torture_context *torture) printf("Opening %d connections\n", nprocs); for (i=0;i<nprocs;i++) { + state[i].mem_ctx = talloc_new(state); state[i].client_num = i; state[i].ev = ev; - if (!torture_open_connection_ev(&state[i].cli, i, ev)) { + if (!torture_open_connection_ev(&cli, i, ev)) { return False; } talloc_steal(mem_ctx, state); + state[i].tree = cli->tree; + state[i].dest_host = talloc_strdup(state[i].mem_ctx, + cli->tree->session->transport->socket->hostname); + state[i].dest_port = cli->tree->session->transport->socket->port; + state[i].called_name = talloc_strdup(state[i].mem_ctx, + cli->tree->session->transport->called.name); + state[i].service_type = talloc_strdup(state[i].mem_ctx, + cli->tree->device); } - if (!torture_setup_dir(state[0].cli, BASEDIR)) { + if (!torture_setup_dir(cli, BASEDIR)) { goto failed; } for (i=0;i<nprocs;i++) { - state[i].fnum = smbcli_open(state[i].cli->tree, + state[i].fnum = smbcli_open(state[i].tree, FNAME, O_RDWR|O_CREAT, DENY_NONE); if (state[i].fnum == -1) { @@ -179,8 +266,8 @@ BOOL torture_bench_lock(struct torture_context *torture) state[i].offset = i; state[i].io.lockx.in.file.fnum = state[i].fnum; state[i].lock[0].offset = state[i].offset; - state[i].lock[0].pid = state[i].cli->session->pid; - status = smb_raw_lock(state[i].cli->tree, &state[i].io); + state[i].lock[0].pid = state[i].tree->session->pid; + status = smb_raw_lock(state[i].tree, &state[i].io); CHECK_STATUS(status, NT_STATUS_OK); } @@ -226,19 +313,14 @@ BOOL torture_bench_lock(struct torture_context *torture) for (i=0;i<nprocs;i++) { talloc_free(state[i].req); - smb_raw_exit(state[i].cli->session); + smb_raw_exit(state[i].tree->session); } - smbcli_deltree(state[0].cli->tree, BASEDIR); + smbcli_deltree(state[0].tree, BASEDIR); talloc_free(mem_ctx); return ret; failed: - for (i=0;i<nprocs;i++) { - talloc_free(state[i].req); - smb_raw_exit(state[i].cli->session); - } - smbcli_deltree(state[0].cli->tree, BASEDIR); talloc_free(mem_ctx); return False; } |