From: Volker Lendecke Date: Tue, 21 Jun 2016 14:23:19 +0000 (+0200) Subject: smbd: Re-register notify requests X-Git-Tag: tdb-1.3.10~314 X-Git-Url: http://git.samba.org/?p=samba.git;a=commitdiff_plain;h=fa96452f9cde535f3cfe31afe8c54199a940f027 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 Reviewed-by: Jeremy Allison --- diff --git a/librpc/idl/messaging.idl b/librpc/idl/messaging.idl index 62323228cfb..a54d13c42f4 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 4837ca5bda4..f64185dc2d2 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 97d738c40e6..26fec95dc54 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 27cf770e170..0d7e43b0811 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 ef434f9f368..5b54aecd12f 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; }