summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2010-03-01 14:28:22 +0100
committerVolker Lendecke <vl@samba.org>2010-03-01 14:51:34 +0100
commit8bebb380e8b581b41f3057c128d73094c1bde332 (patch)
tree3470aabb76b4800f32ef85a13f6f53936a9e261e /source3
parent3deba6349ca751d669e2af817ec7e2c7eb6195b3 (diff)
downloadsamba-8bebb380e8b581b41f3057c128d73094c1bde332.tar.gz
samba-8bebb380e8b581b41f3057c128d73094c1bde332.tar.bz2
samba-8bebb380e8b581b41f3057c128d73094c1bde332.zip
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.
Diffstat (limited to 'source3')
-rw-r--r--source3/include/proto.h4
-rw-r--r--source3/lib/conn_tdb.c42
-rw-r--r--source3/smbd/sesssetup.c5
-rw-r--r--source3/utils/net_status.c5
-rw-r--r--source3/utils/smbcontrol.c5
-rw-r--r--source3/utils/status.c5
-rw-r--r--source3/web/statuspage.c15
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("</tr>\n");
- connections_forall(traverse_fn2, NULL);
+ connections_forall_read(traverse_fn2, NULL);
printf("</table><p>\n");
@@ -424,7 +421,7 @@ void status_page(void)
printf("<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n\n",
_("Share"), _("User"), _("Group"), _("PID"), _("Client"), _("Date"));
- connections_forall(traverse_fn3, NULL);
+ connections_forall_read(traverse_fn3, NULL);
printf("</table><p>\n");