diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/messages.h | 5 | ||||
-rw-r--r-- | source3/lib/messages.c | 2 | ||||
-rw-r--r-- | source3/locking/brlock.c | 106 | ||||
-rw-r--r-- | source3/smbd/server.c | 2 | ||||
-rw-r--r-- | source3/utils/smbcontrol.c | 30 |
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" }, |