[SCM] Samba Shared Repository - branch master updated

Martin Schwenke martins at samba.org
Fri Nov 24 14:50:02 UTC 2017


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 <amitay at gmail.com>
Date:   Wed Nov 8 20:09:59 2017 +1100

    ctdb-eventd: Simplify eventd code
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Martin Schwenke <martin at meltin.net>
    
    Autobuild-User(master): Martin Schwenke <martins at samba.org>
    Autobuild-Date(master): Fri Nov 24 15:49:46 CET 2017 on sn-devel-144

commit ada9e95c1bda5995d87b0e2830bcf1a935bcfc4a
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Wed Nov 8 19:31:05 2017 +1100

    ctdb-common: Add special monitor handling to run_event abstraction
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Martin Schwenke <martin at meltin.net>

commit c19fc7c9cc94dcf708a3ad0e417304a9d5c965ff
Author: Amitay Isaacs <amitay at gmail.com>
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 <amitay at gmail.com>
    Reviewed-by: Martin Schwenke <martin at meltin.net>

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

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



More information about the samba-cvs mailing list