import pacemaker-2.1.0-3.el8

# Conflicts:
#	SOURCES/003-pacemakerd-output.patch
#	SPECS/pacemaker.spec
This commit is contained in:
CentOS Sources 2021-07-01 04:14:19 +00:00 committed by Cloud User
commit 24b716c802
7 changed files with 4263 additions and 0 deletions

View File

@ -0,0 +1,343 @@
From 7c35387a9896cb968cf4087b5cbed94af44e1ea5 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Fri, 14 May 2021 12:03:46 -0400
Subject: [PATCH 1/5] Feature: daemons: Convert pacemakerd to formatted output.
The main purpose of this is to finish getting pacemakerd moved off the
existing command line handling code (pcmk__cli_help in particular) so
that code can eventually be deprecated or removed. pacemakerd itself
does fairly little printing.
---
daemons/pacemakerd/pacemakerd.c | 58 ++++++++++++++++++++++++++++++-----------
1 file changed, 43 insertions(+), 15 deletions(-)
diff --git a/daemons/pacemakerd/pacemakerd.c b/daemons/pacemakerd/pacemakerd.c
index ce194bf..bd59729 100644
--- a/daemons/pacemakerd/pacemakerd.c
+++ b/daemons/pacemakerd/pacemakerd.c
@@ -25,6 +25,7 @@
#include <crm/common/ipc_internal.h>
#include <crm/common/mainloop.h>
#include <crm/common/cmdline_internal.h>
+#include <crm/common/output_internal.h>
#include <crm/cluster/internal.h>
#include <crm/cluster.h>
@@ -37,6 +38,14 @@ struct {
gboolean standby;
} options;
+static pcmk__output_t *out = NULL;
+
+static pcmk__supported_format_t formats[] = {
+ PCMK__SUPPORTED_FORMAT_NONE,
+ PCMK__SUPPORTED_FORMAT_TEXT,
+ { NULL, NULL, NULL }
+};
+
static gboolean
pid_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError **err) {
return TRUE;
@@ -1167,10 +1176,10 @@ pacemakerd_event_cb(pcmk_ipc_api_t *pacemakerd_api,
}
static GOptionContext *
-build_arg_context(pcmk__common_args_t *args) {
+build_arg_context(pcmk__common_args_t *args, GOptionGroup **group) {
GOptionContext *context = NULL;
- context = pcmk__build_arg_context(args, NULL, NULL, NULL);
+ context = pcmk__build_arg_context(args, "text", group, NULL);
pcmk__add_main_args(context, entries);
return context;
}
@@ -1182,9 +1191,11 @@ main(int argc, char **argv)
GError *error = NULL;
+ int rc = pcmk_rc_ok;
+ GOptionGroup *output_group = NULL;
pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY);
gchar **processed_args = pcmk__cmdline_preproc(argv, "p");
- GOptionContext *context = build_arg_context(args);
+ GOptionContext *context = build_arg_context(args, &output_group);
bool old_instance_connected = false;
@@ -1195,23 +1205,30 @@ main(int argc, char **argv)
mainloop_add_signal(SIGHUP, pcmk_ignore);
mainloop_add_signal(SIGQUIT, pcmk_sigquit);
+ pcmk__register_formats(output_group, formats);
if (!g_option_context_parse_strv(context, &processed_args, &error)) {
exit_code = CRM_EX_USAGE;
goto done;
}
+ rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
+ if (rc != pcmk_rc_ok) {
+ exit_code = CRM_EX_ERROR;
+ g_set_error(&error, PCMK__EXITC_ERROR, exit_code, "Error creating output format %s: %s",
+ args->output_ty, pcmk_rc_str(rc));
+ goto done;
+ }
+
if (options.features) {
- printf("Pacemaker %s (Build: %s)\n Supporting v%s: %s\n", PACEMAKER_VERSION, BUILD_VERSION,
- CRM_FEATURE_SET, CRM_FEATURES);
+ out->info(out, "Pacemaker %s (Build: %s)\n Supporting v%s: %s", PACEMAKER_VERSION,
+ BUILD_VERSION, CRM_FEATURE_SET, CRM_FEATURES);
exit_code = CRM_EX_OK;
goto done;
}
if (args->version) {
- g_strfreev(processed_args);
- pcmk__free_arg_context(context);
- /* FIXME: When pacemakerd is converted to use formatted output, this can go. */
- pcmk__cli_help('v', CRM_EX_USAGE);
+ out->version(out, false);
+ goto done;
}
setenv("LC_ALL", "C", 1);
@@ -1248,6 +1265,13 @@ main(int argc, char **argv)
crm_ipc_close(old_instance);
crm_ipc_destroy(old_instance);
+ /* Don't allow any accidental output after this point. */
+ if (out != NULL) {
+ out->finish(out, exit_code, true, NULL);
+ pcmk__output_free(out);
+ out = NULL;
+ }
+
#ifdef SUPPORT_COROSYNC
if (mcp_read_config() == FALSE) {
exit_code = CRM_EX_UNAVAILABLE;
@@ -1333,6 +1357,11 @@ done:
g_strfreev(processed_args);
pcmk__free_arg_context(context);
- pcmk__output_and_clear_error(error, NULL);
+ pcmk__output_and_clear_error(error, out);
+
+ if (out != NULL) {
+ out->finish(out, exit_code, true, NULL);
+ pcmk__output_free(out);
+ }
crm_exit(exit_code);
}
--
1.8.3.1
From 35e6da64381fcb092d81ce16835cc28670b077cb Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 17 May 2021 10:04:04 -0400
Subject: [PATCH 2/5] Features: daemons: Output the pacemakerd feature list in
XML.
---
daemons/pacemakerd/pacemakerd.c | 45 ++++++++++++++++++++++++++++++++++++++---
1 file changed, 42 insertions(+), 3 deletions(-)
diff --git a/daemons/pacemakerd/pacemakerd.c b/daemons/pacemakerd/pacemakerd.c
index bd59729..93cf743 100644
--- a/daemons/pacemakerd/pacemakerd.c
+++ b/daemons/pacemakerd/pacemakerd.c
@@ -43,6 +43,42 @@ static pcmk__output_t *out = NULL;
static pcmk__supported_format_t formats[] = {
PCMK__SUPPORTED_FORMAT_NONE,
PCMK__SUPPORTED_FORMAT_TEXT,
+ PCMK__SUPPORTED_FORMAT_XML,
+ { NULL, NULL, NULL }
+};
+
+static int
+pacemakerd_features(pcmk__output_t *out, va_list args) {
+ out->info(out, "Pacemaker %s (Build: %s)\n Supporting v%s: %s", PACEMAKER_VERSION,
+ BUILD_VERSION, CRM_FEATURE_SET, CRM_FEATURES);
+ return pcmk_rc_ok;
+}
+
+static int
+pacemakerd_features_xml(pcmk__output_t *out, va_list args) {
+ gchar **feature_list = g_strsplit(CRM_FEATURES, " ", 0);
+
+ pcmk__output_xml_create_parent(out, "pacemakerd",
+ "version", PACEMAKER_VERSION,
+ "build", BUILD_VERSION,
+ "feature_set", CRM_FEATURE_SET,
+ NULL);
+ out->begin_list(out, NULL, NULL, "features");
+
+ for (char **s = feature_list; *s != NULL; s++) {
+ pcmk__output_create_xml_text_node(out, "feature", *s);
+ }
+
+ out->end_list(out);
+
+ g_strfreev(feature_list);
+ return pcmk_rc_ok;
+}
+
+static pcmk__message_entry_t fmt_functions[] = {
+ { "features", "default", pacemakerd_features },
+ { "features", "xml", pacemakerd_features_xml },
+
{ NULL, NULL, NULL }
};
@@ -200,7 +236,7 @@ static GOptionContext *
build_arg_context(pcmk__common_args_t *args, GOptionGroup **group) {
GOptionContext *context = NULL;
- context = pcmk__build_arg_context(args, "text", group, NULL);
+ context = pcmk__build_arg_context(args, "text (default), xml", group, NULL);
pcmk__add_main_args(context, entries);
return context;
}
@@ -241,9 +277,12 @@ main(int argc, char **argv)
goto done;
}
+ pcmk__force_args(context, &error, "%s --xml-simple-list", g_get_prgname());
+
+ pcmk__register_messages(out, fmt_functions);
+
if (options.features) {
- out->info(out, "Pacemaker %s (Build: %s)\n Supporting v%s: %s", PACEMAKER_VERSION,
- BUILD_VERSION, CRM_FEATURE_SET, CRM_FEATURES);
+ out->message(out, "features");
exit_code = CRM_EX_OK;
goto done;
}
--
1.8.3.1
From 5b7f5eb35b025b59805cf3c7c3dcb6a3cf4b71b3 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 17 May 2021 11:09:53 -0400
Subject: [PATCH 3/5] Low: daemons: Conditionally enable logging in pacemakerd.
If we're doing an interactive command-line call, use
pcmk__cli_init_logging. At the moment, all command line calls except
for --shutdown do their work before logging would even come up, so we
really only need to do this for --shutdown.
If we're doing a daemon call, use crm_log_init.
---
daemons/pacemakerd/pacemakerd.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/daemons/pacemakerd/pacemakerd.c b/daemons/pacemakerd/pacemakerd.c
index 93cf743..c20bde7 100644
--- a/daemons/pacemakerd/pacemakerd.c
+++ b/daemons/pacemakerd/pacemakerd.c
@@ -296,8 +296,11 @@ main(int argc, char **argv)
pcmk__set_env_option("mcp", "true");
- pcmk__cli_init_logging("pacemakerd", args->verbosity);
- crm_log_init(NULL, LOG_INFO, TRUE, FALSE, argc, argv, FALSE);
+ if (options.shutdown) {
+ pcmk__cli_init_logging("pacemakerd", args->verbosity);
+ } else {
+ crm_log_init(NULL, LOG_INFO, TRUE, FALSE, argc, argv, FALSE);
+ }
crm_debug("Checking for existing Pacemaker instance");
old_instance = crm_ipc_new(CRM_SYSTEM_MCP, 0);
--
1.8.3.1
From 2393362bb7489e86d937ed46a1c5cfb93d9bf3ab Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 17 May 2021 11:58:06 -0400
Subject: [PATCH 4/5] Fix: include: Bump CRM_FEATURE_SET for new pacemakerd
args.
---
include/crm/crm.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/crm/crm.h b/include/crm/crm.h
index fdfc825..92a98fa 100644
--- a/include/crm/crm.h
+++ b/include/crm/crm.h
@@ -66,7 +66,7 @@ extern "C" {
* >=3.0.13: Fail counts include operation name and interval
* >=3.2.0: DC supports PCMK_LRM_OP_INVALID and PCMK_LRM_OP_NOT_CONNECTED
*/
-# define CRM_FEATURE_SET "3.10.0"
+# define CRM_FEATURE_SET "3.10.1"
/* Pacemaker's CPG protocols use fixed-width binary fields for the sender and
* recipient of a CPG message. This imposes an arbitrary limit on cluster node
--
1.8.3.1
From 3ad8edbd91631b87ef5f53fa2d68f0c8bbb9ee2b Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 17 May 2021 11:57:09 -0400
Subject: [PATCH 5/5] Feature: xml: Add schema for pacemakerd.
---
xml/Makefile.am | 1 +
xml/api/pacemakerd-2.10.rng | 28 ++++++++++++++++++++++++++++
2 files changed, 29 insertions(+)
create mode 100644 xml/api/pacemakerd-2.10.rng
diff --git a/xml/Makefile.am b/xml/Makefile.am
index 12a51c5..b9448d4 100644
--- a/xml/Makefile.am
+++ b/xml/Makefile.am
@@ -56,6 +56,7 @@ API_request_base = command-output \
crm_simulate \
crmadmin \
digests \
+ pacemakerd \
stonith_admin \
version
diff --git a/xml/api/pacemakerd-2.10.rng b/xml/api/pacemakerd-2.10.rng
new file mode 100644
index 0000000..41a11e7
--- /dev/null
+++ b/xml/api/pacemakerd-2.10.rng
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+
+ <start>
+ <ref name="element-pacemakerd"/>
+ </start>
+
+ <define name="element-pacemakerd">
+ <element name="pacemakerd">
+ <attribute name="version"> <text /> </attribute>
+ <attribute name="build"> <text /> </attribute>
+ <attribute name="feature_set"> <text /> </attribute>
+
+ <optional>
+ <ref name="feature-list" />
+ </optional>
+ </element>
+ </define>
+
+ <define name="feature-list">
+ <element name="features">
+ <oneOrMore>
+ <element name="feature"> <text/> </element>
+ </oneOrMore>
+ </element>
+ </define>
+</grammar>
--
1.8.3.1

View File

@ -0,0 +1,866 @@
From a5a507d4e1abf242903472719a19977811e6f164 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Thu, 20 May 2021 11:59:36 -0400
Subject: [PATCH 01/10] Feature: libcrmcommon: Add OCF_OUTPUT_FORMAT to
crm_resource environment.
See: rhbz#1644628
---
lib/common/output.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/common/output.c b/lib/common/output.c
index 6cb49b5..58872e0 100644
--- a/lib/common/output.c
+++ b/lib/common/output.c
@@ -71,6 +71,8 @@ pcmk__output_new(pcmk__output_t **out, const char *fmt_name, const char *filenam
return ENOMEM;
}
+ setenv("OCF_OUTPUT_FORMAT", (*out)->fmt_name, 1);
+
return pcmk_rc_ok;
}
--
1.8.3.1
From acc6ecdbfb797d69794e68f75a734d6252434e01 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Fri, 21 May 2021 14:20:30 -0400
Subject: [PATCH 02/10] Feature: schemas: Copy crm_resource schema in
preparation for changes.
See: rhbz#1644628
---
xml/api/crm_resource-2.11.rng | 238 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 238 insertions(+)
create mode 100644 xml/api/crm_resource-2.11.rng
diff --git a/xml/api/crm_resource-2.11.rng b/xml/api/crm_resource-2.11.rng
new file mode 100644
index 0000000..8e386db
--- /dev/null
+++ b/xml/api/crm_resource-2.11.rng
@@ -0,0 +1,238 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+
+ <start>
+ <ref name="element-crm-resource"/>
+ </start>
+
+ <define name="element-crm-resource">
+ <choice>
+ <ref name="agents-list" />
+ <ref name="alternatives-list" />
+ <ref name="constraints-list" />
+ <externalRef href="generic-list-2.4.rng"/>
+ <element name="metadata"> <text/> </element>
+ <ref name="locate-list" />
+ <ref name="operations-list" />
+ <ref name="providers-list" />
+ <ref name="reasons-list" />
+ <ref name="resource-check" />
+ <ref name="resource-config" />
+ <ref name="resources-list" />
+ </choice>
+ </define>
+
+ <define name="agents-list">
+ <element name="agents">
+ <attribute name="standard"> <text/> </attribute>
+ <optional>
+ <attribute name="provider"> <text/> </attribute>
+ </optional>
+ <zeroOrMore>
+ <element name="agent"> <text/> </element>
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="alternatives-list">
+ <element name="providers">
+ <attribute name="for"> <text/> </attribute>
+ <zeroOrMore>
+ <element name="provider"> <text/> </element>
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="constraints-list">
+ <element name="constraints">
+ <interleave>
+ <zeroOrMore>
+ <ref name="rsc-location" />
+ </zeroOrMore>
+ <zeroOrMore>
+ <ref name="rsc-colocation" />
+ </zeroOrMore>
+ </interleave>
+ </element>
+ </define>
+
+ <define name="locate-list">
+ <element name="nodes">
+ <attribute name="resource"> <text/> </attribute>
+ <zeroOrMore>
+ <element name="node">
+ <optional>
+ <attribute name="state"><value>promoted</value></attribute>
+ </optional>
+ <text/>
+ </element>
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="rsc-location">
+ <element name="rsc_location">
+ <attribute name="node"> <text/> </attribute>
+ <attribute name="rsc"> <text/> </attribute>
+ <attribute name="id"> <text/> </attribute>
+ <externalRef href="../score.rng"/>
+ </element>
+ </define>
+
+ <define name="operations-list">
+ <element name="operations">
+ <oneOrMore>
+ <ref name="element-operation-list" />
+ </oneOrMore>
+ </element>
+ </define>
+
+ <define name="providers-list">
+ <element name="providers">
+ <attribute name="standard"> <value>ocf</value> </attribute>
+ <optional>
+ <attribute name="agent"> <text/> </attribute>
+ </optional>
+ <zeroOrMore>
+ <element name="provider"> <text/> </element>
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="reasons-list">
+ <choice>
+ <ref name="no-resource-or-uname"/>
+ <ref name="resource-and-uname"/>
+ <ref name="no-resource-but-uname"/>
+ <ref name="resource-but-no-uname"/>
+ </choice>
+ </define>
+
+ <define name="no-resource-or-uname">
+ <element name="reason">
+ <element name="resources">
+ <zeroOrMore>
+ <element name="resource">
+ <attribute name="id"> <text/> </attribute>
+ <attribute name="running"> <data type="boolean"/> </attribute>
+ <ref name="resource-check"/>
+ </element>
+ </zeroOrMore>
+ </element>
+ </element>
+ </define>
+
+ <define name="resource-and-uname">
+ <element name="reason">
+ <attribute name="running_on"> <text/> </attribute>
+ <ref name="resource-check"/>
+ </element>
+ </define>
+
+ <define name="no-resource-but-uname">
+ <element name="reason">
+ <element name="resources">
+ <zeroOrMore>
+ <element name="resource">
+ <attribute name="id"> <text/> </attribute>
+ <attribute name="running"> <data type="boolean"/> </attribute>
+ <attribute name="host"> <text/> </attribute>
+ <ref name="resource-check"/>
+ </element>
+ </zeroOrMore>
+ </element>
+ </element>
+ </define>
+
+ <define name="resource-but-no-uname">
+ <element name="reason">
+ <attribute name="running"> <data type="boolean"/> </attribute>
+ <ref name="resource-check"/>
+ </element>
+ </define>
+
+ <define name="resource-config">
+ <element name="resource_config">
+ <externalRef href="resources-2.4.rng" />
+ <element name="xml"> <text/> </element>
+ </element>
+ </define>
+
+ <define name="resource-check">
+ <element name="check">
+ <attribute name="id"> <text/> </attribute>
+ <optional>
+ <choice>
+ <attribute name="remain_stopped"><value>true</value></attribute>
+ <attribute name="promotable"><value>false</value></attribute>
+ </choice>
+ </optional>
+ <optional>
+ <attribute name="unmanaged"><value>true</value></attribute>
+ </optional>
+ <optional>
+ <attribute name="locked-to"> <text/> </attribute>
+ </optional>
+ </element>
+ </define>
+
+ <define name="resources-list">
+ <element name="resources">
+ <zeroOrMore>
+ <externalRef href="resources-2.4.rng" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="rsc-colocation">
+ <element name="rsc_colocation">
+ <attribute name="id"> <text/> </attribute>
+ <attribute name="rsc"> <text/> </attribute>
+ <attribute name="with-rsc"> <text/> </attribute>
+ <externalRef href="../score.rng"/>
+ <optional>
+ <attribute name="node-attribute"> <text/> </attribute>
+ </optional>
+ <optional>
+ <attribute name="rsc-role">
+ <ref name="attribute-roles"/>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="with-rsc-role">
+ <ref name="attribute-roles"/>
+ </attribute>
+ </optional>
+ </element>
+ </define>
+
+ <define name="element-operation-list">
+ <element name="operation">
+ <optional>
+ <group>
+ <attribute name="rsc"> <text/> </attribute>
+ <attribute name="agent"> <text/> </attribute>
+ </group>
+ </optional>
+ <attribute name="op"> <text/> </attribute>
+ <attribute name="node"> <text/> </attribute>
+ <attribute name="call"> <data type="integer" /> </attribute>
+ <attribute name="rc"> <data type="nonNegativeInteger" /> </attribute>
+ <optional>
+ <attribute name="last-rc-change"> <text/> </attribute>
+ <attribute name="exec-time"> <data type="nonNegativeInteger" /> </attribute>
+ </optional>
+ <attribute name="status"> <text/> </attribute>
+ </element>
+ </define>
+
+ <define name="attribute-roles">
+ <choice>
+ <value>Stopped</value>
+ <value>Started</value>
+ <value>Master</value>
+ <value>Slave</value>
+ </choice>
+ </define>
+</grammar>
--
1.8.3.1
From 1bbdf2149a111e9e19c388834f82001e0d31c427 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 24 May 2021 12:23:55 -0400
Subject: [PATCH 03/10] Feature: xml: Update the crm_resource schema for XML
output.
See: rhbz#1644628
---
xml/api/crm_resource-2.11.rng | 50 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/xml/api/crm_resource-2.11.rng b/xml/api/crm_resource-2.11.rng
index 8e386db..aaa54d6 100644
--- a/xml/api/crm_resource-2.11.rng
+++ b/xml/api/crm_resource-2.11.rng
@@ -20,6 +20,7 @@
<ref name="resource-check" />
<ref name="resource-config" />
<ref name="resources-list" />
+ <ref name="resource-agent-action" />
</choice>
</define>
@@ -227,6 +228,55 @@
</element>
</define>
+ <define name="resource-agent-action">
+ <element name="resource-agent-action">
+ <attribute name="action"> <text/> </attribute>
+ <optional>
+ <attribute name="rsc"> <text/> </attribute>
+ </optional>
+ <attribute name="class"> <text/> </attribute>
+ <attribute name="type"> <text/> </attribute>
+ <optional>
+ <attribute name="provider"> <text/> </attribute>
+ </optional>
+ <optional>
+ <ref name="overrides-list"/>
+ </optional>
+ <ref name="agent-status"/>
+ <optional>
+ <choice>
+ <element name="command">
+ <text />
+ </element>
+ <externalRef href="command-output-1.0.rng"/>
+ </choice>
+ </optional>
+ </element>
+ </define>
+
+ <define name="overrides-list">
+ <element name="overrides">
+ <zeroOrMore>
+ <element name="override">
+ <optional>
+ <attribute name="rsc"> <text/> </attribute>
+ </optional>
+ <attribute name="name"> <text/> </attribute>
+ <attribute name="value"> <text/> </attribute>
+ </element>
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="agent-status">
+ <element name="agent-status">
+ <attribute name="code"> <data type="integer" /> </attribute>
+ <optional>
+ <attribute name="message"> <text/> </attribute>
+ </optional>
+ </element>
+ </define>
+
<define name="attribute-roles">
<choice>
<value>Stopped</value>
--
1.8.3.1
From d89f5bc7fec856fdcd32fa14edbd0019507d5d15 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Tue, 1 Jun 2021 15:26:58 -0400
Subject: [PATCH 04/10] Low: libcrmcommon: Increase PCMK__API_VERSION for new
crm_resource output.
See: rhbz#1644628
---
include/crm/common/output_internal.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/crm/common/output_internal.h b/include/crm/common/output_internal.h
index 10b315b..0436cde 100644
--- a/include/crm/common/output_internal.h
+++ b/include/crm/common/output_internal.h
@@ -27,7 +27,7 @@ extern "C" {
# include <glib.h>
# include <crm/common/results.h>
-# define PCMK__API_VERSION "2.9"
+# define PCMK__API_VERSION "2.11"
#if defined(PCMK__WITH_ATTRIBUTE_OUTPUT_ARGS)
# define PCMK__OUTPUT_ARGS(ARGS...) __attribute__((output_args(ARGS)))
--
1.8.3.1
From 30bd2ddf43ee2a911681e51f40ed9ba20ec250b0 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Thu, 27 May 2021 13:57:12 -0400
Subject: [PATCH 05/10] Low: tools: Pass NULL to
cli_resource_execute_from_params...
if no resource name is given. This happens if we are validating based
on the --class/--agent/--provider command line options instead.
---
tools/crm_resource.c | 2 +-
tools/crm_resource_runtime.c | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/tools/crm_resource.c b/tools/crm_resource.c
index 24f1121..37a0bb0 100644
--- a/tools/crm_resource.c
+++ b/tools/crm_resource.c
@@ -1840,7 +1840,7 @@ main(int argc, char **argv)
case cmd_execute_agent:
if (options.cmdline_config) {
- exit_code = cli_resource_execute_from_params(out, "test",
+ exit_code = cli_resource_execute_from_params(out, NULL,
options.v_class, options.v_provider, options.v_agent,
"validate-all", options.cmdline_params,
options.override_params, options.timeout_ms,
diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c
index 48a4b40..ebf48bb 100644
--- a/tools/crm_resource_runtime.c
+++ b/tools/crm_resource_runtime.c
@@ -1717,14 +1717,14 @@ cli_resource_execute_from_params(pcmk__output_t *out, const char *rsc_name,
*/
params_copy = pcmk__str_table_dup(params);
- op = resources_action_create(rsc_name, rsc_class, rsc_prov, rsc_type, action, 0,
- timeout_ms, params_copy, 0);
+ op = resources_action_create(rsc_name ? rsc_name : "test", rsc_class, rsc_prov,
+ rsc_type, action, 0, timeout_ms, params_copy, 0);
if (op == NULL) {
/* Re-run with stderr enabled so we can display a sane error message */
crm_enable_stderr(TRUE);
params_copy = pcmk__str_table_dup(params);
- op = resources_action_create(rsc_name, rsc_class, rsc_prov, rsc_type, action, 0,
- timeout_ms, params_copy, 0);
+ op = resources_action_create(rsc_name ? rsc_name : "test", rsc_class, rsc_prov,
+ rsc_type, action, 0, timeout_ms, params_copy, 0);
/* Callers of cli_resource_execute expect that the params hash table will
* be freed. That function uses this one, so for that reason and for
--
1.8.3.1
From ee56efd53d14cfc4f902769540b72b3bb6096a73 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 24 May 2021 12:08:52 -0400
Subject: [PATCH 06/10] Feature: tools: Add an agent-status message for
crm_resource.
This moves what was previously only done in an out->info call to its own
output message, which means it will appear in XML output as well. Also,
note that if --class/--agent/--provider are given, the resource name
will be set to "test". In that case, do not display the resource name
in the output.
This message will be used for --validate and the --force-* command line
options to crm_resource.
See: rhbz#1644628
---
tools/crm_resource_print.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/tools/crm_resource_print.c b/tools/crm_resource_print.c
index 9d82cf8..88d5878 100644
--- a/tools/crm_resource_print.c
+++ b/tools/crm_resource_print.c
@@ -152,6 +152,57 @@ attribute_list_default(pcmk__output_t *out, va_list args) {
return pcmk_rc_ok;
}
+PCMK__OUTPUT_ARGS("agent-status", "int", "const char *", "const char *", "const char *",
+ "const char *", "const char *", "int")
+static int
+agent_status_default(pcmk__output_t *out, va_list args) {
+ int status = va_arg(args, int);
+ const char *action = va_arg(args, const char *);
+ const char *name = va_arg(args, const char *);
+ const char *class = va_arg(args, const char *);
+ const char *provider = va_arg(args, const char *);
+ const char *type = va_arg(args, const char *);
+ int rc = va_arg(args, int);
+
+ if (status == PCMK_LRM_OP_DONE) {
+ out->info(out, "Operation %s%s%s (%s%s%s:%s) returned: '%s' (%d)",
+ action, name ? " for " : "", name ? name : "",
+ class, provider ? ":" : "", provider ? provider : "", type,
+ services_ocf_exitcode_str(rc), rc);
+ } else {
+ out->err(out, "Operation %s%s%s (%s%s%s:%s) failed: '%s' (%d)",
+ action, name ? " for " : "", name ? name : "",
+ class, provider ? ":" : "", provider ? provider : "", type,
+ services_lrm_status_str(status), status);
+ }
+
+ return pcmk_rc_ok;
+}
+
+PCMK__OUTPUT_ARGS("agent-status", "int", "const char *", "const char *", "const char *",
+ "const char *", "const char *", "int")
+static int
+agent_status_xml(pcmk__output_t *out, va_list args) {
+ int status G_GNUC_UNUSED = va_arg(args, int);
+ const char *action G_GNUC_UNUSED = va_arg(args, const char *);
+ const char *name G_GNUC_UNUSED = va_arg(args, const char *);
+ const char *class G_GNUC_UNUSED = va_arg(args, const char *);
+ const char *provider G_GNUC_UNUSED = va_arg(args, const char *);
+ const char *type G_GNUC_UNUSED = va_arg(args, const char *);
+ int rc = va_arg(args, int);
+
+ char *status_str = pcmk__itoa(rc);
+
+ pcmk__output_create_xml_node(out, "agent-status",
+ "code", status_str,
+ "message", services_ocf_exitcode_str(rc),
+ NULL);
+
+ free(status_str);
+
+ return pcmk_rc_ok;
+}
+
PCMK__OUTPUT_ARGS("attribute-list", "pe_resource_t *", "char *", "GHashTable *")
static int
attribute_list_text(pcmk__output_t *out, va_list args) {
@@ -562,6 +613,8 @@ resource_names(pcmk__output_t *out, va_list args) {
}
static pcmk__message_entry_t fmt_functions[] = {
+ { "agent-status", "default", agent_status_default },
+ { "agent-status", "xml", agent_status_xml },
{ "attribute-list", "default", attribute_list_default },
{ "attribute-list", "text", attribute_list_text },
{ "property-list", "default", property_list_default },
--
1.8.3.1
From 85cb6b6bff96b18c5174d11e4de4d49cbfb20bb7 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Tue, 1 Jun 2021 14:47:30 -0400
Subject: [PATCH 07/10] Feature: tools: Add an overridden params output
message.
This also replaces what was previously being done in an out->info call
with an output message. This means it shows up in XML output as well.
Also, note that if --class/--agent/--provider are given, the resource
name will be set to "test". In that case, do not display the resource
name in the output.
See: rhbz#1644628
---
tools/crm_resource_print.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/tools/crm_resource_print.c b/tools/crm_resource_print.c
index 88d5878..119d83f 100644
--- a/tools/crm_resource_print.c
+++ b/tools/crm_resource_print.c
@@ -224,6 +224,43 @@ attribute_list_text(pcmk__output_t *out, va_list args) {
return pcmk_rc_ok;
}
+PCMK__OUTPUT_ARGS("override", "const char *", "const char *", "const char *")
+static int
+override_default(pcmk__output_t *out, va_list args) {
+ const char *rsc_name = va_arg(args, const char *);
+ const char *name = va_arg(args, const char *);
+ const char *value = va_arg(args, const char *);
+
+ if (rsc_name == NULL) {
+ out->list_item(out, NULL, "Overriding the cluster configuration with '%s' = '%s'",
+ name, value);
+ } else {
+ out->list_item(out, NULL, "Overriding the cluster configuration for '%s' with '%s' = '%s'",
+ rsc_name, name, value);
+ }
+
+ return pcmk_rc_ok;
+}
+
+PCMK__OUTPUT_ARGS("override", "const char *", "const char *", "const char *")
+static int
+override_xml(pcmk__output_t *out, va_list args) {
+ const char *rsc_name = va_arg(args, const char *);
+ const char *name = va_arg(args, const char *);
+ const char *value = va_arg(args, const char *);
+
+ xmlNodePtr node = pcmk__output_create_xml_node(out, "override",
+ "name", name,
+ "value", value,
+ NULL);
+
+ if (rsc_name != NULL) {
+ crm_xml_add(node, "rsc", rsc_name);
+ }
+
+ return pcmk_rc_ok;
+}
+
PCMK__OUTPUT_ARGS("property-list", "pe_resource_t *", "char *")
static int
property_list_default(pcmk__output_t *out, va_list args) {
@@ -617,6 +654,8 @@ static pcmk__message_entry_t fmt_functions[] = {
{ "agent-status", "xml", agent_status_xml },
{ "attribute-list", "default", attribute_list_default },
{ "attribute-list", "text", attribute_list_text },
+ { "override", "default", override_default },
+ { "override", "xml", override_xml },
{ "property-list", "default", property_list_default },
{ "property-list", "text", property_list_text },
{ "resource-check-list", "default", resource_check_list_default },
--
1.8.3.1
From e5e24592c7c3231c619fb5253e7925ffbc634a99 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Fri, 4 Jun 2021 10:24:51 -0400
Subject: [PATCH 08/10] Low: tools: Use simple XML lists for resource actions
as well.
See: rhbz#1644628
---
tools/crm_resource.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/crm_resource.c b/tools/crm_resource.c
index 37a0bb0..e957011 100644
--- a/tools/crm_resource.c
+++ b/tools/crm_resource.c
@@ -1643,6 +1643,7 @@ main(int argc, char **argv)
* saves from having to write custom messages to build the lists around all these things
*/
switch (options.rsc_cmd) {
+ case cmd_execute_agent:
case cmd_list_resources:
case cmd_query_xml:
case cmd_query_raw_xml:
--
1.8.3.1
From 3e75174d0bc31b261adb1994214a5878b79da85b Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Fri, 4 Jun 2021 10:30:10 -0400
Subject: [PATCH 09/10] Feature: tools: Add an output message for resource
actions.
This wraps up the override and agent-status messages into a single
message, along with any stdout/stderr from the resource action. This
message should be called after taking the action.
This also implements handling XML output from resource actions. Check
to see if the validate-all action returns XML. If so, output it as a
CDATA block under a "command" element. If not, treat it as plain text
and output it as stdout/stderr from a command.
See: rhbz#1644628
---
tools/crm_resource_print.c | 122 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 122 insertions(+)
diff --git a/tools/crm_resource_print.c b/tools/crm_resource_print.c
index 119d83f..19a366d 100644
--- a/tools/crm_resource_print.c
+++ b/tools/crm_resource_print.c
@@ -293,6 +293,126 @@ property_list_text(pcmk__output_t *out, va_list args) {
return pcmk_rc_ok;
}
+PCMK__OUTPUT_ARGS("resource-agent-action", "int", "const char *", "const char *",
+ "const char *", "const char *", "const char *", "GHashTable *",
+ "int", "int", "char *", "char *")
+static int
+resource_agent_action_default(pcmk__output_t *out, va_list args) {
+ int verbose = va_arg(args, int);
+
+ const char *class = va_arg(args, const char *);
+ const char *provider = va_arg(args, const char *);
+ const char *type = va_arg(args, const char *);
+ const char *rsc_name = va_arg(args, const char *);
+ const char *action = va_arg(args, const char *);
+ GHashTable *overrides = va_arg(args, GHashTable *);
+ int rc = va_arg(args, int);
+ int status = va_arg(args, int);
+ char *stdout_data = va_arg(args, char *);
+ char *stderr_data = va_arg(args, char *);
+
+ if (overrides) {
+ GHashTableIter iter;
+ char *name = NULL;
+ char *value = NULL;
+
+ out->begin_list(out, NULL, NULL, "overrides");
+
+ g_hash_table_iter_init(&iter, overrides);
+ while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &value)) {
+ out->message(out, "override", rsc_name, name, value);
+ }
+
+ out->end_list(out);
+ }
+
+ out->message(out, "agent-status", status, action, rsc_name, class, provider,
+ type, rc);
+
+ /* hide output for validate-all if not in verbose */
+ if (verbose == 0 && pcmk__str_eq(action, "validate-all", pcmk__str_casei)) {
+ return pcmk_rc_ok;
+ }
+
+ if (stdout_data || stderr_data) {
+ xmlNodePtr doc = string2xml(stdout_data);
+
+ if (doc != NULL) {
+ out->output_xml(out, "command", stdout_data);
+ xmlFreeNode(doc);
+ } else {
+ out->subprocess_output(out, rc, stdout_data, stderr_data);
+ }
+ }
+
+ return pcmk_rc_ok;
+}
+
+PCMK__OUTPUT_ARGS("resource-agent-action", "int", "const char *", "const char *",
+ "const char *", "const char *", "const char *", "GHashTable *",
+ "int", "int", "char *", "char *")
+static int
+resource_agent_action_xml(pcmk__output_t *out, va_list args) {
+ int verbose G_GNUC_UNUSED = va_arg(args, int);
+
+ const char *class = va_arg(args, const char *);
+ const char *provider = va_arg(args, const char *);
+ const char *type = va_arg(args, const char *);
+ const char *rsc_name = va_arg(args, const char *);
+ const char *action = va_arg(args, const char *);
+ GHashTable *overrides = va_arg(args, GHashTable *);
+ int rc = va_arg(args, int);
+ int status = va_arg(args, int);
+ char *stdout_data = va_arg(args, char *);
+ char *stderr_data = va_arg(args, char *);
+
+ xmlNodePtr node = pcmk__output_xml_create_parent(out, "resource-agent-action",
+ "action", action,
+ "class", class,
+ "type", type,
+ NULL);
+
+ if (rsc_name) {
+ crm_xml_add(node, "rsc", rsc_name);
+ }
+
+ if (provider) {
+ crm_xml_add(node, "provider", provider);
+ }
+
+ if (overrides) {
+ GHashTableIter iter;
+ char *name = NULL;
+ char *value = NULL;
+
+ out->begin_list(out, NULL, NULL, "overrides");
+
+ g_hash_table_iter_init(&iter, overrides);
+ while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &value)) {
+ out->message(out, "override", rsc_name, name, value);
+ }
+
+ out->end_list(out);
+ }
+
+ out->message(out, "agent-status", status, action, rsc_name, class, provider,
+ type, rc);
+
+ if (stdout_data || stderr_data) {
+ xmlNodePtr doc = string2xml(stdout_data);
+
+ if (doc != NULL) {
+ out->output_xml(out, "command", stdout_data);
+ xmlFreeNode(doc);
+ } else {
+ out->subprocess_output(out, rc, stdout_data, stderr_data);
+ }
+ }
+
+ pcmk__output_xml_pop_parent(out);
+ return pcmk_rc_ok;
+}
+
PCMK__OUTPUT_ARGS("resource-check-list", "resource_checks_t *")
static int
resource_check_list_default(pcmk__output_t *out, va_list args) {
@@ -658,6 +778,8 @@ static pcmk__message_entry_t fmt_functions[] = {
{ "override", "xml", override_xml },
{ "property-list", "default", property_list_default },
{ "property-list", "text", property_list_text },
+ { "resource-agent-action", "default", resource_agent_action_default },
+ { "resource-agent-action", "xml", resource_agent_action_xml },
{ "resource-check-list", "default", resource_check_list_default },
{ "resource-check-list", "xml", resource_check_list_xml },
{ "resource-search-list", "default", resource_search_list_default },
--
1.8.3.1
From b50b2418e1e997b42f5370b4672a3f105d74634f Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Fri, 4 Jun 2021 10:40:16 -0400
Subject: [PATCH 10/10] Feature: tools: Use the new resource-agent-action
message.
See: rhbz#1644628
---
tools/crm_resource_runtime.c | 21 +++------------------
1 file changed, 3 insertions(+), 18 deletions(-)
diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c
index ebf48bb..755be9f 100644
--- a/tools/crm_resource_runtime.c
+++ b/tools/crm_resource_runtime.c
@@ -1765,28 +1765,13 @@ cli_resource_execute_from_params(pcmk__output_t *out, const char *rsc_name,
if (services_action_sync(op)) {
exit_code = op->rc;
- if (op->status == PCMK_LRM_OP_DONE) {
- out->info(out, "Operation %s for %s (%s:%s:%s) returned: '%s' (%d)",
- action, rsc_name, rsc_class, rsc_prov ? rsc_prov : "", rsc_type,
- services_ocf_exitcode_str(op->rc), op->rc);
- } else {
- out->err(out, "Operation %s for %s (%s:%s:%s) failed: '%s' (%d)",
- action, rsc_name, rsc_class, rsc_prov ? rsc_prov : "", rsc_type,
- services_lrm_status_str(op->status), op->status);
- }
-
- /* hide output for validate-all if not in verbose */
- if (resource_verbose == 0 && pcmk__str_eq(action, "validate-all", pcmk__str_casei))
- goto done;
-
- if (op->stdout_data || op->stderr_data) {
- out->subprocess_output(out, op->rc, op->stdout_data, op->stderr_data);
- }
+ out->message(out, "resource-agent-action", resource_verbose, rsc_class,
+ rsc_prov, rsc_type, rsc_name, action, override_hash, op->rc,
+ op->status, op->stdout_data, op->stderr_data);
} else {
exit_code = op->rc == 0 ? CRM_EX_ERROR : op->rc;
}
-done:
services_action_free(op);
/* See comment above about why we free params here. */
g_hash_table_destroy(params);
--
1.8.3.1

View File

@ -0,0 +1,896 @@
From 97571e6ccc9b7fa339a7e27d9b0b9ab782ff3003 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Wed, 16 Jun 2021 13:54:10 -0400
Subject: [PATCH 1/5] Low: schemas: Copy crm_mon.rng in preparation for
changes.
---
xml/api/crm_mon-2.12.rng | 243 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 243 insertions(+)
create mode 100644 xml/api/crm_mon-2.12.rng
diff --git a/xml/api/crm_mon-2.12.rng b/xml/api/crm_mon-2.12.rng
new file mode 100644
index 0000000..ffec923
--- /dev/null
+++ b/xml/api/crm_mon-2.12.rng
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+
+ <start>
+ <ref name="element-crm-mon"/>
+ </start>
+
+ <define name="element-crm-mon">
+ <optional>
+ <ref name="element-summary" />
+ </optional>
+ <optional>
+ <ref name="nodes-list" />
+ </optional>
+ <optional>
+ <ref name="resources-list" />
+ </optional>
+ <optional>
+ <ref name="node-attributes-list" />
+ </optional>
+ <optional>
+ <ref name="node-history-list" />
+ </optional>
+ <optional>
+ <ref name="failures-list" />
+ </optional>
+ <optional>
+ <ref name="fence-event-list" />
+ </optional>
+ <optional>
+ <ref name="tickets-list" />
+ </optional>
+ <optional>
+ <ref name="bans-list" />
+ </optional>
+ </define>
+
+ <define name="element-summary">
+ <element name="summary">
+ <optional>
+ <element name="stack">
+ <attribute name="type"> <text /> </attribute>
+ </element>
+ </optional>
+ <optional>
+ <element name="current_dc">
+ <attribute name="present"> <data type="boolean" /> </attribute>
+ <optional>
+ <group>
+ <attribute name="version"> <text /> </attribute>
+ <attribute name="name"> <text /> </attribute>
+ <attribute name="id"> <text /> </attribute>
+ <attribute name="with_quorum"> <data type="boolean" /> </attribute>
+ </group>
+ </optional>
+ </element>
+ </optional>
+ <optional>
+ <element name="last_update">
+ <attribute name="time"> <text /> </attribute>
+ </element>
+ <element name="last_change">
+ <attribute name="time"> <text /> </attribute>
+ <attribute name="user"> <text /> </attribute>
+ <attribute name="client"> <text /> </attribute>
+ <attribute name="origin"> <text /> </attribute>
+ </element>
+ </optional>
+ <optional>
+ <element name="nodes_configured">
+ <attribute name="number"> <data type="nonNegativeInteger" /> </attribute>
+ </element>
+ <element name="resources_configured">
+ <attribute name="number"> <data type="nonNegativeInteger" /> </attribute>
+ <attribute name="disabled"> <data type="nonNegativeInteger" /> </attribute>
+ <attribute name="blocked"> <data type="nonNegativeInteger" /> </attribute>
+ </element>
+ </optional>
+ <optional>
+ <element name="cluster_options">
+ <attribute name="stonith-enabled"> <data type="boolean" /> </attribute>
+ <attribute name="symmetric-cluster"> <data type="boolean" /> </attribute>
+ <attribute name="no-quorum-policy"> <text /> </attribute>
+ <attribute name="maintenance-mode"> <data type="boolean" /> </attribute>
+ <attribute name="stop-all-resources"> <data type="boolean" /> </attribute>
+ </element>
+ </optional>
+ </element>
+ </define>
+
+ <define name="resources-list">
+ <element name="resources">
+ <zeroOrMore>
+ <externalRef href="resources-2.4.rng" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="nodes-list">
+ <element name="nodes">
+ <zeroOrMore>
+ <externalRef href="nodes-2.8.rng" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="node-attributes-list">
+ <element name="node_attributes">
+ <zeroOrMore>
+ <externalRef href="node-attrs-2.8.rng" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="node-history-list">
+ <element name="node_history">
+ <zeroOrMore>
+ <ref name="element-node-history" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="failures-list">
+ <element name="failures">
+ <zeroOrMore>
+ <externalRef href="failure-2.8.rng" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="fence-event-list">
+ <element name="fence_history">
+ <optional>
+ <attribute name="status"> <data type="integer" /> </attribute>
+ </optional>
+ <zeroOrMore>
+ <externalRef href="fence-event-2.0.rng" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="tickets-list">
+ <element name="tickets">
+ <zeroOrMore>
+ <ref name="element-ticket" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="bans-list">
+ <element name="bans">
+ <zeroOrMore>
+ <ref name="element-ban" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="element-node-history">
+ <element name="node">
+ <attribute name="name"> <text /> </attribute>
+ <zeroOrMore>
+ <ref name="element-resource-history" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="element-resource-history">
+ <element name="resource_history">
+ <attribute name="id"> <text /> </attribute>
+ <attribute name="orphan"> <data type="boolean" /> </attribute>
+ <optional>
+ <group>
+ <attribute name="migration-threshold"> <data type="nonNegativeInteger" /> </attribute>
+ <optional>
+ <attribute name="fail-count"> <text /> </attribute>
+ </optional>
+ <optional>
+ <attribute name="last-failure"> <text /> </attribute>
+ </optional>
+ </group>
+ </optional>
+ <zeroOrMore>
+ <ref name="element-operation-history" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="element-operation-history">
+ <element name="operation_history">
+ <attribute name="call"> <text /> </attribute>
+ <attribute name="task"> <text /> </attribute>
+ <optional>
+ <attribute name="interval"> <text /> </attribute>
+ </optional>
+ <optional>
+ <attribute name="last-rc-change"> <text /> </attribute>
+ </optional>
+ <optional>
+ <attribute name="last-run"> <text /> </attribute>
+ </optional>
+ <optional>
+ <attribute name="exec-time"> <text /> </attribute>
+ </optional>
+ <optional>
+ <attribute name="queue-time"> <text /> </attribute>
+ </optional>
+ <attribute name="rc"> <data type="integer" /> </attribute>
+ <attribute name="rc_text"> <text /> </attribute>
+ </element>
+ </define>
+
+ <define name="element-ticket">
+ <element name="ticket">
+ <attribute name="id"> <text /> </attribute>
+ <attribute name="status">
+ <choice>
+ <value>granted</value>
+ <value>revoked</value>
+ </choice>
+ </attribute>
+ <attribute name="standby"> <data type="boolean" /> </attribute>
+ <optional>
+ <attribute name="last-granted"> <text /> </attribute>
+ </optional>
+ </element>
+ </define>
+
+ <define name="element-ban">
+ <element name="ban">
+ <attribute name="id"> <text /> </attribute>
+ <attribute name="resource"> <text /> </attribute>
+ <attribute name="node"> <text /> </attribute>
+ <attribute name="weight"> <data type="integer" /> </attribute>
+ <attribute name="promoted-only"> <data type="boolean" /> </attribute>
+ <!-- DEPRECATED: master_only is a duplicate of promoted-only that is
+ provided solely for API backward compatibility. It will be
+ removed in a future release. Check promoted-only instead.
+ -->
+ <attribute name="master_only"> <data type="boolean" /> </attribute>
+ </element>
+ </define>
+</grammar>
--
1.8.3.1
From da394983f106f974274ddd94675a04c85086010e Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Fri, 18 Jun 2021 15:06:34 -0400
Subject: [PATCH 2/5] Refactor: Split node history out into its own XML schema.
This allows for sharing it between crm_mon and crm_simulate.
---
xml/Makefile.am | 2 +-
xml/api/crm_mon-2.12.rng | 64 +--------------------------------------
xml/api/node-history-2.12.rng | 70 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 72 insertions(+), 64 deletions(-)
create mode 100644 xml/api/node-history-2.12.rng
diff --git a/xml/Makefile.am b/xml/Makefile.am
index b9448d4..8e7b6d3 100644
--- a/xml/Makefile.am
+++ b/xml/Makefile.am
@@ -64,7 +64,7 @@ API_request_base = command-output \
CIB_cfg_base = options nodes resources constraints fencing acls tags alerts
# Names of all schemas (including top level and those included by others)
-API_base = $(API_request_base) fence-event failure generic-list item node-attrs nodes resources status
+API_base = $(API_request_base) fence-event failure generic-list item node-attrs node-history nodes resources status
CIB_base = cib $(CIB_cfg_base) status score rule nvset
# Static schema files and transforms (only CIB has transforms)
diff --git a/xml/api/crm_mon-2.12.rng b/xml/api/crm_mon-2.12.rng
index ffec923..be14412 100644
--- a/xml/api/crm_mon-2.12.rng
+++ b/xml/api/crm_mon-2.12.rng
@@ -20,7 +20,7 @@
<ref name="node-attributes-list" />
</optional>
<optional>
- <ref name="node-history-list" />
+ <externalRef href="node-history-2.12.rng"/>
</optional>
<optional>
<ref name="failures-list" />
@@ -113,14 +113,6 @@
</element>
</define>
- <define name="node-history-list">
- <element name="node_history">
- <zeroOrMore>
- <ref name="element-node-history" />
- </zeroOrMore>
- </element>
- </define>
-
<define name="failures-list">
<element name="failures">
<zeroOrMore>
@@ -156,60 +148,6 @@
</element>
</define>
- <define name="element-node-history">
- <element name="node">
- <attribute name="name"> <text /> </attribute>
- <zeroOrMore>
- <ref name="element-resource-history" />
- </zeroOrMore>
- </element>
- </define>
-
- <define name="element-resource-history">
- <element name="resource_history">
- <attribute name="id"> <text /> </attribute>
- <attribute name="orphan"> <data type="boolean" /> </attribute>
- <optional>
- <group>
- <attribute name="migration-threshold"> <data type="nonNegativeInteger" /> </attribute>
- <optional>
- <attribute name="fail-count"> <text /> </attribute>
- </optional>
- <optional>
- <attribute name="last-failure"> <text /> </attribute>
- </optional>
- </group>
- </optional>
- <zeroOrMore>
- <ref name="element-operation-history" />
- </zeroOrMore>
- </element>
- </define>
-
- <define name="element-operation-history">
- <element name="operation_history">
- <attribute name="call"> <text /> </attribute>
- <attribute name="task"> <text /> </attribute>
- <optional>
- <attribute name="interval"> <text /> </attribute>
- </optional>
- <optional>
- <attribute name="last-rc-change"> <text /> </attribute>
- </optional>
- <optional>
- <attribute name="last-run"> <text /> </attribute>
- </optional>
- <optional>
- <attribute name="exec-time"> <text /> </attribute>
- </optional>
- <optional>
- <attribute name="queue-time"> <text /> </attribute>
- </optional>
- <attribute name="rc"> <data type="integer" /> </attribute>
- <attribute name="rc_text"> <text /> </attribute>
- </element>
- </define>
-
<define name="element-ticket">
<element name="ticket">
<attribute name="id"> <text /> </attribute>
diff --git a/xml/api/node-history-2.12.rng b/xml/api/node-history-2.12.rng
new file mode 100644
index 0000000..9628000
--- /dev/null
+++ b/xml/api/node-history-2.12.rng
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+
+ <start>
+ <ref name="node-history-list" />
+ </start>
+
+ <define name="node-history-list">
+ <element name="node_history">
+ <zeroOrMore>
+ <ref name="element-node-history" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="element-node-history">
+ <element name="node">
+ <attribute name="name"> <text /> </attribute>
+ <zeroOrMore>
+ <ref name="element-resource-history" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="element-resource-history">
+ <element name="resource_history">
+ <attribute name="id"> <text /> </attribute>
+ <attribute name="orphan"> <data type="boolean" /> </attribute>
+ <optional>
+ <group>
+ <attribute name="migration-threshold"> <data type="nonNegativeInteger" /> </attribute>
+ <optional>
+ <attribute name="fail-count"> <text /> </attribute>
+ </optional>
+ <optional>
+ <attribute name="last-failure"> <text /> </attribute>
+ </optional>
+ </group>
+ </optional>
+ <zeroOrMore>
+ <ref name="element-operation-history" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="element-operation-history">
+ <element name="operation_history">
+ <attribute name="call"> <text /> </attribute>
+ <attribute name="task"> <text /> </attribute>
+ <optional>
+ <attribute name="interval"> <text /> </attribute>
+ </optional>
+ <optional>
+ <attribute name="last-rc-change"> <text /> </attribute>
+ </optional>
+ <optional>
+ <attribute name="last-run"> <text /> </attribute>
+ </optional>
+ <optional>
+ <attribute name="exec-time"> <text /> </attribute>
+ </optional>
+ <optional>
+ <attribute name="queue-time"> <text /> </attribute>
+ </optional>
+ <attribute name="rc"> <data type="integer" /> </attribute>
+ <attribute name="rc_text"> <text /> </attribute>
+ </element>
+ </define>
+</grammar>
--
1.8.3.1
From bf72b2615630eef7876e443d60b34d5a316de847 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Wed, 16 Jun 2021 14:09:31 -0400
Subject: [PATCH 3/5] Low: schemas: Copy crm_simulate.rng in preparation for
changes.
---
xml/api/crm_simulate-2.12.rng | 335 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 335 insertions(+)
create mode 100644 xml/api/crm_simulate-2.12.rng
diff --git a/xml/api/crm_simulate-2.12.rng b/xml/api/crm_simulate-2.12.rng
new file mode 100644
index 0000000..9a7612d
--- /dev/null
+++ b/xml/api/crm_simulate-2.12.rng
@@ -0,0 +1,335 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+
+ <start>
+ <ref name="element-crm-simulate"/>
+ </start>
+
+ <define name="element-crm-simulate">
+ <choice>
+ <ref name="timings-list" />
+ <group>
+ <ref name="cluster-status" />
+ <optional>
+ <ref name="modifications-list" />
+ </optional>
+ <optional>
+ <ref name="allocations-utilizations-list" />
+ </optional>
+ <optional>
+ <ref name="action-list" />
+ </optional>
+ <optional>
+ <ref name="cluster-injected-actions-list" />
+ <ref name="revised-cluster-status" />
+ </optional>
+ </group>
+ </choice>
+ </define>
+
+ <define name="allocations-utilizations-list">
+ <choice>
+ <element name="allocations">
+ <zeroOrMore>
+ <choice>
+ <ref name="element-allocation" />
+ <ref name="element-promotion" />
+ </choice>
+ </zeroOrMore>
+ </element>
+ <element name="utilizations">
+ <zeroOrMore>
+ <choice>
+ <ref name="element-capacity" />
+ <ref name="element-utilization" />
+ </choice>
+ </zeroOrMore>
+ </element>
+ <element name="allocations_utilizations">
+ <zeroOrMore>
+ <choice>
+ <ref name="element-allocation" />
+ <ref name="element-promotion" />
+ <ref name="element-capacity" />
+ <ref name="element-utilization" />
+ </choice>
+ </zeroOrMore>
+ </element>
+ </choice>
+ </define>
+
+ <define name="cluster-status">
+ <element name="cluster_status">
+ <ref name="nodes-list" />
+ <ref name="resources-list" />
+ <optional>
+ <ref name="node-attributes-list" />
+ </optional>
+ <optional>
+ <ref name="failures-list" />
+ </optional>
+ </element>
+ </define>
+
+ <define name="modifications-list">
+ <element name="modifications">
+ <optional>
+ <attribute name="quorum"> <text /> </attribute>
+ </optional>
+ <optional>
+ <attribute name="watchdog"> <text /> </attribute>
+ </optional>
+ <zeroOrMore>
+ <ref name="element-inject-modify-node" />
+ </zeroOrMore>
+ <zeroOrMore>
+ <ref name="element-inject-modify-ticket" />
+ </zeroOrMore>
+ <zeroOrMore>
+ <ref name="element-inject-spec" />
+ </zeroOrMore>
+ <zeroOrMore>
+ <ref name="element-inject-attr" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="revised-cluster-status">
+ <element name="revised_cluster_status">
+ <ref name="nodes-list" />
+ <ref name="resources-list" />
+ <optional>
+ <ref name="node-attributes-list" />
+ </optional>
+ <optional>
+ <ref name="failures-list" />
+ </optional>
+ </element>
+ </define>
+
+ <define name="element-inject-attr">
+ <element name="inject_attr">
+ <attribute name="cib_node"> <text /> </attribute>
+ <attribute name="name"> <text /> </attribute>
+ <attribute name="node_path"> <text /> </attribute>
+ <attribute name="value"> <text /> </attribute>
+ </element>
+ </define>
+
+ <define name="element-inject-modify-node">
+ <element name="modify_node">
+ <attribute name="action"> <text /> </attribute>
+ <attribute name="node"> <text /> </attribute>
+ </element>
+ </define>
+
+ <define name="element-inject-spec">
+ <element name="inject_spec">
+ <attribute name="spec"> <text /> </attribute>
+ </element>
+ </define>
+
+ <define name="element-inject-modify-ticket">
+ <element name="modify_ticket">
+ <attribute name="action"> <text /> </attribute>
+ <attribute name="ticket"> <text /> </attribute>
+ </element>
+ </define>
+
+ <define name="cluster-injected-actions-list">
+ <element name="transition">
+ <zeroOrMore>
+ <ref name="element-injected-actions" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="node-attributes-list">
+ <element name="node_attributes">
+ <zeroOrMore>
+ <externalRef href="node-attrs-2.8.rng" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="failures-list">
+ <element name="failures">
+ <zeroOrMore>
+ <externalRef href="failure-2.8.rng" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="nodes-list">
+ <element name="nodes">
+ <zeroOrMore>
+ <externalRef href="nodes-2.8.rng" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="resources-list">
+ <element name="resources">
+ <zeroOrMore>
+ <externalRef href="resources-2.4.rng" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="timings-list">
+ <element name="timings">
+ <zeroOrMore>
+ <ref name="element-timing" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="action-list">
+ <element name="actions">
+ <zeroOrMore>
+ <ref name="element-node-action" />
+ </zeroOrMore>
+ <zeroOrMore>
+ <ref name="element-rsc-action" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="element-allocation">
+ <element name="node_weight">
+ <attribute name="function"> <text /> </attribute>
+ <attribute name="node"> <text /> </attribute>
+ <externalRef href="../score.rng" />
+ <optional>
+ <attribute name="id"> <text /> </attribute>
+ </optional>
+ </element>
+ </define>
+
+ <define name="element-capacity">
+ <element name="capacity">
+ <attribute name="comment"> <text /> </attribute>
+ <attribute name="node"> <text /> </attribute>
+ <zeroOrMore>
+ <element>
+ <anyName />
+ <text />
+ </element>
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="element-inject-cluster-action">
+ <element name="cluster_action">
+ <attribute name="node"> <text /> </attribute>
+ <attribute name="task"> <text /> </attribute>
+ <optional>
+ <attribute name="id"> <text /> </attribute>
+ </optional>
+ </element>
+ </define>
+
+ <define name="element-injected-actions">
+ <choice>
+ <ref name="element-inject-cluster-action" />
+ <ref name="element-inject-fencing-action" />
+ <ref name="element-inject-pseudo-action" />
+ <ref name="element-inject-rsc-action" />
+ </choice>
+ </define>
+
+ <define name="element-inject-fencing-action">
+ <element name="fencing_action">
+ <attribute name="op"> <text /> </attribute>
+ <attribute name="target"> <text /> </attribute>
+ </element>
+ </define>
+
+ <define name="element-node-action">
+ <element name="node_action">
+ <attribute name="node"> <text /> </attribute>
+ <attribute name="reason"> <text /> </attribute>
+ <attribute name="task"> <text /> </attribute>
+ </element>
+ </define>
+
+ <define name="element-promotion">
+ <element name="promotion_score">
+ <attribute name="id"> <text /> </attribute>
+ <externalRef href="../score.rng" />
+ <optional>
+ <attribute name="node"> <text /> </attribute>
+ </optional>
+ </element>
+ </define>
+
+ <define name="element-inject-pseudo-action">
+ <element name="pseudo_action">
+ <attribute name="task"> <text /> </attribute>
+ <optional>
+ <attribute name="node"> <text /> </attribute>
+ </optional>
+ </element>
+ </define>
+
+ <define name="element-inject-rsc-action">
+ <element name="rsc_action">
+ <attribute name="node"> <text /> </attribute>
+ <attribute name="op"> <text /> </attribute>
+ <attribute name="resource"> <text /> </attribute>
+ <optional>
+ <attribute name="interval"> <data type="integer" /> </attribute>
+ </optional>
+ </element>
+ </define>
+
+ <define name="element-timing">
+ <element name="timing">
+ <attribute name="file"> <text /> </attribute>
+ <attribute name="duration"> <data type="double" /> </attribute>
+ </element>
+ </define>
+
+ <define name="element-rsc-action">
+ <element name="rsc_action">
+ <attribute name="action"> <text /> </attribute>
+ <attribute name="resource"> <text /> </attribute>
+ <optional>
+ <attribute name="blocked"> <data type="boolean" /> </attribute>
+ </optional>
+ <optional>
+ <attribute name="dest"> <text /> </attribute>
+ </optional>
+ <optional>
+ <attribute name="next-role"> <text /> </attribute>
+ </optional>
+ <optional>
+ <attribute name="node"> <text /> </attribute>
+ </optional>
+ <optional>
+ <attribute name="reason"> <text /> </attribute>
+ </optional>
+ <optional>
+ <attribute name="role"> <text /> </attribute>
+ </optional>
+ <optional>
+ <attribute name="source"> <text /> </attribute>
+ </optional>
+ </element>
+ </define>
+
+ <define name="element-utilization">
+ <element name="utilization">
+ <attribute name="function"> <text /> </attribute>
+ <attribute name="node"> <text /> </attribute>
+ <attribute name="resource"> <text /> </attribute>
+ <zeroOrMore>
+ <element>
+ <anyName />
+ <text />
+ </element>
+ </zeroOrMore>
+ </element>
+ </define>
+</grammar>
--
1.8.3.1
From c46e07788788acf5669e3f89b9344190a91c7331 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Fri, 18 Jun 2021 15:10:19 -0400
Subject: [PATCH 4/5] Feature: tools: Add the node-summary to crm_simulate
output.
If --show-failcounts is given to crm_simulate, it should also display
the node-summary message.
See: rhbz#1686426
---
tools/crm_simulate.c | 7 +++++--
xml/api/crm_simulate-2.12.rng | 3 +++
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/tools/crm_simulate.c b/tools/crm_simulate.c
index b4aa9d1..2ea292c 100644
--- a/tools/crm_simulate.c
+++ b/tools/crm_simulate.c
@@ -409,11 +409,14 @@ print_cluster_status(pe_working_set_t * data_set, unsigned int print_opts)
FALSE, FALSE, all, all, FALSE);
if (options.show_attrs) {
- out->message(out, "node-attribute-list", data_set,
- 0, rc == pcmk_rc_ok, FALSE, FALSE, FALSE, all, all);
+ rc = out->message(out, "node-attribute-list", data_set,
+ 0, rc == pcmk_rc_ok, FALSE, FALSE, FALSE, all, all);
}
if (options.show_failcounts) {
+ rc = out->message(out, "node-summary", data_set, all, all,
+ 0, print_opts, FALSE, FALSE, FALSE, FALSE, rc == pcmk_rc_ok);
+
out->message(out, "failed-action-list", data_set, all, all,
rc == pcmk_rc_ok);
}
diff --git a/xml/api/crm_simulate-2.12.rng b/xml/api/crm_simulate-2.12.rng
index 9a7612d..f90bd36 100644
--- a/xml/api/crm_simulate-2.12.rng
+++ b/xml/api/crm_simulate-2.12.rng
@@ -67,6 +67,9 @@
<ref name="node-attributes-list" />
</optional>
<optional>
+ <externalRef href="node-history-2.12.rng" />
+ </optional>
+ <optional>
<ref name="failures-list" />
</optional>
</element>
--
1.8.3.1
From bac50336e0264604716e5997b87ee7e65311b982 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Fri, 18 Jun 2021 15:21:52 -0400
Subject: [PATCH 5/5] Low: libcrmcommon: Increase PCMK__API_VERSION for new
crm_resource output.
See: rhbz#1686426
---
include/crm/common/output_internal.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/crm/common/output_internal.h b/include/crm/common/output_internal.h
index 0436cde..ba9c423 100644
--- a/include/crm/common/output_internal.h
+++ b/include/crm/common/output_internal.h
@@ -27,7 +27,7 @@ extern "C" {
# include <glib.h>
# include <crm/common/results.h>
-# define PCMK__API_VERSION "2.11"
+# define PCMK__API_VERSION "2.12"
#if defined(PCMK__WITH_ATTRIBUTE_OUTPUT_ARGS)
# define PCMK__OUTPUT_ARGS(ARGS...) __attribute__((output_args(ARGS)))
--
1.8.3.1

View File

@ -0,0 +1,733 @@
From 6dcd6b51d7d3993bc483588d6ed75077518ed600 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Fri, 4 Jun 2021 16:30:55 -0500
Subject: [PATCH 01/11] Low: controller: check whether unfenced node was remote
node
... so the controller can indicate the node is remote (if known at that point,
which is not guaranteed) when setting unfencing-related node attributes.
---
daemons/controld/controld_fencing.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/daemons/controld/controld_fencing.c b/daemons/controld/controld_fencing.c
index 23dff28..0fba661 100644
--- a/daemons/controld/controld_fencing.c
+++ b/daemons/controld/controld_fencing.c
@@ -757,15 +757,30 @@ tengine_stonith_callback(stonith_t *stonith, stonith_callback_data_t *data)
if (pcmk__str_eq("on", op, pcmk__str_casei)) {
const char *value = NULL;
char *now = pcmk__ttoa(time(NULL));
+ gboolean is_remote_node = FALSE;
+
+ /* This check is not 100% reliable, since this node is not
+ * guaranteed to have the remote node cached. However, it
+ * doesn't have to be reliable, since the attribute manager can
+ * learn a node's "remoteness" by other means sooner or later.
+ * This allows it to learn more quickly if this node does have
+ * the information.
+ */
+ if (g_hash_table_lookup(crm_remote_peer_cache, uuid) != NULL) {
+ is_remote_node = TRUE;
+ }
- update_attrd(target, CRM_ATTR_UNFENCED, now, NULL, FALSE);
+ update_attrd(target, CRM_ATTR_UNFENCED, now, NULL,
+ is_remote_node);
free(now);
value = crm_meta_value(action->params, XML_OP_ATTR_DIGESTS_ALL);
- update_attrd(target, CRM_ATTR_DIGESTS_ALL, value, NULL, FALSE);
+ update_attrd(target, CRM_ATTR_DIGESTS_ALL, value, NULL,
+ is_remote_node);
value = crm_meta_value(action->params, XML_OP_ATTR_DIGESTS_SECURE);
- update_attrd(target, CRM_ATTR_DIGESTS_SECURE, value, NULL, FALSE);
+ update_attrd(target, CRM_ATTR_DIGESTS_SECURE, value, NULL,
+ is_remote_node);
} else if (action->sent_update == FALSE) {
send_stonith_update(action, target, uuid);
--
1.8.3.1
From 3ef6d9403f68ab8559c45cc99f5a8da05ca6420b Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Mon, 7 Jun 2021 10:50:36 -0500
Subject: [PATCH 02/11] Refactor: pacemaker-attrd: functionize adding remote
node to cache
... for future reuse
---
daemons/attrd/attrd_commands.c | 34 +++++++++++++++++++++++-----------
1 file changed, 23 insertions(+), 11 deletions(-)
diff --git a/daemons/attrd/attrd_commands.c b/daemons/attrd/attrd_commands.c
index 731c243..93a165b 100644
--- a/daemons/attrd/attrd_commands.c
+++ b/daemons/attrd/attrd_commands.c
@@ -102,6 +102,28 @@ free_attribute(gpointer data)
}
}
+/*!
+ * \internal
+ * \brief Ensure a Pacemaker Remote node is in the correct peer cache
+ *
+ * \param[in]
+ */
+static void
+cache_remote_node(const char *node_name)
+{
+ /* If we previously assumed this node was an unseen cluster node,
+ * remove its entry from the cluster peer cache.
+ */
+ crm_node_t *dup = pcmk__search_cluster_node_cache(0, node_name);
+
+ if (dup && (dup->uuid == NULL)) {
+ reap_crm_member(0, node_name);
+ }
+
+ // Ensure node is in the remote peer cache
+ CRM_ASSERT(crm_remote_peer_get(node_name) != NULL);
+}
+
static xmlNode *
build_attribute_xml(
xmlNode *parent, const char *name, const char *set, const char *uuid, unsigned int timeout_ms, const char *user,
@@ -709,17 +731,7 @@ attrd_lookup_or_create_value(GHashTable *values, const char *host, xmlNode *xml)
crm_element_value_int(xml, PCMK__XA_ATTR_IS_REMOTE, &is_remote);
if (is_remote) {
- /* If we previously assumed this node was an unseen cluster node,
- * remove its entry from the cluster peer cache.
- */
- crm_node_t *dup = pcmk__search_cluster_node_cache(0, host);
-
- if (dup && (dup->uuid == NULL)) {
- reap_crm_member(0, host);
- }
-
- /* Ensure this host is in the remote peer cache */
- CRM_ASSERT(crm_remote_peer_get(host) != NULL);
+ cache_remote_node(host);
}
if (v == NULL) {
--
1.8.3.1
From 6fac2c71bc2c56870ac828d7cd7b7c799279c47e Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Mon, 7 Jun 2021 10:39:34 -0500
Subject: [PATCH 03/11] Refactor: pacemaker-attrd: don't try to remove votes
for remote nodes
Remote nodes never vote.
This has no effect in practice since the removal would simply do nothing,
but we might as well not waste time trying.
---
daemons/attrd/attrd_commands.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/daemons/attrd/attrd_commands.c b/daemons/attrd/attrd_commands.c
index 93a165b..dbe777e 100644
--- a/daemons/attrd/attrd_commands.c
+++ b/daemons/attrd/attrd_commands.c
@@ -976,7 +976,8 @@ attrd_election_cb(gpointer user_data)
void
attrd_peer_change_cb(enum crm_status_type kind, crm_node_t *peer, const void *data)
{
- bool remove_voter = FALSE;
+ bool gone = false;
+ bool is_remote = pcmk_is_set(peer->flags, crm_remote_node);
switch (kind) {
case crm_status_uname:
@@ -984,7 +985,7 @@ attrd_peer_change_cb(enum crm_status_type kind, crm_node_t *peer, const void *da
case crm_status_processes:
if (!pcmk_is_set(peer->processes, crm_get_cluster_proc())) {
- remove_voter = TRUE;
+ gone = true;
}
break;
@@ -1000,13 +1001,13 @@ attrd_peer_change_cb(enum crm_status_type kind, crm_node_t *peer, const void *da
} else {
// Remove all attribute values associated with lost nodes
attrd_peer_remove(peer->uname, FALSE, "loss");
- remove_voter = TRUE;
+ gone = true;
}
break;
}
- // In case an election is in progress, remove any vote by the node
- if (remove_voter) {
+ // Remove votes from cluster nodes that leave, in case election in progress
+ if (gone && !is_remote) {
attrd_remove_voter(peer);
}
}
--
1.8.3.1
From 54089fc663d6aaf10ca164c6c94b3b17237788de Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Mon, 7 Jun 2021 10:40:06 -0500
Subject: [PATCH 04/11] Low: pacemaker-attrd: check for remote nodes in peer
update callback
If a remote node was started before the local cluster node joined the cluster,
the cluster node will assume its node attributes are for a cluster node until
it learns otherwise. Check for remoteness in the peer update callback, to have
another way we can learn it.
---
daemons/attrd/attrd_commands.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/daemons/attrd/attrd_commands.c b/daemons/attrd/attrd_commands.c
index dbe777e..5f6a754 100644
--- a/daemons/attrd/attrd_commands.c
+++ b/daemons/attrd/attrd_commands.c
@@ -1009,6 +1009,10 @@ attrd_peer_change_cb(enum crm_status_type kind, crm_node_t *peer, const void *da
// Remove votes from cluster nodes that leave, in case election in progress
if (gone && !is_remote) {
attrd_remove_voter(peer);
+
+ // Ensure remote nodes that come up are in the remote node cache
+ } else if (!gone && is_remote) {
+ cache_remote_node(peer->uname);
}
}
--
1.8.3.1
From 8c048df0312d0d9c857d87b570a352429a710928 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Mon, 7 Jun 2021 11:29:12 -0500
Subject: [PATCH 05/11] Log: pacemaker-attrd: log peer status changes
---
daemons/attrd/attrd_commands.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/daemons/attrd/attrd_commands.c b/daemons/attrd/attrd_commands.c
index 5f6a754..d6d179b 100644
--- a/daemons/attrd/attrd_commands.c
+++ b/daemons/attrd/attrd_commands.c
@@ -972,6 +972,7 @@ attrd_election_cb(gpointer user_data)
return FALSE;
}
+#define state_text(state) ((state)? (const char *)(state) : "in unknown state")
void
attrd_peer_change_cb(enum crm_status_type kind, crm_node_t *peer, const void *data)
@@ -981,15 +982,23 @@ attrd_peer_change_cb(enum crm_status_type kind, crm_node_t *peer, const void *da
switch (kind) {
case crm_status_uname:
+ crm_debug("%s node %s is now %s",
+ (is_remote? "Remote" : "Cluster"),
+ peer->uname, state_text(peer->state));
break;
case crm_status_processes:
if (!pcmk_is_set(peer->processes, crm_get_cluster_proc())) {
gone = true;
}
+ crm_debug("Node %s is %s a peer",
+ peer->uname, (gone? "no longer" : "now"));
break;
case crm_status_nstate:
+ crm_debug("%s node %s is now %s (was %s)",
+ (is_remote? "Remote" : "Cluster"),
+ peer->uname, state_text(peer->state), state_text(data));
if (pcmk__str_eq(peer->state, CRM_NODE_MEMBER, pcmk__str_casei)) {
/* If we're the writer, send new peers a list of all attributes
* (unless it's a remote node, which doesn't run its own attrd)
--
1.8.3.1
From 1dcc8dee4990cf0dbdec0e14db6d9a3ad67a41d5 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Mon, 7 Jun 2021 11:13:53 -0500
Subject: [PATCH 06/11] Low: pacemaker-attrd: ensure node ID is only set for
attributes when known
In most cases, attribute updates contained the node ID, and the node ID was
used by other code, only if known (i.e. positive). However a couple places did
not check this, so add that.
I am unsure whether the missing check caused problems in practice, but there
appears to be the possibility that a remote node would wrongly be added to the
cluster node cache.
---
daemons/attrd/attrd_commands.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/daemons/attrd/attrd_commands.c b/daemons/attrd/attrd_commands.c
index d6d179b..b3f441c 100644
--- a/daemons/attrd/attrd_commands.c
+++ b/daemons/attrd/attrd_commands.c
@@ -136,7 +136,9 @@ build_attribute_xml(
crm_xml_add(xml, PCMK__XA_ATTR_UUID, uuid);
crm_xml_add(xml, PCMK__XA_ATTR_USER, user);
crm_xml_add(xml, PCMK__XA_ATTR_NODE_NAME, peer);
- crm_xml_add_int(xml, PCMK__XA_ATTR_NODE_ID, peerid);
+ if (peerid > 0) {
+ crm_xml_add_int(xml, PCMK__XA_ATTR_NODE_ID, peerid);
+ }
crm_xml_add(xml, PCMK__XA_ATTR_VALUE, value);
crm_xml_add_int(xml, PCMK__XA_ATTR_DAMPENING, timeout_ms/1000);
crm_xml_add_int(xml, PCMK__XA_ATTR_IS_PRIVATE, is_private);
@@ -937,7 +939,7 @@ attrd_peer_update(crm_node_t *peer, xmlNode *xml, const char *host, bool filter)
/* If this is a cluster node whose node ID we are learning, remember it */
if ((v->nodeid == 0) && (v->is_remote == FALSE)
&& (crm_element_value_int(xml, PCMK__XA_ATTR_NODE_ID,
- (int*)&v->nodeid) == 0)) {
+ (int*)&v->nodeid) == 0) && (v->nodeid > 0)) {
crm_node_t *known_peer = crm_get_peer(v->nodeid, host);
--
1.8.3.1
From 8d12490e88b558d01db37a38f7d35175c6d2d69a Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Thu, 10 Jun 2021 17:25:57 -0500
Subject: [PATCH 07/11] Refactor: pacemaker-attrd: functionize processing a
sync response
... for code isolation, and because we need to add more to it
---
daemons/attrd/attrd_commands.c | 59 ++++++++++++++++++++++++++++--------------
1 file changed, 39 insertions(+), 20 deletions(-)
diff --git a/daemons/attrd/attrd_commands.c b/daemons/attrd/attrd_commands.c
index b3f441c..d02d3e6 100644
--- a/daemons/attrd/attrd_commands.c
+++ b/daemons/attrd/attrd_commands.c
@@ -572,6 +572,43 @@ attrd_peer_clear_failure(crm_node_t *peer, xmlNode *xml)
}
/*!
+ * \internal
+ * \brief Load attributes from a peer sync response
+ *
+ * \param[in] peer Peer that sent clear request
+ * \param[in] peer_won Whether peer is the attribute writer
+ * \param[in] xml Request XML
+ */
+static void
+process_peer_sync_response(crm_node_t *peer, bool peer_won, xmlNode *xml)
+{
+ crm_info("Processing " PCMK__ATTRD_CMD_SYNC_RESPONSE " from %s",
+ peer->uname);
+
+ if (peer_won) {
+ /* Initialize the "seen" flag for all attributes to cleared, so we can
+ * detect attributes that local node has but the writer doesn't.
+ */
+ clear_attribute_value_seen();
+ }
+
+ // Process each attribute update in the sync response
+ for (xmlNode *child = pcmk__xml_first_child(xml); child != NULL;
+ child = pcmk__xml_next(child)) {
+ attrd_peer_update(peer, child,
+ crm_element_value(child, PCMK__XA_ATTR_NODE_NAME),
+ TRUE);
+ }
+
+ if (peer_won) {
+ /* If any attributes are still not marked as seen, the writer doesn't
+ * know about them, so send all peers an update with them.
+ */
+ attrd_current_only_attribute_update(peer, xml);
+ }
+}
+
+/*!
\internal
\brief Broadcast private attribute for local node with protocol version
*/
@@ -596,7 +633,7 @@ attrd_peer_message(crm_node_t *peer, xmlNode *xml)
const char *op = crm_element_value(xml, PCMK__XA_TASK);
const char *election_op = crm_element_value(xml, F_CRM_TASK);
const char *host = crm_element_value(xml, PCMK__XA_ATTR_NODE_NAME);
- bool peer_won = FALSE;
+ bool peer_won = false;
if (election_op) {
attrd_handle_election_op(peer, xml);
@@ -631,25 +668,7 @@ attrd_peer_message(crm_node_t *peer, xmlNode *xml)
} else if (pcmk__str_eq(op, PCMK__ATTRD_CMD_SYNC_RESPONSE, pcmk__str_casei)
&& !pcmk__str_eq(peer->uname, attrd_cluster->uname, pcmk__str_casei)) {
- xmlNode *child = NULL;
-
- crm_info("Processing %s from %s", op, peer->uname);
-
- /* Clear the seen flag for attribute processing held only in the own node. */
- if (peer_won) {
- clear_attribute_value_seen();
- }
-
- for (child = pcmk__xml_first_child(xml); child != NULL;
- child = pcmk__xml_next(child)) {
- host = crm_element_value(child, PCMK__XA_ATTR_NODE_NAME);
- attrd_peer_update(peer, child, host, TRUE);
- }
-
- if (peer_won) {
- /* Synchronize if there is an attribute held only by own node that Writer does not have. */
- attrd_current_only_attribute_update(peer, xml);
- }
+ process_peer_sync_response(peer, peer_won, xml);
} else if (pcmk__str_eq(op, PCMK__ATTRD_CMD_FLUSH, pcmk__str_casei)) {
/* Ignore. The flush command was removed in 2.0.0 but may be
--
1.8.3.1
From a890a0e5bbbcabf907f51ed0460868035f72464d Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Fri, 11 Jun 2021 14:40:39 -0500
Subject: [PATCH 08/11] Refactor: pacemaker-attrd: functionize broadcasting
local override
... for code isolation
---
daemons/attrd/attrd_commands.c | 42 +++++++++++++++++++++++++++++-------------
1 file changed, 29 insertions(+), 13 deletions(-)
diff --git a/daemons/attrd/attrd_commands.c b/daemons/attrd/attrd_commands.c
index d02d3e6..4783427 100644
--- a/daemons/attrd/attrd_commands.c
+++ b/daemons/attrd/attrd_commands.c
@@ -804,6 +804,34 @@ attrd_current_only_attribute_update(crm_node_t *peer, xmlNode *xml)
free_xml(sync);
}
+/*!
+ * \internal
+ * \brief Override an attribute sync with a local value
+ *
+ * Broadcast the local node's value for an attribute that's different from the
+ * value provided in a peer's attribute synchronization response. This ensures a
+ * node's values for itself take precedence and all peers are kept in sync.
+ *
+ * \param[in] a Attribute entry to override
+ *
+ * \return Local instance of attribute value
+ */
+static attribute_value_t *
+broadcast_local_value(attribute_t *a)
+{
+ attribute_value_t *v = g_hash_table_lookup(a->values, attrd_cluster->uname);
+ xmlNode *sync = create_xml_node(NULL, __func__);
+
+ crm_xml_add(sync, PCMK__XA_TASK, PCMK__ATTRD_CMD_SYNC_RESPONSE);
+ build_attribute_xml(sync, a->id, a->set, a->uuid, a->timeout_ms,
+ a->user, a->is_private, v->nodename, v->nodeid,
+ v->current, FALSE);
+ attrd_xml_add_writer(sync);
+ send_attrd_message(NULL, sync);
+ free_xml(sync);
+ return v;
+}
+
void
attrd_peer_update(crm_node_t *peer, xmlNode *xml, const char *host, bool filter)
{
@@ -899,21 +927,9 @@ attrd_peer_update(crm_node_t *peer, xmlNode *xml, const char *host, bool filter)
if (filter && !pcmk__str_eq(v->current, value, pcmk__str_casei)
&& pcmk__str_eq(host, attrd_cluster->uname, pcmk__str_casei)) {
- xmlNode *sync = create_xml_node(NULL, __func__);
-
crm_notice("%s[%s]: local value '%s' takes priority over '%s' from %s",
attr, host, v->current, value, peer->uname);
-
- crm_xml_add(sync, PCMK__XA_TASK, PCMK__ATTRD_CMD_SYNC_RESPONSE);
- v = g_hash_table_lookup(a->values, host);
- build_attribute_xml(sync, attr, a->set, a->uuid, a->timeout_ms, a->user,
- a->is_private, v->nodename, v->nodeid, v->current, FALSE);
-
- attrd_xml_add_writer(sync);
-
- /* Broadcast in case any other nodes had the inconsistent value */
- send_attrd_message(NULL, sync);
- free_xml(sync);
+ v = broadcast_local_value(a);
} else if (!pcmk__str_eq(v->current, value, pcmk__str_casei)) {
crm_notice("Setting %s[%s]: %s -> %s " CRM_XS " from %s",
--
1.8.3.1
From f6f65e3dab070f1bbdf6d1383f4d6173a8840bc9 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Fri, 11 Jun 2021 14:50:29 -0500
Subject: [PATCH 09/11] Log: pacemaker-attrd: improve messages when
broadcasting local-only values
The traces aren't necessary since build_attribute_xml() already logs the same
info at debug. Also, rename function for clarity, and make static.
---
daemons/attrd/attrd_commands.c | 35 ++++++++++++++++-------------------
1 file changed, 16 insertions(+), 19 deletions(-)
diff --git a/daemons/attrd/attrd_commands.c b/daemons/attrd/attrd_commands.c
index 4783427..356defb 100644
--- a/daemons/attrd/attrd_commands.c
+++ b/daemons/attrd/attrd_commands.c
@@ -51,11 +51,12 @@ GHashTable *attributes = NULL;
void write_attribute(attribute_t *a, bool ignore_delay);
void write_or_elect_attribute(attribute_t *a);
-void attrd_current_only_attribute_update(crm_node_t *peer, xmlNode *xml);
void attrd_peer_update(crm_node_t *peer, xmlNode *xml, const char *host, bool filter);
void attrd_peer_sync(crm_node_t *peer, xmlNode *xml);
void attrd_peer_remove(const char *host, gboolean uncache, const char *source);
+static void broadcast_unseen_local_values(crm_node_t *peer, xmlNode *xml);
+
static gboolean
send_attrd_message(crm_node_t * node, xmlNode * data)
{
@@ -604,7 +605,7 @@ process_peer_sync_response(crm_node_t *peer, bool peer_won, xmlNode *xml)
/* If any attributes are still not marked as seen, the writer doesn't
* know about them, so send all peers an update with them.
*/
- attrd_current_only_attribute_update(peer, xml);
+ broadcast_unseen_local_values(peer, xml);
}
}
@@ -768,40 +769,36 @@ attrd_lookup_or_create_value(GHashTable *values, const char *host, xmlNode *xml)
return(v);
}
-void
-attrd_current_only_attribute_update(crm_node_t *peer, xmlNode *xml)
+void
+broadcast_unseen_local_values(crm_node_t *peer, xmlNode *xml)
{
GHashTableIter aIter;
GHashTableIter vIter;
- attribute_t *a;
+ attribute_t *a = NULL;
attribute_value_t *v = NULL;
- xmlNode *sync = create_xml_node(NULL, __func__);
- gboolean build = FALSE;
-
- crm_xml_add(sync, PCMK__XA_TASK, PCMK__ATTRD_CMD_SYNC_RESPONSE);
+ xmlNode *sync = NULL;
g_hash_table_iter_init(&aIter, attributes);
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)) {
- if (pcmk__str_eq(v->nodename, attrd_cluster->uname, pcmk__str_casei) && v->seen == FALSE) {
- crm_trace("Syncing %s[%s] = %s to everyone.(from local only attributes)", a->id, v->nodename, v->current);
-
- build = TRUE;
+ if (!(v->seen) && pcmk__str_eq(v->nodename, attrd_cluster->uname,
+ pcmk__str_casei)) {
+ if (sync == NULL) {
+ sync = create_xml_node(NULL, __func__);
+ crm_xml_add(sync, PCMK__XA_TASK, PCMK__ATTRD_CMD_SYNC_RESPONSE);
+ }
build_attribute_xml(sync, a->id, a->set, a->uuid, a->timeout_ms, a->user, a->is_private,
v->nodename, v->nodeid, v->current, (a->timeout_ms && a->timer ? TRUE : FALSE));
- } else {
- crm_trace("Local attribute(%s[%s] = %s) was ignore.(another host) : [%s]", a->id, v->nodename, v->current, attrd_cluster->uname);
- continue;
}
}
}
- if (build) {
- crm_debug("Syncing values to everyone.(from local only attributes)");
+ if (sync != NULL) {
+ crm_debug("Broadcasting local-only values");
send_attrd_message(NULL, sync);
+ free_xml(sync);
}
- free_xml(sync);
}
/*!
--
1.8.3.1
From ab90ffb785ea018556f216b8f540f8c3429a3947 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Fri, 11 Jun 2021 15:04:20 -0500
Subject: [PATCH 10/11] Refactor: pacemaker-attrd: simplify attribute XML
creation function
... and rename for clarity
---
daemons/attrd/attrd_commands.c | 48 ++++++++++++++++++++++++------------------
1 file changed, 27 insertions(+), 21 deletions(-)
diff --git a/daemons/attrd/attrd_commands.c b/daemons/attrd/attrd_commands.c
index 356defb..5b32a77 100644
--- a/daemons/attrd/attrd_commands.c
+++ b/daemons/attrd/attrd_commands.c
@@ -125,25 +125,35 @@ cache_remote_node(const char *node_name)
CRM_ASSERT(crm_remote_peer_get(node_name) != NULL);
}
+/*!
+ * \internal
+ * \brief Create an XML representation of an attribute for use in peer messages
+ *
+ * \param[in] parent Create attribute XML as child element of this element
+ * \param[in] a Attribute to represent
+ * \param[in] v Attribute value to represent
+ * \param[in] force_write If true, value should be written even if unchanged
+ *
+ * \return XML representation of attribute
+ */
static xmlNode *
-build_attribute_xml(
- xmlNode *parent, const char *name, const char *set, const char *uuid, unsigned int timeout_ms, const char *user,
- gboolean is_private, const char *peer, uint32_t peerid, const char *value, gboolean is_force_write)
+add_attribute_value_xml(xmlNode *parent, attribute_t *a, attribute_value_t *v,
+ bool force_write)
{
xmlNode *xml = create_xml_node(parent, __func__);
- crm_xml_add(xml, PCMK__XA_ATTR_NAME, name);
- crm_xml_add(xml, PCMK__XA_ATTR_SET, set);
- crm_xml_add(xml, PCMK__XA_ATTR_UUID, uuid);
- crm_xml_add(xml, PCMK__XA_ATTR_USER, user);
- crm_xml_add(xml, PCMK__XA_ATTR_NODE_NAME, peer);
- if (peerid > 0) {
- crm_xml_add_int(xml, PCMK__XA_ATTR_NODE_ID, peerid);
+ crm_xml_add(xml, PCMK__XA_ATTR_NAME, a->id);
+ crm_xml_add(xml, PCMK__XA_ATTR_SET, a->set);
+ crm_xml_add(xml, PCMK__XA_ATTR_UUID, a->uuid);
+ crm_xml_add(xml, PCMK__XA_ATTR_USER, a->user);
+ crm_xml_add(xml, PCMK__XA_ATTR_NODE_NAME, v->nodename);
+ if (v->nodeid > 0) {
+ crm_xml_add_int(xml, PCMK__XA_ATTR_NODE_ID, v->nodeid);
}
- crm_xml_add(xml, PCMK__XA_ATTR_VALUE, value);
- crm_xml_add_int(xml, PCMK__XA_ATTR_DAMPENING, timeout_ms/1000);
- crm_xml_add_int(xml, PCMK__XA_ATTR_IS_PRIVATE, is_private);
- crm_xml_add_int(xml, PCMK__XA_ATTR_FORCE, is_force_write);
+ crm_xml_add(xml, PCMK__XA_ATTR_VALUE, v->current);
+ crm_xml_add_int(xml, PCMK__XA_ATTR_DAMPENING, a->timeout_ms / 1000);
+ crm_xml_add_int(xml, PCMK__XA_ATTR_IS_PRIVATE, a->is_private);
+ crm_xml_add_int(xml, PCMK__XA_ATTR_FORCE, force_write);
return xml;
}
@@ -695,8 +705,7 @@ attrd_peer_sync(crm_node_t *peer, xmlNode *xml)
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");
- build_attribute_xml(sync, a->id, a->set, a->uuid, a->timeout_ms, a->user, a->is_private,
- v->nodename, v->nodeid, v->current, FALSE);
+ add_attribute_value_xml(sync, a, v, false);
}
}
@@ -788,8 +797,7 @@ broadcast_unseen_local_values(crm_node_t *peer, xmlNode *xml)
sync = create_xml_node(NULL, __func__);
crm_xml_add(sync, PCMK__XA_TASK, PCMK__ATTRD_CMD_SYNC_RESPONSE);
}
- build_attribute_xml(sync, a->id, a->set, a->uuid, a->timeout_ms, a->user, a->is_private,
- v->nodename, v->nodeid, v->current, (a->timeout_ms && a->timer ? TRUE : FALSE));
+ add_attribute_value_xml(sync, a, v, a->timeout_ms && a->timer);
}
}
}
@@ -820,9 +828,7 @@ broadcast_local_value(attribute_t *a)
xmlNode *sync = create_xml_node(NULL, __func__);
crm_xml_add(sync, PCMK__XA_TASK, PCMK__ATTRD_CMD_SYNC_RESPONSE);
- build_attribute_xml(sync, a->id, a->set, a->uuid, a->timeout_ms,
- a->user, a->is_private, v->nodename, v->nodeid,
- v->current, FALSE);
+ add_attribute_value_xml(sync, a, v, false);
attrd_xml_add_writer(sync);
send_attrd_message(NULL, sync);
free_xml(sync);
--
1.8.3.1
From 540d74130c5c8d9c626d6c50475e4dc4f64234e7 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Fri, 4 Jun 2021 16:34:26 -0500
Subject: [PATCH 11/11] Fix: pacemaker-attrd: avoid repeated unfencing of
remote nodes
The attribute manager can't record a remote node's attributes to the CIB until
it knows the node is remote. Normally, this is learned when the remote node
starts, because the controller clears the CRM_OP_PROBED attribute and indicates
that it is for a remote node.
However, if a cluster node is down when a remote node starts, and later comes
up, it learns the remote node's existing attributes as part of the attribute
sync. Previously, this did not include whether each value is for a cluster or
remote node, so the newly joined attribute manager couldn't write out remote
nodes' attributes until it learned that via some other event -- which might not
happen before the node becomes DC, in which case its scheduler will not see any
unfencing-related node attributes and may wrongly schedule unfencing.
The sync response handling already calls attrd_lookup_or_create_value(), which
checks PCMK__XA_ATTR_IS_REMOTE, so all we need to do is add that to the sync
response.
---
daemons/attrd/attrd_commands.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/daemons/attrd/attrd_commands.c b/daemons/attrd/attrd_commands.c
index 5b32a77..0142383 100644
--- a/daemons/attrd/attrd_commands.c
+++ b/daemons/attrd/attrd_commands.c
@@ -43,8 +43,9 @@
* 1 1.1.15 PCMK__ATTRD_CMD_UPDATE_BOTH,
* PCMK__ATTRD_CMD_UPDATE_DELAY
* 2 1.1.17 PCMK__ATTRD_CMD_CLEAR_FAILURE
+ * 3 2.1.1 PCMK__ATTRD_CMD_SYNC_RESPONSE indicates remote nodes
*/
-#define ATTRD_PROTOCOL_VERSION "2"
+#define ATTRD_PROTOCOL_VERSION "3"
int last_cib_op_done = 0;
GHashTable *attributes = NULL;
@@ -150,6 +151,9 @@ add_attribute_value_xml(xmlNode *parent, attribute_t *a, attribute_value_t *v,
if (v->nodeid > 0) {
crm_xml_add_int(xml, PCMK__XA_ATTR_NODE_ID, v->nodeid);
}
+ if (v->is_remote != 0) {
+ crm_xml_add_int(xml, PCMK__XA_ATTR_IS_REMOTE, 1);
+ }
crm_xml_add(xml, PCMK__XA_ATTR_VALUE, v->current);
crm_xml_add_int(xml, PCMK__XA_ATTR_DAMPENING, a->timeout_ms / 1000);
crm_xml_add_int(xml, PCMK__XA_ATTR_IS_PRIVATE, a->is_private);
--
1.8.3.1

Binary file not shown.

Binary file not shown.

1425
SPECS/pacemaker.spec Normal file

File diff suppressed because it is too large Load Diff