diff options
Diffstat (limited to 'source3')
| -rw-r--r-- | source3/include/messages.h | 6 | ||||
| -rw-r--r-- | source3/lib/messages.c | 17 | ||||
| -rw-r--r-- | source3/lib/messages_local.c | 38 | ||||
| -rw-r--r-- | source3/smbd/server.c | 7 |
4 files changed, 68 insertions, 0 deletions
diff --git a/source3/include/messages.h b/source3/include/messages.h index d7a28538cd..47c5f7a2d9 100644 --- a/source3/include/messages.h +++ b/source3/include/messages.h @@ -97,6 +97,9 @@ NTSTATUS messaging_tdb_init(struct messaging_context *msg_ctx, bool messaging_tdb_parent_init(TALLOC_CTX *mem_ctx); +NTSTATUS messaging_tdb_cleanup(struct messaging_context *msg_ctx, + struct server_id pid); + NTSTATUS messaging_ctdbd_init(struct messaging_context *msg_ctx, TALLOC_CTX *mem_ctx, struct messaging_backend **presult); @@ -143,6 +146,9 @@ struct tevent_req *messaging_read_send(TALLOC_CTX *mem_ctx, int messaging_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct messaging_rec **presult); +void messaging_cleanup_server(struct messaging_context *msg_ctx, + struct server_id pid); + #include "librpc/gen_ndr/ndr_messaging.h" #endif diff --git a/source3/lib/messages.c b/source3/lib/messages.c index 96b6b88a80..4ff933dc6e 100644 --- a/source3/lib/messages.c +++ b/source3/lib/messages.c @@ -567,4 +567,21 @@ void messaging_dispatch_rec(struct messaging_context *msg_ctx, return; } +/* + Call when a process has terminated abnormally. +*/ +void messaging_cleanup_server(struct messaging_context *msg_ctx, + struct server_id server) +{ + if (server_id_is_disconnected(&server)) { + return; + } + + if (!procid_is_local(&server)) { + return; + } + + (void)messaging_tdb_cleanup(msg_ctx, server); + +} /** @} **/ diff --git a/source3/lib/messages_local.c b/source3/lib/messages_local.c index 1fe89c3bfa..d535df1be2 100644 --- a/source3/lib/messages_local.c +++ b/source3/lib/messages_local.c @@ -45,6 +45,7 @@ #include "includes.h" #include "system/filesys.h" #include "messages.h" +#include "serverid.h" #include "lib/tdb_wrap/tdb_wrap.h" #include "lib/param/param.h" @@ -221,6 +222,43 @@ static TDB_DATA message_key_pid(TALLOC_CTX *mem_ctx, struct server_id pid) return kbuf; } +/******************************************************************* + Called when a process has terminated abnormally. Remove all messages + pending for it. +******************************************************************/ + +NTSTATUS messaging_tdb_cleanup(struct messaging_context *msg_ctx, + struct server_id pid) +{ + struct messaging_tdb_context *ctx = talloc_get_type( + msg_ctx->local->private_data, + struct messaging_tdb_context); + struct tdb_wrap *tdb = ctx->tdb; + TDB_DATA key; + TALLOC_CTX *frame = talloc_stackframe(); + + key = message_key_pid(frame, pid); + /* + * We have to lock the key to avoid + * races in case the server_id was + * re-used and is active (a remote + * possibility, true). We only + * clean up the database if we + * know server_id doesn't exist + * while checked under the chainlock. + */ + if (tdb_chainlock(tdb->tdb, key) != 0) { + TALLOC_FREE(frame); + return NT_STATUS_LOCK_NOT_GRANTED; + } + if (!serverid_exists(&pid)) { + (void)tdb_delete(tdb->tdb, key); + } + tdb_chainunlock(tdb->tdb, key); + TALLOC_FREE(frame); + return NT_STATUS_OK; +} + /* Fetch the messaging array for a process */ diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 29e688d3f0..bc9d293b49 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -481,6 +481,13 @@ static void remove_child_pid(struct smbd_parent_context *parent, parent); DEBUG(1,("Scheduled cleanup of brl and lock database after unclean shutdown\n")); } + + /* + * Ensure we flush any stored messages + * queued for the child process that + * terminated uncleanly. + */ + messaging_cleanup_server(parent->msg_ctx, child_id); } if (!serverid_deregister(child_id)) { |
