[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