From 843432d56f9114a4d0d3021a772953dc5a1193dd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 4 Apr 2012 14:51:43 +0200 Subject: s3: New notify implementation From notify_internal.c: /* * The notify database is split up into two databases: One * relatively static index db and the real notify db with the * volatile entries. */ This change is necessary to make notify scale better in a cluster --- source3/smbd/server.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) (limited to 'source3/smbd/server.c') diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 2920bbd7fb..912d7a129b 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -41,6 +41,7 @@ #include "smbprofile.h" #include "lib/id_cache.h" #include "lib/param/param.h" +#include "lib/background.h" struct smbd_open_socket; struct smbd_child_pid; @@ -269,6 +270,103 @@ static void smbd_parent_id_cache_delete(struct messaging_context *ctx, messaging_send_to_children(ctx, msg_type, msg_data); } +struct smbd_parent_notify_state { + struct tevent_context *ev; + struct messaging_context *msg; + uint32_t msgtype; + struct notify_context *notify; +}; + +static int smbd_parent_notify_cleanup(void *private_data); +static void smbd_parent_notify_cleanup_done(struct tevent_req *req); +static void smbd_parent_notify_proxy_done(struct tevent_req *req); + +static bool smbd_parent_notify_init(TALLOC_CTX *mem_ctx, + struct messaging_context *msg, + struct tevent_context *ev) +{ + struct smbd_parent_notify_state *state; + struct tevent_req *req; + + state = talloc(mem_ctx, struct smbd_parent_notify_state); + if (state == NULL) { + return NULL; + } + state->msg = msg; + state->ev = ev; + state->msgtype = MSG_SMB_NOTIFY_CLEANUP; + + state->notify = notify_init(state, msg, ev); + if (state->notify == NULL) { + goto fail; + } + req = background_job_send( + state, state->ev, state->msg, &state->msgtype, 1, + lp_parm_int(-1, "smbd", "notify cleanup interval", 60), + smbd_parent_notify_cleanup, state->notify); + if (req == NULL) { + goto fail; + } + tevent_req_set_callback(req, smbd_parent_notify_cleanup_done, state); + + if (!lp_clustering()) { + return true; + } + + req = notify_cluster_proxy_send(state, ev, state->notify); + if (req == NULL) { + goto fail; + } + tevent_req_set_callback(req, smbd_parent_notify_proxy_done, state); + + return true; +fail: + TALLOC_FREE(state); + return false; +} + +static int smbd_parent_notify_cleanup(void *private_data) +{ + struct notify_context *notify = talloc_get_type_abort( + private_data, struct notify_context); + notify_cleanup(notify); + return lp_parm_int(-1, "smbd", "notify cleanup interval", 60); +} + +static void smbd_parent_notify_cleanup_done(struct tevent_req *req) +{ + struct smbd_parent_notify_state *state = tevent_req_callback_data( + req, struct smbd_parent_notify_state); + NTSTATUS status; + + status = background_job_recv(req); + TALLOC_FREE(req); + DEBUG(1, ("notify cleanup job ended with %s\n", nt_errstr(status))); + + /* + * Provide self-healing: Whatever the error condition was, it + * will have printed it into log.smbd. Just retrying and + * spamming log.smbd once a minute should be fine. + */ + req = background_job_send( + state, state->ev, state->msg, &state->msgtype, 1, 60, + smbd_parent_notify_cleanup, state->notify); + if (req == NULL) { + DEBUG(1, ("background_job_send failed\n")); + return; + } + tevent_req_set_callback(req, smbd_parent_notify_cleanup_done, state); +} + +static void smbd_parent_notify_proxy_done(struct tevent_req *req) +{ + int ret; + + ret = notify_cluster_proxy_recv(req); + TALLOC_FREE(req); + DEBUG(1, ("notify proxy job ended with %s\n", strerror(ret))); +} + static void smb_parent_force_tdis(struct messaging_context *ctx, void* data, uint32_t msg_type, @@ -1319,7 +1417,7 @@ extern void build_options(bool screen); exit(1); } - if (!notify_internal_parent_init(ev_ctx)) { + if (!smbd_parent_notify_init(NULL, msg_ctx, ev_ctx)) { exit(1); } -- cgit