The branch, master has been updated
       via  f026314 ctdb-eventd: Simplify eventd code
       via  ada9e95 ctdb-common: Add special monitor handling to run_event 
abstraction
       via  c19fc7c ctdb-tests: Make sure child processes are waited on after 
termination
      from  926e7a7 lib/replace: apply readline -Wstrict-prototypes workaround

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit f026314661a76f9892f79da970810fe3fe040c8e
Author: Amitay Isaacs <[email protected]>
Date:   Wed Nov 8 20:09:59 2017 +1100

    ctdb-eventd: Simplify eventd code
    
    Signed-off-by: Amitay Isaacs <[email protected]>
    Reviewed-by: Martin Schwenke <[email protected]>
    
    Autobuild-User(master): Martin Schwenke <[email protected]>
    Autobuild-Date(master): Fri Nov 24 15:49:46 CET 2017 on sn-devel-144

commit ada9e95c1bda5995d87b0e2830bcf1a935bcfc4a
Author: Amitay Isaacs <[email protected]>
Date:   Wed Nov 8 19:31:05 2017 +1100

    ctdb-common: Add special monitor handling to run_event abstraction
    
    Signed-off-by: Amitay Isaacs <[email protected]>
    Reviewed-by: Martin Schwenke <[email protected]>

commit c19fc7c9cc94dcf708a3ad0e417304a9d5c965ff
Author: Amitay Isaacs <[email protected]>
Date:   Wed Nov 22 11:08:14 2017 +1100

    ctdb-tests: Make sure child processes are waited on after termination
    
    Looks like the if a process holding fcntl lock (on pid file) is killed,
    then the lock is not released till the process is reaped using either
    wait() or waitpid().
    
    Signed-off-by: Amitay Isaacs <[email protected]>
    Reviewed-by: Martin Schwenke <[email protected]>

-----------------------------------------------------------------------

Summary of changes:
 ctdb/common/run_event.c           | 145 +++++++++++++++++++++++++++---
 ctdb/server/ctdb_eventd.c         | 183 ++++----------------------------------
 ctdb/tests/src/sock_daemon_test.c |  13 ++-
 3 files changed, 163 insertions(+), 178 deletions(-)


Changeset truncated at 500 lines:

diff --git a/ctdb/common/run_event.c b/ctdb/common/run_event.c
index 0961d65..e230b12 100644
--- a/ctdb/common/run_event.c
+++ b/ctdb/common/run_event.c
@@ -271,6 +271,10 @@ struct run_event_context {
        const char *script_dir;
        const char *debug_prog;
        bool debug_running;
+
+       struct tevent_queue *queue;
+       struct tevent_req *current_req;
+       bool monitor_running;
 };
 
 
@@ -321,6 +325,14 @@ int run_event_init(TALLOC_CTX *mem_ctx, struct 
tevent_context *ev,
 
        run_ctx->debug_running = false;
 
+       run_ctx->queue = tevent_queue_create(run_ctx, "run event queue");
+       if (run_ctx->queue == NULL) {
+               talloc_free(run_ctx);
+               return ENOMEM;
+       }
+
+       run_ctx->monitor_running = false;
+
        *out = run_ctx;
        return 0;
 }
@@ -341,6 +353,32 @@ static const char *run_event_debug_prog(struct 
run_event_context *run_ctx)
        return run_ctx->debug_prog;
 }
 
+static struct tevent_queue *run_event_queue(struct run_event_context *run_ctx)
+{
+       return run_ctx->queue;
+}
+
+static void run_event_start_running(struct run_event_context *run_ctx,
+                                   struct tevent_req *req, bool is_monitor)
+{
+       run_ctx->current_req = req;
+       run_ctx->monitor_running = is_monitor;
+}
+
+static void run_event_stop_running(struct run_event_context *run_ctx)
+{
+       run_ctx->current_req = NULL;
+       run_ctx->monitor_running = false;
+}
+
+static struct tevent_req *run_event_get_running(
+                               struct run_event_context *run_ctx,
+                               bool *is_monitor)
+{
+       *is_monitor = run_ctx->monitor_running;
+       return run_ctx->current_req;
+}
+
 static int run_event_script_status(struct run_event_script *script)
 {
        int ret;
@@ -583,14 +621,18 @@ struct run_event_state {
        struct tevent_context *ev;
        struct run_event_context *run_ctx;
        const char *event_str;
+       const char *arg_str;
        struct timeval timeout;
 
        struct run_event_script_list *script_list;
        const char **argv;
+       struct tevent_req *script_subreq;
        int index;
-       int status;
+       bool cancelled;
 };
 
+static void run_event_cancel(struct tevent_req *req);
+static void run_event_trigger(struct tevent_req *req, void *private_data);
 static struct tevent_req *run_event_run_script(struct tevent_req *req);
 static void run_event_next_script(struct tevent_req *subreq);
 static void run_event_debug(struct tevent_req *req, pid_t pid);
@@ -603,9 +645,9 @@ struct tevent_req *run_event_send(TALLOC_CTX *mem_ctx,
                                  const char *arg_str,
                                  struct timeval timeout)
 {
-       struct tevent_req *req, *subreq;
+       struct tevent_req *req, *current_req;
        struct run_event_state *state;
-       int ret;
+       bool monitor_running, status;
 
        req = tevent_req_create(mem_ctx, &state, struct run_event_state);
        if (req == NULL) {
@@ -618,39 +660,113 @@ struct tevent_req *run_event_send(TALLOC_CTX *mem_ctx,
        if (tevent_req_nomem(state->event_str, req)) {
                return tevent_req_post(req, ev);
        }
+       if (arg_str != NULL) {
+               state->arg_str = talloc_strdup(state, arg_str);
+               if (tevent_req_nomem(state->arg_str, req)) {
+                       return tevent_req_post(req, ev);
+               }
+       }
        state->timeout = timeout;
+       state->cancelled = false;
+
+       /*
+        * If monitor event is running,
+        *   cancel the running monitor event and run new event
+        *
+        * If any other event is running,
+        *   if new event is monitor, cancel that event
+        *   else add new event to the queue
+        */
+
+       current_req = run_event_get_running(run_ctx, &monitor_running);
+       if (current_req != NULL) {
+               if (monitor_running) {
+                       run_event_cancel(current_req);
+               } else if (strcmp(event_str, "monitor") == 0) {
+                       state->script_list = talloc_zero(
+                               state, struct run_event_script_list);
+                       if (tevent_req_nomem(state->script_list, req)) {
+                               return tevent_req_post(req, ev);
+                       }
+                       state->script_list->summary = -ECANCELED;
+                       tevent_req_done(req);
+                       return tevent_req_post(req, ev);
+               }
+       }
+
+       status = tevent_queue_add(run_event_queue(run_ctx), ev, req,
+                                 run_event_trigger, NULL);
+       if (! status) {
+               tevent_req_error(req, ENOMEM);
+               return tevent_req_post(req, ev);
+       }
+
+       return req;
+}
 
-       ret = get_script_list(state, run_event_script_dir(run_ctx),
+static void run_event_cancel(struct tevent_req *req)
+{
+       struct run_event_state *state = tevent_req_data(
+               req, struct run_event_state);
+
+       run_event_stop_running(state->run_ctx);
+
+       state->script_list->summary = -ECANCELED;
+       state->cancelled = true;
+
+       TALLOC_FREE(state->script_subreq);
+
+       tevent_req_done(req);
+}
+
+static void run_event_trigger(struct tevent_req *req, void *private_data)
+{
+       struct tevent_req *subreq;
+       struct run_event_state *state = tevent_req_data(
+               req, struct run_event_state);
+       int ret;
+       bool is_monitor = false;
+
+       D_DEBUG("Running event %s with args \"%s\"\n", state->event_str,
+               state->arg_str == NULL ? "(null)" : state->arg_str);
+
+       ret = get_script_list(state, run_event_script_dir(state->run_ctx),
                              &state->script_list);
        if (ret != 0) {
                D_ERR("get_script_list() failed, ret=%d\n", ret);
                tevent_req_error(req, ret);
-               return tevent_req_post(req, ev);
+               return;
        }
 
        /* No scripts */
        if (state->script_list == NULL ||
            state->script_list->num_scripts == 0) {
                tevent_req_done(req);
-               return tevent_req_post(req, ev);
+               return;
        }
 
-       ret = script_args(state, event_str, arg_str, &state->argv);
+       ret = script_args(state, state->event_str, state->arg_str,
+                         &state->argv);
        if (ret != 0) {
                D_ERR("script_args() failed, ret=%d\n", ret);
                tevent_req_error(req, ret);
-               return tevent_req_post(req, ev);
+               return;
        }
 
        state->index = 0;
 
        subreq = run_event_run_script(req);
        if (tevent_req_nomem(subreq, req)) {
-               return tevent_req_post(req, ev);
+               return;
        }
        tevent_req_set_callback(subreq, run_event_next_script, req);
 
-       return req;
+       state->script_subreq = subreq;
+
+       if (strcmp(state->event_str, "monitor") == 0) {
+               is_monitor = true;
+       }
+       run_event_start_running(state->run_ctx, req, is_monitor);
 }
 
 static struct tevent_req *run_event_run_script(struct tevent_req *req)
@@ -702,12 +818,17 @@ static void run_event_next_script(struct tevent_req 
*subreq)
        status = run_proc_recv(subreq, &ret, &script->result, &pid,
                               state->script_list, &script->output);
        TALLOC_FREE(subreq);
+       state->script_subreq = NULL;
        if (! status) {
                D_ERR("run_proc failed for %s, ret=%d\n", script->name, ret);
                tevent_req_error(req, ret);
                return;
        }
 
+       if (state->cancelled) {
+               return;
+       }
+
        /* Log output */
        if (script->output != NULL) {
                debug_log(DEBUG_ERR, script->output, script->name);
@@ -731,6 +852,7 @@ static void run_event_next_script(struct tevent_req *subreq)
                D_NOTICE("%s event %s\n", state->event_str,
                         (script->summary == -ETIME) ? "timed out" : "failed");
 
+               run_event_stop_running(state->run_ctx);
                tevent_req_done(req);
                return;
        }
@@ -739,6 +861,7 @@ static void run_event_next_script(struct tevent_req *subreq)
 
        /* All scripts executed */
        if (state->index >= state->script_list->num_scripts) {
+               run_event_stop_running(state->run_ctx);
                tevent_req_done(req);
                return;
        }
@@ -748,6 +871,8 @@ static void run_event_next_script(struct tevent_req *subreq)
                return;
        }
        tevent_req_set_callback(subreq, run_event_next_script, req);
+
+       state->script_subreq = subreq;
 }
 
 static void run_event_debug(struct tevent_req *req, pid_t pid)
diff --git a/ctdb/server/ctdb_eventd.c b/ctdb/server/ctdb_eventd.c
index 1a6c69c..feeac07 100644
--- a/ctdb/server/ctdb_eventd.c
+++ b/ctdb/server/ctdb_eventd.c
@@ -42,12 +42,6 @@
 #include "common/run_event.h"
 #include "common/sock_daemon.h"
 
-struct pending_event {
-       struct pending_event *prev, *next;
-
-       struct tevent_req *req;
-};
-
 struct eventd_client {
        struct eventd_client *prev, *next;
 
@@ -57,12 +51,6 @@ struct eventd_client {
 
 struct eventd_context {
        struct run_event_context *run_ctx;
-       struct tevent_queue *queue;
-
-       /* current state */
-       bool running;
-       enum ctdb_event event;
-       struct tevent_req *req;
 
        /* result of last execution */
        struct run_event_script_list *status_run[CTDB_EVENT_MAX];
@@ -97,15 +85,6 @@ static int eventd_context_init(TALLOC_CTX *mem_ctx,
                return ret;
        }
 
-       ectx->queue = tevent_queue_create(ectx, "run event queue");
-       if (ectx->queue == NULL) {
-               talloc_free(ectx);
-               return ENOMEM;
-       }
-
-       ectx->running = false;
-       ectx->event = CTDB_EVENT_INIT;
-
        *result = ectx;
        return 0;
 }
@@ -115,46 +94,6 @@ static struct run_event_context *eventd_run_context(struct 
eventd_context *ectx)
        return ectx->run_ctx;
 }
 
-static struct tevent_queue *eventd_queue(struct eventd_context *ectx)
-{
-       return ectx->queue;
-}
-
-static void eventd_start_running(struct eventd_context *ectx,
-                                enum ctdb_event event,
-                                struct tevent_req *req)
-{
-       ectx->running = true;
-       ectx->event = event;
-       ectx->req = req;
-}
-
-static void eventd_stop_running(struct eventd_context *ectx)
-{
-       ectx->running = false;
-       ectx->req = NULL;
-}
-
-static struct tevent_req *eventd_cancel_running(struct eventd_context *ectx)
-{
-       struct tevent_req *req = ectx->req;
-
-       ectx->req = NULL;
-       eventd_stop_running(ectx);
-
-       return req;
-}
-
-static bool eventd_is_running(struct eventd_context *ectx,
-                             enum ctdb_event *event)
-{
-       if (event != NULL && ectx->running) {
-               *event = ectx->event;
-       }
-
-       return ectx->running;
-}
-
 static struct run_event_script_list *script_list_copy(
                                        TALLOC_CTX *mem_ctx,
                                        struct run_event_script_list *s)
@@ -226,6 +165,11 @@ static void eventd_set_result(struct eventd_context *ectx,
                return;
        }
 
+       /* Do not update status if event was cancelled */
+       if (script_list->summary == -ECANCELED) {
+               return;
+       }
+
        TALLOC_FREE(ectx->status_run[event]);
        ectx->status_run[event] = talloc_steal(ectx, script_list);
 
@@ -279,20 +223,13 @@ static int eventd_get_result(struct eventd_context *ectx,
  */
 
 struct command_run_state {
-       struct tevent_context *ev;
        struct eventd_context *ectx;
-       struct eventd_client *client;
 
        enum ctdb_event event;
-       uint32_t timeout;
-       const char *arg_str;
        struct ctdb_event_reply *reply;
-       struct tevent_req *subreq;
 };
 
-static void command_run_trigger(struct tevent_req *req, void *private_data);
 static void command_run_done(struct tevent_req *subreq);
-static void command_run_cancel(struct tevent_req *req);
 
 static struct tevent_req *command_run_send(TALLOC_CTX *mem_ctx,
                                           struct tevent_context *ev,
@@ -300,24 +237,17 @@ static struct tevent_req *command_run_send(TALLOC_CTX 
*mem_ctx,
                                           struct eventd_client *client,
                                           struct ctdb_event_request *request)
 {
-       struct tevent_req *req, *mon_req;
+       struct tevent_req *req, *subreq;
        struct command_run_state *state;
-       struct pending_event *pending;
-       enum ctdb_event running_event;
-       bool running, status;
+       uint32_t timeout;
 
        req = tevent_req_create(mem_ctx, &state, struct command_run_state);
        if (req == NULL) {
                return NULL;
        }
 
-       state->ev = ev;
        state->ectx = ectx;
-       state->client = client;
-
        state->event = request->rdata.data.run->event;
-       state->timeout = request->rdata.data.run->timeout;
-       state->arg_str = talloc_steal(state, request->rdata.data.run->arg_str);
 
        state->reply = talloc_zero(state, struct ctdb_event_reply);
        if (tevent_req_nomem(state->reply, req)) {
@@ -326,79 +256,20 @@ static struct tevent_req *command_run_send(TALLOC_CTX 
*mem_ctx,
 
        state->reply->rdata.command = request->rdata.command;
 
-       /*
-        * If monitor event is running,
-        *   Cancel the running monitor event and run new event
-        *
-        * If any other event is running,
-        *   If new event is monitor, cancel that event
-        *   Else add new event to the queue
-        */
-
-       running = eventd_is_running(ectx, &running_event);
-       if (running) {
-               if (running_event == CTDB_EVENT_MONITOR) {
-                       mon_req = eventd_cancel_running(ectx);
-                       command_run_cancel(mon_req);
-               } else if (state->event == CTDB_EVENT_MONITOR) {
-                       state->reply->rdata.result = -ECANCELED;
-                       tevent_req_done(req);
-                       return tevent_req_post(req, ev);
-               }
-       }
-
-       pending = talloc_zero(state, struct pending_event);
-       if (tevent_req_nomem(pending, req)) {
-               return tevent_req_post(req, ev);
-       }
-
-       pending->req = req;
-       DLIST_ADD(client->pending_list, pending);
-
-       status = tevent_queue_add(eventd_queue(ectx), ev, req,
-                                 command_run_trigger, pending);
-       if (! status) {
-               tevent_req_error(req, ENOMEM);
+       timeout = request->rdata.data.run->timeout;
+       subreq = run_event_send(state, ev,
+                               eventd_run_context(state->ectx),
+                               ctdb_event_to_string(state->event),
+                               request->rdata.data.run->arg_str,
+                               tevent_timeval_current_ofs(timeout, 0));
+       if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
+       tevent_req_set_callback(subreq, command_run_done, req);
 
        return req;
 }
 
-static void command_run_trigger(struct tevent_req *req, void *private_data)
-{
-       struct pending_event *pending = talloc_get_type_abort(
-               private_data, struct pending_event);
-       struct command_run_state *state = tevent_req_data(
-               req, struct command_run_state);
-
-       DLIST_REMOVE(state->client->pending_list, pending);
-
-       if (pending->req != req) {
-               tevent_req_error(req, EIO);
-               return;
-       }
-
-       talloc_free(pending);
-
-       D_DEBUG("Running event %s with args \"%s\"\n",
-               ctdb_event_to_string(state->event),
-               state->arg_str == NULL ? "(null)" : state->arg_str);
-
-       state->subreq = run_event_send(state, state->ev,
-                                      eventd_run_context(state->ectx),
-                                      ctdb_event_to_string(state->event),
-                                      state->arg_str,
-                                      tevent_timeval_current_ofs(
-                                              state->timeout, 0));
-       if (tevent_req_nomem(state->subreq, req)) {
-               return;
-       }
-       tevent_req_set_callback(state->subreq, command_run_done, req);
-
-       eventd_start_running(state->ectx, state->event, req);
-}
-
 static void command_run_done(struct tevent_req *subreq)
 {
        struct tevent_req *req = tevent_req_callback_data(


-- 
Samba Shared Repository

Reply via email to