summaryrefslogtreecommitdiffstats
path: root/source3/lib
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2014-04-02 16:45:25 -0700
committerJeremy Allison <jra@samba.org>2014-04-03 06:22:13 +0200
commit837671f47670b16726aa96ba7a0902974a1037eb (patch)
treeed199a59526ad0b1b55e0e937a502fd73fe3c10a /source3/lib
parent5cf6e9c8520be49aa57436bf725521cdc5d160f8 (diff)
downloadsamba-837671f47670b16726aa96ba7a0902974a1037eb.tar.gz
samba-837671f47670b16726aa96ba7a0902974a1037eb.tar.xz
samba-837671f47670b16726aa96ba7a0902974a1037eb.zip
s3: messages: Implement cleanup of dead records.
When a smbd process dies, pending messages.tdb records for this process might not get cleaned up. Implement a cleanup for dead records that is triggered after a smbd dies uncleanly; the records for that PID are deleted. Based on a patchset from Christof Schmitt <cs@samba.org>. Signed-off-by: Jeremy Allison <jra@samba.org> Reviewed-by: Christof Schmitt <cs@samba.org>
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/messages.c17
-rw-r--r--source3/lib/messages_local.c38
2 files changed, 55 insertions, 0 deletions
diff --git a/source3/lib/messages.c b/source3/lib/messages.c
index 96b6b88a808..4ff933dc6e7 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 1fe89c3bfaa..d535df1be27 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
*/