From: Martin Schwenke Date: Mon, 29 Sep 2025 07:24:53 +0000 (+1000) Subject: ctdb-event: Replace "no data" event scripts with previous data X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=56e6f810b019a5475c850007494ff5404c5472da;p=thirdparty%2Fsamba.git ctdb-event: Replace "no data" event scripts with previous data If an event script list contains results with "no data" (summary == -ENODATA), then overwrite these with results from the previous run, where possible. To maintain current behaviour in "ctdb event status ...", stop processing scripts if the begin timestamp in the list goes backwards. This maintains backward compatibility, where only status for scripts from the most recent run are shown. Signed-off-by: Martin Schwenke Reviewed-by: Ralph Boehme Autobuild-User(master): Ralph Böhme Autobuild-Date(master): Tue Oct 7 11:09:41 UTC 2025 on atb-devel-224 --- diff --git a/ctdb/event/event_context.c b/ctdb/event/event_context.c index e26d9ae4d1c..afde9b0542e 100644 --- a/ctdb/event/event_context.c +++ b/ctdb/event/event_context.c @@ -134,6 +134,9 @@ static int eventd_event_set(struct event_component *comp, struct run_event_script_list *script_list) { struct event_event *event = NULL; + struct run_event_script_list *old_list = NULL; + unsigned int n = 0; + unsigned int o = 0; int ret; ret = eventd_event_add(comp, event_name, &event); @@ -146,9 +149,62 @@ static int eventd_event_set(struct event_component *comp, return 0; } - TALLOC_FREE(event->script_list); + old_list = event->script_list; event->script_list = talloc_steal(event, script_list); + /* No previous run, so the loop below can't be run */ + if (old_list == NULL) { + goto done; + } + + /* The loop below is a no-op if no script failed, so optimise */ + if (script_list->summary == 0) { + goto done; + } + + /* + * Replace any "no data" items in the new list with the data + * from the old list + */ + while (n < script_list->num_scripts && o < old_list->num_scripts) { + struct run_event_script *new = &script_list->script[n]; + struct run_event_script *old = &old_list->script[o]; + + /* + * If these are the same event, copy data if "no + * data". Otherwise step through the lists. + */ + ret = strcmp(new->name, old->name); + if (ret < 0) { + n++; + continue; + } + if (ret > 0) { + o++; + continue; + } + + if (new->summary == -ENODATA) { + /* + * Do not do a struct assignment here. This + * would cause name and output to point to + * memory allocated off old_list, and that is + * freed below. + */ + new->begin = old->begin; + new->end = old->end; + new->result = old->result; + new->summary = old->summary; + new->output = talloc_move(event->script_list, + &old->output); + } + + n++; + o++; + } + +done: + TALLOC_FREE(old_list); return 0; } diff --git a/ctdb/event/event_tool.c b/ctdb/event/event_tool.c index 1acf94f1492..baf4763cb1f 100644 --- a/ctdb/event/event_tool.c +++ b/ctdb/event/event_tool.c @@ -262,6 +262,7 @@ static void print_status(const char *component, int result, struct ctdb_event_reply_status *status) { + struct timeval prev = { .tv_sec = 0, }; int i; if (result != 0) { @@ -282,11 +283,27 @@ static void print_status(const char *component, for (i=0; iscript_list->num_scripts; i++) { struct ctdb_event_script *s = &status->script_list->script[i]; + int ret = 0; + /* + * Occurs when a new script is enabled, it hasn't + * been previously run, and a previous script fails + */ if (s->result == -ENODATA) { continue; } + + /* + * Occurs when data for s is from a previous run, so + * it was run before the previous script + */ + ret = tevent_timeval_compare(&s->begin, &prev); + if (ret == -1) { + break; + } + print_status_one(s); + prev = s->begin; } }