summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/include/messages.h5
-rw-r--r--source3/lib/messages.c2
-rw-r--r--source3/locking/brlock.c106
-rw-r--r--source3/smbd/server.c2
-rw-r--r--source3/utils/smbcontrol.c30
5 files changed, 144 insertions, 1 deletions
diff --git a/source3/include/messages.h b/source3/include/messages.h
index cde104e897..5ba2f45bd2 100644
--- a/source3/include/messages.h
+++ b/source3/include/messages.h
@@ -83,6 +83,11 @@
* Samba4 compatibility
*/
#define MSG_PVFS_NOTIFY 0x0310
+/*
+ * cluster reconfigure events
+ */
+#define MSG_SMB_BRL_VALIDATE 0x0311
+#define MSG_SMB_RELEASE_IP 0x0312
/* winbind messages */
#define MSG_WINBIND_FINISHED 0x0401
diff --git a/source3/lib/messages.c b/source3/lib/messages.c
index 01683bf9ec..256d4d097c 100644
--- a/source3/lib/messages.c
+++ b/source3/lib/messages.c
@@ -199,7 +199,7 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx,
status = messaging_tdb_init(ctx, ctx, &ctx->local);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("message_init failed: %s\n", nt_errstr(status)));
+ DEBUG(0, ("messaging_tdb_init failed: %s\n", nt_errstr(status)));
TALLOC_FREE(ctx);
}
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c
index b51076bf43..a50d4faa52 100644
--- a/source3/locking/brlock.c
+++ b/source3/locking/brlock.c
@@ -1686,3 +1686,109 @@ struct byte_range_lock *brl_get_locks_readonly(TALLOC_CTX *mem_ctx,
{
return brl_get_locks_internal(mem_ctx, fsp, True);
}
+
+struct brl_revalidate_state {
+ ssize_t array_size;
+ uint32 num_pids;
+ struct server_id *pids;
+};
+
+/*
+ * Collect PIDs of all processes with pending entries
+ */
+
+static void brl_revalidate_collect(struct file_id id, struct server_id pid,
+ enum brl_type lock_type,
+ enum brl_flavour lock_flav,
+ br_off start, br_off size,
+ void *private_data)
+{
+ struct brl_revalidate_state *state =
+ (struct brl_revalidate_state *)private_data;
+
+ if (!IS_PENDING_LOCK(lock_type)) {
+ return;
+ }
+
+ add_to_large_array(state, sizeof(pid), (void *)&pid,
+ &state->pids, &state->num_pids,
+ &state->array_size);
+}
+
+/*
+ * qsort callback to sort the processes
+ */
+
+static int compare_procids(const void *p1, const void *p2)
+{
+ const struct server_id *i1 = (struct server_id *)i1;
+ const struct server_id *i2 = (struct server_id *)i2;
+
+ if (i1->pid < i2->pid) return -1;
+ if (i2->pid > i2->pid) return 1;
+ return 0;
+}
+
+/*
+ * Send a MSG_SMB_UNLOCK message to all processes with pending byte range
+ * locks so that they retry. Mainly used in the cluster code after a node has
+ * died.
+ *
+ * Done in two steps to avoid double-sends: First we collect all entries in an
+ * array, then qsort that array and only send to non-dupes.
+ */
+
+static void brl_revalidate(struct messaging_context *msg_ctx,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id server_id,
+ DATA_BLOB *data)
+{
+ struct brl_revalidate_state *state;
+ uint32 i;
+ struct server_id last_pid;
+
+ if (!(state = TALLOC_ZERO_P(NULL, struct brl_revalidate_state))) {
+ DEBUG(0, ("talloc failed\n"));
+ return;
+ }
+
+ brl_forall(brl_revalidate_collect, state);
+
+ if (state->array_size == -1) {
+ DEBUG(0, ("talloc failed\n"));
+ goto done;
+ }
+
+ if (state->num_pids == 0) {
+ goto done;
+ }
+
+ qsort(state->pids, state->num_pids, sizeof(state->pids[0]),
+ compare_procids);
+
+ ZERO_STRUCT(last_pid);
+
+ for (i=0; i<state->num_pids; i++) {
+ if (procid_equal(&last_pid, &state->pids[i])) {
+ /*
+ * We've seen that one already
+ */
+ continue;
+ }
+
+ messaging_send(msg_ctx, state->pids[i], MSG_SMB_UNLOCK,
+ &data_blob_null);
+ last_pid = state->pids[i];
+ }
+
+ done:
+ TALLOC_FREE(state);
+ return;
+}
+
+void brl_register_msgs(struct messaging_context *msg_ctx)
+{
+ messaging_register(msg_ctx, NULL, MSG_SMB_BRL_VALIDATE,
+ brl_revalidate);
+}
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index fc1faa9d36..f837d38ac6 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -375,6 +375,7 @@ static BOOL open_sockets_smbd(enum smb_server_mode server_mode, const char *smb_
MSG_SMB_CONF_UPDATED, smb_conf_updated);
messaging_register(smbd_messaging_context(), NULL,
MSG_SMB_STAT_CACHE_DELETE, smb_stat_cache_delete);
+ brl_register_msgs(smbd_messaging_context());
#ifdef DEVELOPER
messaging_register(smbd_messaging_context(), NULL,
@@ -991,6 +992,7 @@ extern void build_options(BOOL screen);
}
/* Setup all the TDB's - including CLEAR_IF_FIRST tdb's. */
+
if (smbd_messaging_context() == NULL)
exit(1);
diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c
index 2b927adb96..1a1a190957 100644
--- a/source3/utils/smbcontrol.c
+++ b/source3/utils/smbcontrol.c
@@ -698,6 +698,34 @@ static BOOL do_closeshare(struct messaging_context *msg_ctx,
strlen(argv[1]) + 1);
}
+/* force a blocking lock retry */
+
+static BOOL do_lockretry(struct messaging_context *msg_ctx,
+ const struct server_id pid,
+ const int argc, const char **argv)
+{
+ if (argc != 1) {
+ fprintf(stderr, "Usage: smbcontrol <dest> lockretry\n");
+ return False;
+ }
+
+ return send_message(msg_ctx, pid, MSG_SMB_UNLOCK, NULL, 0);
+}
+
+/* force a validation of all brl entries, including re-sends. */
+
+static BOOL do_brl_revalidate(struct messaging_context *msg_ctx,
+ const struct server_id pid,
+ const int argc, const char **argv)
+{
+ if (argc != 1) {
+ fprintf(stderr, "Usage: smbcontrol <dest> brl-revalidate\n");
+ return False;
+ }
+
+ return send_message(msg_ctx, pid, MSG_SMB_BRL_VALIDATE, NULL, 0);
+}
+
/* Force a SAM synchronisation */
static BOOL do_samsync(struct messaging_context *msg_ctx,
@@ -1037,6 +1065,8 @@ static const struct {
{ "debuglevel", do_debuglevel, "Display current debuglevels" },
{ "printnotify", do_printnotify, "Send a print notify message" },
{ "close-share", do_closeshare, "Forcibly disconnect a share" },
+ { "lockretry", do_lockretry, "Force a blocking lock retry" },
+ { "brl-revalidate", do_brl_revalidate, "Revalidate all brl entries" },
{ "samsync", do_samsync, "Initiate SAM synchronisation" },
{ "samrepl", do_samrepl, "Initiate SAM replication" },
{ "pool-usage", do_poolusage, "Display talloc memory usage" },