From 8bebb380e8b581b41f3057c128d73094c1bde332 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 1 Mar 2010 14:28:22 +0100 Subject: s3: Add connections_forall_read() In a cluster, this makes a large difference: For r/w traverse, we have to do a fetch_locked on every record which for most users of connections_forall is just overkill. --- source3/include/proto.h | 4 ++++ source3/lib/conn_tdb.c | 42 ++++++++++++++++++++++++++++++++++++++++++ source3/smbd/sesssetup.c | 5 ++--- source3/utils/net_status.c | 5 ++--- source3/utils/smbcontrol.c | 5 ++--- source3/utils/status.c | 5 ++--- source3/web/statuspage.c | 15 ++++++--------- 7 files changed, 60 insertions(+), 21 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 18e60ca078..39aca5f76a 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -431,6 +431,10 @@ int connections_forall(int (*fn)(struct db_record *rec, const struct connections_data *data, void *private_data), void *private_data); +int connections_forall_read(int (*fn)(const struct connections_key *key, + const struct connections_data *data, + void *private_data), + void *private_data); bool connections_init(bool rw); /* The following definitions come from lib/dbwrap_util.c */ diff --git a/source3/lib/conn_tdb.c b/source3/lib/conn_tdb.c index e95ada4c6a..0770f66828 100644 --- a/source3/lib/conn_tdb.c +++ b/source3/lib/conn_tdb.c @@ -121,6 +121,48 @@ int connections_forall(int (*fn)(struct db_record *rec, return ctx->traverse(ctx, conn_traverse_fn, (void *)&state); } +struct conn_traverse_read_state { + int (*fn)(const struct connections_key *key, + const struct connections_data *data, + void *private_data); + void *private_data; +}; + +static int connections_forall_read_fn(struct db_record *rec, + void *private_data) +{ + struct conn_traverse_read_state *state = + (struct conn_traverse_read_state *)private_data; + + if ((rec->key.dsize != sizeof(struct connections_key)) + || (rec->value.dsize != sizeof(struct connections_data))) { + return 0; + } + return state->fn((const struct connections_key *)rec->key.dptr, + (const struct connections_data *)rec->value.dptr, + state->private_data); +} + +int connections_forall_read(int (*fn)(const struct connections_key *key, + const struct connections_data *data, + void *private_data), + void *private_data) +{ + struct db_context *ctx; + struct conn_traverse_read_state state; + + ctx = connections_db_ctx(false); + if (ctx == NULL) { + return -1; + } + + state.fn = fn; + state.private_data = private_data; + + return ctx->traverse_read(ctx, connections_forall_read_fn, + (void *)&state); +} + bool connections_init(bool rw) { return (connections_db_ctx(rw) != NULL); diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 289055cc6b..cad2dd33b8 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1356,8 +1356,7 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req) a new session setup with VC==0 is ignored. ****************************************************************************/ -static int shutdown_other_smbds(struct db_record *rec, - const struct connections_key *key, +static int shutdown_other_smbds(const struct connections_key *key, const struct connections_data *crec, void *private_data) { @@ -1394,7 +1393,7 @@ static void setup_new_vc_session(void) invalidate_all_vuids(); #endif if (lp_reset_on_zero_vc()) { - connections_forall(shutdown_other_smbds, + connections_forall_read(shutdown_other_smbds, CONST_DISCARD(void *, client_addr(get_client_fd(),addr,sizeof(addr)))); } diff --git a/source3/utils/net_status.c b/source3/utils/net_status.c index ce7dbcaf20..47860cb584 100644 --- a/source3/utils/net_status.c +++ b/source3/utils/net_status.c @@ -151,8 +151,7 @@ static int collect_pid(struct db_record *rec, void *private_data) return 0; } -static int show_share_parseable(struct db_record *rec, - const struct connections_key *key, +static int show_share_parseable(const struct connections_key *key, const struct connections_data *crec, void *state) { @@ -205,7 +204,7 @@ static int net_status_shares_parseable(struct net_context *c, int argc, const ch db->traverse_read(db, collect_pid, &ids); TALLOC_FREE(db); - connections_forall(show_share_parseable, &ids); + connections_forall_read(show_share_parseable, &ids); SAFE_FREE(ids.entries); diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c index 0ecab1b5d4..5645386028 100644 --- a/source3/utils/smbcontrol.c +++ b/source3/utils/smbcontrol.c @@ -259,8 +259,7 @@ cleanup: ptrace(PTRACE_DETACH, pid, NULL, NULL); } -static int stack_trace_connection(struct db_record *rec, - const struct connections_key *key, +static int stack_trace_connection(const struct connections_key *key, const struct connections_data *crec, void *priv) { @@ -291,7 +290,7 @@ static bool do_daemon_stack_trace(struct messaging_context *msg_ctx, */ print_stack_trace(dest, &count); } else { - connections_forall(stack_trace_connection, &count); + connections_forall_read(stack_trace_connection, &count); } return True; diff --git a/source3/utils/status.c b/source3/utils/status.c index 6d616149d7..60cad2c28f 100644 --- a/source3/utils/status.c +++ b/source3/utils/status.c @@ -232,8 +232,7 @@ static void print_brl(struct file_id id, TALLOC_FREE(share_mode); } -static int traverse_fn1(struct db_record *rec, - const struct connections_key *key, +static int traverse_fn1(const struct connections_key *key, const struct connections_data *crec, void *state) { @@ -447,7 +446,7 @@ static int traverse_sessionid(struct db_record *db, void *state) d_printf("\nService pid machine Connected at\n"); d_printf("-------------------------------------------------------\n"); - connections_forall(traverse_fn1, NULL); + connections_forall_read(traverse_fn1, NULL); d_printf("\n"); diff --git a/source3/web/statuspage.c b/source3/web/statuspage.c index f94ffb7926..e633036de3 100644 --- a/source3/web/statuspage.c +++ b/source3/web/statuspage.c @@ -182,8 +182,7 @@ static void print_share_mode(const struct share_mode_entry *e, /* kill off any connections chosen by the user */ -static int traverse_fn1(struct db_record *rec, - const struct connections_key *key, +static int traverse_fn1(const struct connections_key *key, const struct connections_data *crec, void *private_data) { @@ -199,8 +198,7 @@ static int traverse_fn1(struct db_record *rec, } /* traversal fn for showing machine connections */ -static int traverse_fn2(struct db_record *rec, - const struct connections_key *key, +static int traverse_fn2(const struct connections_key *key, const struct connections_data *crec, void *private_data) { @@ -224,8 +222,7 @@ static int traverse_fn2(struct db_record *rec, } /* traversal fn for showing share connections */ -static int traverse_fn3(struct db_record *rec, - const struct connections_key *key, +static int traverse_fn3(const struct connections_key *key, const struct connections_data *crec, void *private_data) { @@ -325,7 +322,7 @@ void status_page(void) PID_or_Machine = 0; } - connections_forall(traverse_fn1, NULL); + connections_forall_read(traverse_fn1, NULL); initPid2Machine (); @@ -415,7 +412,7 @@ void status_page(void) } printf("\n"); - connections_forall(traverse_fn2, NULL); + connections_forall_read(traverse_fn2, NULL); printf("

\n"); @@ -424,7 +421,7 @@ void status_page(void) printf("%s%s%s%s%s%s\n\n", _("Share"), _("User"), _("Group"), _("PID"), _("Client"), _("Date")); - connections_forall(traverse_fn3, NULL); + connections_forall_read(traverse_fn3, NULL); printf("

\n"); -- cgit