[PATCH] Make notifyd restartable

Volker Lendecke vl at samba.org
Tue Jul 19 12:29:13 UTC 2016


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?

Thanks, Volker
-------------- next part --------------
>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