import OL pacemaker-2.1.9-1.2.0.1.el9_6
This commit is contained in:
parent
39af7199d9
commit
574e20d02b
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,2 @@
|
||||
SOURCES/nagios-agents-metadata-105ab8a7b2c16b9a29cf1c1596b80136eeef332b.tar.gz
|
||||
SOURCES/pacemaker-0f7f88312.tar.gz
|
||||
SOURCES/pacemaker-49aab9983.tar.gz
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
2cbec94ad67dfbeba75e38d2c3c5c44961b3cd16 SOURCES/nagios-agents-metadata-105ab8a7b2c16b9a29cf1c1596b80136eeef332b.tar.gz
|
||||
88946a460e3be18852861269f8837aaaf339328c SOURCES/pacemaker-0f7f88312.tar.gz
|
||||
08d3f921f145e91371dd540735ebe5aa1a7a766a SOURCES/pacemaker-49aab9983.tar.gz
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1136
SOURCES/001-systemd-overrides.patch
Normal file
1136
SOURCES/001-systemd-overrides.patch
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
252
SOURCES/002-systemd-dbus-prep.patch
Normal file
252
SOURCES/002-systemd-dbus-prep.patch
Normal file
@ -0,0 +1,252 @@
|
||||
From 031e8a5bac5df472796574868f31af700bfa2b2a Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Mon, 6 Jan 2025 12:59:40 -0500
|
||||
Subject: [PATCH 1/4] Refactor: libcrmservice: systemd_init should return a
|
||||
bool.
|
||||
|
||||
---
|
||||
lib/services/systemd.c | 9 +++++----
|
||||
1 file changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/lib/services/systemd.c b/lib/services/systemd.c
|
||||
index e3545a5b123..ed517c83e3e 100644
|
||||
--- a/lib/services/systemd.c
|
||||
+++ b/lib/services/systemd.c
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <crm/services_internal.h>
|
||||
#include <crm/common/mainloop.h>
|
||||
|
||||
+#include <stdbool.h>
|
||||
#include <stdio.h> // fopen(), NULL, etc.
|
||||
#include <sys/stat.h>
|
||||
#include <gio/gio.h>
|
||||
@@ -134,7 +135,7 @@ systemd_call_simple_method(const char *method)
|
||||
return reply;
|
||||
}
|
||||
|
||||
-static gboolean
|
||||
+static bool
|
||||
systemd_init(void)
|
||||
{
|
||||
static int need_init = 1;
|
||||
@@ -153,9 +154,9 @@ systemd_init(void)
|
||||
systemd_proxy = pcmk_dbus_connect();
|
||||
}
|
||||
if (systemd_proxy == NULL) {
|
||||
- return FALSE;
|
||||
+ return false;
|
||||
}
|
||||
- return TRUE;
|
||||
+ return true;
|
||||
}
|
||||
|
||||
static inline char *
|
||||
@@ -546,7 +547,7 @@ systemd_unit_listall(void)
|
||||
DBusMessageIter elem;
|
||||
DBusMessage *reply = NULL;
|
||||
|
||||
- if (systemd_init() == FALSE) {
|
||||
+ if (!systemd_init()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
From 656ec99b060e56b89da08adaba454ce9ae9583ee Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Mon, 13 Jan 2025 14:40:16 -0500
|
||||
Subject: [PATCH 2/4] Refactor: daemons: Unindent the goagain block in
|
||||
action_complete.
|
||||
|
||||
If goagain is not set, just bail to the end of the function. Having
|
||||
done that, everything that was in the previous block can be unindented.
|
||||
I think this is a little more legible. No other code changes.
|
||||
---
|
||||
daemons/execd/execd_commands.c | 90 ++++++++++++++++++----------------
|
||||
1 file changed, 48 insertions(+), 42 deletions(-)
|
||||
|
||||
diff --git a/daemons/execd/execd_commands.c b/daemons/execd/execd_commands.c
|
||||
index 131b7bef6f3..454f8756916 100644
|
||||
--- a/daemons/execd/execd_commands.c
|
||||
+++ b/daemons/execd/execd_commands.c
|
||||
@@ -820,6 +820,9 @@ action_complete(svc_action_t * action)
|
||||
#ifdef PCMK__TIME_USE_CGT
|
||||
const char *rclass = NULL;
|
||||
bool goagain = false;
|
||||
+ int time_sum = 0;
|
||||
+ int timeout_left = 0;
|
||||
+ int delay = 0;
|
||||
#endif
|
||||
|
||||
if (!cmd) {
|
||||
@@ -922,59 +925,62 @@ action_complete(svc_action_t * action)
|
||||
#endif
|
||||
|
||||
#ifdef PCMK__TIME_USE_CGT
|
||||
- if (goagain) {
|
||||
- int time_sum = time_diff_ms(NULL, &(cmd->t_first_run));
|
||||
- int timeout_left = cmd->timeout_orig - time_sum;
|
||||
- int delay = cmd->timeout_orig / 10;
|
||||
+ if (!goagain) {
|
||||
+ goto finalize;
|
||||
+ }
|
||||
|
||||
- if(delay >= timeout_left && timeout_left > 20) {
|
||||
- delay = timeout_left/2;
|
||||
- }
|
||||
+ time_sum = time_diff_ms(NULL, &(cmd->t_first_run));
|
||||
+ timeout_left = cmd->timeout_orig - time_sum;
|
||||
+ delay = cmd->timeout_orig / 10;
|
||||
|
||||
- delay = QB_MIN(2000, delay);
|
||||
- if (delay < timeout_left) {
|
||||
- cmd->start_delay = delay;
|
||||
- cmd->timeout = timeout_left;
|
||||
+ if (delay >= timeout_left && timeout_left > 20) {
|
||||
+ delay = timeout_left/2;
|
||||
+ }
|
||||
|
||||
- if (pcmk__result_ok(&(cmd->result))) {
|
||||
- crm_debug("%s %s may still be in progress: re-scheduling (elapsed=%dms, remaining=%dms, start_delay=%dms)",
|
||||
- cmd->rsc_id, cmd->real_action, time_sum, timeout_left, delay);
|
||||
+ delay = QB_MIN(2000, delay);
|
||||
+ if (delay < timeout_left) {
|
||||
+ cmd->start_delay = delay;
|
||||
+ cmd->timeout = timeout_left;
|
||||
|
||||
- } else if (cmd->result.execution_status == PCMK_EXEC_PENDING) {
|
||||
- crm_info("%s %s is still in progress: re-scheduling (elapsed=%dms, remaining=%dms, start_delay=%dms)",
|
||||
- cmd->rsc_id, cmd->action, time_sum, timeout_left, delay);
|
||||
+ if (pcmk__result_ok(&(cmd->result))) {
|
||||
+ crm_debug("%s %s may still be in progress: re-scheduling (elapsed=%dms, remaining=%dms, start_delay=%dms)",
|
||||
+ cmd->rsc_id, cmd->real_action, time_sum, timeout_left, delay);
|
||||
|
||||
- } else {
|
||||
- crm_notice("%s %s failed '%s' (%d): re-scheduling (elapsed=%dms, remaining=%dms, start_delay=%dms)",
|
||||
- cmd->rsc_id, cmd->action,
|
||||
- services_ocf_exitcode_str(cmd->result.exit_status),
|
||||
- cmd->result.exit_status, time_sum, timeout_left,
|
||||
- delay);
|
||||
- }
|
||||
-
|
||||
- cmd_reset(cmd);
|
||||
- if(rsc) {
|
||||
- rsc->active = NULL;
|
||||
- }
|
||||
- schedule_lrmd_cmd(rsc, cmd);
|
||||
-
|
||||
- /* Don't finalize cmd, we're not done with it yet */
|
||||
- return;
|
||||
+ } else if (cmd->result.execution_status == PCMK_EXEC_PENDING) {
|
||||
+ crm_info("%s %s is still in progress: re-scheduling (elapsed=%dms, remaining=%dms, start_delay=%dms)",
|
||||
+ cmd->rsc_id, cmd->action, time_sum, timeout_left, delay);
|
||||
|
||||
} else {
|
||||
- crm_notice("Giving up on %s %s (rc=%d): timeout (elapsed=%dms, remaining=%dms)",
|
||||
- cmd->rsc_id,
|
||||
- (cmd->real_action? cmd->real_action : cmd->action),
|
||||
- cmd->result.exit_status, time_sum, timeout_left);
|
||||
- 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);
|
||||
+ crm_notice("%s %s failed '%s' (%d): re-scheduling (elapsed=%dms, remaining=%dms, start_delay=%dms)",
|
||||
+ cmd->rsc_id, cmd->action,
|
||||
+ services_ocf_exitcode_str(cmd->result.exit_status),
|
||||
+ cmd->result.exit_status, time_sum, timeout_left,
|
||||
+ delay);
|
||||
}
|
||||
+
|
||||
+ cmd_reset(cmd);
|
||||
+ if (rsc) {
|
||||
+ rsc->active = NULL;
|
||||
+ }
|
||||
+ schedule_lrmd_cmd(rsc, cmd);
|
||||
+
|
||||
+ /* Don't finalize cmd, we're not done with it yet */
|
||||
+ return;
|
||||
+
|
||||
+ } else {
|
||||
+ crm_notice("Giving up on %s %s (rc=%d): timeout (elapsed=%dms, remaining=%dms)",
|
||||
+ cmd->rsc_id,
|
||||
+ (cmd->real_action? cmd->real_action : cmd->action),
|
||||
+ cmd->result.exit_status, time_sum, timeout_left);
|
||||
+ 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
|
||||
|
||||
+finalize:
|
||||
pcmk__set_result_output(&(cmd->result), services__grab_stdout(action),
|
||||
services__grab_stderr(action));
|
||||
cmd_finalize(cmd, rsc);
|
||||
|
||||
From e182eb7d61fb82df2a3703b348a8f0e687985313 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Mon, 3 Feb 2025 12:25:30 -0500
|
||||
Subject: [PATCH 3/4] 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 ed517c83e3e..19878efaa35 100644
|
||||
--- a/lib/services/systemd.c
|
||||
+++ b/lib/services/systemd.c
|
||||
@@ -105,13 +105,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;
|
||||
|
||||
From fc0ef6cd7a35c8a38957e1f0a5353cfa5c397979 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Mon, 3 Feb 2025 12:46:41 -0500
|
||||
Subject: [PATCH 4/4] 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 0f98ddbd294..44e2386701f 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
|
||||
@ -1,42 +0,0 @@
|
||||
From a3bffc7c66bf6f796f977cffd44f223635b008c5 Mon Sep 17 00:00:00 2001
|
||||
From: Reid Wahl <nrwahl@protonmail.com>
|
||||
Date: Wed, 20 Dec 2023 13:33:47 -0800
|
||||
Subject: [PATCH] Doc: Pacemaker Explained: Add replace for
|
||||
PCMK__REMOTE_SCHEMA_DIR
|
||||
|
||||
So that the existing use in local-options.rst expands correctly.
|
||||
|
||||
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
|
||||
---
|
||||
doc/sphinx/Makefile.am | 1 +
|
||||
doc/sphinx/conf.py.in | 1 +
|
||||
3 files changed, 2 insertions(+)
|
||||
create mode 100644 doc/sphinx/conf.py.in.rej
|
||||
|
||||
diff --git a/doc/sphinx/Makefile.am b/doc/sphinx/Makefile.am
|
||||
index e48e19a..d0309ff 100644
|
||||
--- a/doc/sphinx/Makefile.am
|
||||
+++ b/doc/sphinx/Makefile.am
|
||||
@@ -134,6 +134,7 @@ $(BOOKS:%=%/conf.py): conf.py.in
|
||||
-e 's#%CRM_SCHEMA_DIRECTORY%#@CRM_SCHEMA_DIRECTORY@#g' \
|
||||
-e 's#%PACEMAKER_CONFIG_DIR%#@PACEMAKER_CONFIG_DIR@#g' \
|
||||
-e 's#%PCMK_GNUTLS_PRIORITIES%#@PCMK_GNUTLS_PRIORITIES@#g' \
|
||||
+ -e 's#%PCMK__REMOTE_SCHEMA_DIR%#@PCMK__REMOTE_SCHEMA_DIR@#g' \
|
||||
$(<) > "$@"
|
||||
|
||||
$(BOOK)/_build: $(STATIC_FILES) $(BOOK)/conf.py $(DEPS_$(BOOK)) $(wildcard $(srcdir)/$(BOOK)/*.rst)
|
||||
diff --git a/doc/sphinx/conf.py.in b/doc/sphinx/conf.py.in
|
||||
index 556eb72..511f029 100644
|
||||
--- a/doc/sphinx/conf.py.in
|
||||
+++ b/doc/sphinx/conf.py.in
|
||||
@@ -40,6 +40,7 @@ rst_prolog="""
|
||||
.. |PCMK_INIT_ENV_FILE| replace:: ``%PACEMAKER_CONFIG_DIR%/pcmk-init.env``
|
||||
.. |PCMK_LOG_FILE| replace:: %CRM_LOG_DIR%/pacemaker.log
|
||||
.. |PCMK_GNUTLS_PRIORITIES| replace:: %PCMK_GNUTLS_PRIORITIES%
|
||||
+.. |PCMK__REMOTE_SCHEMA_DIR| replace:: %PCMK__REMOTE_SCHEMA_DIR%
|
||||
.. |REMOTE_DISTRO| replace:: AlmaLinux
|
||||
.. |REMOTE_DISTRO_VER| replace:: 9
|
||||
"""
|
||||
--
|
||||
2.31.1
|
||||
|
||||
641
SOURCES/003-systemd-dbus.patch
Normal file
641
SOURCES/003-systemd-dbus.patch
Normal file
@ -0,0 +1,641 @@
|
||||
From dac88ca0fa3d7fbcc4924599e90a3b3465cd8525 Mon Sep 17 00:00:00 2001
|
||||
From: Reid Wahl <nrwahl@protonmail.com>
|
||||
Date: Wed, 5 Feb 2025 16:42:44 -0800
|
||||
Subject: [PATCH 1/4] Refactor: libcrmservice: New services__copy_result()
|
||||
function
|
||||
|
||||
Ref T25
|
||||
|
||||
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
|
||||
---
|
||||
daemons/execd/execd_commands.c | 9 +++------
|
||||
include/crm/services_internal.h | 7 ++++++-
|
||||
lib/fencing/st_actions.c | 5 ++---
|
||||
lib/lrmd/lrmd_client.c | 6 ++----
|
||||
lib/services/services.c | 16 +++++++++++++++-
|
||||
5 files changed, 28 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/daemons/execd/execd_commands.c b/daemons/execd/execd_commands.c
|
||||
index 454f8756916..afb5f599b33 100644
|
||||
--- a/daemons/execd/execd_commands.c
|
||||
+++ b/daemons/execd/execd_commands.c
|
||||
@@ -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.
|
||||
*
|
||||
@@ -1344,8 +1344,7 @@ execute_nonstonith_action(lrmd_rsc_t *rsc, lrmd_cmd_t *cmd)
|
||||
}
|
||||
|
||||
if (action->rc != PCMK_OCF_UNKNOWN) {
|
||||
- pcmk__set_result(&(cmd->result), action->rc, action->status,
|
||||
- services__exit_reason(action));
|
||||
+ services__copy_result(action, &(cmd->result));
|
||||
services_action_free(action);
|
||||
cmd_finalize(cmd, rsc);
|
||||
return;
|
||||
@@ -1370,9 +1369,7 @@ execute_nonstonith_action(lrmd_rsc_t *rsc, lrmd_cmd_t *cmd)
|
||||
* called cmd_finalize(), which in this case should only reset (not
|
||||
* free) cmd.
|
||||
*/
|
||||
-
|
||||
- pcmk__set_result(&(cmd->result), action->rc, action->status,
|
||||
- services__exit_reason(action));
|
||||
+ services__copy_result(action, &(cmd->result));
|
||||
services_action_free(action);
|
||||
}
|
||||
}
|
||||
diff --git a/include/crm/services_internal.h b/include/crm/services_internal.h
|
||||
index ada97e1e711..63b034dcd24 100644
|
||||
--- a/include/crm/services_internal.h
|
||||
+++ b/include/crm/services_internal.h
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright 2010-2022 the Pacemaker project contributors
|
||||
+ * Copyright 2010-2025 the Pacemaker project contributors
|
||||
*
|
||||
* The version control history for this file may have further details.
|
||||
*
|
||||
@@ -10,6 +10,9 @@
|
||||
#ifndef PCMK__SERVICES_INTERNAL__H
|
||||
# define PCMK__SERVICES_INTERNAL__H
|
||||
|
||||
+#include <crm/common/results_internal.h> // pcmk__action_result_t
|
||||
+#include <crm/services.h> // svc_action_t
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -50,6 +53,8 @@ char *services__grab_stderr(svc_action_t *action);
|
||||
void services__set_result(svc_action_t *action, int agent_status,
|
||||
enum pcmk_exec_status exec_status,
|
||||
const char *exit_reason);
|
||||
+void services__copy_result(const svc_action_t *action,
|
||||
+ pcmk__action_result_t *result);
|
||||
|
||||
void services__format_result(svc_action_t *action, int agent_status,
|
||||
enum pcmk_exec_status exec_status,
|
||||
diff --git a/lib/fencing/st_actions.c b/lib/fencing/st_actions.c
|
||||
index 6b4d1e73527..a0f3e0377c0 100644
|
||||
--- a/lib/fencing/st_actions.c
|
||||
+++ b/lib/fencing/st_actions.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.
|
||||
*
|
||||
@@ -63,8 +63,7 @@ static void log_action(stonith_action_t *action, pid_t pid);
|
||||
static void
|
||||
set_result_from_svc_action(stonith_action_t *action, svc_action_t *svc_action)
|
||||
{
|
||||
- pcmk__set_result(&(action->result), svc_action->rc, svc_action->status,
|
||||
- services__exit_reason(svc_action));
|
||||
+ services__copy_result(svc_action, &(action->result));
|
||||
pcmk__set_result_output(&(action->result),
|
||||
services__grab_stdout(svc_action),
|
||||
services__grab_stderr(svc_action));
|
||||
diff --git a/lib/lrmd/lrmd_client.c b/lib/lrmd/lrmd_client.c
|
||||
index ae4c100def0..5fcdf2377e8 100644
|
||||
--- a/lib/lrmd/lrmd_client.c
|
||||
+++ b/lib/lrmd/lrmd_client.c
|
||||
@@ -2555,8 +2555,7 @@ metadata_complete(svc_action_t *action)
|
||||
struct metadata_cb *metadata_cb = (struct metadata_cb *) action->cb_data;
|
||||
pcmk__action_result_t result = PCMK__UNKNOWN_RESULT;
|
||||
|
||||
- pcmk__set_result(&result, action->rc, action->status,
|
||||
- services__exit_reason(action));
|
||||
+ services__copy_result(action, &result);
|
||||
pcmk__set_result_output(&result, action->stdout_data, action->stderr_data);
|
||||
|
||||
metadata_cb->callback(0, &result, metadata_cb->user_data);
|
||||
@@ -2624,8 +2623,7 @@ lrmd__metadata_async(const lrmd_rsc_info_t *rsc,
|
||||
return ENOMEM;
|
||||
}
|
||||
if (action->rc != PCMK_OCF_UNKNOWN) {
|
||||
- pcmk__set_result(&result, action->rc, action->status,
|
||||
- services__exit_reason(action));
|
||||
+ services__copy_result(action, &result);
|
||||
callback(0, &result, user_data);
|
||||
pcmk__reset_result(&result);
|
||||
services_action_free(action);
|
||||
diff --git a/lib/services/services.c b/lib/services/services.c
|
||||
index 2ba0eb24b9d..0d0eb46d342 100644
|
||||
--- a/lib/services/services.c
|
||||
+++ b/lib/services/services.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.
|
||||
*
|
||||
@@ -1336,6 +1336,20 @@ services__set_result(svc_action_t *action, int agent_status,
|
||||
}
|
||||
}
|
||||
|
||||
+/*!
|
||||
+ * \internal
|
||||
+ * \brief Set a \c pcmk__action_result_t based on a \c svc_action_t
|
||||
+ *
|
||||
+ * \param[in] action Service action whose result to copy
|
||||
+ * \param[in,out] result Action result object to set
|
||||
+ */
|
||||
+void
|
||||
+services__copy_result(const svc_action_t *action, pcmk__action_result_t *result)
|
||||
+{
|
||||
+ pcmk__set_result(result, action->rc, action->status,
|
||||
+ action->opaque->exit_reason);
|
||||
+}
|
||||
+
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Set the result of an action, with a formatted exit reason
|
||||
|
||||
From 283225383916358f6fc905afdc40e423583bc9bd Mon Sep 17 00:00:00 2001
|
||||
From: Reid Wahl <nrwahl@protonmail.com>
|
||||
Date: Wed, 5 Feb 2025 03:35:04 -0800
|
||||
Subject: [PATCH 2/4] Refactor: libcrmservice: Store systemd job path in
|
||||
svc_action_private_t
|
||||
|
||||
We will use this later for D-Bus signal message filtering.
|
||||
|
||||
Ref T25
|
||||
|
||||
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
|
||||
---
|
||||
lib/services/services.c | 5 +++++
|
||||
lib/services/services_private.h | 6 +++++-
|
||||
lib/services/systemd.c | 2 ++
|
||||
3 files changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/services/services.c b/lib/services/services.c
|
||||
index 0d0eb46d342..e1e98120c09 100644
|
||||
--- a/lib/services/services.c
|
||||
+++ b/lib/services/services.c
|
||||
@@ -635,6 +635,11 @@ services_action_free(svc_action_t * op)
|
||||
}
|
||||
|
||||
free(op->opaque->exit_reason);
|
||||
+
|
||||
+#if SUPPORT_SYSTEMD
|
||||
+ free(op->opaque->job_path);
|
||||
+#endif // SUPPORT_SYSTEMD
|
||||
+
|
||||
free(op->opaque);
|
||||
free(op->rsc);
|
||||
free(op->action);
|
||||
diff --git a/lib/services/services_private.h b/lib/services/services_private.h
|
||||
index 48269b80308..91b49b4248c 100644
|
||||
--- a/lib/services/services_private.h
|
||||
+++ b/lib/services/services_private.h
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2011 Red Hat, Inc.
|
||||
- * Later changes copyright 2012-2022 the Pacemaker project contributors
|
||||
+ * Later changes copyright 2012-2025 the Pacemaker project contributors
|
||||
*
|
||||
* The version control history for this file may have further details.
|
||||
*
|
||||
@@ -42,6 +42,10 @@ struct svc_action_private_s {
|
||||
DBusPendingCall* pending;
|
||||
unsigned timerid;
|
||||
#endif
|
||||
+
|
||||
+#if SUPPORT_SYSTEMD
|
||||
+ char *job_path;
|
||||
+#endif // SUPPORT_SYSTEMD
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
diff --git a/lib/services/systemd.c b/lib/services/systemd.c
|
||||
index 19878efaa35..090a30bb1ca 100644
|
||||
--- a/lib/services/systemd.c
|
||||
+++ b/lib/services/systemd.c
|
||||
@@ -760,8 +760,10 @@ process_unit_method_reply(DBusMessage *reply, svc_action_t *op)
|
||||
dbus_message_get_args(reply, NULL,
|
||||
DBUS_TYPE_OBJECT_PATH, &path,
|
||||
DBUS_TYPE_INVALID);
|
||||
+
|
||||
crm_debug("DBus request for %s of %s using %s succeeded",
|
||||
op->action, pcmk__s(op->rsc, "unknown resource"), path);
|
||||
+ pcmk__str_update(&(op->opaque->job_path), path);
|
||||
services__set_result(op, PCMK_OCF_OK, PCMK_EXEC_DONE, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
From 67c1821648f314b510a24ed505a560fa34f2d5c0 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Wed, 12 Mar 2025 10:54:54 -0400
|
||||
Subject: [PATCH 3/4] Refactor: libcrmservice: Subscribe to systemd D-Bus
|
||||
signals
|
||||
|
||||
We'll add a filter later. This does not meaningfully change behavior.
|
||||
|
||||
Ref T25
|
||||
|
||||
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
|
||||
---
|
||||
lib/services/systemd.c | 58 +++++++++++++++++++++++++++++++++++++++---
|
||||
1 file changed, 54 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/lib/services/systemd.c b/lib/services/systemd.c
|
||||
index 090a30bb1ca..df843edce05 100644
|
||||
--- a/lib/services/systemd.c
|
||||
+++ b/lib/services/systemd.c
|
||||
@@ -25,6 +25,9 @@
|
||||
|
||||
static void invoke_unit_by_path(svc_action_t *op, const char *unit);
|
||||
|
||||
+/* Systemd D-Bus interface
|
||||
+ * https://www.freedesktop.org/software/systemd/man/latest/org.freedesktop.systemd1.html
|
||||
+ */
|
||||
#define BUS_NAME "org.freedesktop.systemd1"
|
||||
#define BUS_NAME_MANAGER BUS_NAME ".Manager"
|
||||
#define BUS_NAME_UNIT BUS_NAME ".Unit"
|
||||
@@ -137,6 +140,50 @@ systemd_call_simple_method(const char *method)
|
||||
return reply;
|
||||
}
|
||||
|
||||
+/*!
|
||||
+ * \internal
|
||||
+ * \brief Subscribe to D-Bus signals from systemd
|
||||
+ *
|
||||
+ * Systemd does not broadcast signal messages unless at least one client has
|
||||
+ * called the \c Subscribe() method. Also, a D-Bus client ignores broadcast
|
||||
+ * messages unless an appropriate match rule is set, so we set one here.
|
||||
+ *
|
||||
+ * \return Standard Pacemaker return code
|
||||
+ */
|
||||
+static int
|
||||
+subscribe_to_signals(void)
|
||||
+{
|
||||
+ const char *match_rule = "type='signal',"
|
||||
+ "sender='" BUS_NAME "',"
|
||||
+ "interface='" BUS_NAME_MANAGER "',"
|
||||
+ "path='" BUS_PATH "'";
|
||||
+ DBusMessage *reply = NULL;
|
||||
+ DBusError error;
|
||||
+
|
||||
+ /* Tell D-Bus to accept signal messages from systemd.
|
||||
+ * https://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing-match-rules
|
||||
+ */
|
||||
+ dbus_error_init(&error);
|
||||
+ dbus_bus_add_match(systemd_proxy, match_rule, &error);
|
||||
+
|
||||
+ if (dbus_error_is_set(&error)) {
|
||||
+ crm_err("Could not listen for systemd DBus signals: %s " QB_XS " (%s)",
|
||||
+ error.message, error.name);
|
||||
+ dbus_error_free(&error);
|
||||
+ return ECOMM;
|
||||
+ }
|
||||
+
|
||||
+ // Tell systemd to broadcast signals
|
||||
+ reply = systemd_call_simple_method("Subscribe");
|
||||
+ if (reply == NULL) {
|
||||
+ dbus_bus_remove_match(systemd_proxy, match_rule, &error);
|
||||
+ return ECOMM;
|
||||
+ }
|
||||
+
|
||||
+ dbus_message_unref(reply);
|
||||
+ return pcmk_rc_ok;
|
||||
+}
|
||||
+
|
||||
static bool
|
||||
systemd_init(void)
|
||||
{
|
||||
@@ -154,11 +201,14 @@ systemd_init(void)
|
||||
if (need_init) {
|
||||
need_init = 0;
|
||||
systemd_proxy = pcmk_dbus_connect();
|
||||
+
|
||||
+ if (subscribe_to_signals() != pcmk_rc_ok) {
|
||||
+ pcmk_dbus_disconnect(systemd_proxy);
|
||||
+ systemd_proxy = NULL;
|
||||
+ }
|
||||
}
|
||||
- if (systemd_proxy == NULL) {
|
||||
- return false;
|
||||
- }
|
||||
- return true;
|
||||
+
|
||||
+ return (systemd_proxy != NULL);
|
||||
}
|
||||
|
||||
static inline char *
|
||||
|
||||
From 373a7a317023f9d530cd43ab80bdb62a72bb2b05 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Thu, 16 Jan 2025 16:21:44 -0500
|
||||
Subject: [PATCH 4/4] Fix: various: Correctly detect completion of systemd
|
||||
start/stop actions
|
||||
|
||||
When systemd receives a StartUnit() or StopUnit() method call, it
|
||||
returns almost immediately, as soon as a start/stop job is enqueued. A
|
||||
successful return code does NOT indicate that the start/stop has
|
||||
finished.
|
||||
|
||||
Previously, we worked around this in action_complete() with a hack that
|
||||
scheduled a follow-up monitor after a successful start/stop method call,
|
||||
which polled the service after 2 seconds to see whether it was actually
|
||||
running. However, this was not a robust solution. Timing issues could
|
||||
result in Pacemaker having an incorrect view of the resource's status or
|
||||
prematurely declaring the action as failed.
|
||||
|
||||
Now, we follow the best practice as documented in the systemd D-Bus API
|
||||
doc (see StartUnit()):
|
||||
https://www.freedesktop.org/software/systemd/man/latest/org.freedesktop.systemd1.html#Methods
|
||||
|
||||
After kicking off a systemd start/stop action, we make note of the job's
|
||||
D-Bus object path. Then we register a D-Bus message filter that looks
|
||||
for a JobRemoved signal whose bus path matches. This signal indicates
|
||||
that the job has completed and includes its result. When we find the
|
||||
matching signal, we set the action's result. We then remove the filter,
|
||||
which causes the action to be finalized and freed. In the case of the
|
||||
executor daemon, the action has a callback (action_complete()) that runs
|
||||
during finalization and sets the executor's view of the action result.
|
||||
|
||||
Monitor actions still need much of the existing workaround code in
|
||||
action_complete(), so we keep it for now. We bail out for start/stop
|
||||
actions after setting the result as described above.
|
||||
|
||||
Ref T25
|
||||
|
||||
Co-authored-by: Reid Wahl <nrwahl@protonmail.com>
|
||||
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
|
||||
---
|
||||
daemons/execd/execd_commands.c | 13 ++-
|
||||
lib/services/services_private.h | 2 +-
|
||||
lib/services/systemd.c | 167 ++++++++++++++++++++++++++++++--
|
||||
3 files changed, 167 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/daemons/execd/execd_commands.c b/daemons/execd/execd_commands.c
|
||||
index afb5f599b33..67283ce1012 100644
|
||||
--- a/daemons/execd/execd_commands.c
|
||||
+++ b/daemons/execd/execd_commands.c
|
||||
@@ -861,14 +861,13 @@ action_complete(svc_action_t * action)
|
||||
if (pcmk__result_ok(&(cmd->result))
|
||||
&& pcmk__strcase_any_of(cmd->action, PCMK_ACTION_START,
|
||||
PCMK_ACTION_STOP, NULL)) {
|
||||
- /* systemd returns from start and stop actions after the action
|
||||
- * begins, not after it completes. We have to jump through a few
|
||||
- * hoops so that we don't report 'complete' to the rest of pacemaker
|
||||
- * until it's actually done.
|
||||
+ /* Getting results for when a start or stop action completes is now
|
||||
+ * handled by watching for JobRemoved() signals from systemd and
|
||||
+ * reacting to them. So, we can bypass the rest of the code in this
|
||||
+ * function for those actions, and simply finalize cmd.
|
||||
*/
|
||||
- goagain = true;
|
||||
- cmd->real_action = cmd->action;
|
||||
- cmd->action = pcmk__str_copy(PCMK_ACTION_MONITOR);
|
||||
+ services__copy_result(action, &(cmd->result));
|
||||
+ goto finalize;
|
||||
|
||||
} else if (cmd->real_action != NULL) {
|
||||
// This is follow-up monitor to check whether start/stop completed
|
||||
diff --git a/lib/services/services_private.h b/lib/services/services_private.h
|
||||
index 91b49b4248c..b29833c3988 100644
|
||||
--- a/lib/services/services_private.h
|
||||
+++ b/lib/services/services_private.h
|
||||
@@ -44,7 +44,7 @@ struct svc_action_private_s {
|
||||
#endif
|
||||
|
||||
#if SUPPORT_SYSTEMD
|
||||
- char *job_path;
|
||||
+ char *job_path; // D-Bus object path for enqueued start/stop job
|
||||
#endif // SUPPORT_SYSTEMD
|
||||
};
|
||||
|
||||
diff --git a/lib/services/systemd.c b/lib/services/systemd.c
|
||||
index df843edce05..f10d24a050e 100644
|
||||
--- a/lib/services/systemd.c
|
||||
+++ b/lib/services/systemd.c
|
||||
@@ -14,7 +14,9 @@
|
||||
#include <crm/services_internal.h>
|
||||
#include <crm/common/mainloop.h>
|
||||
|
||||
+#include <inttypes.h> // PRIu32
|
||||
#include <stdbool.h>
|
||||
+#include <stdint.h> // uint32_t
|
||||
#include <stdio.h> // fopen(), NULL, etc.
|
||||
#include <sys/stat.h>
|
||||
#include <gio/gio.h>
|
||||
@@ -785,6 +787,8 @@ systemd_unit_metadata(const char *name, int timeout)
|
||||
static void
|
||||
process_unit_method_reply(DBusMessage *reply, svc_action_t *op)
|
||||
{
|
||||
+ bool start_stop = pcmk__strcase_any_of(op->action, PCMK_ACTION_START,
|
||||
+ PCMK_ACTION_STOP, NULL);
|
||||
DBusError error;
|
||||
|
||||
dbus_error_init(&error);
|
||||
@@ -798,11 +802,25 @@ process_unit_method_reply(DBusMessage *reply, svc_action_t *op)
|
||||
|
||||
} else if (!pcmk_dbus_type_check(reply, NULL, DBUS_TYPE_OBJECT_PATH,
|
||||
__func__, __LINE__)) {
|
||||
+ const char *reason = "systemd D-Bus method had unexpected reply";
|
||||
+
|
||||
crm_info("DBus request for %s of %s succeeded but "
|
||||
"return type was unexpected",
|
||||
op->action, pcmk__s(op->rsc, "unknown resource"));
|
||||
- services__set_result(op, PCMK_OCF_OK, PCMK_EXEC_DONE,
|
||||
- "systemd DBus method had unexpected reply");
|
||||
+
|
||||
+ if (!op->synchronous && start_stop) {
|
||||
+ /* The start or stop job is enqueued but is not complete. We need a
|
||||
+ * job path to detect completion in job_removed_filter().
|
||||
+ */
|
||||
+ services__set_result(op, PCMK_OCF_UNKNOWN_ERROR, PCMK_EXEC_ERROR,
|
||||
+ reason);
|
||||
+
|
||||
+ } else {
|
||||
+ /* Something weird happened, but the action is finished and there
|
||||
+ * was no D-Bus error. So call it a success.
|
||||
+ */
|
||||
+ services__set_result(op, PCMK_OCF_OK, PCMK_EXEC_DONE, reason);
|
||||
+ }
|
||||
|
||||
} else {
|
||||
const char *path = NULL;
|
||||
@@ -813,9 +831,114 @@ process_unit_method_reply(DBusMessage *reply, svc_action_t *op)
|
||||
|
||||
crm_debug("DBus request for %s of %s using %s succeeded",
|
||||
op->action, pcmk__s(op->rsc, "unknown resource"), path);
|
||||
- pcmk__str_update(&(op->opaque->job_path), path);
|
||||
- services__set_result(op, PCMK_OCF_OK, PCMK_EXEC_DONE, NULL);
|
||||
+
|
||||
+ if (!op->synchronous && start_stop) {
|
||||
+ // Should be set to unknown/pending already
|
||||
+ services__set_result(op, PCMK_OCF_UNKNOWN, PCMK_EXEC_PENDING, NULL);
|
||||
+ pcmk__str_update(&(op->opaque->job_path), path);
|
||||
+
|
||||
+ } else {
|
||||
+ services__set_result(op, PCMK_OCF_OK, PCMK_EXEC_DONE, NULL);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*!
|
||||
+ * \internal
|
||||
+ * \brief Process a systemd \c JobRemoved signal for a given service action
|
||||
+ *
|
||||
+ * This filter is expected to be added with \c finalize_async_action_dbus() as
|
||||
+ * the \c free_data_function. Then if \p message is a \c JobRemoved signal for
|
||||
+ * the action specified by \p user_data, the action's result is set, the filter
|
||||
+ * is removed, and the action is finalized.
|
||||
+ *
|
||||
+ * \param[in,out] connection D-Bus connection
|
||||
+ * \param[in] message D-Bus message
|
||||
+ * \param[in,out] user_data Service action (\c svc_action_t)
|
||||
+ *
|
||||
+ * \retval \c DBUS_HANDLER_RESULT_HANDLED if \p message is a \c JobRemoved
|
||||
+ * signal for \p user_data
|
||||
+ * \retval \c DBUS_HANDLER_RESULT_NOT_YET_HANDLED otherwise (on error, if
|
||||
+ * \p message is not a \c JobRemoved signal, or if the signal is for
|
||||
+ * some other action's job)
|
||||
+ */
|
||||
+static DBusHandlerResult
|
||||
+job_removed_filter(DBusConnection *connection, DBusMessage *message,
|
||||
+ void *user_data)
|
||||
+{
|
||||
+ svc_action_t *action = user_data;
|
||||
+ const char *action_name = NULL;
|
||||
+ uint32_t job_id = 0;
|
||||
+ const char *bus_path = NULL;
|
||||
+ const char *unit_name = NULL;
|
||||
+ const char *result = NULL;
|
||||
+ DBusError error;
|
||||
+
|
||||
+ CRM_CHECK((connection != NULL) && (message != NULL),
|
||||
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
|
||||
+
|
||||
+ // action should always be set when the filter is added
|
||||
+ if ((action == NULL)
|
||||
+ || !dbus_message_is_signal(message, BUS_NAME_MANAGER, "JobRemoved")) {
|
||||
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
+ }
|
||||
+
|
||||
+ dbus_error_init(&error);
|
||||
+ if (!dbus_message_get_args(message, &error,
|
||||
+ DBUS_TYPE_UINT32, &job_id,
|
||||
+ DBUS_TYPE_OBJECT_PATH, &bus_path,
|
||||
+ DBUS_TYPE_STRING, &unit_name,
|
||||
+ DBUS_TYPE_STRING, &result,
|
||||
+ DBUS_TYPE_INVALID)) {
|
||||
+ crm_err("Could not interpret systemd DBus signal: %s " QB_XS " (%s)",
|
||||
+ error.message, error.name);
|
||||
+ dbus_error_free(&error);
|
||||
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
+ }
|
||||
+
|
||||
+ if (!pcmk__str_eq(bus_path, action->opaque->job_path, pcmk__str_none)) {
|
||||
+ // This filter is not for this job
|
||||
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
+
|
||||
+ action_name = pcmk__s(action->action, "(unknown)");
|
||||
+
|
||||
+ crm_trace("Setting %s result for %s (JobRemoved id=%" PRIu32 ", result=%s",
|
||||
+ action_name, unit_name, job_id, result);
|
||||
+
|
||||
+ if (pcmk__str_eq(result, "done", pcmk__str_none)) {
|
||||
+ services__set_result(action, PCMK_OCF_OK, PCMK_EXEC_DONE, NULL);
|
||||
+
|
||||
+ } else if (pcmk__str_eq(result, "timeout", pcmk__str_none)) {
|
||||
+ services__format_result(action, PCMK_OCF_UNKNOWN_ERROR, PCMK_EXEC_TIMEOUT,
|
||||
+ "systemd %s job for %s timed out",
|
||||
+ action_name, unit_name);
|
||||
+
|
||||
+ } else {
|
||||
+ services__format_result(action, PCMK_OCF_UNKNOWN_ERROR, PCMK_EXEC_ERROR,
|
||||
+ "systemd %s job for %s failed with result '%s'",
|
||||
+ action_name, unit_name, result);
|
||||
+ }
|
||||
+
|
||||
+ /* This instance of the filter was specifically for the given action.
|
||||
+ *
|
||||
+ * The action gets finalized by services__finalize_async_op() via the
|
||||
+ * filter's free_data_function.
|
||||
+ */
|
||||
+ dbus_connection_remove_filter(systemd_proxy, job_removed_filter, action);
|
||||
+ return DBUS_HANDLER_RESULT_HANDLED;
|
||||
+}
|
||||
+
|
||||
+/*!
|
||||
+ * \internal
|
||||
+ * \brief \c DBusFreeFunction wrapper for \c services__finalize_async_op()
|
||||
+ *
|
||||
+ * \param[in,out] action Asynchronous service action to finalize
|
||||
+ */
|
||||
+static void
|
||||
+finalize_async_action_dbus(void *action)
|
||||
+{
|
||||
+ services__finalize_async_op((svc_action_t *) action);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -842,12 +965,34 @@ unit_method_complete(DBusPendingCall *pending, void *user_data)
|
||||
CRM_LOG_ASSERT(pending == op->opaque->pending);
|
||||
services_set_op_pending(op, NULL);
|
||||
|
||||
- // Determine result and finalize action
|
||||
process_unit_method_reply(reply, op);
|
||||
- services__finalize_async_op(op);
|
||||
+
|
||||
if (reply != NULL) {
|
||||
dbus_message_unref(reply);
|
||||
}
|
||||
+
|
||||
+ if ((op->status == PCMK_EXEC_PENDING)
|
||||
+ && pcmk__strcase_any_of(op->action, PCMK_ACTION_START, PCMK_ACTION_STOP,
|
||||
+ NULL)) {
|
||||
+ /* Start and stop method calls return when the job is enqueued, not when
|
||||
+ * it's complete. Start and stop actions must be finalized after the job
|
||||
+ * is complete, because the action callback function may use it. We add
|
||||
+ * a message filter to process the JobRemoved signal, which indicates
|
||||
+ * completion.
|
||||
+ *
|
||||
+ * The filter takes ownership of op, which will be finalized when the
|
||||
+ * filter is later removed.
|
||||
+ */
|
||||
+ if (dbus_connection_add_filter(systemd_proxy, job_removed_filter, op,
|
||||
+ finalize_async_action_dbus)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ crm_err("Could not add D-Bus filter for systemd JobRemoved signals");
|
||||
+ services__set_result(op, PCMK_OCF_UNKNOWN_ERROR, PCMK_EXEC_ERROR,
|
||||
+ "Failed to add D-Bus filter for systemd "
|
||||
+ "JobRemoved signal");
|
||||
+ }
|
||||
+ services__finalize_async_op(op);
|
||||
}
|
||||
|
||||
/* When the cluster manages a systemd resource, we create a unit file override
|
||||
@@ -1193,7 +1338,14 @@ systemd_timeout_callback(gpointer p)
|
||||
services__format_result(op, PCMK_OCF_UNKNOWN_ERROR, PCMK_EXEC_TIMEOUT,
|
||||
"%s action for systemd unit %s "
|
||||
"did not complete in time", op->action, op->agent);
|
||||
- services__finalize_async_op(op);
|
||||
+
|
||||
+ if (op->opaque->job_path != NULL) {
|
||||
+ // A filter owns this op
|
||||
+ dbus_connection_remove_filter(systemd_proxy, job_removed_filter, op);
|
||||
+
|
||||
+ } else {
|
||||
+ services__finalize_async_op(op);
|
||||
+ }
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1247,6 +1399,7 @@ services__execute_systemd(svc_action_t *op)
|
||||
"Bug in service library");
|
||||
|
||||
if (invoke_unit_by_name(op->agent, op, NULL) == pcmk_rc_ok) {
|
||||
+ // @TODO Why plus 5000? No explanation in fccd046.
|
||||
op->opaque->timerid = g_timeout_add(op->timeout + 5000,
|
||||
systemd_timeout_callback, op);
|
||||
services_add_inflight_op(op);
|
||||
File diff suppressed because it is too large
Load Diff
430
SOURCES/004-remote-fencing.patch
Normal file
430
SOURCES/004-remote-fencing.patch
Normal file
@ -0,0 +1,430 @@
|
||||
From 89d6e036039f285eccb538370aac8f7ea0b03ec6 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Wed, 2 Apr 2025 13:27:27 -0400
|
||||
Subject: [PATCH 1/5] Refactor: scheduler: Fix formatting in pe_can_fence.
|
||||
|
||||
---
|
||||
lib/pengine/utils.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c
|
||||
index 87466eb..3e388b9 100644
|
||||
--- a/lib/pengine/utils.c
|
||||
+++ b/lib/pengine/utils.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.
|
||||
*
|
||||
@@ -63,10 +63,10 @@ pe_can_fence(const pcmk_scheduler_t *scheduler, const pcmk_node_t *node)
|
||||
} else if (scheduler->no_quorum_policy == pcmk_no_quorum_ignore) {
|
||||
return true;
|
||||
|
||||
- } else if(node == NULL) {
|
||||
+ } else if (node == NULL) {
|
||||
return false;
|
||||
|
||||
- } else if(node->details->online) {
|
||||
+ } else if (node->details->online) {
|
||||
crm_notice("We can fence %s without quorum because they're in our membership",
|
||||
pcmk__node_name(node));
|
||||
return true;
|
||||
--
|
||||
2.43.0
|
||||
|
||||
From e3d62eec24673bf61b1cb988629b258a31ad1fbc Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Wed, 2 Apr 2025 13:29:44 -0400
|
||||
Subject: [PATCH 2/5] Med: scheduler: Don't always fence online remote nodes.
|
||||
|
||||
Let's assume you have a cluster configured as follows:
|
||||
|
||||
* Three nodes, plus one Pacemaker Remote node.
|
||||
* At least two NICs on each node.
|
||||
* Multiple layers of fencing, including fence_kdump.
|
||||
* The timeout for fence_kdump is set higher on the real nodes than it is
|
||||
on the remote node.
|
||||
* A resource is configured that can only be run on the remote node.
|
||||
|
||||
Now, let's assume that the node running the connection resource for the
|
||||
remote node is disconnect from the rest of the cluster. In testing,
|
||||
this disconnection was done by bringing one network interface down.
|
||||
|
||||
Due to the fence timeouts, the following things will occur:
|
||||
|
||||
* The node whose interface was brought down will split off into its own
|
||||
cluster partition without quorum, while the other two nodes maintain
|
||||
quorum.
|
||||
* The partition with quorum will restart the remote node resource on
|
||||
another real node in the partition.
|
||||
* The node by itself will be fenced. However, due to the long
|
||||
fence_kdump timeout, it will continue to make decisions regarding
|
||||
resources.
|
||||
* The node by itself will re-assign resources, including the remote
|
||||
connection resource. This resource will be assigned back to the same
|
||||
node again.
|
||||
* The node by itself will decide to fence the remote node, which will
|
||||
hit the "in our membership" clause of pe_can_fence. This is because
|
||||
remote nodes are marked as online when they are assigned, not when
|
||||
they are actually running.
|
||||
* When the fence_kdump timeout expires, the node by itself will fence
|
||||
the remote node. This succeeds because there is still a secondary
|
||||
network connection it can use. This fencing will succeed, causing the
|
||||
remote node to reboot and then causing a loss of service.
|
||||
* The node by itself will then be fenced.
|
||||
|
||||
The bug to me seems to be that the remote resource is marked as online
|
||||
when it isn't yet. I think with that changed, all the other remote
|
||||
fencing related code would then work as intended. However, it probably
|
||||
has to remain as-is in order to schedule resources on the remote node -
|
||||
resources probably can't be assigned to an offline node. Making changes
|
||||
in pe_can_fence seems like the least invasive way to deal with this
|
||||
problem.
|
||||
|
||||
I also think this probably has probably been here for a very long time -
|
||||
perhaps always - but we just haven't seen it due to the number of things
|
||||
that have to be configured before it can show up. In particular, the
|
||||
fencing timeouts and secondary network connection are what allow this
|
||||
behavior to happen.
|
||||
|
||||
I can't think of a good reason why a node without quorum would ever want
|
||||
to fence a remote node, especially if the connection resource has been
|
||||
moved to the wquochanges in pe_can_fence seems like the least invasive
|
||||
way to deal with this problem.
|
||||
|
||||
My fix here therefore is just to test whether there is another node it
|
||||
could have been moved to and if so, don't fence it.
|
||||
|
||||
Fixes T978
|
||||
Fixes RHEL-84018
|
||||
---
|
||||
lib/pengine/utils.c | 33 +++++++++++++++++++++++++++++++++
|
||||
1 file changed, 33 insertions(+)
|
||||
|
||||
diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c
|
||||
index 3e388b9..18fd850 100644
|
||||
--- a/lib/pengine/utils.c
|
||||
+++ b/lib/pengine/utils.c
|
||||
@@ -67,6 +67,39 @@ pe_can_fence(const pcmk_scheduler_t *scheduler, const pcmk_node_t *node)
|
||||
return false;
|
||||
|
||||
} else if (node->details->online) {
|
||||
+ /* Remote nodes are marked online when we assign their resource to a
|
||||
+ * node, not when they are actually started (see remote_connection_assigned)
|
||||
+ * so the above test by itself isn't good enough.
|
||||
+ */
|
||||
+ if (pcmk__is_pacemaker_remote_node(node)) {
|
||||
+ /* If we're on a system without quorum, it's entirely possible that
|
||||
+ * the remote resource was automatically moved to a node on the
|
||||
+ * partition with quorum. We can't tell that from this node - the
|
||||
+ * best we can do is check if it's possible for the resource to run
|
||||
+ * on another node in the partition with quorum. If so, it has
|
||||
+ * likely been moved and we shouldn't fence it.
|
||||
+ *
|
||||
+ * NOTE: This condition appears to only come up in very limited
|
||||
+ * circumstances. It at least requires some very lengthy fencing
|
||||
+ * timeouts set, some way for fencing to still take place (a second
|
||||
+ * NIC is how I've reproduced it in testing, but fence_scsi or
|
||||
+ * sbd could work too), and a resource that runs on the remote node.
|
||||
+ */
|
||||
+ pcmk_resource_t *rsc = node->details->remote_rsc;
|
||||
+ pcmk_node_t *n = NULL;
|
||||
+ GHashTableIter iter;
|
||||
+
|
||||
+ g_hash_table_iter_init(&iter, rsc->allowed_nodes);
|
||||
+ while (g_hash_table_iter_next(&iter, NULL, (void **) &n)) {
|
||||
+ /* A node that's not online according to this non-quorum node
|
||||
+ * is a node that's in another partition.
|
||||
+ */
|
||||
+ if (!n->details->online) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
crm_notice("We can fence %s without quorum because they're in our membership",
|
||||
pcmk__node_name(node));
|
||||
return true;
|
||||
--
|
||||
2.43.0
|
||||
|
||||
From f6d995f5c60649c5686600650e6f636ed8b6937c Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Wed, 2 Apr 2025 13:39:21 -0400
|
||||
Subject: [PATCH 3/5] Med: scheduler: Require a cluster option for new remote
|
||||
fencing behavior.
|
||||
|
||||
We don't have a ton of confidence that the previous patch is the right
|
||||
thing to do for everyone, so we are going to hide it behind this
|
||||
undocumented cluster config option. By default, if the option is
|
||||
missing (or is set to "true"), the existing remote fencing behavior will
|
||||
be what happens. That is, a node without quorum will be allowed to
|
||||
fence remote nodes in the same partition even if they've been restarted
|
||||
elsewhere.
|
||||
|
||||
However, with fence-remote-without-quorum="false", we will check to see
|
||||
if the remote node could possibly have been started on another node and
|
||||
if so, it will not be fenced.
|
||||
---
|
||||
cts/cli/regression.daemons.exp | 9 +++++++++
|
||||
cts/cli/regression.tools.exp | 14 ++++++++++++++
|
||||
include/crm/common/options_internal.h | 5 ++++-
|
||||
include/crm/common/scheduler.h | 6 +++++-
|
||||
lib/common/options.c | 13 ++++++++++++-
|
||||
lib/pengine/unpack.c | 11 ++++++++++-
|
||||
lib/pengine/utils.c | 5 ++++-
|
||||
7 files changed, 58 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/cts/cli/regression.daemons.exp b/cts/cli/regression.daemons.exp
|
||||
index 74eedee..fe53044 100644
|
||||
--- a/cts/cli/regression.daemons.exp
|
||||
+++ b/cts/cli/regression.daemons.exp
|
||||
@@ -514,6 +514,15 @@
|
||||
</shortdesc>
|
||||
<content type="boolean" default=""/>
|
||||
</parameter>
|
||||
+ <parameter name="fence-remote-without-quorum">
|
||||
+ <longdesc lang="en">
|
||||
+ By default, inquorate nodes can fence Pacemaker Remote nodes that are part of its partition regardless of whether the resource was successfully restarted elsewhere. If false, an additional check will be added to only fence remote nodes if the cluster thinks they were unable to be restarted.
|
||||
+ </longdesc>
|
||||
+ <shortdesc lang="en">
|
||||
+ *** Advanced Use Only *** Whether remote nodes can be fenced without quorum
|
||||
+ </shortdesc>
|
||||
+ <content type="boolean" default=""/>
|
||||
+ </parameter>
|
||||
<parameter name="stonith-enabled">
|
||||
<longdesc lang="en">
|
||||
If false, unresponsive nodes are immediately assumed to be harmless, and resources that were active on them may be recovered elsewhere. This can result in a "split-brain" situation, potentially leading to data loss and/or service unavailability.
|
||||
diff --git a/cts/cli/regression.tools.exp b/cts/cli/regression.tools.exp
|
||||
index 94b6330..5448ae3 100644
|
||||
--- a/cts/cli/regression.tools.exp
|
||||
+++ b/cts/cli/regression.tools.exp
|
||||
@@ -300,6 +300,11 @@ Also known as properties, these are options that affect behavior across the enti
|
||||
<shortdesc lang="en">Whether the cluster should check for active resources during start-up</shortdesc>
|
||||
<content type="boolean" default=""/>
|
||||
</parameter>
|
||||
+ <parameter name="fence-remote-without-quorum" advanced="1" generated="0">
|
||||
+ <longdesc lang="en">By default, inquorate nodes can fence Pacemaker Remote nodes that are part of its partition regardless of whether the resource was successfully restarted elsewhere. If false, an additional check will be added to only fence remote nodes if the cluster thinks they were unable to be restarted.</longdesc>
|
||||
+ <shortdesc lang="en">Whether remote nodes can be fenced without quorum</shortdesc>
|
||||
+ <content type="boolean" default=""/>
|
||||
+ </parameter>
|
||||
<parameter name="stonith-enabled" advanced="1" generated="0">
|
||||
<longdesc lang="en">If false, unresponsive nodes are immediately assumed to be harmless, and resources that were active on them may be recovered elsewhere. This can result in a "split-brain" situation, potentially leading to data loss and/or service unavailability.</longdesc>
|
||||
<shortdesc lang="en">Whether nodes may be fenced as part of recovery</shortdesc>
|
||||
@@ -635,6 +640,10 @@ Also known as properties, these are options that affect behavior across the enti
|
||||
* Delay cluster recovery for this much time to allow for additional events to occur. Useful if your configuration is sensitive to the order in which ping updates arrive.
|
||||
* Possible values: duration (default: )
|
||||
|
||||
+ * fence-remote-without-quorum: Whether remote nodes can be fenced without quorum
|
||||
+ * By default, inquorate nodes can fence Pacemaker Remote nodes that are part of its partition regardless of whether the resource was successfully restarted elsewhere. If false, an additional check will be added to only fence remote nodes if the cluster thinks they were unable to be restarted.
|
||||
+ * Possible values: boolean (default: )
|
||||
+
|
||||
* stonith-enabled: Whether nodes may be fenced as part of recovery
|
||||
* If false, unresponsive nodes are immediately assumed to be harmless, and resources that were active on them may be recovered elsewhere. This can result in a "split-brain" situation, potentially leading to data loss and/or service unavailability.
|
||||
* Possible values: boolean (default: )
|
||||
@@ -762,6 +771,11 @@ Also known as properties, these are options that affect behavior across the enti
|
||||
<shortdesc lang="en">Whether the cluster should check for active resources during start-up</shortdesc>
|
||||
<content type="boolean" default=""/>
|
||||
</parameter>
|
||||
+ <parameter name="fence-remote-without-quorum" advanced="1" generated="0">
|
||||
+ <longdesc lang="en">By default, inquorate nodes can fence Pacemaker Remote nodes that are part of its partition regardless of whether the resource was successfully restarted elsewhere. If false, an additional check will be added to only fence remote nodes if the cluster thinks they were unable to be restarted.</longdesc>
|
||||
+ <shortdesc lang="en">Whether remote nodes can be fenced without quorum</shortdesc>
|
||||
+ <content type="boolean" default=""/>
|
||||
+ </parameter>
|
||||
<parameter name="stonith-enabled" advanced="1" generated="0">
|
||||
<longdesc lang="en">If false, unresponsive nodes are immediately assumed to be harmless, and resources that were active on them may be recovered elsewhere. This can result in a "split-brain" situation, potentially leading to data loss and/or service unavailability.</longdesc>
|
||||
<shortdesc lang="en">Whether nodes may be fenced as part of recovery</shortdesc>
|
||||
diff --git a/include/crm/common/options_internal.h b/include/crm/common/options_internal.h
|
||||
index 92506a0..6137b94 100644
|
||||
--- a/include/crm/common/options_internal.h
|
||||
+++ b/include/crm/common/options_internal.h
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright 2006-2024 the Pacemaker project contributors
|
||||
+ * Copyright 2006-2025 the Pacemaker project contributors
|
||||
*
|
||||
* The version control history for this file may have further details.
|
||||
*
|
||||
@@ -260,5 +260,8 @@ bool pcmk__valid_stonith_watchdog_timeout(const char *value);
|
||||
|
||||
// @COMPAT Drop when daemon metadata commands are dropped
|
||||
#define PCMK__VALUE_TIME "time"
|
||||
+
|
||||
+// Cluster options
|
||||
+#define PCMK__OPT_FENCE_REMOTE_WITHOUT_QUORUM "fence-remote-without-quorum"
|
||||
|
||||
#endif // PCMK__OPTIONS_INTERNAL__H
|
||||
diff --git a/include/crm/common/scheduler.h b/include/crm/common/scheduler.h
|
||||
index fe8d8fe..c7b989d 100644
|
||||
--- a/include/crm/common/scheduler.h
|
||||
+++ b/include/crm/common/scheduler.h
|
||||
@@ -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.
|
||||
*
|
||||
@@ -216,6 +216,10 @@ struct pe_working_set_s {
|
||||
//! \deprecated Call pcmk_get_no_quorum_policy() to get no-quorum policy
|
||||
enum pe_quorum_policy no_quorum_policy; // Response to loss of quorum
|
||||
|
||||
+ // Can Pacemaker Remote nodes be fenced even from a node that doesn't
|
||||
+ // have quorum?
|
||||
+ bool fence_remote_without_quorum;
|
||||
+
|
||||
GHashTable *config_hash; // Cluster properties
|
||||
|
||||
// Ticket constraints unpacked from ticket state
|
||||
diff --git a/lib/common/options.c b/lib/common/options.c
|
||||
index aab5bb3..5e55c67 100644
|
||||
--- a/lib/common/options.c
|
||||
+++ b/lib/common/options.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.
|
||||
*
|
||||
@@ -236,6 +236,17 @@ static const pcmk__cluster_option_t cluster_options[] = {
|
||||
},
|
||||
|
||||
// Fencing-related options
|
||||
+ {
|
||||
+ PCMK__OPT_FENCE_REMOTE_WITHOUT_QUORUM, NULL, PCMK_VALUE_BOOLEAN, NULL,
|
||||
+ PCMK_VALUE_TRUE, pcmk__valid_boolean,
|
||||
+ pcmk__opt_schedulerd|pcmk__opt_advanced,
|
||||
+ N_("Whether remote nodes can be fenced without quorum"),
|
||||
+ N_("By default, inquorate nodes can fence Pacemaker Remote nodes that "
|
||||
+ "are part of its partition regardless of whether the resource "
|
||||
+ "was successfully restarted elsewhere. If false, an additional "
|
||||
+ "check will be added to only fence remote nodes if the cluster "
|
||||
+ "thinks they were unable to be restarted.")
|
||||
+ },
|
||||
{
|
||||
PCMK_OPT_STONITH_ENABLED, NULL, PCMK_VALUE_BOOLEAN, NULL,
|
||||
PCMK_VALUE_TRUE, pcmk__valid_boolean,
|
||||
diff --git a/lib/pengine/unpack.c b/lib/pengine/unpack.c
|
||||
index 256fe81..0eb7088 100644
|
||||
--- a/lib/pengine/unpack.c
|
||||
+++ b/lib/pengine/unpack.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.
|
||||
*
|
||||
@@ -449,6 +449,15 @@ unpack_config(xmlNode *config, pcmk_scheduler_t *scheduler)
|
||||
* 1000));
|
||||
}
|
||||
|
||||
+ value = pcmk__cluster_option(config_hash, PCMK__OPT_FENCE_REMOTE_WITHOUT_QUORUM);
|
||||
+ if ((value != NULL) && !crm_is_true(value)) {
|
||||
+ crm_warn(PCMK__OPT_FENCE_REMOTE_WITHOUT_QUORUM " disabled - remote "
|
||||
+ "nodes may not be fenced in inquorate partition");
|
||||
+ scheduler->fence_remote_without_quorum = false;
|
||||
+ } else {
|
||||
+ scheduler->fence_remote_without_quorum = true;
|
||||
+ }
|
||||
+
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c
|
||||
index 18fd850..36fcb6e 100644
|
||||
--- a/lib/pengine/utils.c
|
||||
+++ b/lib/pengine/utils.c
|
||||
@@ -70,8 +70,11 @@ pe_can_fence(const pcmk_scheduler_t *scheduler, const pcmk_node_t *node)
|
||||
/* Remote nodes are marked online when we assign their resource to a
|
||||
* node, not when they are actually started (see remote_connection_assigned)
|
||||
* so the above test by itself isn't good enough.
|
||||
+ *
|
||||
+ * This is experimental behavior, so the user has to opt into it by
|
||||
+ * adding fence-remote-without-quorum="false" to their CIB.
|
||||
*/
|
||||
- if (pcmk__is_pacemaker_remote_node(node)) {
|
||||
+ if (pcmk__is_pacemaker_remote_node(node) && !scheduler->fence_remote_without_quorum) {
|
||||
/* If we're on a system without quorum, it's entirely possible that
|
||||
* the remote resource was automatically moved to a node on the
|
||||
* partition with quorum. We can't tell that from this node - the
|
||||
--
|
||||
2.43.0
|
||||
|
||||
From 0d122ecd73cebb27d4bc0474de72de9bff63acb6 Mon Sep 17 00:00:00 2001
|
||||
From: "Gao,Yan" <ygao@suse.com>
|
||||
Date: Thu, 10 Apr 2025 12:51:57 +0200
|
||||
Subject: [PATCH 4/5] Refactor: libcrmcommon: move the new struct member to
|
||||
|
||||
the end for backward compatibility
|
||||
|
||||
Commit f342b77561 broke backward compatibility by inserting the new
|
||||
member `fence_remote_without_quorum` into the middle of the
|
||||
`pe_working_set_s` struct.
|
||||
---
|
||||
include/crm/common/scheduler.h | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/include/crm/common/scheduler.h b/include/crm/common/scheduler.h
|
||||
index c7b989d..7596cb7 100644
|
||||
--- a/include/crm/common/scheduler.h
|
||||
+++ b/include/crm/common/scheduler.h
|
||||
@@ -216,10 +216,6 @@ struct pe_working_set_s {
|
||||
//! \deprecated Call pcmk_get_no_quorum_policy() to get no-quorum policy
|
||||
enum pe_quorum_policy no_quorum_policy; // Response to loss of quorum
|
||||
|
||||
- // Can Pacemaker Remote nodes be fenced even from a node that doesn't
|
||||
- // have quorum?
|
||||
- bool fence_remote_without_quorum;
|
||||
-
|
||||
GHashTable *config_hash; // Cluster properties
|
||||
|
||||
// Ticket constraints unpacked from ticket state
|
||||
@@ -268,6 +264,10 @@ struct pe_working_set_s {
|
||||
void *priv; // For Pacemaker use only
|
||||
|
||||
guint node_pending_timeout; // Pending join times out after this (ms)
|
||||
+
|
||||
+ // Can Pacemaker Remote nodes be fenced even from a node that doesn't
|
||||
+ // have quorum?
|
||||
+ bool fence_remote_without_quorum;
|
||||
};
|
||||
//!@}
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
From 6e5f8472eea018f751c6fa38945f9f28ed013d2f Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Tue, 29 Apr 2025 12:49:45 -0400
|
||||
Subject: [PATCH 5/5] Refactor: scheduler: Lower fencing log message to debug
|
||||
level.
|
||||
|
||||
Most other things in unpack_config are logged at debug or trace level.
|
||||
Having the fencing message at the warn level makes it come up quite
|
||||
often.
|
||||
---
|
||||
lib/pengine/unpack.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/lib/pengine/unpack.c b/lib/pengine/unpack.c
|
||||
index 0eb7088..1466695 100644
|
||||
--- a/lib/pengine/unpack.c
|
||||
+++ b/lib/pengine/unpack.c
|
||||
@@ -451,8 +451,8 @@ unpack_config(xmlNode *config, pcmk_scheduler_t *scheduler)
|
||||
|
||||
value = pcmk__cluster_option(config_hash, PCMK__OPT_FENCE_REMOTE_WITHOUT_QUORUM);
|
||||
if ((value != NULL) && !crm_is_true(value)) {
|
||||
- crm_warn(PCMK__OPT_FENCE_REMOTE_WITHOUT_QUORUM " disabled - remote "
|
||||
- "nodes may not be fenced in inquorate partition");
|
||||
+ crm_debug(PCMK__OPT_FENCE_REMOTE_WITHOUT_QUORUM " disabled - remote "
|
||||
+ "nodes may not be fenced in inquorate partition");
|
||||
scheduler->fence_remote_without_quorum = false;
|
||||
} else {
|
||||
scheduler->fence_remote_without_quorum = true;
|
||||
--
|
||||
2.43.0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,276 +0,0 @@
|
||||
From d50bbafc32428e873c0052a9defcf93d2e52667e Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Wed, 10 Jan 2024 11:35:11 -0500
|
||||
Subject: [PATCH 1/3] Refactor: libcrmcommon: Split feature set check into its
|
||||
own function.
|
||||
|
||||
---
|
||||
include/crm/common/cib_internal.h | 4 +++-
|
||||
lib/cib/cib_utils.c | 12 ++++++------
|
||||
lib/common/cib.c | 18 +++++++++++++++++-
|
||||
3 files changed, 26 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/include/crm/common/cib_internal.h b/include/crm/common/cib_internal.h
|
||||
index c41c12e..fa65e58 100644
|
||||
--- a/include/crm/common/cib_internal.h
|
||||
+++ b/include/crm/common/cib_internal.h
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright 2023 the Pacemaker project contributors
|
||||
+ * Copyright 2023-2024 the Pacemaker project contributors
|
||||
*
|
||||
* The version control history for this file may have further details.
|
||||
*
|
||||
@@ -16,6 +16,8 @@ extern "C" {
|
||||
|
||||
const char *pcmk__cib_abs_xpath_for(const char *element);
|
||||
|
||||
+int pcmk__check_feature_set(const char *cib_version);
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
diff --git a/lib/cib/cib_utils.c b/lib/cib/cib_utils.c
|
||||
index 0082eef..bf2982c 100644
|
||||
--- a/lib/cib/cib_utils.c
|
||||
+++ b/lib/cib/cib_utils.c
|
||||
@@ -353,7 +353,6 @@ cib_perform_op(const char *op, int call_options, cib__op_fn_t fn, bool is_query,
|
||||
xmlNode *patchset_cib = NULL;
|
||||
xmlNode *local_diff = NULL;
|
||||
|
||||
- const char *new_version = NULL;
|
||||
const char *user = crm_element_value(req, F_CIB_USER);
|
||||
bool with_digest = false;
|
||||
|
||||
@@ -470,12 +469,13 @@ cib_perform_op(const char *op, int call_options, cib__op_fn_t fn, bool is_query,
|
||||
}
|
||||
|
||||
if (scratch) {
|
||||
- new_version = crm_element_value(scratch, XML_ATTR_CRM_VERSION);
|
||||
+ const char *new_version = crm_element_value(scratch, XML_ATTR_CRM_VERSION);
|
||||
|
||||
- if (new_version && compare_version(new_version, CRM_FEATURE_SET) > 0) {
|
||||
- crm_err("Discarding update with feature set '%s' greater than our own '%s'",
|
||||
- new_version, CRM_FEATURE_SET);
|
||||
- rc = -EPROTONOSUPPORT;
|
||||
+ rc = pcmk__check_feature_set(new_version);
|
||||
+ if (rc != pcmk_rc_ok) {
|
||||
+ pcmk__config_err("Discarding update with feature set '%s' greater than our own '%s'",
|
||||
+ new_version, CRM_FEATURE_SET);
|
||||
+ rc = pcmk_rc2legacy(rc);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
diff --git a/lib/common/cib.c b/lib/common/cib.c
|
||||
index fee7881..cbebc2e 100644
|
||||
--- a/lib/common/cib.c
|
||||
+++ b/lib/common/cib.c
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Original copyright 2004 International Business Machines
|
||||
- * Later changes copyright 2008-2023 the Pacemaker project contributors
|
||||
+ * Later changes copyright 2008-2024 the Pacemaker project contributors
|
||||
*
|
||||
* The version control history for this file may have further details.
|
||||
*
|
||||
@@ -173,3 +173,19 @@ pcmk_find_cib_element(xmlNode *cib, const char *element_name)
|
||||
{
|
||||
return get_xpath_object(pcmk_cib_xpath_for(element_name), cib, LOG_TRACE);
|
||||
}
|
||||
+
|
||||
+/*!
|
||||
+ * \internal
|
||||
+ * \brief Check that the feature set in the CIB is supported on this node
|
||||
+ *
|
||||
+ * \param[in] new_version XML_ATTR_CRM_VERSION attribute from the CIB
|
||||
+ */
|
||||
+int
|
||||
+pcmk__check_feature_set(const char *cib_version)
|
||||
+{
|
||||
+ if (cib_version && compare_version(cib_version, CRM_FEATURE_SET) > 0) {
|
||||
+ return EPROTONOSUPPORT;
|
||||
+ }
|
||||
+
|
||||
+ return pcmk_rc_ok;
|
||||
+}
|
||||
--
|
||||
2.31.1
|
||||
|
||||
From d89fd8336ae47d892201513c99773705d57f15f0 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Wed, 10 Jan 2024 13:46:42 -0500
|
||||
Subject: [PATCH 2/3] Feature: scheduler: Check the CIB feature set in
|
||||
cluster_status.
|
||||
|
||||
This adds the check that was previously only in cib_perform_op to the
|
||||
scheduler code, ensuring that any daemon or tool that calls the
|
||||
scheduler will check that the feature set in the CIB is supported.
|
||||
---
|
||||
lib/pengine/status.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/lib/pengine/status.c b/lib/pengine/status.c
|
||||
index e6ec237..1294803 100644
|
||||
--- a/lib/pengine/status.c
|
||||
+++ b/lib/pengine/status.c
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <crm/crm.h>
|
||||
#include <crm/msg_xml.h>
|
||||
#include <crm/common/xml.h>
|
||||
+#include <crm/common/cib_internal.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
@@ -70,12 +71,21 @@ pe_free_working_set(pcmk_scheduler_t *scheduler)
|
||||
gboolean
|
||||
cluster_status(pcmk_scheduler_t * scheduler)
|
||||
{
|
||||
+ const char *new_version = NULL;
|
||||
xmlNode *section = NULL;
|
||||
|
||||
if ((scheduler == NULL) || (scheduler->input == NULL)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+ new_version = crm_element_value(scheduler->input, XML_ATTR_CRM_VERSION);
|
||||
+
|
||||
+ if (pcmk__check_feature_set(new_version) != pcmk_rc_ok) {
|
||||
+ pcmk__config_err("Can't process CIB with feature set '%s' greater than our own '%s'",
|
||||
+ new_version, CRM_FEATURE_SET);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
crm_trace("Beginning unpack");
|
||||
|
||||
if (scheduler->failed != NULL) {
|
||||
--
|
||||
2.31.1
|
||||
|
||||
From a3428926d37af506014a6b462d1308d8541c5932 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Wed, 10 Jan 2024 14:56:36 -0500
|
||||
Subject: [PATCH 3/3] Low: libcib: Do not check CIB feature set for files in
|
||||
cib_perform_op.
|
||||
|
||||
This is related to the previous feature for transferring schema files to
|
||||
older remote nodes. In that case, the newer schema files may also have
|
||||
a newer feature set than the node supports, so the transferred files are
|
||||
still not usable.
|
||||
|
||||
However, the feature set only matters for the scheduler, not for most
|
||||
command line tools (obviously, crm_simulate would still care). So in
|
||||
those cases, we can just disable the feature set check if the CIB was
|
||||
read in from a file. For the scheduler, the check is still performed as
|
||||
part of cluster_status.
|
||||
---
|
||||
cts/cli/regression.tools.exp | 2 +-
|
||||
daemons/based/based_callbacks.c | 4 ++--
|
||||
include/crm/cib/internal.h | 4 ++--
|
||||
lib/cib/cib_file.c | 2 +-
|
||||
lib/cib/cib_utils.c | 15 +++++++++------
|
||||
5 files changed, 15 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/cts/cli/regression.tools.exp b/cts/cli/regression.tools.exp
|
||||
index 417b5cd..c81c420 100644
|
||||
--- a/cts/cli/regression.tools.exp
|
||||
+++ b/cts/cli/regression.tools.exp
|
||||
@@ -7939,7 +7939,7 @@ unpack_config warning: Blind faith: not fencing unseen nodes
|
||||
=#=#=#= End test: Verbosely verify a file-specified invalid configuration, outputting as xml - Invalid configuration (78) =#=#=#=
|
||||
* Passed: crm_verify - Verbosely verify a file-specified invalid configuration, outputting as xml
|
||||
=#=#=#= Begin test: Verbosely verify another file-specified invalid configuration, outputting as xml =#=#=#=
|
||||
-(cluster_status@status.c:113) warning: Fencing and resource management disabled due to lack of quorum
|
||||
+(cluster_status@status.c:123) warning: Fencing and resource management disabled due to lack of quorum
|
||||
<pacemaker-result api-version="X" request="crm_verify_invalid_no_stonith.xml --output-as=xml --verbose">
|
||||
<status code="78" message="Invalid configuration">
|
||||
<errors>
|
||||
diff --git a/daemons/based/based_callbacks.c b/daemons/based/based_callbacks.c
|
||||
index 5f3dc62..f16e4d9 100644
|
||||
--- a/daemons/based/based_callbacks.c
|
||||
+++ b/daemons/based/based_callbacks.c
|
||||
@@ -1362,7 +1362,7 @@ cib_process_command(xmlNode *request, const cib__operation_t *operation,
|
||||
input = prepare_input(request, operation->type, §ion);
|
||||
|
||||
if (!pcmk_is_set(operation->flags, cib__op_attr_modifies)) {
|
||||
- rc = cib_perform_op(op, call_options, op_function, true, section,
|
||||
+ rc = cib_perform_op(NULL, op, call_options, op_function, true, section,
|
||||
request, input, false, &config_changed, &the_cib,
|
||||
&result_cib, NULL, &output);
|
||||
|
||||
@@ -1395,7 +1395,7 @@ cib_process_command(xmlNode *request, const cib__operation_t *operation,
|
||||
}
|
||||
|
||||
// result_cib must not be modified after cib_perform_op() returns
|
||||
- rc = cib_perform_op(op, call_options, op_function, false, section,
|
||||
+ rc = cib_perform_op(NULL, op, call_options, op_function, false, section,
|
||||
request, input, manage_counters, &config_changed,
|
||||
&the_cib, &result_cib, cib_diff, &output);
|
||||
|
||||
diff --git a/include/crm/cib/internal.h b/include/crm/cib/internal.h
|
||||
index 9d54d52..b6d6871 100644
|
||||
--- a/include/crm/cib/internal.h
|
||||
+++ b/include/crm/cib/internal.h
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright 2004-2023 the Pacemaker project contributors
|
||||
+ * Copyright 2004-2024 the Pacemaker project contributors
|
||||
*
|
||||
* The version control history for this file may have further details.
|
||||
*
|
||||
@@ -206,7 +206,7 @@ int cib__get_notify_patchset(const xmlNode *msg, const xmlNode **patchset);
|
||||
|
||||
bool cib__element_in_patchset(const xmlNode *patchset, const char *element);
|
||||
|
||||
-int cib_perform_op(const char *op, int call_options, cib__op_fn_t fn,
|
||||
+int cib_perform_op(cib_t *cib, const char *op, int call_options, cib__op_fn_t fn,
|
||||
bool is_query, const char *section, xmlNode *req,
|
||||
xmlNode *input, bool manage_counters, bool *config_changed,
|
||||
xmlNode **current_cib, xmlNode **result_cib, xmlNode **diff,
|
||||
diff --git a/lib/cib/cib_file.c b/lib/cib/cib_file.c
|
||||
index a279823..9dd952c 100644
|
||||
--- a/lib/cib/cib_file.c
|
||||
+++ b/lib/cib/cib_file.c
|
||||
@@ -245,7 +245,7 @@ cib_file_process_request(cib_t *cib, xmlNode *request, xmlNode **output)
|
||||
data = pcmk_find_cib_element(data, section);
|
||||
}
|
||||
|
||||
- rc = cib_perform_op(op, call_options, op_function, read_only, section,
|
||||
+ rc = cib_perform_op(cib, op, call_options, op_function, read_only, section,
|
||||
request, data, true, &changed, &private->cib_xml,
|
||||
&result_cib, &cib_diff, output);
|
||||
|
||||
diff --git a/lib/cib/cib_utils.c b/lib/cib/cib_utils.c
|
||||
index bf2982c..9c3f9f1 100644
|
||||
--- a/lib/cib/cib_utils.c
|
||||
+++ b/lib/cib/cib_utils.c
|
||||
@@ -339,11 +339,10 @@ should_copy_cib(const char *op, const char *section, int call_options)
|
||||
}
|
||||
|
||||
int
|
||||
-cib_perform_op(const char *op, int call_options, cib__op_fn_t fn, bool is_query,
|
||||
- const char *section, xmlNode *req, xmlNode *input,
|
||||
- bool manage_counters, bool *config_changed,
|
||||
- xmlNode **current_cib, xmlNode **result_cib, xmlNode **diff,
|
||||
- xmlNode **output)
|
||||
+cib_perform_op(cib_t *cib, const char *op, int call_options, cib__op_fn_t fn,
|
||||
+ bool is_query, const char *section, xmlNode *req, xmlNode *input,
|
||||
+ bool manage_counters, bool *config_changed, xmlNode **current_cib,
|
||||
+ xmlNode **result_cib, xmlNode **diff, xmlNode **output)
|
||||
{
|
||||
int rc = pcmk_ok;
|
||||
bool check_schema = true;
|
||||
@@ -468,7 +467,11 @@ cib_perform_op(const char *op, int call_options, cib__op_fn_t fn, bool is_query,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- if (scratch) {
|
||||
+ /* If the CIB is from a file, we don't need to check that the feature set is
|
||||
+ * supported. All we care about in that case is the schema version, which
|
||||
+ * is checked elsewhere.
|
||||
+ */
|
||||
+ if (scratch && (cib == NULL || cib->variant != cib_file)) {
|
||||
const char *new_version = crm_element_value(scratch, XML_ATTR_CRM_VERSION);
|
||||
|
||||
rc = pcmk__check_feature_set(new_version);
|
||||
--
|
||||
2.31.1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,373 +0,0 @@
|
||||
From 4823643bef8801b33688167b159bb531bcdf8911 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Thu, 4 Jan 2024 17:10:08 -0600
|
||||
Subject: [PATCH 1/5] Refactor: pacemaker-attrd: drop redundant argument from
|
||||
update_attr_on_host()
|
||||
|
||||
It can check for a force-write via its xml argument, to simplify the caller
|
||||
---
|
||||
daemons/attrd/attrd_corosync.c | 13 +++++++------
|
||||
1 file changed, 7 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/daemons/attrd/attrd_corosync.c b/daemons/attrd/attrd_corosync.c
|
||||
index 158d82f..1b56923 100644
|
||||
--- a/daemons/attrd/attrd_corosync.c
|
||||
+++ b/daemons/attrd/attrd_corosync.c
|
||||
@@ -266,7 +266,7 @@ record_peer_nodeid(attribute_value_t *v, const char *host)
|
||||
static void
|
||||
update_attr_on_host(attribute_t *a, const crm_node_t *peer, const xmlNode *xml,
|
||||
const char *attr, const char *value, const char *host,
|
||||
- bool filter, int is_force_write)
|
||||
+ bool filter)
|
||||
{
|
||||
attribute_value_t *v = NULL;
|
||||
|
||||
@@ -309,6 +309,10 @@ update_attr_on_host(attribute_t *a, const crm_node_t *peer, const xmlNode *xml,
|
||||
}
|
||||
|
||||
} else {
|
||||
+ int is_force_write = 0;
|
||||
+
|
||||
+ crm_element_value_int(xml, PCMK__XA_ATTR_FORCE, &is_force_write);
|
||||
+
|
||||
if (is_force_write == 1 && a->timeout_ms && a->timer) {
|
||||
/* Save forced writing and set change flag. */
|
||||
/* The actual attribute is written by Writer after election. */
|
||||
@@ -338,15 +342,12 @@ attrd_peer_update_one(const crm_node_t *peer, xmlNode *xml, bool filter)
|
||||
const char *attr = crm_element_value(xml, PCMK__XA_ATTR_NAME);
|
||||
const char *value = crm_element_value(xml, PCMK__XA_ATTR_VALUE);
|
||||
const char *host = crm_element_value(xml, PCMK__XA_ATTR_NODE_NAME);
|
||||
- int is_force_write = 0;
|
||||
|
||||
if (attr == NULL) {
|
||||
crm_warn("Could not update attribute: peer did not specify name");
|
||||
return;
|
||||
}
|
||||
|
||||
- crm_element_value_int(xml, PCMK__XA_ATTR_FORCE, &is_force_write);
|
||||
-
|
||||
a = attrd_populate_attribute(xml, attr);
|
||||
if (a == NULL) {
|
||||
return;
|
||||
@@ -361,12 +362,12 @@ attrd_peer_update_one(const crm_node_t *peer, xmlNode *xml, bool filter)
|
||||
g_hash_table_iter_init(&vIter, a->values);
|
||||
|
||||
while (g_hash_table_iter_next(&vIter, (gpointer *) & host, NULL)) {
|
||||
- update_attr_on_host(a, peer, xml, attr, value, host, filter, is_force_write);
|
||||
+ update_attr_on_host(a, peer, xml, attr, value, host, filter);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Update attribute value for the given host
|
||||
- update_attr_on_host(a, peer, xml, attr, value, host, filter, is_force_write);
|
||||
+ update_attr_on_host(a, peer, xml, attr, value, host, filter);
|
||||
}
|
||||
|
||||
/* If this is a message from some attrd instance broadcasting its protocol
|
||||
--
|
||||
2.31.1
|
||||
|
||||
From c7a1ab819b25e3225c185c1630a7139a96fb5c71 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Tue, 9 Jan 2024 16:48:37 -0600
|
||||
Subject: [PATCH 2/5] Refactor: pacemaker-attrd: drop unused argument from
|
||||
attrd_peer_sync()
|
||||
|
||||
---
|
||||
daemons/attrd/attrd_corosync.c | 10 ++++++++--
|
||||
daemons/attrd/attrd_elections.c | 2 +-
|
||||
daemons/attrd/attrd_messages.c | 2 +-
|
||||
daemons/attrd/pacemaker-attrd.h | 2 +-
|
||||
4 files changed, 11 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/daemons/attrd/attrd_corosync.c b/daemons/attrd/attrd_corosync.c
|
||||
index 1b56923..088f00c 100644
|
||||
--- a/daemons/attrd/attrd_corosync.c
|
||||
+++ b/daemons/attrd/attrd_corosync.c
|
||||
@@ -233,7 +233,7 @@ attrd_peer_change_cb(enum crm_status_type kind, crm_node_t *peer, const void *da
|
||||
*/
|
||||
if (attrd_election_won()
|
||||
&& !pcmk_is_set(peer->flags, crm_remote_node)) {
|
||||
- attrd_peer_sync(peer, NULL);
|
||||
+ attrd_peer_sync(peer);
|
||||
}
|
||||
} else {
|
||||
// Remove all attribute values associated with lost nodes
|
||||
@@ -535,8 +535,14 @@ attrd_peer_remove(const char *host, bool uncache, const char *source)
|
||||
}
|
||||
}
|
||||
|
||||
+/*!
|
||||
+ * \internal
|
||||
+ * \brief Send all known attributes and values to a peer
|
||||
+ *
|
||||
+ * \param[in] peer Peer to send sync to (if NULL, broadcast to all peers)
|
||||
+ */
|
||||
void
|
||||
-attrd_peer_sync(crm_node_t *peer, xmlNode *xml)
|
||||
+attrd_peer_sync(crm_node_t *peer)
|
||||
{
|
||||
GHashTableIter aIter;
|
||||
GHashTableIter vIter;
|
||||
diff --git a/daemons/attrd/attrd_elections.c b/daemons/attrd/attrd_elections.c
|
||||
index 82fbe8a..9dbf133 100644
|
||||
--- a/daemons/attrd/attrd_elections.c
|
||||
+++ b/daemons/attrd/attrd_elections.c
|
||||
@@ -23,7 +23,7 @@ attrd_election_cb(gpointer user_data)
|
||||
attrd_declare_winner();
|
||||
|
||||
/* Update the peers after an election */
|
||||
- attrd_peer_sync(NULL, NULL);
|
||||
+ attrd_peer_sync(NULL);
|
||||
|
||||
/* After winning an election, update the CIB with the values of all
|
||||
* attributes as the winner knows them.
|
||||
diff --git a/daemons/attrd/attrd_messages.c b/daemons/attrd/attrd_messages.c
|
||||
index 5525d4b..13ac01f 100644
|
||||
--- a/daemons/attrd/attrd_messages.c
|
||||
+++ b/daemons/attrd/attrd_messages.c
|
||||
@@ -180,7 +180,7 @@ handle_sync_request(pcmk__request_t *request)
|
||||
crm_node_t *peer = pcmk__get_node(0, request->peer, NULL,
|
||||
pcmk__node_search_cluster);
|
||||
|
||||
- attrd_peer_sync(peer, request->xml);
|
||||
+ attrd_peer_sync(peer);
|
||||
pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
|
||||
return NULL;
|
||||
} else {
|
||||
diff --git a/daemons/attrd/pacemaker-attrd.h b/daemons/attrd/pacemaker-attrd.h
|
||||
index 7384188..bacaad6 100644
|
||||
--- a/daemons/attrd/pacemaker-attrd.h
|
||||
+++ b/daemons/attrd/pacemaker-attrd.h
|
||||
@@ -175,7 +175,7 @@ extern GHashTable *peer_protocol_vers;
|
||||
int attrd_cluster_connect(void);
|
||||
void attrd_peer_update(const crm_node_t *peer, xmlNode *xml, const char *host,
|
||||
bool filter);
|
||||
-void attrd_peer_sync(crm_node_t *peer, xmlNode *xml);
|
||||
+void attrd_peer_sync(crm_node_t *peer);
|
||||
void attrd_peer_remove(const char *host, bool uncache, const char *source);
|
||||
void attrd_peer_clear_failure(pcmk__request_t *request);
|
||||
void attrd_peer_sync_response(const crm_node_t *peer, bool peer_won,
|
||||
--
|
||||
2.31.1
|
||||
|
||||
From abafae0068e10abb135b0496086947728365299a Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Thu, 11 Jan 2024 17:31:17 -0600
|
||||
Subject: [PATCH 3/5] Refactor: pacemaker-attrd: de-functionize
|
||||
attrd_lookup_or_create_value()
|
||||
|
||||
... to make planned changes easier
|
||||
---
|
||||
daemons/attrd/attrd_corosync.c | 62 +++++++++++++---------------------
|
||||
1 file changed, 24 insertions(+), 38 deletions(-)
|
||||
|
||||
diff --git a/daemons/attrd/attrd_corosync.c b/daemons/attrd/attrd_corosync.c
|
||||
index 088f00c..59e6a26 100644
|
||||
--- a/daemons/attrd/attrd_corosync.c
|
||||
+++ b/daemons/attrd/attrd_corosync.c
|
||||
@@ -168,40 +168,6 @@ broadcast_local_value(const attribute_t *a)
|
||||
|
||||
#define state_text(state) pcmk__s((state), "in unknown state")
|
||||
|
||||
-/*!
|
||||
- * \internal
|
||||
- * \brief Return a node's value from hash table (creating one if needed)
|
||||
- *
|
||||
- * \param[in,out] values Hash table of values
|
||||
- * \param[in] node_name Name of node to look up
|
||||
- * \param[in] xml XML describing the attribute
|
||||
- *
|
||||
- * \return Pointer to new or existing hash table entry
|
||||
- */
|
||||
-static attribute_value_t *
|
||||
-attrd_lookup_or_create_value(GHashTable *values, const char *node_name,
|
||||
- const xmlNode *xml)
|
||||
-{
|
||||
- attribute_value_t *v = g_hash_table_lookup(values, node_name);
|
||||
- int is_remote = 0;
|
||||
-
|
||||
- if (v == NULL) {
|
||||
- v = calloc(1, sizeof(attribute_value_t));
|
||||
- CRM_ASSERT(v != NULL);
|
||||
-
|
||||
- pcmk__str_update(&v->nodename, node_name);
|
||||
- g_hash_table_replace(values, v->nodename, v);
|
||||
- }
|
||||
-
|
||||
- crm_element_value_int(xml, PCMK__XA_ATTR_IS_REMOTE, &is_remote);
|
||||
- if (is_remote) {
|
||||
- attrd_set_value_flags(v, attrd_value_remote);
|
||||
- CRM_ASSERT(crm_remote_peer_get(node_name) != NULL);
|
||||
- }
|
||||
-
|
||||
- return(v);
|
||||
-}
|
||||
-
|
||||
static void
|
||||
attrd_peer_change_cb(enum crm_status_type kind, crm_node_t *peer, const void *data)
|
||||
{
|
||||
@@ -268,18 +234,38 @@ update_attr_on_host(attribute_t *a, const crm_node_t *peer, const xmlNode *xml,
|
||||
const char *attr, const char *value, const char *host,
|
||||
bool filter)
|
||||
{
|
||||
+ int is_remote = 0;
|
||||
+ bool changed = false;
|
||||
attribute_value_t *v = NULL;
|
||||
|
||||
- v = attrd_lookup_or_create_value(a->values, host, xml);
|
||||
+ // Create entry for value if not already existing
|
||||
+ v = g_hash_table_lookup(a->values, host);
|
||||
+ if (v == NULL) {
|
||||
+ v = calloc(1, sizeof(attribute_value_t));
|
||||
+ CRM_ASSERT(v != NULL);
|
||||
+
|
||||
+ pcmk__str_update(&v->nodename, host);
|
||||
+ g_hash_table_replace(a->values, v->nodename, v);
|
||||
+ }
|
||||
+
|
||||
+ // 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) {
|
||||
+ attrd_set_value_flags(v, attrd_value_remote);
|
||||
+ CRM_ASSERT(crm_remote_peer_get(host) != NULL);
|
||||
+ }
|
||||
+
|
||||
+ // Check whether the value changed
|
||||
+ changed = !pcmk__str_eq(v->current, value, pcmk__str_casei);
|
||||
|
||||
- if (filter && !pcmk__str_eq(v->current, value, pcmk__str_casei)
|
||||
- && pcmk__str_eq(host, attrd_cluster->uname, pcmk__str_casei)) {
|
||||
+ if (changed && filter && pcmk__str_eq(host, attrd_cluster->uname,
|
||||
+ pcmk__str_casei)) {
|
||||
|
||||
crm_notice("%s[%s]: local value '%s' takes priority over '%s' from %s",
|
||||
attr, host, v->current, value, peer->uname);
|
||||
v = broadcast_local_value(a);
|
||||
|
||||
- } else if (!pcmk__str_eq(v->current, value, pcmk__str_casei)) {
|
||||
+ } else if (changed) {
|
||||
crm_notice("Setting %s[%s]%s%s: %s -> %s "
|
||||
CRM_XS " from %s with %s write delay",
|
||||
attr, host, a->set_type ? " in " : "",
|
||||
--
|
||||
2.31.1
|
||||
|
||||
From 72529ec512fb4938bd8dbbd2caf44bbb1a616826 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Thu, 11 Jan 2024 18:04:33 -0600
|
||||
Subject: [PATCH 4/5] Refactor: pacemaker-attrd: minor shuffling to make
|
||||
planned changes easier
|
||||
|
||||
---
|
||||
daemons/attrd/attrd_cib.c | 19 +++++++++++--------
|
||||
1 file changed, 11 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/daemons/attrd/attrd_cib.c b/daemons/attrd/attrd_cib.c
|
||||
index bdc0a10..481fea7 100644
|
||||
--- a/daemons/attrd/attrd_cib.c
|
||||
+++ b/daemons/attrd/attrd_cib.c
|
||||
@@ -51,6 +51,7 @@ attrd_cib_updated_cb(const char *event, xmlNode *msg)
|
||||
{
|
||||
const xmlNode *patchset = NULL;
|
||||
const char *client_name = NULL;
|
||||
+ bool status_changed = false;
|
||||
|
||||
if (attrd_shutting_down(true)) {
|
||||
return;
|
||||
@@ -64,20 +65,22 @@ attrd_cib_updated_cb(const char *event, xmlNode *msg)
|
||||
mainloop_set_trigger(attrd_config_read);
|
||||
}
|
||||
|
||||
- if (!attrd_election_won()) {
|
||||
- // Don't write attributes if we're not the writer
|
||||
- return;
|
||||
- }
|
||||
+ status_changed = cib__element_in_patchset(patchset, XML_CIB_TAG_STATUS);
|
||||
|
||||
client_name = crm_element_value(msg, F_CIB_CLIENTNAME);
|
||||
if (!cib__client_triggers_refresh(client_name)) {
|
||||
- // The CIB is still accurate
|
||||
+ /* This change came from a source that ensured the CIB is consistent
|
||||
+ * with our attributes table, so we don't need to write anything out.
|
||||
+ */
|
||||
return;
|
||||
}
|
||||
|
||||
- if (cib__element_in_patchset(patchset, XML_CIB_TAG_NODES)
|
||||
- || cib__element_in_patchset(patchset, XML_CIB_TAG_STATUS)) {
|
||||
-
|
||||
+ if (!attrd_election_won()) {
|
||||
+ // Don't write attributes if we're not the writer
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (status_changed || cib__element_in_patchset(patchset, XML_CIB_TAG_NODES)) {
|
||||
/* An unsafe client modified the nodes or status section. Write
|
||||
* transient attributes to ensure they're up-to-date in the CIB.
|
||||
*/
|
||||
--
|
||||
2.31.1
|
||||
|
||||
From b83c2567fb450eec5b18882ded16403831d2c3c0 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Thu, 11 Jan 2024 17:53:55 -0600
|
||||
Subject: [PATCH 5/5] Log: pacemaker-attrd: make sure we don't try to log NULL
|
||||
|
||||
---
|
||||
daemons/attrd/attrd_corosync.c | 15 +++++++++++----
|
||||
1 file changed, 11 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/daemons/attrd/attrd_corosync.c b/daemons/attrd/attrd_corosync.c
|
||||
index 59e6a26..b348d52 100644
|
||||
--- a/daemons/attrd/attrd_corosync.c
|
||||
+++ b/daemons/attrd/attrd_corosync.c
|
||||
@@ -229,6 +229,11 @@ record_peer_nodeid(attribute_value_t *v, const char *host)
|
||||
}
|
||||
}
|
||||
|
||||
+#define readable_value(rv_v) pcmk__s((rv_v)->current, "(unset)")
|
||||
+
|
||||
+#define readable_peer(p) \
|
||||
+ (((p) == NULL)? "all peers" : pcmk__s((p)->uname, "unknown peer"))
|
||||
+
|
||||
static void
|
||||
update_attr_on_host(attribute_t *a, const crm_node_t *peer, const xmlNode *xml,
|
||||
const char *attr, const char *value, const char *host,
|
||||
@@ -262,14 +267,14 @@ update_attr_on_host(attribute_t *a, const crm_node_t *peer, const xmlNode *xml,
|
||||
pcmk__str_casei)) {
|
||||
|
||||
crm_notice("%s[%s]: local value '%s' takes priority over '%s' from %s",
|
||||
- attr, host, v->current, value, peer->uname);
|
||||
+ attr, host, readable_value(v), value, peer->uname);
|
||||
v = broadcast_local_value(a);
|
||||
|
||||
} else if (changed) {
|
||||
crm_notice("Setting %s[%s]%s%s: %s -> %s "
|
||||
CRM_XS " from %s with %s write delay",
|
||||
attr, host, a->set_type ? " in " : "",
|
||||
- pcmk__s(a->set_type, ""), pcmk__s(v->current, "(unset)"),
|
||||
+ pcmk__s(a->set_type, ""), readable_value(v),
|
||||
pcmk__s(value, "(unset)"), peer->uname,
|
||||
(a->timeout_ms == 0)? "no" : pcmk__readable_interval(a->timeout_ms));
|
||||
pcmk__str_update(&v->current, value);
|
||||
@@ -543,12 +548,14 @@ attrd_peer_sync(crm_node_t *peer)
|
||||
while (g_hash_table_iter_next(&aIter, NULL, (gpointer *) & a)) {
|
||||
g_hash_table_iter_init(&vIter, a->values);
|
||||
while (g_hash_table_iter_next(&vIter, NULL, (gpointer *) & v)) {
|
||||
- crm_debug("Syncing %s[%s] = %s to %s", a->id, v->nodename, v->current, peer?peer->uname:"everyone");
|
||||
+ crm_debug("Syncing %s[%s]='%s' to %s",
|
||||
+ a->id, v->nodename, readable_value(v),
|
||||
+ readable_peer(peer));
|
||||
attrd_add_value_xml(sync, a, v, false);
|
||||
}
|
||||
}
|
||||
|
||||
- crm_debug("Syncing values to %s", peer?peer->uname:"everyone");
|
||||
+ crm_debug("Syncing values to %s", readable_peer(peer));
|
||||
attrd_send_message(peer, sync, false);
|
||||
free_xml(sync);
|
||||
}
|
||||
--
|
||||
2.31.1
|
||||
|
||||
@ -1,385 +0,0 @@
|
||||
From 84d4a0d5f562df91baa0fece45d06ad3732f941c Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Tue, 16 Jan 2024 11:20:53 -0600
|
||||
Subject: [PATCH 1/5] Low: pacemaker-attrd: properly validate attribute set
|
||||
type
|
||||
|
||||
The sense of the test was accidentally reversed in 26471a52689
|
||||
---
|
||||
daemons/attrd/attrd_attributes.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/daemons/attrd/attrd_attributes.c b/daemons/attrd/attrd_attributes.c
|
||||
index 8f32988..f059059 100644
|
||||
--- a/daemons/attrd/attrd_attributes.c
|
||||
+++ b/daemons/attrd/attrd_attributes.c
|
||||
@@ -40,9 +40,9 @@ attrd_create_attribute(xmlNode *xml)
|
||||
* attributes are not written.
|
||||
*/
|
||||
crm_element_value_int(xml, PCMK__XA_ATTR_IS_PRIVATE, &is_private);
|
||||
- if ((is_private != 0)
|
||||
- && !pcmk__str_any_of(set_type, XML_TAG_ATTR_SETS, XML_TAG_UTILIZATION,
|
||||
- NULL)) {
|
||||
+ if (!is_private && !pcmk__str_any_of(set_type,
|
||||
+ XML_TAG_ATTR_SETS,
|
||||
+ XML_TAG_UTILIZATION, NULL)) {
|
||||
crm_warn("Ignoring attribute %s with invalid set type %s",
|
||||
pcmk__s(name, "(unidentified)"), set_type);
|
||||
return NULL;
|
||||
--
|
||||
2.31.1
|
||||
|
||||
From d0d0511e71fe983a2d89589c39810b79fb48a8ca Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Tue, 16 Jan 2024 12:13:42 -0600
|
||||
Subject: [PATCH 2/5] Fix: pacemaker-attrd: sync utilization attributes to
|
||||
peers correctly
|
||||
|
||||
Include the set type with attribute syncs.
|
||||
|
||||
Previously, utilization attributes would have the correct set_type on the node
|
||||
where they were set, but peers would store it as a regular node attribute. If
|
||||
one of those peers became writer, the attribute would get written to the wrong
|
||||
set.
|
||||
---
|
||||
daemons/attrd/attrd_attributes.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/daemons/attrd/attrd_attributes.c b/daemons/attrd/attrd_attributes.c
|
||||
index f059059..0ad9630 100644
|
||||
--- a/daemons/attrd/attrd_attributes.c
|
||||
+++ b/daemons/attrd/attrd_attributes.c
|
||||
@@ -139,6 +139,7 @@ attrd_add_value_xml(xmlNode *parent, const attribute_t *a,
|
||||
xmlNode *xml = create_xml_node(parent, __func__);
|
||||
|
||||
crm_xml_add(xml, PCMK__XA_ATTR_NAME, a->id);
|
||||
+ 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_UUID, a->uuid);
|
||||
crm_xml_add(xml, PCMK__XA_ATTR_USER, a->user);
|
||||
--
|
||||
2.31.1
|
||||
|
||||
From 4479ff8507dd69f5946d31cf83c7e47fe15d3bdb Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Tue, 16 Jan 2024 12:18:40 -0600
|
||||
Subject: [PATCH 3/5] Refactor: pacemaker-attrd: functionize getting attribute
|
||||
set ID
|
||||
|
||||
... for future reuse
|
||||
---
|
||||
daemons/attrd/attrd_attributes.c | 38 ++++++++++++++++++++++++++++++++
|
||||
daemons/attrd/attrd_cib.c | 9 +-------
|
||||
daemons/attrd/pacemaker-attrd.h | 3 ++-
|
||||
3 files changed, 41 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/daemons/attrd/attrd_attributes.c b/daemons/attrd/attrd_attributes.c
|
||||
index 0ad9630..5727ab8 100644
|
||||
--- a/daemons/attrd/attrd_attributes.c
|
||||
+++ b/daemons/attrd/attrd_attributes.c
|
||||
@@ -210,3 +210,41 @@ attrd_populate_attribute(xmlNode *xml, const char *attr)
|
||||
|
||||
return a;
|
||||
}
|
||||
+
|
||||
+/*!
|
||||
+ * \internal
|
||||
+ * \brief Get the XML ID used to write out an attribute set
|
||||
+ *
|
||||
+ * \param[in] attr Attribute to get set ID for
|
||||
+ * \param[in] node_state_id XML ID of node state that attribute value is for
|
||||
+ *
|
||||
+ * \return Newly allocated string with XML ID to use for \p attr set
|
||||
+ */
|
||||
+char *
|
||||
+attrd_set_id(const attribute_t *attr, const char *node_state_id)
|
||||
+{
|
||||
+ char *set_id = NULL;
|
||||
+
|
||||
+ CRM_ASSERT((attr != NULL) && (node_state_id != NULL));
|
||||
+
|
||||
+ if (attr->set_id == NULL) {
|
||||
+ /* @COMPAT This should really take the set type into account. Currently
|
||||
+ * we use the same XML ID for transient attributes and utilization
|
||||
+ * attributes. It doesn't cause problems because the status section is
|
||||
+ * not limited by the schema in any way, but it's still unfortunate.
|
||||
+ * For backward compatibility reasons, we can't change this.
|
||||
+ */
|
||||
+ set_id = crm_strdup_printf("%s-%s", XML_CIB_TAG_STATUS, node_state_id);
|
||||
+ } else {
|
||||
+ /* @COMPAT When the user specifies a set ID for an attribute, it is the
|
||||
+ * same for every node. That is less than ideal, but again, the schema
|
||||
+ * doesn't enforce anything for the status section. We couldn't change
|
||||
+ * it without allowing the set ID to vary per value rather than per
|
||||
+ * attribute, which would break backward compatibility, pose design
|
||||
+ * challenges, and potentially cause problems in rolling upgrades.
|
||||
+ */
|
||||
+ pcmk__str_update(&set_id, attr->set_id);
|
||||
+ }
|
||||
+ crm_xml_sanitize_id(set_id);
|
||||
+ return set_id;
|
||||
+}
|
||||
diff --git a/daemons/attrd/attrd_cib.c b/daemons/attrd/attrd_cib.c
|
||||
index 481fea7..08d3425 100644
|
||||
--- a/daemons/attrd/attrd_cib.c
|
||||
+++ b/daemons/attrd/attrd_cib.c
|
||||
@@ -423,17 +423,10 @@ add_unset_attr_update(const attribute_t *attr, const char *attr_id,
|
||||
static int
|
||||
add_attr_update(const attribute_t *attr, const char *value, const char *node_id)
|
||||
{
|
||||
- char *set_id = NULL;
|
||||
+ char *set_id = attrd_set_id(attr, node_id);
|
||||
char *attr_id = NULL;
|
||||
int rc = pcmk_rc_ok;
|
||||
|
||||
- if (attr->set_id != NULL) {
|
||||
- pcmk__str_update(&set_id, attr->set_id);
|
||||
- } else {
|
||||
- set_id = crm_strdup_printf("%s-%s", XML_CIB_TAG_STATUS, node_id);
|
||||
- }
|
||||
- crm_xml_sanitize_id(set_id);
|
||||
-
|
||||
if (attr->uuid != NULL) {
|
||||
pcmk__str_update(&attr_id, attr->uuid);
|
||||
} else {
|
||||
diff --git a/daemons/attrd/pacemaker-attrd.h b/daemons/attrd/pacemaker-attrd.h
|
||||
index bacaad6..3da7f8d 100644
|
||||
--- a/daemons/attrd/pacemaker-attrd.h
|
||||
+++ b/daemons/attrd/pacemaker-attrd.h
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright 2013-2023 the Pacemaker project contributors
|
||||
+ * Copyright 2013-2024 the Pacemaker project contributors
|
||||
*
|
||||
* The version control history for this file may have further details.
|
||||
*
|
||||
@@ -195,6 +195,7 @@ void attrd_clear_value_seen(void);
|
||||
void attrd_free_attribute(gpointer data);
|
||||
void attrd_free_attribute_value(gpointer data);
|
||||
attribute_t *attrd_populate_attribute(xmlNode *xml, const char *attr);
|
||||
+char *attrd_set_id(const attribute_t *attr, const char *node_state_id);
|
||||
|
||||
enum attrd_write_options {
|
||||
attrd_write_changed = 0,
|
||||
--
|
||||
2.31.1
|
||||
|
||||
From eee2169ac348b8ed26ac0b78cb11ddc5cef9384e Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Tue, 16 Jan 2024 12:25:59 -0600
|
||||
Subject: [PATCH 4/5] Refactor: pacemaker-attrd: functionize getting attribute
|
||||
nvpair ID
|
||||
|
||||
... for future reuse
|
||||
---
|
||||
daemons/attrd/attrd_attributes.c | 28 ++++++++++++++++++++++++++++
|
||||
daemons/attrd/attrd_cib.c | 17 +++++------------
|
||||
daemons/attrd/pacemaker-attrd.h | 1 +
|
||||
3 files changed, 34 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/daemons/attrd/attrd_attributes.c b/daemons/attrd/attrd_attributes.c
|
||||
index 5727ab8..23de2e2 100644
|
||||
--- a/daemons/attrd/attrd_attributes.c
|
||||
+++ b/daemons/attrd/attrd_attributes.c
|
||||
@@ -248,3 +248,31 @@ attrd_set_id(const attribute_t *attr, const char *node_state_id)
|
||||
crm_xml_sanitize_id(set_id);
|
||||
return set_id;
|
||||
}
|
||||
+
|
||||
+/*!
|
||||
+ * \internal
|
||||
+ * \brief Get the XML ID used to write out an attribute value
|
||||
+ *
|
||||
+ * \param[in] attr Attribute to get value XML ID for
|
||||
+ * \param[in] node_state_id UUID of node that attribute value is for
|
||||
+ *
|
||||
+ * \return Newly allocated string with XML ID of \p attr value
|
||||
+ */
|
||||
+char *
|
||||
+attrd_nvpair_id(const attribute_t *attr, const char *node_state_id)
|
||||
+{
|
||||
+ char *nvpair_id = NULL;
|
||||
+
|
||||
+ if (attr->uuid != NULL) {
|
||||
+ pcmk__str_update(&nvpair_id, attr->uuid);
|
||||
+
|
||||
+ } else if (attr->set_id != NULL) {
|
||||
+ nvpair_id = crm_strdup_printf("%s-%s", attr->set_id, attr->id);
|
||||
+
|
||||
+ } else {
|
||||
+ nvpair_id = crm_strdup_printf(XML_CIB_TAG_STATUS "-%s-%s",
|
||||
+ node_state_id, attr->id);
|
||||
+ }
|
||||
+ crm_xml_sanitize_id(nvpair_id);
|
||||
+ return nvpair_id;
|
||||
+}
|
||||
diff --git a/daemons/attrd/attrd_cib.c b/daemons/attrd/attrd_cib.c
|
||||
index 08d3425..d42345f 100644
|
||||
--- a/daemons/attrd/attrd_cib.c
|
||||
+++ b/daemons/attrd/attrd_cib.c
|
||||
@@ -424,23 +424,16 @@ static int
|
||||
add_attr_update(const attribute_t *attr, const char *value, const char *node_id)
|
||||
{
|
||||
char *set_id = attrd_set_id(attr, node_id);
|
||||
- char *attr_id = NULL;
|
||||
+ char *nvpair_id = attrd_nvpair_id(attr, node_id);
|
||||
int rc = pcmk_rc_ok;
|
||||
|
||||
- if (attr->uuid != NULL) {
|
||||
- pcmk__str_update(&attr_id, attr->uuid);
|
||||
+ if (value == NULL) {
|
||||
+ rc = add_unset_attr_update(attr, nvpair_id, node_id, set_id);
|
||||
} else {
|
||||
- attr_id = crm_strdup_printf("%s-%s", set_id, attr->id);
|
||||
- }
|
||||
- crm_xml_sanitize_id(attr_id);
|
||||
-
|
||||
- if (value != NULL) {
|
||||
- rc = add_set_attr_update(attr, attr_id, node_id, set_id, value);
|
||||
- } else {
|
||||
- rc = add_unset_attr_update(attr, attr_id, node_id, set_id);
|
||||
+ rc = add_set_attr_update(attr, nvpair_id, node_id, set_id, value);
|
||||
}
|
||||
free(set_id);
|
||||
- free(attr_id);
|
||||
+ free(nvpair_id);
|
||||
return rc;
|
||||
}
|
||||
|
||||
diff --git a/daemons/attrd/pacemaker-attrd.h b/daemons/attrd/pacemaker-attrd.h
|
||||
index 3da7f8d..deec790 100644
|
||||
--- a/daemons/attrd/pacemaker-attrd.h
|
||||
+++ b/daemons/attrd/pacemaker-attrd.h
|
||||
@@ -196,6 +196,7 @@ void attrd_free_attribute(gpointer data);
|
||||
void attrd_free_attribute_value(gpointer data);
|
||||
attribute_t *attrd_populate_attribute(xmlNode *xml, const char *attr);
|
||||
char *attrd_set_id(const attribute_t *attr, const char *node_state_id);
|
||||
+char *attrd_nvpair_id(const attribute_t *attr, const char *node_state_id);
|
||||
|
||||
enum attrd_write_options {
|
||||
attrd_write_changed = 0,
|
||||
--
|
||||
2.31.1
|
||||
|
||||
From 2abde6cb87d2e3d31a370c74656f6f7c0818c185 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Thu, 18 Jan 2024 10:01:56 -0600
|
||||
Subject: [PATCH 5/5] Log: pacemaker-attrd: improve some messages for debugging
|
||||
|
||||
---
|
||||
daemons/attrd/attrd_attributes.c | 8 +++++---
|
||||
daemons/attrd/attrd_cib.c | 13 +++++++++----
|
||||
daemons/attrd/attrd_corosync.c | 10 ++++++----
|
||||
3 files changed, 20 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/daemons/attrd/attrd_attributes.c b/daemons/attrd/attrd_attributes.c
|
||||
index 23de2e2..68b9585 100644
|
||||
--- a/daemons/attrd/attrd_attributes.c
|
||||
+++ b/daemons/attrd/attrd_attributes.c
|
||||
@@ -60,13 +60,10 @@ attrd_create_attribute(xmlNode *xml)
|
||||
a->values = pcmk__strikey_table(NULL, attrd_free_attribute_value);
|
||||
|
||||
a->user = crm_element_value_copy(xml, PCMK__XA_ATTR_USER);
|
||||
- crm_trace("Performing all %s operations as user '%s'", a->id, a->user);
|
||||
|
||||
if (dampen_s != NULL) {
|
||||
dampen = crm_get_msec(dampen_s);
|
||||
}
|
||||
- crm_trace("Created attribute %s with %s write delay", a->id,
|
||||
- (a->timeout_ms == 0)? "no" : pcmk__readable_interval(a->timeout_ms));
|
||||
|
||||
if(dampen > 0) {
|
||||
a->timeout_ms = dampen;
|
||||
@@ -75,6 +72,11 @@ attrd_create_attribute(xmlNode *xml)
|
||||
crm_warn("Ignoring invalid delay %s for attribute %s", dampen_s, a->id);
|
||||
}
|
||||
|
||||
+ crm_trace("Created attribute %s with %s write delay and %s CIB user",
|
||||
+ a->id,
|
||||
+ ((dampen > 0)? pcmk__readable_interval(a->timeout_ms) : "no"),
|
||||
+ pcmk__s(a->user, "default"));
|
||||
+
|
||||
g_hash_table_replace(attributes, a->id, a);
|
||||
return a;
|
||||
}
|
||||
diff --git a/daemons/attrd/attrd_cib.c b/daemons/attrd/attrd_cib.c
|
||||
index d42345f..cae6846 100644
|
||||
--- a/daemons/attrd/attrd_cib.c
|
||||
+++ b/daemons/attrd/attrd_cib.c
|
||||
@@ -54,6 +54,7 @@ attrd_cib_updated_cb(const char *event, xmlNode *msg)
|
||||
bool status_changed = false;
|
||||
|
||||
if (attrd_shutting_down(true)) {
|
||||
+ crm_debug("Ignoring CIB change during shutdown");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -278,11 +279,13 @@ attrd_cib_callback(xmlNode *msg, int call_id, int rc, xmlNode *output, void *use
|
||||
|
||||
g_hash_table_iter_init(&iter, a->values);
|
||||
while (g_hash_table_iter_next(&iter, (gpointer *) & peer, (gpointer *) & v)) {
|
||||
- do_crm_log(level, "* %s[%s]=%s",
|
||||
- a->id, peer, pcmk__s(v->requested, "(null)"));
|
||||
if (rc == pcmk_ok) {
|
||||
+ crm_info("* Wrote %s[%s]=%s",
|
||||
+ a->id, peer, pcmk__s(v->requested, "(unset)"));
|
||||
pcmk__str_update(&(v->requested), NULL);
|
||||
} else {
|
||||
+ do_crm_log(level, "* Could not write %s[%s]=%s",
|
||||
+ a->id, peer, pcmk__s(v->requested, "(unset)"));
|
||||
a->changed = true; // Reattempt write below if we are still writer
|
||||
}
|
||||
}
|
||||
@@ -292,6 +295,7 @@ attrd_cib_callback(xmlNode *msg, int call_id, int rc, xmlNode *output, void *use
|
||||
/* We deferred a write of a new update because this update was in
|
||||
* progress. Write out the new value without additional delay.
|
||||
*/
|
||||
+ crm_debug("Pending update for %s can be written now", a->id);
|
||||
write_attribute(a, false);
|
||||
|
||||
/* We're re-attempting a write because the original failed; delay
|
||||
@@ -593,8 +597,9 @@ write_attribute(attribute_t *a, bool ignore_delay)
|
||||
continue;
|
||||
}
|
||||
|
||||
- crm_debug("Updating %s[%s]=%s (node uuid=%s id=%" PRIu32 ")",
|
||||
- a->id, v->nodename, v->current, uuid, v->nodeid);
|
||||
+ crm_debug("Writing %s[%s]=%s (node-state-id=%s node-id=%" PRIu32 ")",
|
||||
+ a->id, v->nodename, pcmk__s(v->current, "(unset)"),
|
||||
+ uuid, v->nodeid);
|
||||
cib_updates++;
|
||||
|
||||
/* Preservation of the attribute to transmit alert */
|
||||
diff --git a/daemons/attrd/attrd_corosync.c b/daemons/attrd/attrd_corosync.c
|
||||
index b348d52..6fb847b 100644
|
||||
--- a/daemons/attrd/attrd_corosync.c
|
||||
+++ b/daemons/attrd/attrd_corosync.c
|
||||
@@ -293,7 +293,8 @@ update_attr_on_host(attribute_t *a, const crm_node_t *peer, const xmlNode *xml,
|
||||
|
||||
// Write out new value or start dampening timer
|
||||
if (a->timeout_ms && a->timer) {
|
||||
- crm_trace("Delayed write out (%dms) for %s", a->timeout_ms, attr);
|
||||
+ crm_trace("Delaying write of %s %s for dampening",
|
||||
+ attr, pcmk__readable_interval(a->timeout_ms));
|
||||
mainloop_timer_start(a->timer);
|
||||
} else {
|
||||
attrd_write_or_elect_attribute(a);
|
||||
@@ -307,11 +308,12 @@ update_attr_on_host(attribute_t *a, const crm_node_t *peer, const xmlNode *xml,
|
||||
if (is_force_write == 1 && a->timeout_ms && a->timer) {
|
||||
/* Save forced writing and set change flag. */
|
||||
/* The actual attribute is written by Writer after election. */
|
||||
- crm_trace("Unchanged %s[%s] from %s is %s(Set the forced write flag)",
|
||||
- attr, host, peer->uname, value);
|
||||
+ crm_trace("%s[%s] from %s is unchanged (%s), forcing write",
|
||||
+ attr, host, peer->uname, pcmk__s(value, "unset"));
|
||||
a->force_write = TRUE;
|
||||
} else {
|
||||
- crm_trace("Unchanged %s[%s] from %s is %s", attr, host, peer->uname, value);
|
||||
+ crm_trace("%s[%s] from %s is unchanged (%s)",
|
||||
+ attr, host, peer->uname, pcmk__s(value, "unset"));
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.31.1
|
||||
|
||||
@ -1,53 +0,0 @@
|
||||
From 9c13ce6fe95812308443c188ace8f897e6bce942 Mon Sep 17 00:00:00 2001
|
||||
From: Reid Wahl <nrwahl@protonmail.com>
|
||||
Date: Mon, 29 Jan 2024 11:14:25 -0800
|
||||
Subject: [PATCH] Fix: tools: crm_attribute emits garbage for --node localhost
|
||||
or auto
|
||||
|
||||
This happens because pcmk__node_attr_target() returns its argument if
|
||||
its argument is NULL, "auto", or "localhost" and no relevant environment
|
||||
variables are found. Then crm_attribute frees the return value, makes a
|
||||
copy of it, and assigns it back to options.dest_uname.
|
||||
|
||||
The fix is to check whether the return value is equal to the argument.
|
||||
|
||||
Fixes RHEL-23065
|
||||
|
||||
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
|
||||
---
|
||||
tools/crm_attribute.c | 19 +++++++++++++++++--
|
||||
1 file changed, 17 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tools/crm_attribute.c b/tools/crm_attribute.c
|
||||
index d221ab85d..636d03dbd 100644
|
||||
--- a/tools/crm_attribute.c
|
||||
+++ b/tools/crm_attribute.c
|
||||
@@ -766,8 +766,23 @@ main(int argc, char **argv)
|
||||
const char *target = pcmk__node_attr_target(options.dest_uname);
|
||||
|
||||
if (target != NULL) {
|
||||
- g_free(options.dest_uname);
|
||||
- options.dest_uname = g_strdup(target);
|
||||
+ /* If options.dest_uname is "auto" or "localhost", then
|
||||
+ * pcmk__node_attr_target() may return it, depending on environment
|
||||
+ * variables. In that case, attribute lookups will fail for "auto"
|
||||
+ * (unless there's a node named "auto"). attrd maps "localhost" to
|
||||
+ * the true local node name for queries.
|
||||
+ *
|
||||
+ * @TODO
|
||||
+ * * Investigate whether "localhost" is mapped to a real node name
|
||||
+ * for non-query commands. If not, possibly modify it so that it
|
||||
+ * is.
|
||||
+ * * Map "auto" to "localhost" (probably).
|
||||
+ */
|
||||
+ if (target != (const char *) options.dest_uname) {
|
||||
+ g_free(options.dest_uname);
|
||||
+ options.dest_uname = g_strdup(target);
|
||||
+ }
|
||||
+
|
||||
} else if (getenv("CIB_file") != NULL && options.dest_uname == NULL) {
|
||||
get_node_name_from_local();
|
||||
}
|
||||
--
|
||||
2.41.0
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
From 8dc0d9b43343919edf4f4011ceecfd6b6765b4a4 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Wed, 8 May 2024 11:18:50 -0500
|
||||
Subject: [PATCH] Low: libcib: avoid memory leak in async calls
|
||||
|
||||
Never in a release
|
||||
---
|
||||
lib/cib/cib_native.c | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/lib/cib/cib_native.c b/lib/cib/cib_native.c
|
||||
index 0e502155bc..b014223112 100644
|
||||
--- a/lib/cib/cib_native.c
|
||||
+++ b/lib/cib/cib_native.c
|
||||
@@ -94,9 +94,10 @@ cib_native_perform_op_delegate(cib_t *cib, const char *op, const char *host,
|
||||
|
||||
if (!(call_options & cib_sync_call)) {
|
||||
crm_trace("Async call, returning %d", cib->call_id);
|
||||
- CRM_CHECK(cib->call_id != 0, return -ENOMSG);
|
||||
- free_xml(op_reply);
|
||||
- return cib->call_id;
|
||||
+ CRM_CHECK(cib->call_id != 0,
|
||||
+ rc = -ENOMSG; goto done);
|
||||
+ rc = cib->call_id;
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
rc = pcmk_ok;
|
||||
--
|
||||
2.41.0
|
||||
|
||||
@ -1,121 +0,0 @@
|
||||
From d7c233090057d4f660fa458a2ff97896b15ea951 Mon Sep 17 00:00:00 2001
|
||||
From: Reid Wahl <nrwahl@protonmail.com>
|
||||
Date: Thu, 11 Jul 2024 12:43:49 -0700
|
||||
Subject: [PATCH] Refactor: various: Don't set cluster-layer node ID as XML ID
|
||||
|
||||
Currently, we call the pcmk__xe_set_id() function using a stringified
|
||||
version of the numeric cluster-layer node ID. However, pcmk__xe_set_id()
|
||||
tries to sanitize its input to a valid XML ID. An XML ID cannot begin
|
||||
with a digit.
|
||||
|
||||
crm_xml_set_id() does not sanitize comprehensively, and in particular,
|
||||
it does not care whether its argument begins with a digit. So the
|
||||
current code doesn't cause a problem.
|
||||
|
||||
Still, as a best practice, set the PCMK_XA_ID attribute using
|
||||
crm_xml_add_ll() instead.
|
||||
|
||||
Ref T848
|
||||
|
||||
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
|
||||
---
|
||||
daemons/controld/controld_messages.c | 6 +++++-
|
||||
lib/cluster/corosync.c | 2 +-
|
||||
lib/common/ipc_client.c | 2 +-
|
||||
lib/common/ipc_controld.c | 9 ++++++---
|
||||
tools/crm_node.c | 4 ++--
|
||||
5 files changed, 15 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/daemons/controld/controld_messages.c b/daemons/controld/controld_messages.c
|
||||
index bd5237e..0b0f25b 100644
|
||||
--- a/daemons/controld/controld_messages.c
|
||||
+++ b/daemons/controld/controld_messages.c
|
||||
@@ -893,7 +893,11 @@ handle_node_info_request(const xmlNode *msg)
|
||||
pcmk_is_set(controld_globals.flags,
|
||||
controld_has_quorum));
|
||||
|
||||
- // Check whether client requested node info by ID and/or name
|
||||
+ /* Check whether client requested node info by ID and/or name
|
||||
+ *
|
||||
+ * @TODO A Corosync-layer node ID is of type uint32_t. We should be able to
|
||||
+ * handle legitimate node IDs greater than INT_MAX, but currently we do not.
|
||||
+ */
|
||||
crm_element_value_int(msg, XML_ATTR_ID, &node_id);
|
||||
if (node_id < 0) {
|
||||
node_id = 0;
|
||||
diff --git a/lib/cluster/corosync.c b/lib/cluster/corosync.c
|
||||
index 374250f..fc33cce 100644
|
||||
--- a/lib/cluster/corosync.c
|
||||
+++ b/lib/cluster/corosync.c
|
||||
@@ -650,7 +650,7 @@ pcmk__corosync_add_nodes(xmlNode *xml_parent)
|
||||
if (xml_parent) {
|
||||
xmlNode *node = create_xml_node(xml_parent, XML_CIB_TAG_NODE);
|
||||
|
||||
- crm_xml_set_id(node, "%u", nodeid);
|
||||
+ crm_xml_add_ll(node, XML_ATTR_ID, (long long) nodeid);
|
||||
crm_xml_add(node, XML_ATTR_UNAME, name);
|
||||
}
|
||||
}
|
||||
diff --git a/lib/common/ipc_client.c b/lib/common/ipc_client.c
|
||||
index 5e64e23..7696a69 100644
|
||||
--- a/lib/common/ipc_client.c
|
||||
+++ b/lib/common/ipc_client.c
|
||||
@@ -769,7 +769,7 @@ create_purge_node_request(const pcmk_ipc_api_t *api, const char *node_name,
|
||||
request = create_request(CRM_OP_RM_NODE_CACHE, NULL, NULL,
|
||||
pcmk_ipc_name(api, false), client, NULL);
|
||||
if (nodeid > 0) {
|
||||
- crm_xml_set_id(request, "%lu", (unsigned long) nodeid);
|
||||
+ crm_xml_add_ll(request, XML_ATTR_ID, (unsigned long) nodeid);
|
||||
}
|
||||
crm_xml_add(request, XML_ATTR_UNAME, node_name);
|
||||
break;
|
||||
diff --git a/lib/common/ipc_controld.c b/lib/common/ipc_controld.c
|
||||
index 8e2016e..e4284f5 100644
|
||||
--- a/lib/common/ipc_controld.c
|
||||
+++ b/lib/common/ipc_controld.c
|
||||
@@ -9,9 +9,12 @@
|
||||
|
||||
#include <crm_internal.h>
|
||||
|
||||
-#include <stdio.h>
|
||||
-#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
+#include <inttypes.h> // PRIu32
|
||||
+#include <stdbool.h>
|
||||
+#include <stdint.h> // uint32_t
|
||||
+#include <stdio.h>
|
||||
+
|
||||
#include <libxml/tree.h>
|
||||
|
||||
#include <crm/crm.h>
|
||||
@@ -412,7 +415,7 @@ pcmk_controld_api_node_info(pcmk_ipc_api_t *api, uint32_t nodeid)
|
||||
return EINVAL;
|
||||
}
|
||||
if (nodeid > 0) {
|
||||
- crm_xml_set_id(request, "%lu", (unsigned long) nodeid);
|
||||
+ crm_xml_add_ll(request, XML_ATTR_ID, (unsigned long) nodeid);
|
||||
}
|
||||
|
||||
rc = send_controller_request(api, request, true);
|
||||
diff --git a/tools/crm_node.c b/tools/crm_node.c
|
||||
index 1e7ce6c..ad8c459 100644
|
||||
--- a/tools/crm_node.c
|
||||
+++ b/tools/crm_node.c
|
||||
@@ -552,7 +552,7 @@ remove_from_section(cib_t *cib, const char *element, const char *section,
|
||||
}
|
||||
crm_xml_add(xml, XML_ATTR_UNAME, node_name);
|
||||
if (node_id > 0) {
|
||||
- crm_xml_set_id(xml, "%ld", node_id);
|
||||
+ crm_xml_add_ll(xml, XML_ATTR_ID, node_id);
|
||||
}
|
||||
rc = cib->cmds->remove(cib, section, xml, cib_transaction);
|
||||
free_xml(xml);
|
||||
@@ -691,7 +691,7 @@ purge_node_from_fencer(const char *node_name, long node_id)
|
||||
cmd = create_request(CRM_OP_RM_NODE_CACHE, NULL, NULL, "stonith-ng",
|
||||
crm_system_name, NULL);
|
||||
if (node_id > 0) {
|
||||
- crm_xml_set_id(cmd, "%ld", node_id);
|
||||
+ crm_xml_add_ll(cmd, XML_ATTR_ID, node_id);
|
||||
}
|
||||
crm_xml_add(cmd, XML_ATTR_UNAME, node_name);
|
||||
|
||||
@ -1,89 +0,0 @@
|
||||
From 22e093a5bff608c86d0ea68588078ca747a6d945 Mon Sep 17 00:00:00 2001
|
||||
From: Reid Wahl <nrwahl@protonmail.com>
|
||||
Date: Thu, 11 Jul 2024 12:29:34 -0700
|
||||
Subject: [PATCH] Fix: tools: crm_node -i must initialize nodeid before passing
|
||||
pointer
|
||||
|
||||
This is a regression introduced in 2.1.7 via a27f099.
|
||||
|
||||
Currently, crm_node -i passes a pointer to the uninitialized uint32_t
|
||||
nodeid variable, to pcmk__query_node_info(). Since the pointer is
|
||||
non-NULL, pcmk__query_node_info() dereferences it. Whatever garbage
|
||||
value resides there gets passed as the ID to query.
|
||||
|
||||
The controller parses the node ID from the request as an int. If the
|
||||
garbage value is greater than INT_MAX, it overflows to a negative int
|
||||
value, and the controller (in handle_node_info_request()) defaults it to
|
||||
0. In that case, there's no problem: we search for the local node name
|
||||
instead of the garbage node ID.
|
||||
|
||||
If the garbage value is less than or equal to INT_MAX, we search for it
|
||||
directly. We won't find a matching node unless one happens to exist with
|
||||
that garbage node ID. In the case of no match, crm_node -i outputs "Node
|
||||
is not known to cluster" instead of the local node's cluster-layer ID.
|
||||
|
||||
Thanks to Artur Novik for the report:
|
||||
https://lists.clusterlabs.org/pipermail/users/2024-July/036270.html
|
||||
|
||||
Fixes T847
|
||||
|
||||
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
|
||||
---
|
||||
lib/pacemaker/pcmk_cluster_queries.c | 22 +++++++++++-----------
|
||||
tools/crm_node.c | 2 +-
|
||||
2 files changed, 12 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/lib/pacemaker/pcmk_cluster_queries.c b/lib/pacemaker/pcmk_cluster_queries.c
|
||||
index 3229fae3eff..8404584580e 100644
|
||||
--- a/lib/pacemaker/pcmk_cluster_queries.c
|
||||
+++ b/lib/pacemaker/pcmk_cluster_queries.c
|
||||
@@ -586,25 +586,25 @@ pcmk_designated_controller(xmlNodePtr *xml, unsigned int message_timeout_ms)
|
||||
* the controller
|
||||
*
|
||||
* \param[in,out] out Output object
|
||||
- * \param[in,out] node_id ID of node whose name to get. If \p NULL
|
||||
- * or 0, get the local node name. If not
|
||||
- * \p NULL, store the true node ID here on
|
||||
+ * \param[in,out] node_id ID of node whose info to get. If \p NULL
|
||||
+ * or 0, get the local node's info. If not
|
||||
+ * \c NULL, store the true node ID here on
|
||||
* success.
|
||||
- * \param[out] node_name If not \p NULL, where to store the node
|
||||
+ * \param[out] node_name If not \c NULL, where to store the node
|
||||
* name
|
||||
- * \param[out] uuid If not \p NULL, where to store the node
|
||||
+ * \param[out] uuid If not \c NULL, where to store the node
|
||||
* UUID
|
||||
- * \param[out] state If not \p NULL, where to store the
|
||||
+ * \param[out] state If not \c NULL, where to store the
|
||||
* membership state
|
||||
- * \param[out] is_remote If not \p NULL, where to store whether the
|
||||
+ * \param[out] is_remote If not \c NULL, where to store whether the
|
||||
* node is a Pacemaker Remote node
|
||||
- * \param[out] have_quorum If not \p NULL, where to store whether the
|
||||
+ * \param[out] have_quorum If not \c NULL, where to store whether the
|
||||
* node has quorum
|
||||
* \param[in] show_output Whether to show the node info
|
||||
* \param[in] message_timeout_ms How long to wait for a reply from the
|
||||
- * \p pacemaker-controld API. If 0,
|
||||
- * \p pcmk_ipc_dispatch_sync will be used.
|
||||
- * Otherwise, \p pcmk_ipc_dispatch_poll will
|
||||
+ * \c pacemaker-controld API. If 0,
|
||||
+ * \c pcmk_ipc_dispatch_sync will be used.
|
||||
+ * Otherwise, \c pcmk_ipc_dispatch_poll will
|
||||
* be used.
|
||||
*
|
||||
* \return Standard Pacemaker return code
|
||||
diff --git a/tools/crm_node.c b/tools/crm_node.c
|
||||
index d4153605a69..8aa8d3d29c7 100644
|
||||
--- a/tools/crm_node.c
|
||||
+++ b/tools/crm_node.c
|
||||
@@ -434,7 +434,7 @@ run_controller_mainloop(void)
|
||||
static void
|
||||
print_node_id(void)
|
||||
{
|
||||
- uint32_t nodeid;
|
||||
+ uint32_t nodeid = 0;
|
||||
int rc = pcmk__query_node_info(out, &nodeid, NULL, NULL, NULL, NULL, NULL,
|
||||
false, 0);
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
## Where bug reports should be submitted
|
||||
## Leave bug_url undefined to use ClusterLabs default, others define it here
|
||||
%if 0%{?rhel}
|
||||
%global bug_url https://bugzilla.redhat.com/
|
||||
%global bug_url https://github.com/oracle/oracle-linux/
|
||||
%else
|
||||
%if 0%{?fedora}
|
||||
%global bug_url https://bugz.fedoraproject.org/%{name}
|
||||
@ -35,11 +35,11 @@
|
||||
## Upstream pacemaker version, and its package version (specversion
|
||||
## can be incremented to build packages reliably considered "newer"
|
||||
## than previously built packages with the same pcmkversion)
|
||||
%global pcmkversion 2.1.7
|
||||
%global specversion 5
|
||||
%global pcmkversion 2.1.9
|
||||
%global specversion 1
|
||||
|
||||
## Upstream commit (full commit ID, abbreviated commit ID, or tag) to build
|
||||
%global commit 0f7f88312f7a1ccedee60bf768aba79ee13d41e0
|
||||
%global commit 49aab998399b9fec21631ff610ae5bdcc4ffb7a4
|
||||
|
||||
## Since git v2.11, the extent of abbreviation is autoscaled by default
|
||||
## (used to be constant of 7), so we need to convey it for non-tags, too.
|
||||
@ -230,7 +230,7 @@
|
||||
Name: pacemaker
|
||||
Summary: Scalable High-Availability cluster resource manager
|
||||
Version: %{pcmkversion}
|
||||
Release: %{pcmk_release}.2%{?dist}
|
||||
Release: %{pcmk_release}.2.0.1%{?dist}
|
||||
License: GPL-2.0-or-later AND LGPL-2.1-or-later
|
||||
Url: https://www.clusterlabs.org/
|
||||
|
||||
@ -247,19 +247,10 @@ Source1: https://codeload.github.com/%{github_owner}/%{nagios_name}/tar.gz
|
||||
Source2: pacemaker.sysusers
|
||||
|
||||
# upstream commits
|
||||
Patch001: 001-schema-glib.patch
|
||||
Patch002: 002-schema-transfer.patch
|
||||
Patch003: 003-schema-doc.patch
|
||||
Patch004: 004-attrd-cache-1.patch
|
||||
Patch005: 005-attrd-cache-2.patch
|
||||
Patch006: 006-cib-file-feature-set.patch
|
||||
Patch007: 007-option-metadata.patch
|
||||
Patch008: 008-attrd-prep.patch
|
||||
Patch009: 009-attrd-cache-3.patch
|
||||
Patch010: 010-crm_attribute-free.patch
|
||||
Patch011: 011-attrd-memory-leak.patch
|
||||
Patch012: 012-dont-set-as-xml-id.patch
|
||||
Patch013: 013-crm_node-i-initialize.patch
|
||||
Patch001: 001-systemd-overrides.patch
|
||||
Patch002: 002-systemd-dbus-prep.patch
|
||||
Patch003: 003-systemd-dbus.patch
|
||||
Patch004: 004-remote-fencing.patch
|
||||
|
||||
Requires: resource-agents
|
||||
Requires: %{pkgname_pcmk_libs}%{?_isa} = %{version}-%{release}
|
||||
@ -740,6 +731,7 @@ exit 0
|
||||
%endif
|
||||
%{_sbindir}/fence_watchdog
|
||||
|
||||
%doc %{_mandir}/man7/pacemaker-based.*
|
||||
%doc %{_mandir}/man7/pacemaker-controld.*
|
||||
%doc %{_mandir}/man7/pacemaker-schedulerd.*
|
||||
%doc %{_mandir}/man7/pacemaker-fenced.*
|
||||
@ -809,6 +801,7 @@ exit 0
|
||||
%{ocf_root}/resource.d/pacemaker
|
||||
|
||||
%doc %{_mandir}/man7/*pacemaker*
|
||||
%exclude %{_mandir}/man7/pacemaker-based.*
|
||||
%exclude %{_mandir}/man7/pacemaker-controld.*
|
||||
%exclude %{_mandir}/man7/pacemaker-schedulerd.*
|
||||
%exclude %{_mandir}/man7/pacemaker-fenced.*
|
||||
@ -924,13 +917,56 @@ exit 0
|
||||
%license %{nagios_name}-%{nagios_hash}/COPYING
|
||||
|
||||
%changelog
|
||||
* Tue Jul 23 2024 Chris Lumens <clumens@redhat.com> - 2.1.7-5.2
|
||||
- Fix an error in node ID handling in `crm_node -i`
|
||||
- Resolves: RHEL-49925
|
||||
* Tue Jun 24 2025 EL Errata <el-errata_ww@oracle.com> - 2.1.9-1.2.0.1
|
||||
- Replace bug url [Orabug: 34202300]
|
||||
- Upstream reference in pacemaker crm_report binary [Orabug: 32825154]
|
||||
|
||||
* Thu Jun 6 2024 Chris Lumens <clumens@redhat.com> - 2.1.7-5.1
|
||||
* Wed May 21 2025 Chris Lumens <clumens@redhat.com> - 2.1.9-1.2
|
||||
- Rebuild in proper build root
|
||||
- Related: RHEL-92505
|
||||
- Related: RHEL-92513
|
||||
|
||||
* Tue May 20 2025 Chris Lumens <clumens@redhat.com> - 2.1.9-1.1
|
||||
- Use dbus signalling for systemd resource start/stop
|
||||
- Add an option to disable default remote node fencing behavior
|
||||
- Resolves: RHEL-92505
|
||||
- Resolves: RHEL-92513
|
||||
|
||||
* Fri Nov 1 2024 Chris Lumens <clumens@redhat.com> - 2.1.9-1
|
||||
- Rebase on upstream 2.1.9 final release
|
||||
- Use async communication to establish TLS connections
|
||||
- Fix regression in adding alerts to CIB
|
||||
- Fix a crash in command line tools when stderr is closed
|
||||
- Resolves: RHEL-61382
|
||||
- Resolves: RHEL-34276
|
||||
- Resolves: RHEL-55458
|
||||
- Resolves: RHEL-59043
|
||||
|
||||
* Fri Aug 9 2024 Chris Lumens <clumens@redhat.com> - 2.1.8-3
|
||||
- Rebase on upstream 2.1.8 final release
|
||||
- Resolves: RHEL-38540
|
||||
|
||||
* Wed Jul 17 2024 Chris Lumens <clumens@redhat.com> - 2.1.8-2
|
||||
- Rebase on upstream 2.1.8-rc4 release
|
||||
- Add ability to immediately shutdown system with PCMK_panic_action=
|
||||
- Fix a memory leak in the attribute daemon
|
||||
- Resolves: RHEL-40118
|
||||
- Add ability to list options and parameters as parseable metadata
|
||||
- crm_verify now reports invalid fence level indexes
|
||||
- Fix an error in node ID handling in `crm_node -i`
|
||||
- Fix regression in attrd_updater output
|
||||
- Resolves: RHEL-39057
|
||||
- Resolves: RHEL-40117
|
||||
- Resolves: RHEL-23401
|
||||
- Resolves: RHEL-2996
|
||||
- Resolves: RHEL-47249
|
||||
- Resolves: RHEL-45935
|
||||
|
||||
* Wed May 22 2024 Chris Lumens <clumens@redhat.com> - 2.1.8-1
|
||||
- Rebase on upstream 2.1.8-rc1 release
|
||||
- Fix a typo in the help output of pacemaker-fenced
|
||||
- Fix escaping characters in XML attribute output
|
||||
- Resolves: RHEL-25819
|
||||
- Resolves: RHEL-30822
|
||||
|
||||
* Thu Mar 21 2024 Chris Lumens <clumens@redhat.com> - 2.1.7-5
|
||||
- Fix upgrading to this package on multilib systems
|
||||
|
||||
Loading…
Reference in New Issue
Block a user