vanishing messaging context names

Jeremy Allison jra at samba.org
Tue Mar 28 22:42:12 UTC 2017


On Wed, Mar 29, 2017 at 10:53:04AM +1300, Andrew Bartlett wrote:
> 
> I agree.  I've been bitten by it before. 
> 
> In any case, here is a patch.  The result of irpc_add_name() is no
> longer removed by talloc_free(), but is removed when the stream or task
> is terminated.  In source3 this is left as-was, but it is safe because
> only the notify server registers a name.
> 
> Now we just need tests to show it stays around, that don't rely on
> side-effects of other tests and test test order.

Hmmm. I can see the point of it, but I think it's a band-aid
around the lack of proper handling of fork() inside the
source4 code.

If you look inside lib/util/server_id_db.c, there is already
server_id_db_reinit(), called in source3 from messaging_reinit(),
which is called from reinit_after_fork(), and *that* is
called inside every child created using fork() inside source3/

I think the proper fix is going to be doing the same thing
inside the bin/samba binary for forked tasks. Otherwise we
will forever be fighting this inside source4-forked children.

I'd rather bite the bullet and fix this properly for all
time now :-).

> From f2febc44e10e34186d5a29f3c8b9a1b2fdc69776 Mon Sep 17 00:00:00 2001
> From: Andrew Bartlett <abartlet at samba.org>
> Date: Tue, 28 Mar 2017 22:02:13 +1300
> Subject: [PATCH] messaging: Move names cleanup from the destructor on
>  server_id_db
> 
> Instead, it is on the messaging_context in source3, and in imessaging_cleanup() in source4
> 
> Signed-off-by: Andrew Bartlett <abartlet at samba.org>
> ---
>  lib/util/server_id_db.c           | 14 +++++++++-----
>  lib/util/server_id_db.h           |  1 +
>  source3/lib/messages.c            |  4 ++++
>  source4/lib/messaging/messaging.c | 17 ++++++++++++++++-
>  4 files changed, 30 insertions(+), 6 deletions(-)
> 
> diff --git a/lib/util/server_id_db.c b/lib/util/server_id_db.c
> index e190f457526..059d766d94a 100644
> --- a/lib/util/server_id_db.c
> +++ b/lib/util/server_id_db.c
> @@ -37,8 +37,6 @@ struct server_id_db {
>  	char *names;
>  };
>  
> -static int server_id_db_destructor(struct server_id_db *db);
> -
>  struct server_id_db *server_id_db_init(TALLOC_CTX *mem_ctx,
>  				       struct server_id pid,
>  				       const char *base_path,
> @@ -64,8 +62,6 @@ struct server_id_db *server_id_db_init(TALLOC_CTX *mem_ctx,
>  		return NULL;
>  	}
>  
> -	talloc_set_destructor(db, server_id_db_destructor);
> -
>  	return db;
>  }
>  
> @@ -80,7 +76,15 @@ struct server_id server_id_db_pid(struct server_id_db *db)
>  	return db->pid;
>  }
>  
> -static int server_id_db_destructor(struct server_id_db *db)
> +/* 
> + * This MUST be called when the messaging context on which this
> + * server_id is finished with, but only in the same process, ie do not
> + * call it in a child. 
> + *
> + * For this reason, use in a talloc destructor should be carefully
> + * considered, and avoided if possible.
> + */
> +int server_id_db_cleanup(struct server_id_db *db)
>  {
>  	char *name = NULL;
>  
> diff --git a/lib/util/server_id_db.h b/lib/util/server_id_db.h
> index 2dcce622939..a1a5591f136 100644
> --- a/lib/util/server_id_db.h
> +++ b/lib/util/server_id_db.h
> @@ -46,5 +46,6 @@ int server_id_db_traverse_read(struct server_id_db *db,
>  					 const struct server_id *servers,
>  					 void *private_data),
>  			       void *private_data);
> +int server_id_db_cleanup(struct server_id_db *db);
>  
>  #endif
> diff --git a/source3/lib/messages.c b/source3/lib/messages.c
> index d7ad49d7c30..31b9905b0ff 100644
> --- a/source3/lib/messages.c
> +++ b/source3/lib/messages.c
> @@ -227,6 +227,10 @@ static int messaging_context_destructor(struct messaging_context *ctx)
>  		}
>  	}
>  
> +	if (ctx->names_db) {
> +		server_id_db_cleanup(ctx->names_db);
> +	}
> +	
>  	return 0;
>  }
>  
> diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c
> index 4d75f0976dc..5a858483227 100644
> --- a/source4/lib/messaging/messaging.c
> +++ b/source4/lib/messaging/messaging.c
> @@ -296,9 +296,24 @@ NTSTATUS imessaging_send_ptr(struct imessaging_context *msg, struct server_id se
>  */
>  int imessaging_cleanup(struct imessaging_context *msg)
>  {
> -	if (!msg) {
> +	if (msg == NULL || msg->names == NULL) {
>  		return 0;
>  	}
> +	/* 
> +	 * Trigger the server_id cleanup, triggering the removal of
> +	 * any registered names.  This call is important because it is
> +	 * made regardless of if the talloc_free() eventually happens
> +	 * (and a destructor could remove a parent's name in a child,
> +	 * so we don't want that).
> +	 *
> +	 * This is called before the model_ops->terminate() in
> +	 * stream_terminate_connection() and task_server_terminate()
> +	 *
> +	 * PID-based sockets are cleaned up by the parent task in
> +	 * process_standard or the destructor on the referenced
> +	 * messages_dgm context (which checks getpid()).
> +	 */
> +	server_id_db_cleanup(msg->names);
>  	return 0;
>  }
>  
> -- 
> 2.11.0
> 




More information about the samba-technical mailing list