smbd: Re-register notify requests
authorVolker Lendecke <vl@samba.org>
Tue, 21 Jun 2016 14:23:19 +0000 (16:23 +0200)
committerJeremy Allison <jra@samba.org>
Wed, 20 Jul 2016 03:21:07 +0000 (05:21 +0200)
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@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
librpc/idl/messaging.idl
source3/smbd/notify.c
source3/smbd/proto.h
source3/smbd/server.c
source3/smbd/service.c

index 6232322..a54d13c 100644 (file)
@@ -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,
index 4837ca5..f64185d 100644 (file)
@@ -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.
 *****************************************************************************/
index 97d738c..26fec95 100644 (file)
@@ -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,
index 27cf770..0d7e43b 100644 (file)
@@ -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()) {
index ef434f9..5b54aec 100644 (file)
@@ -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;
 }