messaging: Enforce just one messaging context
authorVolker Lendecke <vl@samba.org>
Tue, 18 Feb 2014 19:51:23 +0000 (20:51 +0100)
committerJeremy Allison <jra@samba.org>
Thu, 20 Feb 2014 00:38:30 +0000 (16:38 -0800)
The current messaging implementation is based on a tdb indexed by server_id. If
we have more than one messaging context in a process, messages might not arrive
at the right context and be dropped, depending on which signal handler is
triggered first.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/lib/messages_local.c

index 6b9c251cbb67e6b365fea1e7c17358246913f206..4f8d81c8bfe9a8a2d4803581c5e777ac7b4801e5 100644 (file)
@@ -53,6 +53,7 @@ struct messaging_tdb_context {
        struct tdb_wrap *tdb;
        struct tevent_signal *se;
        int received_messages;
+       bool *have_context;
 };
 
 static NTSTATUS messaging_tdb_send(struct messaging_context *msg_ctx,
@@ -77,6 +78,8 @@ static void messaging_tdb_signal_handler(struct tevent_context *ev_ctx,
        message_dispatch(ctx->msg_ctx);
 }
 
+static int messaging_tdb_context_destructor(struct messaging_tdb_context *ctx);
+
 /****************************************************************************
  Initialise the messaging functions. 
 ****************************************************************************/
@@ -88,6 +91,12 @@ NTSTATUS messaging_tdb_init(struct messaging_context *msg_ctx,
        struct messaging_backend *result;
        struct messaging_tdb_context *ctx;
        struct loadparm_context *lp_ctx;
+       static bool have_context = false;
+
+       if (have_context) {
+               DEBUG(0, ("No two messaging contexts per process\n"));
+               return NT_STATUS_OBJECT_NAME_COLLISION;
+       }
 
        if (!(result = talloc(mem_ctx, struct messaging_backend))) {
                DEBUG(0, ("talloc failed\n"));
@@ -110,6 +119,7 @@ NTSTATUS messaging_tdb_init(struct messaging_context *msg_ctx,
        result->send_fn = messaging_tdb_send;
 
        ctx->msg_ctx = msg_ctx;
+       ctx->have_context = &have_context;
 
        ctx->tdb = tdb_wrap_open(ctx, lock_path("messages.tdb"), 0,
                                 TDB_CLEAR_IF_FIRST|TDB_DEFAULT|TDB_VOLATILE|TDB_INCOMPATIBLE_HASH,
@@ -139,10 +149,20 @@ NTSTATUS messaging_tdb_init(struct messaging_context *msg_ctx,
 
        sec_init();
 
+       have_context = true;
+       talloc_set_destructor(ctx, messaging_tdb_context_destructor);
+
        *presult = result;
        return NT_STATUS_OK;
 }
 
+static int messaging_tdb_context_destructor(struct messaging_tdb_context *ctx)
+{
+       SMB_ASSERT(*ctx->have_context);
+       *ctx->have_context = false;
+       return 0;
+}
+
 bool messaging_tdb_parent_init(TALLOC_CTX *mem_ctx)
 {
        struct tdb_wrap *db;