diff --git a/_service b/_service index 7d7d1a9..305c9fc 100644 --- a/_service +++ b/_service @@ -11,7 +11,7 @@ 3.0.0 --> 3.0.0+%cd.%h - fa492f5181 + 64cd85422c enable diff --git a/_servicedata b/_servicedata index 381e380..1eaf3ae 100644 --- a/_servicedata +++ b/_servicedata @@ -5,4 +5,4 @@ https://github.com/ClusterLabs/pacemaker.git - dc802bfe4bebd89448b53e42dcc5d022905a4215 \ No newline at end of file + d60b9407f2db9c9eca5f4dea0726478e068db910 \ No newline at end of file diff --git a/pacemaker#3716-0001-Fix-crmadmin-return-error-if-DC-is-not-elected-2902-.patch b/pacemaker#3716-0001-Fix-crmadmin-return-error-if-DC-is-not-elected-2902-.patch new file mode 100644 index 0000000..afd76c4 --- /dev/null +++ b/pacemaker#3716-0001-Fix-crmadmin-return-error-if-DC-is-not-elected-2902-.patch @@ -0,0 +1,116 @@ +From a1d94f7ab57a71a36faa8282dd7db6af4cb25f39 Mon Sep 17 00:00:00 2001 +From: Aleksei Burlakov +Date: Sat, 2 Nov 2024 12:49:01 +0100 +Subject: [PATCH] Fix: crmadmin: return error if DC is not elected #2902 #3606 + +If the DC is not yet elected, the crmadmin will return an error. +(This change complements #3606). +--- + cts/cli/regression.error_codes.exp | 4 ++++ + include/crm/common/results.h | 2 ++ + lib/common/results.c | 5 +++++ + lib/pacemaker/pcmk_cluster_queries.c | 2 +- + 4 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/cts/cli/regression.error_codes.exp b/cts/cli/regression.error_codes.exp +index f620845b9e..3c330eda3f 100644 +--- a/cts/cli/regression.error_codes.exp ++++ b/cts/cli/regression.error_codes.exp +@@ -404,6 +404,7 @@ CRM_EX_ERROR - Error occurred + 111: Requested item is not yet in effect + 112: Could not determine status + 113: Not applicable under current conditions ++ 114: DC is not yet elected + 124: Timeout occurred + 190: Service is active but might fail soon + 191: Service is promoted but might fail soon +@@ -451,6 +452,7 @@ CRM_EX_ERROR - Error occurred + + + ++ + + + +@@ -499,6 +501,7 @@ CRM_EX_ERROR - Error occurred + 111: CRM_EX_NOT_YET_IN_EFFECT Requested item is not yet in effect + 112: CRM_EX_INDETERMINATE Could not determine status + 113: CRM_EX_UNSATISFIED Not applicable under current conditions ++ 114: CRM_EX_NO_DC DC is not yet elected + 124: CRM_EX_TIMEOUT Timeout occurred + 190: CRM_EX_DEGRADED Service is active but might fail soon + 191: CRM_EX_DEGRADED_PROMOTED Service is promoted but might fail soon +@@ -546,6 +549,7 @@ CRM_EX_ERROR - Error occurred + + + ++ + + + +diff --git a/include/crm/common/results.h b/include/crm/common/results.h +index 2fedb7c736..a671cb8efd 100644 +--- a/include/crm/common/results.h ++++ b/include/crm/common/results.h +@@ -111,6 +111,7 @@ enum pcmk_rc_e { + /* When adding new values, use consecutively lower numbers, update the array + * in lib/common/results.c, and test with crm_error. + */ ++ pcmk_rc_no_dc = -1040, + pcmk_rc_compression = -1039, + pcmk_rc_ns_resolution = -1038, + pcmk_rc_no_transaction = -1037, +@@ -273,6 +274,7 @@ typedef enum crm_exit_e { + CRM_EX_NOT_YET_IN_EFFECT = 111, //!< Requested item is not in effect + CRM_EX_INDETERMINATE = 112, //!< Could not determine status + CRM_EX_UNSATISFIED = 113, //!< Requested item does not satisfy constraints ++ CRM_EX_NO_DC = 114, //!< DC is not yet elected, e.g. right after cluster restart + + // Other + CRM_EX_TIMEOUT = 124, //!< Convention from timeout(1) +diff --git a/lib/common/results.c b/lib/common/results.c +index 507280492c..359d1eeccc 100644 +--- a/lib/common/results.c ++++ b/lib/common/results.c +@@ -734,6 +734,7 @@ crm_exit_name(crm_exit_t exit_code) + case CRM_EX_NOT_YET_IN_EFFECT: return "CRM_EX_NOT_YET_IN_EFFECT"; + case CRM_EX_INDETERMINATE: return "CRM_EX_INDETERMINATE"; + case CRM_EX_UNSATISFIED: return "CRM_EX_UNSATISFIED"; ++ case CRM_EX_NO_DC: return "CRM_EX_NO_DC"; + case CRM_EX_OLD: return "CRM_EX_OLD"; + case CRM_EX_TIMEOUT: return "CRM_EX_TIMEOUT"; + case CRM_EX_DEGRADED: return "CRM_EX_DEGRADED"; +@@ -786,6 +787,7 @@ crm_exit_str(crm_exit_t exit_code) + case CRM_EX_NOT_YET_IN_EFFECT: return "Requested item is not yet in effect"; + case CRM_EX_INDETERMINATE: return "Could not determine status"; + case CRM_EX_UNSATISFIED: return "Not applicable under current conditions"; ++ case CRM_EX_NO_DC: return "DC is not yet elected"; + case CRM_EX_OLD: return "Update was older than existing configuration"; + case CRM_EX_TIMEOUT: return "Timeout occurred"; + case CRM_EX_DEGRADED: return "Service is active but might fail soon"; +@@ -922,6 +924,9 @@ pcmk_rc2exitc(int rc) + case pcmk_rc_bad_xml_patch: + return CRM_EX_DATAERR; + ++ case pcmk_rc_no_dc: ++ return CRM_EX_NO_DC; ++ + default: + return CRM_EX_ERROR; + } +diff --git a/lib/pacemaker/pcmk_cluster_queries.c b/lib/pacemaker/pcmk_cluster_queries.c +index 3f7584e9ff..e99d91f7d0 100644 +--- a/lib/pacemaker/pcmk_cluster_queries.c ++++ b/lib/pacemaker/pcmk_cluster_queries.c +@@ -235,7 +235,7 @@ designated_controller_event_cb(pcmk_ipc_api_t *controld_api, + + reply = (const pcmk_controld_api_reply_t *) event_data; + out->message(out, "dc", reply->host_from); +- data->rc = pcmk_rc_ok; ++ data->rc = reply->host_from ? pcmk_rc_ok : pcmk_rc_no_dc; + } + + /*! +-- +2.43.0 + diff --git a/pacemaker#3746-0001-Mid-systemd-Fix-when-monitor-of-systemd-resource-con.patch b/pacemaker#3746-0001-Mid-systemd-Fix-when-monitor-of-systemd-resource-con.patch new file mode 100644 index 0000000..ba52d3a --- /dev/null +++ b/pacemaker#3746-0001-Mid-systemd-Fix-when-monitor-of-systemd-resource-con.patch @@ -0,0 +1,45 @@ +From 20b1aaff9bb0e5fe8682c9c9630f2f34ec8b9086 Mon Sep 17 00:00:00 2001 +From: Hideo Yamauchi +Date: Mon, 2 Dec 2024 16:26:42 +0900 +Subject: [PATCH 1/2] Mid: systemd: Fix when monitor of systemd resource + continues to be pending. + +--- + daemons/execd/execd_commands.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/daemons/execd/execd_commands.c b/daemons/execd/execd_commands.c +index 5356c5cc97..8ade0ac345 100644 +--- a/daemons/execd/execd_commands.c ++++ b/daemons/execd/execd_commands.c +@@ -903,6 +903,27 @@ action_complete(svc_action_t * action) + } + } + } ++ } else if (pcmk__str_any_of(cmd->action, PCMK_ACTION_MONITOR, PCMK_ACTION_STATUS, NULL) && ++ (cmd->interval_ms > 0)) { ++ /* For monitors, excluding follow-up monitors, */ ++ /* if the pending state persists from the first notification until its timeout, */ ++ /* it will be treated as a timeout. */ ++ ++ if ((cmd->result.execution_status == PCMK_EXEC_PENDING) && ++ (cmd->last_notify_op_status == PCMK_EXEC_PENDING)) { ++ int time_left = time(NULL) - (cmd->epoch_rcchange + (cmd->timeout_orig/1000)); ++ ++ if (time_left >= 0) { ++ crm_notice("Giving up on %s %s (rc=%d): monitor pending timeout (first pending notification=%s timeout=%ds)", ++ cmd->rsc_id, cmd->action, ++ cmd->result.exit_status, pcmk__trim(ctime(&cmd->epoch_rcchange)), cmd->timeout_orig); ++ pcmk__set_result(&(cmd->result), PCMK_OCF_UNKNOWN_ERROR, ++ PCMK_EXEC_TIMEOUT, ++ "Investigate reason for timeout, and adjust " ++ "configured operation timeout if necessary"); ++ cmd_original_times(cmd); ++ } ++ } + } + } + #endif +-- +2.43.0 + diff --git a/pacemaker#3746-0002-Mid-systemd-If-the-state-is-Pending-at-the-time-of-p.patch b/pacemaker#3746-0002-Mid-systemd-If-the-state-is-Pending-at-the-time-of-p.patch new file mode 100644 index 0000000..f48ef7f --- /dev/null +++ b/pacemaker#3746-0002-Mid-systemd-If-the-state-is-Pending-at-the-time-of-p.patch @@ -0,0 +1,36 @@ +From 6fee07dfc482a0069184813437a84ebd7f11a7b4 Mon Sep 17 00:00:00 2001 +From: Hideo Yamauchi +Date: Mon, 2 Dec 2024 16:27:34 +0900 +Subject: [PATCH 2/2] Mid: systemd: If the state is Pending at the time of + probe, execute follow up monitor. + +--- + daemons/execd/execd_commands.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/daemons/execd/execd_commands.c b/daemons/execd/execd_commands.c +index 8ade0ac345..ece2315e36 100644 +--- a/daemons/execd/execd_commands.c ++++ b/daemons/execd/execd_commands.c +@@ -869,8 +869,16 @@ action_complete(svc_action_t * action) + cmd->real_action = cmd->action; + cmd->action = pcmk__str_copy(PCMK_ACTION_MONITOR); + +- } else if (cmd->real_action != NULL) { +- // This is follow-up monitor to check whether start/stop completed ++ } else if (cmd->result.execution_status == PCMK_EXEC_PENDING && ++ pcmk__str_any_of(cmd->action, PCMK_ACTION_MONITOR, PCMK_ACTION_STATUS, NULL) && ++ cmd->interval_ms == 0 && ++ cmd->real_action == NULL) { ++ /* If the state is Pending at the time of probe, execute follow-up monitor. */ ++ goagain = true; ++ cmd->real_action = cmd->action; ++ cmd->action = pcmk__str_copy(PCMK_ACTION_MONITOR); ++ } else if (cmd->real_action != NULL) { ++ // This is follow-up monitor to check whether start/stop/probe(monitor) completed + if (cmd->result.execution_status == PCMK_EXEC_PENDING) { + goagain = true; + +-- +2.43.0 + diff --git a/pacemaker#3781-0001-Low-controller-round-timeout-when-checking-remaining.patch b/pacemaker#3781-0001-Low-controller-round-timeout-when-checking-remaining.patch new file mode 100644 index 0000000..dc205f3 --- /dev/null +++ b/pacemaker#3781-0001-Low-controller-round-timeout-when-checking-remaining.patch @@ -0,0 +1,104 @@ +From 4193fb1d8e5023289e7a600a8dabc864b99f24a2 Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Tue, 10 Dec 2024 14:56:20 -0600 +Subject: [PATCH] Low: controller: round timeout when checking remaining remote + command time + +Use pcmk__timeout_ms2s() to ensure that remote command timeout values +are properly rounded. + +Also, refactor to drop remaining_timeout from remote_ra_cmd_t. The value +was only ever used locally when calculated and doesn't need to be +remembered. +--- + daemons/controld/controld_remote_ra.c | 33 +++++++++++++++++---------- + 1 file changed, 21 insertions(+), 12 deletions(-) + +diff --git a/daemons/controld/controld_remote_ra.c b/daemons/controld/controld_remote_ra.c +index 060a231d74..df4e0bd6fc 100644 +--- a/daemons/controld/controld_remote_ra.c ++++ b/daemons/controld/controld_remote_ra.c +@@ -55,7 +55,6 @@ typedef struct remote_ra_cmd_s { + int delay_id; + /*! timeout in ms for cmd */ + int timeout; +- int remaining_timeout; + /*! recurring interval in ms */ + guint interval_ms; + /*! interval timer id */ +@@ -512,10 +511,18 @@ report_remote_ra_result(remote_ra_cmd_t * cmd) + lrmd__reset_result(&op); + } + +-static void +-update_remaining_timeout(remote_ra_cmd_t * cmd) ++/*! ++ * \internal ++ * \brief Return a remote command's remaining timeout in seconds ++ * ++ * \param[in] cmd Remote command to check ++ * ++ * \return Command's remaining timeout in seconds ++ */ ++static int ++remaining_timeout_sec(const remote_ra_cmd_t *cmd) + { +- cmd->remaining_timeout = ((cmd->timeout / 1000) - (time(NULL) - cmd->start_time)) * 1000; ++ return pcmk__timeout_ms2s(cmd->timeout) - (time(NULL) - cmd->start_time); + } + + static gboolean +@@ -525,6 +532,7 @@ retry_start_cmd_cb(gpointer data) + remote_ra_data_t *ra_data = lrm_state->remote_ra_data; + remote_ra_cmd_t *cmd = NULL; + int rc = ETIME; ++ int remaining = 0; + + if (!ra_data || !ra_data->cur_cmd) { + return FALSE; +@@ -534,10 +542,10 @@ retry_start_cmd_cb(gpointer data) + PCMK_ACTION_MIGRATE_FROM, NULL)) { + return FALSE; + } +- update_remaining_timeout(cmd); + +- if (cmd->remaining_timeout > 0) { +- rc = handle_remote_ra_start(lrm_state, cmd, cmd->remaining_timeout); ++ remaining = remaining_timeout_sec(cmd); ++ if (remaining > 0) { ++ rc = handle_remote_ra_start(lrm_state, cmd, remaining * 1000); + } else { + pcmk__set_result(&(cmd->result), PCMK_OCF_UNKNOWN_ERROR, + PCMK_EXEC_TIMEOUT, +@@ -723,7 +731,7 @@ remote_lrm_op_callback(lrmd_event_data_t * op) + && pcmk__strcase_any_of(cmd->action, PCMK_ACTION_START, + PCMK_ACTION_MIGRATE_FROM, NULL)) { + if (op->connection_rc < 0) { +- update_remaining_timeout(cmd); ++ int remaining = remaining_timeout_sec(cmd); + + if ((op->connection_rc == -ENOKEY) + || (op->connection_rc == -EKEYREJECTED)) { +@@ -732,14 +740,15 @@ remote_lrm_op_callback(lrmd_event_data_t * op) + PCMK_EXEC_ERROR, + pcmk_strerror(op->connection_rc)); + +- } else if (cmd->remaining_timeout > 3000) { +- crm_trace("rescheduling start, remaining timeout %d", cmd->remaining_timeout); ++ } else if (remaining > 3) { ++ crm_trace("Rescheduling start (%ds remains before timeout)", ++ remaining); + pcmk__create_timer(1000, retry_start_cmd_cb, lrm_state); + return; + + } else { +- crm_trace("can't reschedule start, remaining timeout too small %d", +- cmd->remaining_timeout); ++ crm_trace("Not enough time before timeout (%ds) " ++ "to reschedule start", remaining); + pcmk__format_result(&(cmd->result), PCMK_OCF_UNKNOWN_ERROR, + PCMK_EXEC_TIMEOUT, + "%s without enough time to retry", +-- +2.43.0 + diff --git a/pacemaker#3791-0001-Mid-schedulerd-Resetting-error-and-warning-flags.patch b/pacemaker#3791-0001-Mid-schedulerd-Resetting-error-and-warning-flags.patch new file mode 100644 index 0000000..325ac2a --- /dev/null +++ b/pacemaker#3791-0001-Mid-schedulerd-Resetting-error-and-warning-flags.patch @@ -0,0 +1,23 @@ +From 78e6b46a2bbb80af24a804045313370a6404a251 Mon Sep 17 00:00:00 2001 +From: Hideo Yamauchi +Date: Thu, 9 Jan 2025 08:32:48 +0900 +Subject: [PATCH] Mid: schedulerd: Resetting error and warning flags. + +--- + lib/pengine/status.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +Index: pacemaker-3.0.0+20250128.fa492f5181/lib/pengine/status.c +=================================================================== +--- pacemaker-3.0.0+20250128.fa492f5181.orig/lib/pengine/status.c ++++ pacemaker-3.0.0+20250128.fa492f5181/lib/pengine/status.c +@@ -447,6 +447,9 @@ set_working_set_defaults(pcmk_scheduler_ + |pcmk__sched_stop_removed_resources + |pcmk__sched_cancel_removed_actions); + #endif ++ ++ pcmk__config_has_error = false; ++ pcmk__config_has_warning = false; + } + + pcmk_resource_t * diff --git a/pacemaker#3793-0001-Low-various-Correct-some-printf-specifiers.patch b/pacemaker#3793-0001-Low-various-Correct-some-printf-specifiers.patch new file mode 100644 index 0000000..091efc2 --- /dev/null +++ b/pacemaker#3793-0001-Low-various-Correct-some-printf-specifiers.patch @@ -0,0 +1,374 @@ +From c120c1ebbcb68966e229d4c3647fdbb511150f94 Mon Sep 17 00:00:00 2001 +From: Reid Wahl +Date: Wed, 8 Jan 2025 20:44:25 -0800 +Subject: [PATCH 1/2] Low: various: Correct some printf specifiers + +As of 18a93372, we can use the 'z' modifier for size_t and ssize_t. So +here we take advantage of that to avoid some (long long) casts. + +We also correct some incorrect specifiers (signed vs. unsigned, and +using proper macros from inttypes.h). + +Signed-off-by: Reid Wahl +--- + daemons/controld/controld_fsa.c | 12 +++--- + daemons/controld/controld_messages.c | 8 ++-- + lib/cluster/cpg.c | 24 +++++------ + lib/common/ipc_server.c | 25 ++++++----- + lib/common/remote.c | 62 ++++++++++++---------------- + lib/services/services_linux.c | 17 ++++---- + 6 files changed, 67 insertions(+), 81 deletions(-) + +Index: pacemaker-3.0.0+20250128.fa492f5181/daemons/controld/controld_fsa.c +=================================================================== +--- pacemaker-3.0.0+20250128.fa492f5181.orig/daemons/controld/controld_fsa.c ++++ pacemaker-3.0.0+20250128.fa492f5181/daemons/controld/controld_fsa.c +@@ -1,5 +1,5 @@ + /* +- * Copyright 2004-2024 the Pacemaker project contributors ++ * Copyright 2004-2025 the Pacemaker project contributors + * + * The version control history for this file may have further details. + * +@@ -9,6 +9,7 @@ + + #include + ++#include // PRIx64 + #include + #include + #include // uint64_t +@@ -279,9 +280,10 @@ s_crmd_fsa(enum crmd_fsa_cause cause) + || (controld_globals.fsa_actions != A_NOTHING) + || pcmk_is_set(controld_globals.flags, controld_fsa_is_stalled)) { + +- crm_debug("Exiting the FSA: queue=%d, fsa_actions=%#llx, stalled=%s", ++ crm_debug("Exiting the FSA: queue=%d, fsa_actions=%" PRIx64 ++ ", stalled=%s", + g_list_length(controld_globals.fsa_message_queue), +- (unsigned long long) controld_globals.fsa_actions, ++ controld_globals.fsa_actions, + pcmk__flag_text(controld_globals.flags, + controld_fsa_is_stalled)); + } else { +@@ -505,9 +507,9 @@ s_crmd_fsa_actions(fsa_data_t * fsa_data + + /* Error checking and reporting */ + } else { +- crm_err("Action %s not supported " QB_XS " %#llx", ++ crm_err("Action %s not supported " QB_XS " %" PRIx64, + fsa_action2string(controld_globals.fsa_actions), +- (unsigned long long) controld_globals.fsa_actions); ++ controld_globals.fsa_actions); + register_fsa_error_adv(C_FSA_INTERNAL, I_ERROR, fsa_data, NULL, + __func__); + } +Index: pacemaker-3.0.0+20250128.fa492f5181/daemons/controld/controld_messages.c +=================================================================== +--- pacemaker-3.0.0+20250128.fa492f5181.orig/daemons/controld/controld_messages.c ++++ pacemaker-3.0.0+20250128.fa492f5181/daemons/controld/controld_messages.c +@@ -9,8 +9,10 @@ + + #include + +-#include ++#include // PRIx64 ++#include // uint64_t + #include ++#include + #include + + #include +@@ -110,8 +112,7 @@ register_fsa_input_adv(enum crmd_fsa_cau + fsa_data->actions = with_actions; + + if (with_actions != A_NOTHING) { +- crm_trace("Adding actions %.16llx to input", +- (unsigned long long) with_actions); ++ crm_trace("Adding actions %.16" PRIx64 " to input", with_actions); + } + + if (data != NULL) { +@@ -1382,4 +1383,3 @@ broadcast_remote_state_message(const cha + pcmk__cluster_send_message(NULL, pcmk_ipc_controld, msg); + pcmk__xml_free(msg); + } +- +Index: pacemaker-3.0.0+20250128.fa492f5181/lib/cluster/cpg.c +=================================================================== +--- pacemaker-3.0.0+20250128.fa492f5181.orig/lib/cluster/cpg.c ++++ pacemaker-3.0.0+20250128.fa492f5181/lib/cluster/cpg.c +@@ -1,5 +1,5 @@ + /* +- * Copyright 2004-2024 the Pacemaker project contributors ++ * Copyright 2004-2025 the Pacemaker project contributors + * + * The version control history for this file may have further details. + * +@@ -237,8 +237,7 @@ crm_cs_flush(gpointer data) + } + + sent++; +- crm_trace("CPG message sent, size=%llu", +- (unsigned long long) iov->iov_len); ++ crm_trace("CPG message sent, size=%zu", iov->iov_len); + + cs_message_queue = g_list_remove(cs_message_queue, iov); + free(iov->iov_base); +@@ -360,10 +359,9 @@ check_message_sanity(const pcmk__cpg_msg + (((msg->size > 1) && (msg->data[msg->size - 2] == '\0')) + || (msg->data[msg->size - 1] != '\0'))) { + crm_err("CPG message %d from %s invalid: " +- "Payload does not end at byte %llu " ++ "Payload does not end at byte %" PRIu32 " " + QB_XS " from %s[%u] to %s@%s", +- msg->id, ais_dest(&(msg->sender)), +- (unsigned long long) msg->size, ++ msg->id, ais_dest(&(msg->sender)), msg->size, + msg_type2text(msg->sender.type), msg->sender.pid, + msg_type2text(msg->host.type), ais_dest(&(msg->host))); + return false; +@@ -1009,15 +1007,13 @@ send_cpg_text(const char *data, const pc + iov->iov_len = msg->header.size; + + if (msg->compressed_size > 0) { +- crm_trace("Queueing CPG message %u to %s " +- "(%llu bytes, %d bytes compressed payload): %.200s", +- msg->id, target, (unsigned long long) iov->iov_len, +- msg->compressed_size, data); ++ crm_trace("Queueing CPG message %" PRIu32 " to %s " ++ "(%zu bytes, %" PRIu32 " bytes compressed payload): %.200s", ++ msg->id, target, iov->iov_len, msg->compressed_size, data); + } else { +- crm_trace("Queueing CPG message %u to %s " +- "(%llu bytes, %d bytes payload): %.200s", +- msg->id, target, (unsigned long long) iov->iov_len, +- msg->size, data); ++ crm_trace("Queueing CPG message %" PRIu32 " to %s " ++ "(%zu bytes, %" PRIu32 " bytes payload): %.200s", ++ msg->id, target, iov->iov_len, msg->size, data); + } + + free(target); +Index: pacemaker-3.0.0+20250128.fa492f5181/lib/common/ipc_server.c +=================================================================== +--- pacemaker-3.0.0+20250128.fa492f5181.orig/lib/common/ipc_server.c ++++ pacemaker-3.0.0+20250128.fa492f5181/lib/common/ipc_server.c +@@ -1,5 +1,5 @@ + /* +- * Copyright 2004-2024 the Pacemaker project contributors ++ * Copyright 2004-2025 the Pacemaker project contributors + * + * The version control history for this file may have further details. + * +@@ -540,9 +540,8 @@ crm_ipcs_flush_events(pcmk__client_t *c) + + queue_len -= sent; + if (sent > 0 || queue_len) { +- crm_trace("Sent %d events (%d remaining) for %p[%d]: %s (%lld)", +- sent, queue_len, c->ipcs, c->pid, +- pcmk_rc_str(rc), (long long) qb_rc); ++ crm_trace("Sent %u events (%u remaining) for %p[%d]: %s (%zd)", ++ sent, queue_len, c->ipcs, c->pid, pcmk_rc_str(rc), qb_rc); + } + + if (queue_len) { +Index: pacemaker-3.0.0+20250128.fa492f5181/lib/common/remote.c +=================================================================== +--- pacemaker-3.0.0+20250128.fa492f5181.orig/lib/common/remote.c ++++ pacemaker-3.0.0+20250128.fa492f5181/lib/common/remote.c +@@ -137,29 +137,26 @@ send_tls(gnutls_session_t session, struc + return EINVAL; + } + +- crm_trace("Sending TLS message of %llu bytes", +- (unsigned long long) unsent_len); ++ crm_trace("Sending TLS message of %zu bytes", unsent_len); ++ + while (true) { + gnutls_rc = gnutls_record_send(session, unsent, unsent_len); + + if (gnutls_rc == GNUTLS_E_INTERRUPTED || gnutls_rc == GNUTLS_E_AGAIN) { +- crm_trace("Retrying to send %llu bytes remaining", +- (unsigned long long) unsent_len); ++ crm_trace("Retrying to send %zu bytes remaining", unsent_len); + + } else if (gnutls_rc < 0) { + // Caller can log as error if necessary +- crm_info("TLS connection terminated: %s " QB_XS " rc=%lld", +- gnutls_strerror((int) gnutls_rc), +- (long long) gnutls_rc); ++ crm_info("TLS connection terminated: %s " QB_XS " rc=%zd", ++ gnutls_strerror((int) gnutls_rc), gnutls_rc); + return ECONNABORTED; + + } else if (gnutls_rc < unsent_len) { +- crm_trace("Sent %lld of %llu bytes remaining", +- (long long) gnutls_rc, (unsigned long long) unsent_len); ++ crm_trace("Sent %zd of %zu bytes remaining", gnutls_rc, unsent_len); + unsent_len -= gnutls_rc; + unsent += gnutls_rc; + } else { +- crm_trace("Sent all %lld bytes remaining", (long long) gnutls_rc); ++ crm_trace("Sent all %zd bytes remaining", gnutls_rc); + break; + } + } +@@ -178,16 +175,16 @@ send_plaintext(int sock, struct iovec *i + return EINVAL; + } + +- crm_debug("Sending plaintext message of %llu bytes to socket %d", +- (unsigned long long) unsent_len, sock); ++ crm_debug("Sending plaintext message of %zu bytes to socket %d", ++ unsent_len, sock); + while (true) { + write_rc = write(sock, unsent, unsent_len); + if (write_rc < 0) { + int rc = errno; + + if ((errno == EINTR) || (errno == EAGAIN)) { +- crm_trace("Retrying to send %llu bytes remaining to socket %d", +- (unsigned long long) unsent_len, sock); ++ crm_trace("Retrying to send %zu bytes remaining to socket %d", ++ unsent_len, sock); + continue; + } + +@@ -197,15 +194,14 @@ send_plaintext(int sock, struct iovec *i + return rc; + + } else if (write_rc < unsent_len) { +- crm_trace("Sent %lld of %llu bytes remaining", +- (long long) write_rc, (unsigned long long) unsent_len); ++ crm_trace("Sent %zd of %zu bytes remaining", write_rc, unsent_len); + unsent += write_rc; + unsent_len -= write_rc; + continue; + + } else { +- crm_trace("Sent all %lld bytes remaining: %.100s", +- (long long) write_rc, (char *) (iov->iov_base)); ++ crm_trace("Sent all %zd bytes remaining: %.100s", ++ write_rc, (char *) (iov->iov_base)); + break; + } + } +@@ -456,8 +452,7 @@ pcmk__read_available_remote_data(pcmk__r + /* automatically grow the buffer when needed */ + if(remote->buffer_size < read_len) { + remote->buffer_size = 2 * read_len; +- crm_trace("Expanding buffer to %llu bytes", +- (unsigned long long) remote->buffer_size); ++ crm_trace("Expanding buffer to %zu bytes", remote->buffer_size); + remote->buffer = pcmk__realloc(remote->buffer, remote->buffer_size + 1); + } + +@@ -470,8 +465,8 @@ pcmk__read_available_remote_data(pcmk__r + } else if (read_rc == GNUTLS_E_AGAIN) { + rc = EAGAIN; + } else if (read_rc < 0) { +- crm_debug("TLS receive failed: %s (%lld)", +- gnutls_strerror(read_rc), (long long) read_rc); ++ crm_debug("TLS receive failed: %s (%zd)", ++ gnutls_strerror((int) read_rc), read_rc); + rc = EIO; + } + } else if (remote->tcp_socket) { +@@ -491,35 +486,32 @@ pcmk__read_available_remote_data(pcmk__r + remote->buffer_offset += read_rc; + /* always null terminate buffer, the +1 to alloc always allows for this. */ + remote->buffer[remote->buffer_offset] = '\0'; +- crm_trace("Received %lld more bytes (%llu total)", +- (long long) read_rc, +- (unsigned long long) remote->buffer_offset); ++ crm_trace("Received %zd more bytes (%zu total)", ++ read_rc, remote->buffer_offset); + + } else if ((rc == EINTR) || (rc == EAGAIN)) { + crm_trace("No data available for non-blocking remote read: %s (%d)", + pcmk_rc_str(rc), rc); + + } else if (read_rc == 0) { +- crm_debug("End of remote data encountered after %llu bytes", +- (unsigned long long) remote->buffer_offset); ++ crm_debug("End of remote data encountered after %zu bytes", ++ remote->buffer_offset); + return ENOTCONN; + + } else { +- crm_debug("Error receiving remote data after %llu bytes: %s (%d)", +- (unsigned long long) remote->buffer_offset, +- pcmk_rc_str(rc), rc); ++ crm_debug("Error receiving remote data after %zu bytes: %s (%d)", ++ remote->buffer_offset, pcmk_rc_str(rc), rc); + return ENOTCONN; + } + + header = localized_remote_header(remote); + if(header) { + if(remote->buffer_offset < header->size_total) { +- crm_trace("Read partial remote message (%llu of %u bytes)", +- (unsigned long long) remote->buffer_offset, +- header->size_total); ++ crm_trace("Read partial remote message (%zu of %" PRIu32 " bytes)", ++ remote->buffer_offset, header->size_total); + } else { +- crm_trace("Read full remote message of %llu bytes", +- (unsigned long long) remote->buffer_offset); ++ crm_trace("Read full remote message of %zu bytes", ++ remote->buffer_offset); + return pcmk_rc_ok; + } + } +Index: pacemaker-3.0.0+20250128.fa492f5181/lib/services/services_linux.c +=================================================================== +--- pacemaker-3.0.0+20250128.fa492f5181.orig/lib/services/services_linux.c ++++ pacemaker-3.0.0+20250128.fa492f5181/lib/services/services_linux.c +@@ -1,5 +1,5 @@ + /* +- * Copyright 2010-2024 the Pacemaker project contributors ++ * Copyright 2010-2025 the Pacemaker project contributors + * + * The version control history for this file may have further details. + * +@@ -305,14 +305,12 @@ svc_read_output(int fd, svc_action_t * o + if (is_stderr && op->stderr_data) { + len = strlen(op->stderr_data); + data = op->stderr_data; +- crm_trace("Reading %s stderr into offset %lld", +- op->id, (long long) len); ++ crm_trace("Reading %s stderr into offset %zu", op->id, len); + + } else if (is_stderr == FALSE && op->stdout_data) { + len = strlen(op->stdout_data); + data = op->stdout_data; +- crm_trace("Reading %s stdout into offset %lld", +- op->id, (long long) len); ++ crm_trace("Reading %s stdout into offset %zu", op->id, len); + + } else { + crm_trace("Reading %s %s", op->id, out_type(is_stderr)); +@@ -324,8 +322,8 @@ svc_read_output(int fd, svc_action_t * o + if (rc > 0) { + if (len < MAX_OUTPUT) { + buf[rc] = 0; +- crm_trace("Received %lld bytes of %s %s: %.80s", +- (long long) rc, op->id, out_type(is_stderr), buf); ++ crm_trace("Received %zd bytes of %s %s: %.80s", ++ rc, op->id, out_type(is_stderr), buf); + data = pcmk__realloc(data, len + rc + 1); + strcpy(data + len, buf); + len += rc; +@@ -340,9 +338,8 @@ svc_read_output(int fd, svc_action_t * o + } while ((rc == buf_read_len) || (rc < 0)); + + if (discarded > 0) { +- crm_warn("Truncated %s %s to %lld bytes (discarded %lld)", +- op->id, out_type(is_stderr), (long long) len, +- (long long) discarded); ++ crm_warn("Truncated %s %s to %zu bytes (discarded %zu)", ++ op->id, out_type(is_stderr), len, discarded); + } + + if (is_stderr) { diff --git a/pacemaker#3793-0002-Low-libcrmcommon-Catch-correct-errors-for-remote-con.patch b/pacemaker#3793-0002-Low-libcrmcommon-Catch-correct-errors-for-remote-con.patch new file mode 100644 index 0000000..cbf6f90 --- /dev/null +++ b/pacemaker#3793-0002-Low-libcrmcommon-Catch-correct-errors-for-remote-con.patch @@ -0,0 +1,121 @@ +From d8564d24f704fa6d5b1f6e9963b5b3587953a598 Mon Sep 17 00:00:00 2001 +From: Reid Wahl +Date: Wed, 8 Jan 2025 22:49:08 -0800 +Subject: [PATCH 2/2] Low: libcrmcommon: Catch correct errors for remote + connection sockets + +connect() can be interrupted by a signal, and we can treat that the same +as EAGAIN. + +select() doesn't set errno to EINPROGRESS, but it can set EINTR. + +read() and write() can set EWOULDBLOCK, which is not guaranteed to have +the same value as EAGAIN. However, it might (and in fact it does on my +system), which causes a compiler error ("duplicate case value") if we +use a switch statement for those two cases. + +Signed-off-by: Reid Wahl +--- + lib/common/remote.c | 36 +++++++++++++++++++++--------------- + 1 file changed, 21 insertions(+), 15 deletions(-) + +diff --git a/lib/common/remote.c b/lib/common/remote.c +index 6a4a4ff79a..bb29ad938c 100644 +--- a/lib/common/remote.c ++++ b/lib/common/remote.c +@@ -169,7 +169,6 @@ send_plaintext(int sock, struct iovec *iov) + { + const char *unsent = iov->iov_base; + size_t unsent_len = iov->iov_len; +- ssize_t write_rc; + + if (unsent == NULL) { + return EINVAL; +@@ -178,11 +177,12 @@ send_plaintext(int sock, struct iovec *iov) + crm_debug("Sending plaintext message of %zu bytes to socket %d", + unsent_len, sock); + while (true) { +- write_rc = write(sock, unsent, unsent_len); ++ ssize_t write_rc = write(sock, unsent, unsent_len); ++ + if (write_rc < 0) { + int rc = errno; + +- if ((errno == EINTR) || (errno == EAGAIN)) { ++ if ((rc == EINTR) || (rc == EAGAIN) || (rc == EWOULDBLOCK)) { + crm_trace("Retrying to send %zu bytes remaining to socket %d", + unsent_len, sock); + continue; +@@ -197,15 +197,13 @@ send_plaintext(int sock, struct iovec *iov) + crm_trace("Sent %zd of %zu bytes remaining", write_rc, unsent_len); + unsent += write_rc; + unsent_len -= write_rc; +- continue; + + } else { + crm_trace("Sent all %zd bytes remaining: %.100s", + write_rc, (char *) (iov->iov_base)); +- break; ++ return pcmk_rc_ok; + } + } +- return pcmk_rc_ok; + } + + // \return Standard Pacemaker return code +@@ -485,15 +483,15 @@ pcmk__read_available_remote_data(pcmk__remote_t *remote) + crm_trace("Received %zd more bytes (%zu total)", + read_rc, remote->buffer_offset); + +- } else if ((rc == EINTR) || (rc == EAGAIN)) { +- crm_trace("No data available for non-blocking remote read: %s (%d)", +- pcmk_rc_str(rc), rc); +- + } else if (read_rc == 0) { + crm_debug("End of remote data encountered after %zu bytes", + remote->buffer_offset); + return ENOTCONN; + ++ } else if ((rc == EINTR) || (rc == EAGAIN) || (rc == EWOULDBLOCK)) { ++ crm_trace("No data available for non-blocking remote read: %s (%d)", ++ pcmk_rc_str(rc), rc); ++ + } else { + crm_debug("Error receiving remote data after %zu bytes: %s (%d)", + remote->buffer_offset, pcmk_rc_str(rc), rc); +@@ -608,7 +606,7 @@ check_connect_finished(gpointer userdata) + + if (rc < 0) { // select() error + rc = errno; +- if ((rc == EINPROGRESS) || (rc == EAGAIN)) { ++ if ((rc == EINTR) || (rc == EAGAIN)) { + if ((time(NULL) - cb_data->start) < pcmk__timeout_ms2s(cb_data->timeout_ms)) { + return TRUE; // There is time left, so reschedule timer + } else { +@@ -704,11 +702,19 @@ connect_socket_retry(int sock, const struct sockaddr *addr, socklen_t addrlen, + } + + rc = connect(sock, addr, addrlen); +- if (rc < 0 && (errno != EINPROGRESS) && (errno != EAGAIN)) { ++ if (rc < 0) { + rc = errno; +- crm_warn("Could not connect socket: %s " QB_XS " rc=%d", +- pcmk_rc_str(rc), rc); +- return rc; ++ switch (rc) { ++ case EINTR: ++ case EINPROGRESS: ++ case EAGAIN: ++ break; ++ ++ default: ++ crm_warn("Could not connect socket: %s " QB_XS " rc=%d", ++ pcmk_rc_str(rc), rc); ++ return rc; ++ } + } + + cb_data = pcmk__assert_alloc(1, sizeof(struct tcp_async_cb_data)); +-- +2.43.0 + diff --git a/pacemaker#3794-0001-Low-controller-address-format-overflow-warnings.patch b/pacemaker#3794-0001-Low-controller-address-format-overflow-warnings.patch new file mode 100644 index 0000000..ba5895d --- /dev/null +++ b/pacemaker#3794-0001-Low-controller-address-format-overflow-warnings.patch @@ -0,0 +1,38 @@ +From 961be70139c04beb19d4b514afa73eadee54d23c Mon Sep 17 00:00:00 2001 +From: Athos Ribeiro +Date: Thu, 9 Jan 2025 11:37:14 -0300 +Subject: [PATCH] Low: controller: address format-overflow warnings + +When using -O3 to build pacemaker, gcc (14) will throw format-overflow +warnings for some possibly null '%s' directive arguments. While we could +address the current instance of such warning by introducing checks for +null pointers, let's just remove this log entry here since it is not +meaningful. + +alerts.c:153:19: error: '%s' directive argument is null [-Werror=format-overflow=] +153 | crm_trace("Inserting alert key %s = '%s'", *key, value); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +alerts.c:153:46: note: format string is defined here +153 | crm_trace("Inserting alert key %s = '%s'", *key, value); + | + +Signed-off-by: Athos Ribeiro +--- + daemons/controld/controld_te_events.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/daemons/controld/controld_te_events.c b/daemons/controld/controld_te_events.c +index 9ac0a2c4a2..b65f43ab10 100644 +--- a/daemons/controld/controld_te_events.c ++++ b/daemons/controld/controld_te_events.c +@@ -327,7 +327,6 @@ get_cancel_action(const char *id, const char *node) + + task = crm_element_value(action->xml, PCMK__XA_OPERATION_KEY); + if (!pcmk__str_eq(task, id, pcmk__str_casei)) { +- crm_trace("Wrong key %s for %s on %s", task, id, node); + continue; + } + +-- +2.43.0 + diff --git a/pacemaker#3796-0001-Refactor-pacemaker-attrd-always-add-remoteness-to-at.patch b/pacemaker#3796-0001-Refactor-pacemaker-attrd-always-add-remoteness-to-at.patch new file mode 100644 index 0000000..8b3db35 --- /dev/null +++ b/pacemaker#3796-0001-Refactor-pacemaker-attrd-always-add-remoteness-to-at.patch @@ -0,0 +1,35 @@ +From 9e68cb64f6660fe9e40c4ef75e1a891aa0804dbb Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Thu, 24 Oct 2024 11:18:18 -0500 +Subject: [PATCH 01/16] Refactor: pacemaker-attrd: always add remoteness to + attribute value XML + +... even if false, for code consistency and simplicity +--- + daemons/attrd/attrd_attributes.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/daemons/attrd/attrd_attributes.c b/daemons/attrd/attrd_attributes.c +index b3eda6e2f9..74301d678a 100644 +--- a/daemons/attrd/attrd_attributes.c ++++ b/daemons/attrd/attrd_attributes.c +@@ -143,14 +143,13 @@ attrd_add_value_xml(xmlNode *parent, const attribute_t *a, + crm_xml_add(xml, PCMK__XA_ATTR_SET, a->set_id); + crm_xml_add(xml, PCMK__XA_ATTR_USER, a->user); + pcmk__xe_add_node(xml, v->nodename, v->nodeid); +- if (pcmk_is_set(v->flags, attrd_value_remote)) { +- crm_xml_add_int(xml, PCMK__XA_ATTR_IS_REMOTE, 1); +- } + crm_xml_add(xml, PCMK__XA_ATTR_VALUE, v->current); + crm_xml_add_int(xml, PCMK__XA_ATTR_DAMPENING, + pcmk__timeout_ms2s(a->timeout_ms)); + crm_xml_add_int(xml, PCMK__XA_ATTR_IS_PRIVATE, + pcmk_is_set(a->flags, attrd_attr_is_private)); ++ crm_xml_add_int(xml, PCMK__XA_ATTR_IS_REMOTE, ++ pcmk_is_set(v->flags, attrd_value_remote)); + crm_xml_add_int(xml, PCMK__XA_ATTRD_IS_FORCE_WRITE, force_write); + + return xml; +-- +2.43.0 + diff --git a/pacemaker#3796-0002-Refactor-pacemaker-attrd-don-t-use-uuid-to-mean-XML-.patch b/pacemaker#3796-0002-Refactor-pacemaker-attrd-don-t-use-uuid-to-mean-XML-.patch new file mode 100644 index 0000000..a453e31 --- /dev/null +++ b/pacemaker#3796-0002-Refactor-pacemaker-attrd-don-t-use-uuid-to-mean-XML-.patch @@ -0,0 +1,85 @@ +From a1a2e20080688865b2f49e7f84b98e41e5b0381f Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Thu, 24 Oct 2024 12:13:54 -0500 +Subject: [PATCH 02/16] Refactor: pacemaker-attrd: don't use "uuid" to mean + "XML ID" + +... in write_attribute() +--- + daemons/attrd/attrd_cib.c | 33 +++++++++++++++++---------------- + 1 file changed, 17 insertions(+), 16 deletions(-) + +diff --git a/daemons/attrd/attrd_cib.c b/daemons/attrd/attrd_cib.c +index a40e7a1087..b8f509ab7d 100644 +--- a/daemons/attrd/attrd_cib.c ++++ b/daemons/attrd/attrd_cib.c +@@ -543,21 +543,22 @@ write_attribute(attribute_t *a, bool ignore_delay) + /* Iterate over each peer value of this attribute */ + g_hash_table_iter_init(&iter, a->values); + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &v)) { +- const char *uuid = NULL; ++ const char *node_xml_id = NULL; + ++ // Try to get the XML ID used for the node in the CIB + if (pcmk_is_set(v->flags, attrd_value_remote)) { +- /* If this is a Pacemaker Remote node, the node's UUID is the same +- * as its name, which we already have. +- */ +- uuid = v->nodename; ++ // A Pacemaker Remote node's XML ID is the same as its name ++ node_xml_id = v->nodename; + + } else { +- // This will create a cluster node cache entry if none exists ++ /* Get cluster node XML IDs from the peer caches. ++ * This will create a cluster node cache entry if none exists. ++ */ + pcmk__node_status_t *peer = pcmk__get_node(v->nodeid, v->nodename, + NULL, + pcmk__node_search_any); + +- uuid = peer->xml_id; ++ node_xml_id = peer->xml_id; + + // Remember peer's node ID if we're just now learning it + if ((peer->cluster_layer_id != 0) && (v->nodeid == 0)) { +@@ -574,27 +575,27 @@ write_attribute(attribute_t *a, bool ignore_delay) + } + + // Defer write if this is a cluster node that's never been seen +- if (uuid == NULL) { ++ if (node_xml_id == NULL) { + attrd_set_attr_flags(a, attrd_attr_uuid_missing); +- crm_notice("Cannot update %s[%s]='%s' now because node's UUID is " +- "unknown (will retry if learned)", ++ crm_notice("Cannot write %s[%s]='%s' to CIB because node's XML ID " ++ "is unknown (will retry if learned)", + a->id, v->nodename, v->current); + continue; + } + + // Update this value as part of the CIB transaction we're building +- rc = add_attr_update(a, v->current, uuid); ++ rc = add_attr_update(a, v->current, node_xml_id); + if (rc != pcmk_rc_ok) { +- crm_err("Failed to update %s[%s]='%s': %s " +- QB_XS " node uuid=%s id=%" PRIu32, ++ crm_err("Couldn't add %s[%s]='%s' to CIB transaction: %s " ++ QB_XS " node XML ID %s", + a->id, v->nodename, v->current, pcmk_rc_str(rc), +- uuid, v->nodeid); ++ node_xml_id); + continue; + } + +- crm_debug("Writing %s[%s]=%s (node-state-id=%s node-id=%" PRIu32 ")", ++ crm_debug("Added %s[%s]=%s to CIB transaction (node XML ID %s)", + a->id, v->nodename, pcmk__s(v->current, "(unset)"), +- uuid, v->nodeid); ++ node_xml_id); + cib_updates++; + + /* Preservation of the attribute to transmit alert */ +-- +2.43.0 + diff --git a/pacemaker#3796-0003-Low-pacemaker-attrd-use-API-to-get-peer-XML-ID.patch b/pacemaker#3796-0003-Low-pacemaker-attrd-use-API-to-get-peer-XML-ID.patch new file mode 100644 index 0000000..962f222 --- /dev/null +++ b/pacemaker#3796-0003-Low-pacemaker-attrd-use-API-to-get-peer-XML-ID.patch @@ -0,0 +1,42 @@ +From 704b42f153f060af814ae83e1193d383f14088c4 Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Thu, 24 Oct 2024 12:29:33 -0500 +Subject: [PATCH 03/16] Low: pacemaker-attrd: use API to get peer XML ID + +... for cleaner separation, and to ensure it is set whenever possible. +--- + daemons/attrd/attrd_cib.c | 2 +- + daemons/attrd/attrd_corosync.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/daemons/attrd/attrd_cib.c b/daemons/attrd/attrd_cib.c +index b8f509ab7d..6129f54c75 100644 +--- a/daemons/attrd/attrd_cib.c ++++ b/daemons/attrd/attrd_cib.c +@@ -558,7 +558,7 @@ write_attribute(attribute_t *a, bool ignore_delay) + NULL, + pcmk__node_search_any); + +- node_xml_id = peer->xml_id; ++ node_xml_id = pcmk__cluster_node_uuid(peer); + + // Remember peer's node ID if we're just now learning it + if ((peer->cluster_layer_id != 0) && (v->nodeid == 0)) { +diff --git a/daemons/attrd/attrd_corosync.c b/daemons/attrd/attrd_corosync.c +index eeb2b9b1df..72ebc1843b 100644 +--- a/daemons/attrd/attrd_corosync.c ++++ b/daemons/attrd/attrd_corosync.c +@@ -215,8 +215,8 @@ record_peer_nodeid(attribute_value_t *v, const char *host) + pcmk__node_status_t *known_peer = + pcmk__get_node(v->nodeid, host, NULL, pcmk__node_search_cluster_member); + +- crm_trace("Learned %s has node id %s", +- known_peer->name, known_peer->xml_id); ++ crm_trace("Learned %s has XML ID %s", ++ known_peer->name, pcmk__cluster_node_uuid(known_peer)); + if (attrd_election_won()) { + attrd_write_attributes(attrd_write_changed); + } +-- +2.43.0 + diff --git a/pacemaker#3796-0004-Low-pacemaker-attrd-bail-earlier-if-value-won-t-be-w.patch b/pacemaker#3796-0004-Low-pacemaker-attrd-bail-earlier-if-value-won-t-be-w.patch new file mode 100644 index 0000000..97bd2c3 --- /dev/null +++ b/pacemaker#3796-0004-Low-pacemaker-attrd-bail-earlier-if-value-won-t-be-w.patch @@ -0,0 +1,48 @@ +From 28faf9cdd3cd79b0290b9b457c5192421fc5c52f Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Thu, 24 Oct 2024 14:46:36 -0500 +Subject: [PATCH 04/16] Low: pacemaker-attrd: bail earlier if value won't be + written + +We only need the node XML ID for writing values to the CIB, so if a +value will never be written, skip looking for the XML ID. + +This does mean that cluster nodes won't be added to the peer cache for +unwritten attributes, but that shouldn't matter for them. +--- + daemons/attrd/attrd_cib.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/daemons/attrd/attrd_cib.c b/daemons/attrd/attrd_cib.c +index 6129f54c75..808a7bc7e3 100644 +--- a/daemons/attrd/attrd_cib.c ++++ b/daemons/attrd/attrd_cib.c +@@ -545,6 +545,12 @@ write_attribute(attribute_t *a, bool ignore_delay) + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &v)) { + const char *node_xml_id = NULL; + ++ // Private attributes (or any in standalone mode) are not written to CIB ++ if (stand_alone || pcmk_is_set(a->flags, attrd_attr_is_private)) { ++ private_updates++; ++ continue; ++ } ++ + // Try to get the XML ID used for the node in the CIB + if (pcmk_is_set(v->flags, attrd_value_remote)) { + // A Pacemaker Remote node's XML ID is the same as its name +@@ -568,12 +574,6 @@ write_attribute(attribute_t *a, bool ignore_delay) + } + } + +- /* If this is a private attribute, no update needs to be sent */ +- if (stand_alone || pcmk_is_set(a->flags, attrd_attr_is_private)) { +- private_updates++; +- continue; +- } +- + // Defer write if this is a cluster node that's never been seen + if (node_xml_id == NULL) { + attrd_set_attr_flags(a, attrd_attr_uuid_missing); +-- +2.43.0 + diff --git a/pacemaker#3796-0005-Refactor-libcrmcluster-allow-searching-by-XML-ID-in-.patch b/pacemaker#3796-0005-Refactor-libcrmcluster-allow-searching-by-XML-ID-in-.patch new file mode 100644 index 0000000..8c42efa --- /dev/null +++ b/pacemaker#3796-0005-Refactor-libcrmcluster-allow-searching-by-XML-ID-in-.patch @@ -0,0 +1,244 @@ +From ee01715f3ae7ff64da6f8aad0d3537faa84b013b Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Mon, 28 Oct 2024 11:24:08 -0500 +Subject: [PATCH 05/16] Refactor: libcrmcluster: allow searching by XML ID in + pcmk__search_node_caches() + +--- + daemons/attrd/attrd_ipc.c | 2 +- + daemons/based/based_messages.c | 2 +- + daemons/controld/controld_corosync.c | 2 +- + daemons/controld/controld_fencing.c | 2 +- + daemons/controld/controld_messages.c | 8 ++++--- + daemons/fenced/fenced_commands.c | 2 +- + daemons/fenced/fenced_history.c | 2 +- + daemons/fenced/fenced_remote.c | 2 +- + include/crm/cluster/internal.h | 1 + + lib/cluster/cpg.c | 2 +- + lib/cluster/membership.c | 35 ++++++++++++++++++---------- + 11 files changed, 37 insertions(+), 23 deletions(-) + +diff --git a/daemons/attrd/attrd_ipc.c b/daemons/attrd/attrd_ipc.c +index 4b26cdb3d7..5ab2763dbf 100644 +--- a/daemons/attrd/attrd_ipc.c ++++ b/daemons/attrd/attrd_ipc.c +@@ -155,7 +155,7 @@ attrd_client_peer_remove(pcmk__request_t *request) + pcmk__node_status_t *node = NULL; + char *host_alloc = NULL; + +- node = pcmk__search_node_caches(nodeid, NULL, ++ node = pcmk__search_node_caches(nodeid, NULL, NULL, + pcmk__node_search_cluster_member); + if ((node != NULL) && (node->name != NULL)) { + // Use cached name if available +diff --git a/daemons/based/based_messages.c b/daemons/based/based_messages.c +index 25d31f49ac..e8a85904f7 100644 +--- a/daemons/based/based_messages.c ++++ b/daemons/based/based_messages.c +@@ -254,7 +254,7 @@ cib_process_upgrade_server(const char *op, int options, const char *section, xml + // Notify originating peer so it can notify its local clients + pcmk__node_status_t *origin = NULL; + +- origin = pcmk__search_node_caches(0, host, ++ origin = pcmk__search_node_caches(0, host, NULL, + pcmk__node_search_cluster_member); + + crm_info("Rejecting upgrade request from %s: %s " +diff --git a/daemons/controld/controld_corosync.c b/daemons/controld/controld_corosync.c +index 02b0e823ad..61cf6293cc 100644 +--- a/daemons/controld/controld_corosync.c ++++ b/daemons/controld/controld_corosync.c +@@ -119,7 +119,7 @@ cpg_membership_callback(cpg_handle_t handle, const struct cpg_name *cpg_name, + if (controld_globals.dc_name != NULL) { + pcmk__node_status_t *peer = NULL; + +- peer = pcmk__search_node_caches(0, controld_globals.dc_name, ++ peer = pcmk__search_node_caches(0, controld_globals.dc_name, NULL, + pcmk__node_search_cluster_member); + if (peer != NULL) { + for (int i = 0; i < left_list_entries; ++i) { +diff --git a/daemons/controld/controld_fencing.c b/daemons/controld/controld_fencing.c +index e24523cbb0..093f48eb45 100644 +--- a/daemons/controld/controld_fencing.c ++++ b/daemons/controld/controld_fencing.c +@@ -591,7 +591,7 @@ handle_fence_notification(stonith_t *st, stonith_event_t *event) + |pcmk__node_search_cluster_cib; + + pcmk__node_status_t *peer = pcmk__search_node_caches(0, event->target, +- flags); ++ NULL, flags); + const char *uuid = NULL; + + if (peer == NULL) { +diff --git a/daemons/controld/controld_messages.c b/daemons/controld/controld_messages.c +index 1f4b3891ce..65b1b829ce 100644 +--- a/daemons/controld/controld_messages.c ++++ b/daemons/controld/controld_messages.c +@@ -501,7 +501,7 @@ relay_message(xmlNode * msg, gboolean originated_locally) + } + + if (!broadcast) { +- node_to = pcmk__search_node_caches(0, host_to, ++ node_to = pcmk__search_node_caches(0, host_to, NULL, + pcmk__node_search_cluster_member); + if (node_to == NULL) { + crm_warn("Ignoring message %s because node %s is unknown", +@@ -943,7 +943,8 @@ handle_node_info_request(const xmlNode *msg) + value = controld_globals.cluster->priv->node_name; + } + +- node = pcmk__search_node_caches(node_id, value, pcmk__node_search_any); ++ node = pcmk__search_node_caches(node_id, value, NULL, ++ pcmk__node_search_any); + if (node) { + crm_xml_add(reply_data, PCMK_XA_ID, node->xml_id); + crm_xml_add(reply_data, PCMK_XA_UNAME, node->name); +@@ -1070,7 +1071,8 @@ handle_request(xmlNode *stored_msg, enum crmd_fsa_cause cause) + if (strcmp(op, CRM_OP_SHUTDOWN_REQ) == 0) { + const char *from = crm_element_value(stored_msg, PCMK__XA_SRC); + pcmk__node_status_t *node = +- pcmk__search_node_caches(0, from, pcmk__node_search_cluster_member); ++ pcmk__search_node_caches(0, from, NULL, ++ pcmk__node_search_cluster_member); + + pcmk__update_peer_expected(__func__, node, CRMD_JOINSTATE_DOWN); + if(AM_I_DC == FALSE) { +diff --git a/daemons/fenced/fenced_commands.c b/daemons/fenced/fenced_commands.c +index 082a4f5af3..9205ec727d 100644 +--- a/daemons/fenced/fenced_commands.c ++++ b/daemons/fenced/fenced_commands.c +@@ -2875,7 +2875,7 @@ fence_locally(xmlNode *msg, pcmk__action_result_t *result) + pcmk__node_status_t *node = NULL; + + pcmk__scan_min_int(host, &nodeid, 0); +- node = pcmk__search_node_caches(nodeid, NULL, ++ node = pcmk__search_node_caches(nodeid, NULL, NULL, + pcmk__node_search_any + |pcmk__node_search_cluster_cib); + if (node != NULL) { +diff --git a/daemons/fenced/fenced_history.c b/daemons/fenced/fenced_history.c +index a5285209be..d1e088a617 100644 +--- a/daemons/fenced/fenced_history.c ++++ b/daemons/fenced/fenced_history.c +@@ -487,7 +487,7 @@ stonith_fence_history(xmlNode *msg, xmlNode **output, + pcmk__node_status_t *node = NULL; + + pcmk__scan_min_int(target, &nodeid, 0); +- node = pcmk__search_node_caches(nodeid, NULL, ++ node = pcmk__search_node_caches(nodeid, NULL, NULL, + pcmk__node_search_any + |pcmk__node_search_cluster_cib); + if (node != NULL) { +diff --git a/daemons/fenced/fenced_remote.c b/daemons/fenced/fenced_remote.c +index 1e19c51dc3..0f92ed5f30 100644 +--- a/daemons/fenced/fenced_remote.c ++++ b/daemons/fenced/fenced_remote.c +@@ -1245,7 +1245,7 @@ create_remote_stonith_op(const char *client, xmlNode *request, gboolean peer) + pcmk__node_status_t *node = NULL; + + pcmk__scan_min_int(op->target, &nodeid, 0); +- node = pcmk__search_node_caches(nodeid, NULL, ++ node = pcmk__search_node_caches(nodeid, NULL, NULL, + pcmk__node_search_any + |pcmk__node_search_cluster_cib); + +diff --git a/include/crm/cluster/internal.h b/include/crm/cluster/internal.h +index 11a82beee3..0afca28950 100644 +--- a/include/crm/cluster/internal.h ++++ b/include/crm/cluster/internal.h +@@ -309,6 +309,7 @@ void pcmk__cluster_forget_cluster_node(uint32_t id, const char *node_name); + void pcmk__cluster_forget_remote_node(const char *node_name); + pcmk__node_status_t *pcmk__search_node_caches(unsigned int id, + const char *uname, ++ const char *xml_id, + uint32_t flags); + void pcmk__purge_node_from_cache(const char *node_name, uint32_t node_id); + +diff --git a/lib/cluster/cpg.c b/lib/cluster/cpg.c +index 559dd408e0..fa9892e993 100644 +--- a/lib/cluster/cpg.c ++++ b/lib/cluster/cpg.c +@@ -576,7 +576,7 @@ node_left(const char *cpg_group_name, int event_counter, + size_t member_list_entries) + { + pcmk__node_status_t *peer = +- pcmk__search_node_caches(cpg_peer->nodeid, NULL, ++ pcmk__search_node_caches(cpg_peer->nodeid, NULL, NULL, + pcmk__node_search_cluster_member); + const struct cpg_address **rival = NULL; + +diff --git a/lib/cluster/membership.c b/lib/cluster/membership.c +index 0705b6570d..bccbe12aa7 100644 +--- a/lib/cluster/membership.c ++++ b/lib/cluster/membership.c +@@ -156,7 +156,7 @@ pcmk__cluster_lookup_remote_node(const char *node_name) + * entry unless it has a node ID, which means the name actually is + * associated with a cluster node. (@TODO return an error in that case?) + */ +- node = pcmk__search_node_caches(0, node_name, ++ node = pcmk__search_node_caches(0, node_name, NULL, + pcmk__node_search_cluster_member); + if ((node != NULL) && (node->xml_id == NULL)) { + /* node_name could be a pointer into the cache entry being removed, so +@@ -791,36 +791,47 @@ search_cluster_member_cache(unsigned int id, const char *uname, + * \internal + * \brief Search caches for a node (cluster or Pacemaker Remote) + * +- * \param[in] id If not 0, cluster node ID to search for +- * \param[in] uname If not NULL, node name to search for +- * \param[in] flags Group of enum pcmk__node_search_flags ++ * \param[in] id If not 0, cluster node ID to search for ++ * \param[in] uname If not NULL, node name to search for ++ * \param[in] xml_id If not NULL, CIB XML ID of node to search for ++ * \param[in] flags Group of enum pcmk__node_search_flags + * + * \return Node cache entry if found, otherwise NULL + */ + pcmk__node_status_t * +-pcmk__search_node_caches(unsigned int id, const char *uname, uint32_t flags) ++pcmk__search_node_caches(unsigned int id, const char *uname, ++ const char *xml_id, uint32_t flags) + { + pcmk__node_status_t *node = NULL; + +- pcmk__assert((id > 0) || (uname != NULL)); ++ pcmk__assert((id > 0) || (uname != NULL) || (xml_id != NULL)); + + pcmk__cluster_init_node_caches(); + +- if ((uname != NULL) && pcmk_is_set(flags, pcmk__node_search_remote)) { +- node = g_hash_table_lookup(pcmk__remote_peer_cache, uname); ++ if (pcmk_is_set(flags, pcmk__node_search_remote)) { ++ if (uname != NULL) { ++ node = g_hash_table_lookup(pcmk__remote_peer_cache, uname); ++ } else if (xml_id != NULL) { ++ node = g_hash_table_lookup(pcmk__remote_peer_cache, xml_id); ++ } + } + + if ((node == NULL) + && pcmk_is_set(flags, pcmk__node_search_cluster_member)) { + +- node = search_cluster_member_cache(id, uname, NULL); ++ node = search_cluster_member_cache(id, uname, xml_id); + } + + if ((node == NULL) && pcmk_is_set(flags, pcmk__node_search_cluster_cib)) { +- char *id_str = (id == 0)? NULL : crm_strdup_printf("%u", id); ++ if (xml_id != NULL) { ++ node = find_cib_cluster_node(xml_id, uname); ++ } else { ++ // Assumes XML ID is node ID as string (as with Corosync) ++ char *id_str = (id == 0)? NULL : crm_strdup_printf("%u", id); + +- node = find_cib_cluster_node(id_str, uname); +- free(id_str); ++ node = find_cib_cluster_node(id_str, uname); ++ free(id_str); ++ } + } + + return node; +-- +2.43.0 + diff --git a/pacemaker#3796-0006-Refactor-libcrmcluster-rename-pcmk__cluster_node_uui.patch b/pacemaker#3796-0006-Refactor-libcrmcluster-rename-pcmk__cluster_node_uui.patch new file mode 100644 index 0000000..8f83c20 --- /dev/null +++ b/pacemaker#3796-0006-Refactor-libcrmcluster-rename-pcmk__cluster_node_uui.patch @@ -0,0 +1,155 @@ +From 634ce35492459b03f26ecb217033fc033264287c Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Mon, 28 Oct 2024 12:26:12 -0500 +Subject: [PATCH 06/16] Refactor: libcrmcluster: rename + pcmk__cluster_node_uuid() + +... to pcmk__cluster_get_xml_id(). It's getting the CIB XML ID; there's +no such thing as a cluster-layer UUID, and it can be used with Pacemaker +Remote nodes as well as cluster nodes. +--- + daemons/attrd/attrd_cib.c | 2 +- + daemons/controld/controld_control.c | 2 +- + daemons/controld/controld_fencing.c | 4 ++-- + daemons/controld/controld_join_dc.c | 2 +- + daemons/controld/controld_membership.c | 2 +- + include/crm/cluster/internal.h | 2 +- + lib/cluster/cluster.c | 9 ++++++--- + lib/cluster/membership.c | 2 +- + 8 files changed, 14 insertions(+), 11 deletions(-) + +diff --git a/daemons/attrd/attrd_cib.c b/daemons/attrd/attrd_cib.c +index 808a7bc7e3..ad2bf2052c 100644 +--- a/daemons/attrd/attrd_cib.c ++++ b/daemons/attrd/attrd_cib.c +@@ -564,7 +564,7 @@ write_attribute(attribute_t *a, bool ignore_delay) + NULL, + pcmk__node_search_any); + +- node_xml_id = pcmk__cluster_node_uuid(peer); ++ node_xml_id = pcmk__cluster_get_xml_id(peer); + + // Remember peer's node ID if we're just now learning it + if ((peer->cluster_layer_id != 0) && (v->nodeid == 0)) { +diff --git a/daemons/controld/controld_control.c b/daemons/controld/controld_control.c +index 4b00f894ef..ed4751b8d7 100644 +--- a/daemons/controld/controld_control.c ++++ b/daemons/controld/controld_control.c +@@ -69,7 +69,7 @@ do_ha_control(long long action, + + free(controld_globals.our_uuid); + controld_globals.our_uuid = +- pcmk__str_copy(pcmk__cluster_node_uuid(node)); ++ pcmk__str_copy(pcmk__cluster_get_xml_id(node)); + + if (controld_globals.our_uuid == NULL) { + crm_err("Could not obtain local uuid"); +diff --git a/daemons/controld/controld_fencing.c b/daemons/controld/controld_fencing.c +index 093f48eb45..7565b6c6c4 100644 +--- a/daemons/controld/controld_fencing.c ++++ b/daemons/controld/controld_fencing.c +@@ -384,7 +384,7 @@ execute_stonith_cleanup(void) + char *target = iter->data; + pcmk__node_status_t *target_node = + pcmk__get_node(0, target, NULL, pcmk__node_search_cluster_member); +- const char *uuid = pcmk__cluster_node_uuid(target_node); ++ const char *uuid = pcmk__cluster_get_xml_id(target_node); + + crm_notice("Marking %s, target of a previous stonith action, as clean", target); + send_stonith_update(NULL, target, uuid); +@@ -598,7 +598,7 @@ handle_fence_notification(stonith_t *st, stonith_event_t *event) + return; + } + +- uuid = pcmk__cluster_node_uuid(peer); ++ uuid = pcmk__cluster_get_xml_id(peer); + + if (AM_I_DC) { + /* The DC always sends updates */ +diff --git a/daemons/controld/controld_join_dc.c b/daemons/controld/controld_join_dc.c +index 7ada26949d..9960966c6b 100644 +--- a/daemons/controld/controld_join_dc.c ++++ b/daemons/controld/controld_join_dc.c +@@ -920,7 +920,7 @@ finalize_join_for(gpointer key, gpointer value, gpointer user_data) + */ + crm_trace("Updating node name and UUID in CIB for %s", join_to); + tmp1 = pcmk__xe_create(NULL, PCMK_XE_NODE); +- crm_xml_add(tmp1, PCMK_XA_ID, pcmk__cluster_node_uuid(join_node)); ++ crm_xml_add(tmp1, PCMK_XA_ID, pcmk__cluster_get_xml_id(join_node)); + crm_xml_add(tmp1, PCMK_XA_UNAME, join_to); + fsa_cib_anon_update(PCMK_XE_NODES, tmp1); + pcmk__xml_free(tmp1); +diff --git a/daemons/controld/controld_membership.c b/daemons/controld/controld_membership.c +index 8075955953..daf0c5fd43 100644 +--- a/daemons/controld/controld_membership.c ++++ b/daemons/controld/controld_membership.c +@@ -142,7 +142,7 @@ create_node_state_update(pcmk__node_status_t *node, int flags, + } + + if (crm_xml_add(node_state, PCMK_XA_ID, +- pcmk__cluster_node_uuid(node)) == NULL) { ++ pcmk__cluster_get_xml_id(node)) == NULL) { + crm_info("Node update for %s cancelled: no ID", node->name); + pcmk__xml_free(node_state); + return NULL; +diff --git a/include/crm/cluster/internal.h b/include/crm/cluster/internal.h +index 0afca28950..bc722cb3de 100644 +--- a/include/crm/cluster/internal.h ++++ b/include/crm/cluster/internal.h +@@ -260,7 +260,7 @@ char *pcmk__cpg_message_data(cpg_handle_t handle, uint32_t sender_id, + + # endif + +-const char *pcmk__cluster_node_uuid(pcmk__node_status_t *node); ++const char *pcmk__cluster_get_xml_id(pcmk__node_status_t *node); + char *pcmk__cluster_node_name(uint32_t nodeid); + const char *pcmk__cluster_local_node_name(void); + const char *pcmk__node_name_from_uuid(const char *uuid); +diff --git a/lib/cluster/cluster.c b/lib/cluster/cluster.c +index 3427a409f3..87abcfc43e 100644 +--- a/lib/cluster/cluster.c ++++ b/lib/cluster/cluster.c +@@ -34,14 +34,14 @@ CRM_TRACE_INIT_DATA(cluster); + + /*! + * \internal +- * \brief Get a node's cluster-layer UUID, setting it if not already set ++ * \brief Get a node's XML ID in the CIB, setting it if not already set + * + * \param[in,out] node Node to check + * +- * \return Cluster-layer node UUID of \p node, or \c NULL if unknown ++ * \return CIB XML ID of \p node if known, otherwise \c NULL + */ + const char * +-pcmk__cluster_node_uuid(pcmk__node_status_t *node) ++pcmk__cluster_get_xml_id(pcmk__node_status_t *node) + { + const enum pcmk_cluster_layer cluster_layer = pcmk_get_cluster_layer(); + +@@ -52,6 +52,9 @@ pcmk__cluster_node_uuid(pcmk__node_status_t *node) + return node->xml_id; + } + ++ // xml_id is always set when a Pacemaker Remote node entry is created ++ CRM_CHECK(!pcmk_is_set(node->flags, pcmk__node_status_remote), return NULL); ++ + switch (cluster_layer) { + #if SUPPORT_COROSYNC + case pcmk_cluster_layer_corosync: +diff --git a/lib/cluster/membership.c b/lib/cluster/membership.c +index bccbe12aa7..ad55658d78 100644 +--- a/lib/cluster/membership.c ++++ b/lib/cluster/membership.c +@@ -1000,7 +1000,7 @@ pcmk__get_node(unsigned int id, const char *uname, const char *xml_id, + } + + if ((xml_id == NULL) && (node->xml_id == NULL)) { +- xml_id = pcmk__cluster_node_uuid(node); ++ xml_id = pcmk__cluster_get_xml_id(node); + if (xml_id == NULL) { + crm_debug("Cannot obtain an XML ID for node %s[%u] at this time", + node->name, id); +-- +2.43.0 + diff --git a/pacemaker#3796-0007-Low-libcrmcluster-use-pcmk__cluster_get_xml_id-when-.patch b/pacemaker#3796-0007-Low-libcrmcluster-use-pcmk__cluster_get_xml_id-when-.patch new file mode 100644 index 0000000..168bce5 --- /dev/null +++ b/pacemaker#3796-0007-Low-libcrmcluster-use-pcmk__cluster_get_xml_id-when-.patch @@ -0,0 +1,102 @@ +From 8b4d6075c778f374f7289a910dad03f425e27728 Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Mon, 28 Oct 2024 12:40:14 -0500 +Subject: [PATCH 07/16] Low: libcrmcluster: use pcmk__cluster_get_xml_id() when + possible + +... rather than using node->xml_id directly, so it gets set whenever +possible. Also, make comparisons case-sensitive. +--- + lib/cluster/cluster.c | 3 ++- + lib/cluster/election.c | 7 ++++--- + lib/cluster/membership.c | 14 +++++++++----- + 3 files changed, 15 insertions(+), 9 deletions(-) + +diff --git a/lib/cluster/cluster.c b/lib/cluster/cluster.c +index 87abcfc43e..b560eaae52 100644 +--- a/lib/cluster/cluster.c ++++ b/lib/cluster/cluster.c +@@ -337,7 +337,8 @@ pcmk__node_name_from_uuid(const char *uuid) + + g_hash_table_iter_init(&iter, pcmk__peer_cache); + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) { +- if (pcmk__str_eq(node->xml_id, uuid, pcmk__str_casei)) { ++ if (pcmk__str_eq(uuid, pcmk__cluster_get_xml_id(node), ++ pcmk__str_none)) { + return node->name; + } + } +diff --git a/lib/cluster/election.c b/lib/cluster/election.c +index 60a9156de9..51d4630b18 100644 +--- a/lib/cluster/election.c ++++ b/lib/cluster/election.c +@@ -307,7 +307,8 @@ election_vote(pcmk_cluster_t *cluster) + NULL, message_type, CRM_OP_VOTE, NULL); + + cluster->priv->election->count++; +- crm_xml_add(vote, PCMK__XA_ELECTION_OWNER, our_node->xml_id); ++ crm_xml_add(vote, PCMK__XA_ELECTION_OWNER, ++ pcmk__cluster_get_xml_id(our_node)); + crm_xml_add_int(vote, PCMK__XA_ELECTION_ID, cluster->priv->election->count); + + // Warning: PCMK__XA_ELECTION_AGE_NANO_SEC value is actually microseconds +@@ -546,8 +547,8 @@ election_count_vote(pcmk_cluster_t *cluster, const xmlNode *message, + our_node = pcmk__get_node(0, cluster->priv->node_name, NULL, + pcmk__node_search_cluster_member); + we_are_owner = (our_node != NULL) +- && pcmk__str_eq(our_node->xml_id, vote.election_owner, +- pcmk__str_none); ++ && pcmk__str_eq(pcmk__cluster_get_xml_id(our_node), ++ vote.election_owner, pcmk__str_none); + + if (!can_win) { + reason = "Not eligible"; +diff --git a/lib/cluster/membership.c b/lib/cluster/membership.c +index ad55658d78..e033f4e754 100644 +--- a/lib/cluster/membership.c ++++ b/lib/cluster/membership.c +@@ -153,7 +153,7 @@ pcmk__cluster_lookup_remote_node(const char *node_name) + + /* It's theoretically possible that the node was added to the cluster peer + * cache before it was known to be a Pacemaker Remote node. Remove that +- * entry unless it has a node ID, which means the name actually is ++ * entry unless it has an XML ID, which means the name actually is + * associated with a cluster node. (@TODO return an error in that case?) + */ + node = pcmk__search_node_caches(0, node_name, NULL, +@@ -713,8 +713,11 @@ search_cluster_member_cache(unsigned int id, const char *uname, + } else if (uuid != NULL) { + g_hash_table_iter_init(&iter, pcmk__peer_cache); + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) { +- if (pcmk__str_eq(node->xml_id, uuid, pcmk__str_casei)) { +- crm_trace("UUID match: %s", node->xml_id); ++ const char *this_xml_id = pcmk__cluster_get_xml_id(node); ++ ++ if (pcmk__str_eq(uuid, this_xml_id, pcmk__str_none)) { ++ crm_trace("Found cluster node cache entry by XML ID %s", ++ this_xml_id); + by_id = node; + break; + } +@@ -1388,7 +1391,8 @@ find_cib_cluster_node(const char *id, const char *uname) + if (id) { + g_hash_table_iter_init(&iter, cluster_node_cib_cache); + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) { +- if (pcmk__str_eq(node->xml_id, id, pcmk__str_casei)) { ++ if (pcmk__str_eq(id, pcmk__cluster_get_xml_id(node), ++ pcmk__str_none)) { + crm_trace("ID match: %s= %p", id, node); + by_id = node; + break; +@@ -1424,7 +1428,7 @@ find_cib_cluster_node(const char *id, const char *uname) + * Return by_id. */ + + } else if ((id != NULL) && (by_name->xml_id != NULL) +- && pcmk__str_eq(id, by_name->xml_id, pcmk__str_casei)) { ++ && pcmk__str_eq(id, by_name->xml_id, pcmk__str_none)) { + /* Multiple nodes have the same id in the CIB. + * Return by_name. */ + node = by_name; +-- +2.43.0 + diff --git a/pacemaker#3796-0008-Refactor-libcrmcluster-track-local-node-XML-ID-in-cl.patch b/pacemaker#3796-0008-Refactor-libcrmcluster-track-local-node-XML-ID-in-cl.patch new file mode 100644 index 0000000..0908c05 --- /dev/null +++ b/pacemaker#3796-0008-Refactor-libcrmcluster-track-local-node-XML-ID-in-cl.patch @@ -0,0 +1,67 @@ +From e3376f56cdb35a3f87389b71111bdfe29a0ea31b Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Wed, 30 Oct 2024 10:43:51 -0500 +Subject: [PATCH 08/16] Refactor: libcrmcluster: track local node XML ID in + cluster object + +This effectively reverts 7afc16075 +--- + include/crm/cluster/internal.h | 1 + + lib/cluster/cluster.c | 1 + + lib/cluster/corosync.c | 9 +++++++-- + 3 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/include/crm/cluster/internal.h b/include/crm/cluster/internal.h +index bc722cb3de..0d0ed59f2a 100644 +--- a/include/crm/cluster/internal.h ++++ b/include/crm/cluster/internal.h +@@ -91,6 +91,7 @@ typedef struct pcmk__election pcmk__election_t; + struct pcmk__cluster_private { + enum pcmk_ipc_server server; //!< Server this connection is for (if any) + char *node_name; //!< Local node name at cluster layer ++ char *node_xml_id; //!< Local node XML ID in CIB + pcmk__election_t *election; //!< Election state (if election is needed) + + /* @TODO Corosync uses an integer node ID, but cluster layers in the +diff --git a/lib/cluster/cluster.c b/lib/cluster/cluster.c +index b560eaae52..dda4b8e89a 100644 +--- a/lib/cluster/cluster.c ++++ b/lib/cluster/cluster.c +@@ -166,6 +166,7 @@ pcmk_cluster_free(pcmk_cluster_t *cluster) + return; + } + election_fini(cluster); ++ free(cluster->priv->node_xml_id); + free(cluster->priv->node_name); + free(cluster->priv); + free(cluster); +diff --git a/lib/cluster/corosync.c b/lib/cluster/corosync.c +index 32443a1e07..2782b10067 100644 +--- a/lib/cluster/corosync.c ++++ b/lib/cluster/corosync.c +@@ -460,6 +460,7 @@ pcmk__corosync_connect(pcmk_cluster_t *cluster) + { + const enum pcmk_cluster_layer cluster_layer = pcmk_get_cluster_layer(); + const char *cluster_layer_s = pcmk_cluster_layer_text(cluster_layer); ++ pcmk__node_status_t *local_node = NULL; + int rc = pcmk_rc_ok; + + pcmk__cluster_init_node_caches(); +@@ -490,8 +491,12 @@ pcmk__corosync_connect(pcmk_cluster_t *cluster) + } + + // Ensure local node always exists in peer cache +- pcmk__get_node(cluster->priv->node_id, cluster->priv->node_name, NULL, +- pcmk__node_search_cluster_member); ++ local_node = pcmk__get_node(cluster->priv->node_id, ++ cluster->priv->node_name, NULL, ++ pcmk__node_search_cluster_member); ++ ++ cluster->priv->node_xml_id = pcmk__corosync_uuid(local_node); ++ CRM_LOG_ASSERT(cluster->priv->node_xml_id != NULL); + + return pcmk_rc_ok; + } +-- +2.43.0 + diff --git a/pacemaker#3796-0009-Refactor-pacemaker-attrd-track-node-CIB-ID-rather-th.patch b/pacemaker#3796-0009-Refactor-pacemaker-attrd-track-node-CIB-ID-rather-th.patch new file mode 100644 index 0000000..3d6dc93 --- /dev/null +++ b/pacemaker#3796-0009-Refactor-pacemaker-attrd-track-node-CIB-ID-rather-th.patch @@ -0,0 +1,350 @@ +From 85d7a70916c5fd85d89ad34396be5df0ed151669 Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Thu, 24 Oct 2024 11:30:00 -0500 +Subject: [PATCH 09/16] Refactor: pacemaker-attrd: track node CIB ID rather + than cluster ID + +Previously, attribute_value_t had a nodeid member to track the cluster +ID of the node that the value is for. However the only reason we need +it is to be able to get the node's XML ID in the CIB, for writing out +the value. Rename it to node_xml_id and track the XML ID directly. + +In practice, there is no real change, since the CIB XML ID of Corosync +nodes is simply their cluster ID as a string. This allows us to keep +the same XML attribute and value in peer messages for backward +compatibility. + +If we ever support node XML IDs that are *not* the string equivalent of +their cluster IDs, rolling upgrades will be possible only from versions +with this commit and later. +--- + daemons/attrd/attrd_alerts.c | 12 ++++++++- + daemons/attrd/attrd_attributes.c | 11 +++++++- + daemons/attrd/attrd_cib.c | 45 ++++++++++++++++++++------------ + daemons/attrd/attrd_corosync.c | 42 +++++++++++++++-------------- + daemons/attrd/attrd_ipc.c | 14 +++++----- + daemons/attrd/attrd_messages.c | 6 +++-- + daemons/attrd/attrd_utils.c | 1 + + daemons/attrd/pacemaker-attrd.h | 4 +-- + 8 files changed, 86 insertions(+), 49 deletions(-) + +diff --git a/daemons/attrd/attrd_alerts.c b/daemons/attrd/attrd_alerts.c +index 55cb477c22..81d02d2ce2 100644 +--- a/daemons/attrd/attrd_alerts.c ++++ b/daemons/attrd/attrd_alerts.c +@@ -124,12 +124,22 @@ attrd_read_options(gpointer user_data) + } + + int +-attrd_send_attribute_alert(const char *node, int nodeid, ++attrd_send_attribute_alert(const char *node, const char *node_xml_id, + const char *attr, const char *value) + { ++ uint32_t nodeid = 0U; ++ pcmk__node_status_t *node_status = NULL; ++ + if (attrd_alert_list == NULL) { + return pcmk_ok; + } ++ node_status = pcmk__search_node_caches(0, node, node_xml_id, ++ pcmk__node_search_remote ++ |pcmk__node_search_cluster_member ++ |pcmk__node_search_cluster_cib); ++ if (node_status != NULL) { ++ nodeid = node_status->cluster_layer_id; ++ } + return lrmd_send_attribute_alert(attrd_lrmd_connect(), attrd_alert_list, + node, nodeid, attr, value); + } +diff --git a/daemons/attrd/attrd_attributes.c b/daemons/attrd/attrd_attributes.c +index 74301d678a..6d80acfce1 100644 +--- a/daemons/attrd/attrd_attributes.c ++++ b/daemons/attrd/attrd_attributes.c +@@ -142,7 +142,16 @@ attrd_add_value_xml(xmlNode *parent, const attribute_t *a, + crm_xml_add(xml, PCMK__XA_ATTR_SET_TYPE, a->set_type); + crm_xml_add(xml, PCMK__XA_ATTR_SET, a->set_id); + crm_xml_add(xml, PCMK__XA_ATTR_USER, a->user); +- pcmk__xe_add_node(xml, v->nodename, v->nodeid); ++ crm_xml_add(xml, PCMK__XA_ATTR_HOST, v->nodename); ++ ++ /* @COMPAT Prior to 2.1.10 and 3.0.1, the node's cluster ID was added ++ * instead of its XML ID. For Corosync and Pacemaker Remote nodes, those are ++ * the same, but if we ever support node XML IDs that differ from their ++ * cluster IDs, we will have to drop support for rolling upgrades from ++ * versions before those. ++ */ ++ crm_xml_add(xml, PCMK__XA_ATTR_HOST_ID, v->node_xml_id); ++ + crm_xml_add(xml, PCMK__XA_ATTR_VALUE, v->current); + crm_xml_add_int(xml, PCMK__XA_ATTR_DAMPENING, + pcmk__timeout_ms2s(a->timeout_ms)); +diff --git a/daemons/attrd/attrd_cib.c b/daemons/attrd/attrd_cib.c +index ad2bf2052c..665af3625d 100644 +--- a/daemons/attrd/attrd_cib.c ++++ b/daemons/attrd/attrd_cib.c +@@ -10,7 +10,6 @@ + #include + + #include +-#include // PRIu32 + #include + #include + #include +@@ -450,10 +449,12 @@ send_alert_attributes_value(attribute_t *a, GHashTable *t) + g_hash_table_iter_init(&vIter, t); + + while (g_hash_table_iter_next(&vIter, NULL, (gpointer *) & at)) { +- rc = attrd_send_attribute_alert(at->nodename, at->nodeid, ++ rc = attrd_send_attribute_alert(at->nodename, at->node_xml_id, + a->id, at->current); +- crm_trace("Sent alerts for %s[%s]=%s: nodeid=%d rc=%d", +- a->id, at->nodename, at->current, at->nodeid, rc); ++ crm_trace("Sent alerts for %s[%s]=%s with node XML ID %s " ++ "(%s agents failed)", ++ a->id, at->nodename, at->current, at->node_xml_id, ++ ((rc == 0)? "no" : ((rc == -1)? "some" : "all"))); + } + } + +@@ -462,7 +463,7 @@ set_alert_attribute_value(GHashTable *t, attribute_value_t *v) + { + attribute_value_t *a_v = pcmk__assert_alloc(1, sizeof(attribute_value_t)); + +- a_v->nodeid = v->nodeid; ++ a_v->node_xml_id = pcmk__str_copy(v->node_xml_id); + a_v->nodename = pcmk__str_copy(v->nodename); + a_v->current = pcmk__str_copy(v->current); + +@@ -551,26 +552,25 @@ write_attribute(attribute_t *a, bool ignore_delay) + continue; + } + +- // Try to get the XML ID used for the node in the CIB ++ /* We need the node's CIB XML ID to write out its attributes, so look ++ * for it now. Check the node caches first, even if the ID was ++ * previously known (in case it changed), but use any previous value as ++ * a fallback. ++ */ ++ + if (pcmk_is_set(v->flags, attrd_value_remote)) { + // A Pacemaker Remote node's XML ID is the same as its name + node_xml_id = v->nodename; + + } else { +- /* Get cluster node XML IDs from the peer caches. +- * This will create a cluster node cache entry if none exists. +- */ +- pcmk__node_status_t *peer = pcmk__get_node(v->nodeid, v->nodename, +- NULL, ++ // This creates a cluster node cache entry if none exists ++ pcmk__node_status_t *peer = pcmk__get_node(0, v->nodename, ++ v->node_xml_id, + pcmk__node_search_any); + + node_xml_id = pcmk__cluster_get_xml_id(peer); +- +- // Remember peer's node ID if we're just now learning it +- if ((peer->cluster_layer_id != 0) && (v->nodeid == 0)) { +- crm_trace("Learned ID %" PRIu32 " for node %s", +- peer->cluster_layer_id, v->nodename); +- v->nodeid = peer->cluster_layer_id; ++ if (node_xml_id == NULL) { ++ node_xml_id = v->node_xml_id; + } + } + +@@ -583,6 +583,17 @@ write_attribute(attribute_t *a, bool ignore_delay) + continue; + } + ++ /* Remember the XML ID and let peers know it (in case one of them ++ * becomes the writer later) ++ */ ++ if (!pcmk__str_eq(v->node_xml_id, node_xml_id, pcmk__str_none)) { ++ crm_trace("Setting %s[%s] node XML ID to %s (was %s)", ++ a->id, v->nodename, node_xml_id, ++ pcmk__s(v->node_xml_id, "unknown")); ++ pcmk__str_update(&(v->node_xml_id), node_xml_id); ++ attrd_broadcast_value(a, v); ++ } ++ + // Update this value as part of the CIB transaction we're building + rc = add_attr_update(a, v->current, node_xml_id); + if (rc != pcmk_rc_ok) { +diff --git a/daemons/attrd/attrd_corosync.c b/daemons/attrd/attrd_corosync.c +index 72ebc1843b..02816b94d2 100644 +--- a/daemons/attrd/attrd_corosync.c ++++ b/daemons/attrd/attrd_corosync.c +@@ -209,19 +209,6 @@ attrd_peer_change_cb(enum pcmk__node_update kind, pcmk__node_status_t *peer, + } + } + +-static void +-record_peer_nodeid(attribute_value_t *v, const char *host) +-{ +- pcmk__node_status_t *known_peer = +- pcmk__get_node(v->nodeid, host, NULL, pcmk__node_search_cluster_member); +- +- crm_trace("Learned %s has XML ID %s", +- known_peer->name, pcmk__cluster_node_uuid(known_peer)); +- if (attrd_election_won()) { +- attrd_write_attributes(attrd_write_changed); +- } +-} +- + #define readable_value(rv_v) pcmk__s((rv_v)->current, "(unset)") + + #define readable_peer(p) \ +@@ -235,6 +222,7 @@ update_attr_on_host(attribute_t *a, const pcmk__node_status_t *peer, + int is_remote = 0; + bool changed = false; + attribute_value_t *v = NULL; ++ const char *node_xml_id = crm_element_value(xml, PCMK__XA_ATTR_HOST_ID); + + // Create entry for value if not already existing + v = g_hash_table_lookup(a->values, host); +@@ -245,6 +233,13 @@ update_attr_on_host(attribute_t *a, const pcmk__node_status_t *peer, + g_hash_table_replace(a->values, v->nodename, v); + } + ++ /* If update doesn't contain the node XML ID, fall back to any previously ++ * known value (for logging) ++ */ ++ if (node_xml_id == NULL) { ++ node_xml_id = v->node_xml_id; ++ } ++ + // If value is for a Pacemaker Remote node, remember that + crm_element_value_int(xml, PCMK__XA_ATTR_IS_REMOTE, &is_remote); + if (is_remote) { +@@ -270,11 +265,12 @@ update_attr_on_host(attribute_t *a, const pcmk__node_status_t *peer, + + } else if (changed) { + crm_notice("Setting %s[%s]%s%s: %s -> %s " +- QB_XS " from %s with %s write delay", ++ QB_XS " from %s with %s write delay and node XML ID %s", + attr, host, a->set_type ? " in " : "", + pcmk__s(a->set_type, ""), readable_value(v), + pcmk__s(value, "(unset)"), peer->name, +- (a->timeout_ms == 0)? "no" : pcmk__readable_interval(a->timeout_ms)); ++ (a->timeout_ms == 0)? "no" : pcmk__readable_interval(a->timeout_ms), ++ pcmk__s(node_xml_id, "unknown")); + pcmk__str_update(&v->current, value); + attrd_set_attr_flags(a, attrd_attr_changed); + +@@ -319,11 +315,17 @@ update_attr_on_host(attribute_t *a, const pcmk__node_status_t *peer, + // This allows us to later detect local values that peer doesn't know about + attrd_set_value_flags(v, attrd_value_from_peer); + +- /* If this is a cluster node whose node ID we are learning, remember it */ +- if ((v->nodeid == 0) && !pcmk_is_set(v->flags, attrd_value_remote) +- && (crm_element_value_int(xml, PCMK__XA_ATTR_HOST_ID, +- (int*)&v->nodeid) == 0) && (v->nodeid > 0)) { +- record_peer_nodeid(v, host); ++ // Remember node's XML ID if we're just learning it ++ if ((node_xml_id != NULL) ++ && !pcmk__str_eq(node_xml_id, v->node_xml_id, pcmk__str_none)) { ++ crm_trace("Learned %s[%s] node XML ID is %s (was %s)", ++ a->id, v->nodename, node_xml_id, ++ pcmk__s(v->node_xml_id, "unknown")); ++ pcmk__str_update(&(v->node_xml_id), node_xml_id); ++ if (attrd_election_won()) { ++ // In case we couldn't write a value missing the XML ID before ++ attrd_write_attributes(attrd_write_changed); ++ } + } + } + +diff --git a/daemons/attrd/attrd_ipc.c b/daemons/attrd/attrd_ipc.c +index 5ab2763dbf..fd917a37bb 100644 +--- a/daemons/attrd/attrd_ipc.c ++++ b/daemons/attrd/attrd_ipc.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include // PRIu32 + #include + + #include +@@ -232,12 +233,13 @@ attrd_client_refresh(pcmk__request_t *request) + static void + handle_missing_host(xmlNode *xml) + { +- const char *host = crm_element_value(xml, PCMK__XA_ATTR_HOST); +- +- if (host == NULL) { +- crm_trace("Inferring host"); +- pcmk__xe_add_node(xml, attrd_cluster->priv->node_name, +- attrd_cluster->priv->node_id); ++ if (crm_element_value(xml, PCMK__XA_ATTR_HOST) == NULL) { ++ crm_trace("Inferring local node %s with XML ID %s", ++ attrd_cluster->priv->node_name, ++ attrd_cluster->priv->node_xml_id); ++ crm_xml_add(xml, PCMK__XA_ATTR_HOST, attrd_cluster->priv->node_name); ++ crm_xml_add(xml, PCMK__XA_ATTR_HOST_ID, ++ attrd_cluster->priv->node_xml_id); + } + } + +diff --git a/daemons/attrd/attrd_messages.c b/daemons/attrd/attrd_messages.c +index b6eebc66cb..e1038a820b 100644 +--- a/daemons/attrd/attrd_messages.c ++++ b/daemons/attrd/attrd_messages.c +@@ -9,6 +9,7 @@ + + #include + ++#include // PRIu32 + #include + + #include +@@ -314,8 +315,9 @@ attrd_broadcast_protocol(void) + crm_xml_add(attrd_op, PCMK__XA_ATTR_NAME, CRM_ATTR_PROTOCOL); + crm_xml_add(attrd_op, PCMK__XA_ATTR_VALUE, ATTRD_PROTOCOL_VERSION); + crm_xml_add_int(attrd_op, PCMK__XA_ATTR_IS_PRIVATE, 1); +- pcmk__xe_add_node(attrd_op, attrd_cluster->priv->node_name, +- attrd_cluster->priv->node_id); ++ crm_xml_add(attrd_op, PCMK__XA_ATTR_HOST, attrd_cluster->priv->node_name); ++ crm_xml_add(attrd_op, PCMK__XA_ATTR_HOST_ID, ++ attrd_cluster->priv->node_xml_id); + + crm_debug("Broadcasting attrd protocol version %s for node %s", + ATTRD_PROTOCOL_VERSION, attrd_cluster->priv->node_name); +diff --git a/daemons/attrd/attrd_utils.c b/daemons/attrd/attrd_utils.c +index f219b8862d..3621f5f354 100644 +--- a/daemons/attrd/attrd_utils.c ++++ b/daemons/attrd/attrd_utils.c +@@ -232,6 +232,7 @@ attrd_free_attribute_value(gpointer data) + free(v->nodename); + free(v->current); + free(v->requested); ++ free(v->node_xml_id); + free(v); + } + +diff --git a/daemons/attrd/pacemaker-attrd.h b/daemons/attrd/pacemaker-attrd.h +index 13646b8e51..07103a6b01 100644 +--- a/daemons/attrd/pacemaker-attrd.h ++++ b/daemons/attrd/pacemaker-attrd.h +@@ -99,7 +99,7 @@ extern crm_trigger_t *attrd_config_read; + + void attrd_lrmd_disconnect(void); + gboolean attrd_read_options(gpointer user_data); +-int attrd_send_attribute_alert(const char *node, int nodeid, ++int attrd_send_attribute_alert(const char *node, const char *node_xml_id, + const char *attr, const char *value); + + // Elections +@@ -155,7 +155,7 @@ typedef struct attribute_value_s { + char *nodename; // Node that this value is for + char *current; // Attribute value + char *requested; // Value specified in pending CIB write, if any +- uint32_t nodeid; // Cluster node ID of node that this value is for ++ char *node_xml_id; // XML ID used for node in CIB + uint32_t flags; // Group of attrd_value_flags + } attribute_value_t; + +-- +2.43.0 + diff --git a/pacemaker#3796-0010-Refactor-pacemaker-attrd-rename-flag-to-match-recent.patch b/pacemaker#3796-0010-Refactor-pacemaker-attrd-rename-flag-to-match-recent.patch new file mode 100644 index 0000000..946f5da --- /dev/null +++ b/pacemaker#3796-0010-Refactor-pacemaker-attrd-rename-flag-to-match-recent.patch @@ -0,0 +1,82 @@ +From aee2a5af668b6e15d9da6ecbbba7521acd1f0ea1 Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Wed, 7 Feb 2024 16:05:50 -0600 +Subject: [PATCH 10/16] Refactor: pacemaker-attrd: rename flag to match recent + change + +--- + daemons/attrd/attrd_cib.c | 15 +++++++++------ + daemons/attrd/pacemaker-attrd.h | 16 ++++++++++++---- + 2 files changed, 21 insertions(+), 10 deletions(-) + +diff --git a/daemons/attrd/attrd_cib.c b/daemons/attrd/attrd_cib.c +index 665af3625d..e7eeaa96d9 100644 +--- a/daemons/attrd/attrd_cib.c ++++ b/daemons/attrd/attrd_cib.c +@@ -532,10 +532,13 @@ write_attribute(attribute_t *a, bool ignore_delay) + } + } + +- /* Attribute will be written shortly, so clear changed flag and force +- * write flag, and initialize UUID missing flag to false. ++ /* The changed and force-write flags apply only to the next write, ++ * which this is, so clear them now. Also clear the "node unknown" flag ++ * because we will check whether it is known below and reset if appopriate. + */ +- attrd_clear_attr_flags(a, attrd_attr_changed|attrd_attr_uuid_missing|attrd_attr_force_write); ++ attrd_clear_attr_flags(a, attrd_attr_changed ++ |attrd_attr_force_write ++ |attrd_attr_node_unknown); + + /* Make the table for the attribute trap */ + alert_attribute_value = pcmk__strikey_table(NULL, +@@ -576,7 +579,7 @@ write_attribute(attribute_t *a, bool ignore_delay) + + // Defer write if this is a cluster node that's never been seen + if (node_xml_id == NULL) { +- attrd_set_attr_flags(a, attrd_attr_uuid_missing); ++ attrd_set_attr_flags(a, attrd_attr_node_unknown); + crm_notice("Cannot write %s[%s]='%s' to CIB because node's XML ID " + "is unknown (will retry if learned)", + a->id, v->nodename, v->current); +@@ -668,8 +671,8 @@ attrd_write_attributes(uint32_t options) + pcmk_is_set(options, attrd_write_all)? "all" : "changed"); + g_hash_table_iter_init(&iter, attributes); + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) & a)) { +- if (!pcmk_is_set(options, attrd_write_all) && +- pcmk_is_set(a->flags, attrd_attr_uuid_missing)) { ++ if (!pcmk_is_set(options, attrd_write_all) ++ && pcmk_is_set(a->flags, attrd_attr_node_unknown)) { + // Try writing this attribute again, in case peer ID was learned + attrd_set_attr_flags(a, attrd_attr_changed); + } else if (pcmk_is_set(a->flags, attrd_attr_force_write)) { +diff --git a/daemons/attrd/pacemaker-attrd.h b/daemons/attrd/pacemaker-attrd.h +index 07103a6b01..f0535eabaa 100644 +--- a/daemons/attrd/pacemaker-attrd.h ++++ b/daemons/attrd/pacemaker-attrd.h +@@ -115,10 +115,18 @@ void attrd_xml_add_writer(xmlNode *xml); + + enum attrd_attr_flags { + attrd_attr_none = 0U, +- attrd_attr_changed = (1U << 0), // Attribute value has changed since last write +- attrd_attr_uuid_missing = (1U << 1), // Whether we know we're missing a peer UUID +- attrd_attr_is_private = (1U << 2), // Whether to keep this attribute out of the CIB +- attrd_attr_force_write = (1U << 3), // Update attribute by ignoring delay ++ ++ // At least one of attribute's values has changed since last write ++ attrd_attr_changed = (1U << 0), ++ ++ // At least one of attribute's values has an unknown node XML ID ++ attrd_attr_node_unknown = (1U << 1), ++ ++ // This attribute should never be written to the CIB ++ attrd_attr_is_private = (1U << 2), ++ ++ // Ignore any configured delay for next write of this attribute ++ attrd_attr_force_write = (1U << 3), + }; + + typedef struct attribute_s { +-- +2.43.0 + diff --git a/pacemaker#3796-0011-Refactor-pacemaker-attrd-use-variable-for-whether-to.patch b/pacemaker#3796-0011-Refactor-pacemaker-attrd-use-variable-for-whether-to.patch new file mode 100644 index 0000000..03c590a --- /dev/null +++ b/pacemaker#3796-0011-Refactor-pacemaker-attrd-use-variable-for-whether-to.patch @@ -0,0 +1,49 @@ +From a045a72a7ea122c10c4ceacb0cf15ff7ecd125c0 Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Wed, 7 Feb 2024 16:13:44 -0600 +Subject: [PATCH 11/16] Refactor: pacemaker-attrd: use variable for whether to + write + +... for readability and to reduce code duplication +--- + daemons/attrd/attrd_cib.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/daemons/attrd/attrd_cib.c b/daemons/attrd/attrd_cib.c +index e7eeaa96d9..193b06739e 100644 +--- a/daemons/attrd/attrd_cib.c ++++ b/daemons/attrd/attrd_cib.c +@@ -492,13 +492,19 @@ write_attribute(attribute_t *a, bool ignore_delay) + GHashTableIter iter; + GHashTable *alert_attribute_value = NULL; + int rc = pcmk_ok; ++ bool should_write = true; + + if (a == NULL) { + return; + } + ++ // Private attributes (or any in standalone mode) are not written to the CIB ++ if (stand_alone || pcmk_is_set(a->flags, attrd_attr_is_private)) { ++ should_write = false; ++ } ++ + /* If this attribute will be written to the CIB ... */ +- if (!stand_alone && !pcmk_is_set(a->flags, attrd_attr_is_private)) { ++ if (should_write) { + /* Defer the write if now's not a good time */ + if (a->update && (a->update < last_cib_op_done)) { + crm_info("Write out of '%s' continuing: update %d considered lost", +@@ -549,8 +555,7 @@ write_attribute(attribute_t *a, bool ignore_delay) + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &v)) { + const char *node_xml_id = NULL; + +- // Private attributes (or any in standalone mode) are not written to CIB +- if (stand_alone || pcmk_is_set(a->flags, attrd_attr_is_private)) { ++ if (!should_write) { + private_updates++; + continue; + } +-- +2.43.0 + diff --git a/pacemaker#3796-0012-Low-pacemaker-attrd-track-node-XML-IDs-independent-o.patch b/pacemaker#3796-0012-Low-pacemaker-attrd-track-node-XML-IDs-independent-o.patch new file mode 100644 index 0000000..0047485 --- /dev/null +++ b/pacemaker#3796-0012-Low-pacemaker-attrd-track-node-XML-IDs-independent-o.patch @@ -0,0 +1,306 @@ +From 034c421a457b9dd5c654cb26292d9c05b1cd9244 Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Thu, 24 Oct 2024 17:36:40 -0500 +Subject: [PATCH 12/16] Low: pacemaker-attrd: track node XML IDs independent of + attribute values + +Previously, node XML IDs were kept in attribute_value_t. That meant that +they were duplicated for every value for a node, the values might be +known for some values and unknown or inconsistent for others, and newly +learned XML IDs would have to be broadcast per value. + +Now, maintain a global node XML ID cache. +--- + daemons/attrd/Makefile.am | 1 + + daemons/attrd/attrd_attributes.c | 2 +- + daemons/attrd/attrd_cib.c | 25 +++++----- + daemons/attrd/attrd_corosync.c | 11 +++-- + daemons/attrd/attrd_nodes.c | 82 ++++++++++++++++++++++++++++++++ + daemons/attrd/attrd_utils.c | 1 - + daemons/attrd/pacemaker-attrd.c | 2 + + daemons/attrd/pacemaker-attrd.h | 6 +++ + 8 files changed, 112 insertions(+), 18 deletions(-) + create mode 100644 daemons/attrd/attrd_nodes.c + +diff --git a/daemons/attrd/Makefile.am b/daemons/attrd/Makefile.am +index 47119679cf..a2c8fd1477 100644 +--- a/daemons/attrd/Makefile.am ++++ b/daemons/attrd/Makefile.am +@@ -31,6 +31,7 @@ pacemaker_attrd_SOURCES = attrd_alerts.c \ + attrd_elections.c \ + attrd_ipc.c \ + attrd_messages.c \ ++ attrd_nodes.c \ + attrd_sync.c \ + attrd_utils.c \ + pacemaker-attrd.c +diff --git a/daemons/attrd/attrd_attributes.c b/daemons/attrd/attrd_attributes.c +index 6d80acfce1..fdc238375e 100644 +--- a/daemons/attrd/attrd_attributes.c ++++ b/daemons/attrd/attrd_attributes.c +@@ -150,7 +150,7 @@ attrd_add_value_xml(xmlNode *parent, const attribute_t *a, + * cluster IDs, we will have to drop support for rolling upgrades from + * versions before those. + */ +- crm_xml_add(xml, PCMK__XA_ATTR_HOST_ID, v->node_xml_id); ++ crm_xml_add(xml, PCMK__XA_ATTR_HOST_ID, attrd_get_node_xml_id(v->nodename)); + + crm_xml_add(xml, PCMK__XA_ATTR_VALUE, v->current); + crm_xml_add_int(xml, PCMK__XA_ATTR_DAMPENING, +diff --git a/daemons/attrd/attrd_cib.c b/daemons/attrd/attrd_cib.c +index 193b06739e..4231e4a668 100644 +--- a/daemons/attrd/attrd_cib.c ++++ b/daemons/attrd/attrd_cib.c +@@ -449,11 +449,14 @@ send_alert_attributes_value(attribute_t *a, GHashTable *t) + g_hash_table_iter_init(&vIter, t); + + while (g_hash_table_iter_next(&vIter, NULL, (gpointer *) & at)) { +- rc = attrd_send_attribute_alert(at->nodename, at->node_xml_id, ++ const char *node_xml_id = attrd_get_node_xml_id(at->nodename); ++ ++ rc = attrd_send_attribute_alert(at->nodename, node_xml_id, + a->id, at->current); + crm_trace("Sent alerts for %s[%s]=%s with node XML ID %s " + "(%s agents failed)", +- a->id, at->nodename, at->current, at->node_xml_id, ++ a->id, at->nodename, at->current, ++ pcmk__s(node_xml_id, "unknown"), + ((rc == 0)? "no" : ((rc == -1)? "some" : "all"))); + } + } +@@ -463,7 +466,6 @@ set_alert_attribute_value(GHashTable *t, attribute_value_t *v) + { + attribute_value_t *a_v = pcmk__assert_alloc(1, sizeof(attribute_value_t)); + +- a_v->node_xml_id = pcmk__str_copy(v->node_xml_id); + a_v->nodename = pcmk__str_copy(v->nodename); + a_v->current = pcmk__str_copy(v->current); + +@@ -554,6 +556,7 @@ write_attribute(attribute_t *a, bool ignore_delay) + g_hash_table_iter_init(&iter, a->values); + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &v)) { + const char *node_xml_id = NULL; ++ const char *prev_xml_id = NULL; + + if (!should_write) { + private_updates++; +@@ -566,6 +569,8 @@ write_attribute(attribute_t *a, bool ignore_delay) + * a fallback. + */ + ++ prev_xml_id = attrd_get_node_xml_id(v->nodename); ++ + if (pcmk_is_set(v->flags, attrd_value_remote)) { + // A Pacemaker Remote node's XML ID is the same as its name + node_xml_id = v->nodename; +@@ -573,12 +578,12 @@ write_attribute(attribute_t *a, bool ignore_delay) + } else { + // This creates a cluster node cache entry if none exists + pcmk__node_status_t *peer = pcmk__get_node(0, v->nodename, +- v->node_xml_id, ++ prev_xml_id, + pcmk__node_search_any); + + node_xml_id = pcmk__cluster_get_xml_id(peer); + if (node_xml_id == NULL) { +- node_xml_id = v->node_xml_id; ++ node_xml_id = prev_xml_id; + } + } + +@@ -591,15 +596,11 @@ write_attribute(attribute_t *a, bool ignore_delay) + continue; + } + +- /* Remember the XML ID and let peers know it (in case one of them +- * becomes the writer later) +- */ +- if (!pcmk__str_eq(v->node_xml_id, node_xml_id, pcmk__str_none)) { ++ if (!pcmk__str_eq(prev_xml_id, node_xml_id, pcmk__str_none)) { + crm_trace("Setting %s[%s] node XML ID to %s (was %s)", + a->id, v->nodename, node_xml_id, +- pcmk__s(v->node_xml_id, "unknown")); +- pcmk__str_update(&(v->node_xml_id), node_xml_id); +- attrd_broadcast_value(a, v); ++ pcmk__s(prev_xml_id, "unknown")); ++ attrd_set_node_xml_id(v->nodename, node_xml_id); + } + + // Update this value as part of the CIB transaction we're building +diff --git a/daemons/attrd/attrd_corosync.c b/daemons/attrd/attrd_corosync.c +index 02816b94d2..e97e09cb86 100644 +--- a/daemons/attrd/attrd_corosync.c ++++ b/daemons/attrd/attrd_corosync.c +@@ -222,6 +222,7 @@ update_attr_on_host(attribute_t *a, const pcmk__node_status_t *peer, + int is_remote = 0; + bool changed = false; + attribute_value_t *v = NULL; ++ const char *prev_xml_id = NULL; + const char *node_xml_id = crm_element_value(xml, PCMK__XA_ATTR_HOST_ID); + + // Create entry for value if not already existing +@@ -236,8 +237,9 @@ update_attr_on_host(attribute_t *a, const pcmk__node_status_t *peer, + /* If update doesn't contain the node XML ID, fall back to any previously + * known value (for logging) + */ ++ prev_xml_id = attrd_get_node_xml_id(v->nodename); + if (node_xml_id == NULL) { +- node_xml_id = v->node_xml_id; ++ node_xml_id = prev_xml_id; + } + + // If value is for a Pacemaker Remote node, remember that +@@ -317,11 +319,11 @@ update_attr_on_host(attribute_t *a, const pcmk__node_status_t *peer, + + // Remember node's XML ID if we're just learning it + if ((node_xml_id != NULL) +- && !pcmk__str_eq(node_xml_id, v->node_xml_id, pcmk__str_none)) { ++ && !pcmk__str_eq(node_xml_id, prev_xml_id, pcmk__str_none)) { + crm_trace("Learned %s[%s] node XML ID is %s (was %s)", + a->id, v->nodename, node_xml_id, +- pcmk__s(v->node_xml_id, "unknown")); +- pcmk__str_update(&(v->node_xml_id), node_xml_id); ++ pcmk__s(prev_xml_id, "unknown")); ++ attrd_set_node_xml_id(v->nodename, node_xml_id); + if (attrd_election_won()) { + // In case we couldn't write a value missing the XML ID before + attrd_write_attributes(attrd_write_changed); +@@ -540,6 +542,7 @@ attrd_peer_remove(const char *host, bool uncache, const char *source) + + if (uncache) { + pcmk__purge_node_from_cache(host, 0); ++ attrd_forget_node_xml_id(host); + } + } + +diff --git a/daemons/attrd/attrd_nodes.c b/daemons/attrd/attrd_nodes.c +new file mode 100644 +index 0000000000..8fb7797f2d +--- /dev/null ++++ b/daemons/attrd/attrd_nodes.c +@@ -0,0 +1,82 @@ ++/* ++ * Copyright 2024-2025 the Pacemaker project contributors ++ * ++ * The version control history for this file may have further details. ++ * ++ * This source code is licensed under the GNU General Public License version 2 ++ * or later (GPLv2+) WITHOUT ANY WARRANTY. ++ */ ++ ++#include ++ ++#include // NULL ++#include // GHashTable, etc. ++ ++#include "pacemaker-attrd.h" ++ ++// Track the last known node XML ID for each node name ++static GHashTable *node_xml_ids = NULL; ++ ++/*! ++ * \internal ++ * \brief Get last known XML ID for a given node ++ * ++ * \param[in] node_name Name of node to check ++ * ++ * \return Last known XML ID for node (or NULL if none known) ++ * ++ * \note The return value may become invalid if attrd_set_node_xml_id() or ++ * attrd_forget_node_xml_id() is later called for \p node_name. ++ */ ++const char * ++attrd_get_node_xml_id(const char *node_name) ++{ ++ if (node_xml_ids == NULL) { ++ return NULL; ++ } ++ return g_hash_table_lookup(node_xml_ids, node_name); ++} ++ ++/*! ++ * \internal ++ * \brief Set last known XML ID for a given node ++ * ++ * \param[in] node_name Name of node to set ++ * \param[in] node_xml_id New XML ID to set for node ++ */ ++void ++attrd_set_node_xml_id(const char *node_name, const char *node_xml_id) ++{ ++ if (node_xml_ids == NULL) { ++ node_xml_ids = pcmk__strikey_table(free, free); ++ } ++ pcmk__insert_dup(node_xml_ids, node_name, node_xml_id); ++} ++ ++/*! ++ * \internal ++ * \brief Forget last known XML ID for a given node ++ * ++ * \param[in] node_name Name of node to forget ++ */ ++void ++attrd_forget_node_xml_id(const char *node_name) ++{ ++ if (node_xml_ids == NULL) { ++ return; ++ } ++ g_hash_table_remove(node_xml_ids, node_name); ++} ++ ++/*! ++ * \internal ++ * \brief Free the node XML ID cache ++ */ ++void ++attrd_cleanup_xml_ids(void) ++{ ++ if (node_xml_ids != NULL) { ++ g_hash_table_destroy(node_xml_ids); ++ node_xml_ids = NULL; ++ } ++} +diff --git a/daemons/attrd/attrd_utils.c b/daemons/attrd/attrd_utils.c +index 3621f5f354..f219b8862d 100644 +--- a/daemons/attrd/attrd_utils.c ++++ b/daemons/attrd/attrd_utils.c +@@ -232,7 +232,6 @@ attrd_free_attribute_value(gpointer data) + free(v->nodename); + free(v->current); + free(v->requested); +- free(v->node_xml_id); + free(v); + } + +diff --git a/daemons/attrd/pacemaker-attrd.c b/daemons/attrd/pacemaker-attrd.c +index a5dac1272a..3c31bcd932 100644 +--- a/daemons/attrd/pacemaker-attrd.c ++++ b/daemons/attrd/pacemaker-attrd.c +@@ -207,6 +207,8 @@ main(int argc, char **argv) + g_hash_table_destroy(attributes); + } + ++ attrd_cleanup_xml_ids(); ++ + g_strfreev(processed_args); + pcmk__free_arg_context(context); + +diff --git a/daemons/attrd/pacemaker-attrd.h b/daemons/attrd/pacemaker-attrd.h +index f0535eabaa..57d707c37c 100644 +--- a/daemons/attrd/pacemaker-attrd.h ++++ b/daemons/attrd/pacemaker-attrd.h +@@ -252,4 +252,10 @@ bool attrd_request_has_sync_point(xmlNode *xml); + + extern gboolean stand_alone; + ++// Node utilities (from attrd_nodes.c) ++const char *attrd_get_node_xml_id(const char *node_name); ++void attrd_set_node_xml_id(const char *node_name, const char *node_xml_id); ++void attrd_forget_node_xml_id(const char *node_name); ++void attrd_cleanup_xml_ids(void); ++ + #endif /* PACEMAKER_ATTRD__H */ +-- +2.43.0 + diff --git a/pacemaker#3796-0013-Refactor-pacemaker-attrd-drop-unused-struct-member.patch b/pacemaker#3796-0013-Refactor-pacemaker-attrd-drop-unused-struct-member.patch new file mode 100644 index 0000000..a27cc16 --- /dev/null +++ b/pacemaker#3796-0013-Refactor-pacemaker-attrd-drop-unused-struct-member.patch @@ -0,0 +1,31 @@ +From 5025e575cfb6118b4fa4d55e80e6425de03f41d2 Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Tue, 14 Jan 2025 09:24:15 -0600 +Subject: [PATCH 13/16] Refactor: pacemaker-attrd: drop unused struct member + +--- + daemons/attrd/pacemaker-attrd.h | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/daemons/attrd/pacemaker-attrd.h b/daemons/attrd/pacemaker-attrd.h +index 57d707c37c..cc0dcf29ee 100644 +--- a/daemons/attrd/pacemaker-attrd.h ++++ b/daemons/attrd/pacemaker-attrd.h +@@ -1,5 +1,5 @@ + /* +- * Copyright 2013-2024 the Pacemaker project contributors ++ * Copyright 2013-2025 the Pacemaker project contributors + * + * The version control history for this file may have further details. + * +@@ -163,7 +163,6 @@ typedef struct attribute_value_s { + char *nodename; // Node that this value is for + char *current; // Attribute value + char *requested; // Value specified in pending CIB write, if any +- char *node_xml_id; // XML ID used for node in CIB + uint32_t flags; // Group of attrd_value_flags + } attribute_value_t; + +-- +2.43.0 + diff --git a/pacemaker#3796-0014-Low-libcrmcluster-better-detect-remote-nodes-in-peer.patch b/pacemaker#3796-0014-Low-libcrmcluster-better-detect-remote-nodes-in-peer.patch new file mode 100644 index 0000000..82f36f5 --- /dev/null +++ b/pacemaker#3796-0014-Low-libcrmcluster-better-detect-remote-nodes-in-peer.patch @@ -0,0 +1,32 @@ +From c709b083d2e798970de0d4df5758764203d105b9 Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Tue, 14 Jan 2025 14:11:04 -0600 +Subject: [PATCH 14/16] Low: libcrmcluster: better detect remote nodes in peer + cache + +--- + lib/cluster/membership.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/lib/cluster/membership.c b/lib/cluster/membership.c +index e033f4e754..04bcc396f7 100644 +--- a/lib/cluster/membership.c ++++ b/lib/cluster/membership.c +@@ -158,7 +158,13 @@ pcmk__cluster_lookup_remote_node(const char *node_name) + */ + node = pcmk__search_node_caches(0, node_name, NULL, + pcmk__node_search_cluster_member); +- if ((node != NULL) && (node->xml_id == NULL)) { ++ if ((node != NULL) ++ && ((node->xml_id == NULL) ++ /* This assumes only Pacemaker Remote nodes have their XML ID the ++ * same as their node name ++ */ ++ || pcmk__str_eq(node->name, node->xml_id, pcmk__str_none))) { ++ + /* node_name could be a pointer into the cache entry being removed, so + * reassign it to a copy before the original gets freed + */ +-- +2.43.0 + diff --git a/pacemaker#3796-0015-Refactor-controller-drop-unused-argument.patch b/pacemaker#3796-0015-Refactor-controller-drop-unused-argument.patch new file mode 100644 index 0000000..ca92b72 --- /dev/null +++ b/pacemaker#3796-0015-Refactor-controller-drop-unused-argument.patch @@ -0,0 +1,62 @@ +From 200b0896455e243f2840b9849eb3a9230315c85f Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Tue, 14 Jan 2025 14:11:58 -0600 +Subject: [PATCH 15/16] Refactor: controller: drop unused argument + +--- + daemons/controld/controld_fencing.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/daemons/controld/controld_fencing.c b/daemons/controld/controld_fencing.c +index 7565b6c6c4..e5f03ef51c 100644 +--- a/daemons/controld/controld_fencing.c ++++ b/daemons/controld/controld_fencing.c +@@ -208,8 +208,7 @@ cib_fencing_updated(xmlNode *msg, int call_id, int rc, xmlNode *output, + } + + static void +-send_stonith_update(pcmk__graph_action_t *action, const char *target, +- const char *uuid) ++send_stonith_update(const char *target, const char *uuid) + { + int rc = pcmk_ok; + pcmk__node_status_t *peer = NULL; +@@ -387,7 +386,7 @@ execute_stonith_cleanup(void) + const char *uuid = pcmk__cluster_get_xml_id(target_node); + + crm_notice("Marking %s, target of a previous stonith action, as clean", target); +- send_stonith_update(NULL, target, uuid); ++ send_stonith_update(target, uuid); + free(target); + } + g_list_free(stonith_cleanup_list); +@@ -602,7 +601,7 @@ handle_fence_notification(stonith_t *st, stonith_event_t *event) + + if (AM_I_DC) { + /* The DC always sends updates */ +- send_stonith_update(NULL, event->target, uuid); ++ send_stonith_update(event->target, uuid); + + /* @TODO Ideally, at this point, we'd check whether the fenced node + * hosted any guest nodes, and call remote_node_down() for them. +@@ -639,7 +638,7 @@ handle_fence_notification(stonith_t *st, stonith_event_t *event) + * have them do so too after the election + */ + if (controld_is_local_node(event->executioner)) { +- send_stonith_update(NULL, event->target, uuid); ++ send_stonith_update(event->target, uuid); + } + add_stonith_cleanup(event->target); + } +@@ -887,7 +886,7 @@ tengine_stonith_callback(stonith_t *stonith, stonith_callback_data_t *data) + is_remote_node); + + } else if (!(pcmk_is_set(action->flags, pcmk__graph_action_sent_update))) { +- send_stonith_update(action, target, uuid); ++ send_stonith_update(target, uuid); + pcmk__set_graph_action_flags(action, + pcmk__graph_action_sent_update); + } +-- +2.43.0 + diff --git a/pacemaker#3796-0016-Refactor-controller-best-practices-for-send_stonith_.patch b/pacemaker#3796-0016-Refactor-controller-best-practices-for-send_stonith_.patch new file mode 100644 index 0000000..3ca259e --- /dev/null +++ b/pacemaker#3796-0016-Refactor-controller-best-practices-for-send_stonith_.patch @@ -0,0 +1,147 @@ +From 3c1145cc6b520cca5180fc91c8345e666b09ebce Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Tue, 14 Jan 2025 14:19:23 -0600 +Subject: [PATCH 16/16] Refactor: controller: best practices for + send_stonith_update() + +Add a doxygen block, rename function to +update_node_state_after_fencing() and uuid argument to target_xml_id for +readability, and improve log messages, comments, and formatting. +--- + daemons/controld/controld_fencing.c | 53 ++++++++++++----------------- + 1 file changed, 21 insertions(+), 32 deletions(-) + +diff --git a/daemons/controld/controld_fencing.c b/daemons/controld/controld_fencing.c +index e5f03ef51c..49d1142cb3 100644 +--- a/daemons/controld/controld_fencing.c ++++ b/daemons/controld/controld_fencing.c +@@ -207,11 +207,19 @@ cib_fencing_updated(xmlNode *msg, int call_id, int rc, xmlNode *output, + } + } + ++/*! ++ * \internal ++ * \brief Update a fencing target's node state ++ * ++ * \param[in] target Node that was successfully fenced ++ * \param[in] target_xml_id CIB XML ID of target ++ */ + static void +-send_stonith_update(const char *target, const char *uuid) ++update_node_state_after_fencing(const char *target, const char *target_xml_id) + { + int rc = pcmk_ok; + pcmk__node_status_t *peer = NULL; ++ xmlNode *node_state = NULL; + + /* We (usually) rely on the membership layer to do node_update_cluster, + * and the peer status callback to do node_update_peer, because the node +@@ -219,18 +227,10 @@ send_stonith_update(const char *target, const char *uuid) + */ + int flags = node_update_join | node_update_expected; + +- /* zero out the node-status & remove all LRM status info */ +- xmlNode *node_state = NULL; +- +- CRM_CHECK(target != NULL, return); +- CRM_CHECK(uuid != NULL, return); +- +- /* Make sure the membership and join caches are accurate. +- * Try getting any existing node cache entry also by node uuid in case it +- * doesn't have an uname yet. +- */ +- peer = pcmk__get_node(0, target, uuid, pcmk__node_search_any); ++ CRM_CHECK((target != NULL) && (target_xml_id != NULL), return); + ++ // Ensure target is cached ++ peer = pcmk__get_node(0, target, target_xml_id, pcmk__node_search_any); + CRM_CHECK(peer != NULL, return); + + if (peer->state == NULL) { +@@ -242,16 +242,15 @@ send_stonith_update(const char *target, const char *uuid) + } + + if (peer->xml_id == NULL) { +- crm_info("Recording XML ID '%s' for node '%s'", uuid, target); +- peer->xml_id = pcmk__str_copy(uuid); ++ crm_info("Recording XML ID '%s' for node '%s'", target_xml_id, target); ++ peer->xml_id = pcmk__str_copy(target_xml_id); + } + + crmd_peer_down(peer, TRUE); + +- /* Generate a node state update for the CIB */ + node_state = create_node_state_update(peer, flags, NULL, __func__); ++ crm_xml_add(node_state, PCMK_XA_ID, target_xml_id); + +- /* we have to mark whether or not remote nodes have already been fenced */ + if (pcmk_is_set(peer->flags, pcmk__node_status_remote)) { + char *now_s = pcmk__ttoa(time(NULL)); + +@@ -259,25 +258,15 @@ send_stonith_update(const char *target, const char *uuid) + free(now_s); + } + +- /* Force our known ID */ +- crm_xml_add(node_state, PCMK_XA_ID, uuid); +- + rc = controld_globals.cib_conn->cmds->modify(controld_globals.cib_conn, + PCMK_XE_STATUS, node_state, + cib_can_create); ++ pcmk__xml_free(node_state); + +- /* Delay processing the trigger until the update completes */ +- crm_debug("Sending fencing update %d for %s", rc, target); ++ crm_debug("Updating node state for %s after fencing (call %d)", target, rc); + fsa_register_cib_callback(rc, pcmk__str_copy(target), cib_fencing_updated); + +- // Make sure it sticks +- /* controld_globals.cib_conn->cmds->bump_epoch(controld_globals.cib_conn, +- * cib_none); +- */ +- + controld_delete_node_state(peer->name, controld_section_all, cib_none); +- pcmk__xml_free(node_state); +- return; + } + + /*! +@@ -386,7 +375,7 @@ execute_stonith_cleanup(void) + const char *uuid = pcmk__cluster_get_xml_id(target_node); + + crm_notice("Marking %s, target of a previous stonith action, as clean", target); +- send_stonith_update(target, uuid); ++ update_node_state_after_fencing(target, uuid); + free(target); + } + g_list_free(stonith_cleanup_list); +@@ -601,7 +590,7 @@ handle_fence_notification(stonith_t *st, stonith_event_t *event) + + if (AM_I_DC) { + /* The DC always sends updates */ +- send_stonith_update(event->target, uuid); ++ update_node_state_after_fencing(event->target, uuid); + + /* @TODO Ideally, at this point, we'd check whether the fenced node + * hosted any guest nodes, and call remote_node_down() for them. +@@ -638,7 +627,7 @@ handle_fence_notification(stonith_t *st, stonith_event_t *event) + * have them do so too after the election + */ + if (controld_is_local_node(event->executioner)) { +- send_stonith_update(event->target, uuid); ++ update_node_state_after_fencing(event->target, uuid); + } + add_stonith_cleanup(event->target); + } +@@ -886,7 +875,7 @@ tengine_stonith_callback(stonith_t *stonith, stonith_callback_data_t *data) + is_remote_node); + + } else if (!(pcmk_is_set(action->flags, pcmk__graph_action_sent_update))) { +- send_stonith_update(target, uuid); ++ update_node_state_after_fencing(target, uuid); + pcmk__set_graph_action_flags(action, + pcmk__graph_action_sent_update); + } +-- +2.43.0 + diff --git a/pacemaker#3814-0001-Low-libcrmcommon-Fix-memory-leak-in-text_end_list-cu.patch b/pacemaker#3814-0001-Low-libcrmcommon-Fix-memory-leak-in-text_end_list-cu.patch new file mode 100644 index 0000000..3cf2b19 --- /dev/null +++ b/pacemaker#3814-0001-Low-libcrmcommon-Fix-memory-leak-in-text_end_list-cu.patch @@ -0,0 +1,58 @@ +From 2cad441b37a6aff8a695754332793ac569ad54ba Mon Sep 17 00:00:00 2001 +From: Reid Wahl +Date: Fri, 24 Jan 2025 13:20:46 -0800 +Subject: [PATCH] Low: libcrmcommon: Fix memory leak in + text_end_list()/curses_end_list() + +We were freeing the string members of text_list_data_t, but not the +text_list_data_t object itself. Similarly for curses_list_data_t. + +Ref T704 + +Signed-off-by: Reid Wahl +--- + lib/common/output_text.c | 3 ++- + tools/crm_mon_curses.c | 3 ++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/lib/common/output_text.c b/lib/common/output_text.c +index 5b557834b7..4e0024c95a 100644 +--- a/lib/common/output_text.c ++++ b/lib/common/output_text.c +@@ -1,5 +1,5 @@ + /* +- * Copyright 2019-2024 the Pacemaker project contributors ++ * Copyright 2019-2025 the Pacemaker project contributors + * + * The version control history for this file may have further details. + * +@@ -34,6 +34,7 @@ free_list_data(gpointer data) { + + free(list_data->singular_noun); + free(list_data->plural_noun); ++ free(list_data); + } + + static void +diff --git a/tools/crm_mon_curses.c b/tools/crm_mon_curses.c +index 325ae03515..0654322cbe 100644 +--- a/tools/crm_mon_curses.c ++++ b/tools/crm_mon_curses.c +@@ -1,5 +1,5 @@ + /* +- * Copyright 2019-2024 the Pacemaker project contributors ++ * Copyright 2019-2025 the Pacemaker project contributors + * + * The version control history for this file may have further details. + * +@@ -40,6 +40,7 @@ free_list_data(gpointer data) { + + free(list_data->singular_noun); + free(list_data->plural_noun); ++ free(list_data); + } + + static void +-- +2.43.0 + diff --git a/pacemaker#3815-0001-Low-python-Add-python-value-for-new-CRM_EX_NO_DC-exi.patch b/pacemaker#3815-0001-Low-python-Add-python-value-for-new-CRM_EX_NO_DC-exi.patch new file mode 100644 index 0000000..04fa8dc --- /dev/null +++ b/pacemaker#3815-0001-Low-python-Add-python-value-for-new-CRM_EX_NO_DC-exi.patch @@ -0,0 +1,69 @@ +From e8ab7135f77f22ec494a202a66c7a5e9b74630d0 Mon Sep 17 00:00:00 2001 +From: Chris Lumens +Date: Fri, 31 Jan 2025 10:06:04 -0500 +Subject: [PATCH] Low: python: Add python value for new CRM_EX_NO_DC exit code. + +--- + doc/sphinx/Pacemaker_Development/c.rst | 2 ++ + include/crm/common/results.h | 5 ++++- + python/pacemaker/exitstatus.py | 3 ++- + 3 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/doc/sphinx/Pacemaker_Development/c.rst b/doc/sphinx/Pacemaker_Development/c.rst +index bfdff64633..8d879617f1 100644 +--- a/doc/sphinx/Pacemaker_Development/c.rst ++++ b/doc/sphinx/Pacemaker_Development/c.rst +@@ -850,6 +850,8 @@ messages and converting from one to another, can be found in + + * ``crm_exit_t`` (the ``CRM_EX_*`` enum values) is a system-independent code + suitable for the exit status of a process, or for interchange between nodes. ++ These values need to be kept in sync with the ``ExitStatus`` enum in ++ ``python/pacemaker/exitstatus.py``. + + * Other special-purpose status codes exist, such as ``enum ocf_exitcode`` for + the possible exit statuses of OCF resource agents (along with some +diff --git a/include/crm/common/results.h b/include/crm/common/results.h +index a671cb8efd..60a88ddbc0 100644 +--- a/include/crm/common/results.h ++++ b/include/crm/common/results.h +@@ -1,5 +1,5 @@ + /* +- * Copyright 2012-2024 the Pacemaker project contributors ++ * Copyright 2012-2025 the Pacemaker project contributors + * + * The version control history for this file may have further details. + * +@@ -226,6 +226,9 @@ enum ocf_exitcode { + * tldp.org recommends 64-113 for application use. + * + * We try to overlap with the above conventions when practical. ++ * ++ * NOTE: When new exit codes are added here, remember to also update ++ * python/pacemaker/exitstatus.py. + */ + typedef enum crm_exit_e { + // Common convention +diff --git a/python/pacemaker/exitstatus.py b/python/pacemaker/exitstatus.py +index 03f7d2c8e2..3f951ce465 100644 +--- a/python/pacemaker/exitstatus.py ++++ b/python/pacemaker/exitstatus.py +@@ -1,7 +1,7 @@ + """A module providing constants relating to why a process or function exited.""" + + __all__ = ["ExitStatus"] +-__copyright__ = "Copyright 2023-2024 the Pacemaker project contributors" ++__copyright__ = "Copyright 2023-2025 the Pacemaker project contributors" + __license__ = "GNU Lesser General Public License version 2.1 or later (LGPLv2.1+)" + + from enum import IntEnum, unique +@@ -57,6 +57,7 @@ class ExitStatus(IntEnum): + NOT_YET_IN_EFFECT = 111 + INDETERMINATE = 112 + UNSATISFIED = 113 ++ NO_DC = 114 + TIMEOUT = 124 + DEGRADED = 190 + DEGRADED_PROMOTED = 191 +-- +2.43.0 + diff --git a/pacemaker#3816-0001-Low-libcrmservices-Don-t-leak-msg-if-systemd_proxy-i.patch b/pacemaker#3816-0001-Low-libcrmservices-Don-t-leak-msg-if-systemd_proxy-i.patch new file mode 100644 index 0000000..5608990 --- /dev/null +++ b/pacemaker#3816-0001-Low-libcrmservices-Don-t-leak-msg-if-systemd_proxy-i.patch @@ -0,0 +1,34 @@ +From 51a93e7716566f78ba6f3b8fda34d0547e49d449 Mon Sep 17 00:00:00 2001 +From: Chris Lumens +Date: Mon, 3 Feb 2025 12:25:30 -0500 +Subject: [PATCH 1/2] Low: libcrmservices: Don't leak msg if systemd_proxy is + NULL. + +--- + lib/services/systemd.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/lib/services/systemd.c b/lib/services/systemd.c +index b1ab9ea49c..282e588fdd 100644 +--- a/lib/services/systemd.c ++++ b/lib/services/systemd.c +@@ -104,13 +104,15 @@ systemd_send_recv(DBusMessage *msg, DBusError *error, int timeout) + static DBusMessage * + systemd_call_simple_method(const char *method) + { +- DBusMessage *msg = systemd_new_method(method); ++ DBusMessage *msg = NULL; + DBusMessage *reply = NULL; + DBusError error; + + /* Don't call systemd_init() here, because that calls this */ + CRM_CHECK(systemd_proxy, return NULL); + ++ msg = systemd_new_method(method); ++ + if (msg == NULL) { + crm_err("Could not create message to send %s to systemd", method); + return NULL; +-- +2.43.0 + diff --git a/pacemaker#3816-0002-Refactor-libcrmservices-Unref-the-dbus-connection.patch b/pacemaker#3816-0002-Refactor-libcrmservices-Unref-the-dbus-connection.patch new file mode 100644 index 0000000..6abac9b --- /dev/null +++ b/pacemaker#3816-0002-Refactor-libcrmservices-Unref-the-dbus-connection.patch @@ -0,0 +1,37 @@ +From 4a4e721520a7c72afc42ab2ffa944327edab7325 Mon Sep 17 00:00:00 2001 +From: Chris Lumens +Date: Mon, 3 Feb 2025 12:46:41 -0500 +Subject: [PATCH 2/2] Refactor: libcrmservices: Unref the dbus connection... + +...when we disconnect from the bus. We aren't allowed to close the +connection since we acquired it with dbus_bus_get which makes it a +shared connection. So, this is the best cleanup we can do. +--- + lib/services/dbus.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/lib/services/dbus.c b/lib/services/dbus.c +index 8befef8d2e..9033d3cea6 100644 +--- a/lib/services/dbus.c ++++ b/lib/services/dbus.c +@@ -294,12 +294,12 @@ pcmk_dbus_connect(void) + void + pcmk_dbus_disconnect(DBusConnection *connection) + { +- /* Per the DBus documentation, connections created with +- * dbus_connection_open() are owned by libdbus and should never be closed. +- * +- * @TODO Should we call dbus_connection_unref() here? ++ /* We acquire our dbus connection with dbus_bus_get(), which makes it a ++ * shared connection. Therefore, we can't close or free it here. The ++ * best we can do is decrement the reference count so dbus knows when ++ * there are no more clients connected to it. + */ +- return; ++ dbus_connection_unref(connection); + } + + // Custom DBus error names to use +-- +2.43.0 + diff --git a/pacemaker#3821-0001-Fix-libcrmcluster-prevent-external-callers-from-trig.patch b/pacemaker#3821-0001-Fix-libcrmcluster-prevent-external-callers-from-trig.patch new file mode 100644 index 0000000..69003f5 --- /dev/null +++ b/pacemaker#3821-0001-Fix-libcrmcluster-prevent-external-callers-from-trig.patch @@ -0,0 +1,41 @@ +From e128ae183337327ff62012a0a11125ddbe71f06b Mon Sep 17 00:00:00 2001 +From: "Gao,Yan" +Date: Thu, 6 Feb 2025 16:45:29 +0100 +Subject: [PATCH] Fix: libcrmcluster: prevent external callers from triggering + assertion when connecting to cluster + +When sbd is connecting to cluster by calling crm_cluster_connect() -> +pcmk_cluster_connect() -> pcmk__corosync_connect() -> +pcmk__cpg_connect() -> pcmk__server_message_type() + +, it triggers assertion: + +error: log_assertion_as: pcmk__server_message_type: Triggered fatal +assertion at servers.c:165 : (server > 0) && (server < +PCMK__NELEM(server_info)) + +This fixes it by avoiding calling pcmk__server_message_type() in +pcmk__cpg_connect(). +--- + lib/cluster/cpg.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/lib/cluster/cpg.c b/lib/cluster/cpg.c +index db051fc9e4..9d84286828 100644 +--- a/lib/cluster/cpg.c ++++ b/lib/cluster/cpg.c +@@ -805,7 +805,10 @@ pcmk__cpg_connect(pcmk_cluster_t *cluster) + + cpg_evicted = false; + +- cpg_group_name = pcmk__server_message_type(cluster->priv->server); ++ if (cluster->priv->server != pcmk_ipc_unknown) { ++ cpg_group_name = pcmk__server_message_type(cluster->priv->server); ++ } ++ + if (cpg_group_name == NULL) { + /* The name will already be non-NULL for Pacemaker servers. If a + * command-line tool or external caller connects to the cluster, +-- +2.43.0 + diff --git a/pacemaker-3.0.0+20250128.fa492f5181.tar.xz b/pacemaker-3.0.0+20250128.fa492f5181.tar.xz deleted file mode 100644 index e4b6c32..0000000 --- a/pacemaker-3.0.0+20250128.fa492f5181.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2eef5d8bb8cd2a29eea4b7a9f0cb6eb7105b6c9f38f2f6849dbd2a2fb39632d7 -size 5353856 diff --git a/pacemaker-3.0.0+20250218.64cd85422c.tar.xz b/pacemaker-3.0.0+20250218.64cd85422c.tar.xz new file mode 100644 index 0000000..ad2cba4 --- /dev/null +++ b/pacemaker-3.0.0+20250218.64cd85422c.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bbc994529b987a32a8dbf79ac2e1f3300ecefc7be26ead282842299ecbfc703e +size 5354600 diff --git a/pacemaker.changes b/pacemaker.changes index 60256c6..66d1163 100644 --- a/pacemaker.changes +++ b/pacemaker.changes @@ -1,3 +1,111 @@ +------------------------------------------------------------------- +Fri Feb 21 09:34:47 UTC 2025 - Yan Gao + +- Update to version 3.0.0+20250218.64cd85422c: +- build: Fix default pacemaker-remoted path + +------------------------------------------------------------------- +Fri Feb 21 09:12:35 UTC 2025 - Yan Gao + +- libcrmcluster: prevent external callers from triggering assertion when connecting to cluster (gh#ClusterLabs/pacemaker#3821) + * pacemaker#3821-0001-Fix-libcrmcluster-prevent-external-callers-from-trig.patch + +------------------------------------------------------------------- +Wed Feb 19 17:01:34 UTC 2025 - Yan Gao + +- libcrmservices: Unref the dbus connection... (gh#ClusterLabs/pacemaker#3816) + * pacemaker#3816-0002-Refactor-libcrmservices-Unref-the-dbus-connection.patch + +- libcrmservices: Don't leak msg if systemd_proxy is NULL. (gh#ClusterLabs/pacemaker#3816) + * pacemaker#3816-0001-Low-libcrmservices-Don-t-leak-msg-if-systemd_proxy-i.patch + +------------------------------------------------------------------- +Wed Feb 19 13:58:59 UTC 2025 - Yan Gao + +- python: Add python value for new CRM_EX_NO_DC exit code. (gh#ClusterLabs/pacemaker#3815) + * pacemaker#3815-0001-Low-python-Add-python-value-for-new-CRM_EX_NO_DC-exi.patch + +- libcrmcommon: Fix memory leak in text_end_list()/curses_end_list() (gh#ClusterLabs/pacemaker#3814) + * pacemaker#3814-0001-Low-libcrmcommon-Fix-memory-leak-in-text_end_list-cu.patch + +- crmadmin: return error if DC is not elected #2902 #3606 (gh#ClusterLabs/pacemaker#3716) + * pacemaker#3716-0001-Fix-crmadmin-return-error-if-DC-is-not-elected-2902-.patch + +------------------------------------------------------------------- +Mon Feb 17 20:29:03 UTC 2025 - Yan Gao + +- controller: best practices for send_stonith_update() (gh#ClusterLabs/pacemaker#3796) + * pacemaker#3796-0016-Refactor-controller-best-practices-for-send_stonith_.patch + +- controller: drop unused argument + * pacemaker#3796-0015-Refactor-controller-drop-unused-argument.patch + +- libcrmcluster: better detect remote nodes in peer cache + * pacemaker#3796-0014-Low-libcrmcluster-better-detect-remote-nodes-in-peer.patch + +- pacemaker-attrd: drop unused struct member + * pacemaker#3796-0013-Refactor-pacemaker-attrd-drop-unused-struct-member.patch + +- pacemaker-attrd: track node XML IDs independent of attribute values + * pacemaker#3796-0012-Low-pacemaker-attrd-track-node-XML-IDs-independent-o.patch + +- pacemaker-attrd: use variable for whether to write + * pacemaker#3796-0011-Refactor-pacemaker-attrd-use-variable-for-whether-to.patch + +- pacemaker-attrd: rename flag to match recent change + * pacemaker#3796-0010-Refactor-pacemaker-attrd-rename-flag-to-match-recent.patch + +- pacemaker-attrd: track node CIB ID rather than cluster ID + * pacemaker#3796-0009-Refactor-pacemaker-attrd-track-node-CIB-ID-rather-th.patch + +- libcrmcluster: track local node XML ID in cluster object + * pacemaker#3796-0008-Refactor-libcrmcluster-track-local-node-XML-ID-in-cl.patch + +- libcrmcluster: use pcmk__cluster_get_xml_id() when possible + * pacemaker#3796-0007-Low-libcrmcluster-use-pcmk__cluster_get_xml_id-when-.patch + +- libcrmcluster: rename pcmk__cluster_node_uuid() + * pacemaker#3796-0006-Refactor-libcrmcluster-rename-pcmk__cluster_node_uui.patch + +- libcrmcluster: allow searching by XML ID in pcmk__search_node_caches() + * pacemaker#3796-0005-Refactor-libcrmcluster-allow-searching-by-XML-ID-in-.patch + +- pacemaker-attrd: bail earlier if value won't be written + * pacemaker#3796-0004-Low-pacemaker-attrd-bail-earlier-if-value-won-t-be-w.patch + +- pacemaker-attrd: use API to get peer XML ID + * pacemaker#3796-0003-Low-pacemaker-attrd-use-API-to-get-peer-XML-ID.patch + +- pacemaker-attrd: don't use "uuid" to mean "XML ID" + * pacemaker#3796-0002-Refactor-pacemaker-attrd-don-t-use-uuid-to-mean-XML-.patch + +- pacemaker-attrd: always add remoteness to attribute value XML (gh#ClusterLabs/pacemaker#3796) + * pacemaker#3796-0001-Refactor-pacemaker-attrd-always-add-remoteness-to-at.patch + +------------------------------------------------------------------- +Mon Feb 17 19:50:01 UTC 2025 - Yan Gao + +- controller: address format-overflow warnings (gh#ClusterLabs/pacemaker#3794) + * pacemaker#3794-0001-Low-controller-address-format-overflow-warnings.patch + +- libcrmcommon: Catch correct errors for remote connection sockets (gh#ClusterLabs/pacemaker#3793) + * pacemaker#3793-0002-Low-libcrmcommon-Catch-correct-errors-for-remote-con.patch + +- various: Correct some printf specifiers (gh#ClusterLabs/pacemaker#3793) + * pacemaker#3793-0001-Low-various-Correct-some-printf-specifiers.patch + +- schedulerd: Resetting error and warning flags. (gh#ClusterLabs/pacemaker#3791) + * pacemaker#3791-0001-Mid-schedulerd-Resetting-error-and-warning-flags.patch + +- controller: round timeout when checking remaining remote command time (gh#ClusterLabs/pacemaker#3781) + * pacemaker#3781-0001-Low-controller-round-timeout-when-checking-remaining.patch + +- systemd: If the state is Pending at the time of probe, execute follow up monitor. (gh#ClusterLabs/pacemaker#3746) + * pacemaker#3746-0002-Mid-systemd-If-the-state-is-Pending-at-the-time-of-p.patch + +- systemd: Fix when monitor of systemd resource continues to be pending. (gh#ClusterLabs/pacemaker#3746) + * pacemaker#3746-0001-Mid-systemd-Fix-when-monitor-of-systemd-resource-con.patch + ------------------------------------------------------------------- Mon Feb 03 10:44:36 UTC 2025 - Yan Gao diff --git a/pacemaker.spec b/pacemaker.spec index 06ae1c7..af808ae 100644 --- a/pacemaker.spec +++ b/pacemaker.spec @@ -121,7 +121,7 @@ %define with_regression_tests 0 Name: pacemaker -Version: 3.0.0+20250128.fa492f5181 +Version: 3.0.0+20250218.64cd85422c Release: 0 Summary: Scalable High-Availability cluster resource manager # AGPL-3.0 licensed extra/clustermon.sh is not present in the binary @@ -140,6 +140,35 @@ Patch6: bug-977201_pacemaker-controld-self-fencing.patch Patch7: bug-995365_pacemaker-cts-restart-systemd-journald.patch Patch8: pacemaker-cts-StartCmd.patch Patch9: bsc#1180966-0001-Log-pacemakerd-downgrade-the-warning-about-SBD_SYNC_.patch +Patch10: pacemaker#3746-0001-Mid-systemd-Fix-when-monitor-of-systemd-resource-con.patch +Patch11: pacemaker#3746-0002-Mid-systemd-If-the-state-is-Pending-at-the-time-of-p.patch +Patch12: pacemaker#3781-0001-Low-controller-round-timeout-when-checking-remaining.patch +Patch13: pacemaker#3791-0001-Mid-schedulerd-Resetting-error-and-warning-flags.patch +Patch14: pacemaker#3793-0001-Low-various-Correct-some-printf-specifiers.patch +Patch15: pacemaker#3793-0002-Low-libcrmcommon-Catch-correct-errors-for-remote-con.patch +Patch16: pacemaker#3794-0001-Low-controller-address-format-overflow-warnings.patch +Patch17: pacemaker#3796-0001-Refactor-pacemaker-attrd-always-add-remoteness-to-at.patch +Patch18: pacemaker#3796-0002-Refactor-pacemaker-attrd-don-t-use-uuid-to-mean-XML-.patch +Patch19: pacemaker#3796-0003-Low-pacemaker-attrd-use-API-to-get-peer-XML-ID.patch +Patch20: pacemaker#3796-0004-Low-pacemaker-attrd-bail-earlier-if-value-won-t-be-w.patch +Patch21: pacemaker#3796-0005-Refactor-libcrmcluster-allow-searching-by-XML-ID-in-.patch +Patch22: pacemaker#3796-0006-Refactor-libcrmcluster-rename-pcmk__cluster_node_uui.patch +Patch23: pacemaker#3796-0007-Low-libcrmcluster-use-pcmk__cluster_get_xml_id-when-.patch +Patch24: pacemaker#3796-0008-Refactor-libcrmcluster-track-local-node-XML-ID-in-cl.patch +Patch25: pacemaker#3796-0009-Refactor-pacemaker-attrd-track-node-CIB-ID-rather-th.patch +Patch26: pacemaker#3796-0010-Refactor-pacemaker-attrd-rename-flag-to-match-recent.patch +Patch27: pacemaker#3796-0011-Refactor-pacemaker-attrd-use-variable-for-whether-to.patch +Patch28: pacemaker#3796-0012-Low-pacemaker-attrd-track-node-XML-IDs-independent-o.patch +Patch29: pacemaker#3796-0013-Refactor-pacemaker-attrd-drop-unused-struct-member.patch +Patch30: pacemaker#3796-0014-Low-libcrmcluster-better-detect-remote-nodes-in-peer.patch +Patch31: pacemaker#3796-0015-Refactor-controller-drop-unused-argument.patch +Patch32: pacemaker#3796-0016-Refactor-controller-best-practices-for-send_stonith_.patch +Patch33: pacemaker#3716-0001-Fix-crmadmin-return-error-if-DC-is-not-elected-2902-.patch +Patch34: pacemaker#3814-0001-Low-libcrmcommon-Fix-memory-leak-in-text_end_list-cu.patch +Patch35: pacemaker#3815-0001-Low-python-Add-python-value-for-new-CRM_EX_NO_DC-exi.patch +Patch36: pacemaker#3816-0001-Low-libcrmservices-Don-t-leak-msg-if-systemd_proxy-i.patch +Patch37: pacemaker#3816-0002-Refactor-libcrmservices-Unref-the-dbus-connection.patch +Patch38: pacemaker#3821-0001-Fix-libcrmcluster-prevent-external-callers-from-trig.patch # Required basic build tools BuildRequires: autoconf BuildRequires: automake