source4 messaging: clean up terminated processes
authorGary Lockyer <gary@catalyst.net.nz>
Thu, 13 Sep 2018 21:43:59 +0000 (09:43 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 23 Nov 2018 07:25:20 +0000 (08:25 +0100)
Now that the smbd pre-fork process model restarts failed processes rather than
terminating, we end up with names registered to defunct processes.
This patch adds a function to clean up all the names registered to a process.

Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/lib/messaging/messaging.c
source4/lib/messaging/messaging.h

index 935951f3fbae075b1324b1f15c80c8b6935663a6..413a19445eb9e019ec5a65be1d0c6946f3c4e3d1 100644 (file)
@@ -248,6 +248,48 @@ static void imessaging_dgm_recv(struct tevent_context *ev,
 /* Keep a list of imessaging contexts */
 static struct imessaging_context *msg_ctxs;
 
+/*
+ * A process has terminated, clean-up any names it has registered.
+ */
+NTSTATUS imessaging_process_cleanup(
+       struct imessaging_context *msg_ctx,
+       pid_t pid)
+{
+       struct irpc_name_records *names = NULL;
+       int i = 0;
+       int j = 0;
+       TALLOC_CTX *mem_ctx = talloc_new(NULL);
+
+       if (mem_ctx == NULL) {
+               DBG_ERR("OOM unable to clean up messaging for process (%d)\n",
+                       pid);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       names = irpc_all_servers(msg_ctx, mem_ctx);
+       if (names == NULL) {
+               TALLOC_FREE(mem_ctx);
+               return NT_STATUS_OK;
+       }
+       for (i = 0; i < names->num_records; i++) {
+               for (j = 0; j < names->names[i]->count; j++) {
+                       if (names->names[i]->ids[j].pid == pid) {
+                               int ret = server_id_db_prune_name(
+                                       msg_ctx->names,
+                                       names->names[i]->name,
+                                       names->names[i]->ids[j]);
+                               if (ret != 0 && ret != ENOENT) {
+                                       TALLOC_FREE(mem_ctx);
+                                       return map_nt_error_from_unix_common(
+                                           ret);
+                               }
+                       }
+               }
+       }
+       TALLOC_FREE(mem_ctx);
+       return NT_STATUS_OK;
+}
+
 static int imessaging_context_destructor(struct imessaging_context *msg)
 {
        DLIST_REMOVE(msg_ctxs, msg);
index 668464dc061d9fe07a57c0b93308a25c708f7eb6..8eb195dfb2e72788682e5c61d629d26f71af95e1 100644 (file)
@@ -54,5 +54,7 @@ NTSTATUS imessaging_send_ptr(struct imessaging_context *msg, struct server_id se
                            uint32_t msg_type, void *ptr);
 void imessaging_deregister(struct imessaging_context *msg, uint32_t msg_type, void *private_data);
 struct server_id imessaging_get_server_id(struct imessaging_context *msg_ctx);
+NTSTATUS imessaging_process_cleanup(struct imessaging_context *msg_ctx,
+                                   pid_t pid);
 
 #endif