[PATCH] Make notifyd restartable

Jeremy Allison jra at samba.org
Tue Jul 19 23:14:12 UTC 2016


On Tue, Jul 19, 2016 at 02:29:13PM +0200, Volker Lendecke wrote:
> Hi!
> 
> Attached find a patchset that serves two purposes: First, it
> simplifies notify_msg.c. All information that is kept in "struct
> notify_list" is also available elsewhere, so there is no need to
> maintain that duplicate data structure. That's the first 12 patches.
> The last 6 ones makes notifyd restartable should it die for some
> reason.
> 
> Comments?

FYI. Reviewing and testing this now. Hopefully done by
tomorrow !

I like the fact it removes lots of code :-).

Jeremy.

> From 64360d91351c2fd2abf93f6d281a48a1e27cad51 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Tue, 21 Jun 2016 16:10:14 +0200
> Subject: [PATCH 01/18] smbd: Don't stop sending to children when one send
>  fails
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/smbd/server.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/source3/smbd/server.c b/source3/smbd/server.c
> index 65dc173..07eca51 100644
> --- a/source3/smbd/server.c
> +++ b/source3/smbd/server.c
> @@ -205,7 +205,8 @@ static NTSTATUS messaging_send_to_children(struct messaging_context *msg_ctx,
>  					pid_to_procid(child->pid),
>  					msg_type, data);
>  		if (!NT_STATUS_IS_OK(status)) {
> -			return status;
> +			DBG_DEBUG("messaging_send(%d) failed: %s\n",
> +				  (int)child->pid, nt_errstr(status));
>  		}
>  	}
>  	return NT_STATUS_OK;
> -- 
> 2.1.4
> 
> 
> From 95f72a1d17578e1d49f918bdf5e7b331f3273cbb Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Wed, 15 Jun 2016 10:21:48 +0200
> Subject: [PATCH 02/18] smbd: sconn->sys_notify_ctx is not used
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/smbd/globals.h | 1 -
>  source3/smbd/service.c | 4 ----
>  2 files changed, 5 deletions(-)
> 
> diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
> index 0266533..8ba564d 100644
> --- a/source3/smbd/globals.h
> +++ b/source3/smbd/globals.h
> @@ -860,7 +860,6 @@ struct smbd_server_connection {
>  	const char *remote_hostname;
>  	struct tevent_context *ev_ctx;
>  	struct messaging_context *msg_ctx;
> -	struct sys_notify_context *sys_notify_ctx;
>  	struct notify_context *notify_ctx;
>  	bool using_smb2;
>  	int trans_num;
> diff --git a/source3/smbd/service.c b/source3/smbd/service.c
> index 34cc369..46bb226 100644
> --- a/source3/smbd/service.c
> +++ b/source3/smbd/service.c
> @@ -697,10 +697,6 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
>  				MSG_SMB_NOTIFY_CANCEL_DELETED,
>  				smbd_notify_cancel_deleted);
>  		}
> -		if (sconn->sys_notify_ctx == NULL) {
> -			sconn->sys_notify_ctx = sys_notify_context_create(
> -				sconn, sconn->ev_ctx);
> -		}
>  	}
>  
>  	if (lp_kernel_oplocks(snum)) {
> -- 
> 2.1.4
> 
> 
> From de89af1a4f4fdf6fe480101412ce15d855ba90d4 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Thu, 23 Jun 2016 12:53:47 +0200
> Subject: [PATCH 03/18] smbd: Factor out notify_init
> 
> Before this patch, failure of notify_init was ignored. Also, no proper error
> handling of a messaging_register failure was done. Fix those, also adding some
> debug messages.
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/smbd/service.c | 37 ++++++++++++++++++++++++++++++-------
>  1 file changed, 30 insertions(+), 7 deletions(-)
> 
> diff --git a/source3/smbd/service.c b/source3/smbd/service.c
> index 46bb226..37440e0 100644
> --- a/source3/smbd/service.c
> +++ b/source3/smbd/service.c
> @@ -520,6 +520,32 @@ NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum)
>  	return NT_STATUS_OK;
>  }
>  
> +static NTSTATUS notify_init_sconn(struct smbd_server_connection *sconn)
> +{
> +	NTSTATUS status;
> +
> +	if (sconn->notify_ctx != NULL) {
> +		return NT_STATUS_OK;
> +	}
> +
> +	sconn->notify_ctx = notify_init(sconn, sconn->msg_ctx, sconn->ev_ctx);
> +	if (sconn->notify_ctx == NULL) {
> +		return NT_STATUS_NO_MEMORY;
> +	}
> +
> +	status = messaging_register(sconn->msg_ctx, sconn,
> +				    MSG_SMB_NOTIFY_CANCEL_DELETED,
> +				    smbd_notify_cancel_deleted);
> +	if (!NT_STATUS_IS_OK(status)) {
> +		DBG_DEBUG("messaging_register failed: %s\n",
> +			  nt_errstr(status));
> +		TALLOC_FREE(sconn->notify_ctx);
> +		return status;
> +	}
> +
> +	return NT_STATUS_OK;
> +}
> +
>  /****************************************************************************
>    Make a connection, given the snum to connect to, and the vuser of the
>    connecting user if appropriate.
> @@ -689,13 +715,10 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
>  
>  	if ((!conn->printer) && (!conn->ipc) &&
>  	    lp_change_notify()) {
> -		if (sconn->notify_ctx == NULL) {
> -			sconn->notify_ctx = notify_init(
> -				sconn, sconn->msg_ctx, sconn->ev_ctx);
> -			status = messaging_register(
> -				sconn->msg_ctx, sconn,
> -				MSG_SMB_NOTIFY_CANCEL_DELETED,
> -				smbd_notify_cancel_deleted);
> +
> +		status = notify_init_sconn(sconn);
> +		if (!NT_STATUS_IS_OK(status)) {
> +			goto err_root_exit;
>  		}
>  	}
>  
> -- 
> 2.1.4
> 
> 
> From d6168ff1ef3651c8b02ab3debebed554e97bece7 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Mon, 13 Jun 2016 16:12:54 +0200
> Subject: [PATCH 04/18] smbd: Add fsp_fullbasepath
> 
> Okay, this is similar to full_path_tos, but with variable arrays now and much
> simpler :-)
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/smbd/files.c | 11 +++++++++++
>  source3/smbd/proto.h |  1 +
>  2 files changed, 12 insertions(+)
> 
> diff --git a/source3/smbd/files.c b/source3/smbd/files.c
> index a3cce13..f211c17 100644
> --- a/source3/smbd/files.c
> +++ b/source3/smbd/files.c
> @@ -780,3 +780,14 @@ uint32_t fsp_lease_type(struct files_struct *fsp)
>  	}
>  	return map_oplock_to_lease_type(fsp->oplock_type);
>  }
> +
> +size_t fsp_fullbasepath(struct files_struct *fsp, char *buf, size_t buflen)
> +{
> +	int len;
> +
> +	len = snprintf(buf, buflen, "%s/%s", fsp->conn->connectpath,
> +		       fsp->fsp_name->base_name);
> +	SMB_ASSERT(len>0);
> +
> +	return len;
> +}
> diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
> index 86fafe5..764673c 100644
> --- a/source3/smbd/proto.h
> +++ b/source3/smbd/proto.h
> @@ -412,6 +412,7 @@ NTSTATUS fsp_set_smb_fname(struct files_struct *fsp,
>  			   const struct smb_filename *smb_fname_in);
>  const struct GUID *fsp_client_guid(const files_struct *fsp);
>  uint32_t fsp_lease_type(struct files_struct *fsp);
> +size_t fsp_fullbasepath(struct files_struct *fsp, char *buf, size_t buflen);
>  
>  /* The following definitions come from smbd/ipc.c  */
>  
> -- 
> 2.1.4
> 
> 
> From 73ef43e851431777b2bba736a638e0eeda14dd48 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Mon, 13 Jun 2016 16:22:31 +0200
> Subject: [PATCH 05/18] smbd: Avoid a talloc_asprintf
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/smbd/notify.c | 17 ++++-------------
>  1 file changed, 4 insertions(+), 13 deletions(-)
> 
> diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
> index d7382db..2f07192 100644
> --- a/source3/smbd/notify.c
> +++ b/source3/smbd/notify.c
> @@ -251,8 +251,8 @@ static void notify_callback(void *private_data, struct timespec when,
>  NTSTATUS change_notify_create(struct files_struct *fsp, uint32_t filter,
>  			      bool recursive)
>  {
> -	char *fullpath;
> -	size_t len;
> +	size_t len = fsp_fullbasepath(fsp, NULL, 0);
> +	char fullpath[len+1];
>  	uint32_t subdir_filter;
>  	NTSTATUS status = NT_STATUS_NOT_IMPLEMENTED;
>  
> @@ -267,20 +267,11 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32_t filter,
>  		return NT_STATUS_NO_MEMORY;
>  	}
>  
> -	/* Do notify operations on the base_name. */
> -	fullpath = talloc_asprintf(
> -		talloc_tos(), "%s/%s", fsp->conn->connectpath,
> -		fsp->fsp_name->base_name);
> -	if (fullpath == NULL) {
> -		DEBUG(0, ("talloc_asprintf failed\n"));
> -		TALLOC_FREE(fsp->notify);
> -		return NT_STATUS_NO_MEMORY;
> -	}
> +	fsp_fullbasepath(fsp, fullpath, sizeof(fullpath));
>  
>  	/*
>  	 * Avoid /. at the end of the path name. notify can't deal with it.
>  	 */
> -	len = strlen(fullpath);
>  	if (len > 1 && fullpath[len-1] == '.' && fullpath[len-2] == '/') {
>  		fullpath[len-2] = '\0';
>  	}
> @@ -292,7 +283,7 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32_t filter,
>  				    fullpath, filter, subdir_filter,
>  				    notify_callback, fsp);
>  	}
> -	TALLOC_FREE(fullpath);
> +
>  	return status;
>  }
>  
> -- 
> 2.1.4
> 
> 
> From 001564ce955b0738a67549667dbdce9af1d7ce01 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Mon, 13 Jun 2016 18:06:08 +0200
> Subject: [PATCH 06/18] smbd: Add "path" to notify_remove
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/smbd/files.c      | 18 +++++++++++++++---
>  source3/smbd/notify_msg.c |  7 ++++---
>  source3/smbd/proto.h      |  3 ++-
>  3 files changed, 21 insertions(+), 7 deletions(-)
> 
> diff --git a/source3/smbd/files.c b/source3/smbd/files.c
> index f211c17..1ef1bc9 100644
> --- a/source3/smbd/files.c
> +++ b/source3/smbd/files.c
> @@ -518,9 +518,21 @@ void file_free(struct smb_request *req, files_struct *fsp)
>  	uint64_t fnum = fsp->fnum;
>  
>  	if (fsp->notify) {
> -		struct notify_context *notify_ctx =
> -			fsp->conn->sconn->notify_ctx;
> -		notify_remove(notify_ctx, fsp);
> +		size_t len = fsp_fullbasepath(fsp, NULL, 0);
> +		char fullpath[len+1];
> +
> +		fsp_fullbasepath(fsp, fullpath, sizeof(fullpath));
> +
> +		/*
> +		 * Avoid /. at the end of the path name. notify can't
> +		 * deal with it.
> +		 */
> +		if (len > 1 && fullpath[len-1] == '.' &&
> +		    fullpath[len-2] == '/') {
> +			fullpath[len-2] = '\0';
> +		}
> +
> +		notify_remove(fsp->conn->sconn->notify_ctx, fsp, fullpath);
>  		TALLOC_FREE(fsp->notify);
>  	}
>  
> diff --git a/source3/smbd/notify_msg.c b/source3/smbd/notify_msg.c
> index ea067d0..572ec3e 100644
> --- a/source3/smbd/notify_msg.c
> +++ b/source3/smbd/notify_msg.c
> @@ -176,7 +176,8 @@ NTSTATUS notify_add(struct notify_context *ctx,
>  	return NT_STATUS_OK;
>  }
>  
> -NTSTATUS notify_remove(struct notify_context *ctx, void *private_data)
> +NTSTATUS notify_remove(struct notify_context *ctx, void *private_data,
> +		       char *path)
>  {
>  	struct notify_list *listel;
>  	struct notify_rec_change_msg msg = {};
> @@ -203,8 +204,8 @@ NTSTATUS notify_remove(struct notify_context *ctx, void *private_data)
>  
>  	iov[0].iov_base = &msg;
>  	iov[0].iov_len = offsetof(struct notify_rec_change_msg, path);
> -	iov[1].iov_base = discard_const_p(char, listel->path);
> -	iov[1].iov_len = strlen(listel->path)+1;
> +	iov[1].iov_base = path;
> +	iov[1].iov_len = strlen(path)+1;
>  
>  	status = messaging_send_iov(
>  		ctx->msg_ctx, ctx->notifyd, MSG_SMB_NOTIFY_REC_CHANGE,
> diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
> index 764673c..9706fb0 100644
> --- a/source3/smbd/proto.h
> +++ b/source3/smbd/proto.h
> @@ -589,7 +589,8 @@ NTSTATUS notify_add(struct notify_context *notify,
>  		    void (*callback)(void *, struct timespec,
>  				     const struct notify_event *),
>  		    void *private_data);
> -NTSTATUS notify_remove(struct notify_context *notify, void *private_data);
> +NTSTATUS notify_remove(struct notify_context *ctx, void *private_data,
> +		       char *path);
>  void notify_trigger(struct notify_context *notify,
>  		    uint32_t action, uint32_t filter,
>  		    const char *dir, const char *path);
> -- 
> 2.1.4
> 
> 
> From e5c0eadcf868c4147d8b3d3bc2e891a355ff8653 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Mon, 13 Jun 2016 18:08:58 +0200
> Subject: [PATCH 07/18] smbd: "path" is no longer needed in notify_list
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/smbd/notify_msg.c | 5 +----
>  1 file changed, 1 insertion(+), 4 deletions(-)
> 
> diff --git a/source3/smbd/notify_msg.c b/source3/smbd/notify_msg.c
> index 572ec3e..817bc79 100644
> --- a/source3/smbd/notify_msg.c
> +++ b/source3/smbd/notify_msg.c
> @@ -35,7 +35,6 @@ struct notify_list {
>  	void (*callback)(void *private_data, struct timespec when,
>  			 const struct notify_event *ctx);
>  	void *private_data;
> -	char path[1];
>  };
>  
>  struct notify_context {
> @@ -142,14 +141,12 @@ NTSTATUS notify_add(struct notify_context *ctx,
>  
>  	pathlen = strlen(path)+1;
>  
> -	listel = (struct notify_list *)talloc_size(
> -		ctx, offsetof(struct notify_list, path) + pathlen);
> +	listel = (struct notify_list *)talloc(ctx, struct notify_list);
>  	if (listel == NULL) {
>  		return NT_STATUS_NO_MEMORY;
>  	}
>  	listel->callback = callback;
>  	listel->private_data = private_data;
> -	memcpy(listel->path, path, pathlen);
>  
>  	clock_gettime_mono(&msg.instance.creation_time);
>  	msg.instance.filter = filter;
> -- 
> 2.1.4
> 
> 
> From 21905de075a55e58f1de4a2cefdc5eba61855d93 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Tue, 14 Jun 2016 06:54:11 +0200
> Subject: [PATCH 08/18] smbd: Make notify_callback() public
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/smbd/notify.c | 4 ++--
>  source3/smbd/proto.h  | 2 ++
>  2 files changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
> index 2f07192..c824ced 100644
> --- a/source3/smbd/notify.c
> +++ b/source3/smbd/notify.c
> @@ -240,8 +240,8 @@ void change_notify_reply(struct smb_request *req,
>  	notify_buf->num_changes = 0;
>  }
>  
> -static void notify_callback(void *private_data, struct timespec when,
> -			    const struct notify_event *e)
> +void notify_callback(void *private_data, struct timespec when,
> +		     const struct notify_event *e)
>  {
>  	files_struct *fsp = (files_struct *)private_data;
>  	DEBUG(10, ("notify_callback called for %s\n", fsp_str_dbg(fsp)));
> diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
> index 9706fb0..f3b9e73 100644
> --- a/source3/smbd/proto.h
> +++ b/source3/smbd/proto.h
> @@ -530,6 +530,8 @@ void change_notify_reply(struct smb_request *req,
>  			 void (*reply_fn)(struct smb_request *req,
>  					  NTSTATUS error_code,
>  					  uint8_t *buf, size_t len));
> +void notify_callback(void *private_data, struct timespec when,
> +		     const struct notify_event *e);
>  NTSTATUS change_notify_create(struct files_struct *fsp, uint32_t filter,
>  			      bool recursive);
>  NTSTATUS change_notify_add_request(struct smb_request *req,
> -- 
> 2.1.4
> 
> 
> From f1156b08fcc77795de8808d7712e4c3339b62530 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Tue, 14 Jun 2016 11:55:13 +0200
> Subject: [PATCH 09/18] smbd: There's only one notify_callback
> 
> We do not have different callbacks per notify, put the callback function into
> the notify context
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/smbd/notify.c     |  3 +--
>  source3/smbd/notify_msg.c | 35 +++++++++++++++++++----------------
>  source3/smbd/proto.h      | 12 ++++++------
>  source3/smbd/service.c    |  3 ++-
>  source3/utils/status.c    |  2 +-
>  5 files changed, 29 insertions(+), 26 deletions(-)
> 
> diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
> index c824ced..f493f11 100644
> --- a/source3/smbd/notify.c
> +++ b/source3/smbd/notify.c
> @@ -280,8 +280,7 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32_t filter,
>  
>  	if ((filter != 0) || (subdir_filter != 0)) {
>  		status = notify_add(fsp->conn->sconn->notify_ctx,
> -				    fullpath, filter, subdir_filter,
> -				    notify_callback, fsp);
> +				    fullpath, filter, subdir_filter, fsp);
>  	}
>  
>  	return status;
> diff --git a/source3/smbd/notify_msg.c b/source3/smbd/notify_msg.c
> index 817bc79..e9f9199 100644
> --- a/source3/smbd/notify_msg.c
> +++ b/source3/smbd/notify_msg.c
> @@ -32,8 +32,6 @@
>  
>  struct notify_list {
>  	struct notify_list *next, *prev;
> -	void (*callback)(void *private_data, struct timespec when,
> -			 const struct notify_event *ctx);
>  	void *private_data;
>  };
>  
> @@ -41,15 +39,19 @@ struct notify_context {
>  	struct server_id notifyd;
>  	struct messaging_context *msg_ctx;
>  	struct notify_list *list;
> +	void (*callback)(void *private_data, struct timespec when,
> +			 const struct notify_event *ctx);
>  };
>  
>  static void notify_handler(struct messaging_context *msg, void *private_data,
>  			   uint32_t msg_type, struct server_id src,
>  			   DATA_BLOB *data);
>  
> -struct notify_context *notify_init(TALLOC_CTX *mem_ctx,
> -				   struct messaging_context *msg,
> -				   struct tevent_context *ev)
> +struct notify_context *notify_init(
> +	TALLOC_CTX *mem_ctx, struct messaging_context *msg,
> +	struct tevent_context *ev,
> +	void (*callback)(void *, struct timespec,
> +			 const struct notify_event *))
>  {
>  	struct server_id_db *names_db;
>  	struct notify_context *ctx;
> @@ -61,6 +63,7 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx,
>  	}
>  	ctx->msg_ctx = msg;
>  	ctx->list = NULL;
> +	ctx->callback = callback;
>  
>  	names_db = messaging_names_db(msg);
>  	if (!server_id_db_lookup_one(names_db, "notify-daemon",
> @@ -70,12 +73,15 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx,
>  		return NULL;
>  	}
>  
> -	status = messaging_register(msg, ctx, MSG_PVFS_NOTIFY, notify_handler);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		DEBUG(1, ("messaging_register failed: %s\n",
> -			  nt_errstr(status)));
> -		TALLOC_FREE(ctx);
> -		return NULL;
> +	if (callback != NULL) {
> +		status = messaging_register(msg, ctx, MSG_PVFS_NOTIFY,
> +					    notify_handler);
> +		if (!NT_STATUS_IS_OK(status)) {
> +			DEBUG(1, ("messaging_register failed: %s\n",
> +				  nt_errstr(status)));
> +			TALLOC_FREE(ctx);
> +			return NULL;
> +		}
>  	}
>  
>  	return ctx;
> @@ -112,8 +118,8 @@ static void notify_handler(struct messaging_context *msg, void *private_data,
>  
>  	for (listel = ctx->list; listel != NULL; listel = listel->next) {
>  		if (listel->private_data == event.private_data) {
> -			listel->callback(listel->private_data, event_msg->when,
> -					 &event);
> +			ctx->callback(listel->private_data, event_msg->when,
> +				      &event);
>  			break;
>  		}
>  	}
> @@ -121,8 +127,6 @@ static void notify_handler(struct messaging_context *msg, void *private_data,
>  
>  NTSTATUS notify_add(struct notify_context *ctx,
>  		    const char *path, uint32_t filter, uint32_t subdir_filter,
> -		    void (*callback)(void *, struct timespec,
> -				     const struct notify_event *),
>  		    void *private_data)
>  {
>  	struct notify_list *listel;
> @@ -145,7 +149,6 @@ NTSTATUS notify_add(struct notify_context *ctx,
>  	if (listel == NULL) {
>  		return NT_STATUS_NO_MEMORY;
>  	}
> -	listel->callback = callback;
>  	listel->private_data = private_data;
>  
>  	clock_gettime_mono(&msg.instance.creation_time);
> diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
> index f3b9e73..b677748 100644
> --- a/source3/smbd/proto.h
> +++ b/source3/smbd/proto.h
> @@ -583,13 +583,13 @@ int fam_watch(TALLOC_CTX *mem_ctx,
>  
>  /* The following definitions come from smbd/notify_internal.c  */
>  
> -struct notify_context *notify_init(TALLOC_CTX *mem_ctx,
> -				   struct messaging_context *messaging_ctx,
> -				   struct tevent_context *ev);
> -NTSTATUS notify_add(struct notify_context *notify,
> +struct notify_context *notify_init(
> +	TALLOC_CTX *mem_ctx, struct messaging_context *msg,
> +	struct tevent_context *ev,
> +	void (*callback)(void *, struct timespec,
> +			 const struct notify_event *));
> +NTSTATUS notify_add(struct notify_context *ctx,
>  		    const char *path, uint32_t filter, uint32_t subdir_filter,
> -		    void (*callback)(void *, struct timespec,
> -				     const struct notify_event *),
>  		    void *private_data);
>  NTSTATUS notify_remove(struct notify_context *ctx, void *private_data,
>  		       char *path);
> diff --git a/source3/smbd/service.c b/source3/smbd/service.c
> index 37440e0..4b16dba 100644
> --- a/source3/smbd/service.c
> +++ b/source3/smbd/service.c
> @@ -528,7 +528,8 @@ static NTSTATUS notify_init_sconn(struct smbd_server_connection *sconn)
>  		return NT_STATUS_OK;
>  	}
>  
> -	sconn->notify_ctx = notify_init(sconn, sconn->msg_ctx, sconn->ev_ctx);
> +	sconn->notify_ctx = notify_init(sconn, sconn->msg_ctx, sconn->ev_ctx,
> +					notify_callback);
>  	if (sconn->notify_ctx == NULL) {
>  		return NT_STATUS_NO_MEMORY;
>  	}
> diff --git a/source3/utils/status.c b/source3/utils/status.c
> index 9aefd5e..7bff102 100644
> --- a/source3/utils/status.c
> +++ b/source3/utils/status.c
> @@ -708,7 +708,7 @@ int main(int argc, const char *argv[])
>  		struct notify_context *n;
>  
>  		n = notify_init(talloc_tos(), msg_ctx,
> -				messaging_tevent_context(msg_ctx));
> +				messaging_tevent_context(msg_ctx), NULL);
>  		if (n == NULL) {
>  			goto done;
>  		}
> -- 
> 2.1.4
> 
> 
> From 045190b869263422c64462389a9ff70fc6356162 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Tue, 14 Jun 2016 14:54:32 +0200
> Subject: [PATCH 10/18] smbd: Pass "sconn" via notify to notify_callback()
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/smbd/notify.c     |  3 ++-
>  source3/smbd/notify_msg.c | 15 +++++++++++----
>  source3/smbd/proto.h      |  7 +++++--
>  source3/smbd/service.c    |  2 +-
>  source3/utils/status.c    |  3 ++-
>  5 files changed, 21 insertions(+), 9 deletions(-)
> 
> diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
> index f493f11..7a436a9 100644
> --- a/source3/smbd/notify.c
> +++ b/source3/smbd/notify.c
> @@ -240,7 +240,8 @@ void change_notify_reply(struct smb_request *req,
>  	notify_buf->num_changes = 0;
>  }
>  
> -void notify_callback(void *private_data, struct timespec when,
> +void notify_callback(struct smbd_server_connection *sconn,
> +		     void *private_data, struct timespec when,
>  		     const struct notify_event *e)
>  {
>  	files_struct *fsp = (files_struct *)private_data;
> diff --git a/source3/smbd/notify_msg.c b/source3/smbd/notify_msg.c
> index e9f9199..cd9a0fb 100644
> --- a/source3/smbd/notify_msg.c
> +++ b/source3/smbd/notify_msg.c
> @@ -39,7 +39,10 @@ struct notify_context {
>  	struct server_id notifyd;
>  	struct messaging_context *msg_ctx;
>  	struct notify_list *list;
> -	void (*callback)(void *private_data, struct timespec when,
> +
> +	struct smbd_server_connection *sconn;
> +	void (*callback)(struct smbd_server_connection *sconn,
> +			 void *private_data, struct timespec when,
>  			 const struct notify_event *ctx);
>  };
>  
> @@ -50,7 +53,9 @@ static void notify_handler(struct messaging_context *msg, void *private_data,
>  struct notify_context *notify_init(
>  	TALLOC_CTX *mem_ctx, struct messaging_context *msg,
>  	struct tevent_context *ev,
> -	void (*callback)(void *, struct timespec,
> +	struct smbd_server_connection *sconn,
> +	void (*callback)(struct smbd_server_connection *sconn,
> +			 void *, struct timespec,
>  			 const struct notify_event *))
>  {
>  	struct server_id_db *names_db;
> @@ -63,6 +68,8 @@ struct notify_context *notify_init(
>  	}
>  	ctx->msg_ctx = msg;
>  	ctx->list = NULL;
> +
> +	ctx->sconn = sconn;
>  	ctx->callback = callback;
>  
>  	names_db = messaging_names_db(msg);
> @@ -118,8 +125,8 @@ static void notify_handler(struct messaging_context *msg, void *private_data,
>  
>  	for (listel = ctx->list; listel != NULL; listel = listel->next) {
>  		if (listel->private_data == event.private_data) {
> -			ctx->callback(listel->private_data, event_msg->when,
> -				      &event);
> +			ctx->callback(ctx->sconn, listel->private_data,
> +				      event_msg->when, &event);
>  			break;
>  		}
>  	}
> diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
> index b677748..97d738c 100644
> --- a/source3/smbd/proto.h
> +++ b/source3/smbd/proto.h
> @@ -530,7 +530,8 @@ void change_notify_reply(struct smb_request *req,
>  			 void (*reply_fn)(struct smb_request *req,
>  					  NTSTATUS error_code,
>  					  uint8_t *buf, size_t len));
> -void notify_callback(void *private_data, struct timespec when,
> +void notify_callback(struct smbd_server_connection *sconn,
> +		     void *private_data, struct timespec when,
>  		     const struct notify_event *e);
>  NTSTATUS change_notify_create(struct files_struct *fsp, uint32_t filter,
>  			      bool recursive);
> @@ -586,7 +587,9 @@ int fam_watch(TALLOC_CTX *mem_ctx,
>  struct notify_context *notify_init(
>  	TALLOC_CTX *mem_ctx, struct messaging_context *msg,
>  	struct tevent_context *ev,
> -	void (*callback)(void *, struct timespec,
> +	struct smbd_server_connection *sconn,
> +	void (*callback)(struct smbd_server_connection *sconn,
> +			 void *, struct timespec,
>  			 const struct notify_event *));
>  NTSTATUS notify_add(struct notify_context *ctx,
>  		    const char *path, uint32_t filter, uint32_t subdir_filter,
> diff --git a/source3/smbd/service.c b/source3/smbd/service.c
> index 4b16dba..ef434f9 100644
> --- a/source3/smbd/service.c
> +++ b/source3/smbd/service.c
> @@ -529,7 +529,7 @@ static NTSTATUS notify_init_sconn(struct smbd_server_connection *sconn)
>  	}
>  
>  	sconn->notify_ctx = notify_init(sconn, sconn->msg_ctx, sconn->ev_ctx,
> -					notify_callback);
> +					sconn, notify_callback);
>  	if (sconn->notify_ctx == NULL) {
>  		return NT_STATUS_NO_MEMORY;
>  	}
> diff --git a/source3/utils/status.c b/source3/utils/status.c
> index 7bff102..f185663 100644
> --- a/source3/utils/status.c
> +++ b/source3/utils/status.c
> @@ -708,7 +708,8 @@ int main(int argc, const char *argv[])
>  		struct notify_context *n;
>  
>  		n = notify_init(talloc_tos(), msg_ctx,
> -				messaging_tevent_context(msg_ctx), NULL);
> +				messaging_tevent_context(msg_ctx),
> +				NULL, NULL);
>  		if (n == NULL) {
>  			goto done;
>  		}
> -- 
> 2.1.4
> 
> 
> From 0f88d21fc374147ac4fb379cfcda932929e5e0e0 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Tue, 14 Jun 2016 15:00:29 +0200
> Subject: [PATCH 11/18] smbd: Protect notify_callback from stray pointers
> 
> This protection right now lives in notify_msg.c with the notify_list, but that
> will go.
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/smbd/notify.c | 27 ++++++++++++++++++++++++---
>  1 file changed, 24 insertions(+), 3 deletions(-)
> 
> diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
> index 7a436a9..c2d5d40 100644
> --- a/source3/smbd/notify.c
> +++ b/source3/smbd/notify.c
> @@ -240,13 +240,34 @@ void change_notify_reply(struct smb_request *req,
>  	notify_buf->num_changes = 0;
>  }
>  
> +struct notify_fsp_state {
> +	struct files_struct *notified_fsp;
> +	struct timespec when;
> +	const struct notify_event *e;
> +};
> +
> +static struct files_struct *notify_fsp_cb(struct files_struct *fsp,
> +					  void *private_data)
> +{
> +	struct notify_fsp_state *state = private_data;
> +
> +	if (fsp == state->notified_fsp) {
> +		DBG_DEBUG("notify_callback called for %s\n", fsp_str_dbg(fsp));
> +		notify_fsp(fsp, state->when, state->e->action, state->e->path);
> +		return fsp;
> +	}
> +
> +	return NULL;
> +}
> +
>  void notify_callback(struct smbd_server_connection *sconn,
>  		     void *private_data, struct timespec when,
>  		     const struct notify_event *e)
>  {
> -	files_struct *fsp = (files_struct *)private_data;
> -	DEBUG(10, ("notify_callback called for %s\n", fsp_str_dbg(fsp)));
> -	notify_fsp(fsp, when, e->action, e->path);
> +	struct notify_fsp_state state = {
> +		.notified_fsp = private_data, .when = when, .e = e
> +	};
> +	files_forall(sconn, notify_fsp_cb, &state);
>  }
>  
>  NTSTATUS change_notify_create(struct files_struct *fsp, uint32_t filter,
> -- 
> 2.1.4
> 
> 
> From bf78113b97c22bbb1e983dd5884530337477f323 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Tue, 14 Jun 2016 15:03:35 +0200
> Subject: [PATCH 12/18] smbd: Remove "listel" from notify_msg
> 
> We have all information that was kept in "notify_list" in other parts of smbd
> as well. The only possible downside of this patch is that we possibly have a
> lot more fsp's than fsp's with notifies, so notify_callback() might be a bit
> slower in this situation. If this turns out to be a problem, I'd rather put
> some more smarts into the notifyd protocol to enable a better indexed
> notify_callback(). For now, this avoids data to be kept in two places.
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/smbd/notify_msg.c | 38 +-------------------------------------
>  1 file changed, 1 insertion(+), 37 deletions(-)
> 
> diff --git a/source3/smbd/notify_msg.c b/source3/smbd/notify_msg.c
> index cd9a0fb..1379fc4 100644
> --- a/source3/smbd/notify_msg.c
> +++ b/source3/smbd/notify_msg.c
> @@ -30,15 +30,9 @@
>  #include "lib/util/server_id_db.h"
>  #include "smbd/notifyd/notifyd.h"
>  
> -struct notify_list {
> -	struct notify_list *next, *prev;
> -	void *private_data;
> -};
> -
>  struct notify_context {
>  	struct server_id notifyd;
>  	struct messaging_context *msg_ctx;
> -	struct notify_list *list;
>  
>  	struct smbd_server_connection *sconn;
>  	void (*callback)(struct smbd_server_connection *sconn,
> @@ -67,7 +61,6 @@ struct notify_context *notify_init(
>  		return NULL;
>  	}
>  	ctx->msg_ctx = msg;
> -	ctx->list = NULL;
>  
>  	ctx->sconn = sconn;
>  	ctx->callback = callback;
> @@ -102,7 +95,6 @@ static void notify_handler(struct messaging_context *msg, void *private_data,
>  		private_data, struct notify_context);
>  	struct notify_event_msg *event_msg;
>  	struct notify_event event;
> -	struct notify_list *listel;
>  
>  	if (data->length < offsetof(struct notify_event_msg, path) + 1) {
>  		DEBUG(1, ("message too short: %u\n", (unsigned)data->length));
> @@ -123,20 +115,13 @@ static void notify_handler(struct messaging_context *msg, void *private_data,
>  		   "path=%s\n", __func__, (unsigned)event.action,
>  		   event.private_data, event.path));
>  
> -	for (listel = ctx->list; listel != NULL; listel = listel->next) {
> -		if (listel->private_data == event.private_data) {
> -			ctx->callback(ctx->sconn, listel->private_data,
> -				      event_msg->when, &event);
> -			break;
> -		}
> -	}
> +	ctx->callback(ctx->sconn, event.private_data, event_msg->when, &event);
>  }
>  
>  NTSTATUS notify_add(struct notify_context *ctx,
>  		    const char *path, uint32_t filter, uint32_t subdir_filter,
>  		    void *private_data)
>  {
> -	struct notify_list *listel;
>  	struct notify_rec_change_msg msg = {};
>  	struct iovec iov[2];
>  	size_t pathlen;
> @@ -152,12 +137,6 @@ NTSTATUS notify_add(struct notify_context *ctx,
>  
>  	pathlen = strlen(path)+1;
>  
> -	listel = (struct notify_list *)talloc(ctx, struct notify_list);
> -	if (listel == NULL) {
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -	listel->private_data = private_data;
> -
>  	clock_gettime_mono(&msg.instance.creation_time);
>  	msg.instance.filter = filter;
>  	msg.instance.subdir_filter = subdir_filter;
> @@ -173,20 +152,17 @@ NTSTATUS notify_add(struct notify_context *ctx,
>  		iov, ARRAY_SIZE(iov), NULL, 0);
>  
>  	if (!NT_STATUS_IS_OK(status)) {
> -		TALLOC_FREE(listel);
>  		DEBUG(10, ("messaging_send_iov returned %s\n",
>  			   nt_errstr(status)));
>  		return status;
>  	}
>  
> -	DLIST_ADD(ctx->list, listel);
>  	return NT_STATUS_OK;
>  }
>  
>  NTSTATUS notify_remove(struct notify_context *ctx, void *private_data,
>  		       char *path)
>  {
> -	struct notify_list *listel;
>  	struct notify_rec_change_msg msg = {};
>  	struct iovec iov[2];
>  	NTSTATUS status;
> @@ -196,17 +172,6 @@ NTSTATUS notify_remove(struct notify_context *ctx, void *private_data,
>  		return NT_STATUS_NOT_IMPLEMENTED;
>  	}
>  
> -	for (listel = ctx->list; listel != NULL; listel = listel->next) {
> -		if (listel->private_data == private_data) {
> -			DLIST_REMOVE(ctx->list, listel);
> -			break;
> -		}
> -	}
> -	if (listel == NULL) {
> -		DEBUG(10, ("%p not found\n", private_data));
> -		return NT_STATUS_NOT_FOUND;
> -	}
> -
>  	msg.instance.private_data = private_data;
>  
>  	iov[0].iov_base = &msg;
> @@ -218,7 +183,6 @@ NTSTATUS notify_remove(struct notify_context *ctx, void *private_data,
>  		ctx->msg_ctx, ctx->notifyd, MSG_SMB_NOTIFY_REC_CHANGE,
>  		iov, ARRAY_SIZE(iov), NULL, 0);
>  
> -	TALLOC_FREE(listel);
>  	return status;
>  }
>  
> -- 
> 2.1.4
> 
> 
> From d410ba1f67054b72ff859832c9ba6938b94b5068 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Tue, 21 Jun 2016 13:04:25 +0200
> Subject: [PATCH 13/18] notify_msg: Deregister handler upon talloc_free
> 
> So far, we haven't TALLOC_FREE'ed the notify context. This will change.
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/smbd/notify_msg.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/source3/smbd/notify_msg.c b/source3/smbd/notify_msg.c
> index 1379fc4..d349e91 100644
> --- a/source3/smbd/notify_msg.c
> +++ b/source3/smbd/notify_msg.c
> @@ -43,6 +43,7 @@ struct notify_context {
>  static void notify_handler(struct messaging_context *msg, void *private_data,
>  			   uint32_t msg_type, struct server_id src,
>  			   DATA_BLOB *data);
> +static int notify_context_destructor(struct notify_context *ctx);
>  
>  struct notify_context *notify_init(
>  	TALLOC_CTX *mem_ctx, struct messaging_context *msg,
> @@ -84,9 +85,20 @@ struct notify_context *notify_init(
>  		}
>  	}
>  
> +	talloc_set_destructor(ctx, notify_context_destructor);
> +
>  	return ctx;
>  }
>  
> +static int notify_context_destructor(struct notify_context *ctx)
> +{
> +	if (ctx->callback != NULL) {
> +		messaging_deregister(ctx->msg_ctx, MSG_PVFS_NOTIFY, ctx);
> +	}
> +
> +	return 0;
> +}
> +
>  static void notify_handler(struct messaging_context *msg, void *private_data,
>  			   uint32_t msg_type, struct server_id src,
>  			   DATA_BLOB *data)
> -- 
> 2.1.4
> 
> 
> From 6b735bab19381d6a0a56f98b372ffaeecbcf6a8f Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Tue, 21 Jun 2016 14:13:06 +0200
> Subject: [PATCH 14/18] smbd: Remember notifyd's serverid
> 
> Similarly to cleanupd, this is necessary to restart notifyd
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/smbd/server.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/source3/smbd/server.c b/source3/smbd/server.c
> index 07eca51..8875bcd 100644
> --- a/source3/smbd/server.c
> +++ b/source3/smbd/server.c
> @@ -73,6 +73,7 @@ struct smbd_parent_context {
>  	size_t num_children;
>  
>  	struct server_id cleanupd;
> +	struct server_id notifyd;
>  
>  	struct tevent_timer *cleanup_te;
>  };
> @@ -374,7 +375,8 @@ static void notifyd_stopped(struct tevent_req *req)
>  	DEBUG(1, ("notifyd stopped: %s\n", strerror(ret)));
>  }
>  
> -static bool smbd_notifyd_init(struct messaging_context *msg, bool interactive)
> +static bool smbd_notifyd_init(struct messaging_context *msg, bool interactive,
> +			      struct server_id *ppid)
>  {
>  	struct tevent_context *ev = messaging_tevent_context(msg);
>  	struct tevent_req *req;
> @@ -394,6 +396,10 @@ static bool smbd_notifyd_init(struct messaging_context *msg, bool interactive)
>  	}
>  
>  	if (pid != 0) {
> +		if (am_parent != 0) {
> +			add_child_pid(am_parent, pid);
> +		}
> +		*ppid = pid_to_procid(pid);
>  		return true;
>  	}
>  
> @@ -1600,7 +1606,7 @@ extern void build_options(bool screen);
>  		exit_daemon("Samba cannot init leases", EACCES);
>  	}
>  
> -	if (!smbd_notifyd_init(msg_ctx, interactive)) {
> +	if (!smbd_notifyd_init(msg_ctx, interactive, &parent->notifyd)) {
>  		exit_daemon("Samba cannot init notification", EACCES);
>  	}
>  
> -- 
> 2.1.4
> 
> 
> From d609320b9027686ddde5b82ef3cb8f9019eaf116 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Thu, 23 Jun 2016 14:24:32 +0200
> Subject: [PATCH 15/18] smbd: Log which notifyd was found
> 
> Just a debugging aid
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/smbd/notify_msg.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/source3/smbd/notify_msg.c b/source3/smbd/notify_msg.c
> index d349e91..20b2864 100644
> --- a/source3/smbd/notify_msg.c
> +++ b/source3/smbd/notify_msg.c
> @@ -74,6 +74,12 @@ struct notify_context *notify_init(
>  		return NULL;
>  	}
>  
> +	{
> +		struct server_id_buf tmp;
> +		DBG_DEBUG("notifyd=%s\n",
> +			  server_id_str_buf(ctx->notifyd, &tmp));
> +	}
> +
>  	if (callback != NULL) {
>  		status = messaging_register(msg, ctx, MSG_PVFS_NOTIFY,
>  					    notify_handler);
> -- 
> 2.1.4
> 
> 
> From 7d0b95c6c9238b92b8edd103718246bf56a3421d Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Fri, 24 Jun 2016 16:27:34 +0200
> Subject: [PATCH 16/18] smbd: Store notify filters in fsp->notify
> 
> When notifyd crashes, it will be restarted. We need to restore the filters with
> notifyd
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/smbd/notify.c | 17 ++++++++++++-----
>  1 file changed, 12 insertions(+), 5 deletions(-)
> 
> diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
> index c2d5d40..4837ca5 100644
> --- a/source3/smbd/notify.c
> +++ b/source3/smbd/notify.c
> @@ -33,6 +33,12 @@ struct notify_change_event {
>  
>  struct notify_change_buf {
>  	/*
> +	 * Filters for reinitializing after notifyd has been restarted
> +	 */
> +	uint32_t filter;
> +	uint32_t subdir_filter;
> +
> +	/*
>  	 * If no requests are pending, changes are queued here. Simple array,
>  	 * we only append.
>  	 */
> @@ -275,7 +281,6 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32_t filter,
>  {
>  	size_t len = fsp_fullbasepath(fsp, NULL, 0);
>  	char fullpath[len+1];
> -	uint32_t subdir_filter;
>  	NTSTATUS status = NT_STATUS_NOT_IMPLEMENTED;
>  
>  	if (fsp->notify != NULL) {
> @@ -288,6 +293,8 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32_t filter,
>  		DEBUG(0, ("talloc failed\n"));
>  		return NT_STATUS_NO_MEMORY;
>  	}
> +	fsp->notify->filter = filter;
> +	fsp->notify->subdir_filter = recursive ? filter : 0;
>  
>  	fsp_fullbasepath(fsp, fullpath, sizeof(fullpath));
>  
> @@ -298,11 +305,11 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32_t filter,
>  		fullpath[len-2] = '\0';
>  	}
>  
> -	subdir_filter = recursive ? filter : 0;
> -
> -	if ((filter != 0) || (subdir_filter != 0)) {
> +	if ((fsp->notify->filter != 0) ||
> +	    (fsp->notify->subdir_filter != 0)) {
>  		status = notify_add(fsp->conn->sconn->notify_ctx,
> -				    fullpath, filter, subdir_filter, fsp);
> +				    fullpath, fsp->notify->filter,
> +				    fsp->notify->subdir_filter, fsp);
>  	}
>  
>  	return status;
> -- 
> 2.1.4
> 
> 
> From 16d4cfffe48367815a68613486983669aad4c624 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Fri, 24 Jun 2016 16:29:28 +0200
> Subject: [PATCH 17/18] smbd: Restart notifyd
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  source3/smbd/server.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/source3/smbd/server.c b/source3/smbd/server.c
> index 8875bcd..27cf770 100644
> --- a/source3/smbd/server.c
> +++ b/source3/smbd/server.c
> @@ -595,6 +595,18 @@ static void remove_child_pid(struct smbd_parent_context *parent,
>  		return;
>  	}
>  
> +	if (pid == procid_to_pid(&parent->notifyd)) {
> +		bool ok;
> +
> +		DBG_WARNING("Restarting notifyd\n");
> +		ok = smbd_notifyd_init(parent->msg_ctx, false,
> +				       &parent->notifyd);
> +		if (!ok) {
> +			DBG_ERR("Failed to restart notifyd\n");
> +		}
> +		return;
> +	}
> +
>  	iov[0] = (struct iovec) { .iov_base = (uint8_t *)&pid,
>  				  .iov_len = sizeof(pid) };
>  	iov[1] = (struct iovec) { .iov_base = (uint8_t *)&unclean_shutdown,
> -- 
> 2.1.4
> 
> 
> From 84b5e3507beafcf148f75509c69aaa6ee1121750 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Tue, 21 Jun 2016 16:23:19 +0200
> Subject: [PATCH 18/18] smbd: Re-register notify requests
> 
> When notifyd is restarted, the parent will broadcast that fact to all workers.
> They will then re-register their notify requests.
> 
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
>  librpc/idl/messaging.idl |  1 +
>  source3/smbd/notify.c    | 50 ++++++++++++++++++++++++++++++++++++++++++++++++
>  source3/smbd/proto.h     |  3 +++
>  source3/smbd/server.c    |  6 ++++++
>  source3/smbd/service.c   | 12 ++++++++++++
>  5 files changed, 72 insertions(+)
> 
> diff --git a/librpc/idl/messaging.idl b/librpc/idl/messaging.idl
> index 6232322..a54d13c 100644
> --- a/librpc/idl/messaging.idl
> +++ b/librpc/idl/messaging.idl
> @@ -105,6 +105,7 @@ interface messaging
>  		MSG_SMB_NOTIFY_GET_DB		= 0x031C,
>  		MSG_SMB_NOTIFY_DB		= 0x031D,
>  		MSG_SMB_NOTIFY_REC_CHANGES	= 0x031E,
> +		MSG_SMB_NOTIFY_STARTED          = 0x031F,
>  
>  		/* winbind messages */
>  		MSG_WINBIND_FINISHED		= 0x0401,
> diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
> index 4837ca5..f64185d 100644
> --- a/source3/smbd/notify.c
> +++ b/source3/smbd/notify.c
> @@ -490,6 +490,56 @@ done:
>  	TALLOC_FREE(fid);
>  }
>  
> +static struct files_struct *smbd_notifyd_reregister(struct files_struct *fsp,
> +						    void *private_data)
> +{
> +	DBG_DEBUG("reregister %s\n", fsp->fsp_name->base_name);
> +
> +	if ((fsp->conn->sconn->notify_ctx != NULL) &&
> +	    (fsp->notify != NULL) &&
> +	    ((fsp->notify->filter != 0) ||
> +	     (fsp->notify->subdir_filter != 0))) {
> +		size_t len = fsp_fullbasepath(fsp, NULL, 0);
> +		char fullpath[len+1];
> +
> +		NTSTATUS status;
> +
> +		fsp_fullbasepath(fsp, fullpath, sizeof(fullpath));
> +		if (len > 1 && fullpath[len-1] == '.' &&
> +		    fullpath[len-2] == '/') {
> +			fullpath[len-2] = '\0';
> +		}
> +
> +		status = notify_add(fsp->conn->sconn->notify_ctx,
> +				    fullpath, fsp->notify->filter,
> +				    fsp->notify->subdir_filter, fsp);
> +		if (!NT_STATUS_IS_OK(status)) {
> +			DBG_DEBUG("notify_add failed: %s\n",
> +				  nt_errstr(status));
> +		}
> +	}
> +	return NULL;
> +}
> +
> +void smbd_notifyd_restarted(struct messaging_context *msg,
> +			    void *private_data, uint32_t msg_type,
> +			    struct server_id server_id, DATA_BLOB *data)
> +{
> +	struct smbd_server_connection *sconn = talloc_get_type_abort(
> +		private_data, struct smbd_server_connection);
> +
> +	TALLOC_FREE(sconn->notify_ctx);
> +
> +	sconn->notify_ctx = notify_init(sconn, sconn->msg_ctx, sconn->ev_ctx,
> +					sconn, notify_callback);
> +	if (sconn->notify_ctx == NULL) {
> +		DBG_DEBUG("notify_init failed\n");
> +		return;
> +	}
> +
> +	files_forall(sconn, smbd_notifyd_reregister, sconn->notify_ctx);
> +}
> +
>  /****************************************************************************
>   Delete entries by fnum from the change notify pending queue.
>  *****************************************************************************/
> diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
> index 97d738c..26fec95 100644
> --- a/source3/smbd/proto.h
> +++ b/source3/smbd/proto.h
> @@ -545,6 +545,9 @@ NTSTATUS change_notify_add_request(struct smb_request *req,
>  void smbd_notify_cancel_deleted(struct messaging_context *msg,
>  				void *private_data, uint32_t msg_type,
>  				struct server_id server_id, DATA_BLOB *data);
> +void smbd_notifyd_restarted(struct messaging_context *msg,
> +			    void *private_data, uint32_t msg_type,
> +			    struct server_id server_id, DATA_BLOB *data);
>  void remove_pending_change_notify_requests_by_mid(
>  	struct smbd_server_connection *sconn, uint64_t mid);
>  void remove_pending_change_notify_requests_by_fid(files_struct *fsp,
> diff --git a/source3/smbd/server.c b/source3/smbd/server.c
> index 27cf770..0d7e43b 100644
> --- a/source3/smbd/server.c
> +++ b/source3/smbd/server.c
> @@ -415,6 +415,10 @@ static bool smbd_notifyd_init(struct messaging_context *msg, bool interactive,
>  		exit(1);
>  	}
>  	tevent_req_set_callback(req, notifyd_stopped, msg);
> +
> +	messaging_send(msg, pid_to_procid(getppid()), MSG_SMB_NOTIFY_STARTED,
> +		       NULL);
> +
>  	return tevent_req_poll(req, ev);
>  }
>  
> @@ -1050,6 +1054,8 @@ static bool open_sockets_smbd(struct smbd_parent_context *parent,
>  			   ID_CACHE_DELETE, smbd_parent_id_cache_delete);
>  	messaging_register(msg_ctx, NULL,
>  			   ID_CACHE_KILL, smbd_parent_id_cache_kill);
> +	messaging_register(msg_ctx, NULL, MSG_SMB_NOTIFY_STARTED,
> +			   smb_parent_send_to_children);
>  
>  #ifdef CLUSTER_SUPPORT
>  	if (lp_clustering()) {
> diff --git a/source3/smbd/service.c b/source3/smbd/service.c
> index ef434f9..5b54aec 100644
> --- a/source3/smbd/service.c
> +++ b/source3/smbd/service.c
> @@ -544,6 +544,18 @@ static NTSTATUS notify_init_sconn(struct smbd_server_connection *sconn)
>  		return status;
>  	}
>  
> +	status = messaging_register(sconn->msg_ctx, sconn,
> +				    MSG_SMB_NOTIFY_STARTED,
> +				    smbd_notifyd_restarted);
> +	if (!NT_STATUS_IS_OK(status)) {
> +		DBG_DEBUG("messaging_register failed: %s\n",
> +			  nt_errstr(status));
> +		messaging_deregister(sconn->msg_ctx,
> +				     MSG_SMB_NOTIFY_CANCEL_DELETED, sconn);
> +		TALLOC_FREE(sconn->notify_ctx);
> +		return status;
> +	}
> +
>  	return NT_STATUS_OK;
>  }
>  
> -- 
> 2.1.4
> 




More information about the samba-technical mailing list