import pacemaker-2.1.0-8.el8

This commit is contained in:
CentOS Sources 2021-10-06 00:52:50 -04:00 committed by Stepan Oksanichenko
parent 513d314720
commit 59d3b0e629
62 changed files with 7773 additions and 62589 deletions

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
SOURCES/nagios-agents-metadata-105ab8a.tar.gz
SOURCES/pacemaker-ba59be7.tar.gz
SOURCES/pacemaker-7c3f660.tar.gz

View File

@ -1,2 +1,2 @@
ea6c0a27fd0ae8ce02f84a11f08a0d79377041c3 SOURCES/nagios-agents-metadata-105ab8a.tar.gz
268769bcd0d6c2ea2d50db92aaea0f31637775d0 SOURCES/pacemaker-ba59be7.tar.gz
17aa11e179c3f9eacbacac5735d7f5b14a1ac010 SOURCES/pacemaker-7c3f660.tar.gz

View File

@ -1,704 +0,0 @@
From d81282f1ac5e1226fbf6cfa1bd239d317e106def Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Tue, 13 Oct 2020 10:08:21 +0200
Subject: [PATCH 1/3] Feature: crmadmin: implement formatted output
---
include/crm/crm.h | 2 +-
tools/crmadmin.c | 312 ++++++++++++++++++++++++++++++++++++++++--------------
2 files changed, 232 insertions(+), 82 deletions(-)
diff --git a/include/crm/crm.h b/include/crm/crm.h
index 389b6aa..4eca278 100644
--- a/include/crm/crm.h
+++ b/include/crm/crm.h
@@ -51,7 +51,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.6.1"
+# define CRM_FEATURE_SET "3.6.2"
# define EOS '\0'
# define DIMOF(a) ((int) (sizeof(a)/sizeof(a[0])) )
diff --git a/tools/crmadmin.c b/tools/crmadmin.c
index 0b87d01..14078e6 100644
--- a/tools/crmadmin.c
+++ b/tools/crmadmin.c
@@ -20,6 +20,7 @@
#include <crm/cib.h>
#include <crm/msg_xml.h>
#include <crm/common/cmdline_internal.h>
+#include <crm/common/output_internal.h>
#include <crm/common/xml.h>
#include <crm/common/iso8601.h>
#include <crm/common/ipc_controld.h>
@@ -38,7 +39,6 @@ bool need_controld_api = true;
bool need_pacemakerd_api = false;
bool do_work(pcmk_ipc_api_t *api);
-void do_find_node_list(xmlNode *xml_node);
static char *ipc_name = NULL;
gboolean admin_message_timeout(gpointer data);
@@ -55,13 +55,12 @@ static enum {
static gboolean BE_VERBOSE = FALSE;
static gboolean BASH_EXPORT = FALSE;
-static gboolean BE_SILENT = FALSE;
static char *dest_node = NULL;
static crm_exit_t exit_code = CRM_EX_OK;
+pcmk__output_t *out = NULL;
struct {
- gboolean quiet;
gboolean health;
gint timeout;
} options;
@@ -168,6 +167,191 @@ command_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError
return TRUE;
}
+PCMK__OUTPUT_ARGS("health", "char *", "char *", "char *", "char *")
+static int
+health_text(pcmk__output_t *out, va_list args)
+{
+ char *sys_from = va_arg(args, char *);
+ char *host_from = va_arg(args, char *);
+ char *fsa_state = va_arg(args, char *);
+ char *result = va_arg(args, char *);
+
+ if (!out->is_quiet(out)) {
+ out->info(out, "Status of %s@%s: %s (%s)", crm_str(sys_from),
+ crm_str(host_from), crm_str(fsa_state), crm_str(result));
+ } else if (fsa_state != NULL) {
+ out->info(out, "%s", fsa_state);
+ }
+
+ return pcmk_rc_ok;
+}
+
+PCMK__OUTPUT_ARGS("health", "char *", "char *", "char *", "char *")
+static int
+health_xml(pcmk__output_t *out, va_list args)
+{
+ char *sys_from = va_arg(args, char *);
+ char *host_from = va_arg(args, char *);
+ char *fsa_state = va_arg(args, char *);
+ char *result = va_arg(args, char *);
+
+ xmlNodePtr node = pcmk__output_create_xml_node(out, crm_str(sys_from));
+ xmlSetProp(node, (pcmkXmlStr) "node_name", (pcmkXmlStr) crm_str(host_from));
+ xmlSetProp(node, (pcmkXmlStr) "state", (pcmkXmlStr) crm_str(fsa_state));
+ xmlSetProp(node, (pcmkXmlStr) "result", (pcmkXmlStr) crm_str(result));
+
+ return pcmk_rc_ok;
+}
+
+PCMK__OUTPUT_ARGS("pacemakerd-health", "char *", "char *", "char *")
+static int
+pacemakerd_health_text(pcmk__output_t *out, va_list args)
+{
+ char *sys_from = va_arg(args, char *);
+ char *state = va_arg(args, char *);
+ char *last_updated = va_arg(args, char *);
+
+ if (!out->is_quiet(out)) {
+ out->info(out, "Status of %s: '%s' %s %s", crm_str(sys_from),
+ crm_str(state), (!pcmk__str_empty(last_updated))?
+ "last updated":"", crm_str(last_updated));
+ } else {
+ out->info(out, "%s", crm_str(state));
+ }
+
+ return pcmk_rc_ok;
+}
+
+PCMK__OUTPUT_ARGS("pacemakerd-health", "char *", "char *", "char *")
+static int
+pacemakerd_health_xml(pcmk__output_t *out, va_list args)
+{
+ char *sys_from = va_arg(args, char *);
+ char *state = va_arg(args, char *);
+ char *last_updated = va_arg(args, char *);
+
+
+ xmlNodePtr node = pcmk__output_create_xml_node(out, crm_str(sys_from));
+ xmlSetProp(node, (pcmkXmlStr) "state", (pcmkXmlStr) crm_str(state));
+ xmlSetProp(node, (pcmkXmlStr) "last_updated", (pcmkXmlStr) crm_str(last_updated));
+
+ return pcmk_rc_ok;
+}
+
+PCMK__OUTPUT_ARGS("dc", "char *")
+static int
+dc_text(pcmk__output_t *out, va_list args)
+{
+ char *dc = va_arg(args, char *);
+
+ if (!out->is_quiet(out)) {
+ out->info(out, "Designated Controller is: %s", crm_str(dc));
+ } else if (dc != NULL) {
+ out->info(out, "%s", dc);
+ }
+
+ return pcmk_rc_ok;
+}
+
+PCMK__OUTPUT_ARGS("dc", "char *")
+static int
+dc_xml(pcmk__output_t *out, va_list args)
+{
+ char *dc = va_arg(args, char *);
+
+ xmlNodePtr node = pcmk__output_create_xml_node(out, "dc");
+ xmlSetProp(node, (pcmkXmlStr) "node_name", (pcmkXmlStr) crm_str(dc));
+
+ return pcmk_rc_ok;
+}
+
+
+PCMK__OUTPUT_ARGS("crmadmin-node-list", "xmlNode *")
+static int
+crmadmin_node_list(pcmk__output_t *out, va_list args)
+{
+ xmlNode *xml_node = va_arg(args, xmlNode *);
+ int found = 0;
+ xmlNode *node = NULL;
+ xmlNode *nodes = get_object_root(XML_CIB_TAG_NODES, xml_node);
+
+ out->begin_list(out, NULL, NULL, "Nodes");
+
+ for (node = first_named_child(nodes, XML_CIB_TAG_NODE); node != NULL;
+ node = crm_next_same_xml(node)) {
+ const char *node_type = BASH_EXPORT ? NULL :
+ crm_element_value(node, XML_ATTR_TYPE);
+ out->message(out, "crmadmin-node", node_type,
+ crm_str(crm_element_value(node, XML_ATTR_UNAME)),
+ crm_str(crm_element_value(node, XML_ATTR_ID)));
+
+ found++;
+ }
+ // @TODO List Pacemaker Remote nodes that don't have a <node> entry
+
+ out->end_list(out);
+
+ if (found == 0) {
+ out->info(out, "No nodes configured");
+ }
+
+ return pcmk_rc_ok;
+}
+
+PCMK__OUTPUT_ARGS("crmadmin-node", "char *", "char *", "char *")
+static int
+crmadmin_node_text(pcmk__output_t *out, va_list args)
+{
+ char *type = va_arg(args, char *);
+ char *name = va_arg(args, char *);
+ char *id = va_arg(args, char *);
+
+ if (BASH_EXPORT) {
+ out->info(out, "export %s=%s", crm_str(name), crm_str(id));
+ } else {
+ out->info(out, "%s node: %s (%s)", type ? type : "member",
+ crm_str(name), crm_str(id));
+ }
+
+ return pcmk_rc_ok;
+}
+
+PCMK__OUTPUT_ARGS("crmadmin-node", "char *", "char *", "char *")
+static int
+crmadmin_node_xml(pcmk__output_t *out, va_list args)
+{
+ char *type = va_arg(args, char *);
+ char *name = va_arg(args, char *);
+ char *id = va_arg(args, char *);
+
+ xmlNodePtr node = pcmk__output_create_xml_node(out, "crmadmin-node");
+ xmlSetProp(node, (pcmkXmlStr) "type", (pcmkXmlStr) (type ? type : "member"));
+ xmlSetProp(node, (pcmkXmlStr) "name", (pcmkXmlStr) crm_str(name));
+ xmlSetProp(node, (pcmkXmlStr) "id", (pcmkXmlStr) crm_str(id));
+
+ return pcmk_rc_ok;
+}
+
+static pcmk__message_entry_t fmt_functions[] = {
+ {"health", "default", health_text },
+ {"health", "xml", health_xml },
+ {"pacemakerd-health", "default", pacemakerd_health_text },
+ {"pacemakerd-health", "xml", pacemakerd_health_xml },
+ {"dc", "default", dc_text },
+ {"dc", "xml", dc_xml },
+ {"crmadmin-node-list", "default", crmadmin_node_list },
+ {"crmadmin-node", "default", crmadmin_node_text },
+ {"crmadmin-node", "xml", crmadmin_node_xml },
+
+ { NULL, NULL, NULL }
+};
+
+static pcmk__supported_format_t formats[] = {
+ PCMK__SUPPORTED_FORMAT_TEXT,
+ PCMK__SUPPORTED_FORMAT_XML,
+ { NULL, NULL, NULL }
+};
+
static void
quit_main_loop(crm_exit_t ec)
{
@@ -191,7 +375,7 @@ controller_event_cb(pcmk_ipc_api_t *controld_api,
switch (event_type) {
case pcmk_ipc_event_disconnect:
if (exit_code == CRM_EX_DISCONNECT) { // Unexpected
- fprintf(stderr, "error: Lost connection to controller\n");
+ out->err(out, "error: Lost connection to controller");
}
goto done;
break;
@@ -209,14 +393,14 @@ controller_event_cb(pcmk_ipc_api_t *controld_api,
}
if (status != CRM_EX_OK) {
- fprintf(stderr, "error: Bad reply from controller: %s",
+ out->err(out, "error: Bad reply from controller: %s",
crm_exit_str(status));
exit_code = status;
goto done;
}
if (reply->reply_type != pcmk_controld_reply_ping) {
- fprintf(stderr, "error: Unknown reply type %d from controller\n",
+ out->err(out, "error: Unknown reply type %d from controller",
reply->reply_type);
goto done;
}
@@ -224,22 +408,16 @@ controller_event_cb(pcmk_ipc_api_t *controld_api,
// Parse desired information from reply
switch (command) {
case cmd_health:
- printf("Status of %s@%s: %s (%s)\n",
+ out->message(out, "health",
reply->data.ping.sys_from,
reply->host_from,
reply->data.ping.fsa_state,
reply->data.ping.result);
- if (BE_SILENT && (reply->data.ping.fsa_state != NULL)) {
- fprintf(stderr, "%s\n", reply->data.ping.fsa_state);
- }
exit_code = CRM_EX_OK;
break;
case cmd_whois_dc:
- printf("Designated Controller is: %s\n", reply->host_from);
- if (BE_SILENT && (reply->host_from != NULL)) {
- fprintf(stderr, "%s\n", reply->host_from);
- }
+ out->message(out, "dc", reply->host_from);
exit_code = CRM_EX_OK;
break;
@@ -263,7 +441,7 @@ pacemakerd_event_cb(pcmk_ipc_api_t *pacemakerd_api,
switch (event_type) {
case pcmk_ipc_event_disconnect:
if (exit_code == CRM_EX_DISCONNECT) { // Unexpected
- fprintf(stderr, "error: Lost connection to pacemakerd\n");
+ out->err(out, "error: Lost connection to pacemakerd");
}
goto done;
break;
@@ -281,14 +459,14 @@ pacemakerd_event_cb(pcmk_ipc_api_t *pacemakerd_api,
}
if (status != CRM_EX_OK) {
- fprintf(stderr, "error: Bad reply from pacemakerd: %s",
+ out->err(out, "error: Bad reply from pacemakerd: %s",
crm_exit_str(status));
exit_code = status;
goto done;
}
if (reply->reply_type != pcmk_pacemakerd_reply_ping) {
- fprintf(stderr, "error: Unknown reply type %d from pacemakerd\n",
+ out->err(out, "error: Unknown reply type %d from pacemakerd",
reply->reply_type);
goto done;
}
@@ -305,21 +483,12 @@ pacemakerd_event_cb(pcmk_ipc_api_t *pacemakerd_api,
crm_time_log_date | crm_time_log_timeofday |
crm_time_log_with_timezone);
- printf("Status of %s: '%s' %s %s\n",
+ out->message(out, "pacemakerd-health",
reply->data.ping.sys_from,
(reply->data.ping.status == pcmk_rc_ok)?
pcmk_pacemakerd_api_daemon_state_enum2text(
reply->data.ping.state):"query failed",
- (reply->data.ping.status == pcmk_rc_ok)?"last updated":"",
(reply->data.ping.status == pcmk_rc_ok)?pinged_buf:"");
- if (BE_SILENT &&
- (reply->data.ping.state != pcmk_pacemakerd_state_invalid)) {
- fprintf(stderr, "%s\n",
- (reply->data.ping.status == pcmk_rc_ok)?
- pcmk_pacemakerd_api_daemon_state_enum2text(
- reply->data.ping.state):
- "query failed");
- }
exit_code = CRM_EX_OK;
free(pinged_buf);
}
@@ -354,7 +523,7 @@ list_nodes()
rc = the_cib->cmds->query(the_cib, NULL, &output,
cib_scope_local | cib_sync_call);
if (rc == pcmk_ok) {
- do_find_node_list(output);
+ out->message(out, "crmadmin-node-list", output);
free_xml(output);
}
the_cib->cmds->signoff(the_cib);
@@ -362,20 +531,20 @@ list_nodes()
}
static GOptionContext *
-build_arg_context(pcmk__common_args_t *args) {
+build_arg_context(pcmk__common_args_t *args, GOptionGroup **group) {
GOptionContext *context = NULL;
const char *description = "Report bugs to users@clusterlabs.org";
GOptionEntry extra_prog_entries[] = {
- { "quiet", 'q', 0, G_OPTION_ARG_NONE, &options.quiet,
+ { "quiet", 'q', 0, G_OPTION_ARG_NONE, &(args->quiet),
"Display only the essential query information",
NULL },
{ NULL }
};
- context = pcmk__build_arg_context(args, NULL, NULL, NULL);
+ context = pcmk__build_arg_context(args, "text (default), xml", group, NULL);
g_option_context_set_description(context, description);
/* Add the -q option, which cannot be part of the globally supported options
@@ -402,9 +571,11 @@ main(int argc, char **argv)
GError *error = NULL;
GOptionContext *context = NULL;
+ GOptionGroup *output_group = NULL;
gchar **processed_args = NULL;
- context = build_arg_context(args);
+ context = build_arg_context(args, &output_group);
+ pcmk__register_formats(output_group, formats);
crm_log_cli_init("crmadmin");
@@ -421,9 +592,21 @@ main(int argc, char **argv)
crm_bump_log_level(argc, argv);
}
+ rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
+ if (rc != pcmk_rc_ok) {
+ fprintf(stderr, "Error creating output format %s: %s\n",
+ args->output_ty, pcmk_rc_str(rc));
+ exit_code = CRM_EX_ERROR;
+ goto done;
+ }
+
+ out->quiet = args->quiet;
+
+ pcmk__register_messages(out, fmt_functions);
+
if (args->version) {
- /* FIXME: When crmadmin is converted to use formatted output, this can go. */
- pcmk__cli_help('v', CRM_EX_USAGE);
+ out->version(out, false);
+ goto done;
}
if (options.timeout) {
@@ -433,12 +616,8 @@ main(int argc, char **argv)
}
}
- if (options.quiet) {
- BE_SILENT = TRUE;
- }
-
if (options.health) {
- fprintf(stderr, "Cluster-wide health option not supported\n");
+ out->err(out, "Cluster-wide health option not supported");
++argerr;
}
@@ -447,14 +626,14 @@ main(int argc, char **argv)
}
if (command == cmd_none) {
- fprintf(stderr, "error: Must specify a command option\n\n");
+ out->err(out, "error: Must specify a command option");
++argerr;
}
if (argerr) {
char *help = g_option_context_get_help(context, TRUE, NULL);
- fprintf(stderr, "%s", help);
+ out->err(out, "%s", help);
g_free(help);
exit_code = CRM_EX_USAGE;
goto done;
@@ -464,7 +643,7 @@ main(int argc, char **argv)
if (need_controld_api) {
rc = pcmk_new_ipc_api(&controld_api, pcmk_ipc_controld);
if (controld_api == NULL) {
- fprintf(stderr, "error: Could not connect to controller: %s\n",
+ out->err(out, "error: Could not connect to controller: %s",
pcmk_rc_str(rc));
exit_code = pcmk_rc2exitc(rc);
goto done;
@@ -472,7 +651,7 @@ main(int argc, char **argv)
pcmk_register_ipc_callback(controld_api, controller_event_cb, NULL);
rc = pcmk_connect_ipc(controld_api, pcmk_ipc_dispatch_main);
if (rc != pcmk_rc_ok) {
- fprintf(stderr, "error: Could not connect to controller: %s\n",
+ out->err(out, "error: Could not connect to controller: %s",
pcmk_rc_str(rc));
exit_code = pcmk_rc2exitc(rc);
goto done;
@@ -483,7 +662,7 @@ main(int argc, char **argv)
if (need_pacemakerd_api) {
rc = pcmk_new_ipc_api(&pacemakerd_api, pcmk_ipc_pacemakerd);
if (pacemakerd_api == NULL) {
- fprintf(stderr, "error: Could not connect to pacemakerd: %s\n",
+ out->err(out, "error: Could not connect to pacemakerd: %s",
pcmk_rc_str(rc));
exit_code = pcmk_rc2exitc(rc);
goto done;
@@ -491,7 +670,7 @@ main(int argc, char **argv)
pcmk_register_ipc_callback(pacemakerd_api, pacemakerd_event_cb, NULL);
rc = pcmk_connect_ipc(pacemakerd_api, pcmk_ipc_dispatch_main);
if (rc != pcmk_rc_ok) {
- fprintf(stderr, "error: Could not connect to pacemakerd: %s\n",
+ out->err(out, "error: Could not connect to pacemakerd: %s",
pcmk_rc_str(rc));
exit_code = pcmk_rc2exitc(rc);
goto done;
@@ -528,6 +707,10 @@ done:
g_strfreev(processed_args);
g_clear_error(&error);
pcmk__free_arg_context(context);
+ if (out != NULL) {
+ out->finish(out, exit_code, true, NULL);
+ pcmk__output_free(out);
+ }
return crm_exit(exit_code);
}
@@ -567,7 +750,7 @@ do_work(pcmk_ipc_api_t *api)
break;
}
if (rc != pcmk_rc_ok) {
- fprintf(stderr, "error: Command failed: %s", pcmk_rc_str(rc));
+ out->err(out, "error: Command failed: %s", pcmk_rc_str(rc));
exit_code = pcmk_rc2exitc(rc);
}
return need_reply;
@@ -576,43 +759,10 @@ do_work(pcmk_ipc_api_t *api)
gboolean
admin_message_timeout(gpointer data)
{
- fprintf(stderr,
- "error: No reply received from controller before timeout (%dms)\n",
+ out->err(out,
+ "error: No reply received from controller before timeout (%dms)",
message_timeout_ms);
message_timer_id = 0;
quit_main_loop(CRM_EX_TIMEOUT);
return FALSE; // Tells glib to remove source
}
-
-void
-do_find_node_list(xmlNode * xml_node)
-{
- int found = 0;
- xmlNode *node = NULL;
- xmlNode *nodes = get_object_root(XML_CIB_TAG_NODES, xml_node);
-
- for (node = first_named_child(nodes, XML_CIB_TAG_NODE); node != NULL;
- node = crm_next_same_xml(node)) {
-
- if (BASH_EXPORT) {
- printf("export %s=%s\n",
- crm_element_value(node, XML_ATTR_UNAME),
- crm_element_value(node, XML_ATTR_ID));
- } else {
- const char *node_type = crm_element_value(node, XML_ATTR_TYPE);
-
- if (node_type == NULL) {
- node_type = "member";
- }
- printf("%s node: %s (%s)\n", node_type,
- crm_element_value(node, XML_ATTR_UNAME),
- crm_element_value(node, XML_ATTR_ID));
- }
- found++;
- }
- // @TODO List Pacemaker Remote nodes that don't have a <node> entry
-
- if (found == 0) {
- printf("No nodes configured\n");
- }
-}
--
1.8.3.1
From 2b121066c8eead96e85dc3bf6ecc1c2674cbdf32 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Tue, 20 Oct 2020 16:19:03 +0200
Subject: [PATCH 2/3] Refactor: crmadmin: use simple XML lists
---
tools/crmadmin.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/tools/crmadmin.c b/tools/crmadmin.c
index 14078e6..b80a31a 100644
--- a/tools/crmadmin.c
+++ b/tools/crmadmin.c
@@ -275,7 +275,7 @@ crmadmin_node_list(pcmk__output_t *out, va_list args)
xmlNode *node = NULL;
xmlNode *nodes = get_object_root(XML_CIB_TAG_NODES, xml_node);
- out->begin_list(out, NULL, NULL, "Nodes");
+ out->begin_list(out, NULL, NULL, "nodes");
for (node = first_named_child(nodes, XML_CIB_TAG_NODE); node != NULL;
node = crm_next_same_xml(node)) {
@@ -324,7 +324,7 @@ crmadmin_node_xml(pcmk__output_t *out, va_list args)
char *name = va_arg(args, char *);
char *id = va_arg(args, char *);
- xmlNodePtr node = pcmk__output_create_xml_node(out, "crmadmin-node");
+ xmlNodePtr node = pcmk__output_create_xml_node(out, "node");
xmlSetProp(node, (pcmkXmlStr) "type", (pcmkXmlStr) (type ? type : "member"));
xmlSetProp(node, (pcmkXmlStr) "name", (pcmkXmlStr) crm_str(name));
xmlSetProp(node, (pcmkXmlStr) "id", (pcmkXmlStr) crm_str(id));
@@ -604,6 +604,10 @@ main(int argc, char **argv)
pcmk__register_messages(out, fmt_functions);
+ if (!pcmk__force_args(context, &error, "%s --xml-simple-list --xml-substitute", g_get_prgname())) {
+ goto done;
+ }
+
if (args->version) {
out->version(out, false);
goto done;
--
1.8.3.1
From 9b53a7eda078db736be5212aeb77daf8117e2f17 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Tue, 20 Oct 2020 16:21:12 +0200
Subject: [PATCH 3/3] Feature: xml: add schema for new crmadmin output
---
xml/Makefile.am | 2 +-
xml/api/crmadmin-2.4.rng | 68 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 69 insertions(+), 1 deletion(-)
create mode 100644 xml/api/crmadmin-2.4.rng
diff --git a/xml/Makefile.am b/xml/Makefile.am
index c045522..892c811 100644
--- a/xml/Makefile.am
+++ b/xml/Makefile.am
@@ -45,7 +45,7 @@ version_pairs_last = $(wordlist \
)
# Names of API schemas that form the choices for pacemaker-result content
-API_request_base = command-output crm_mon stonith_admin version
+API_request_base = command-output crm_mon crmadmin stonith_admin version
# Names of CIB schemas that form the choices for cib/configuration content
CIB_cfg_base = options nodes resources constraints fencing acls tags alerts
diff --git a/xml/api/crmadmin-2.4.rng b/xml/api/crmadmin-2.4.rng
new file mode 100644
index 0000000..34c9ca4
--- /dev/null
+++ b/xml/api/crmadmin-2.4.rng
@@ -0,0 +1,68 @@
+<?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-crmadmin"/>
+ </start>
+
+ <define name="element-crmadmin">
+ <optional>
+ <ref name="element-status" />
+ </optional>
+ <optional>
+ <ref name="element-pacemakerd" />
+ </optional>
+ <optional>
+ <ref name="element-dc" />
+ </optional>
+ <optional>
+ <ref name="crmadmin-nodes-list" />
+ </optional>
+ </define>
+
+ <define name="element-status">
+ <element name="crmd">
+ <attribute name="node_name"> <text /> </attribute>
+ <attribute name="state"> <text /> </attribute>
+ <attribute name="result"> <text /> </attribute>
+ </element>
+ </define>
+
+ <define name="element-pacemakerd">
+ <element name="pacemakerd">
+ <attribute name="state"> <text /> </attribute>
+ <attribute name="last_updated"> <text /> </attribute>
+ </element>
+ </define>
+
+ <define name="element-dc">
+ <element name="dc">
+ <attribute name="node_name"> <text /> </attribute>
+ </element>
+ </define>
+
+ <define name="crmadmin-nodes-list">
+ <element name="nodes">
+ <zeroOrMore>
+ <ref name="element-crmadmin-node" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="element-crmadmin-node">
+ <element name="node">
+ <attribute name="type">
+ <choice>
+ <value>unknown</value>
+ <value>member</value>
+ <value>remote</value>
+ <value>ping</value>
+ </choice>
+ </attribute>
+
+ <attribute name="name"> <text/> </attribute>
+ <attribute name="id"> <text/> </attribute>
+ </element>
+ </define>
+</grammar>
--
1.8.3.1

View File

@ -0,0 +1,225 @@
From c6ee0973522268ed7b3241cf0ec2e06398444114 Mon Sep 17 00:00:00 2001
From: Grace Chin <gchin@redhat.com>
Date: Tue, 4 May 2021 12:02:17 -0400
Subject: [PATCH 1/4] Remove deprecated attrd_options
---
extra/resources/ping | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/extra/resources/ping b/extra/resources/ping
index 3cf8dfe..2e93f22 100755
--- a/extra/resources/ping
+++ b/extra/resources/ping
@@ -178,7 +178,7 @@ ping_stop() {
rm -f "${OCF_RESKEY_pidfile}"
- attrd_updater -D -n "$OCF_RESKEY_name" -d "$OCF_RESKEY_dampen" $attrd_options
+ attrd_updater -D -n "$OCF_RESKEY_name" -d "$OCF_RESKEY_dampen"
return $OCF_SUCCESS
}
@@ -302,9 +302,9 @@ ping_update() {
score=$(expr $active \* $OCF_RESKEY_multiplier)
if [ "$__OCF_ACTION" = "start" ] ; then
- attrd_updater -n "$OCF_RESKEY_name" -B "$score" -d "$OCF_RESKEY_dampen" $attrd_options
+ attrd_updater -n "$OCF_RESKEY_name" -B "$score" -d "$OCF_RESKEY_dampen"
else
- attrd_updater -n "$OCF_RESKEY_name" -v "$score" -d "$OCF_RESKEY_dampen" $attrd_options
+ attrd_updater -n "$OCF_RESKEY_name" -v "$score" -d "$OCF_RESKEY_dampen"
fi
rc=$?
case $rc in
@@ -396,11 +396,6 @@ case "${OCF_RESKEY_debug}" in
;;
esac
-attrd_options='-q'
-if [ "${OCF_RESKEY_debug}" = "true" ]; then
- attrd_options=''
-fi
-
case "$__OCF_ACTION" in
meta-data) meta_data
exit $OCF_SUCCESS
--
1.8.3.1
From 6d6c4691cf0970059689856c354daf9e098b4451 Mon Sep 17 00:00:00 2001
From: Grace Chin <gchin@redhat.com>
Date: Tue, 4 May 2021 14:50:37 -0400
Subject: [PATCH 2/4] Replace debug values, true and false, with 0 and 1
---
extra/resources/ping | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/extra/resources/ping b/extra/resources/ping
index 2e93f22..fee019b 100755
--- a/extra/resources/ping
+++ b/extra/resources/ping
@@ -24,7 +24,7 @@
: ${OCF_RESKEY_dampen:="5s"}
: ${OCF_RESKEY_attempts:="3"}
: ${OCF_RESKEY_multiplier:="1"}
-: ${OCF_RESKEY_debug:="false"}
+: ${OCF_RESKEY_debug:="0"}
: ${OCF_RESKEY_failure_score:="0"}
: ${OCF_RESKEY_use_fping:="1"}
: ${OCF_RESKEY_host_list:=""}
@@ -152,7 +152,7 @@ END
ping_conditional_log() {
level="$1"; shift
- if [ "${OCF_RESKEY_debug}" = "true" ]; then
+ if [ $OCF_RESKEY_debug -gt 0 ]; then
ocf_log "$level" "$*"
fi
}
@@ -388,8 +388,8 @@ fi
# Check the debug option
case "${OCF_RESKEY_debug}" in
- true|True|TRUE|1) OCF_RESKEY_debug=true;;
- false|False|FALSE|0) OCF_RESKEY_debug=false;;
+ true|True|TRUE|1) OCF_RESKEY_debug=0;;
+ false|False|FALSE|0) OCF_RESKEY_debug=1;;
*)
ocf_log warn "Value for 'debug' is incorrect. Please specify 'true' or 'false' not: ${OCF_RESKEY_debug}"
OCF_RESKEY_debug=false
--
1.8.3.1
From a886a31056b6aca764c6911f5432af2c5ebf51df Mon Sep 17 00:00:00 2001
From: Grace Chin <gchin@redhat.com>
Date: Tue, 11 May 2021 11:04:50 -0400
Subject: [PATCH 3/4] Add verbose debug mode which logs ping and fping output
when set
---
extra/resources/ping | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/extra/resources/ping b/extra/resources/ping
index fee019b..cc796af 100755
--- a/extra/resources/ping
+++ b/extra/resources/ping
@@ -249,10 +249,13 @@ fping_check() {
case $rc in
0)
+ if [ $OCF_RESKEY_debug -gt 1 ]; then
+ ping_conditional_log info "$output"
+ fi
;;
1)
for h in $(echo "$output" | grep "is unreachable" | awk '{print $1}'); do
- ping_conditional_log warn "$h is inactive"
+ ping_conditional_log warn "$h is inactive: $output"
done
;;
*)
@@ -282,7 +285,12 @@ ping_check() {
p_out=$($p_exe $p_args $OCF_RESKEY_options $host 2>&1); rc=$?
case $rc in
- 0) active=$(expr $active + 1);;
+ 0)
+ active=$(expr $active + 1)
+ if [ $OCF_RESKEY_debug -gt 1 ]; then
+ ping_conditional_log info "$p_out"
+ fi
+ ;;
1) ping_conditional_log warn "$host is inactive: $p_out";;
*) ocf_log err "Unexpected result for '$p_exe $p_args $OCF_RESKEY_options $host' $rc: $p_out";;
esac
@@ -388,10 +396,11 @@ fi
# Check the debug option
case "${OCF_RESKEY_debug}" in
- true|True|TRUE|1) OCF_RESKEY_debug=0;;
- false|False|FALSE|0) OCF_RESKEY_debug=1;;
+ true|True|TRUE|1) OCF_RESKEY_debug=1;;
+ false|False|FALSE|0) OCF_RESKEY_debug=0;;
+ verbose|Verbose|VERBOSE|2) OCF_RESKEY_debug=2;;
*)
- ocf_log warn "Value for 'debug' is incorrect. Please specify 'true' or 'false' not: ${OCF_RESKEY_debug}"
+ ocf_log warn "Value for 'debug' is incorrect. Please specify 'true', 'false', or 'verbose', not: ${OCF_RESKEY_debug}"
OCF_RESKEY_debug=false
;;
esac
--
1.8.3.1
From 460043f133ced80e923b1290af70502a72deb7f8 Mon Sep 17 00:00:00 2001
From: Grace Chin <gchin@redhat.com>
Date: Tue, 11 May 2021 11:07:05 -0400
Subject: [PATCH 4/4] Improve variable names
---
extra/resources/ping | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/extra/resources/ping b/extra/resources/ping
index cc796af..9763b60 100755
--- a/extra/resources/ping
+++ b/extra/resources/ping
@@ -244,22 +244,22 @@ fping_check() {
timeout=$(expr $OCF_RESKEY_timeout \* 1000 / $OCF_RESKEY_attempts)
cmd="$p_exe -r $OCF_RESKEY_attempts -t $timeout -B 1.0 $OCF_RESKEY_options $OCF_RESKEY_host_list"
- output=$($cmd 2>&1); rc=$?
- active=$(echo "$output" | grep "is alive" | wc -l)
+ fping_output=$($cmd 2>&1); rc=$?
+ active=$(echo "$fping_output" | grep "is alive" | wc -l)
case $rc in
0)
if [ $OCF_RESKEY_debug -gt 1 ]; then
- ping_conditional_log info "$output"
+ ping_conditional_log info "$fping_output"
fi
;;
1)
- for h in $(echo "$output" | grep "is unreachable" | awk '{print $1}'); do
- ping_conditional_log warn "$h is inactive: $output"
+ for h in $(echo "$fping_output" | grep "is unreachable" | awk '{print $1}'); do
+ ping_conditional_log warn "$h is inactive: $fping_output"
done
;;
*)
- ocf_log err "Unexpected result for '$cmd' $rc: $(echo "$output" | tr '\n' ';')"
+ ocf_log err "Unexpected result for '$cmd' $rc: $(echo "$fping_output" | tr '\n' ';')"
;;
esac
@@ -282,17 +282,17 @@ ping_check() {
*:*) p_exe=ping6
esac
- p_out=$($p_exe $p_args $OCF_RESKEY_options $host 2>&1); rc=$?
+ ping_output=$($p_exe $p_args $OCF_RESKEY_options $host 2>&1); rc=$?
case $rc in
0)
active=$(expr $active + 1)
if [ $OCF_RESKEY_debug -gt 1 ]; then
- ping_conditional_log info "$p_out"
+ ping_conditional_log info "$ping_output"
fi
;;
- 1) ping_conditional_log warn "$host is inactive: $p_out";;
- *) ocf_log err "Unexpected result for '$p_exe $p_args $OCF_RESKEY_options $host' $rc: $p_out";;
+ 1) ping_conditional_log warn "$host is inactive: $ping_output";;
+ *) ocf_log err "Unexpected result for '$p_exe $p_args $OCF_RESKEY_options $host' $rc: $ping_output";;
esac
done
return $active
--
1.8.3.1

View File

@ -1,165 +0,0 @@
From 12e59f337f838d647deb8f84850324f785e58824 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Tue, 20 Oct 2020 10:53:26 -0400
Subject: [PATCH] Feature: libcrmcommon: Add a spacer formatted output message.
---
include/crm/common/output_internal.h | 10 +++++++++-
lib/common/output_html.c | 6 ++++++
lib/common/output_log.c | 6 ++++++
lib/common/output_text.c | 6 ++++++
lib/common/output_xml.c | 6 ++++++
tools/crm_mon_curses.c | 6 ++++++
6 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/include/crm/common/output_internal.h b/include/crm/common/output_internal.h
index 2874259..e1bd295 100644
--- a/include/crm/common/output_internal.h
+++ b/include/crm/common/output_internal.h
@@ -460,6 +460,14 @@ struct pcmk__output_s {
* \return true if output should be supressed, false otherwise.
*/
bool (*is_quiet) (pcmk__output_t *out);
+
+ /*!
+ * \internal
+ * \brief Output a spacer. Not all formatter will do this.
+ *
+ * \param[in] out The output functions structure.
+ */
+ void (*spacer) (pcmk__output_t *out);
};
/*!
@@ -745,7 +753,7 @@ G_GNUC_NULL_TERMINATED;
#define PCMK__OUTPUT_SPACER_IF(out_obj, cond) \
if (cond) { \
- out_obj->info(out_obj, "%s", ""); \
+ out->spacer(out); \
}
#define PCMK__OUTPUT_LIST_HEADER(out_obj, cond, retcode, title...) \
diff --git a/lib/common/output_html.c b/lib/common/output_html.c
index 156887d..e354b5d 100644
--- a/lib/common/output_html.c
+++ b/lib/common/output_html.c
@@ -368,6 +368,11 @@ html_is_quiet(pcmk__output_t *out) {
return false;
}
+static void
+html_spacer(pcmk__output_t *out) {
+ pcmk__output_create_xml_node(out, "br");
+}
+
pcmk__output_t *
pcmk__mk_html_output(char **argv) {
pcmk__output_t *retval = calloc(1, sizeof(pcmk__output_t));
@@ -399,6 +404,7 @@ pcmk__mk_html_output(char **argv) {
retval->end_list = html_end_list;
retval->is_quiet = html_is_quiet;
+ retval->spacer = html_spacer;
return retval;
}
diff --git a/lib/common/output_log.c b/lib/common/output_log.c
index fd13c89..6336fa2 100644
--- a/lib/common/output_log.c
+++ b/lib/common/output_log.c
@@ -226,6 +226,11 @@ log_is_quiet(pcmk__output_t *out) {
return false;
}
+static void
+log_spacer(pcmk__output_t *out) {
+ /* This function intentionally left blank */
+}
+
pcmk__output_t *
pcmk__mk_log_output(char **argv) {
pcmk__output_t *retval = calloc(1, sizeof(pcmk__output_t));
@@ -256,6 +261,7 @@ pcmk__mk_log_output(char **argv) {
retval->end_list = log_end_list;
retval->is_quiet = log_is_quiet;
+ retval->spacer = log_spacer;
return retval;
}
diff --git a/lib/common/output_text.c b/lib/common/output_text.c
index 9b3c09a..3432505 100644
--- a/lib/common/output_text.c
+++ b/lib/common/output_text.c
@@ -244,6 +244,11 @@ text_is_quiet(pcmk__output_t *out) {
return out->quiet;
}
+static void
+text_spacer(pcmk__output_t *out) {
+ fprintf(out->dest, "\n");
+}
+
pcmk__output_t *
pcmk__mk_text_output(char **argv) {
pcmk__output_t *retval = calloc(1, sizeof(pcmk__output_t));
@@ -275,6 +280,7 @@ pcmk__mk_text_output(char **argv) {
retval->end_list = text_end_list;
retval->is_quiet = text_is_quiet;
+ retval->spacer = text_spacer;
return retval;
}
diff --git a/lib/common/output_xml.c b/lib/common/output_xml.c
index 9a08d20..1710fac 100644
--- a/lib/common/output_xml.c
+++ b/lib/common/output_xml.c
@@ -376,6 +376,11 @@ xml_is_quiet(pcmk__output_t *out) {
return false;
}
+static void
+xml_spacer(pcmk__output_t *out) {
+ /* This function intentionally left blank */
+}
+
pcmk__output_t *
pcmk__mk_xml_output(char **argv) {
pcmk__output_t *retval = calloc(1, sizeof(pcmk__output_t));
@@ -407,6 +412,7 @@ pcmk__mk_xml_output(char **argv) {
retval->end_list = xml_end_list;
retval->is_quiet = xml_is_quiet;
+ retval->spacer = xml_spacer;
return retval;
}
diff --git a/tools/crm_mon_curses.c b/tools/crm_mon_curses.c
index 2c092df..8a08578 100644
--- a/tools/crm_mon_curses.c
+++ b/tools/crm_mon_curses.c
@@ -247,6 +247,11 @@ curses_is_quiet(pcmk__output_t *out) {
return out->quiet;
}
+static void
+curses_spacer(pcmk__output_t *out) {
+ addch('\n');
+}
+
pcmk__output_t *
crm_mon_mk_curses_output(char **argv) {
pcmk__output_t *retval = calloc(1, sizeof(pcmk__output_t));
@@ -278,6 +283,7 @@ crm_mon_mk_curses_output(char **argv) {
retval->end_list = curses_end_list;
retval->is_quiet = curses_is_quiet;
+ retval->spacer = curses_spacer;
return retval;
}
--
1.8.3.1

View File

@ -0,0 +1,451 @@
From 0d40ebf10b1794ece2c5c9768ea7222d3834d3b3 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Thu, 13 May 2021 11:42:18 -0400
Subject: [PATCH 1/4] Build: Use a different variable to find man page
includes.
With other programs outside of the tools directory being converted to
use glib for command line handling, their includes are not going to be
in tools/. So we need to use a different autoconf variable to find
them.
---
mk/common.mk | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/mk/common.mk b/mk/common.mk
index b247670..aa59feb 100644
--- a/mk/common.mk
+++ b/mk/common.mk
@@ -1,5 +1,5 @@
#
-# Copyright 2014-2020 the Pacemaker project contributors
+# Copyright 2014-2021 the Pacemaker project contributors
#
# The version control history for this file may have further details.
#
@@ -68,11 +68,11 @@ HELP2MAN_ARGS = -N --section 8 --name "Part of the Pacemaker cluster resource ma
# and all wrappers to C code.
%.8: % $(MAN8DEPS)
$(AM_V_at)chmod a+x $(abs_builddir)/$<
- $(AM_V_MAN)if [ -f $(top_srcdir)/tools/$@.inc ]; then \
+ $(AM_V_MAN)if [ -f $(abs_srcdir)/$@.inc ]; then \
PATH=$(abs_builddir):$$PATH $(HELP2MAN) $(HELP2MAN_ARGS) \
-h --help-all \
--no-discard-stderr \
- -i $(top_srcdir)/tools/$@.inc $(abs_builddir)/$< \
+ -i $(abs_srcdir)/$@.inc $(abs_builddir)/$< \
| sed -f $(top_srcdir)/tools/fix-manpages > $@ ; \
else \
PATH=$(abs_builddir):$$PATH $(HELP2MAN) $(HELP2MAN_ARGS) \
--
1.8.3.1
From c7ab1d901bcbbf0137277e783e072777ca2f82d9 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Thu, 13 May 2021 11:44:16 -0400
Subject: [PATCH 2/4] Refactor: daemons: Remove the pid_file variable from
pacemakerd.
It's never used anywhere.
---
daemons/pacemakerd/pacemakerd.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/daemons/pacemakerd/pacemakerd.c b/daemons/pacemakerd/pacemakerd.c
index 8ec9708..03d688e 100644
--- a/daemons/pacemakerd/pacemakerd.c
+++ b/daemons/pacemakerd/pacemakerd.c
@@ -27,8 +27,7 @@
static crm_trigger_t *shutdown_trigger = NULL;
static crm_trigger_t *startup_trigger = NULL;
-static const char *pid_file = PCMK_RUN_DIR "/pacemaker.pid";
/* state we report when asked via pacemakerd-api status-ping */
static const char *pacemakerd_state = XML_PING_ATTR_PACEMAKERDSTATE_INIT;
static gboolean running_with_sbd = FALSE; /* local copy */
@@ -224,7 +222,6 @@ main(int argc, char **argv)
/* Legacy */
break;
case 'p':
- pid_file = optarg;
break;
case 's':
pcmk__set_env_option("node_start_state", "standby");
--
1.8.3.1
From 98990eed9f6a5dbde7c8a5aa0783e93d5479295b Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Thu, 13 May 2021 13:14:38 -0400
Subject: [PATCH 3/4] Refactor: daemons: Use glib for command line handling in
pacemakerd.
---
daemons/pacemakerd/Makefile.am | 2 +
daemons/pacemakerd/pacemakerd.8.inc | 5 +
daemons/pacemakerd/pacemakerd.c | 195 ++++++++++++++++++------------------
3 files changed, 102 insertions(+), 100 deletions(-)
create mode 100644 daemons/pacemakerd/pacemakerd.8.inc
diff --git a/daemons/pacemakerd/Makefile.am b/daemons/pacemakerd/Makefile.am
index cc657f5..84517a3 100644
--- a/daemons/pacemakerd/Makefile.am
+++ b/daemons/pacemakerd/Makefile.am
@@ -15,6 +15,8 @@ if BUILD_SYSTEMD
systemdsystemunit_DATA = pacemaker.service
endif
+EXTRA_DIST = pacemakerd.8.inc
+
## SOURCES
noinst_HEADERS = pacemakerd.h
diff --git a/daemons/pacemakerd/pacemakerd.8.inc b/daemons/pacemakerd/pacemakerd.8.inc
new file mode 100644
index 0000000..902af4e
--- /dev/null
+++ b/daemons/pacemakerd/pacemakerd.8.inc
@@ -0,0 +1,5 @@
+[synopsis]
+pacemakerd [options]
+
+/subsidiary Pacemaker daemons/
+.SH OPTIONS
diff --git a/daemons/pacemakerd/pacemakerd.c b/daemons/pacemakerd/pacemakerd.c
index 03d688e..ce194bf 100644
--- a/daemons/pacemakerd/pacemakerd.c
+++ b/daemons/pacemakerd/pacemakerd.c
@@ -23,12 +23,54 @@
#include <crm/msg_xml.h>
#include <crm/common/ipc_internal.h>
#include <crm/common/mainloop.h>
+#include <crm/common/cmdline_internal.h>
#include <crm/cluster/internal.h>
#include <crm/cluster.h>
#include <dirent.h>
#include <ctype.h>
+#define SUMMARY "pacemakerd - primary Pacemaker daemon that launches and monitors all subsidiary Pacemaker daemons"
+
+struct {
+ gboolean features;
+ gboolean foreground;
+ gboolean shutdown;
+ gboolean standby;
+} options;
+
+static gboolean
+pid_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError **err) {
+ return TRUE;
+}
+
+static gboolean
+standby_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError **err) {
+ options.standby = TRUE;
+ pcmk__set_env_option("node_start_state", "standby");
+ return TRUE;
+}
+
+static GOptionEntry entries[] = {
+ { "features", 'F', 0, G_OPTION_ARG_NONE, &options.features,
+ "Display full version and list of features Pacemaker was built with",
+ NULL },
+ { "foreground", 'f', 0, G_OPTION_ARG_NONE, &options.foreground,
+ "(Ignored) Pacemaker always runs in the foreground",
+ NULL },
+ { "pid-file", 'p', 0, G_OPTION_ARG_CALLBACK, pid_cb,
+ "(Ignored) Daemon pid file location",
+ "FILE" },
+ { "shutdown", 'S', 0, G_OPTION_ARG_NONE, &options.shutdown,
+ "Instruct Pacemaker to shutdown on this machine",
+ NULL },
+ { "standby", 's', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, standby_cb,
+ "Start node in standby state",
+ NULL },
+
+ { NULL }
+};
+
static gboolean fatal_error = FALSE;
static GMainLoop *mainloop = NULL;
static bool global_keep_tracking = false;
@@ -642,49 +685,6 @@ pcmk_sigquit(int nsig)
.connection_destroyed = pcmk_ipc_destroy
};
-static pcmk__cli_option_t long_options[] = {
- // long option, argument type, storage, short option, description, flags
- {
- "help", no_argument, NULL, '?',
- "\tThis text", pcmk__option_default
- },
- {
- "version", no_argument, NULL, '$',
- "\tVersion information", pcmk__option_default
- },
- {
- "verbose", no_argument, NULL, 'V',
- "\tIncrease debug output", pcmk__option_default
- },
- {
- "shutdown", no_argument, NULL, 'S',
- "\tInstruct Pacemaker to shutdown on this machine", pcmk__option_default
- },
- {
- "features", no_argument, NULL, 'F',
- "\tDisplay full version and list of features Pacemaker was built with",
- pcmk__option_default
- },
- {
- "-spacer-", no_argument, NULL, '-',
- "\nAdditional Options:", pcmk__option_default
- },
- {
- "foreground", no_argument, NULL, 'f',
- "\t(Ignored) Pacemaker always runs in the foreground",
- pcmk__option_default
- },
- {
- "pid-file", required_argument, NULL, 'p',
- "\t(Ignored) Daemon pid file location", pcmk__option_default
- },
- {
- "standby", no_argument, NULL, 's',
- "\tStart node in standby state", pcmk__option_default
- },
- { 0, 0, 0, 0 }
-};
-
static void
mcp_chown(const char *path, uid_t uid, gid_t gid)
{
@@ -1168,83 +1211,66 @@ request_shutdown(crm_ipc_t *ipc)
return status;
}
+static GOptionContext *
+build_arg_context(pcmk__common_args_t *args) {
+ GOptionContext *context = NULL;
+
+ context = pcmk__build_arg_context(args, NULL, NULL, NULL);
+ pcmk__add_main_args(context, entries);
+ return context;
+}
+
int
main(int argc, char **argv)
{
- int flag;
- int argerr = 0;
+ crm_exit_t exit_code = CRM_EX_OK;
+
+ GError *error = 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);
- int option_index = 0;
bool old_instance_connected = false;
- gboolean shutdown = FALSE;
crm_ipc_t *old_instance = NULL;
qb_ipcs_service_t *ipcs = NULL;
crm_log_preinit(NULL, argc, argv);
- pcmk__set_cli_options(NULL, "[options]", long_options,
- "primary Pacemaker daemon that launches and "
- "monitors all subsidiary Pacemaker daemons");
mainloop_add_signal(SIGHUP, pcmk_ignore);
mainloop_add_signal(SIGQUIT, pcmk_sigquit);
- while (1) {
- flag = pcmk__next_cli_option(argc, argv, &option_index, NULL);
- if (flag == -1)
- break;
-
- switch (flag) {
- case 'V':
- crm_bump_log_level(argc, argv);
- break;
- case 'f':
- /* Legacy */
- break;
- case 'p':
- break;
- case 's':
- pcmk__set_env_option("node_start_state", "standby");
- break;
- case '$':
- case '?':
- pcmk__cli_help(flag, CRM_EX_OK);
- break;
- case 'S':
- shutdown = TRUE;
- break;
- case 'F':
- printf("Pacemaker %s (Build: %s)\n Supporting v%s: %s\n", PACEMAKER_VERSION, BUILD_VERSION,
- CRM_FEATURE_SET, CRM_FEATURES);
- crm_exit(CRM_EX_OK);
- default:
- printf("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag);
- ++argerr;
- break;
- }
+ if (!g_option_context_parse_strv(context, &processed_args, &error)) {
+ exit_code = CRM_EX_USAGE;
+ goto done;
}
- if (optind < argc) {
- printf("non-option ARGV-elements: ");
- while (optind < argc)
- printf("%s ", argv[optind++]);
- printf("\n");
- }
- if (argerr) {
- pcmk__cli_help('?', CRM_EX_USAGE);
+ if (options.features) {
+ printf("Pacemaker %s (Build: %s)\n Supporting v%s: %s\n", 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);
+ }
setenv("LC_ALL", "C", 1);
pcmk__set_env_option("mcp", "true");
+ pcmk__cli_init_logging("pacemakerd", args->verbosity);
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);
old_instance_connected = crm_ipc_connect(old_instance);
- if (shutdown) {
+ if (options.shutdown) {
if (old_instance_connected) {
crm_exit(request_shutdown(old_instance));
} else {
@@ -1253,22 +1279,25 @@ main(int argc, char **argv)
"Pacemaker instance: %s", strerror(errno));
crm_ipc_close(old_instance);
crm_ipc_destroy(old_instance);
- crm_exit(CRM_EX_DISCONNECT);
+ exit_code = CRM_EX_DISCONNECT;
+ goto done;
}
} else if (old_instance_connected) {
crm_ipc_close(old_instance);
crm_ipc_destroy(old_instance);
crm_err("Aborting start-up because active Pacemaker instance found");
- crm_exit(CRM_EX_FATAL);
+ exit_code = CRM_EX_FATAL;
+ goto done;
}
crm_ipc_close(old_instance);
crm_ipc_destroy(old_instance);
#ifdef SUPPORT_COROSYNC
if (mcp_read_config() == FALSE) {
- crm_exit(CRM_EX_UNAVAILABLE);
+ exit_code = CRM_EX_UNAVAILABLE;
+ goto done;
}
#endif
@@ -1292,7 +1321,8 @@ main(int argc, char **argv)
#ifdef SUPPORT_COROSYNC
/* Allows us to block shutdown */
if (!cluster_connect_cfg()) {
- crm_exit(CRM_EX_PROTOCOL);
+ exit_code = CRM_EX_PROTOCOL;
+ goto done;
}
#endif
@@ -1307,9 +1337,11 @@ main(int argc, char **argv)
case pcmk_rc_ok:
break;
case pcmk_rc_ipc_unauthorized:
- crm_exit(CRM_EX_CANTCREAT);
+ exit_code = CRM_EX_CANTCREAT;
+ goto done;
default:
- crm_exit(CRM_EX_FATAL);
+ exit_code = CRM_EX_FATAL;
+ goto done;
};
mainloop_add_signal(SIGTERM, pcmk_shutdown);
@@ -1342,5 +1374,11 @@ main(int argc, char **argv)
#ifdef SUPPORT_COROSYNC
cluster_disconnect_cfg();
#endif
- crm_exit(CRM_EX_OK);
+
+done:
+ g_strfreev(processed_args);
+ pcmk__free_arg_context(context);
+
+ pcmk__output_and_clear_error(error, NULL);
+ crm_exit(exit_code);
}
--
1.8.3.1
From 8f7924fbb2a012bedcad59335b7bebc5020b26e3 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Thu, 13 May 2021 13:27:13 -0400
Subject: [PATCH 4/4] Low: pacemaker.service: Don't start pacemakerd with -f.
This option is completely ignored by pacemakerd.
---
daemons/pacemakerd/pacemaker.service.in | 2 +-
doc/sphinx/Clusters_from_Scratch/verification.rst | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/daemons/pacemakerd/pacemaker.service.in b/daemons/pacemakerd/pacemaker.service.in
index b128ddc..0363a22 100644
--- a/daemons/pacemakerd/pacemaker.service.in
+++ b/daemons/pacemakerd/pacemaker.service.in
@@ -44,7 +44,7 @@ EnvironmentFile=-@CONFIGDIR@/pacemaker
EnvironmentFile=-@CONFIGDIR@/sbd
SuccessExitStatus=100
-ExecStart=@sbindir@/pacemakerd -f
+ExecStart=@sbindir@/pacemakerd
# Systemd v227 and above can limit the number of processes spawned by a
# service. That is a bad idea for an HA cluster resource manager, so disable it
diff --git a/doc/sphinx/Clusters_from_Scratch/verification.rst b/doc/sphinx/Clusters_from_Scratch/verification.rst
index 9d647f8..b7fa20e 100644
--- a/doc/sphinx/Clusters_from_Scratch/verification.rst
+++ b/doc/sphinx/Clusters_from_Scratch/verification.rst
@@ -103,7 +103,7 @@ the necessary processes are running:
2 ? S 0:00 [kthreadd]
...lots of processes...
17121 ? SLsl 0:01 /usr/sbin/corosync -f
- 17133 ? Ss 0:00 /usr/sbin/pacemakerd -f
+ 17133 ? Ss 0:00 /usr/sbin/pacemakerd
17134 ? Ss 0:00 \_ /usr/libexec/pacemaker/pacemaker-based
17135 ? Ss 0:00 \_ /usr/libexec/pacemaker/pacemaker-fenced
17136 ? Ss 0:00 \_ /usr/libexec/pacemaker/pacemaker-execd
--
1.8.3.1

View File

@ -1,208 +0,0 @@
From 0deb5145c336bc4b32766c6f7af259d643af9143 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Wed, 28 Oct 2020 13:56:09 -0400
Subject: [PATCH 1/2] Fix: scheduler, tools: Update typing on maint-mode args.
---
lib/pengine/pe_output.c | 2 +-
tools/crm_mon_curses.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/pengine/pe_output.c b/lib/pengine/pe_output.c
index 186be33..d0f96f4 100644
--- a/lib/pengine/pe_output.c
+++ b/lib/pengine/pe_output.c
@@ -686,7 +686,7 @@ pe__cluster_dc_xml(pcmk__output_t *out, va_list args) {
return pcmk_rc_ok;
}
-PCMK__OUTPUT_ARGS("maint-mode", "unsigned long long")
+PCMK__OUTPUT_ARGS("maint-mode", "unsigned long long int")
int
pe__cluster_maint_mode_text(pcmk__output_t *out, va_list args) {
unsigned long long flags = va_arg(args, unsigned long long);
diff --git a/tools/crm_mon_curses.c b/tools/crm_mon_curses.c
index 8a08578..9cf28dc 100644
--- a/tools/crm_mon_curses.c
+++ b/tools/crm_mon_curses.c
@@ -365,7 +365,7 @@ stonith_event_console(pcmk__output_t *out, va_list args) {
return pcmk_rc_ok;
}
-PCMK__OUTPUT_ARGS("maint-mode", "unsigned long long")
+PCMK__OUTPUT_ARGS("maint-mode", "unsigned long long int")
static int
cluster_maint_mode_console(pcmk__output_t *out, va_list args) {
unsigned long long flags = va_arg(args, unsigned long long);
--
1.8.3.1
From 7a61ae2384b0a1653b4a06926b4ec23099ccf292 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Wed, 28 Oct 2020 13:57:51 -0400
Subject: [PATCH 2/2] Fix: tools: Update typing on formatted output args in
crmadmin.
A lot of these are actually taking const char * as an argument, not
regular char *.
---
tools/crmadmin.c | 62 ++++++++++++++++++++++++++++----------------------------
1 file changed, 31 insertions(+), 31 deletions(-)
diff --git a/tools/crmadmin.c b/tools/crmadmin.c
index b80a31a..e61dbf4 100644
--- a/tools/crmadmin.c
+++ b/tools/crmadmin.c
@@ -167,14 +167,14 @@ command_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError
return TRUE;
}
-PCMK__OUTPUT_ARGS("health", "char *", "char *", "char *", "char *")
+PCMK__OUTPUT_ARGS("health", "const char *", "const char *", "const char *", "const char *")
static int
health_text(pcmk__output_t *out, va_list args)
{
- char *sys_from = va_arg(args, char *);
- char *host_from = va_arg(args, char *);
- char *fsa_state = va_arg(args, char *);
- char *result = va_arg(args, char *);
+ const char *sys_from = va_arg(args, const char *);
+ const char *host_from = va_arg(args, const char *);
+ const char *fsa_state = va_arg(args, const char *);
+ const char *result = va_arg(args, const char *);
if (!out->is_quiet(out)) {
out->info(out, "Status of %s@%s: %s (%s)", crm_str(sys_from),
@@ -186,14 +186,14 @@ health_text(pcmk__output_t *out, va_list args)
return pcmk_rc_ok;
}
-PCMK__OUTPUT_ARGS("health", "char *", "char *", "char *", "char *")
+PCMK__OUTPUT_ARGS("health", "const char *", "const char *", "const char *", "const char *")
static int
health_xml(pcmk__output_t *out, va_list args)
{
- char *sys_from = va_arg(args, char *);
- char *host_from = va_arg(args, char *);
- char *fsa_state = va_arg(args, char *);
- char *result = va_arg(args, char *);
+ const char *sys_from = va_arg(args, const char *);
+ const char *host_from = va_arg(args, const char *);
+ const char *fsa_state = va_arg(args, const char *);
+ const char *result = va_arg(args, const char *);
xmlNodePtr node = pcmk__output_create_xml_node(out, crm_str(sys_from));
xmlSetProp(node, (pcmkXmlStr) "node_name", (pcmkXmlStr) crm_str(host_from));
@@ -203,13 +203,13 @@ health_xml(pcmk__output_t *out, va_list args)
return pcmk_rc_ok;
}
-PCMK__OUTPUT_ARGS("pacemakerd-health", "char *", "char *", "char *")
+PCMK__OUTPUT_ARGS("pacemakerd-health", "const char *", "const char *", "const char *")
static int
pacemakerd_health_text(pcmk__output_t *out, va_list args)
{
- char *sys_from = va_arg(args, char *);
- char *state = va_arg(args, char *);
- char *last_updated = va_arg(args, char *);
+ const char *sys_from = va_arg(args, const char *);
+ const char *state = va_arg(args, const char *);
+ const char *last_updated = va_arg(args, const char *);
if (!out->is_quiet(out)) {
out->info(out, "Status of %s: '%s' %s %s", crm_str(sys_from),
@@ -222,13 +222,13 @@ pacemakerd_health_text(pcmk__output_t *out, va_list args)
return pcmk_rc_ok;
}
-PCMK__OUTPUT_ARGS("pacemakerd-health", "char *", "char *", "char *")
+PCMK__OUTPUT_ARGS("pacemakerd-health", "const char *", "const char *", "const char *")
static int
pacemakerd_health_xml(pcmk__output_t *out, va_list args)
{
- char *sys_from = va_arg(args, char *);
- char *state = va_arg(args, char *);
- char *last_updated = va_arg(args, char *);
+ const char *sys_from = va_arg(args, const char *);
+ const char *state = va_arg(args, const char *);
+ const char *last_updated = va_arg(args, const char *);
xmlNodePtr node = pcmk__output_create_xml_node(out, crm_str(sys_from));
@@ -238,11 +238,11 @@ pacemakerd_health_xml(pcmk__output_t *out, va_list args)
return pcmk_rc_ok;
}
-PCMK__OUTPUT_ARGS("dc", "char *")
+PCMK__OUTPUT_ARGS("dc", "const char *")
static int
dc_text(pcmk__output_t *out, va_list args)
{
- char *dc = va_arg(args, char *);
+ const char *dc = va_arg(args, const char *);
if (!out->is_quiet(out)) {
out->info(out, "Designated Controller is: %s", crm_str(dc));
@@ -253,11 +253,11 @@ dc_text(pcmk__output_t *out, va_list args)
return pcmk_rc_ok;
}
-PCMK__OUTPUT_ARGS("dc", "char *")
+PCMK__OUTPUT_ARGS("dc", "const char *")
static int
dc_xml(pcmk__output_t *out, va_list args)
{
- char *dc = va_arg(args, char *);
+ const char *dc = va_arg(args, const char *);
xmlNodePtr node = pcmk__output_create_xml_node(out, "dc");
xmlSetProp(node, (pcmkXmlStr) "node_name", (pcmkXmlStr) crm_str(dc));
@@ -266,7 +266,7 @@ dc_xml(pcmk__output_t *out, va_list args)
}
-PCMK__OUTPUT_ARGS("crmadmin-node-list", "xmlNode *")
+PCMK__OUTPUT_ARGS("crmadmin-node-list", "struct xmlNode *")
static int
crmadmin_node_list(pcmk__output_t *out, va_list args)
{
@@ -298,13 +298,13 @@ crmadmin_node_list(pcmk__output_t *out, va_list args)
return pcmk_rc_ok;
}
-PCMK__OUTPUT_ARGS("crmadmin-node", "char *", "char *", "char *")
+PCMK__OUTPUT_ARGS("crmadmin-node", "const char *", "const char *", "const char *")
static int
crmadmin_node_text(pcmk__output_t *out, va_list args)
{
- char *type = va_arg(args, char *);
- char *name = va_arg(args, char *);
- char *id = va_arg(args, char *);
+ const char *type = va_arg(args, const char *);
+ const char *name = va_arg(args, const char *);
+ const char *id = va_arg(args, const char *);
if (BASH_EXPORT) {
out->info(out, "export %s=%s", crm_str(name), crm_str(id));
@@ -316,13 +316,13 @@ crmadmin_node_text(pcmk__output_t *out, va_list args)
return pcmk_rc_ok;
}
-PCMK__OUTPUT_ARGS("crmadmin-node", "char *", "char *", "char *")
+PCMK__OUTPUT_ARGS("crmadmin-node", "const char *", "const char *", "const char *")
static int
crmadmin_node_xml(pcmk__output_t *out, va_list args)
{
- char *type = va_arg(args, char *);
- char *name = va_arg(args, char *);
- char *id = va_arg(args, char *);
+ const char *type = va_arg(args, const char *);
+ const char *name = va_arg(args, const char *);
+ const char *id = va_arg(args, const char *);
xmlNodePtr node = pcmk__output_create_xml_node(out, "node");
xmlSetProp(node, (pcmkXmlStr) "type", (pcmkXmlStr) (type ? type : "member"));
--
1.8.3.1

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,199 @@
From 3905e7eac11298fc20efd567a773666f948edf61 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 3 May 2021 11:19:04 -0400
Subject: [PATCH 1/2] Feature: tools: Add OCF_CHECK_LEVEL to crm_resource
environment.
If --validate= or --force-check= are given with a level, pass that along
as OCF_CHECK_LEVEL. This argument is optional, and if no value is given
then the environment variable will not be set and whatever's the default
on the resource agent will be used.
See: rhbz#1955792.
---
tools/crm_resource.c | 29 +++++++++++++++++++++--------
tools/crm_resource.h | 4 ++--
tools/crm_resource_runtime.c | 13 ++++++++++---
3 files changed, 33 insertions(+), 13 deletions(-)
diff --git a/tools/crm_resource.c b/tools/crm_resource.c
index 45db2b2..6ca96f8 100644
--- a/tools/crm_resource.c
+++ b/tools/crm_resource.c
@@ -100,6 +100,7 @@ struct {
int timeout_ms; // Parsed from --timeout value
char *agent_spec; // Standard and/or provider and/or agent
gchar *xml_file; // Value of (deprecated) --xml-file
+ int check_level; // Optional value of --validate or --force-check
// Resource configuration specified via command-line arguments
gboolean cmdline_config; // Resource configuration was via arguments
@@ -113,6 +114,7 @@ struct {
GHashTable *override_params; // Resource parameter values that override config
} options = {
.attr_set_type = XML_TAG_ATTR_SETS,
+ .check_level = -1,
.cib_options = cib_sync_call,
.require_cib = TRUE,
.require_dataset = TRUE,
@@ -402,14 +404,15 @@ static GOptionEntry query_entries[] = {
};
static GOptionEntry command_entries[] = {
- { "validate", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
+ { "validate", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
validate_or_force_cb,
"Validate resource configuration by calling agent's validate-all\n"
INDENT "action. The configuration may be specified either by giving an\n"
INDENT "existing resource name with -r, or by specifying --class,\n"
INDENT "--agent, and --provider arguments, along with any number of\n"
- INDENT "--option arguments.",
- NULL },
+ INDENT "--option arguments. An optional LEVEL argument can be given\n"
+ INDENT "to control the level of checking performed.",
+ "LEVEL" },
{ "cleanup", 'C', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, cleanup_refresh_cb,
"If resource has any past failures, clear its history and fail\n"
INDENT "count. Optionally filtered by --resource, --node, --operation\n"
@@ -546,11 +549,12 @@ static GOptionEntry advanced_entries[] = {
INDENT "the cluster believes the resource is a clone instance already\n"
INDENT "running on the local node.",
NULL },
- { "force-check", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
+ { "force-check", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
validate_or_force_cb,
"(Advanced) Bypass the cluster and check the state of a resource on\n"
- INDENT "the local node",
- NULL },
+ INDENT "the local node. An optional LEVEL argument can be given\n"
+ INDENT "to control the level of checking performed.",
+ "LEVEL" },
{ NULL }
};
@@ -910,6 +914,15 @@ validate_or_force_cb(const gchar *option_name, const gchar *optarg,
if (options.override_params == NULL) {
options.override_params = pcmk__strkey_table(free, free);
}
+
+ if (optarg != NULL) {
+ if (pcmk__scan_min_int(optarg, &options.check_level, 0) != pcmk_rc_ok) {
+ g_set_error(error, G_OPTION_ERROR, CRM_EX_INVALID_PARAM,
+ "Invalid check level setting: %s", optarg);
+ return FALSE;
+ }
+ }
+
return TRUE;
}
@@ -1826,12 +1839,12 @@ main(int argc, char **argv)
options.v_class, options.v_provider, options.v_agent,
"validate-all", options.cmdline_params,
options.override_params, options.timeout_ms,
- args->verbosity, options.force);
+ args->verbosity, options.force, options.check_level);
} else {
exit_code = cli_resource_execute(rsc, options.rsc_id,
options.operation, options.override_params,
options.timeout_ms, cib_conn, data_set,
- args->verbosity, options.force);
+ args->verbosity, options.force, options.check_level);
}
goto done;
diff --git a/tools/crm_resource.h b/tools/crm_resource.h
index 3560377..5ab10d6 100644
--- a/tools/crm_resource.h
+++ b/tools/crm_resource.h
@@ -88,11 +88,11 @@ crm_exit_t cli_resource_execute_from_params(pcmk__output_t *out, const char *rsc
const char *rsc_type, const char *rsc_action,
GHashTable *params, GHashTable *override_hash,
int timeout_ms, int resource_verbose,
- gboolean force);
+ gboolean force, int check_level);
crm_exit_t cli_resource_execute(pe_resource_t *rsc, const char *requested_name,
const char *rsc_action, GHashTable *override_hash,
int timeout_ms, cib_t *cib, pe_working_set_t *data_set,
- int resource_verbose, gboolean force);
+ int resource_verbose, gboolean force, int check_level);
int cli_resource_update_attribute(pe_resource_t *rsc, const char *requested_name,
const char *attr_set, const char *attr_set_type,
diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c
index fe0ec98..bde83b6 100644
--- a/tools/crm_resource_runtime.c
+++ b/tools/crm_resource_runtime.c
@@ -1679,7 +1679,8 @@ cli_resource_execute_from_params(pcmk__output_t *out, const char *rsc_name,
const char *rsc_class, const char *rsc_prov,
const char *rsc_type, const char *action,
GHashTable *params, GHashTable *override_hash,
- int timeout_ms, int resource_verbose, gboolean force)
+ int timeout_ms, int resource_verbose, gboolean force,
+ int check_level)
{
GHashTable *params_copy = NULL;
crm_exit_t exit_code = CRM_EX_OK;
@@ -1703,6 +1704,12 @@ cli_resource_execute_from_params(pcmk__output_t *out, const char *rsc_name,
/* add crm_feature_set env needed by some resource agents */
g_hash_table_insert(params, strdup(XML_ATTR_CRM_VERSION), strdup(CRM_FEATURE_SET));
+ if (check_level >= 0) {
+ char *level = crm_strdup_printf("%d", check_level);
+ setenv("OCF_CHECK_LEVEL", level, 1);
+ free(level);
+ }
+
/* resources_action_create frees the params hash table it's passed, but we
* may need to reuse it in a second call to resources_action_create. Thus
* we'll make a copy here so that gets freed and the original remains for
@@ -1790,7 +1797,7 @@ crm_exit_t
cli_resource_execute(pe_resource_t *rsc, const char *requested_name,
const char *rsc_action, GHashTable *override_hash,
int timeout_ms, cib_t * cib, pe_working_set_t *data_set,
- int resource_verbose, gboolean force)
+ int resource_verbose, gboolean force, int check_level)
{
pcmk__output_t *out = data_set->priv;
crm_exit_t exit_code = CRM_EX_OK;
@@ -1856,7 +1863,7 @@ cli_resource_execute(pe_resource_t *rsc, const char *requested_name,
exit_code = cli_resource_execute_from_params(out, rid, rclass, rprov, rtype, action,
params, override_hash, timeout_ms,
- resource_verbose, force);
+ resource_verbose, force, check_level);
return exit_code;
}
--
1.8.3.1
From d13ba4bd6defe0dd81fdf8ab39ae5b889513c0c0 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Thu, 20 May 2021 10:59:23 -0400
Subject: [PATCH 2/2] Fix: include: Bump feature set to 3.10.2.
This is for the OCF_CHECK_LEVEL environment variable.
See: rhbz#1955792.
---
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 92a98fa..ee52c36 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.1"
+# define CRM_FEATURE_SET "3.10.2"
/* 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

View File

@ -1,771 +0,0 @@
From 9faa62f0701801f1d420462025e863d8ca3d6a06 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 21 Sep 2020 14:19:19 -0400
Subject: [PATCH 1/6] Fix: libcrmcommon: Automatically lower case XML list
names.
---
lib/common/output_xml.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/lib/common/output_xml.c b/lib/common/output_xml.c
index 1710fac..6a6ed6e 100644
--- a/lib/common/output_xml.c
+++ b/lib/common/output_xml.c
@@ -50,7 +50,6 @@ typedef struct subst_s {
} subst_t;
static subst_t substitutions[] = {
- { "Attributes", "attributes" },
{ "Active Resources", "resources" },
{ "Full List of Resources", "resources" },
{ "Inactive Resources", "resources" },
@@ -61,8 +60,6 @@ static subst_t substitutions[] = {
{ "Operations", "node_history" },
{ "Negative Location Constraints", "bans" },
{ "Node Attributes", "node_attributes" },
- { "Resources", "resources" },
- { "Tickets", "tickets" },
{ NULL, NULL }
};
@@ -288,7 +285,7 @@ static void
xml_begin_list(pcmk__output_t *out, const char *singular_noun, const char *plural_noun,
const char *format, ...) {
va_list ap;
- const char *name = NULL;
+ char *name = NULL;
char *buf = NULL;
int len;
@@ -300,14 +297,14 @@ xml_begin_list(pcmk__output_t *out, const char *singular_noun, const char *plura
if (substitute) {
for (subst_t *s = substitutions; s->from != NULL; s++) {
if (!strcmp(s->from, buf)) {
- name = s->to;
+ name = g_strdup(s->to);
break;
}
}
}
if (name == NULL) {
- name = buf;
+ name = g_ascii_strdown(buf, -1);
}
if (legacy_xml || simple_list) {
@@ -319,6 +316,7 @@ xml_begin_list(pcmk__output_t *out, const char *singular_noun, const char *plura
xmlSetProp(list_node, (pcmkXmlStr) "name", (pcmkXmlStr) name);
}
+ g_free(name);
free(buf);
}
--
1.8.3.1
From 7a77441ae8d3ab943dfafebfc06b63402be323e1 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Tue, 27 Oct 2020 12:49:45 -0400
Subject: [PATCH 2/6] Feature: xml: Move resource-related XML schema into its
own file.
This allows it to be shared between the crm_mon and crm_resource
schemas. Also, this adds support for resource XML to crm_mon given that
this is now technically possible as part of the library output.
---
xml/Makefile.am | 2 +-
xml/api/crm_mon-2.4.rng | 311 ++++++++++++++++++++++++++++++++++++++++++++++
xml/api/resources-2.4.rng | 109 ++++++++++++++++
3 files changed, 421 insertions(+), 1 deletion(-)
create mode 100644 xml/api/crm_mon-2.4.rng
create mode 100644 xml/api/resources-2.4.rng
diff --git a/xml/Makefile.am b/xml/Makefile.am
index 892c811..79ce900 100644
--- a/xml/Makefile.am
+++ b/xml/Makefile.am
@@ -51,7 +51,7 @@ API_request_base = command-output crm_mon crmadmin stonith_admin version
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 item status
+API_base = $(API_request_base) fence-event item 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.4.rng b/xml/api/crm_mon-2.4.rng
new file mode 100644
index 0000000..88973a4
--- /dev/null
+++ b/xml/api/crm_mon-2.4.rng
@@ -0,0 +1,311 @@
+<?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>
+ <ref name="element-full-node" />
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="node-attributes-list">
+ <element name="node_attributes">
+ <zeroOrMore>
+ <ref name="element-node-with-attributes" />
+ </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>
+ <ref name="element-failure" />
+ </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-full-node">
+ <element name="node">
+ <attribute name="name"> <text/> </attribute>
+ <attribute name="id"> <text/> </attribute>
+ <attribute name="online"> <data type="boolean" /> </attribute>
+ <attribute name="standby"> <data type="boolean" /> </attribute>
+ <attribute name="standby_onfail"> <data type="boolean" /> </attribute>
+ <attribute name="maintenance"> <data type="boolean" /> </attribute>
+ <attribute name="pending"> <data type="boolean" /> </attribute>
+ <attribute name="unclean"> <data type="boolean" /> </attribute>
+ <attribute name="shutdown"> <data type="boolean" /> </attribute>
+ <attribute name="expected_up"> <data type="boolean" /> </attribute>
+ <attribute name="is_dc"> <data type="boolean" /> </attribute>
+ <attribute name="resources_running"> <data type="nonNegativeInteger" /> </attribute>
+ <attribute name="type">
+ <choice>
+ <value>unknown</value>
+ <value>member</value>
+ <value>remote</value>
+ <value>ping</value>
+ </choice>
+ </attribute>
+ <optional>
+ <!-- for virtualized pacemaker_remote nodes, crm_mon 1.1.13 uses
+ "container_id" while later versions use "id_as_resource" -->
+ <choice>
+ <attribute name="container_id"> <text/> </attribute>
+ <attribute name="id_as_resource"> <text/> </attribute>
+ </choice>
+ </optional>
+ <externalRef href="resources-2.4.rng" />
+ </element>
+ </define>
+
+ <define name="element-node-with-attributes">
+ <element name="node">
+ <attribute name="name"> <text /> </attribute>
+ <zeroOrMore>
+ <element name="attribute">
+ <attribute name="name"> <text /> </attribute>
+ <attribute name="value"> <text /> </attribute>
+ <optional>
+ <attribute name="expected"> <data type="nonNegativeInteger" /> </attribute>
+ </optional>
+ </element>
+ </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-failure">
+ <element name="failure">
+ <choice>
+ <attribute name="op_key"> <text/> </attribute>
+ <attribute name="id"> <text/> </attribute>
+ </choice>
+ <attribute name="node"> <text /> </attribute>
+ <attribute name="exitstatus"> <text /> </attribute>
+ <attribute name="exitreason"> <text /> </attribute>
+ <attribute name="exitcode"> <data type="nonNegativeInteger" /> </attribute>
+ <attribute name="call"> <data type="nonNegativeInteger" /> </attribute>
+ <attribute name="status"> <text /> </attribute>
+ <optional>
+ <group>
+ <attribute name="last-rc-change"> <text /> </attribute>
+ <attribute name="queued"> <data type="nonNegativeInteger" /> </attribute>
+ <attribute name="exec"> <data type="nonNegativeInteger" /> </attribute>
+ <attribute name="interval"> <data type="nonNegativeInteger" /> </attribute>
+ <attribute name="task"> <text /> </attribute>
+ </group>
+ </optional>
+ </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="master_only"> <data type="boolean" /> </attribute>
+ </element>
+ </define>
+</grammar>
diff --git a/xml/api/resources-2.4.rng b/xml/api/resources-2.4.rng
new file mode 100644
index 0000000..e279583
--- /dev/null
+++ b/xml/api/resources-2.4.rng
@@ -0,0 +1,109 @@
+<?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-resource-list"/>
+ </start>
+
+ <define name="element-resource-list">
+ <interleave>
+ <zeroOrMore>
+ <ref name="element-bundle" />
+ </zeroOrMore>
+ <zeroOrMore>
+ <ref name="element-clone" />
+ </zeroOrMore>
+ <zeroOrMore>
+ <ref name="element-group" />
+ </zeroOrMore>
+ <zeroOrMore>
+ <ref name="element-resource" />
+ </zeroOrMore>
+ </interleave>
+ </define>
+
+ <define name="element-bundle">
+ <element name="bundle">
+ <attribute name="id"> <text/> </attribute>
+ <attribute name="type">
+ <choice>
+ <value>docker</value>
+ <value>rkt</value>
+ <value>podman</value>
+ </choice>
+ </attribute>
+ <attribute name="image"> <text/> </attribute>
+ <attribute name="unique"> <data type="boolean" /> </attribute>
+ <attribute name="managed"> <data type="boolean" /> </attribute>
+ <attribute name="failed"> <data type="boolean" /> </attribute>
+ <zeroOrMore>
+ <element name="replica">
+ <attribute name="id"> <data type="nonNegativeInteger" /> </attribute>
+ <zeroOrMore>
+ <ref name="element-resource" />
+ </zeroOrMore>
+ </element>
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="element-clone">
+ <element name="clone">
+ <attribute name="id"> <text/> </attribute>
+ <attribute name="multi_state"> <data type="boolean" /> </attribute>
+ <attribute name="unique"> <data type="boolean" /> </attribute>
+ <attribute name="managed"> <data type="boolean" /> </attribute>
+ <attribute name="disabled"> <data type="boolean" /> </attribute>
+ <attribute name="failed"> <data type="boolean" /> </attribute>
+ <attribute name="failure_ignored"> <data type="boolean" /> </attribute>
+ <optional>
+ <attribute name="target_role"> <text/> </attribute>
+ </optional>
+ <ref name="element-resource-list" />
+ </element>
+ </define>
+
+ <define name="element-group">
+ <element name="group">
+ <attribute name="id"> <text/> </attribute>
+ <attribute name="number_resources"> <data type="nonNegativeInteger" /> </attribute>
+ <attribute name="managed"> <data type="boolean" /> </attribute>
+ <attribute name="disabled"> <data type="boolean" /> </attribute>
+ <ref name="element-resource-list" />
+ </element>
+ </define>
+
+ <define name="element-resource">
+ <element name="resource">
+ <attribute name="id"> <text/> </attribute>
+ <attribute name="resource_agent"> <text/> </attribute>
+ <attribute name="role"> <text/> </attribute>
+ <optional>
+ <attribute name="target_role"> <text/> </attribute>
+ </optional>
+ <attribute name="active"> <data type="boolean" /> </attribute>
+ <attribute name="orphaned"> <data type="boolean" /> </attribute>
+ <optional>
+ <attribute name="blocked"> <data type="boolean" /> </attribute>
+ </optional>
+ <attribute name="managed"> <data type="boolean" /> </attribute>
+ <attribute name="failed"> <data type="boolean" /> </attribute>
+ <attribute name="failure_ignored"> <data type="boolean" /> </attribute>
+ <attribute name="nodes_running_on"> <data type="nonNegativeInteger" /> </attribute>
+ <optional>
+ <attribute name="pending"> <text/> </attribute>
+ </optional>
+ <zeroOrMore>
+ <element name="node">
+ <attribute name="name"> <text/> </attribute>
+ <attribute name="id"> <text/> </attribute>
+ <attribute name="cached"> <data type="boolean" /> </attribute>
+ </element>
+ </zeroOrMore>
+ <optional>
+ <element name="xml"> <text/> </element>
+ </optional>
+ </element>
+ </define>
+</grammar>
--
1.8.3.1
From 814eb921cd429692220f33722c9bc061266bd838 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Thu, 29 Oct 2020 14:45:02 -0400
Subject: [PATCH 3/6] Feature: xml: Add a generic list XML schema file.
Formatted output supports a generic list structure that isn't used in
too many places at the moment, but it could be getting used more in the
future. It's also really easy to have a schema for this piece of XML.
---
xml/Makefile.am | 7 ++++++-
xml/api/generic-list-2.4.rng | 21 +++++++++++++++++++++
2 files changed, 27 insertions(+), 1 deletion(-)
create mode 100644 xml/api/generic-list-2.4.rng
diff --git a/xml/Makefile.am b/xml/Makefile.am
index 79ce900..2f99f1c 100644
--- a/xml/Makefile.am
+++ b/xml/Makefile.am
@@ -44,6 +44,11 @@ version_pairs_last = $(wordlist \
),$(1),$(2) \
)
+# NOTE: All files in API_request_base, CIB_cfg_base, API_base, and CIB_base
+# need to start with a unique prefix. These variables all get iterated over
+# and globbed, and two files starting with the same prefix will cause
+# problems.
+
# Names of API schemas that form the choices for pacemaker-result content
API_request_base = command-output crm_mon crmadmin stonith_admin version
@@ -51,7 +56,7 @@ API_request_base = command-output crm_mon crmadmin stonith_admin version
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 item resources status
+API_base = $(API_request_base) fence-event generic-list item 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/generic-list-2.4.rng b/xml/api/generic-list-2.4.rng
new file mode 100644
index 0000000..fee93a9
--- /dev/null
+++ b/xml/api/generic-list-2.4.rng
@@ -0,0 +1,21 @@
+<?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="generic-list"/>
+ </start>
+
+ <define name="generic-list">
+ <element name="list">
+ <attribute name="name"> <text /> </attribute>
+ <attribute name="count"> <data type="nonNegativeInteger" /> </attribute>
+ <choice>
+ <empty/>
+ <oneOrMore>
+ <externalRef href="item-1.1.rng"/>
+ </oneOrMore>
+ </choice>
+ </element>
+ </define>
+</grammar>
--
1.8.3.1
From 316b6f66ca5425093503c51c2f8738922287ebca Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Wed, 16 Sep 2020 15:59:34 -0400
Subject: [PATCH 4/6] Fix: tools: Save the optarg parameter for
--list-ocf-alternatives.
We need this so it can be added to the XML output of crm_resource.
---
tools/crm_resource.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/tools/crm_resource.c b/tools/crm_resource.c
index 6573ad5..acaddc0 100644
--- a/tools/crm_resource.c
+++ b/tools/crm_resource.c
@@ -720,9 +720,7 @@ list_alternatives_cb(const gchar *option_name, const gchar *optarg,
gpointer data, GError **error)
{
SET_COMMAND(cmd_list_alternatives);
- options.require_cib = FALSE;
- options.require_dataset = FALSE;
- options.require_resource = FALSE;
+ get_agent_spec(optarg);
return TRUE;
}
--
1.8.3.1
From c063ce9b193f2022611e651c13afcb3ceb5969e3 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Wed, 2 Sep 2020 16:20:10 -0400
Subject: [PATCH 5/6] Fix: scheduler: Use the default format handler in a few
more places.
---
lib/pengine/pe_output.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/lib/pengine/pe_output.c b/lib/pengine/pe_output.c
index d0f96f4..9d43e5f 100644
--- a/lib/pengine/pe_output.c
+++ b/lib/pengine/pe_output.c
@@ -1847,9 +1847,7 @@ static pcmk__message_entry_t fmt_functions[] = {
{ "cluster-times", "log", pe__cluster_times_text },
{ "cluster-times", "text", pe__cluster_times_text },
{ "cluster-times", "xml", pe__cluster_times_xml },
- { "failed-action", "html", pe__failed_action_text },
- { "failed-action", "log", pe__failed_action_text },
- { "failed-action", "text", pe__failed_action_text },
+ { "failed-action", "default", pe__failed_action_text },
{ "failed-action", "xml", pe__failed_action_xml },
{ "group", "xml", pe__group_xml },
{ "group", "html", pe__group_html },
@@ -1868,9 +1866,7 @@ static pcmk__message_entry_t fmt_functions[] = {
{ "node-attribute", "log", pe__node_attribute_text },
{ "node-attribute", "text", pe__node_attribute_text },
{ "node-attribute", "xml", pe__node_attribute_xml },
- { "op-history", "html", pe__op_history_text },
- { "op-history", "log", pe__op_history_text },
- { "op-history", "text", pe__op_history_text },
+ { "op-history", "default", pe__op_history_text },
{ "op-history", "xml", pe__op_history_xml },
{ "primitive", "xml", pe__resource_xml },
{ "primitive", "html", pe__resource_html },
--
1.8.3.1
From a32b99f5fd09ec15dbba6785c5d8dc2e220417a3 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Thu, 3 Sep 2020 10:23:16 -0400
Subject: [PATCH 6/6] Refactor: scheduler: Expose native_output_string as
pcmk__native_output_string.
The plan is that this function can be used to help build the string that
is output for each line of "crm_resource -o" output. It appears that
output only happens for primitive resources. However, I've added a
check at the beginning just in case it's called for some other type of
resource.
---
include/crm/pengine/internal.h | 3 +++
lib/pengine/native.c | 24 ++++++++++++++----------
2 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/include/crm/pengine/internal.h b/include/crm/pengine/internal.h
index abe7a76..d658e86 100644
--- a/include/crm/pengine/internal.h
+++ b/include/crm/pengine/internal.h
@@ -243,6 +243,9 @@ void clone_print(pe_resource_t * rsc, const char *pre_text, long options, void *
void pe__print_bundle(pe_resource_t *rsc, const char *pre_text, long options,
void *print_data);
+gchar * pcmk__native_output_string(pe_resource_t *rsc, const char *name, pe_node_t *node,
+ long options, const char *target_role, bool show_nodes);
+
int pe__name_and_nvpairs_xml(pcmk__output_t *out, bool is_list, const char *tag_name
, size_t pairs_count, ...);
char *pe__node_display_name(pe_node_t *node, bool print_detail);
diff --git a/lib/pengine/native.c b/lib/pengine/native.c
index 8f0c5c9..bf1f5c0 100644
--- a/lib/pengine/native.c
+++ b/lib/pengine/native.c
@@ -570,17 +570,21 @@ add_output_node(GString *s, const char *node, bool have_nodes)
* \return Newly allocated string description of resource
* \note Caller must free the result with g_free().
*/
-static gchar *
-native_output_string(pe_resource_t *rsc, const char *name, pe_node_t *node,
- long options, const char *target_role, bool show_nodes)
+gchar *
+pcmk__native_output_string(pe_resource_t *rsc, const char *name, pe_node_t *node,
+ long options, const char *target_role, bool show_nodes)
{
const char *class = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS);
const char *provider = NULL;
const char *kind = crm_element_value(rsc->xml, XML_ATTR_TYPE);
- char *retval = NULL;
+ gchar *retval = NULL;
GString *outstr = NULL;
bool have_flags = false;
+ if (rsc->variant != pe_native) {
+ return NULL;
+ }
+
CRM_CHECK(name != NULL, name = "unknown");
CRM_CHECK(kind != NULL, kind = "unknown");
CRM_CHECK(class != NULL, class = "unknown");
@@ -758,8 +762,8 @@ pe__common_output_html(pcmk__output_t *out, pe_resource_t * rsc,
}
{
- gchar *s = native_output_string(rsc, name, node, options, target_role,
- true);
+ gchar *s = pcmk__native_output_string(rsc, name, node, options,
+ target_role, true);
list_node = pcmk__output_create_html_node(out, "li", NULL, NULL, NULL);
pcmk_create_html_node(list_node, "span", NULL, cl, s);
@@ -826,8 +830,8 @@ pe__common_output_text(pcmk__output_t *out, pe_resource_t * rsc,
}
{
- gchar *s = native_output_string(rsc, name, node, options, target_role,
- true);
+ gchar *s = pcmk__native_output_string(rsc, name, node, options,
+ target_role, true);
out->list_item(out, NULL, "%s", s);
g_free(s);
@@ -923,8 +927,8 @@ common_print(pe_resource_t * rsc, const char *pre_text, const char *name, pe_nod
}
{
- gchar *resource_s = native_output_string(rsc, name, node, options,
- target_role, false);
+ gchar *resource_s = pcmk__native_output_string(rsc, name, node, options,
+ target_role, false);
status_print("%s%s", (pre_text? pre_text : ""), resource_s);
g_free(resource_s);
}
--
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

@ -1,210 +0,0 @@
From 477b7b679d58455dc38c2594b29a1ecfbe88e80c Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 2 Nov 2020 14:55:27 -0500
Subject: [PATCH 1/2] Fix: libcrmcommon: Prevent a segfault in
pcmk__cmdline_preproc.
The list of special single-character args is optional. The function
currently handles it being an empty string, but it should handle a NULL
as well.
---
lib/common/cmdline.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/common/cmdline.c b/lib/common/cmdline.c
index d66ccc7..66f1976 100644
--- a/lib/common/cmdline.c
+++ b/lib/common/cmdline.c
@@ -203,7 +203,7 @@ pcmk__cmdline_preproc(char **argv, const char *special) {
* glib does not. Grab both the argument and its value and
* separate them into a new argument.
*/
- if (strchr(special, *ch) != NULL) {
+ if (special != NULL && strchr(special, *ch) != NULL) {
/* The argument does not occur at the end of this string of
* arguments. Take everything through the end as its value.
*/
--
1.8.3.1
From d1f4a975fa783045254521f415f1899b34ee96e3 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 2 Nov 2020 16:06:29 -0500
Subject: [PATCH 2/2] Test: libcrmcommon: Add unit tests for
pcmk__cmdline_preproc.
---
configure.ac | 1 +
lib/common/tests/Makefile.am | 2 +-
lib/common/tests/cmdline/Makefile.am | 29 ++++++
.../tests/cmdline/pcmk__cmdline_preproc_test.c | 102 +++++++++++++++++++++
4 files changed, 133 insertions(+), 1 deletion(-)
create mode 100644 lib/common/tests/cmdline/Makefile.am
create mode 100644 lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c
diff --git a/configure.ac b/configure.ac
index 7ed4a30..36e85a9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2006,6 +2006,7 @@ AC_CONFIG_FILES(Makefile \
lib/pacemaker-cluster.pc \
lib/common/Makefile \
lib/common/tests/Makefile \
+ lib/common/tests/cmdline/Makefile \
lib/common/tests/flags/Makefile \
lib/common/tests/operations/Makefile \
lib/common/tests/strings/Makefile \
diff --git a/lib/common/tests/Makefile.am b/lib/common/tests/Makefile.am
index 33c45cb..f3eaeec 100644
--- a/lib/common/tests/Makefile.am
+++ b/lib/common/tests/Makefile.am
@@ -1 +1 @@
-SUBDIRS = flags operations strings utils
+SUBDIRS = cmdline flags operations strings utils
diff --git a/lib/common/tests/cmdline/Makefile.am b/lib/common/tests/cmdline/Makefile.am
new file mode 100644
index 0000000..e69ef21
--- /dev/null
+++ b/lib/common/tests/cmdline/Makefile.am
@@ -0,0 +1,29 @@
+#
+# Copyright 2020 the Pacemaker project contributors
+#
+# The version control history for this file may have further details.
+#
+# This source code is licensed under the GNU General Public License version 2
+# or later (GPLv2+) WITHOUT ANY WARRANTY.
+#
+AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include
+LDADD = $(top_builddir)/lib/common/libcrmcommon.la
+
+include $(top_srcdir)/mk/glib-tap.mk
+
+# Add each test program here. Each test should be written as a little standalone
+# program using the glib unit testing functions. See the documentation for more
+# information.
+#
+# https://developer.gnome.org/glib/unstable/glib-Testing.html
+#
+# Add "_test" to the end of all test program names to simplify .gitignore.
+test_programs = pcmk__cmdline_preproc_test
+
+# If any extra data needs to be added to the source distribution, add it to the
+# following list.
+dist_test_data =
+
+# If any extra data needs to be used by tests but should not be added to the
+# source distribution, add it to the following list.
+test_data =
diff --git a/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c b/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c
new file mode 100644
index 0000000..e13c983
--- /dev/null
+++ b/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2020 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
+ *
+ * This source code is licensed under the GNU Lesser General Public License
+ * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
+ */
+
+#include <crm_internal.h>
+#include <crm/common/cmdline_internal.h>
+
+#define LISTS_EQ(a, b) { \
+ g_assert_cmpint(g_strv_length((gchar **) (a)), ==, g_strv_length((gchar **) (b))); \
+ for (int i = 0; i < g_strv_length((a)); i++) { \
+ g_assert_cmpstr((a)[i], ==, (b)[i]); \
+ } \
+}
+
+static void
+empty_input(void) {
+ g_assert_cmpint(pcmk__cmdline_preproc(NULL, "") == NULL, ==, TRUE);
+}
+
+static void
+no_specials(void) {
+ const char *argv[] = { "-a", "-b", "-c", "-d", NULL };
+ const gchar *expected[] = { "-a", "-b", "-c", "-d", NULL };
+
+ gchar **processed = pcmk__cmdline_preproc((char **) argv, NULL);
+ LISTS_EQ(processed, expected);
+ g_strfreev(processed);
+
+ processed = pcmk__cmdline_preproc((char **) argv, "");
+ LISTS_EQ(processed, expected);
+ g_strfreev(processed);
+}
+
+static void
+single_dash(void) {
+ const char *argv[] = { "-", NULL };
+ const gchar *expected[] = { "-", NULL };
+
+ gchar **processed = pcmk__cmdline_preproc((char **) argv, NULL);
+ LISTS_EQ(processed, expected);
+ g_strfreev(processed);
+}
+
+static void
+double_dash(void) {
+ const char *argv[] = { "-a", "--", "-bc", NULL };
+ const gchar *expected[] = { "-a", "--", "-bc", NULL };
+
+ gchar **processed = pcmk__cmdline_preproc((char **) argv, NULL);
+ LISTS_EQ(processed, expected);
+ g_strfreev(processed);
+}
+
+static void
+special_args(void) {
+ const char *argv[] = { "-aX", "-Fval", NULL };
+ const gchar *expected[] = { "-a", "X", "-F", "val", NULL };
+
+ gchar **processed = pcmk__cmdline_preproc((char **) argv, "aF");
+ LISTS_EQ(processed, expected);
+ g_strfreev(processed);
+}
+
+static void
+special_arg_at_end(void) {
+ const char *argv[] = { "-a", NULL };
+ const gchar *expected[] = { "-a", NULL };
+
+ gchar **processed = pcmk__cmdline_preproc((char **) argv, "a");
+ LISTS_EQ(processed, expected);
+ g_strfreev(processed);
+}
+
+static void
+long_arg(void) {
+ const char *argv[] = { "--blah=foo", NULL };
+ const gchar *expected[] = { "--blah=foo", NULL };
+
+ gchar **processed = pcmk__cmdline_preproc((char **) argv, NULL);
+ LISTS_EQ(processed, expected);
+ g_strfreev(processed);
+}
+
+int
+main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+
+ g_test_add_func("/common/cmdline/preproc/empty_input", empty_input);
+ g_test_add_func("/common/cmdline/preproc/no_specials", no_specials);
+ g_test_add_func("/common/cmdline/preproc/single_dash", single_dash);
+ g_test_add_func("/common/cmdline/preproc/double_dash", double_dash);
+ g_test_add_func("/common/cmdline/preproc/special_args", special_args);
+ g_test_add_func("/common/cmdline/preproc/special_arg_at_end", special_arg_at_end);
+ g_test_add_func("/common/cmdline/preproc/long_arg", long_arg);
+ return g_test_run();
+}
--
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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,140 @@
From 2d15fb37525f88ec8d5acb689b698044c4bb69b1 Mon Sep 17 00:00:00 2001
From: Hideo Yamauchi <renayama19661014@ybb.ne.jp>
Date: Thu, 17 Jun 2021 22:39:12 +0900
Subject: [PATCH 1/2] Low: fenced: Low: fenced: Remove unnecessary release.
---
daemons/fenced/fenced_commands.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/daemons/fenced/fenced_commands.c b/daemons/fenced/fenced_commands.c
index fee55a7..35aec06 100644
--- a/daemons/fenced/fenced_commands.c
+++ b/daemons/fenced/fenced_commands.c
@@ -1104,9 +1104,6 @@ dynamic_list_search_cb(GPid pid, int rc, const char *output, gpointer user_data)
/* Fall back to status */
g_hash_table_replace(dev->params,
strdup(PCMK_STONITH_HOST_CHECK), strdup("status"));
-
- g_list_free_full(dev->targets, free);
- dev->targets = NULL;
} else if (!rc) {
crm_info("Refreshing port list for %s", dev->id);
g_list_free_full(dev->targets, free);
--
1.8.3.1
From a29f88f6020aac5f1ac32072942eb5713d7be50d Mon Sep 17 00:00:00 2001
From: Hideo Yamauchi <renayama19661014@ybb.ne.jp>
Date: Thu, 17 Jun 2021 22:40:40 +0900
Subject: [PATCH 2/2] High: fenced: Wrong device may be selected when
"dynamic-list" is specified.
---
daemons/fenced/fenced_commands.c | 67 +++++++++++++++++++++++-----------------
1 file changed, 38 insertions(+), 29 deletions(-)
diff --git a/daemons/fenced/fenced_commands.c b/daemons/fenced/fenced_commands.c
index 35aec06..da076fb 100644
--- a/daemons/fenced/fenced_commands.c
+++ b/daemons/fenced/fenced_commands.c
@@ -904,6 +904,31 @@ xml2device_params(const char *name, xmlNode *dev)
return params;
}
+static const char *
+target_list_type(stonith_device_t * dev)
+{
+ const char *check_type = NULL;
+
+ check_type = g_hash_table_lookup(dev->params, PCMK_STONITH_HOST_CHECK);
+
+ if (check_type == NULL) {
+
+ if (g_hash_table_lookup(dev->params, PCMK_STONITH_HOST_LIST)) {
+ check_type = "static-list";
+ } else if (g_hash_table_lookup(dev->params, PCMK_STONITH_HOST_MAP)) {
+ check_type = "static-list";
+ } else if (pcmk_is_set(dev->flags, st_device_supports_list)) {
+ check_type = "dynamic-list";
+ } else if (pcmk_is_set(dev->flags, st_device_supports_status)) {
+ check_type = "status";
+ } else {
+ check_type = "none";
+ }
+ }
+
+ return check_type;
+}
+
static stonith_device_t *
build_device_from_xml(xmlNode * msg)
{
@@ -931,6 +956,12 @@ build_device_from_xml(xmlNode * msg)
value = g_hash_table_lookup(device->params, PCMK_STONITH_HOST_MAP);
device->aliases = build_port_aliases(value, &(device->targets));
+ value = target_list_type(device);
+ if (!pcmk__str_eq(value, "static-list", pcmk__str_casei) && device->targets) {
+ /* Other than "static-list", dev-> targets is unnecessary. */
+ g_list_free_full(device->targets, free);
+ device->targets = NULL;
+ }
device->agent_metadata = get_agent_metadata(device->agent);
if (device->agent_metadata) {
read_action_metadata(device);
@@ -971,31 +1002,6 @@ build_device_from_xml(xmlNode * msg)
return device;
}
-static const char *
-target_list_type(stonith_device_t * dev)
-{
- const char *check_type = NULL;
-
- check_type = g_hash_table_lookup(dev->params, PCMK_STONITH_HOST_CHECK);
-
- if (check_type == NULL) {
-
- if (g_hash_table_lookup(dev->params, PCMK_STONITH_HOST_LIST)) {
- check_type = "static-list";
- } else if (g_hash_table_lookup(dev->params, PCMK_STONITH_HOST_MAP)) {
- check_type = "static-list";
- } else if (pcmk_is_set(dev->flags, st_device_supports_list)) {
- check_type = "dynamic-list";
- } else if (pcmk_is_set(dev->flags, st_device_supports_status)) {
- check_type = "status";
- } else {
- check_type = "none";
- }
- }
-
- return check_type;
-}
-
static void
schedule_internal_command(const char *origin,
stonith_device_t * device,
@@ -1099,11 +1105,14 @@ dynamic_list_search_cb(GPid pid, int rc, const char *output, gpointer user_data)
/* If we successfully got the targets earlier, don't disable. */
if (rc != 0 && !dev->targets) {
- crm_notice("Disabling port list queries for %s: %s "
- CRM_XS " rc=%d", dev->id, output, rc);
- /* Fall back to status */
- g_hash_table_replace(dev->params,
+ if (g_hash_table_lookup(dev->params, PCMK_STONITH_HOST_CHECK) == NULL) {
+ /*
+ If the operation fails if the user does not explicitly specify "dynamic-list", it will fall back to "status".
+ */
+ crm_notice("Disabling port list queries for %s (%d): %s", dev->id, rc, output);
+ g_hash_table_replace(dev->params,
strdup(PCMK_STONITH_HOST_CHECK), strdup("status"));
+ }
} else if (!rc) {
crm_info("Refreshing port list for %s", dev->id);
g_list_free_full(dev->targets, free);
--
1.8.3.1

View File

@ -0,0 +1,229 @@
From 5bcab230ad4c647ca78b18bd4a66e30a4bb4417f Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Wed, 16 Jun 2021 11:19:03 +0200
Subject: [PATCH 1/2] Feature: crm_resource: report not supported for --force-*
w/systemd, upstart, nagios and bundled resources
---
tools/crm_resource.c | 21 ++++----------
tools/crm_resource_runtime.c | 67 +++++++++++++++++++++++++++++---------------
2 files changed, 51 insertions(+), 37 deletions(-)
diff --git a/tools/crm_resource.c b/tools/crm_resource.c
index 4abdd03..fa7902c 100644
--- a/tools/crm_resource.c
+++ b/tools/crm_resource.c
@@ -660,21 +660,12 @@ attr_set_type_cb(const gchar *option_name, const gchar *optarg, gpointer data, G
gboolean
class_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError **error) {
- if (!(pcmk_get_ra_caps(optarg) & pcmk_ra_cap_params)) {
- if (!args->quiet) {
- g_set_error(error, G_OPTION_ERROR, CRM_EX_INVALID_PARAM,
- "Standard %s does not support parameters\n", optarg);
- }
- return FALSE;
-
- } else {
- if (options.v_class != NULL) {
- free(options.v_class);
- }
-
- options.v_class = strdup(optarg);
+ if (options.v_class != NULL) {
+ free(options.v_class);
}
+ options.v_class = strdup(optarg);
+
options.cmdline_config = TRUE;
options.require_resource = FALSE;
return TRUE;
@@ -1422,7 +1413,7 @@ validate_cmdline_config(void)
} else if (options.rsc_cmd != cmd_execute_agent) {
g_set_error(&error, PCMK__EXITC_ERROR, CRM_EX_USAGE,
"--class, --agent, and --provider can only be used with "
- "--validate");
+ "--validate and --force-*");
// Not all of --class, --agent, and --provider need to be given. Not all
// classes support the concept of a provider. Check that what we were given
@@ -1841,7 +1832,7 @@ main(int argc, char **argv)
if (options.cmdline_config) {
exit_code = cli_resource_execute_from_params(out, NULL,
options.v_class, options.v_provider, options.v_agent,
- "validate-all", options.cmdline_params,
+ options.operation, options.cmdline_params,
options.override_params, options.timeout_ms,
args->verbosity, options.force, options.check_level);
} else {
diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c
index fe42e60..59e6df5 100644
--- a/tools/crm_resource_runtime.c
+++ b/tools/crm_resource_runtime.c
@@ -1674,24 +1674,59 @@ wait_till_stable(pcmk__output_t *out, int timeout_ms, cib_t * cib)
return rc;
}
+static const char *
+get_action(const char *rsc_action) {
+ const char *action = NULL;
+
+ if (pcmk__str_eq(rsc_action, "validate", pcmk__str_casei)) {
+ action = "validate-all";
+
+ } else if (pcmk__str_eq(rsc_action, "force-check", pcmk__str_casei)) {
+ action = "monitor";
+
+ } else if (pcmk__strcase_any_of(rsc_action, "force-start", "force-stop",
+ "force-demote", "force-promote", NULL)) {
+ action = rsc_action+6;
+ } else {
+ action = rsc_action;
+ }
+
+ return action;
+}
+
crm_exit_t
cli_resource_execute_from_params(pcmk__output_t *out, const char *rsc_name,
const char *rsc_class, const char *rsc_prov,
- const char *rsc_type, const char *action,
+ const char *rsc_type, const char *rsc_action,
GHashTable *params, GHashTable *override_hash,
int timeout_ms, int resource_verbose, gboolean force,
int check_level)
{
+ const char *action = NULL;
GHashTable *params_copy = NULL;
crm_exit_t exit_code = CRM_EX_OK;
svc_action_t *op = NULL;
if (pcmk__str_eq(rsc_class, PCMK_RESOURCE_CLASS_STONITH, pcmk__str_casei)) {
out->err(out, "Sorry, the %s option doesn't support %s resources yet",
- action, rsc_class);
+ rsc_action, rsc_class);
+ crm_exit(CRM_EX_UNIMPLEMENT_FEATURE);
+ } else if (pcmk__strcase_any_of(rsc_class, PCMK_RESOURCE_CLASS_SYSTEMD,
+ PCMK_RESOURCE_CLASS_UPSTART, PCMK_RESOURCE_CLASS_NAGIOS, NULL)) {
+ out->err(out, "Sorry, the %s option doesn't support %s resources",
+ rsc_action, rsc_class);
+ crm_exit(CRM_EX_UNIMPLEMENT_FEATURE);
+ } else if (pcmk__str_eq(rsc_class, PCMK_RESOURCE_CLASS_SERVICE,
+ pcmk__str_casei) && !pcmk__str_eq(
+ resources_find_service_class(rsc_name), PCMK_RESOURCE_CLASS_LSB,
+ pcmk__str_casei)) {
+ out->err(out, "Sorry, the %s option doesn't support %s resources",
+ rsc_action, resources_find_service_class(rsc_name));
crm_exit(CRM_EX_UNIMPLEMENT_FEATURE);
}
+ action = get_action(rsc_action);
+
/* If no timeout was provided, grab the default. */
if (timeout_ms == 0) {
timeout_ms = crm_get_msec(CRM_DEFAULT_OP_TIMEOUT_S);
@@ -1766,7 +1801,7 @@ cli_resource_execute_from_params(pcmk__output_t *out, const char *rsc_name,
exit_code = op->rc;
out->message(out, "resource-agent-action", resource_verbose, rsc_class,
- rsc_prov, rsc_type, rsc_name, action, override_hash, op->rc,
+ rsc_prov, rsc_type, rsc_name, rsc_action, override_hash, op->rc,
op->status, op->stdout_data, op->stderr_data);
} else {
exit_code = op->rc == 0 ? CRM_EX_ERROR : op->rc;
@@ -1790,27 +1825,15 @@ cli_resource_execute(pe_resource_t *rsc, const char *requested_name,
const char *rtype = NULL;
const char *rprov = NULL;
const char *rclass = NULL;
- const char *action = NULL;
GHashTable *params = NULL;
- if (pcmk__str_eq(rsc_action, "validate", pcmk__str_casei)) {
- action = "validate-all";
-
- } else if (pcmk__str_eq(rsc_action, "force-check", pcmk__str_casei)) {
- action = "monitor";
-
- } else if (pcmk__str_eq(rsc_action, "force-stop", pcmk__str_casei)) {
- action = rsc_action+6;
-
- } else if (pcmk__strcase_any_of(rsc_action, "force-start", "force-demote",
+ if (pcmk__strcase_any_of(rsc_action, "force-start", "force-demote",
"force-promote", NULL)) {
- action = rsc_action+6;
-
if(pe_rsc_is_clone(rsc)) {
GList *nodes = cli_resource_search(rsc, requested_name, data_set);
if(nodes != NULL && force == FALSE) {
out->err(out, "It is not safe to %s %s here: the cluster claims it is already active",
- action, rsc->id);
+ rsc_action, rsc->id);
out->err(out, "Try setting target-role=Stopped first or specifying "
"the force option");
return CRM_EX_UNSAFE;
@@ -1818,9 +1841,6 @@ cli_resource_execute(pe_resource_t *rsc, const char *requested_name,
g_list_free_full(nodes, free);
}
-
- } else {
- action = rsc_action;
}
if(pe_rsc_is_clone(rsc)) {
@@ -1831,6 +1851,9 @@ cli_resource_execute(pe_resource_t *rsc, const char *requested_name,
if(rsc->variant == pe_group) {
out->err(out, "Sorry, the %s option doesn't support group resources", rsc_action);
return CRM_EX_UNIMPLEMENT_FEATURE;
+ } else if (rsc->variant == pe_container || pe_rsc_is_bundled(rsc)) {
+ out->err(out, "Sorry, the %s option doesn't support bundled resources", rsc_action);
+ return CRM_EX_UNIMPLEMENT_FEATURE;
}
rclass = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS);
@@ -1841,12 +1864,12 @@ cli_resource_execute(pe_resource_t *rsc, const char *requested_name,
data_set);
if (timeout_ms == 0) {
- timeout_ms = pe_get_configured_timeout(rsc, action, data_set);
+ timeout_ms = pe_get_configured_timeout(rsc, get_action(rsc_action), data_set);
}
rid = pe_rsc_is_anon_clone(rsc->parent)? requested_name : rsc->id;
- exit_code = cli_resource_execute_from_params(out, rid, rclass, rprov, rtype, action,
+ exit_code = cli_resource_execute_from_params(out, rid, rclass, rprov, rtype, rsc_action,
params, override_hash, timeout_ms,
resource_verbose, force, check_level);
return exit_code;
--
1.8.3.1
From 289cd231186755d99c1262eb9f968dc852409588 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Fri, 16 Jul 2021 13:20:55 +0200
Subject: [PATCH 2/2] Refactor: crm_resource: remove duplicate Overriding
message that's handled elsewhere
---
tools/crm_resource_runtime.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c
index 59e6df5..ce037c5 100644
--- a/tools/crm_resource_runtime.c
+++ b/tools/crm_resource_runtime.c
@@ -1791,8 +1791,6 @@ cli_resource_execute_from_params(pcmk__output_t *out, const char *rsc_name,
g_hash_table_iter_init(&iter, override_hash);
while (g_hash_table_iter_next(&iter, (gpointer *) & name, (gpointer *) & value)) {
- out->info(out, "Overriding the cluster configuration for '%s' with '%s' = '%s'",
- rsc_name, name, value);
g_hash_table_replace(op->params, strdup(name), strdup(value));
}
}
--
1.8.3.1

View File

@ -1,846 +0,0 @@
From df587aaec07b4a08364d4024b3d0c73e6dede562 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Mon, 9 Nov 2020 14:55:42 -0600
Subject: [PATCH 1/9] Refactor: scheduler: simplify XML attribute filtering
function
---
lib/pengine/pe_digest.c | 52 ++++++++++++++++++++++++++-----------------------
1 file changed, 28 insertions(+), 24 deletions(-)
diff --git a/lib/pengine/pe_digest.c b/lib/pengine/pe_digest.c
index 5bcd22b..1e119f9 100644
--- a/lib/pengine/pe_digest.c
+++ b/lib/pengine/pe_digest.c
@@ -45,30 +45,38 @@ pe__free_digests(gpointer ptr)
}
}
+/*!
+ * \internal
+ * \brief Remove named attributes from an XML element
+ *
+ * \param[in,out] param_set XML to be filtered
+ * \param[in] param_string Space-separated list of attribute names
+ * \param[in] need_present Whether to remove attributes that match,
+ * or those that don't match
+ */
static void
-filter_parameters(xmlNode * param_set, const char *param_string, bool need_present)
+filter_parameters(xmlNode *param_set, const char *param_string,
+ bool need_present)
{
- if (param_set && param_string) {
- xmlAttrPtr xIter = param_set->properties;
-
- while (xIter) {
- const char *prop_name = (const char *)xIter->name;
- char *name = crm_strdup_printf(" %s ", prop_name);
- char *match = strstr(param_string, name);
+ if ((param_set == NULL) || (param_string == NULL)) {
+ return;
+ }
+ for (xmlAttrPtr xIter = param_set->properties; xIter; ) {
+ const char *prop_name = (const char *) xIter->name;
+ char *name = crm_strdup_printf(" %s ", prop_name);
+ char *match = strstr(param_string, name);
- free(name);
+ free(name);
- // Do now, because current entry might get removed below
- xIter = xIter->next;
+ // Do now, because current entry might get removed below
+ xIter = xIter->next;
- if (need_present && match == NULL) {
- crm_trace("%s not found in %s", prop_name, param_string);
- xml_remove_prop(param_set, prop_name);
+ if ((need_present && (match == NULL))
+ || (!need_present && (match != NULL))) {
- } else if (need_present == FALSE && match) {
- crm_trace("%s found in %s", prop_name, param_string);
- xml_remove_prop(param_set, prop_name);
- }
+ crm_trace("Filtering %s (%sfound in '%s')",
+ prop_name, (need_present? "not " : ""), param_string);
+ xml_remove_prop(param_set, prop_name);
}
}
}
@@ -203,9 +211,7 @@ calculate_secure_digest(op_digest_cache_t *data, pe_resource_t *rsc,
g_hash_table_foreach(overrides, hash2field, data->params_secure);
}
g_hash_table_foreach(rsc->parameters, hash2field, data->params_secure);
- if (secure_list != NULL) {
- filter_parameters(data->params_secure, secure_list, FALSE);
- }
+ filter_parameters(data->params_secure, secure_list, FALSE);
if (pcmk_is_set(pcmk_get_ra_caps(class),
pcmk_ra_cap_fence_params)) {
/* For stonith resources, Pacemaker adds special parameters,
@@ -259,9 +265,7 @@ calculate_restart_digest(op_digest_cache_t *data, xmlNode *xml_op,
// Then filter out reloadable parameters, if any
value = crm_element_value(xml_op, XML_LRM_ATTR_OP_RESTART);
- if (value != NULL) {
- filter_parameters(data->params_restart, value, TRUE);
- }
+ filter_parameters(data->params_restart, value, TRUE);
value = crm_element_value(xml_op, XML_ATTR_CRM_VERSION);
data->digest_restart_calc = calculate_operation_digest(data->params_restart,
--
1.8.3.1
From f030af8771601d46947ac9276538c46c6c296504 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Mon, 9 Nov 2020 18:37:37 -0600
Subject: [PATCH 2/9] Refactor: scheduler: remember whether action is probe
when unpacking
... to reduce code duplication and improve readability
---
lib/pengine/utils.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c
index 04110be..b0922fa 100644
--- a/lib/pengine/utils.c
+++ b/lib/pengine/utils.c
@@ -995,6 +995,8 @@ unpack_operation(pe_action_t * action, xmlNode * xml_obj, pe_resource_t * contai
{
int timeout_ms = 0;
const char *value = NULL;
+ bool is_probe = pcmk__str_eq(action->task, RSC_STATUS, pcmk__str_casei)
+ && (interval_ms == 0);
#if ENABLE_VERSIONED_ATTRS
pe_rsc_action_details_t *rsc_details = NULL;
#endif
@@ -1026,8 +1028,7 @@ unpack_operation(pe_action_t * action, xmlNode * xml_obj, pe_resource_t * contai
action->meta, NULL, FALSE, data_set);
// Determine probe default timeout differently
- if (pcmk__str_eq(action->task, RSC_STATUS, pcmk__str_casei)
- && (interval_ms == 0)) {
+ if (is_probe) {
xmlNode *min_interval_mon = find_min_interval_mon(action->rsc, FALSE);
if (min_interval_mon) {
@@ -1099,8 +1100,7 @@ unpack_operation(pe_action_t * action, xmlNode * xml_obj, pe_resource_t * contai
if (pcmk_is_set(pcmk_get_ra_caps(rsc_rule_data.standard),
pcmk_ra_cap_fence_params)
&& (pcmk__str_eq(action->task, RSC_START, pcmk__str_casei)
- || (pcmk__str_eq(action->task, RSC_STATUS, pcmk__str_casei)
- && (interval_ms == 0)))
+ || is_probe)
&& action->rsc->parameters) {
value = g_hash_table_lookup(action->rsc->parameters,
--
1.8.3.1
From 9de547849697cd6a3581db3f83b04f68d0405d9d Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Tue, 10 Nov 2020 15:15:01 -0600
Subject: [PATCH 3/9] Refactor: scheduler: don't include originally unpacked
resource parameters in digest
Previously, when calculating an operation digest, calculate_main_digest() would
grab the following, in order of highest to lowest precedence:
* instance attributes evaluated for the appropriate node
* instance attributes specified with the operation
* instance attributes as originally unpacked (without evaluating for any node)
* resource meta-attributes
Adding the originally unpacked instance attributes was redundant, since
node-evaluated instance attributes would always be a superset of those and
would take precedence.
---
lib/pengine/pe_digest.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/lib/pengine/pe_digest.c b/lib/pengine/pe_digest.c
index 1e119f9..dd6b753 100644
--- a/lib/pengine/pe_digest.c
+++ b/lib/pengine/pe_digest.c
@@ -162,7 +162,6 @@ calculate_main_digest(op_digest_cache_t *data, pe_resource_t *rsc,
}
g_hash_table_foreach(local_rsc_params, hash2field, data->params_all);
g_hash_table_foreach(action->extra, hash2field, data->params_all);
- g_hash_table_foreach(rsc->parameters, hash2field, data->params_all);
g_hash_table_foreach(action->meta, hash2metafield, data->params_all);
#if ENABLE_VERSIONED_ATTRS
--
1.8.3.1
From e9921b2ab3e9eeab6227d97cc12b85fa04dfd187 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Fri, 13 Nov 2020 09:27:12 -0600
Subject: [PATCH 4/9] Refactor: scheduler: reuse existing function to check for
remote in XML
... to reduce code duplication and improve readability
---
lib/pengine/bundle.c | 21 +++------------------
1 file changed, 3 insertions(+), 18 deletions(-)
diff --git a/lib/pengine/bundle.c b/lib/pengine/bundle.c
index 76730c7..4f6eac3 100644
--- a/lib/pengine/bundle.c
+++ b/lib/pengine/bundle.c
@@ -959,28 +959,13 @@ pe__bundle_needs_remote_name(pe_resource_t *rsc)
const char *value;
if (rsc == NULL) {
- return FALSE;
+ return false;
}
value = g_hash_table_lookup(rsc->parameters, XML_RSC_ATTR_REMOTE_RA_ADDR);
- if (!pcmk__str_eq(value, "#uname", pcmk__str_casei)) {
- return FALSE;
- } else {
- const char *match[3][2] = {
- { XML_ATTR_TYPE, "remote" },
- { XML_AGENT_ATTR_CLASS, PCMK_RESOURCE_CLASS_OCF },
- { XML_AGENT_ATTR_PROVIDER, "pacemaker" },
- };
-
- for (int m = 0; m < 3; m++) {
- value = crm_element_value(rsc->xml, match[m][0]);
- if (!pcmk__str_eq(value, match[m][1], pcmk__str_casei)) {
- return FALSE;
- }
- }
- }
- return TRUE;
+ return pcmk__str_eq(value, "#uname", pcmk__str_casei)
+ && xml_contains_remote_node(rsc->xml);
}
const char *
--
1.8.3.1
From 0f220e1cd25ec095492ac4b346452520f4b71cf1 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Wed, 11 Nov 2020 15:29:46 -0600
Subject: [PATCH 5/9] Refactor: scheduler: remove dead code
Several internal expression-testing functions were unused. While they might
have had some potential future value, the abundance of similarly named
functions made debugging difficult. Comment blocks were added to the functions
they wrapped, which should add similar value.
Also, we had an internal wrapper for pe__eval_date_expr() that was used
only in crm_rule, so it was moved there.
---
include/crm/pengine/rules_internal.h | 10 +--
lib/pengine/rules.c | 130 +++++++++++------------------------
tools/crm_rule.c | 27 +++++++-
3 files changed, 66 insertions(+), 101 deletions(-)
diff --git a/include/crm/pengine/rules_internal.h b/include/crm/pengine/rules_internal.h
index f60263a..7380826 100644
--- a/include/crm/pengine/rules_internal.h
+++ b/include/crm/pengine/rules_internal.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2019 the Pacemaker project contributors
+ * Copyright 2015-2020 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -28,14 +28,6 @@ gboolean pe__eval_op_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data);
gboolean pe__eval_role_expr(xmlNode *expr, pe_rule_eval_data_t *rule_data);
gboolean pe__eval_rsc_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data);
-int pe_eval_date_expression(xmlNode *time_expr,
- crm_time_t *now,
- crm_time_t *next_change);
-gboolean pe_test_date_expression(xmlNode *time_expr, crm_time_t *now,
- crm_time_t *next_change);
int pe_cron_range_satisfied(crm_time_t * now, xmlNode * cron_spec);
-gboolean pe_test_attr_expression(xmlNode *expr, GHashTable *hash, crm_time_t *now,
- pe_match_data_t *match_data);
-gboolean pe_test_role_expression(xmlNode * expr, enum rsc_role_e role, crm_time_t * now);
#endif
diff --git a/lib/pengine/rules.c b/lib/pengine/rules.c
index 28562aa..be30e67 100644
--- a/lib/pengine/rules.c
+++ b/lib/pengine/rules.c
@@ -140,37 +140,6 @@ find_expression_type(xmlNode * expr)
return attr_expr;
}
-gboolean
-pe_test_role_expression(xmlNode *expr, enum rsc_role_e role, crm_time_t *now)
-{
- pe_rule_eval_data_t rule_data = {
- .node_hash = NULL,
- .role = role,
- .now = now,
- .match_data = NULL,
- .rsc_data = NULL,
- .op_data = NULL
- };
-
- return pe__eval_role_expr(expr, &rule_data);
-}
-
-gboolean
-pe_test_attr_expression(xmlNode *expr, GHashTable *hash, crm_time_t *now,
- pe_match_data_t *match_data)
-{
- pe_rule_eval_data_t rule_data = {
- .node_hash = hash,
- .role = RSC_ROLE_UNKNOWN,
- .now = now,
- .match_data = match_data,
- .rsc_data = NULL,
- .op_data = NULL
- };
-
- return pe__eval_attr_expr(expr, &rule_data);
-}
-
/* As per the nethack rules:
*
* moon period = 29.53058 days ~= 30, year = 365.2422 days
@@ -331,38 +300,6 @@ pe_parse_xml_duration(crm_time_t * start, xmlNode * duration_spec)
return end;
}
-/*!
- * \internal
- * \brief Test a date expression (pass/fail) for a specific time
- *
- * \param[in] time_expr date_expression XML
- * \param[in] now Time for which to evaluate expression
- * \param[out] next_change If not NULL, set to when evaluation will change
- *
- * \return TRUE if date expression is in effect at given time, FALSE otherwise
- */
-gboolean
-pe_test_date_expression(xmlNode *expr, crm_time_t *now, crm_time_t *next_change)
-{
- pe_rule_eval_data_t rule_data = {
- .node_hash = NULL,
- .role = RSC_ROLE_UNKNOWN,
- .now = now,
- .match_data = NULL,
- .rsc_data = NULL,
- .op_data = NULL
- };
-
- switch (pe__eval_date_expr(expr, &rule_data, next_change)) {
- case pcmk_rc_within_range:
- case pcmk_rc_ok:
- return TRUE;
-
- default:
- return FALSE;
- }
-}
-
// Set next_change to t if t is earlier
static void
crm_time_set_if_earlier(crm_time_t *next_change, crm_time_t *t)
@@ -375,31 +312,6 @@ crm_time_set_if_earlier(crm_time_t *next_change, crm_time_t *t)
}
}
-/*!
- * \internal
- * \brief Evaluate a date expression for a specific time
- *
- * \param[in] time_expr date_expression XML
- * \param[in] now Time for which to evaluate expression
- * \param[out] next_change If not NULL, set to when evaluation will change
- *
- * \return Standard Pacemaker return code
- */
-int
-pe_eval_date_expression(xmlNode *expr, crm_time_t *now, crm_time_t *next_change)
-{
- pe_rule_eval_data_t rule_data = {
- .node_hash = NULL,
- .role = RSC_ROLE_UNKNOWN,
- .now = now,
- .match_data = NULL,
- .rsc_data = NULL,
- .op_data = NULL
- };
-
- return pe__eval_date_expr(expr, &rule_data, next_change);
-}
-
// Information about a block of nvpair elements
typedef struct sorted_set_s {
int score; // This block's score for sorting
@@ -908,7 +820,16 @@ pe_eval_subexpr(xmlNode *expr, pe_rule_eval_data_t *rule_data, crm_time_t *next_
break;
case time_expr:
- accept = pe_test_date_expression(expr, rule_data->now, next_change);
+ switch (pe__eval_date_expr(expr, rule_data, next_change)) {
+ case pcmk_rc_within_range:
+ case pcmk_rc_ok:
+ accept = TRUE;
+ break;
+
+ default:
+ accept = FALSE;
+ break;
+ }
break;
case role_expr:
@@ -1104,6 +1025,16 @@ accept_attr_expr(const char *l_val, const char *r_val, const char *type,
return false; // Should never reach this point
}
+/*!
+ * \internal
+ * \brief Evaluate a node attribute expression based on #uname, #id, #kind,
+ * or a generic node attribute
+ *
+ * \param[in] expr XML of rule expression
+ * \param[in] rule_data The match_data and node_hash members are used
+ *
+ * \return TRUE if rule_data satisfies the expression, FALSE otherwise
+ */
gboolean
pe__eval_attr_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data)
{
@@ -1169,8 +1100,16 @@ pe__eval_attr_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data)
return accept_attr_expr(h_val, value, type, op);
}
-
-
+/*!
+ * \internal
+ * \brief Evaluate a date_expression
+ *
+ * \param[in] expr XML of rule expression
+ * \param[in] rule_data Only the now member is used
+ * \param[out] next_change If not NULL, set to when evaluation will change
+ *
+ * \return Standard Pacemaker return code
+ */
int
pe__eval_date_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data, crm_time_t *next_change)
{
@@ -1285,6 +1224,15 @@ pe__eval_op_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data) {
return TRUE;
}
+/*!
+ * \internal
+ * \brief Evaluate a node attribute expression based on #role
+ *
+ * \param[in] expr XML of rule expression
+ * \param[in] rule_data Only the role member is used
+ *
+ * \return TRUE if rule_data->role satisfies the expression, FALSE otherwise
+ */
gboolean
pe__eval_role_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data)
{
diff --git a/tools/crm_rule.c b/tools/crm_rule.c
index 0e44828..2871f3d 100644
--- a/tools/crm_rule.c
+++ b/tools/crm_rule.c
@@ -75,6 +75,31 @@ mode_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError **e
return TRUE;
}
+/*!
+ * \internal
+ * \brief Evaluate a date expression for a specific time
+ *
+ * \param[in] time_expr date_expression XML
+ * \param[in] now Time for which to evaluate expression
+ * \param[out] next_change If not NULL, set to when evaluation will change
+ *
+ * \return Standard Pacemaker return code
+ */
+static int
+eval_date_expression(xmlNode *expr, crm_time_t *now, crm_time_t *next_change)
+{
+ pe_rule_eval_data_t rule_data = {
+ .node_hash = NULL,
+ .role = RSC_ROLE_UNKNOWN,
+ .now = now,
+ .match_data = NULL,
+ .rsc_data = NULL,
+ .op_data = NULL
+ };
+
+ return pe__eval_date_expr(expr, &rule_data, next_change);
+}
+
static int
crm_rule_check(pe_working_set_t *data_set, const char *rule_id, crm_time_t *effective_date)
{
@@ -156,7 +181,7 @@ crm_rule_check(pe_working_set_t *data_set, const char *rule_id, crm_time_t *effe
CRM_ASSERT(match != NULL);
CRM_ASSERT(find_expression_type(match) == time_expr);
- rc = pe_eval_date_expression(match, effective_date, NULL);
+ rc = eval_date_expression(match, effective_date, NULL);
if (rc == pcmk_rc_within_range) {
printf("Rule %s is still in effect\n", rule_id);
--
1.8.3.1
From 91a6ec4bec86de7389fcd64cb27e315da760f0dd Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Wed, 11 Nov 2020 16:44:57 -0600
Subject: [PATCH 6/9] Refactor: scheduler: make constraint unpacking function
static
... for linker efficiency and readability. Also change the return type to void
since it was ignored (and the same for some related functions).
---
include/pcmki/pcmki_sched_allocate.h | 4 +--
lib/pacemaker/pcmk_sched_constraints.c | 46 ++++++++++++++++------------------
2 files changed, 23 insertions(+), 27 deletions(-)
diff --git a/include/pcmki/pcmki_sched_allocate.h b/include/pcmki/pcmki_sched_allocate.h
index efc0da6..a7f8c11 100644
--- a/include/pcmki/pcmki_sched_allocate.h
+++ b/include/pcmki/pcmki_sched_allocate.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2019 the Pacemaker project contributors
+ * Copyright 2004-2020 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -143,8 +143,6 @@ extern gboolean unpack_rsc_order(xmlNode * xml_obj, pe_working_set_t * data_set)
extern gboolean unpack_rsc_colocation(xmlNode * xml_obj, pe_working_set_t * data_set);
-extern gboolean unpack_location(xmlNode * xml_obj, pe_working_set_t * data_set);
-
extern gboolean unpack_rsc_ticket(xmlNode * xml_obj, pe_working_set_t * data_set);
void LogNodeActions(pe_working_set_t * data_set, gboolean terminal);
diff --git a/lib/pacemaker/pcmk_sched_constraints.c b/lib/pacemaker/pcmk_sched_constraints.c
index 6ed2d8c..121754d 100644
--- a/lib/pacemaker/pcmk_sched_constraints.c
+++ b/lib/pacemaker/pcmk_sched_constraints.c
@@ -48,6 +48,7 @@ static pe__location_t *generate_location_rule(pe_resource_t *rsc,
crm_time_t *next_change,
pe_working_set_t *data_set,
pe_match_data_t *match_data);
+static void unpack_location(xmlNode *xml_obj, pe_working_set_t *data_set);
static bool
evaluate_lifetime(xmlNode *lifetime, pe_working_set_t *data_set)
@@ -709,11 +710,13 @@ tag_to_set(xmlNode * xml_obj, xmlNode ** rsc_set, const char * attr,
return TRUE;
}
-static gboolean unpack_rsc_location(xmlNode * xml_obj, pe_resource_t * rsc_lh, const char * role,
- const char * score, pe_working_set_t * data_set, pe_match_data_t * match_data);
+static void unpack_rsc_location(xmlNode *xml_obj, pe_resource_t *rsc_lh,
+ const char *role, const char *score,
+ pe_working_set_t *data_set,
+ pe_match_data_t *match_data);
-static gboolean
-unpack_simple_location(xmlNode * xml_obj, pe_working_set_t * data_set)
+static void
+unpack_simple_location(xmlNode *xml_obj, pe_working_set_t *data_set)
{
const char *id = crm_element_value(xml_obj, XML_ATTR_ID);
const char *value = crm_element_value(xml_obj, XML_LOC_ATTR_SOURCE);
@@ -721,7 +724,7 @@ unpack_simple_location(xmlNode * xml_obj, pe_working_set_t * data_set)
if(value) {
pe_resource_t *rsc_lh = pe_find_constraint_resource(data_set->resources, value);
- return unpack_rsc_location(xml_obj, rsc_lh, NULL, NULL, data_set, NULL);
+ unpack_rsc_location(xml_obj, rsc_lh, NULL, NULL, data_set, NULL);
}
value = crm_element_value(xml_obj, XML_LOC_ATTR_SOURCE_PATTERN);
@@ -741,7 +744,7 @@ unpack_simple_location(xmlNode * xml_obj, pe_working_set_t * data_set)
" has invalid value '%s'", id, value);
regfree(r_patt);
free(r_patt);
- return FALSE;
+ return;
}
for (rIter = data_set->resources; rIter; rIter = rIter->next) {
@@ -787,13 +790,12 @@ unpack_simple_location(xmlNode * xml_obj, pe_working_set_t * data_set)
regfree(r_patt);
free(r_patt);
}
-
- return FALSE;
}
-static gboolean
-unpack_rsc_location(xmlNode * xml_obj, pe_resource_t * rsc_lh, const char * role,
- const char * score, pe_working_set_t * data_set, pe_match_data_t * match_data)
+static void
+unpack_rsc_location(xmlNode *xml_obj, pe_resource_t *rsc_lh, const char *role,
+ const char *score, pe_working_set_t *data_set,
+ pe_match_data_t *match_data)
{
pe__location_t *location = NULL;
const char *id_lh = crm_element_value(xml_obj, XML_LOC_ATTR_SOURCE);
@@ -804,7 +806,7 @@ unpack_rsc_location(xmlNode * xml_obj, pe_resource_t * rsc_lh, const char * role
if (rsc_lh == NULL) {
pcmk__config_warn("Ignoring constraint '%s' because resource '%s' "
"does not exist", id, id_lh);
- return FALSE;
+ return;
}
if (score == NULL) {
@@ -816,7 +818,7 @@ unpack_rsc_location(xmlNode * xml_obj, pe_resource_t * rsc_lh, const char * role
pe_node_t *match = pe_find_node(data_set->nodes, node);
if (!match) {
- return FALSE;
+ return;
}
location = rsc2node_new(id, rsc_lh, score_i, discovery, match, data_set);
@@ -850,7 +852,7 @@ unpack_rsc_location(xmlNode * xml_obj, pe_resource_t * rsc_lh, const char * role
pe__update_recheck_time(t, data_set);
}
crm_time_free(next_change);
- return TRUE;
+ return;
}
if (role == NULL) {
@@ -860,7 +862,7 @@ unpack_rsc_location(xmlNode * xml_obj, pe_resource_t * rsc_lh, const char * role
if (location && role) {
if (text2role(role) == RSC_ROLE_UNKNOWN) {
pe_err("Invalid constraint %s: Bad role %s", id, role);
- return FALSE;
+ return;
} else {
enum rsc_role_e r = text2role(role);
@@ -877,8 +879,6 @@ unpack_rsc_location(xmlNode * xml_obj, pe_resource_t * rsc_lh, const char * role
}
}
}
-
- return TRUE;
}
static gboolean
@@ -992,8 +992,8 @@ unpack_location_set(xmlNode * location, xmlNode * set, pe_working_set_t * data_s
return TRUE;
}
-gboolean
-unpack_location(xmlNode * xml_obj, pe_working_set_t * data_set)
+static void
+unpack_location(xmlNode *xml_obj, pe_working_set_t *data_set)
{
xmlNode *set = NULL;
gboolean any_sets = FALSE;
@@ -1002,7 +1002,7 @@ unpack_location(xmlNode * xml_obj, pe_working_set_t * data_set)
xmlNode *expanded_xml = NULL;
if (unpack_location_tags(xml_obj, &expanded_xml, data_set) == FALSE) {
- return FALSE;
+ return;
}
if (expanded_xml) {
@@ -1020,7 +1020,7 @@ unpack_location(xmlNode * xml_obj, pe_working_set_t * data_set)
if (expanded_xml) {
free_xml(expanded_xml);
}
- return FALSE;
+ return;
}
}
}
@@ -1031,10 +1031,8 @@ unpack_location(xmlNode * xml_obj, pe_working_set_t * data_set)
}
if (any_sets == FALSE) {
- return unpack_simple_location(xml_obj, data_set);
+ unpack_simple_location(xml_obj, data_set);
}
-
- return TRUE;
}
static int
--
1.8.3.1
From df842adafca8ba56ddb5b448490ffef54ea785d4 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Fri, 13 Nov 2020 09:19:51 -0600
Subject: [PATCH 7/9] Refactor: scheduler: trivial refactoring of nvpair
evaluation
... for readability
---
lib/pengine/rules.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/lib/pengine/rules.c b/lib/pengine/rules.c
index be30e67..86e7899 100644
--- a/lib/pengine/rules.c
+++ b/lib/pengine/rules.c
@@ -529,20 +529,19 @@ static GList *
make_pairs(xmlNode *top, xmlNode *xml_obj, const char *set_name,
const char *always_first)
{
- GListPtr unsorted = NULL;
- const char *score = NULL;
- sorted_set_t *pair = NULL;
- xmlNode *attr_set = NULL;
+ GList *unsorted = NULL;
if (xml_obj == NULL) {
return NULL;
}
- for (attr_set = pcmk__xe_first_child(xml_obj); attr_set != NULL;
+ for (xmlNode *attr_set = pcmk__xe_first_child(xml_obj); attr_set != NULL;
attr_set = pcmk__xe_next(attr_set)) {
- /* Uncertain if set_name == NULL check is strictly necessary here */
- if (pcmk__str_eq(set_name, (const char *)attr_set->name, pcmk__str_null_matches)) {
- pair = NULL;
+ if (pcmk__str_eq(set_name, (const char *) attr_set->name,
+ pcmk__str_null_matches)) {
+ const char *score = NULL;
+ sorted_set_t *pair = NULL;
+
attr_set = expand_idref(attr_set, top);
if (attr_set == NULL) {
continue;
--
1.8.3.1
From 373c224ac1c41bd47a928a7523744c6c678a6543 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Fri, 13 Nov 2020 09:21:35 -0600
Subject: [PATCH 8/9] Low: scheduler: correctly skip dangling id-ref
When evaluating XML nvpair blocks, make_pairs() previously reused the
"for" loop variable when expanding id-ref's. However if the id-ref was dangling
(only possible if schema enforcement is turned off), this would make it NULL
and thus exiting the loop instead of continuing.
---
lib/pengine/rules.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/lib/pengine/rules.c b/lib/pengine/rules.c
index 86e7899..1bd807f 100644
--- a/lib/pengine/rules.c
+++ b/lib/pengine/rules.c
@@ -541,18 +541,19 @@ make_pairs(xmlNode *top, xmlNode *xml_obj, const char *set_name,
pcmk__str_null_matches)) {
const char *score = NULL;
sorted_set_t *pair = NULL;
+ xmlNode *expanded_attr_set = expand_idref(attr_set, top);
- attr_set = expand_idref(attr_set, top);
- if (attr_set == NULL) {
+ if (expanded_attr_set == NULL) {
+ // Schema (if not "none") prevents this
continue;
}
pair = calloc(1, sizeof(sorted_set_t));
- pair->name = ID(attr_set);
+ pair->name = ID(expanded_attr_set);
pair->special_name = always_first;
- pair->attr_set = attr_set;
+ pair->attr_set = expanded_attr_set;
- score = crm_element_value(attr_set, XML_RULE_ATTR_SCORE);
+ score = crm_element_value(expanded_attr_set, XML_RULE_ATTR_SCORE);
pair->score = char2score(score);
unsorted = g_list_prepend(unsorted, pair);
--
1.8.3.1
From b59717751c168ec745bedbcc5696bee11036d931 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Thu, 12 Nov 2020 14:37:27 -0600
Subject: [PATCH 9/9] Low: scheduler: treat missing parameter as NULL in rules
with value-source
Previously, if value-source were set to "param" or "meta", and an affected
resource did not have the specified parameter, the parameter name would wrongly
be used as the value to compare against. Now, use NULL as the value to compare
against.
---
lib/pengine/rules.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/lib/pengine/rules.c b/lib/pengine/rules.c
index 1bd807f..e5d452f 100644
--- a/lib/pengine/rules.c
+++ b/lib/pengine/rules.c
@@ -1041,6 +1041,7 @@ pe__eval_attr_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data)
gboolean attr_allocated = FALSE;
const char *h_val = NULL;
GHashTable *table = NULL;
+ bool literal = true;
const char *op = NULL;
const char *type = NULL;
@@ -1071,18 +1072,22 @@ pe__eval_attr_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data)
}
if (pcmk__str_eq(value_source, "param", pcmk__str_casei)) {
+ literal = false;
table = rule_data->match_data->params;
} else if (pcmk__str_eq(value_source, "meta", pcmk__str_casei)) {
+ literal = false;
table = rule_data->match_data->meta;
}
}
- if (table) {
+ if (!literal) {
const char *param_name = value;
const char *param_value = NULL;
- if (param_name && param_name[0]) {
- if ((param_value = (const char *)g_hash_table_lookup(table, param_name))) {
+ value = NULL;
+ if ((table != NULL) && !pcmk__str_empty(param_name)) {
+ param_value = (const char *)g_hash_table_lookup(table, param_name);
+ if (param_value != NULL) {
value = param_value;
}
}
--
1.8.3.1

View File

@ -1,26 +0,0 @@
From d1b6b6cb5151763888ac8bc55708d2e7cbbf590b Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Thu, 19 Nov 2020 13:35:31 -0500
Subject: [PATCH] Fix: scheduler: Fix output of failed actions without an
operation_key.
---
lib/pengine/pe_output.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/pengine/pe_output.c b/lib/pengine/pe_output.c
index 1a3f93d..b91348f 100644
--- a/lib/pengine/pe_output.c
+++ b/lib/pengine/pe_output.c
@@ -975,7 +975,7 @@ pe__failed_action_xml(pcmk__output_t *out, va_list args) {
xmlNodePtr node = pcmk__output_create_xml_node(out, "failure");
xmlSetProp(node, (pcmkXmlStr) (op_key ? "op_key" : "id"),
- (pcmkXmlStr) (op_key ? op_key : "id"));
+ (pcmkXmlStr) (op_key ? op_key : ID(xml_op)));
xmlSetProp(node, (pcmkXmlStr) "node",
(pcmkXmlStr) crm_element_value(xml_op, XML_ATTR_UNAME));
xmlSetProp(node, (pcmkXmlStr) "exitstatus",
--
1.8.3.1

View File

@ -0,0 +1,715 @@
From b0347f7b8e609420a7055d5fe537cc40ac0d1bb2 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Fri, 16 Jul 2021 11:08:05 -0500
Subject: [PATCH 1/3] Fix: scheduler: don't schedule probes of unmanaged
resources on pending nodes
Previously, custom_action() would set an action's optional or runnable flag in
the same, exclusive if-else sequence. This means that if an action should be
optional *and* runnable, only one would be set. In particular, this meant that
if a resource is unmanaged *and* its allocated node is pending, any probe would
be set to optional, but not unrunnable, and the controller could wrongly
attempt the probe before the join completed.
Now, optional is checked separately.
---
lib/pengine/utils.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c
index 5ef742e..965824b 100644
--- a/lib/pengine/utils.c
+++ b/lib/pengine/utils.c
@@ -541,6 +541,20 @@ custom_action(pe_resource_t * rsc, char *key, const char *task,
FALSE, data_set);
}
+ // Make the action optional if its resource is unmanaged
+ if (!pcmk_is_set(action->flags, pe_action_pseudo)
+ && (action->node != NULL)
+ && !pcmk_is_set(action->rsc->flags, pe_rsc_managed)
+ && (g_hash_table_lookup(action->meta,
+ XML_LRM_ATTR_INTERVAL_MS) == NULL)) {
+ pe_rsc_debug(rsc, "%s on %s is optional (%s is unmanaged)",
+ action->uuid, action->node->details->uname,
+ action->rsc->id);
+ pe__set_action_flags(action, pe_action_optional);
+ // We shouldn't clear runnable here because ... something
+ }
+
+ // Make the action runnable or unrunnable as appropriate
if (pcmk_is_set(action->flags, pe_action_pseudo)) {
/* leave untouched */
@@ -549,14 +563,6 @@ custom_action(pe_resource_t * rsc, char *key, const char *task,
action->uuid);
pe__clear_action_flags(action, pe_action_runnable);
- } else if (!pcmk_is_set(rsc->flags, pe_rsc_managed)
- && g_hash_table_lookup(action->meta,
- XML_LRM_ATTR_INTERVAL_MS) == NULL) {
- pe_rsc_debug(rsc, "%s on %s is optional (%s is unmanaged)",
- action->uuid, action->node->details->uname, rsc->id);
- pe__set_action_flags(action, pe_action_optional);
- //pe__clear_action_flags(action, pe_action_runnable);
-
} else if (!pcmk_is_set(action->flags, pe_action_dc)
&& !(action->node->details->online)
&& (!pe__is_guest_node(action->node)
--
1.8.3.1
From 520303b90eb707f5b7a9afa9b106e4a38b90f0f9 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Wed, 14 Jul 2021 17:18:44 -0500
Subject: [PATCH 2/3] Test: scheduler: update existing tests for probe
scheduling change
This is an improvement. Looking at bundle-probe-order-2 for example,
the bundle's first instance has this status to start:
* Replica[0]
* galera (ocf::heartbeat:galera): Stopped (unmanaged)
* galera-bundle-docker-0 (ocf::heartbeat:docker): Started centos2 (unmanaged)
* galera-bundle-0 (ocf::pacemaker:remote): Started centos2 (unmanaged)
After the changes, we now schedule recurring monitors for
galera-bundle-docker-0 and galera-bundle-0 on centos2, and a probe of galera:0
on galera-bundle-0, all of which are possible.
---
cts/scheduler/dot/bundle-probe-order-2.dot | 3 ++
cts/scheduler/dot/bundle-probe-order-3.dot | 1 +
cts/scheduler/exp/bundle-probe-order-2.exp | 33 ++++++++++++++++++++--
cts/scheduler/exp/bundle-probe-order-3.exp | 21 ++++++++++----
cts/scheduler/summary/bundle-probe-order-2.summary | 3 ++
cts/scheduler/summary/bundle-probe-order-3.summary | 1 +
6 files changed, 53 insertions(+), 9 deletions(-)
diff --git a/cts/scheduler/dot/bundle-probe-order-2.dot b/cts/scheduler/dot/bundle-probe-order-2.dot
index 0cce3fd..7706195 100644
--- a/cts/scheduler/dot/bundle-probe-order-2.dot
+++ b/cts/scheduler/dot/bundle-probe-order-2.dot
@@ -1,6 +1,9 @@
digraph "g" {
+"galera-bundle-0_monitor_30000 centos2" [ style=bold color="green" fontcolor="black"]
+"galera-bundle-docker-0_monitor_60000 centos2" [ style=bold color="green" fontcolor="black"]
"galera-bundle-docker-1_monitor_0 centos2" [ style=bold color="green" fontcolor="black"]
"galera-bundle-docker-2_monitor_0 centos1" [ style=bold color="green" fontcolor="black"]
"galera-bundle-docker-2_monitor_0 centos2" [ style=bold color="green" fontcolor="black"]
"galera-bundle-docker-2_monitor_0 centos3" [ style=bold color="green" fontcolor="black"]
+"galera:0_monitor_0 galera-bundle-0" [ style=bold color="green" fontcolor="black"]
}
diff --git a/cts/scheduler/dot/bundle-probe-order-3.dot b/cts/scheduler/dot/bundle-probe-order-3.dot
index a4b109f..53a384b 100644
--- a/cts/scheduler/dot/bundle-probe-order-3.dot
+++ b/cts/scheduler/dot/bundle-probe-order-3.dot
@@ -2,6 +2,7 @@
"galera-bundle-0_monitor_0 centos1" [ style=bold color="green" fontcolor="black"]
"galera-bundle-0_monitor_0 centos2" [ style=bold color="green" fontcolor="black"]
"galera-bundle-0_monitor_0 centos3" [ style=bold color="green" fontcolor="black"]
+"galera-bundle-docker-0_monitor_60000 centos2" [ style=bold color="green" fontcolor="black"]
"galera-bundle-docker-1_monitor_0 centos2" [ style=bold color="green" fontcolor="black"]
"galera-bundle-docker-2_monitor_0 centos1" [ style=bold color="green" fontcolor="black"]
"galera-bundle-docker-2_monitor_0 centos2" [ style=bold color="green" fontcolor="black"]
diff --git a/cts/scheduler/exp/bundle-probe-order-2.exp b/cts/scheduler/exp/bundle-probe-order-2.exp
index d6174e7..5b28050 100644
--- a/cts/scheduler/exp/bundle-probe-order-2.exp
+++ b/cts/scheduler/exp/bundle-probe-order-2.exp
@@ -1,6 +1,33 @@
<transition_graph cluster-delay="60s" stonith-timeout="60s" failed-stop-offset="INFINITY" failed-start-offset="INFINITY" transition_id="0">
<synapse id="0">
<action_set>
+ <rsc_op id="14" operation="monitor" operation_key="galera:0_monitor_0" on_node="galera-bundle-0" on_node_uuid="galera-bundle-0" router_node="centos2">
+ <primitive id="galera" long-id="galera:0" class="ocf" provider="heartbeat" type="galera"/>
+ <attributes CRM_meta_clone="0" CRM_meta_clone_max="3" CRM_meta_clone_node_max="1" CRM_meta_container_attribute_target="host" CRM_meta_globally_unique="false" CRM_meta_master_max="3" CRM_meta_master_node_max="1" CRM_meta_notify="false" CRM_meta_on_node="galera-bundle-0" CRM_meta_on_node_uuid="galera-bundle-0" CRM_meta_op_target_rc="7" CRM_meta_physical_host="centos2" CRM_meta_promoted_max="3" CRM_meta_promoted_node_max="1" CRM_meta_timeout="30000" cluster_host_map="centos1:centos1;centos2:centos2;centos3:centos3" enable_creation="true" wsrep_cluster_address="gcomm://centos1,centos2,centos3"/>
+ </rsc_op>
+ </action_set>
+ <inputs/>
+ </synapse>
+ <synapse id="1">
+ <action_set>
+ <rsc_op id="16" operation="monitor" operation_key="galera-bundle-docker-0_monitor_60000" on_node="centos2" on_node_uuid="2">
+ <primitive id="galera-bundle-docker-0" class="ocf" provider="heartbeat" type="docker"/>
+ <attributes CRM_meta_interval="60000" CRM_meta_name="monitor" CRM_meta_on_node="centos2" CRM_meta_on_node_uuid="2" CRM_meta_timeout="20000" allow_pull="true" force_kill="false" image="docker.io/tripleoupstream/centos-binary-mariadb:latest" monitor_cmd="/bin/true" mount_points="/var/log/pacemaker/bundles/galera-bundle-0" reuse="false" run_cmd="/usr/sbin/pacemaker_remoted" run_opts=" --restart=no -e PCMK_stderr=1 --net=host -e PCMK_remote_port=3123 -v /foo:/etc/libqb/force-filesystem-sockets:ro -v /etc/my.cnf.d/galera.cnf:/etc/my.cnf.d/galera.cnf:ro -v /var/lib/mysql:/var/lib/mysql:rw -v /etc/pacemaker/authkey:/etc/pacemaker/authkey -v /var/log/pacemaker/bundles/galera-bundle-0:/var/log --user=root --log-driver=journald "/>
+ </rsc_op>
+ </action_set>
+ <inputs/>
+ </synapse>
+ <synapse id="2">
+ <action_set>
+ <rsc_op id="18" operation="monitor" operation_key="galera-bundle-0_monitor_30000" on_node="centos2" on_node_uuid="2">
+ <primitive id="galera-bundle-0" class="ocf" provider="pacemaker" type="remote"/>
+ <attributes CRM_meta_container="galera-bundle-docker-0" CRM_meta_interval="30000" CRM_meta_name="monitor" CRM_meta_on_node="centos2" CRM_meta_on_node_uuid="2" CRM_meta_timeout="30000" addr="centos2" port="3123"/>
+ </rsc_op>
+ </action_set>
+ <inputs/>
+ </synapse>
+ <synapse id="3">
+ <action_set>
<rsc_op id="7" operation="monitor" operation_key="galera-bundle-docker-1_monitor_0" on_node="centos2" on_node_uuid="2">
<primitive id="galera-bundle-docker-1" class="ocf" provider="heartbeat" type="docker"/>
<attributes CRM_meta_on_node="centos2" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000" allow_pull="true" force_kill="false" image="docker.io/tripleoupstream/centos-binary-mariadb:latest" monitor_cmd="/bin/true" mount_points="/var/log/pacemaker/bundles/galera-bundle-1" reuse="false" run_cmd="/usr/sbin/pacemaker_remoted" run_opts=" --restart=no -e PCMK_stderr=1 --net=host -e PCMK_remote_port=3123 -v /foo:/etc/libqb/force-filesystem-sockets:ro -v /etc/my.cnf.d/galera.cnf:/etc/my.cnf.d/galera.cnf:ro -v /var/lib/mysql:/var/lib/mysql:rw -v /etc/pacemaker/authkey:/etc/pacemaker/authkey -v /var/log/pacemaker/bundles/galera-bundle-1:/var/log --user=root --log-driver=journald "/>
@@ -8,7 +35,7 @@
</action_set>
<inputs/>
</synapse>
- <synapse id="1">
+ <synapse id="4">
<action_set>
<rsc_op id="12" operation="monitor" operation_key="galera-bundle-docker-2_monitor_0" on_node="centos3" on_node_uuid="3">
<primitive id="galera-bundle-docker-2" class="ocf" provider="heartbeat" type="docker"/>
@@ -17,7 +44,7 @@
</action_set>
<inputs/>
</synapse>
- <synapse id="2">
+ <synapse id="5">
<action_set>
<rsc_op id="9" operation="monitor" operation_key="galera-bundle-docker-2_monitor_0" on_node="centos2" on_node_uuid="2">
<primitive id="galera-bundle-docker-2" class="ocf" provider="heartbeat" type="docker"/>
@@ -26,7 +53,7 @@
</action_set>
<inputs/>
</synapse>
- <synapse id="3">
+ <synapse id="6">
<action_set>
<rsc_op id="5" operation="monitor" operation_key="galera-bundle-docker-2_monitor_0" on_node="centos1" on_node_uuid="1">
<primitive id="galera-bundle-docker-2" class="ocf" provider="heartbeat" type="docker"/>
diff --git a/cts/scheduler/exp/bundle-probe-order-3.exp b/cts/scheduler/exp/bundle-probe-order-3.exp
index e1f60e7..69140a4 100644
--- a/cts/scheduler/exp/bundle-probe-order-3.exp
+++ b/cts/scheduler/exp/bundle-probe-order-3.exp
@@ -1,6 +1,15 @@
<transition_graph cluster-delay="60s" stonith-timeout="60s" failed-stop-offset="INFINITY" failed-start-offset="INFINITY" transition_id="0">
<synapse id="0">
<action_set>
+ <rsc_op id="16" operation="monitor" operation_key="galera-bundle-docker-0_monitor_60000" on_node="centos2" on_node_uuid="2">
+ <primitive id="galera-bundle-docker-0" class="ocf" provider="heartbeat" type="docker"/>
+ <attributes CRM_meta_interval="60000" CRM_meta_name="monitor" CRM_meta_on_node="centos2" CRM_meta_on_node_uuid="2" CRM_meta_timeout="20000" allow_pull="true" force_kill="false" image="docker.io/tripleoupstream/centos-binary-mariadb:latest" monitor_cmd="/bin/true" mount_points="/var/log/pacemaker/bundles/galera-bundle-0" reuse="false" run_cmd="/usr/sbin/pacemaker_remoted" run_opts=" --restart=no -e PCMK_stderr=1 --net=host -e PCMK_remote_port=3123 -v /foo:/etc/libqb/force-filesystem-sockets:ro -v /etc/my.cnf.d/galera.cnf:/etc/my.cnf.d/galera.cnf:ro -v /var/lib/mysql:/var/lib/mysql:rw -v /etc/pacemaker/authkey:/etc/pacemaker/authkey -v /var/log/pacemaker/bundles/galera-bundle-0:/var/log --user=root --log-driver=journald "/>
+ </rsc_op>
+ </action_set>
+ <inputs/>
+ </synapse>
+ <synapse id="1">
+ <action_set>
<rsc_op id="11" operation="monitor" operation_key="galera-bundle-0_monitor_0" on_node="centos3" on_node_uuid="3">
<primitive id="galera-bundle-0" class="ocf" provider="pacemaker" type="remote"/>
<attributes CRM_meta_container="galera-bundle-docker-0" CRM_meta_on_node="centos3" CRM_meta_on_node_uuid="3" CRM_meta_op_target_rc="7" CRM_meta_timeout="30000" addr="centos2" port="3123"/>
@@ -8,7 +17,7 @@
</action_set>
<inputs/>
</synapse>
- <synapse id="1">
+ <synapse id="2">
<action_set>
<rsc_op id="6" operation="monitor" operation_key="galera-bundle-0_monitor_0" on_node="centos2" on_node_uuid="2">
<primitive id="galera-bundle-0" class="ocf" provider="pacemaker" type="remote"/>
@@ -17,7 +26,7 @@
</action_set>
<inputs/>
</synapse>
- <synapse id="2">
+ <synapse id="3">
<action_set>
<rsc_op id="3" operation="monitor" operation_key="galera-bundle-0_monitor_0" on_node="centos1" on_node_uuid="1">
<primitive id="galera-bundle-0" class="ocf" provider="pacemaker" type="remote"/>
@@ -26,7 +35,7 @@
</action_set>
<inputs/>
</synapse>
- <synapse id="3">
+ <synapse id="4">
<action_set>
<rsc_op id="7" operation="monitor" operation_key="galera-bundle-docker-1_monitor_0" on_node="centos2" on_node_uuid="2">
<primitive id="galera-bundle-docker-1" class="ocf" provider="heartbeat" type="docker"/>
@@ -35,7 +44,7 @@
</action_set>
<inputs/>
</synapse>
- <synapse id="4">
+ <synapse id="5">
<action_set>
<rsc_op id="13" operation="monitor" operation_key="galera-bundle-docker-2_monitor_0" on_node="centos3" on_node_uuid="3">
<primitive id="galera-bundle-docker-2" class="ocf" provider="heartbeat" type="docker"/>
@@ -44,7 +53,7 @@
</action_set>
<inputs/>
</synapse>
- <synapse id="5">
+ <synapse id="6">
<action_set>
<rsc_op id="9" operation="monitor" operation_key="galera-bundle-docker-2_monitor_0" on_node="centos2" on_node_uuid="2">
<primitive id="galera-bundle-docker-2" class="ocf" provider="heartbeat" type="docker"/>
@@ -53,7 +62,7 @@
</action_set>
<inputs/>
</synapse>
- <synapse id="6">
+ <synapse id="7">
<action_set>
<rsc_op id="4" operation="monitor" operation_key="galera-bundle-docker-2_monitor_0" on_node="centos1" on_node_uuid="1">
<primitive id="galera-bundle-docker-2" class="ocf" provider="heartbeat" type="docker"/>
diff --git a/cts/scheduler/summary/bundle-probe-order-2.summary b/cts/scheduler/summary/bundle-probe-order-2.summary
index 681d607..024c472 100644
--- a/cts/scheduler/summary/bundle-probe-order-2.summary
+++ b/cts/scheduler/summary/bundle-probe-order-2.summary
@@ -13,6 +13,9 @@ Current cluster status:
Transition Summary:
Executing Cluster Transition:
+ * Resource action: galera:0 monitor on galera-bundle-0
+ * Resource action: galera-bundle-docker-0 monitor=60000 on centos2
+ * Resource action: galera-bundle-0 monitor=30000 on centos2
* Resource action: galera-bundle-docker-1 monitor on centos2
* Resource action: galera-bundle-docker-2 monitor on centos3
* Resource action: galera-bundle-docker-2 monitor on centos2
diff --git a/cts/scheduler/summary/bundle-probe-order-3.summary b/cts/scheduler/summary/bundle-probe-order-3.summary
index f089618..331bd87 100644
--- a/cts/scheduler/summary/bundle-probe-order-3.summary
+++ b/cts/scheduler/summary/bundle-probe-order-3.summary
@@ -12,6 +12,7 @@ Current cluster status:
Transition Summary:
Executing Cluster Transition:
+ * Resource action: galera-bundle-docker-0 monitor=60000 on centos2
* Resource action: galera-bundle-0 monitor on centos3
* Resource action: galera-bundle-0 monitor on centos2
* Resource action: galera-bundle-0 monitor on centos1
--
1.8.3.1
From cb9c294a7ef22916866e0e42e51e88c2b1a61c2e Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Wed, 14 Jul 2021 17:23:11 -0500
Subject: [PATCH 3/3] Test: scheduler: add test for probe of unmanaged resource
on pending node
No probes should be scheduled in this case
---
cts/cts-scheduler.in | 1 +
cts/scheduler/dot/probe-pending-node.dot | 2 +
cts/scheduler/exp/probe-pending-node.exp | 1 +
cts/scheduler/scores/probe-pending-node.scores | 61 ++++++
cts/scheduler/summary/probe-pending-node.summary | 55 +++++
cts/scheduler/xml/probe-pending-node.xml | 247 +++++++++++++++++++++++
6 files changed, 367 insertions(+)
create mode 100644 cts/scheduler/dot/probe-pending-node.dot
create mode 100644 cts/scheduler/exp/probe-pending-node.exp
create mode 100644 cts/scheduler/scores/probe-pending-node.scores
create mode 100644 cts/scheduler/summary/probe-pending-node.summary
create mode 100644 cts/scheduler/xml/probe-pending-node.xml
diff --git a/cts/cts-scheduler.in b/cts/cts-scheduler.in
index fc9790b..7ba2415 100644
--- a/cts/cts-scheduler.in
+++ b/cts/cts-scheduler.in
@@ -110,6 +110,7 @@ TESTS = [
[ "probe-2", "Correctly re-probe cloned groups" ],
[ "probe-3", "Probe (pending node)" ],
[ "probe-4", "Probe (pending node + stopped resource)" ],
+ [ "probe-pending-node", "Probe (pending node + unmanaged resource)" ],
[ "standby", "Standby" ],
[ "comments", "Comments" ],
],
diff --git a/cts/scheduler/dot/probe-pending-node.dot b/cts/scheduler/dot/probe-pending-node.dot
new file mode 100644
index 0000000..d8f1c9f
--- /dev/null
+++ b/cts/scheduler/dot/probe-pending-node.dot
@@ -0,0 +1,2 @@
+ digraph "g" {
+}
diff --git a/cts/scheduler/exp/probe-pending-node.exp b/cts/scheduler/exp/probe-pending-node.exp
new file mode 100644
index 0000000..56e315f
--- /dev/null
+++ b/cts/scheduler/exp/probe-pending-node.exp
@@ -0,0 +1 @@
+<transition_graph cluster-delay="60s" stonith-timeout="60s" failed-stop-offset="INFINITY" failed-start-offset="INFINITY" transition_id="0"/>
diff --git a/cts/scheduler/scores/probe-pending-node.scores b/cts/scheduler/scores/probe-pending-node.scores
new file mode 100644
index 0000000..020a1a0
--- /dev/null
+++ b/cts/scheduler/scores/probe-pending-node.scores
@@ -0,0 +1,61 @@
+
+pcmk__clone_allocate: fs_UC5_SAPMNT-clone allocation score on gcdoubwap01: 0
+pcmk__clone_allocate: fs_UC5_SAPMNT-clone allocation score on gcdoubwap02: 0
+pcmk__clone_allocate: fs_UC5_SAPMNT:0 allocation score on gcdoubwap01: 0
+pcmk__clone_allocate: fs_UC5_SAPMNT:0 allocation score on gcdoubwap02: 0
+pcmk__clone_allocate: fs_UC5_SAPMNT:1 allocation score on gcdoubwap01: 0
+pcmk__clone_allocate: fs_UC5_SAPMNT:1 allocation score on gcdoubwap02: 0
+pcmk__clone_allocate: fs_UC5_SYS-clone allocation score on gcdoubwap01: 0
+pcmk__clone_allocate: fs_UC5_SYS-clone allocation score on gcdoubwap02: 0
+pcmk__clone_allocate: fs_UC5_SYS:0 allocation score on gcdoubwap01: 0
+pcmk__clone_allocate: fs_UC5_SYS:0 allocation score on gcdoubwap02: 0
+pcmk__clone_allocate: fs_UC5_SYS:1 allocation score on gcdoubwap01: 0
+pcmk__clone_allocate: fs_UC5_SYS:1 allocation score on gcdoubwap02: 0
+pcmk__group_allocate: fs_UC5_ascs allocation score on gcdoubwap01: 0
+pcmk__group_allocate: fs_UC5_ascs allocation score on gcdoubwap02: 0
+pcmk__group_allocate: fs_UC5_ers allocation score on gcdoubwap01: 0
+pcmk__group_allocate: fs_UC5_ers allocation score on gcdoubwap02: 0
+pcmk__group_allocate: grp_UC5_ascs allocation score on gcdoubwap01: 0
+pcmk__group_allocate: grp_UC5_ascs allocation score on gcdoubwap02: 0
+pcmk__group_allocate: grp_UC5_ers allocation score on gcdoubwap01: 0
+pcmk__group_allocate: grp_UC5_ers allocation score on gcdoubwap02: 0
+pcmk__group_allocate: rsc_sap_UC5_ASCS11 allocation score on gcdoubwap01: 0
+pcmk__group_allocate: rsc_sap_UC5_ASCS11 allocation score on gcdoubwap02: 0
+pcmk__group_allocate: rsc_sap_UC5_ERS12 allocation score on gcdoubwap01: 0
+pcmk__group_allocate: rsc_sap_UC5_ERS12 allocation score on gcdoubwap02: 0
+pcmk__group_allocate: rsc_vip_gcp_ascs allocation score on gcdoubwap01: INFINITY
+pcmk__group_allocate: rsc_vip_gcp_ascs allocation score on gcdoubwap02: 0
+pcmk__group_allocate: rsc_vip_gcp_ers allocation score on gcdoubwap01: 0
+pcmk__group_allocate: rsc_vip_gcp_ers allocation score on gcdoubwap02: 0
+pcmk__group_allocate: rsc_vip_init_ers allocation score on gcdoubwap01: 0
+pcmk__group_allocate: rsc_vip_init_ers allocation score on gcdoubwap02: 0
+pcmk__group_allocate: rsc_vip_int_ascs allocation score on gcdoubwap01: 0
+pcmk__group_allocate: rsc_vip_int_ascs allocation score on gcdoubwap02: 0
+pcmk__native_allocate: fs_UC5_SAPMNT:0 allocation score on gcdoubwap01: 0
+pcmk__native_allocate: fs_UC5_SAPMNT:0 allocation score on gcdoubwap02: -INFINITY
+pcmk__native_allocate: fs_UC5_SAPMNT:1 allocation score on gcdoubwap01: 0
+pcmk__native_allocate: fs_UC5_SAPMNT:1 allocation score on gcdoubwap02: -INFINITY
+pcmk__native_allocate: fs_UC5_SYS:0 allocation score on gcdoubwap01: 0
+pcmk__native_allocate: fs_UC5_SYS:0 allocation score on gcdoubwap02: -INFINITY
+pcmk__native_allocate: fs_UC5_SYS:1 allocation score on gcdoubwap01: 0
+pcmk__native_allocate: fs_UC5_SYS:1 allocation score on gcdoubwap02: -INFINITY
+pcmk__native_allocate: fs_UC5_ascs allocation score on gcdoubwap01: 0
+pcmk__native_allocate: fs_UC5_ascs allocation score on gcdoubwap02: -INFINITY
+pcmk__native_allocate: fs_UC5_ers allocation score on gcdoubwap01: -INFINITY
+pcmk__native_allocate: fs_UC5_ers allocation score on gcdoubwap02: -INFINITY
+pcmk__native_allocate: rsc_sap_UC5_ASCS11 allocation score on gcdoubwap01: -INFINITY
+pcmk__native_allocate: rsc_sap_UC5_ASCS11 allocation score on gcdoubwap02: -INFINITY
+pcmk__native_allocate: rsc_sap_UC5_ERS12 allocation score on gcdoubwap01: -INFINITY
+pcmk__native_allocate: rsc_sap_UC5_ERS12 allocation score on gcdoubwap02: -INFINITY
+pcmk__native_allocate: rsc_vip_gcp_ascs allocation score on gcdoubwap01: -INFINITY
+pcmk__native_allocate: rsc_vip_gcp_ascs allocation score on gcdoubwap02: -INFINITY
+pcmk__native_allocate: rsc_vip_gcp_ers allocation score on gcdoubwap01: -INFINITY
+pcmk__native_allocate: rsc_vip_gcp_ers allocation score on gcdoubwap02: -INFINITY
+pcmk__native_allocate: rsc_vip_init_ers allocation score on gcdoubwap01: 0
+pcmk__native_allocate: rsc_vip_init_ers allocation score on gcdoubwap02: -INFINITY
+pcmk__native_allocate: rsc_vip_int_ascs allocation score on gcdoubwap01: INFINITY
+pcmk__native_allocate: rsc_vip_int_ascs allocation score on gcdoubwap02: -INFINITY
+pcmk__native_allocate: stonith_gcdoubwap01 allocation score on gcdoubwap01: -INFINITY
+pcmk__native_allocate: stonith_gcdoubwap01 allocation score on gcdoubwap02: 0
+pcmk__native_allocate: stonith_gcdoubwap02 allocation score on gcdoubwap01: 0
+pcmk__native_allocate: stonith_gcdoubwap02 allocation score on gcdoubwap02: -INFINITY
diff --git a/cts/scheduler/summary/probe-pending-node.summary b/cts/scheduler/summary/probe-pending-node.summary
new file mode 100644
index 0000000..208186b
--- /dev/null
+++ b/cts/scheduler/summary/probe-pending-node.summary
@@ -0,0 +1,55 @@
+Using the original execution date of: 2021-06-11 13:55:24Z
+
+ *** Resource management is DISABLED ***
+ The cluster will not attempt to start, stop or recover services
+
+Current cluster status:
+ * Node List:
+ * Node gcdoubwap02: pending
+ * Online: [ gcdoubwap01 ]
+
+ * Full List of Resources:
+ * stonith_gcdoubwap01 (stonith:fence_gce): Stopped (unmanaged)
+ * stonith_gcdoubwap02 (stonith:fence_gce): Stopped (unmanaged)
+ * Clone Set: fs_UC5_SAPMNT-clone [fs_UC5_SAPMNT] (unmanaged):
+ * Stopped: [ gcdoubwap01 gcdoubwap02 ]
+ * Clone Set: fs_UC5_SYS-clone [fs_UC5_SYS] (unmanaged):
+ * Stopped: [ gcdoubwap01 gcdoubwap02 ]
+ * Resource Group: grp_UC5_ascs (unmanaged):
+ * rsc_vip_int_ascs (ocf:heartbeat:IPaddr2): Stopped (unmanaged)
+ * rsc_vip_gcp_ascs (ocf:heartbeat:gcp-vpc-move-vip): Started gcdoubwap01 (unmanaged)
+ * fs_UC5_ascs (ocf:heartbeat:Filesystem): Stopped (unmanaged)
+ * rsc_sap_UC5_ASCS11 (ocf:heartbeat:SAPInstance): Stopped (unmanaged)
+ * Resource Group: grp_UC5_ers (unmanaged):
+ * rsc_vip_init_ers (ocf:heartbeat:IPaddr2): Stopped (unmanaged)
+ * rsc_vip_gcp_ers (ocf:heartbeat:gcp-vpc-move-vip): Stopped (unmanaged)
+ * fs_UC5_ers (ocf:heartbeat:Filesystem): Stopped (unmanaged)
+ * rsc_sap_UC5_ERS12 (ocf:heartbeat:SAPInstance): Stopped (unmanaged)
+
+Transition Summary:
+
+Executing Cluster Transition:
+Using the original execution date of: 2021-06-11 13:55:24Z
+
+Revised Cluster Status:
+ * Node List:
+ * Node gcdoubwap02: pending
+ * Online: [ gcdoubwap01 ]
+
+ * Full List of Resources:
+ * stonith_gcdoubwap01 (stonith:fence_gce): Stopped (unmanaged)
+ * stonith_gcdoubwap02 (stonith:fence_gce): Stopped (unmanaged)
+ * Clone Set: fs_UC5_SAPMNT-clone [fs_UC5_SAPMNT] (unmanaged):
+ * Stopped: [ gcdoubwap01 gcdoubwap02 ]
+ * Clone Set: fs_UC5_SYS-clone [fs_UC5_SYS] (unmanaged):
+ * Stopped: [ gcdoubwap01 gcdoubwap02 ]
+ * Resource Group: grp_UC5_ascs (unmanaged):
+ * rsc_vip_int_ascs (ocf:heartbeat:IPaddr2): Stopped (unmanaged)
+ * rsc_vip_gcp_ascs (ocf:heartbeat:gcp-vpc-move-vip): Started gcdoubwap01 (unmanaged)
+ * fs_UC5_ascs (ocf:heartbeat:Filesystem): Stopped (unmanaged)
+ * rsc_sap_UC5_ASCS11 (ocf:heartbeat:SAPInstance): Stopped (unmanaged)
+ * Resource Group: grp_UC5_ers (unmanaged):
+ * rsc_vip_init_ers (ocf:heartbeat:IPaddr2): Stopped (unmanaged)
+ * rsc_vip_gcp_ers (ocf:heartbeat:gcp-vpc-move-vip): Stopped (unmanaged)
+ * fs_UC5_ers (ocf:heartbeat:Filesystem): Stopped (unmanaged)
+ * rsc_sap_UC5_ERS12 (ocf:heartbeat:SAPInstance): Stopped (unmanaged)
diff --git a/cts/scheduler/xml/probe-pending-node.xml b/cts/scheduler/xml/probe-pending-node.xml
new file mode 100644
index 0000000..9f55c92
--- /dev/null
+++ b/cts/scheduler/xml/probe-pending-node.xml
@@ -0,0 +1,247 @@
+<cib crm_feature_set="3.0.14" validate-with="pacemaker-2.10" epoch="395" num_updates="30" admin_epoch="0" cib-last-written="Thu Jun 10 18:01:13 2021" update-origin="gcdoubwap01" update-client="cibadmin" update-user="root" have-quorum="1" dc-uuid="1" execution-date="1623419724">
+ <configuration>
+ <crm_config>
+ <cluster_property_set id="cib-bootstrap-options">
+ <nvpair id="cib-bootstrap-options-have-watchdog" name="have-watchdog" value="false"/>
+ <nvpair id="cib-bootstrap-options-dc-version" name="dc-version" value="1.1.19-8.el7_6.5-c3c624ea3d"/>
+ <nvpair id="cib-bootstrap-options-cluster-infrastructure" name="cluster-infrastructure" value="corosync"/>
+ <nvpair id="cib-bootstrap-options-cluster-name" name="cluster-name" value="ascscluster"/>
+ <nvpair id="cib-bootstrap-options-maintenance-mode" name="maintenance-mode" value="true"/>
+ <nvpair id="cib-bootstrap-options-last-lrm-refresh" name="last-lrm-refresh" value="1622815036"/>
+ </cluster_property_set>
+ </crm_config>
+ <nodes>
+ <node id="1" uname="gcdoubwap01"/>
+ <node id="2" uname="gcdoubwap02"/>
+ </nodes>
+ <resources>
+ <primitive class="stonith" id="stonith_gcdoubwap01" type="fence_gce">
+ <instance_attributes id="stonith_gcdoubwap01-instance_attributes">
+ <nvpair id="stonith_gcdoubwap01-instance_attributes-project" name="project" value="pj-uat-do-nane1-01"/>
+ <nvpair id="stonith_gcdoubwap01-instance_attributes-zone" name="zone" value="northamerica-northeast1-b"/>
+ </instance_attributes>
+ <operations>
+ <op id="stonith_gcdoubwap01-monitor-interval-60s" interval="60s" name="monitor"/>
+ </operations>
+ </primitive>
+ <primitive class="stonith" id="stonith_gcdoubwap02" type="fence_gce">
+ <instance_attributes id="stonith_gcdoubwap02-instance_attributes">
+ <nvpair id="stonith_gcdoubwap02-instance_attributes-project" name="project" value="pj-uat-do-nane1-01"/>
+ <nvpair id="stonith_gcdoubwap02-instance_attributes-zone" name="zone" value="northamerica-northeast1-c"/>
+ </instance_attributes>
+ <operations>
+ <op id="stonith_gcdoubwap02-monitor-interval-60s" interval="60s" name="monitor"/>
+ </operations>
+ </primitive>
+ <clone id="fs_UC5_SAPMNT-clone">
+ <primitive class="ocf" id="fs_UC5_SAPMNT" provider="heartbeat" type="Filesystem">
+ <instance_attributes id="fs_UC5_SAPMNT-instance_attributes">
+ <nvpair id="fs_UC5_SAPMNT-instance_attributes-device" name="device" value="uatdoelfs.igmfinancial.net:UC5_sapmnt/root"/>
+ <nvpair id="fs_UC5_SAPMNT-instance_attributes-directory" name="directory" value="/sapmnt/UC5"/>
+ <nvpair id="fs_UC5_SAPMNT-instance_attributes-fstype" name="fstype" value="nfs"/>
+ </instance_attributes>
+ <operations>
+ <op id="fs_UC5_SAPMNT-monitor-interval-20s" interval="20s" name="monitor" timeout="40s"/>
+ <op id="fs_UC5_SAPMNT-notify-interval-0s" interval="0s" name="notify" timeout="60s"/>
+ <op id="fs_UC5_SAPMNT-start-interval-0s" interval="0s" name="start" timeout="60s"/>
+ <op id="fs_UC5_SAPMNT-stop-interval-0s" interval="0s" name="stop" timeout="60s"/>
+ </operations>
+ </primitive>
+ <meta_attributes id="fs_UC5_SAPMNT-clone-meta_attributes">
+ <nvpair id="fs_UC5_SAPMNT-clone-meta_attributes-interleave" name="interleave" value="true"/>
+ </meta_attributes>
+ </clone>
+ <clone id="fs_UC5_SYS-clone">
+ <primitive class="ocf" id="fs_UC5_SYS" provider="heartbeat" type="Filesystem">
+ <instance_attributes id="fs_UC5_SYS-instance_attributes">
+ <nvpair id="fs_UC5_SYS-instance_attributes-device" name="device" value="uatdoelfs.igmfinancial.net:UC5_SYS/root"/>
+ <nvpair id="fs_UC5_SYS-instance_attributes-directory" name="directory" value="/usr/sap/UC5/SYS"/>
+ <nvpair id="fs_UC5_SYS-instance_attributes-fstype" name="fstype" value="nfs"/>
+ </instance_attributes>
+ <operations>
+ <op id="fs_UC5_SYS-monitor-interval-20s" interval="20s" name="monitor" timeout="40s"/>
+ <op id="fs_UC5_SYS-notify-interval-0s" interval="0s" name="notify" timeout="60s"/>
+ <op id="fs_UC5_SYS-start-interval-0s" interval="0s" name="start" timeout="60s"/>
+ <op id="fs_UC5_SYS-stop-interval-0s" interval="0s" name="stop" timeout="60s"/>
+ </operations>
+ </primitive>
+ <meta_attributes id="fs_UC5_SYS-clone-meta_attributes">
+ <nvpair id="fs_UC5_SYS-clone-meta_attributes-interleave" name="interleave" value="true"/>
+ </meta_attributes>
+ </clone>
+ <group id="grp_UC5_ascs">
+ <primitive class="ocf" id="rsc_vip_int_ascs" provider="heartbeat" type="IPaddr2">
+ <instance_attributes id="rsc_vip_int_ascs-instance_attributes">
+ <nvpair id="rsc_vip_int_ascs-instance_attributes-cidr_netmask" name="cidr_netmask" value="32"/>
+ <nvpair id="rsc_vip_int_ascs-instance_attributes-ip" name="ip" value="10.4.130.38"/>
+ <nvpair id="rsc_vip_int_ascs-instance_attributes-nic" name="nic" value="eth0"/>
+ </instance_attributes>
+ <operations>
+ <op id="rsc_vip_int_ascs-monitor-interval-10s" interval="10s" name="monitor" timeout="20s"/>
+ <op id="rsc_vip_int_ascs-start-interval-0s" interval="0s" name="start" timeout="20s"/>
+ <op id="rsc_vip_int_ascs-stop-interval-0s" interval="0s" name="stop" timeout="20s"/>
+ </operations>
+ </primitive>
+ <primitive class="ocf" id="rsc_vip_gcp_ascs" provider="heartbeat" type="gcp-vpc-move-vip">
+ <instance_attributes id="rsc_vip_gcp_ascs-instance_attributes">
+ <nvpair id="rsc_vip_gcp_ascs-instance_attributes-alias_ip" name="alias_ip" value="10.4.130.38/32"/>
+ <nvpair id="rsc_vip_gcp_ascs-instance_attributes-hostlist" name="hostlist" value="gcdoubwap01 gcdoubwap02"/>
+ </instance_attributes>
+ <operations>
+ <op id="rsc_vip_gcp_ascs-monitor-interval-60s" interval="60s" name="monitor" on-fail="ignore"/>
+ <op id="rsc_vip_gcp_ascs-start-interval-0s" interval="0s" name="start" timeout="300s"/>
+ <op id="rsc_vip_gcp_ascs-stop-interval-0s" interval="0s" name="stop" timeout="15s"/>
+ </operations>
+ </primitive>
+ <primitive class="ocf" id="fs_UC5_ascs" provider="heartbeat" type="Filesystem">
+ <instance_attributes id="fs_UC5_ascs-instance_attributes">
+ <nvpair id="fs_UC5_ascs-instance_attributes-device" name="device" value="uatdoelfs.igmfinancial.net:UC5_ASCS/root"/>
+ <nvpair id="fs_UC5_ascs-instance_attributes-directory" name="directory" value="/usr/sap/UC5/ASCS11"/>
+ <nvpair id="fs_UC5_ascs-instance_attributes-force_unmount" name="force_unmount" value="safe"/>
+ <nvpair id="fs_UC5_ascs-instance_attributes-fstype" name="fstype" value="nfs"/>
+ </instance_attributes>
+ <operations>
+ <op id="fs_UC5_ascs-monitor-interval-200" interval="200" name="monitor" timeout="40"/>
+ <op id="fs_UC5_ascs-notify-interval-0s" interval="0s" name="notify" timeout="60s"/>
+ <op id="fs_UC5_ascs-start-interval-0" interval="0" name="start" timeout="60"/>
+ <op id="fs_UC5_ascs-stop-interval-0" interval="0" name="stop" timeout="120"/>
+ </operations>
+ </primitive>
+ <primitive class="ocf" id="rsc_sap_UC5_ASCS11" provider="heartbeat" type="SAPInstance">
+ <instance_attributes id="rsc_sap_UC5_ASCS11-instance_attributes">
+ <nvpair id="rsc_sap_UC5_ASCS11-instance_attributes-AUTOMATIC_RECOVER" name="AUTOMATIC_RECOVER" value="false"/>
+ <nvpair id="rsc_sap_UC5_ASCS11-instance_attributes-InstanceName" name="InstanceName" value="UC5_ASCS11_uatdobwscs"/>
+ <nvpair id="rsc_sap_UC5_ASCS11-instance_attributes-START_PROFILE" name="START_PROFILE" value="/sapmnt/UC5/profile/UC5_ASCS11_uatdobwscs"/>
+ </instance_attributes>
+ <meta_attributes id="rsc_sap_UC5_ASCS11-meta_attributes">
+ <nvpair id="rsc_sap_UC5_ASCS11-meta_attributes-failure-timeout" name="failure-timeout" value="60"/>
+ <nvpair id="rsc_sap_UC5_ASCS11-meta_attributes-migration-threshold" name="migration-threshold" value="1"/>
+ <nvpair id="rsc_sap_UC5_ASCS11-meta_attributes-resource-stickiness" name="resource-stickiness" value="5000"/>
+ </meta_attributes>
+ <operations>
+ <op id="rsc_sap_UC5_ASCS11-demote-interval-0s" interval="0s" name="demote" timeout="320s"/>
+ <op id="rsc_sap_UC5_ASCS11-methods-interval-0s" interval="0s" name="methods" timeout="5s"/>
+ <op id="rsc_sap_UC5_ASCS11-monitor-interval-20" interval="20" name="monitor" on-fail="restart" timeout="60"/>
+ <op id="rsc_sap_UC5_ASCS11-promote-interval-0s" interval="0s" name="promote" timeout="320s"/>
+ <op id="rsc_sap_UC5_ASCS11-start-interval-0" interval="0" name="start" timeout="600"/>
+ <op id="rsc_sap_UC5_ASCS11-stop-interval-0" interval="0" name="stop" timeout="600"/>
+ </operations>
+ </primitive>
+ </group>
+ <group id="grp_UC5_ers">
+ <primitive class="ocf" id="rsc_vip_init_ers" provider="heartbeat" type="IPaddr2">
+ <instance_attributes id="rsc_vip_init_ers-instance_attributes">
+ <nvpair id="rsc_vip_init_ers-instance_attributes-cidr_netmask" name="cidr_netmask" value="32"/>
+ <nvpair id="rsc_vip_init_ers-instance_attributes-ip" name="ip" value="10.4.130.39"/>
+ <nvpair id="rsc_vip_init_ers-instance_attributes-nic" name="nic" value="eth0"/>
+ </instance_attributes>
+ <operations>
+ <op id="rsc_vip_init_ers-monitor-interval-10s" interval="10s" name="monitor" timeout="20s"/>
+ <op id="rsc_vip_init_ers-start-interval-0s" interval="0s" name="start" timeout="20s"/>
+ <op id="rsc_vip_init_ers-stop-interval-0s" interval="0s" name="stop" timeout="20s"/>
+ </operations>
+ </primitive>
+ <primitive class="ocf" id="rsc_vip_gcp_ers" provider="heartbeat" type="gcp-vpc-move-vip">
+ <instance_attributes id="rsc_vip_gcp_ers-instance_attributes">
+ <nvpair id="rsc_vip_gcp_ers-instance_attributes-alias_ip" name="alias_ip" value="10.4.130.39/32"/>
+ <nvpair id="rsc_vip_gcp_ers-instance_attributes-hostlist" name="hostlist" value="gcdoubwap01 gcdoubwap02"/>
+ </instance_attributes>
+ <operations>
+ <op id="rsc_vip_gcp_ers-monitor-interval-60s" interval="60s" name="monitor" on-fail="ignore"/>
+ <op id="rsc_vip_gcp_ers-start-interval-0s" interval="0s" name="start" timeout="300s"/>
+ <op id="rsc_vip_gcp_ers-stop-interval-0s" interval="0s" name="stop" timeout="180s"/>
+ </operations>
+ </primitive>
+ <primitive class="ocf" id="fs_UC5_ers" provider="heartbeat" type="Filesystem">
+ <instance_attributes id="fs_UC5_ers-instance_attributes">
+ <nvpair id="fs_UC5_ers-instance_attributes-device" name="device" value="uatdoelfs.igmfinancial.net:UC5_ERS/root"/>
+ <nvpair id="fs_UC5_ers-instance_attributes-directory" name="directory" value="/usr/sap/UC5/ERS12"/>
+ <nvpair id="fs_UC5_ers-instance_attributes-force_unmount" name="force_unmount" value="safe"/>
+ <nvpair id="fs_UC5_ers-instance_attributes-fstype" name="fstype" value="nfs"/>
+ </instance_attributes>
+ <operations>
+ <op id="fs_UC5_ers-monitor-interval-200" interval="200" name="monitor" timeout="40"/>
+ <op id="fs_UC5_ers-notify-interval-0s" interval="0s" name="notify" timeout="60s"/>
+ <op id="fs_UC5_ers-start-interval-0" interval="0" name="start" timeout="60"/>
+ <op id="fs_UC5_ers-stop-interval-0" interval="0" name="stop" timeout="120"/>
+ </operations>
+ </primitive>
+ <primitive class="ocf" id="rsc_sap_UC5_ERS12" provider="heartbeat" type="SAPInstance">
+ <instance_attributes id="rsc_sap_UC5_ERS12-instance_attributes">
+ <nvpair id="rsc_sap_UC5_ERS12-instance_attributes-AUTOMATIC_RECOVER" name="AUTOMATIC_RECOVER" value="false"/>
+ <nvpair id="rsc_sap_UC5_ERS12-instance_attributes-IS_ERS" name="IS_ERS" value="true"/>
+ <nvpair id="rsc_sap_UC5_ERS12-instance_attributes-InstanceName" name="InstanceName" value="UC5_ERS12_uatdobwers"/>
+ <nvpair id="rsc_sap_UC5_ERS12-instance_attributes-START_PROFILE" name="START_PROFILE" value="/sapmnt/UC5/profile/UC5_ERS12_uatdobwers"/>
+ </instance_attributes>
+ <operations>
+ <op id="rsc_sap_UC5_ERS12-demote-interval-0s" interval="0s" name="demote" timeout="320s"/>
+ <op id="rsc_sap_UC5_ERS12-methods-interval-0s" interval="0s" name="methods" timeout="5s"/>
+ <op id="rsc_sap_UC5_ERS12-monitor-interval-20" interval="20" name="monitor" on-fail="restart" timeout="60"/>
+ <op id="rsc_sap_UC5_ERS12-promote-interval-0s" interval="0s" name="promote" timeout="320s"/>
+ <op id="rsc_sap_UC5_ERS12-start-interval-0" interval="0" name="start" timeout="600"/>
+ <op id="rsc_sap_UC5_ERS12-stop-interval-0" interval="0" name="stop" timeout="600"/>
+ </operations>
+ </primitive>
+ </group>
+ </resources>
+ <constraints>
+ <rsc_colocation id="colocation-grp_UC5_ers-grp_UC5_ascs--5000" rsc="grp_UC5_ers" score="-5000" with-rsc="grp_UC5_ascs"/>
+ <rsc_order first="grp_UC5_ascs" first-action="start" id="order-grp_UC5_ascs-grp_UC5_ers-mandatory" symmetrical="false" then="grp_UC5_ers" then-action="stop"/>
+ <rsc_location id="location-rsc_sap_UC5_ASCS11" rsc="rsc_sap_UC5_ASCS11">
+ <rule id="location-rsc_sap_UC5_ASCS11-rule" score="2000">
+ <expression attribute="runs_ERS_UC5" id="location-rsc_sap_UC5_ASCS11-rule-expr" operation="eq" value="1"/>
+ </rule>
+ </rsc_location>
+ <rsc_location id="location-stonith_gcdoubwap01-gcdoubwap02" node="gcdoubwap01" rsc="stonith_gcdoubwap01" score="-INFINITY"/>
+ <rsc_location id="location-stonith_gcdoubwap02-gcdoubwap01" node="gcdoubwap02" rsc="stonith_gcdoubwap02" score="-INFINITY"/>
+ <rsc_order first="fs_UC5_SAPMNT-clone" first-action="start" id="order-fs_UC5_SAPMNT-clone-grp_UC5_ascs-mandatory" then="grp_UC5_ascs" then-action="start"/>
+ <rsc_order first="fs_UC5_SAPMNT-clone" first-action="start" id="order-fs_UC5_SAPMNT-clone-grp_UC5_ers-mandatory" then="grp_UC5_ers" then-action="start"/>
+ </constraints>
+ </configuration>
+ <status>
+ <node_state id="1" uname="gcdoubwap01" in_ccm="true" crmd="online" crm-debug-origin="post_cache_update" join="member" expected="member">
+ <lrm id="1">
+ <lrm_resources>
+ <lrm_resource id="stonith_gcdoubwap01" type="fence_gce" class="stonith">
+ <lrm_rsc_op id="stonith_gcdoubwap01_last_0" operation_key="stonith_gcdoubwap01_monitor_0" operation="monitor" crm-debug-origin="do_update_resource" crm_feature_set="3.0.14" transition-key="1:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" transition-magic="0:7;1:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" exit-reason="" on_node="gcdoubwap01" call-id="5" rc-code="7" op-status="0" interval="0" last-run="1623419700" last-rc-change="1623419700" exec-time="27" queue-time="0" op-digest="e6935031dfde569ad30fb442953d3d91"/>
+ </lrm_resource>
+ <lrm_resource id="stonith_gcdoubwap02" type="fence_gce" class="stonith">
+ <lrm_rsc_op id="stonith_gcdoubwap02_last_0" operation_key="stonith_gcdoubwap02_monitor_0" operation="monitor" crm-debug-origin="do_update_resource" crm_feature_set="3.0.14" transition-key="2:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" transition-magic="0:7;2:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" exit-reason="" on_node="gcdoubwap01" call-id="9" rc-code="7" op-status="0" interval="0" last-run="1623419700" last-rc-change="1623419700" exec-time="0" queue-time="0" op-digest="064645c51d6d3a802eb6928f6116222c"/>
+ </lrm_resource>
+ <lrm_resource id="fs_UC5_SAPMNT" type="Filesystem" class="ocf" provider="heartbeat">
+ <lrm_rsc_op id="fs_UC5_SAPMNT_last_0" operation_key="fs_UC5_SAPMNT_monitor_0" operation="monitor" crm-debug-origin="do_update_resource" crm_feature_set="3.0.14" transition-key="3:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" transition-magic="0:7;3:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" exit-reason="" on_node="gcdoubwap01" call-id="14" rc-code="7" op-status="0" interval="0" last-run="1623419700" last-rc-change="1623419700" exec-time="126" queue-time="1" op-digest="02c74f325691f1af3c3dd9c2ab702b01"/>
+ </lrm_resource>
+ <lrm_resource id="fs_UC5_SYS" type="Filesystem" class="ocf" provider="heartbeat">
+ <lrm_rsc_op id="fs_UC5_SYS_last_0" operation_key="fs_UC5_SYS_monitor_0" operation="monitor" crm-debug-origin="do_update_resource" crm_feature_set="3.0.14" transition-key="4:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" transition-magic="0:7;4:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" exit-reason="" on_node="gcdoubwap01" call-id="19" rc-code="7" op-status="0" interval="0" last-run="1623419700" last-rc-change="1623419700" exec-time="130" queue-time="0" op-digest="f1f67b01fc16ed22d8fa1fe030d9c06b"/>
+ </lrm_resource>
+ <lrm_resource id="rsc_vip_int_ascs" type="IPaddr2" class="ocf" provider="heartbeat">
+ <lrm_rsc_op id="rsc_vip_int_ascs_last_0" operation_key="rsc_vip_int_ascs_monitor_0" operation="monitor" crm-debug-origin="do_update_resource" crm_feature_set="3.0.14" transition-key="5:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" transition-magic="0:7;5:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" exit-reason="" on_node="gcdoubwap01" call-id="23" rc-code="7" op-status="0" interval="0" last-run="1623419700" last-rc-change="1623419700" exec-time="105" queue-time="0" op-digest="da0b35400002727d7281b8f7051fe400"/>
+ </lrm_resource>
+ <lrm_resource id="rsc_vip_gcp_ascs" type="gcp-vpc-move-vip" class="ocf" provider="heartbeat">
+ <lrm_rsc_op id="rsc_vip_gcp_ascs_last_0" operation_key="rsc_vip_gcp_ascs_monitor_0" operation="monitor" crm-debug-origin="do_update_resource" crm_feature_set="3.0.14" transition-key="6:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" transition-magic="0:0;6:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" exit-reason="" on_node="gcdoubwap01" call-id="27" rc-code="0" op-status="0" interval="0" last-run="1623419705" last-rc-change="1623419705" exec-time="1842" queue-time="0" op-digest="face88a40d76658d0caa541eefc02ca8"/>
+ <lrm_rsc_op id="rsc_vip_gcp_ascs_last_failure_0" operation_key="rsc_vip_gcp_ascs_monitor_0" operation="monitor" crm-debug-origin="do_update_resource" crm_feature_set="3.0.14" transition-key="6:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" transition-magic="0:0;6:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" exit-reason="" on_node="gcdoubwap01" call-id="27" rc-code="0" op-status="0" interval="0" last-run="1623419705" last-rc-change="1623419705" exec-time="1842" queue-time="0" op-digest="face88a40d76658d0caa541eefc02ca8"/>
+ </lrm_resource>
+ <lrm_resource id="fs_UC5_ascs" type="Filesystem" class="ocf" provider="heartbeat">
+ <lrm_rsc_op id="fs_UC5_ascs_last_0" operation_key="fs_UC5_ascs_monitor_0" operation="monitor" crm-debug-origin="do_update_resource" crm_feature_set="3.0.14" transition-key="7:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" transition-magic="0:7;7:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" exit-reason="" on_node="gcdoubwap01" call-id="31" rc-code="7" op-status="0" interval="0" last-run="1623419705" last-rc-change="1623419705" exec-time="241" queue-time="0" op-digest="acac63abd6c034d7dad4aae73e2ca95d"/>
+ </lrm_resource>
+ <lrm_resource id="rsc_sap_UC5_ASCS11" type="SAPInstance" class="ocf" provider="heartbeat">
+ <lrm_rsc_op id="rsc_sap_UC5_ASCS11_last_0" operation_key="rsc_sap_UC5_ASCS11_monitor_0" operation="monitor" crm-debug-origin="do_update_resource" crm_feature_set="3.0.14" transition-key="8:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" transition-magic="0:7;8:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" exit-reason="" on_node="gcdoubwap01" call-id="35" rc-code="7" op-status="0" interval="0" last-run="1623419705" last-rc-change="1623419705" exec-time="969" queue-time="0" op-digest="08c114a33aa3c16b3204ff09cb983107" op-force-restart=" ERS_START_PROFILE ERS_InstanceName START_PROFILE InstanceName " op-restart-digest="315a463141e0ef59afedf7a62a8d6362"/>
+ </lrm_resource>
+ <lrm_resource id="rsc_vip_init_ers" type="IPaddr2" class="ocf" provider="heartbeat">
+ <lrm_rsc_op id="rsc_vip_init_ers_last_0" operation_key="rsc_vip_init_ers_monitor_0" operation="monitor" crm-debug-origin="do_update_resource" crm_feature_set="3.0.14" transition-key="9:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" transition-magic="0:7;9:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" exit-reason="" on_node="gcdoubwap01" call-id="39" rc-code="7" op-status="0" interval="0" last-run="1623419705" last-rc-change="1623419705" exec-time="1033" queue-time="0" op-digest="7b29d7af6a7baa6015d1eeac471a9b42"/>
+ </lrm_resource>
+ <lrm_resource id="rsc_vip_gcp_ers" type="gcp-vpc-move-vip" class="ocf" provider="heartbeat">
+ <lrm_rsc_op id="rsc_vip_gcp_ers_last_0" operation_key="rsc_vip_gcp_ers_monitor_0" operation="monitor" crm-debug-origin="do_update_resource" crm_feature_set="3.0.14" transition-key="10:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" transition-magic="0:7;10:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" exit-reason="" on_node="gcdoubwap01" call-id="43" rc-code="7" op-status="0" interval="0" last-run="1623419705" last-rc-change="1623419705" exec-time="1702" queue-time="0" op-digest="10365a97fe5a5864a3679c314bf65bfd"/>
+ </lrm_resource>
+ <lrm_resource id="fs_UC5_ers" type="Filesystem" class="ocf" provider="heartbeat">
+ <lrm_rsc_op id="fs_UC5_ers_last_0" operation_key="fs_UC5_ers_monitor_0" operation="monitor" crm-debug-origin="do_update_resource" crm_feature_set="3.0.14" transition-key="11:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" transition-magic="0:7;11:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" exit-reason="" on_node="gcdoubwap01" call-id="47" rc-code="7" op-status="0" interval="0" last-run="1623419706" last-rc-change="1623419706" exec-time="709" queue-time="0" op-digest="61e45529b2da32c1e53055238a00ca99"/>
+ </lrm_resource>
+ <lrm_resource id="rsc_sap_UC5_ERS12" type="SAPInstance" class="ocf" provider="heartbeat">
+ <lrm_rsc_op id="rsc_sap_UC5_ERS12_last_0" operation_key="rsc_sap_UC5_ERS12_monitor_0" operation="monitor" crm-debug-origin="do_update_resource" crm_feature_set="3.0.14" transition-key="12:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" transition-magic="0:7;12:0:7:5e41afa8-15bd-443a-88fb-ec276232a804" exit-reason="" on_node="gcdoubwap01" call-id="51" rc-code="7" op-status="0" interval="0" last-run="1623419706" last-rc-change="1623419706" exec-time="914" queue-time="1" op-digest="b550e70bd4203af88473e4d914b11f87" op-force-restart=" ERS_START_PROFILE ERS_InstanceName START_PROFILE InstanceName " op-restart-digest="2fb6ec6eb77e25302c8dc0dad84dc46f"/>
+ </lrm_resource>
+ </lrm_resources>
+ </lrm>
+ </node_state>
+ <node_state id="2" uname="gcdoubwap02" crmd="offline" crm-debug-origin="post_cache_update" in_ccm="true"/>
+ </status>
+</cib>
--
1.8.3.1

View File

@ -0,0 +1,150 @@
From ea5510dd979bb6d375324cda26925d9e7c4362f5 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 19 Jul 2021 10:04:16 -0400
Subject: [PATCH 1/2] Low: tools: The --get-value option does not require an
arg.
Regression in 2.1.0 introduced by 15f5c2901.
---
tools/crm_attribute.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/crm_attribute.c b/tools/crm_attribute.c
index 2cc8d26..8a5b4e4 100644
--- a/tools/crm_attribute.c
+++ b/tools/crm_attribute.c
@@ -242,7 +242,7 @@ static GOptionEntry deprecated_entries[] = {
NULL, NULL
},
- { "get-value", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_CALLBACK, value_cb,
+ { "get-value", 0, G_OPTION_FLAG_HIDDEN|G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, value_cb,
NULL, NULL
},
--
1.8.3.1
From ef054d943afe8e60017f6adc4e25f88a59ac91a4 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 19 Jul 2021 11:37:04 -0400
Subject: [PATCH 2/2] Low: libcrmcommon: Allow negative numbers as cmdline
options.
The bug here is that negative numbers (for instance, negative scores)
are not supported as command line arguments. Because we break up a
string that starts with a single dash into multiple arguments, "-1000"
becomes "-1", "-0", "-0", and "-0".
Because we don't have enough information about what is happening on the
command line, the best we can do here is recognize something as a
negative number and pass it on. Any errors will have to be detected at
a later step.
Also note that we only recognize negative numbers if they start with
1-9. Starting with 0 will be recognized as some sort of string.
Regression in 2.1.0 caused by a long-standing bug in
pcmk__cmdline_preproc_test.
---
lib/common/cmdline.c | 29 ++++++++++++++++++++++
.../tests/cmdline/pcmk__cmdline_preproc_test.c | 24 +++++++++++++++++-
2 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/lib/common/cmdline.c b/lib/common/cmdline.c
index 7c95d02..9c1b810 100644
--- a/lib/common/cmdline.c
+++ b/lib/common/cmdline.c
@@ -9,6 +9,7 @@
#include <crm_internal.h>
+#include <ctype.h>
#include <glib.h>
#include <crm/crm.h>
@@ -189,6 +190,34 @@ pcmk__cmdline_preproc(char **argv, const char *special) {
/* Skip over leading dash */
char *ch = argv[i]+1;
+ /* This looks like the start of a number, which means it is a negative
+ * number. It's probably the argument to the preceeding option, but
+ * we can't know that here. Copy it over and let whatever handles
+ * arguments next figure it out.
+ */
+ if (*ch != '\0' && *ch >= '1' && *ch <= '9') {
+ bool is_numeric = true;
+
+ while (*ch != '\0') {
+ if (!isdigit(*ch)) {
+ is_numeric = false;
+ break;
+ }
+
+ ch++;
+ }
+
+ if (is_numeric) {
+ g_ptr_array_add(arr, g_strdup_printf("%s", argv[i]));
+ continue;
+ } else {
+ /* This argument wasn't entirely numeric. Reset ch to the
+ * beginning so we can process it one character at a time.
+ */
+ ch = argv[i]+1;
+ }
+ }
+
while (*ch != '\0') {
/* This is a special short argument that takes an option. getopt
* allows values to be interspersed with a list of arguments, but
diff --git a/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c b/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c
index b8506c6..9a752ef 100644
--- a/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c
+++ b/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 the Pacemaker project contributors
+ * Copyright 2020-2021 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -86,6 +86,26 @@ long_arg(void) {
g_strfreev(processed);
}
+static void
+negative_score(void) {
+ const char *argv[] = { "-v", "-1000", NULL };
+ const gchar *expected[] = { "-v", "-1000", NULL };
+
+ gchar **processed = pcmk__cmdline_preproc((char **) argv, "v");
+ LISTS_EQ(processed, expected);
+ g_strfreev(processed);
+}
+
+static void
+negative_score_2(void) {
+ const char *argv[] = { "-1i3", NULL };
+ const gchar *expected[] = { "-1", "-i", "-3", NULL };
+
+ gchar **processed = pcmk__cmdline_preproc((char **) argv, NULL);
+ LISTS_EQ(processed, expected);
+ g_strfreev(processed);
+}
+
int
main(int argc, char **argv)
{
@@ -98,5 +118,7 @@ main(int argc, char **argv)
g_test_add_func("/common/cmdline/preproc/special_args", special_args);
g_test_add_func("/common/cmdline/preproc/special_arg_at_end", special_arg_at_end);
g_test_add_func("/common/cmdline/preproc/long_arg", long_arg);
+ g_test_add_func("/common/cmdline/preproc/negative_score", negative_score);
+ g_test_add_func("/common/cmdline/preproc/negative_score_2", negative_score_2);
return g_test_run();
}
--
1.8.3.1

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,221 @@
From 2eee93e8f9ea2daa81769bc69843d63ced1a7112 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Tue, 20 Jul 2021 16:39:07 -0400
Subject: [PATCH 1/2] Low: tools: Audit command line options.
This just goes through and makes sure the command line options that take
arguments are in the special parameter to pcmk__cmdline_preproc, and
that options that do not take arguments are not.
---
tools/crm_attribute.c | 2 +-
tools/crm_error.c | 2 +-
tools/crm_resource.c | 2 +-
tools/crm_rule.c | 2 +-
tools/crm_simulate.c | 2 +-
tools/crmadmin.c | 2 +-
tools/stonith_admin.c | 2 +-
7 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/tools/crm_attribute.c b/tools/crm_attribute.c
index 8a5b4e4..6bd4e2a 100644
--- a/tools/crm_attribute.c
+++ b/tools/crm_attribute.c
@@ -312,7 +312,7 @@ main(int argc, char **argv)
GOptionGroup *output_group = NULL;
pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY);
- gchar **processed_args = pcmk__cmdline_preproc(argv, "DGNPdilnpstv");
+ gchar **processed_args = pcmk__cmdline_preproc(argv, "NPUdilnpstv");
GOptionContext *context = build_arg_context(args, &output_group);
if (!g_option_context_parse_strv(context, &processed_args, &error)) {
diff --git a/tools/crm_error.c b/tools/crm_error.c
index b4328ce..923f393 100644
--- a/tools/crm_error.c
+++ b/tools/crm_error.c
@@ -79,7 +79,7 @@ main(int argc, char **argv)
GOptionGroup *output_group = NULL;
pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY);
- gchar **processed_args = pcmk__cmdline_preproc(argv, "lrnX");
+ gchar **processed_args = pcmk__cmdline_preproc(argv, NULL);
GOptionContext *context = build_arg_context(args, &output_group);
if (!g_option_context_parse_strv(context, &processed_args, &error)) {
diff --git a/tools/crm_resource.c b/tools/crm_resource.c
index fa7902c..d8e140f 100644
--- a/tools/crm_resource.c
+++ b/tools/crm_resource.c
@@ -1530,7 +1530,7 @@ main(int argc, char **argv)
*/
args = pcmk__new_common_args(SUMMARY);
- processed_args = pcmk__cmdline_preproc(argv, "GINSTdginpstuv");
+ processed_args = pcmk__cmdline_preproc(argv, "GHINSTdginpstuvx");
context = build_arg_context(args, &output_group);
pcmk__register_formats(output_group, formats);
diff --git a/tools/crm_rule.c b/tools/crm_rule.c
index 8b19bcd..30c5155 100644
--- a/tools/crm_rule.c
+++ b/tools/crm_rule.c
@@ -239,7 +239,7 @@ main(int argc, char **argv)
pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY);
GOptionContext *context = build_arg_context(args);
- gchar **processed_args = pcmk__cmdline_preproc(argv, "nopNO");
+ gchar **processed_args = pcmk__cmdline_preproc(argv, "drX");
if (!g_option_context_parse_strv(context, &processed_args, &error)) {
exit_code = CRM_EX_USAGE;
diff --git a/tools/crm_simulate.c b/tools/crm_simulate.c
index 0406bff..c83b1b1 100644
--- a/tools/crm_simulate.c
+++ b/tools/crm_simulate.c
@@ -865,7 +865,7 @@ main(int argc, char **argv)
GOptionGroup *output_group = NULL;
pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY);
- gchar **processed_args = pcmk__cmdline_preproc(argv, "bdefgiqrtuwxDFGINO");
+ gchar **processed_args = pcmk__cmdline_preproc(argv, "bdefgiqrtuwxDFGINOP");
GOptionContext *context = build_arg_context(args, &output_group);
/* This must come before g_option_context_parse_strv. */
diff --git a/tools/crmadmin.c b/tools/crmadmin.c
index 5cbde1b..b98f282 100644
--- a/tools/crmadmin.c
+++ b/tools/crmadmin.c
@@ -188,7 +188,7 @@ main(int argc, char **argv)
GOptionGroup *output_group = NULL;
pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY);
- gchar **processed_args = pcmk__cmdline_preproc(argv, "itBDEHKNPS");
+ gchar **processed_args = pcmk__cmdline_preproc(argv, "itKNS");
GOptionContext *context = build_arg_context(args, &output_group);
pcmk__register_formats(output_group, formats);
diff --git a/tools/stonith_admin.c b/tools/stonith_admin.c
index 6773cea..2d48326 100644
--- a/tools/stonith_admin.c
+++ b/tools/stonith_admin.c
@@ -349,7 +349,7 @@ main(int argc, char **argv)
GOptionGroup *output_group = NULL;
pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY);
- gchar **processed_args = pcmk__cmdline_preproc(argv, "adehilorstvBCDFHQRTU");
+ gchar **processed_args = pcmk__cmdline_preproc(argv, "adehilorstvyBCDFHQRTU");
GOptionContext *context = build_arg_context(args, &output_group);
pcmk__register_formats(output_group, formats);
--
1.8.3.1
From 8301678ad1162450814d2fea5288aefe47a67a74 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Tue, 20 Jul 2021 16:40:58 -0400
Subject: [PATCH 2/2] Low: libcrmcommon: Also allow string arguments that start
with a dash.
There's various places where an option to a command line argument could
itself be a valid command line argument. For instance:
crm_attribute -n crm_mon_options -v "-1i3"
The previous patching to pcmk__cmdline_preproc did not take this into
account. With this patch, options that are last in a string (or by
themselves) and take an argument will have the next command line option
grabbed and copied straight through without processing.
Regression in 2.1.0 caused by a long-standing bug in pcmk__cmdline_preproc.
---
lib/common/cmdline.c | 8 ++++++
.../tests/cmdline/pcmk__cmdline_preproc_test.c | 33 ++++++++++++++++++++++
2 files changed, 41 insertions(+)
diff --git a/lib/common/cmdline.c b/lib/common/cmdline.c
index 9c1b810..1ca6147 100644
--- a/lib/common/cmdline.c
+++ b/lib/common/cmdline.c
@@ -146,6 +146,7 @@ gchar **
pcmk__cmdline_preproc(char **argv, const char *special) {
GPtrArray *arr = NULL;
bool saw_dash_dash = false;
+ bool copy_option = false;
if (argv == NULL) {
return NULL;
@@ -175,6 +176,12 @@ pcmk__cmdline_preproc(char **argv, const char *special) {
continue;
}
+ if (copy_option == true) {
+ g_ptr_array_add(arr, g_strdup(argv[i]));
+ copy_option = false;
+ continue;
+ }
+
/* This is just a dash by itself. That could indicate stdin/stdout, or
* it could be user error. Copy it over and let glib figure it out.
*/
@@ -239,6 +246,7 @@ pcmk__cmdline_preproc(char **argv, const char *special) {
*/
} else {
g_ptr_array_add(arr, g_strdup_printf("-%c", *ch));
+ copy_option = true;
ch++;
}
diff --git a/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c b/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c
index 9a752ef..edc5640 100644
--- a/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c
+++ b/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c
@@ -106,6 +106,36 @@ negative_score_2(void) {
g_strfreev(processed);
}
+static void
+string_arg_with_dash(void) {
+ const char *argv[] = { "-n", "crm_mon_options", "-v", "--opt1 --opt2", NULL };
+ const gchar *expected[] = { "-n", "crm_mon_options", "-v", "--opt1 --opt2", NULL };
+
+ gchar **processed = pcmk__cmdline_preproc((char **) argv, "v");
+ LISTS_EQ(processed, expected);
+ g_strfreev(processed);
+}
+
+static void
+string_arg_with_dash_2(void) {
+ const char *argv[] = { "-n", "crm_mon_options", "-v", "-1i3", NULL };
+ const gchar *expected[] = { "-n", "crm_mon_options", "-v", "-1i3", NULL };
+
+ gchar **processed = pcmk__cmdline_preproc((char **) argv, "v");
+ LISTS_EQ(processed, expected);
+ g_strfreev(processed);
+}
+
+static void
+string_arg_with_dash_3(void) {
+ const char *argv[] = { "-abc", "-1i3", NULL };
+ const gchar *expected[] = { "-a", "-b", "-c", "-1i3", NULL };
+
+ gchar **processed = pcmk__cmdline_preproc((char **) argv, "c");
+ LISTS_EQ(processed, expected);
+ g_strfreev(processed);
+}
+
int
main(int argc, char **argv)
{
@@ -120,5 +150,8 @@ main(int argc, char **argv)
g_test_add_func("/common/cmdline/preproc/long_arg", long_arg);
g_test_add_func("/common/cmdline/preproc/negative_score", negative_score);
g_test_add_func("/common/cmdline/preproc/negative_score_2", negative_score_2);
+ g_test_add_func("/common/cmdline/preproc/string_arg_with_dash", string_arg_with_dash);
+ g_test_add_func("/common/cmdline/preproc/string_arg_with_dash_2", string_arg_with_dash_2);
+ g_test_add_func("/common/cmdline/preproc/string_arg_with_dash_3", string_arg_with_dash_3);
return g_test_run();
}
--
1.8.3.1

File diff suppressed because it is too large Load Diff

241
SOURCES/013-leaks.patch Normal file
View File

@ -0,0 +1,241 @@
From bee54eba4d9c28d3a7907a3e13a5deeee6bc0916 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Tue, 27 Jul 2021 11:01:04 -0500
Subject: [PATCH 1/2] Low: tools: avoid (insignificant) memory leaks
detected by valgrind
---
lib/pacemaker/pcmk_cluster_queries.c | 2 ++
tools/crm_diff.c | 2 +-
tools/crm_resource.c | 33 ++++++++++++++++++++-------------
tools/crm_resource_ban.c | 2 +-
4 files changed, 24 insertions(+), 15 deletions(-)
diff --git a/lib/pacemaker/pcmk_cluster_queries.c b/lib/pacemaker/pcmk_cluster_queries.c
index c68cf9d..46e5538 100644
--- a/lib/pacemaker/pcmk_cluster_queries.c
+++ b/lib/pacemaker/pcmk_cluster_queries.c
@@ -440,6 +440,7 @@ pcmk__list_nodes(pcmk__output_t *out, char *node_types, gboolean BASH_EXPORT)
}
rc = the_cib->cmds->signon(the_cib, crm_system_name, cib_command);
if (rc != pcmk_ok) {
+ cib_delete(the_cib);
return pcmk_legacy2rc(rc);
}
@@ -488,6 +489,7 @@ pcmk__list_nodes(pcmk__output_t *out, char *node_types, gboolean BASH_EXPORT)
free_xml(xml_node);
}
the_cib->cmds->signoff(the_cib);
+ cib_delete(the_cib);
return pcmk_legacy2rc(rc);
}
diff --git a/tools/crm_diff.c b/tools/crm_diff.c
index b37f0ea..9890c10 100644
--- a/tools/crm_diff.c
+++ b/tools/crm_diff.c
@@ -383,5 +383,5 @@ done:
free_xml(object_2);
pcmk__output_and_clear_error(error, NULL);
- return exit_code;
+ crm_exit(exit_code);
}
diff --git a/tools/crm_resource.c b/tools/crm_resource.c
index d8e140f..8ca90cb 100644
--- a/tools/crm_resource.c
+++ b/tools/crm_resource.c
@@ -1081,6 +1081,8 @@ clear_constraints(pcmk__output_t *out, xmlNodePtr *cib_xml_copy)
g_set_error(&error, PCMK__RC_ERROR, rc,
"Could not get modified CIB: %s\n", pcmk_strerror(rc));
g_list_free(before);
+ free_xml(*cib_xml_copy);
+ *cib_xml_copy = NULL;
return rc;
}
@@ -1232,29 +1234,34 @@ populate_working_set(xmlNodePtr *cib_xml_copy)
if (options.xml_file != NULL) {
*cib_xml_copy = filename2xml(options.xml_file);
+ if (*cib_xml_copy == NULL) {
+ rc = pcmk_rc_cib_corrupt;
+ }
} else {
rc = cib_conn->cmds->query(cib_conn, NULL, cib_xml_copy, cib_scope_local | cib_sync_call);
rc = pcmk_legacy2rc(rc);
}
- if(rc != pcmk_rc_ok) {
- return rc;
+ if (rc == pcmk_rc_ok) {
+ data_set = pe_new_working_set();
+ if (data_set == NULL) {
+ rc = ENOMEM;
+ } else {
+ pe__set_working_set_flags(data_set,
+ pe_flag_no_counts|pe_flag_no_compat);
+ data_set->priv = out;
+ rc = update_working_set_xml(data_set, cib_xml_copy);
+ }
}
- /* Populate the working set instance */
- data_set = pe_new_working_set();
- if (data_set == NULL) {
- rc = ENOMEM;
+ if (rc != pcmk_rc_ok) {
+ free_xml(*cib_xml_copy);
+ *cib_xml_copy = NULL;
return rc;
}
- pe__set_working_set_flags(data_set, pe_flag_no_counts|pe_flag_no_compat);
- data_set->priv = out;
- rc = update_working_set_xml(data_set, cib_xml_copy);
- if (rc == pcmk_rc_ok) {
- cluster_status(data_set);
- }
- return rc;
+ cluster_status(data_set);
+ return pcmk_rc_ok;
}
static int
diff --git a/tools/crm_resource_ban.c b/tools/crm_resource_ban.c
index a297d49..2c4f48d 100644
--- a/tools/crm_resource_ban.c
+++ b/tools/crm_resource_ban.c
@@ -292,7 +292,7 @@ resource_clear_node_in_location(const char *rsc_id, const char *host, cib_t * ci
rc = pcmk_legacy2rc(rc);
}
- free(fragment);
+ free_xml(fragment);
return rc;
}
--
1.8.3.1
From a30ff4a87f291a0c9e03c4efb9c9046d2ac594f1 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Tue, 27 Jul 2021 11:26:59 -0500
Subject: [PATCH 2/2] Fix: tools: avoid memory leaks in crm_mon
could be significant in an interactive session
regressions introduced in 2.0.4 and 2.0.5
---
lib/pengine/bundle.c | 3 ++-
lib/pengine/clone.c | 5 ++---
lib/pengine/pe_output.c | 3 +++
3 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/lib/pengine/bundle.c b/lib/pengine/bundle.c
index 6ba786a..7e1d428 100644
--- a/lib/pengine/bundle.c
+++ b/lib/pengine/bundle.c
@@ -1497,7 +1497,7 @@ pe__bundle_xml(pcmk__output_t *out, va_list args)
for (GList *gIter = bundle_data->replicas; gIter != NULL;
gIter = gIter->next) {
pe__bundle_replica_t *replica = gIter->data;
- char *id = pcmk__itoa(replica->offset);
+ char *id = NULL;
gboolean print_ip, print_child, print_ctnr, print_remote;
CRM_ASSERT(replica);
@@ -1531,6 +1531,7 @@ pe__bundle_xml(pcmk__output_t *out, va_list args)
CRM_ASSERT(rc == pcmk_rc_ok);
}
+ id = pcmk__itoa(replica->offset);
rc = pe__name_and_nvpairs_xml(out, true, "replica", 1, "id", id);
free(id);
CRM_ASSERT(rc == pcmk_rc_ok);
diff --git a/lib/pengine/clone.c b/lib/pengine/clone.c
index 6323692..ab91fd1 100644
--- a/lib/pengine/clone.c
+++ b/lib/pengine/clone.c
@@ -807,10 +807,10 @@ pe__clone_html(pcmk__output_t *out, va_list args)
pcmk__add_word(&list_text, &list_text_len, host->details->uname);
active_instances++;
}
+ g_list_free(promoted_list);
if (list_text != NULL) {
out->list_item(out, NULL, PROMOTED_INSTANCES ": [ %s ]", list_text);
- g_list_free(promoted_list);
free(list_text);
list_text = NULL;
list_text_len = 0;
@@ -828,6 +828,7 @@ pe__clone_html(pcmk__output_t *out, va_list args)
pcmk__add_word(&list_text, &list_text_len, host->details->uname);
active_instances++;
}
+ g_list_free(started_list);
if (list_text != NULL) {
if (pcmk_is_set(rsc->flags, pe_rsc_promotable)) {
@@ -847,7 +848,6 @@ pe__clone_html(pcmk__output_t *out, va_list args)
out->list_item(out, NULL, "Started: [ %s ]", list_text);
}
- g_list_free(started_list);
free(list_text);
list_text = NULL;
list_text_len = 0;
@@ -1048,10 +1048,10 @@ pe__clone_text(pcmk__output_t *out, va_list args)
pcmk__add_word(&list_text, &list_text_len, host->details->uname);
active_instances++;
}
+ g_list_free(promoted_list);
if (list_text != NULL) {
out->list_item(out, PROMOTED_INSTANCES, "[ %s ]", list_text);
- g_list_free(promoted_list);
free(list_text);
list_text = NULL;
list_text_len = 0;
@@ -1069,6 +1069,7 @@ pe__clone_text(pcmk__output_t *out, va_list args)
pcmk__add_word(&list_text, &list_text_len, host->details->uname);
active_instances++;
}
+ g_list_free(started_list);
if (list_text != NULL) {
if (pcmk_is_set(rsc->flags, pe_rsc_promotable)) {
@@ -1084,7 +1085,6 @@ pe__clone_text(pcmk__output_t *out, va_list args)
out->list_item(out, "Started", "[ %s ]", list_text);
}
- g_list_free(started_list);
free(list_text);
list_text = NULL;
}
diff --git a/lib/pengine/pe_output.c b/lib/pengine/pe_output.c
index b8997c4..20bd1a9 100644
--- a/lib/pengine/pe_output.c
+++ b/lib/pengine/pe_output.c
@@ -1410,6 +1410,8 @@ node_text(pcmk__output_t *out, va_list args) {
out->end_list(out);
out->end_list(out);
+
+ g_list_free(rscs);
}
} else {
@@ -1739,6 +1741,7 @@ node_attribute_list(pcmk__output_t *out, va_list args) {
}
if (!pcmk__str_in_list(only_node, node->details->uname)) {
+ g_list_free(attr_list);
continue;
}
--
1.8.3.1

View File

@ -1,285 +0,0 @@
From 0700a4814a598d0e2e9bd54f970c6d3ff66184df Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Tue, 24 Nov 2020 16:17:34 +0100
Subject: [PATCH 1/2] Refactor: move stonith__register_messages() call from
pcmk__out_prologue() to the calling functions
---
lib/pacemaker/pcmk_fence.c | 14 ++++++++++++++
lib/pacemaker/pcmk_output.c | 1 -
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/lib/pacemaker/pcmk_fence.c b/lib/pacemaker/pcmk_fence.c
index 7beedff..d591379 100644
--- a/lib/pacemaker/pcmk_fence.c
+++ b/lib/pacemaker/pcmk_fence.c
@@ -247,6 +247,8 @@ pcmk_fence_history(xmlNodePtr *xml, stonith_t *st, char *target, unsigned int ti
return rc;
}
+ stonith__register_messages(out);
+
out->quiet = quiet;
rc = pcmk__fence_history(out, st, target, timeout, verbose, broadcast, cleanup);
@@ -287,6 +289,8 @@ pcmk_fence_installed(xmlNodePtr *xml, stonith_t *st, unsigned int timeout) {
return rc;
}
+ stonith__register_messages(out);
+
rc = pcmk__fence_installed(out, st, timeout);
pcmk__out_epilogue(out, xml, rc);
return rc;
@@ -321,6 +325,8 @@ pcmk_fence_last(xmlNodePtr *xml, const char *target, bool as_nodeid) {
return rc;
}
+ stonith__register_messages(out);
+
rc = pcmk__fence_last(out, target, as_nodeid);
pcmk__out_epilogue(out, xml, rc);
return rc;
@@ -364,6 +370,8 @@ pcmk_fence_list_targets(xmlNodePtr *xml, stonith_t *st, const char *device_id,
return rc;
}
+ stonith__register_messages(out);
+
rc = pcmk__fence_list_targets(out, st, device_id, timeout);
pcmk__out_epilogue(out, xml, rc);
return rc;
@@ -398,6 +406,8 @@ pcmk_fence_metadata(xmlNodePtr *xml, stonith_t *st, char *agent,
return rc;
}
+ stonith__register_messages(out);
+
rc = pcmk__fence_metadata(out, st, agent, timeout);
pcmk__out_epilogue(out, xml, rc);
return rc;
@@ -442,6 +452,8 @@ pcmk_fence_registered(xmlNodePtr *xml, stonith_t *st, char *target,
return rc;
}
+ stonith__register_messages(out);
+
rc = pcmk__fence_registered(out, st, target, timeout);
pcmk__out_epilogue(out, xml, rc);
return rc;
@@ -501,6 +513,8 @@ pcmk_fence_validate(xmlNodePtr *xml, stonith_t *st, const char *agent,
return rc;
}
+ stonith__register_messages(out);
+
rc = pcmk__fence_validate(out, st, agent, id, params, timeout);
pcmk__out_epilogue(out, xml, rc);
return rc;
diff --git a/lib/pacemaker/pcmk_output.c b/lib/pacemaker/pcmk_output.c
index 74a7c59..a637031 100644
--- a/lib/pacemaker/pcmk_output.c
+++ b/lib/pacemaker/pcmk_output.c
@@ -34,7 +34,6 @@ pcmk__out_prologue(pcmk__output_t **out, xmlNodePtr *xml) {
return rc;
}
- stonith__register_messages(*out);
return rc;
}
--
1.8.3.1
From 27677a6d03ba42aeb0d6a971df9d9b8861232903 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Tue, 24 Nov 2020 16:19:59 +0100
Subject: [PATCH 2/2] API: libpacemaker: add public API functions for cluster
queries
---
include/pacemaker.h | 45 +++++++++++++++++++++-
lib/pacemaker/pcmk_cluster_queries.c | 75 ++++++++++++++++++++++++++++++++++++
2 files changed, 118 insertions(+), 2 deletions(-)
diff --git a/include/pacemaker.h b/include/pacemaker.h
index a1e76d0..b2a73cd 100644
--- a/include/pacemaker.h
+++ b/include/pacemaker.h
@@ -14,8 +14,6 @@
extern "C" {
#endif
-#ifdef BUILD_PUBLIC_LIBPACEMAKER
-
/**
* \file
* \brief High Level API
@@ -26,6 +24,49 @@ extern "C" {
# include <libxml/tree.h>
/*!
+ * \brief Get controller status
+ *
+ * \param[in,out] xml The destination for the result, as an XML tree.
+ * \param[in] dest_node Destination node for request
+ * \param[in] message_timeout_ms Message timeout
+ *
+ * \return Standard Pacemaker return code
+ */
+int pcmk_controller_status(xmlNodePtr *xml, char *dest_node, unsigned int message_timeout_ms);
+
+/*!
+ * \brief Get designated controller
+ *
+ * \param[in,out] xml The destination for the result, as an XML tree.
+ * \param[in] message_timeout_ms Message timeout
+ *
+ * \return Standard Pacemaker return code
+ */
+int pcmk_designated_controller(xmlNodePtr *xml, unsigned int message_timeout_ms);
+
+/*!
+ * \brief Get pacemakerd status
+ *
+ * \param[in,out] xml The destination for the result, as an XML tree.
+ * \param[in] ipc_name IPC name for request
+ * \param[in] message_timeout_ms Message timeout
+ *
+ * \return Standard Pacemaker return code
+ */
+int pcmk_pacemakerd_status(xmlNodePtr *xml, char *ipc_name, unsigned int message_timeout_ms);
+
+#ifdef BUILD_PUBLIC_LIBPACEMAKER
+
+/*!
+ * \brief Get nodes list
+ *
+ * \param[in,out] xml The destination for the result, as an XML tree.
+ *
+ * \return Standard Pacemaker return code
+ */
+int pcmk_list_nodes(xmlNodePtr *xml);
+
+/*!
* \brief Perform a STONITH action.
*
* \param[in] st A connection to the STONITH API.
diff --git a/lib/pacemaker/pcmk_cluster_queries.c b/lib/pacemaker/pcmk_cluster_queries.c
index 8d729eb..c705b7f 100644
--- a/lib/pacemaker/pcmk_cluster_queries.c
+++ b/lib/pacemaker/pcmk_cluster_queries.c
@@ -1,6 +1,7 @@
#include <glib.h> // gboolean, GMainLoop, etc.
#include <libxml/tree.h> // xmlNode
+#include <pacemaker.h>
#include <pacemaker-internal.h>
#include <crm/crm.h>
@@ -282,6 +283,24 @@ pcmk__controller_status(pcmk__output_t *out, char *dest_node, guint message_time
}
int
+pcmk_controller_status(xmlNodePtr *xml, char *dest_node, unsigned int message_timeout_ms)
+{
+ pcmk__output_t *out = NULL;
+ int rc = pcmk_rc_ok;
+
+ rc = pcmk__out_prologue(&out, xml);
+ if (rc != pcmk_rc_ok) {
+ return rc;
+ }
+
+ pcmk__register_lib_messages(out);
+
+ rc = pcmk__controller_status(out, dest_node, (guint) message_timeout_ms);
+ pcmk__out_epilogue(out, xml, rc);
+ return rc;
+}
+
+int
pcmk__designated_controller(pcmk__output_t *out, guint message_timeout_ms)
{
data_t data = {
@@ -309,6 +328,24 @@ pcmk__designated_controller(pcmk__output_t *out, guint message_timeout_ms)
}
int
+pcmk_designated_controller(xmlNodePtr *xml, unsigned int message_timeout_ms)
+{
+ pcmk__output_t *out = NULL;
+ int rc = pcmk_rc_ok;
+
+ rc = pcmk__out_prologue(&out, xml);
+ if (rc != pcmk_rc_ok) {
+ return rc;
+ }
+
+ pcmk__register_lib_messages(out);
+
+ rc = pcmk__designated_controller(out, (guint) message_timeout_ms);
+ pcmk__out_epilogue(out, xml, rc);
+ return rc;
+}
+
+int
pcmk__pacemakerd_status(pcmk__output_t *out, char *ipc_name, guint message_timeout_ms)
{
data_t data = {
@@ -335,6 +372,24 @@ pcmk__pacemakerd_status(pcmk__output_t *out, char *ipc_name, guint message_timeo
return data.rc;
}
+int
+pcmk_pacemakerd_status(xmlNodePtr *xml, char *ipc_name, unsigned int message_timeout_ms)
+{
+ pcmk__output_t *out = NULL;
+ int rc = pcmk_rc_ok;
+
+ rc = pcmk__out_prologue(&out, xml);
+ if (rc != pcmk_rc_ok) {
+ return rc;
+ }
+
+ pcmk__register_lib_messages(out);
+
+ rc = pcmk__pacemakerd_status(out, ipc_name, (guint) message_timeout_ms);
+ pcmk__out_epilogue(out, xml, rc);
+ return rc;
+}
+
// \return Standard Pacemaker return code
int
pcmk__list_nodes(pcmk__output_t *out, gboolean BASH_EXPORT)
@@ -361,6 +416,26 @@ pcmk__list_nodes(pcmk__output_t *out, gboolean BASH_EXPORT)
return pcmk_legacy2rc(rc);
}
+#ifdef BUILD_PUBLIC_LIBPACEMAKER
+int
+pcmk_list_nodes(xmlNodePtr *xml)
+{
+ pcmk__output_t *out = NULL;
+ int rc = pcmk_rc_ok;
+
+ rc = pcmk__out_prologue(&out, xml);
+ if (rc != pcmk_rc_ok) {
+ return rc;
+ }
+
+ pcmk__register_lib_messages(out);
+
+ rc = pcmk__list_nodes(out, FALSE);
+ pcmk__out_epilogue(out, xml, rc);
+ return rc;
+}
+#endif
+
// remove when parameters removed from tools/crmadmin.c
int
pcmk__shutdown_controller(pcmk__output_t *out, char *dest_node)
--
1.8.3.1

465
SOURCES/014-str-list.patch Normal file
View File

@ -0,0 +1,465 @@
From 45813df3eb4c8ad8b1744fa5dd56af86ad0fb3dd Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Thu, 17 Jun 2021 16:07:55 -0400
Subject: [PATCH] Refactor: libs: pcmk__str_in_list should support pcmk__str_*
flags.
---
include/crm/common/strings_internal.h | 2 +-
lib/common/strings.c | 34 +++++++++++++++++++++++----
lib/fencing/st_output.c | 10 ++++----
lib/pengine/bundle.c | 8 +++----
lib/pengine/clone.c | 28 +++++++++++-----------
lib/pengine/group.c | 18 +++++++-------
lib/pengine/native.c | 4 ++--
lib/pengine/pe_output.c | 22 ++++++++---------
lib/pengine/utils.c | 6 ++---
9 files changed, 79 insertions(+), 53 deletions(-)
diff --git a/include/crm/common/strings_internal.h b/include/crm/common/strings_internal.h
index 94982cb4e..687079814 100644
--- a/include/crm/common/strings_internal.h
+++ b/include/crm/common/strings_internal.h
@@ -117,7 +117,7 @@ pcmk__intkey_table_remove(GHashTable *hash_table, int key)
return g_hash_table_remove(hash_table, GINT_TO_POINTER(key));
}
-gboolean pcmk__str_in_list(GList *lst, const gchar *s);
+gboolean pcmk__str_in_list(GList *lst, const gchar *s, uint32_t flags);
bool pcmk__strcase_any_of(const char *s, ...) G_GNUC_NULL_TERMINATED;
bool pcmk__str_any_of(const char *s, ...) G_GNUC_NULL_TERMINATED;
diff --git a/lib/common/strings.c b/lib/common/strings.c
index 3264db5b6..e1e98803b 100644
--- a/lib/common/strings.c
+++ b/lib/common/strings.c
@@ -872,14 +872,30 @@ pcmk__parse_ll_range(const char *srcstring, long long *start, long long *end)
* Search \p lst for \p s, taking case into account. As a special case,
* if "*" is the only element of \p lst, the search is successful.
*
- * \param[in] lst List to search
- * \param[in] s String to search for
+ * Behavior can be changed with various flags:
+ *
+ * - pcmk__str_casei - By default, comparisons are done taking case into
+ * account. This flag makes comparisons case-insensitive.
+ * - pcmk__str_null_matches - If the input string is NULL, return TRUE.
+ *
+ * \note The special "*" matching rule takes precedence over flags. In
+ * particular, "*" will match a NULL input string even without
+ * pcmk__str_null_matches being specified.
+ *
+ * \note No matter what input string or flags are provided, an empty
+ * list will always return FALSE.
+ *
+ * \param[in] lst List to search
+ * \param[in] s String to search for
+ * \param[in] flags A bitfield of pcmk__str_flags to modify operation
*
* \return \c TRUE if \p s is in \p lst, or \c FALSE otherwise
*/
gboolean
-pcmk__str_in_list(GList *lst, const gchar *s)
+pcmk__str_in_list(GList *lst, const gchar *s, uint32_t flags)
{
+ GCompareFunc fn;
+
if (lst == NULL) {
return FALSE;
}
@@ -888,7 +904,17 @@ pcmk__str_in_list(GList *lst, const gchar *s)
return TRUE;
}
- return g_list_find_custom(lst, s, (GCompareFunc) strcmp) != NULL;
+ if (s == NULL) {
+ return pcmk_is_set(flags, pcmk__str_null_matches);
+ }
+
+ if (pcmk_is_set(flags, pcmk__str_casei)) {
+ fn = (GCompareFunc) strcasecmp;
+ } else {
+ fn = (GCompareFunc) strcmp;
+ }
+
+ return g_list_find_custom(lst, s, fn) != NULL;
}
static bool
diff --git a/lib/fencing/st_output.c b/lib/fencing/st_output.c
index 568ae46a8..e1ae8ac87 100644
--- a/lib/fencing/st_output.c
+++ b/lib/fencing/st_output.c
@@ -47,7 +47,7 @@ stonith__failed_history(pcmk__output_t *out, va_list args) {
continue;
}
- if (!pcmk__str_in_list(only_node, hp->target)) {
+ if (!pcmk__str_in_list(only_node, hp->target, pcmk__str_none)) {
continue;
}
@@ -72,7 +72,7 @@ stonith__history(pcmk__output_t *out, va_list args) {
int rc = pcmk_rc_no_output;
for (stonith_history_t *hp = history; hp; hp = hp->next) {
- if (!pcmk__str_in_list(only_node, hp->target)) {
+ if (!pcmk__str_in_list(only_node, hp->target, pcmk__str_none)) {
continue;
}
@@ -101,7 +101,7 @@ stonith__full_history(pcmk__output_t *out, va_list args) {
int rc = pcmk_rc_no_output;
for (stonith_history_t *hp = history; hp; hp = hp->next) {
- if (!pcmk__str_in_list(only_node, hp->target)) {
+ if (!pcmk__str_in_list(only_node, hp->target, pcmk__str_none)) {
continue;
}
@@ -129,7 +129,7 @@ full_history_xml(pcmk__output_t *out, va_list args) {
if (history_rc == 0) {
for (stonith_history_t *hp = history; hp; hp = hp->next) {
- if (!pcmk__str_in_list(only_node, hp->target)) {
+ if (!pcmk__str_in_list(only_node, hp->target, pcmk__str_none)) {
continue;
}
@@ -218,7 +218,7 @@ stonith__pending_actions(pcmk__output_t *out, va_list args) {
int rc = pcmk_rc_no_output;
for (stonith_history_t *hp = history; hp; hp = hp->next) {
- if (!pcmk__str_in_list(only_node, hp->target)) {
+ if (!pcmk__str_in_list(only_node, hp->target, pcmk__str_none)) {
continue;
}
diff --git a/lib/pengine/bundle.c b/lib/pengine/bundle.c
index 9237392e4..6ba786ae6 100644
--- a/lib/pengine/bundle.c
+++ b/lib/pengine/bundle.c
@@ -1492,7 +1492,7 @@ pe__bundle_xml(pcmk__output_t *out, va_list args)
return rc;
}
- print_everything = pcmk__str_in_list(only_rsc, rsc->id);
+ print_everything = pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none);
for (GList *gIter = bundle_data->replicas; gIter != NULL;
gIter = gIter->next) {
@@ -1614,7 +1614,7 @@ pe__bundle_html(pcmk__output_t *out, va_list args)
return rc;
}
- print_everything = pcmk__str_in_list(only_rsc, rsc->id);
+ print_everything = pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none);
for (GList *gIter = bundle_data->replicas; gIter != NULL;
gIter = gIter->next) {
@@ -1742,7 +1742,7 @@ pe__bundle_text(pcmk__output_t *out, va_list args)
return rc;
}
- print_everything = pcmk__str_in_list(only_rsc, rsc->id);
+ print_everything = pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none);
for (GList *gIter = bundle_data->replicas; gIter != NULL;
gIter = gIter->next) {
@@ -2044,7 +2044,7 @@ pe__bundle_is_filtered(pe_resource_t *rsc, GList *only_rsc, gboolean check_paren
gboolean passes = FALSE;
pe__bundle_variant_data_t *bundle_data = NULL;
- if (pcmk__str_in_list(only_rsc, rsc_printable_id(rsc))) {
+ if (pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none)) {
passes = TRUE;
} else {
get_bundle_variant_data(bundle_data, rsc);
diff --git a/lib/pengine/clone.c b/lib/pengine/clone.c
index 5662338f3..5a6bfa61f 100644
--- a/lib/pengine/clone.c
+++ b/lib/pengine/clone.c
@@ -624,8 +624,8 @@ pe__clone_xml(pcmk__output_t *out, va_list args)
return rc;
}
- print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc)) ||
- (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id));
+ print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none) ||
+ (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none));
for (; gIter != NULL; gIter = gIter->next) {
pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
@@ -693,8 +693,8 @@ pe__clone_html(pcmk__output_t *out, va_list args)
return rc;
}
- print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc)) ||
- (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id));
+ print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none) ||
+ (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none));
out->begin_list(out, NULL, NULL, "Clone Set: %s [%s]%s%s%s%s",
rsc->id, ID(clone_data->xml_obj_child),
@@ -801,7 +801,7 @@ pe__clone_html(pcmk__output_t *out, va_list args)
for (gIter = promoted_list; gIter; gIter = gIter->next) {
pe_node_t *host = gIter->data;
- if (!pcmk__str_in_list(only_node, host->details->uname)) {
+ if (!pcmk__str_in_list(only_node, host->details->uname, pcmk__str_none)) {
continue;
}
@@ -822,7 +822,7 @@ pe__clone_html(pcmk__output_t *out, va_list args)
for (gIter = started_list; gIter; gIter = gIter->next) {
pe_node_t *host = gIter->data;
- if (!pcmk__str_in_list(only_node, host->details->uname)) {
+ if (!pcmk__str_in_list(only_node, host->details->uname, pcmk__str_none)) {
continue;
}
@@ -884,7 +884,7 @@ pe__clone_html(pcmk__output_t *out, va_list args)
pe_node_t *node = (pe_node_t *)nIter->data;
if (pe_find_node(rsc->running_on, node->details->uname) == NULL &&
- pcmk__str_in_list(only_node, node->details->uname)) {
+ pcmk__str_in_list(only_node, node->details->uname, pcmk__str_none)) {
pcmk__add_word(&stopped_list, &stopped_list_len,
node->details->uname);
}
@@ -933,8 +933,8 @@ pe__clone_text(pcmk__output_t *out, va_list args)
return rc;
}
- print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc)) ||
- (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id));
+ print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none) ||
+ (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none));
out->begin_list(out, NULL, NULL, "Clone Set: %s [%s]%s%s%s%s",
rsc->id, ID(clone_data->xml_obj_child),
@@ -1041,7 +1041,7 @@ pe__clone_text(pcmk__output_t *out, va_list args)
for (gIter = promoted_list; gIter; gIter = gIter->next) {
pe_node_t *host = gIter->data;
- if (!pcmk__str_in_list(only_node, host->details->uname)) {
+ if (!pcmk__str_in_list(only_node, host->details->uname, pcmk__str_none)) {
continue;
}
@@ -1062,7 +1062,7 @@ pe__clone_text(pcmk__output_t *out, va_list args)
for (gIter = started_list; gIter; gIter = gIter->next) {
pe_node_t *host = gIter->data;
- if (!pcmk__str_in_list(only_node, host->details->uname)) {
+ if (!pcmk__str_in_list(only_node, host->details->uname, pcmk__str_none)) {
continue;
}
@@ -1120,7 +1120,7 @@ pe__clone_text(pcmk__output_t *out, va_list args)
pe_node_t *node = (pe_node_t *)nIter->data;
if (pe_find_node(rsc->running_on, node->details->uname) == NULL &&
- pcmk__str_in_list(only_node, node->details->uname)) {
+ pcmk__str_in_list(only_node, node->details->uname, pcmk__str_none)) {
pcmk__add_word(&stopped_list, &stopped_list_len,
node->details->uname);
}
@@ -1220,11 +1220,11 @@ pe__clone_is_filtered(pe_resource_t *rsc, GList *only_rsc, gboolean check_parent
gboolean passes = FALSE;
clone_variant_data_t *clone_data = NULL;
- if (pcmk__str_in_list(only_rsc, rsc_printable_id(rsc))) {
+ if (pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none)) {
passes = TRUE;
} else {
get_clone_variant_data(clone_data, rsc);
- passes = pcmk__str_in_list(only_rsc, ID(clone_data->xml_obj_child));
+ passes = pcmk__str_in_list(only_rsc, ID(clone_data->xml_obj_child), pcmk__str_none);
if (!passes) {
for (GList *gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
diff --git a/lib/pengine/group.c b/lib/pengine/group.c
index 23a72cff7..5f9aa83ce 100644
--- a/lib/pengine/group.c
+++ b/lib/pengine/group.c
@@ -201,8 +201,8 @@ pe__group_xml(pcmk__output_t *out, va_list args)
return rc;
}
- print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc)) ||
- (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id));
+ print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none) ||
+ (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none));
for (; gIter != NULL; gIter = gIter->next) {
pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
@@ -248,8 +248,8 @@ pe__group_html(pcmk__output_t *out, va_list args)
return rc;
}
- print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc)) ||
- (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id));
+ print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none) ||
+ (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none));
if (options & pe_print_brief) {
GList *rscs = pe__filter_rsc_list(rsc->children, only_rsc);
@@ -303,8 +303,8 @@ pe__group_text(pcmk__output_t *out, va_list args)
return rc;
}
- print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc)) ||
- (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id));
+ print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none) ||
+ (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none));
if (options & pe_print_brief) {
GList *rscs = pe__filter_rsc_list(rsc->children, only_rsc);
@@ -387,11 +387,11 @@ pe__group_is_filtered(pe_resource_t *rsc, GList *only_rsc, gboolean check_parent
{
gboolean passes = FALSE;
- if (check_parent && pcmk__str_in_list(only_rsc, rsc_printable_id(uber_parent(rsc)))) {
+ if (check_parent && pcmk__str_in_list(only_rsc, rsc_printable_id(uber_parent(rsc)), pcmk__str_none)) {
passes = TRUE;
- } else if (pcmk__str_in_list(only_rsc, rsc_printable_id(rsc))) {
+ } else if (pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none)) {
passes = TRUE;
- } else if (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id)) {
+ } else if (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none)) {
passes = TRUE;
} else {
for (GList *gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
diff --git a/lib/pengine/native.c b/lib/pengine/native.c
index c2333d0d2..56054fc4a 100644
--- a/lib/pengine/native.c
+++ b/lib/pengine/native.c
@@ -1338,8 +1338,8 @@ pe__rscs_brief_output(pcmk__output_t *out, GList *rsc_list, unsigned int show_op
gboolean
pe__native_is_filtered(pe_resource_t *rsc, GList *only_rsc, gboolean check_parent)
{
- if (pcmk__str_in_list(only_rsc, rsc_printable_id(rsc)) ||
- pcmk__str_in_list(only_rsc, rsc->id)) {
+ if (pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none) ||
+ pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none)) {
return FALSE;
} else if (check_parent) {
pe_resource_t *up = uber_parent(rsc);
diff --git a/lib/pengine/pe_output.c b/lib/pengine/pe_output.c
index 727475735..a6dc4ade8 100644
--- a/lib/pengine/pe_output.c
+++ b/lib/pengine/pe_output.c
@@ -670,8 +670,8 @@ ban_list(pcmk__output_t *out, va_list args) {
continue;
}
- if (!pcmk__str_in_list(only_rsc, rsc_printable_id(location->rsc_lh)) &&
- !pcmk__str_in_list(only_rsc, rsc_printable_id(uber_parent(location->rsc_lh)))) {
+ if (!pcmk__str_in_list(only_rsc, rsc_printable_id(location->rsc_lh), pcmk__str_none) &&
+ !pcmk__str_in_list(only_rsc, rsc_printable_id(uber_parent(location->rsc_lh)), pcmk__str_none)) {
continue;
}
@@ -1254,7 +1254,7 @@ failed_action_list(pcmk__output_t *out, va_list args) {
xml_op = pcmk__xml_next(xml_op)) {
char *rsc = NULL;
- if (!pcmk__str_in_list(only_node, crm_element_value(xml_op, XML_ATTR_UNAME))) {
+ if (!pcmk__str_in_list(only_node, crm_element_value(xml_op, XML_ATTR_UNAME), pcmk__str_none)) {
continue;
}
@@ -1263,7 +1263,7 @@ failed_action_list(pcmk__output_t *out, va_list args) {
continue;
}
- if (!pcmk__str_in_list(only_rsc, rsc)) {
+ if (!pcmk__str_in_list(only_rsc, rsc, pcmk__str_none)) {
free(rsc);
continue;
}
@@ -1738,7 +1738,7 @@ node_attribute_list(pcmk__output_t *out, va_list args) {
continue;
}
- if (!pcmk__str_in_list(only_node, node->details->uname)) {
+ if (!pcmk__str_in_list(only_node, node->details->uname, pcmk__str_none)) {
g_list_free(attr_list);
continue;
}
@@ -1835,8 +1835,8 @@ node_history_list(pcmk__output_t *out, va_list args) {
* For other resource types, is_filtered is okay.
*/
if (uber_parent(rsc)->variant == pe_group) {
- if (!pcmk__str_in_list(only_rsc, rsc_printable_id(rsc)) &&
- !pcmk__str_in_list(only_rsc, rsc_printable_id(uber_parent(rsc)))) {
+ if (!pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none) &&
+ !pcmk__str_in_list(only_rsc, rsc_printable_id(uber_parent(rsc)), pcmk__str_none)) {
continue;
}
} else {
@@ -1899,7 +1899,7 @@ node_list_html(pcmk__output_t *out, va_list args) {
for (GList *gIter = nodes; gIter != NULL; gIter = gIter->next) {
pe_node_t *node = (pe_node_t *) gIter->data;
- if (!pcmk__str_in_list(only_node, node->details->uname)) {
+ if (!pcmk__str_in_list(only_node, node->details->uname, pcmk__str_none)) {
continue;
}
@@ -1940,7 +1940,7 @@ pe__node_list_text(pcmk__output_t *out, va_list args) {
const char *node_mode = NULL;
char *node_name = pe__node_display_name(node, print_clone_detail);
- if (!pcmk__str_in_list(only_node, node->details->uname)) {
+ if (!pcmk__str_in_list(only_node, node->details->uname, pcmk__str_none)) {
free(node_name);
continue;
}
@@ -2059,7 +2059,7 @@ node_list_xml(pcmk__output_t *out, va_list args) {
for (GList *gIter = nodes; gIter != NULL; gIter = gIter->next) {
pe_node_t *node = (pe_node_t *) gIter->data;
- if (!pcmk__str_in_list(only_node, node->details->uname)) {
+ if (!pcmk__str_in_list(only_node, node->details->uname, pcmk__str_none)) {
continue;
}
@@ -2097,7 +2097,7 @@ node_summary(pcmk__output_t *out, va_list args) {
continue;
}
- if (!pcmk__str_in_list(only_node, node->details->uname)) {
+ if (!pcmk__str_in_list(only_node, node->details->uname, pcmk__str_none)) {
continue;
}
diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c
index 450d8348c..d1be9e4ca 100644
--- a/lib/pengine/utils.c
+++ b/lib/pengine/utils.c
@@ -2394,7 +2394,7 @@ pe__rsc_running_on_any_node_in_list(pe_resource_t *rsc, GList *node_list)
{
for (GList *ele = rsc->running_on; ele; ele = ele->next) {
pe_node_t *node = (pe_node_t *) ele->data;
- if (pcmk__str_in_list(node_list, node->details->uname)) {
+ if (pcmk__str_in_list(node_list, node->details->uname, pcmk__str_none)) {
return true;
}
}
@@ -2419,8 +2419,8 @@ pe__filter_rsc_list(GList *rscs, GList *filter)
/* I think the second condition is safe here for all callers of this
* function. If not, it needs to move into pe__node_text.
*/
- if (pcmk__str_in_list(filter, rsc_printable_id(rsc)) ||
- (rsc->parent && pcmk__str_in_list(filter, rsc_printable_id(rsc->parent)))) {
+ if (pcmk__str_in_list(filter, rsc_printable_id(rsc), pcmk__str_none) ||
+ (rsc->parent && pcmk__str_in_list(filter, rsc_printable_id(rsc->parent), pcmk__str_none))) {
retval = g_list_prepend(retval, rsc);
}
}
--
2.27.0

View File

@ -1,114 +0,0 @@
From 12b30c920dd15287a7b295475ce1cc4a6cb1f43f Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Tue, 8 Dec 2020 15:48:38 -0500
Subject: [PATCH] Fix: scheduler: Don't output a resource header with no list.
If there's no resources to print, don't output just the header with
nothing under it. This potentially comes up if there are only inactive
resources, but inactive_resources is FALSE.
---
lib/pengine/pe_output.c | 48 ++++++++++++++++++++++++++++++++++++------------
1 file changed, 36 insertions(+), 12 deletions(-)
diff --git a/lib/pengine/pe_output.c b/lib/pengine/pe_output.c
index 5562eb6..f1a6b43 100644
--- a/lib/pengine/pe_output.c
+++ b/lib/pengine/pe_output.c
@@ -1761,6 +1761,21 @@ resource_history_xml(pcmk__output_t *out, va_list args) {
return pcmk_rc_ok;
}
+static void
+print_resource_header(pcmk__output_t *out, gboolean group_by_node,
+ gboolean inactive_resources)
+{
+ if (group_by_node) {
+ /* Active resources have already been printed by node */
+ out->begin_list(out, NULL, NULL, "Inactive Resources");
+ } else if (inactive_resources) {
+ out->begin_list(out, NULL, NULL, "Full List of Resources");
+ } else {
+ out->begin_list(out, NULL, NULL, "Active Resources");
+ }
+}
+
+
PCMK__OUTPUT_ARGS("resource-list", "pe_working_set_t *", "unsigned int", "gboolean",
"gboolean", "gboolean", "gboolean", "GList *", "GList *", "gboolean")
static int
@@ -1778,6 +1793,7 @@ resource_list(pcmk__output_t *out, va_list args)
GList *rsc_iter;
int rc = pcmk_rc_no_output;
+ bool printed_header = false;
/* If we already showed active resources by node, and
* we're not showing inactive resources, we have nothing to do
@@ -1786,22 +1802,15 @@ resource_list(pcmk__output_t *out, va_list args)
return rc;
}
- PCMK__OUTPUT_SPACER_IF(out, print_spacer);
-
- if (group_by_node) {
- /* Active resources have already been printed by node */
- out->begin_list(out, NULL, NULL, "Inactive Resources");
- } else if (inactive_resources) {
- out->begin_list(out, NULL, NULL, "Full List of Resources");
- } else {
- out->begin_list(out, NULL, NULL, "Active Resources");
- }
-
/* If we haven't already printed resources grouped by node,
* and brief output was requested, print resource summary */
if (brief_output && !group_by_node) {
GList *rscs = pe__filter_rsc_list(data_set->resources, only_rsc);
+ PCMK__OUTPUT_SPACER_IF(out, print_spacer);
+ print_resource_header(out, group_by_node, inactive_resources);
+ printed_header = true;
+
pe__rscs_brief_output(out, rscs, print_opts, inactive_resources);
g_list_free(rscs);
}
@@ -1839,6 +1848,12 @@ resource_list(pcmk__output_t *out, va_list args)
continue;
}
+ if (!printed_header) {
+ PCMK__OUTPUT_SPACER_IF(out, print_spacer);
+ print_resource_header(out, group_by_node, inactive_resources);
+ printed_header = true;
+ }
+
/* Print this resource */
x = out->message(out, crm_map_element_name(rsc->xml), print_opts, rsc,
only_node, only_rsc);
@@ -1848,6 +1863,12 @@ resource_list(pcmk__output_t *out, va_list args)
}
if (print_summary && rc != pcmk_rc_ok) {
+ if (!printed_header) {
+ PCMK__OUTPUT_SPACER_IF(out, print_spacer);
+ print_resource_header(out, group_by_node, inactive_resources);
+ printed_header = true;
+ }
+
if (group_by_node) {
out->list_item(out, NULL, "No inactive resources");
} else if (inactive_resources) {
@@ -1857,7 +1878,10 @@ resource_list(pcmk__output_t *out, va_list args)
}
}
- out->end_list(out);
+ if (printed_header) {
+ out->end_list(out);
+ }
+
return rc;
}
--
1.8.3.1

1312
SOURCES/015-sbd.patch Normal file

File diff suppressed because it is too large Load Diff

59
SOURCES/016-cts.patch Normal file
View File

@ -0,0 +1,59 @@
From b37391fef92548f31822f9df2a9b5fa2a61b4514 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Wed, 23 Jun 2021 15:17:54 -0500
Subject: [PATCH] Fix: CTS: handle longer Corosync token timeouts
Previously, startall() would call cluster_stable() immediately after detecting
the "controller successfully started" message. If the Corosync token timeout is
small enough, this will be fine. However with a token timeout of more than
about 1 second, the controllers will not have formed a membership by this
point, causing cluster_stable() to think there are multiple partitions, and
wait for a DC to be elected in each one, when really they will unite into a
single partition in a short time, and only elect a single DC.
Now, startall() waits until seeing that each node is a cluster member before
calling cluster_stable().
---
cts/lab/CTS.py.in | 3 ++-
cts/lab/patterns.py | 2 ++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/cts/lab/CTS.py.in b/cts/lab/CTS.py.in
index abcb9d285..d9924437b 100644
--- a/cts/lab/CTS.py.in
+++ b/cts/lab/CTS.py.in
@@ -628,9 +628,10 @@ class ClusterManager(UserDict):
watchpats = [ ]
watchpats.append(self.templates["Pat:DC_IDLE"])
for node in nodelist:
- watchpats.append(self.templates["Pat:Local_started"] % node)
watchpats.append(self.templates["Pat:InfraUp"] % node)
watchpats.append(self.templates["Pat:PacemakerUp"] % node)
+ watchpats.append(self.templates["Pat:Local_started"] % node)
+ watchpats.append(self.templates["Pat:They_up"] % (nodelist[0], node))
# Start all the nodes - at about the same time...
watch = LogWatcher(self.Env["LogFileName"], watchpats, "fast-start", self.Env["DeadTime"]+10, hosts=self.Env["nodes"], kind=self.Env["LogWatcher"])
diff --git a/cts/lab/patterns.py b/cts/lab/patterns.py
index e21a016ff..400fd3dc8 100644
--- a/cts/lab/patterns.py
+++ b/cts/lab/patterns.py
@@ -61,6 +61,7 @@ class BasePatterns(object):
"Pat:We_stopped" : "%s\W.*OVERRIDE THIS PATTERN",
"Pat:They_stopped" : "%s\W.*LOST:.* %s ",
"Pat:They_dead" : "node %s.*: is dead",
+ "Pat:They_up" : "%s %s\W.*OVERRIDE THIS PATTERN",
"Pat:TransitionComplete" : "Transition status: Complete: complete",
"Pat:Fencing_start" : r"Requesting peer fencing .* targeting %s",
@@ -130,6 +131,7 @@ class crm_corosync(BasePatterns):
"Pat:We_stopped" : "%s\W.*Unloading all Corosync service engines",
"Pat:They_stopped" : "%s\W.*pacemaker-controld.*Node %s(\[|\s).*state is now lost",
"Pat:They_dead" : "pacemaker-controld.*Node %s(\[|\s).*state is now lost",
+ "Pat:They_up" : "\W%s\W.*pacemaker-controld.*Node %s state is now member",
"Pat:ChildExit" : r"\[[0-9]+\] exited with status [0-9]+ \(",
# "with signal 9" == pcmk_child_exit(), "$" == check_active_before_startup_processes()
--
2.27.0

File diff suppressed because it is too large Load Diff

View File

@ -1,26 +0,0 @@
From a66f63e1001c2c93e286978c0383b4256abfce6b Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 4 Jan 2021 16:46:52 -0500
Subject: [PATCH] Test: cts: Distribute the new constraints.xml file.
---
cts/Makefile.am | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/cts/Makefile.am b/cts/Makefile.am
index 6abb42f..5666a9f 100644
--- a/cts/Makefile.am
+++ b/cts/Makefile.am
@@ -60,7 +60,8 @@ cts_SCRIPTS = CTSlab.py \
pacemaker-cts-dummyd
clidir = $(testdir)/cli
-dist_cli_DATA = cli/crm_diff_new.xml \
+dist_cli_DATA = cli/constraints.xml \
+ cli/crm_diff_new.xml \
cli/crm_diff_old.xml \
cli/crm_mon.xml \
cli/crm_mon-partial.xml \
--
1.8.3.1

View File

@ -0,0 +1,58 @@
From 61eb9c240004d1dbd0b5973e2fecda3686bb4c53 Mon Sep 17 00:00:00 2001
From: Klaus Wenninger <klaus.wenninger@aon.at>
Date: Tue, 10 Aug 2021 09:06:55 +0200
Subject: [PATCH 1/2] Build: rpm: package fence_watchdog in base-package
---
rpm/pacemaker.spec.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rpm/pacemaker.spec.in b/rpm/pacemaker.spec.in
index f58357a77..0c569b9ca 100644
--- a/rpm/pacemaker.spec.in
+++ b/rpm/pacemaker.spec.in
@@ -734,6 +734,7 @@ exit 0
%{_sbindir}/crm_attribute
%{_sbindir}/crm_master
%{_sbindir}/fence_legacy
+%{_sbindir}/fence_watchdog
%doc %{_mandir}/man7/pacemaker-controld.*
%doc %{_mandir}/man7/pacemaker-schedulerd.*
@@ -797,7 +798,6 @@ exit 0
%{_sbindir}/crm_simulate
%{_sbindir}/crm_report
%{_sbindir}/crm_ticket
-%{_sbindir}/fence_watchdog
%{_sbindir}/stonith_admin
# "dirname" is owned by -schemas, which is a prerequisite
%{_datadir}/pacemaker/report.collector
--
2.27.0
From 88e75d5b98df197fa731e7642434951a24a67095 Mon Sep 17 00:00:00 2001
From: Klaus Wenninger <klaus.wenninger@aon.at>
Date: Tue, 10 Aug 2021 09:10:23 +0200
Subject: [PATCH 2/2] Fix: fence_watchdog: fix version output needed for
help2man
---
daemons/fenced/fence_watchdog.in | 1 +
1 file changed, 1 insertion(+)
diff --git a/daemons/fenced/fence_watchdog.in b/daemons/fenced/fence_watchdog.in
index c83304f1d..700065e0e 100755
--- a/daemons/fenced/fence_watchdog.in
+++ b/daemons/fenced/fence_watchdog.in
@@ -12,6 +12,7 @@ import sys
import atexit
import getopt
+AGENT_VERSION = "1.0.0"
SHORT_DESC = "Dummy watchdog fence agent"
LONG_DESC = """fence_watchdog just provides
meta-data - actual fencing is done by the pacemaker internal watchdog agent."""
--
2.27.0

View File

@ -0,0 +1,122 @@
From ee7eba6a7a05bdf0a12d60ebabb334d8ee021101 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Mon, 9 Aug 2021 14:48:57 -0500
Subject: [PATCH] Fix: controller: ensure lost node's transient attributes are
cleared without DC
Previously, peer_update_callback() cleared a lost node's transient attributes
if either the local node is DC, or there is no DC.
However, that left the possibility of the DC being lost at the same time as
another node -- the local node would still have fsa_our_dc set while processing
the leave notifications, so no node would clear the attributes for the non-DC
node.
Now, the controller has its own CPG configuration change callback, which sets a
global boolean before calling the usual one, so that peer_update_callback() can
know when the DC has been lost.
---
daemons/controld/controld_callbacks.c | 4 +-
daemons/controld/controld_corosync.c | 57 ++++++++++++++++++++++++++-
2 files changed, 59 insertions(+), 2 deletions(-)
diff --git a/daemons/controld/controld_callbacks.c b/daemons/controld/controld_callbacks.c
index af24856ae..e564b3dcd 100644
--- a/daemons/controld/controld_callbacks.c
+++ b/daemons/controld/controld_callbacks.c
@@ -99,6 +99,8 @@ node_alive(const crm_node_t *node)
#define state_text(state) ((state)? (const char *)(state) : "in unknown state")
+bool controld_dc_left = false;
+
void
peer_update_callback(enum crm_status_type type, crm_node_t * node, const void *data)
{
@@ -217,7 +219,7 @@ peer_update_callback(enum crm_status_type type, crm_node_t * node, const void *d
cib_scope_local);
}
- } else if (AM_I_DC || (fsa_our_dc == NULL)) {
+ } else if (AM_I_DC || controld_dc_left || (fsa_our_dc == NULL)) {
/* This only needs to be done once, so normally the DC should do
* it. However if there is no DC, every node must do it, since
* there is no other way to ensure some one node does it.
diff --git a/daemons/controld/controld_corosync.c b/daemons/controld/controld_corosync.c
index db99630fb..c5ab6580a 100644
--- a/daemons/controld/controld_corosync.c
+++ b/daemons/controld/controld_corosync.c
@@ -87,6 +87,61 @@ crmd_cs_destroy(gpointer user_data)
}
}
+extern bool controld_dc_left;
+
+/*!
+ * \brief Handle a Corosync notification of a CPG configuration change
+ *
+ * \param[in] handle CPG connection
+ * \param[in] cpg_name CPG group name
+ * \param[in] member_list List of current CPG members
+ * \param[in] member_list_entries Number of entries in \p member_list
+ * \param[in] left_list List of CPG members that left
+ * \param[in] left_list_entries Number of entries in \p left_list
+ * \param[in] joined_list List of CPG members that joined
+ * \param[in] joined_list_entries Number of entries in \p joined_list
+ */
+static void
+cpg_membership_callback(cpg_handle_t handle, const struct cpg_name *cpg_name,
+ const struct cpg_address *member_list,
+ size_t member_list_entries,
+ const struct cpg_address *left_list,
+ size_t left_list_entries,
+ const struct cpg_address *joined_list,
+ size_t joined_list_entries)
+{
+ /* When nodes leave CPG, the DC clears their transient node attributes.
+ *
+ * However if there is no DC, or the DC is among the nodes that left, each
+ * remaining node needs to do the clearing, to ensure it gets done.
+ * Otherwise, the attributes would persist when the nodes rejoin, which
+ * could have serious consequences for unfencing, agents that use attributes
+ * for internal logic, etc.
+ *
+ * Here, we set a global boolean if the DC is among the nodes that left, for
+ * use by the peer callback.
+ */
+ if (fsa_our_dc != NULL) {
+ crm_node_t *peer = pcmk__search_cluster_node_cache(0, fsa_our_dc);
+
+ if (peer != NULL) {
+ for (int i = 0; i < left_list_entries; ++i) {
+ if (left_list[i].nodeid == peer->id) {
+ controld_dc_left = true;
+ break;
+ }
+ }
+ }
+ }
+
+ // Process the change normally, which will call the peer callback as needed
+ pcmk_cpg_membership(handle, cpg_name, member_list, member_list_entries,
+ left_list, left_list_entries,
+ joined_list, joined_list_entries);
+
+ controld_dc_left = false;
+}
+
extern gboolean crm_connect_corosync(crm_cluster_t * cluster);
gboolean
@@ -95,7 +150,7 @@ crm_connect_corosync(crm_cluster_t * cluster)
if (is_corosync_cluster()) {
crm_set_status_callback(&peer_update_callback);
cluster->cpg.cpg_deliver_fn = crmd_cs_dispatch;
- cluster->cpg.cpg_confchg_fn = pcmk_cpg_membership;
+ cluster->cpg.cpg_confchg_fn = cpg_membership_callback;
cluster->destroy = crmd_cs_destroy;
if (crm_cluster_connect(cluster)) {
--
2.27.0

View File

@ -1,47 +0,0 @@
From c3e2edb78e6d0b6ffc8acbe8fc7caef058b35d76 Mon Sep 17 00:00:00 2001
From: Reid Wahl <nrwahl@protonmail.com>
Date: Tue, 22 Dec 2020 22:28:46 -0800
Subject: [PATCH] Fix: liblrmd: Limit node name addition to proxied attrd
update commands
remote_proxy_cb() currently adds the remote node's name as
PCMK__XA_ATTR_NODE_NAME if that attribute is not explicitly set. This is
necessary for attrd update commands. For those, lack of an explicit node
name means to use the local node. Since requests are proxied to full
nodes, the node hosting the remote resource would be incorrectly treated
as the "local node", causing the attribute to be updated for the wrong
node.
However, for other commands, this is not the case. Lack of an explicit
node name can mean "all nodes" (as for CLEAR_FAILURE and QUERY), or a
node name may be ignored (as for REFRESH). In these cases (the
non-update commands), we don't want to add a node name automatically if
it's not explicitly set.
Resolves: RHBZ#1907726
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
---
lib/lrmd/proxy_common.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/lib/lrmd/proxy_common.c b/lib/lrmd/proxy_common.c
index b8d889e..0f1e76a 100644
--- a/lib/lrmd/proxy_common.c
+++ b/lib/lrmd/proxy_common.c
@@ -259,7 +259,11 @@ remote_proxy_cb(lrmd_t *lrmd, const char *node_name, xmlNode *msg)
if (pcmk__str_eq(type, T_ATTRD, pcmk__str_casei)
&& crm_element_value(request,
- PCMK__XA_ATTR_NODE_NAME) == NULL) {
+ PCMK__XA_ATTR_NODE_NAME) == NULL
+ && pcmk__str_any_of(crm_element_value(request, PCMK__XA_TASK),
+ PCMK__ATTRD_CMD_UPDATE,
+ PCMK__ATTRD_CMD_UPDATE_BOTH,
+ PCMK__ATTRD_CMD_UPDATE_DELAY, NULL)) {
crm_xml_add(request, PCMK__XA_ATTR_NODE_NAME, proxy->node_name);
}
--
1.8.3.1

View File

@ -0,0 +1,114 @@
From b4e426a016a4d7c9ade39e60a83644fc537bce26 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Wed, 11 Aug 2021 12:10:32 +0200
Subject: [PATCH 1/2] Fix: crm_resource: translate LSB rc to exit code and fix
resources_find_service_class() call
---
tools/crm_resource_runtime.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c
index ce037c514..e9d8aa687 100644
--- a/tools/crm_resource_runtime.c
+++ b/tools/crm_resource_runtime.c
@@ -1718,10 +1718,10 @@ cli_resource_execute_from_params(pcmk__output_t *out, const char *rsc_name,
crm_exit(CRM_EX_UNIMPLEMENT_FEATURE);
} else if (pcmk__str_eq(rsc_class, PCMK_RESOURCE_CLASS_SERVICE,
pcmk__str_casei) && !pcmk__str_eq(
- resources_find_service_class(rsc_name), PCMK_RESOURCE_CLASS_LSB,
+ resources_find_service_class(rsc_type), PCMK_RESOURCE_CLASS_LSB,
pcmk__str_casei)) {
out->err(out, "Sorry, the %s option doesn't support %s resources",
- rsc_action, resources_find_service_class(rsc_name));
+ rsc_action, resources_find_service_class(rsc_type));
crm_exit(CRM_EX_UNIMPLEMENT_FEATURE);
}
@@ -1798,9 +1798,17 @@ cli_resource_execute_from_params(pcmk__output_t *out, const char *rsc_name,
if (services_action_sync(op)) {
exit_code = op->rc;
+ /* Lookup exit code based on rc for LSB resources */
+ if (( pcmk__str_eq(rsc_class, PCMK_RESOURCE_CLASS_LSB, pcmk__str_casei) ||
+ (pcmk__str_eq(rsc_class, PCMK_RESOURCE_CLASS_SERVICE, pcmk__str_casei) &&
+ pcmk__str_eq(resources_find_service_class(rsc_type), PCMK_RESOURCE_CLASS_LSB, pcmk__str_casei)) ) &&
+ pcmk__str_eq(rsc_action, "force-check", pcmk__str_casei)) {
+ exit_code = services_get_ocf_exitcode(action, exit_code);
+ }
+
out->message(out, "resource-agent-action", resource_verbose, rsc_class,
- rsc_prov, rsc_type, rsc_name, rsc_action, override_hash, op->rc,
- op->status, op->stdout_data, op->stderr_data);
+ rsc_prov, rsc_type, rsc_name, rsc_action, override_hash,
+ exit_code, op->status, op->stdout_data, op->stderr_data);
} else {
exit_code = op->rc == 0 ? CRM_EX_ERROR : op->rc;
}
--
2.27.0
From 9a6beb74adfb4710fb3a4e588bef79a562c101f3 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Thu, 12 Aug 2021 18:54:30 +0200
Subject: [PATCH 2/2] Refactor: crm_resource: simplify rsc_class logic by
getting actual class early if it's of class "service"
---
tools/crm_resource_runtime.c | 23 +++++++++--------------
1 file changed, 9 insertions(+), 14 deletions(-)
diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c
index e9d8aa687..13b78b6b9 100644
--- a/tools/crm_resource_runtime.c
+++ b/tools/crm_resource_runtime.c
@@ -1702,26 +1702,23 @@ cli_resource_execute_from_params(pcmk__output_t *out, const char *rsc_name,
int timeout_ms, int resource_verbose, gboolean force,
int check_level)
{
+ const char *class = NULL;
const char *action = NULL;
GHashTable *params_copy = NULL;
crm_exit_t exit_code = CRM_EX_OK;
svc_action_t *op = NULL;
- if (pcmk__str_eq(rsc_class, PCMK_RESOURCE_CLASS_STONITH, pcmk__str_casei)) {
+ class = !pcmk__str_eq(rsc_class, PCMK_RESOURCE_CLASS_SERVICE, pcmk__str_casei) ?
+ rsc_class : resources_find_service_class(rsc_type);
+
+ if (pcmk__str_eq(class, PCMK_RESOURCE_CLASS_STONITH, pcmk__str_casei)) {
out->err(out, "Sorry, the %s option doesn't support %s resources yet",
- rsc_action, rsc_class);
+ rsc_action, class);
crm_exit(CRM_EX_UNIMPLEMENT_FEATURE);
- } else if (pcmk__strcase_any_of(rsc_class, PCMK_RESOURCE_CLASS_SYSTEMD,
+ } else if (pcmk__strcase_any_of(class, PCMK_RESOURCE_CLASS_SYSTEMD,
PCMK_RESOURCE_CLASS_UPSTART, PCMK_RESOURCE_CLASS_NAGIOS, NULL)) {
out->err(out, "Sorry, the %s option doesn't support %s resources",
- rsc_action, rsc_class);
- crm_exit(CRM_EX_UNIMPLEMENT_FEATURE);
- } else if (pcmk__str_eq(rsc_class, PCMK_RESOURCE_CLASS_SERVICE,
- pcmk__str_casei) && !pcmk__str_eq(
- resources_find_service_class(rsc_type), PCMK_RESOURCE_CLASS_LSB,
- pcmk__str_casei)) {
- out->err(out, "Sorry, the %s option doesn't support %s resources",
- rsc_action, resources_find_service_class(rsc_type));
+ rsc_action, class);
crm_exit(CRM_EX_UNIMPLEMENT_FEATURE);
}
@@ -1799,9 +1796,7 @@ cli_resource_execute_from_params(pcmk__output_t *out, const char *rsc_name,
exit_code = op->rc;
/* Lookup exit code based on rc for LSB resources */
- if (( pcmk__str_eq(rsc_class, PCMK_RESOURCE_CLASS_LSB, pcmk__str_casei) ||
- (pcmk__str_eq(rsc_class, PCMK_RESOURCE_CLASS_SERVICE, pcmk__str_casei) &&
- pcmk__str_eq(resources_find_service_class(rsc_type), PCMK_RESOURCE_CLASS_LSB, pcmk__str_casei)) ) &&
+ if (pcmk__str_eq(class, PCMK_RESOURCE_CLASS_LSB, pcmk__str_casei) &&
pcmk__str_eq(rsc_action, "force-check", pcmk__str_casei)) {
exit_code = services_get_ocf_exitcode(action, exit_code);
}
--
2.27.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
From 46dd1118cae948649e000b2159e8e92623520ad9 Mon Sep 17 00:00:00 2001
From: Klaus Wenninger <klaus.wenninger@aon.at>
Date: Thu, 19 Aug 2021 09:28:54 +0200
Subject: [PATCH] Fix: fence_watchdog: fix malformed xml in metadata
---
daemons/fenced/fence_watchdog.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/daemons/fenced/fence_watchdog.in b/daemons/fenced/fence_watchdog.in
index 700065e0e..eefa7395e 100755
--- a/daemons/fenced/fence_watchdog.in
+++ b/daemons/fenced/fence_watchdog.in
@@ -124,7 +124,7 @@ def metadata(avail_opt, options):
for option, dummy in sorted_options(avail_opt):
if "shortdesc" in ALL_OPT[option]:
print(' <parameter name="' + option +
- 'required="' + ALL_OPT[option]["required"] + '">')
+ '" required="' + ALL_OPT[option]["required"] + '">')
default = ""
default_name_arg = "-" + ALL_OPT[option]["getopt"][:-1]
--
2.27.0

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,26 +0,0 @@
From b1241e5026a4fd9a8674ad4b867c7efa3d8ef466 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Tue, 12 Jan 2021 09:03:03 -0600
Subject: [PATCH] Feature: tools: bump feature set for crm_resource --digests
... so script and tools can check for support
---
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 b07152c..4bbf46a 100644
--- a/include/crm/crm.h
+++ b/include/crm/crm.h
@@ -51,7 +51,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.6.3"
+# define CRM_FEATURE_SET "3.6.4"
# define EOS '\0'
# define DIMOF(a) ((int) (sizeof(a)/sizeof(a[0])) )
--
1.8.3.1

File diff suppressed because it is too large Load Diff

View File

@ -1,505 +0,0 @@
From cf0eebd913855f9ceda2864cbcd9cbd647fca055 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Wed, 13 Jan 2021 12:10:07 -0600
Subject: [PATCH] Build: xml: rename crm_resource API file
5aadeaf added an API schema 2.5 for crm_resource, but API schema 2.5 was
released with 2.0.5, so rename it to 2.6 to indicate it is a later change.
---
xml/api/crm_resource-2.5.rng | 238 -------------------------------------------
xml/api/crm_resource-2.6.rng | 238 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 238 insertions(+), 238 deletions(-)
delete mode 100644 xml/api/crm_resource-2.5.rng
create mode 100644 xml/api/crm_resource-2.6.rng
diff --git a/xml/api/crm_resource-2.5.rng b/xml/api/crm_resource-2.5.rng
deleted file mode 100644
index b49e24c..0000000
--- a/xml/api/crm_resource-2.5.rng
+++ /dev/null
@@ -1,238 +0,0 @@
-<?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="nonNegativeInteger" /> </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>
diff --git a/xml/api/crm_resource-2.6.rng b/xml/api/crm_resource-2.6.rng
new file mode 100644
index 0000000..b49e24c
--- /dev/null
+++ b/xml/api/crm_resource-2.6.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="nonNegativeInteger" /> </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

View File

@ -1,26 +0,0 @@
From 610e54caf9a695d3d108c87c735a630f2ea5657f Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Wed, 2 Dec 2020 15:09:35 -0600
Subject: [PATCH] Test: cts-fencing: update expected output
b16b24ed changed the order of some XML attributes
---
cts/cts-fencing.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cts/cts-fencing.in b/cts/cts-fencing.in
index c901c6c..224b5d4 100644
--- a/cts/cts-fencing.in
+++ b/cts/cts-fencing.in
@@ -1102,7 +1102,7 @@ class Tests(object):
test.add_cmd("stonith_admin", "--output-as=xml -F node3 -t 5 -V")
- test.add_cmd_check_stdout("stonith_admin", "--output-as=xml -H node3", 'status="success" .* action="off" target="node3"')
+ test.add_cmd_check_stdout("stonith_admin", "--output-as=xml -H node3", 'action="off" target="node3" .* status="success"')
# simple test of dynamic list query
for test_type in test_types:
--
1.8.3.1

View File

@ -1,962 +0,0 @@
From a32b6e14ba51fefbda2d4a699cf1c48dd3a1bb5a Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Thu, 7 Jan 2021 11:37:51 -0500
Subject: [PATCH 01/10] Fix: tools: Don't pass stonith history to
print_simple_status.
It's not being used.
---
tools/crm_mon.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index 4555516..729f6a1 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2020 the Pacemaker project contributors
+ * Copyright 2004-2021 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -1451,14 +1451,13 @@ main(int argc, char **argv)
* \brief Print one-line status suitable for use with monitoring software
*
* \param[in] data_set Working set of CIB state
- * \param[in] history List of stonith actions
*
* \note This function's output (and the return code when the program exits)
* should conform to https://www.monitoring-plugins.org/doc/guidelines.html
*/
static void
print_simple_status(pcmk__output_t *out, pe_working_set_t * data_set,
- stonith_history_t *history, unsigned int mon_ops)
+ unsigned int mon_ops)
{
GListPtr gIter = NULL;
int nodes_online = 0;
@@ -2012,7 +2011,7 @@ mon_refresh_display(gpointer user_data)
break;
case mon_output_monitor:
- print_simple_status(out, mon_data_set, stonith_history, options.mon_ops);
+ print_simple_status(out, mon_data_set, options.mon_ops);
if (pcmk_is_set(options.mon_ops, mon_op_has_warnings)) {
clean_up(MON_STATUS_WARN);
return FALSE;
--
1.8.3.1
From 8b9c47089c70295bc0529671ba5991c6d831e14b Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Thu, 7 Jan 2021 13:17:04 -0500
Subject: [PATCH 02/10] Refactor: tools: Don't pass output_format to
mon_refresh_display.
output_format is a global variable.
---
tools/crm_mon.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index 729f6a1..b801560 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -827,7 +827,7 @@ cib_connect(gboolean full)
rc = cib->cmds->query(cib, NULL, &current_cib, cib_scope_local | cib_sync_call);
if (rc == pcmk_ok) {
- mon_refresh_display(&output_format);
+ mon_refresh_display(NULL);
}
if (rc == pcmk_ok && full) {
--
1.8.3.1
From a1b14ad96f12746167da8588dc086b20e6f6d1d6 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Thu, 7 Jan 2021 13:20:14 -0500
Subject: [PATCH 03/10] Refactor: tools: Remove unnecessary checks for cib !=
NULL.
cib is guaranteed to not be NULL at these points, so there's no need to
do an additional check. This code was leftover from a previous
reorganization that changed when the cib variable gets initialized.
---
tools/crm_mon.c | 41 +++++++++++++++++++----------------------
1 file changed, 19 insertions(+), 22 deletions(-)
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index b801560..1eedd38 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -1346,7 +1346,7 @@ main(int argc, char **argv)
/* Extra sanity checks when in CGI mode */
if (output_format == mon_output_cgi) {
- if (cib && cib->variant == cib_file) {
+ if (cib->variant == cib_file) {
g_set_error(&error, PCMK__EXITC_ERROR, CRM_EX_USAGE, "CGI mode used with CIB file");
return clean_up(CRM_EX_USAGE);
} else if (options.external_agent != NULL) {
@@ -1370,33 +1370,30 @@ main(int argc, char **argv)
crm_info("Starting %s", crm_system_name);
- if (cib) {
-
- do {
- if (!pcmk_is_set(options.mon_ops, mon_op_one_shot)) {
- print_as(output_format ,"Waiting until cluster is available on this node ...\n");
- }
- rc = cib_connect(!pcmk_is_set(options.mon_ops, mon_op_one_shot));
+ do {
+ if (!pcmk_is_set(options.mon_ops, mon_op_one_shot)) {
+ print_as(output_format ,"Waiting until cluster is available on this node ...\n");
+ }
+ rc = cib_connect(!pcmk_is_set(options.mon_ops, mon_op_one_shot));
- if (pcmk_is_set(options.mon_ops, mon_op_one_shot)) {
- break;
+ if (pcmk_is_set(options.mon_ops, mon_op_one_shot)) {
+ break;
- } else if (rc != pcmk_ok) {
- sleep(options.reconnect_msec / 1000);
+ } else if (rc != pcmk_ok) {
+ sleep(options.reconnect_msec / 1000);
#if CURSES_ENABLED
- if (output_format == mon_output_console) {
- clear();
- refresh();
- }
+ if (output_format == mon_output_console) {
+ clear();
+ refresh();
+ }
#endif
- } else {
- if (output_format == mon_output_html && out->dest != stdout) {
- printf("Writing html to %s ...\n", args->output_dest);
- }
+ } else {
+ if (output_format == mon_output_html && out->dest != stdout) {
+ printf("Writing html to %s ...\n", args->output_dest);
}
+ }
- } while (rc == -ENOTCONN);
- }
+ } while (rc == -ENOTCONN);
if (rc != pcmk_ok) {
if (output_format == mon_output_monitor) {
--
1.8.3.1
From fe5284a12765e775905bdfe58711c5733a063132 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Thu, 7 Jan 2021 14:15:40 -0500
Subject: [PATCH 04/10] Fix: tools: mon_refresh_display should return an int.
While GSourceFunc is defined as returning a boolean, our public API
mainloop function expect the dispatch function to return an int. So
change mon_refresh_display to do so.
---
tools/crm_mon.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index 1eedd38..8657a89 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -125,7 +125,7 @@ struct {
static void clean_up_connections(void);
static crm_exit_t clean_up(crm_exit_t exit_code);
static void crm_diff_update(const char *event, xmlNode * msg);
-static gboolean mon_refresh_display(gpointer user_data);
+static int mon_refresh_display(gpointer user_data);
static int cib_connect(gboolean full);
static void mon_st_callback_event(stonith_t * st, stonith_event_t * e);
static void mon_st_callback_display(stonith_t * st, stonith_event_t * e);
@@ -1925,7 +1925,7 @@ crm_diff_update(const char *event, xmlNode * msg)
kick_refresh(cib_updated);
}
-static gboolean
+static int
mon_refresh_display(gpointer user_data)
{
xmlNode *cib_copy = copy_xml(current_cib);
@@ -1940,7 +1940,7 @@ mon_refresh_display(gpointer user_data)
}
out->err(out, "Upgrade failed: %s", pcmk_strerror(-pcmk_err_schema_validation));
clean_up(CRM_EX_CONFIG);
- return FALSE;
+ return 0;
}
/* get the stonith-history if there is evidence we need it
@@ -1966,7 +1966,7 @@ mon_refresh_display(gpointer user_data)
}
free_xml(cib_copy);
out->err(out, "Reading stonith-history failed");
- return FALSE;
+ return 0;
}
if (mon_data_set == NULL) {
@@ -1995,7 +1995,7 @@ mon_refresh_display(gpointer user_data)
options.only_node, options.only_rsc) != 0) {
g_set_error(&error, PCMK__EXITC_ERROR, CRM_EX_CANTCREAT, "Critical: Unable to output html file");
clean_up(CRM_EX_CANTCREAT);
- return FALSE;
+ return 0;
}
break;
@@ -2044,7 +2044,7 @@ mon_refresh_display(gpointer user_data)
stonith_history_free(stonith_history);
stonith_history = NULL;
pe_reset_working_set(mon_data_set);
- return TRUE;
+ return 1;
}
static void
--
1.8.3.1
From 7f88a5a428ed73fb5161096ece2517abe1119f06 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Thu, 7 Jan 2021 16:59:02 -0500
Subject: [PATCH 05/10] Refactor: tools: Change a conditional in cib_connect.
This allows unindenting everything that occurs inside that conditional,
which I think makes it a little bit easier to understand what is going
on.
---
tools/crm_mon.c | 86 +++++++++++++++++++++++++++++----------------------------
1 file changed, 44 insertions(+), 42 deletions(-)
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index 8657a89..b8ba56b 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -804,55 +804,57 @@ cib_connect(gboolean full)
}
}
- if (cib->state != cib_connected_query && cib->state != cib_connected_command) {
- crm_trace("Connecting to the CIB");
-
- /* Hack: the CIB signon will print the prompt for a password if needed,
- * but to stderr. If we're in curses, show it on the screen instead.
- *
- * @TODO Add a password prompt (maybe including input) function to
- * pcmk__output_t and use it in libcib.
- */
- if ((output_format == mon_output_console) && need_pass && (cib->variant == cib_remote)) {
- need_pass = FALSE;
- print_as(output_format, "Password:");
- }
+ if (cib->state == cib_connected_query || cib->state == cib_connected_command) {
+ return rc;
+ }
- rc = cib->cmds->signon(cib, crm_system_name, cib_query);
- if (rc != pcmk_ok) {
- out->err(out, "Could not connect to the CIB: %s",
- pcmk_strerror(rc));
- return rc;
- }
+ crm_trace("Connecting to the CIB");
- rc = cib->cmds->query(cib, NULL, &current_cib, cib_scope_local | cib_sync_call);
- if (rc == pcmk_ok) {
- mon_refresh_display(NULL);
- }
+ /* Hack: the CIB signon will print the prompt for a password if needed,
+ * but to stderr. If we're in curses, show it on the screen instead.
+ *
+ * @TODO Add a password prompt (maybe including input) function to
+ * pcmk__output_t and use it in libcib.
+ */
+ if ((output_format == mon_output_console) && need_pass && (cib->variant == cib_remote)) {
+ need_pass = FALSE;
+ print_as(output_format, "Password:");
+ }
- if (rc == pcmk_ok && full) {
- if (rc == pcmk_ok) {
- rc = cib->cmds->set_connection_dnotify(cib, mon_cib_connection_destroy_regular);
- if (rc == -EPROTONOSUPPORT) {
- print_as
- (output_format, "Notification setup not supported, won't be able to reconnect after failure");
- if (output_format == mon_output_console) {
- sleep(2);
- }
- rc = pcmk_ok;
- }
+ rc = cib->cmds->signon(cib, crm_system_name, cib_query);
+ if (rc != pcmk_ok) {
+ out->err(out, "Could not connect to the CIB: %s",
+ pcmk_strerror(rc));
+ return rc;
+ }
- }
+ rc = cib->cmds->query(cib, NULL, &current_cib, cib_scope_local | cib_sync_call);
+ if (rc == pcmk_ok) {
+ mon_refresh_display(NULL);
+ }
- if (rc == pcmk_ok) {
- cib->cmds->del_notify_callback(cib, T_CIB_DIFF_NOTIFY, crm_diff_update);
- rc = cib->cmds->add_notify_callback(cib, T_CIB_DIFF_NOTIFY, crm_diff_update);
+ if (rc == pcmk_ok && full) {
+ if (rc == pcmk_ok) {
+ rc = cib->cmds->set_connection_dnotify(cib, mon_cib_connection_destroy_regular);
+ if (rc == -EPROTONOSUPPORT) {
+ print_as
+ (output_format, "Notification setup not supported, won't be able to reconnect after failure");
+ if (output_format == mon_output_console) {
+ sleep(2);
+ }
+ rc = pcmk_ok;
}
- if (rc != pcmk_ok) {
- out->err(out, "Notification setup failed, could not monitor CIB actions");
- clean_up_connections();
- }
+ }
+
+ if (rc == pcmk_ok) {
+ cib->cmds->del_notify_callback(cib, T_CIB_DIFF_NOTIFY, crm_diff_update);
+ rc = cib->cmds->add_notify_callback(cib, T_CIB_DIFF_NOTIFY, crm_diff_update);
+ }
+
+ if (rc != pcmk_ok) {
+ out->err(out, "Notification setup failed, could not monitor CIB actions");
+ clean_up_connections();
}
}
return rc;
--
1.8.3.1
From 178ba17e4ee62bef28f8e71cad2c002f823661b5 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Thu, 7 Jan 2021 17:37:36 -0500
Subject: [PATCH 06/10] Refactor: tools: Remove an unnecessary conditional in
cib_connect.
---
tools/crm_mon.c | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index b8ba56b..36249e8 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -834,17 +834,14 @@ cib_connect(gboolean full)
}
if (rc == pcmk_ok && full) {
- if (rc == pcmk_ok) {
- rc = cib->cmds->set_connection_dnotify(cib, mon_cib_connection_destroy_regular);
- if (rc == -EPROTONOSUPPORT) {
- print_as
- (output_format, "Notification setup not supported, won't be able to reconnect after failure");
- if (output_format == mon_output_console) {
- sleep(2);
- }
- rc = pcmk_ok;
+ rc = cib->cmds->set_connection_dnotify(cib, mon_cib_connection_destroy_regular);
+ if (rc == -EPROTONOSUPPORT) {
+ print_as
+ (output_format, "Notification setup not supported, won't be able to reconnect after failure");
+ if (output_format == mon_output_console) {
+ sleep(2);
}
-
+ rc = pcmk_ok;
}
if (rc == pcmk_ok) {
--
1.8.3.1
From 33bac5886417afc5c7bbf56f4d31e0e36f8ae947 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Fri, 8 Jan 2021 10:00:50 -0500
Subject: [PATCH 07/10] Refactor: tools: Simplify another conditional in
crm_mon.
---
tools/crm_mon.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index 36249e8..8b47bbc 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -1386,10 +1386,8 @@ main(int argc, char **argv)
refresh();
}
#endif
- } else {
- if (output_format == mon_output_html && out->dest != stdout) {
- printf("Writing html to %s ...\n", args->output_dest);
- }
+ } else if (output_format == mon_output_html && out->dest != stdout) {
+ printf("Writing html to %s ...\n", args->output_dest);
}
} while (rc == -ENOTCONN);
--
1.8.3.1
From 40bc8b3147e7ebef4318211fa69973a8b5d32e79 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Fri, 8 Jan 2021 12:12:37 -0500
Subject: [PATCH 08/10] Refactor: libcrmcommon,tools,daemons: Put common xpath
code in one place.
---
configure.ac | 1 +
daemons/controld/controld_te_callbacks.c | 26 +++-----------
include/crm/common/xml_internal.h | 14 +++++++-
lib/common/tests/Makefile.am | 2 +-
lib/common/tests/xpath/Makefile.am | 29 +++++++++++++++
lib/common/tests/xpath/pcmk__xpath_node_id_test.c | 43 +++++++++++++++++++++++
lib/common/xpath.c | 34 +++++++++++++++++-
tools/crm_mon.c | 25 ++-----------
8 files changed, 127 insertions(+), 47 deletions(-)
create mode 100644 lib/common/tests/xpath/Makefile.am
create mode 100644 lib/common/tests/xpath/pcmk__xpath_node_id_test.c
diff --git a/configure.ac b/configure.ac
index 5959116..ce0f1fe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1920,6 +1920,7 @@ AC_CONFIG_FILES(Makefile \
lib/common/tests/operations/Makefile \
lib/common/tests/strings/Makefile \
lib/common/tests/utils/Makefile \
+ lib/common/tests/xpath/Makefile \
lib/cluster/Makefile \
lib/cib/Makefile \
lib/gnu/Makefile \
diff --git a/daemons/controld/controld_te_callbacks.c b/daemons/controld/controld_te_callbacks.c
index 66fc645..4e3e4e6 100644
--- a/daemons/controld/controld_te_callbacks.c
+++ b/daemons/controld/controld_te_callbacks.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2020 the Pacemaker project contributors
+ * Copyright 2004-2021 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -276,24 +276,6 @@ process_resource_updates(const char *node, xmlNode *xml, xmlNode *change,
}
}
-#define NODE_PATT "/lrm[@id="
-static char *get_node_from_xpath(const char *xpath)
-{
- char *nodeid = NULL;
- char *tmp = strstr(xpath, NODE_PATT);
-
- if(tmp) {
- tmp += strlen(NODE_PATT);
- tmp += 1;
-
- nodeid = strdup(tmp);
- tmp = strstr(nodeid, "\'");
- CRM_ASSERT(tmp);
- tmp[0] = 0;
- }
- return nodeid;
-}
-
static char *extract_node_uuid(const char *xpath)
{
char *mutable_path = strdup(xpath);
@@ -522,19 +504,19 @@ te_update_diff_v2(xmlNode *diff)
process_resource_updates(ID(match), match, change, op, xpath);
} else if (strcmp(name, XML_LRM_TAG_RESOURCES) == 0) {
- char *local_node = get_node_from_xpath(xpath);
+ char *local_node = pcmk__xpath_node_id(xpath, "lrm");
process_resource_updates(local_node, match, change, op, xpath);
free(local_node);
} else if (strcmp(name, XML_LRM_TAG_RESOURCE) == 0) {
- char *local_node = get_node_from_xpath(xpath);
+ char *local_node = pcmk__xpath_node_id(xpath, "lrm");
process_lrm_resource_diff(match, local_node);
free(local_node);
} else if (strcmp(name, XML_LRM_TAG_RSC_OP) == 0) {
- char *local_node = get_node_from_xpath(xpath);
+ char *local_node = pcmk__xpath_node_id(xpath, "lrm");
process_graph_event(match, local_node);
free(local_node);
diff --git a/include/crm/common/xml_internal.h b/include/crm/common/xml_internal.h
index 1e80bc6..d8694ee 100644
--- a/include/crm/common/xml_internal.h
+++ b/include/crm/common/xml_internal.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the Pacemaker project contributors
+ * Copyright 2017-2021 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -273,4 +273,16 @@ pcmk__xe_first_attr(const xmlNode *xe)
return (xe == NULL)? NULL : xe->properties;
}
+/*!
+ * \internal
+ * \brief Extract the ID attribute from an XML element
+ *
+ * \param[in] xpath String to search
+ * \param[in] node Node to get the ID for
+ *
+ * \return ID attribute of \p node in xpath string \p xpath
+ */
+char *
+pcmk__xpath_node_id(const char *xpath, const char *node);
+
#endif // PCMK__XML_INTERNAL__H
diff --git a/lib/common/tests/Makefile.am b/lib/common/tests/Makefile.am
index 2c33cc5..4c6e8b4 100644
--- a/lib/common/tests/Makefile.am
+++ b/lib/common/tests/Makefile.am
@@ -1 +1 @@
-SUBDIRS = agents cmdline flags operations strings utils
+SUBDIRS = agents cmdline flags operations strings utils xpath
diff --git a/lib/common/tests/xpath/Makefile.am b/lib/common/tests/xpath/Makefile.am
new file mode 100644
index 0000000..7a53683
--- /dev/null
+++ b/lib/common/tests/xpath/Makefile.am
@@ -0,0 +1,29 @@
+#
+# Copyright 2021 the Pacemaker project contributors
+#
+# The version control history for this file may have further details.
+#
+# This source code is licensed under the GNU General Public License version 2
+# or later (GPLv2+) WITHOUT ANY WARRANTY.
+#
+AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include
+LDADD = $(top_builddir)/lib/common/libcrmcommon.la
+
+include $(top_srcdir)/mk/glib-tap.mk
+
+# Add each test program here. Each test should be written as a little standalone
+# program using the glib unit testing functions. See the documentation for more
+# information.
+#
+# https://developer.gnome.org/glib/unstable/glib-Testing.html
+#
+# Add "_test" to the end of all test program names to simplify .gitignore.
+test_programs = pcmk__xpath_node_id_test
+
+# If any extra data needs to be added to the source distribution, add it to the
+# following list.
+dist_test_data =
+
+# If any extra data needs to be used by tests but should not be added to the
+# source distribution, add it to the following list.
+test_data =
diff --git a/lib/common/tests/xpath/pcmk__xpath_node_id_test.c b/lib/common/tests/xpath/pcmk__xpath_node_id_test.c
new file mode 100644
index 0000000..f6b5c10
--- /dev/null
+++ b/lib/common/tests/xpath/pcmk__xpath_node_id_test.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
+ *
+ * This source code is licensed under the GNU Lesser General Public License
+ * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
+ */
+
+#include <crm_internal.h>
+#include <crm/common/xml_internal.h>
+
+static void
+empty_input(void) {
+ g_assert_null(pcmk__xpath_node_id(NULL, "lrm"));
+ g_assert_null(pcmk__xpath_node_id("", "lrm"));
+ g_assert_null(pcmk__xpath_node_id("/blah/blah", NULL));
+ g_assert_null(pcmk__xpath_node_id("/blah/blah", ""));
+ g_assert_null(pcmk__xpath_node_id(NULL, NULL));
+}
+
+static void
+not_present(void) {
+ g_assert_null(pcmk__xpath_node_id("/some/xpath/string[@id='xyz']", "lrm"));
+ g_assert_null(pcmk__xpath_node_id("/some/xpath/containing[@id='lrm']", "lrm"));
+}
+
+static void
+present(void) {
+ g_assert_cmpint(strcmp(pcmk__xpath_node_id("/some/xpath/containing/lrm[@id='xyz']", "lrm"), "xyz"), ==, 0);
+ g_assert_cmpint(strcmp(pcmk__xpath_node_id("/some/other/lrm[@id='xyz']/xpath", "lrm"), "xyz"), ==, 0);
+}
+
+int
+main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+
+ g_test_add_func("/common/xpath/node_id/empty_input", empty_input);
+ g_test_add_func("/common/xpath/node_id/not_present", not_present);
+ g_test_add_func("/common/xpath/node_id/present", present);
+ return g_test_run();
+}
diff --git a/lib/common/xpath.c b/lib/common/xpath.c
index 6fa4941..7851a7c 100644
--- a/lib/common/xpath.c
+++ b/lib/common/xpath.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2020 the Pacemaker project contributors
+ * Copyright 2004-2021 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -11,6 +11,7 @@
#include <stdio.h>
#include <string.h>
#include <crm/msg_xml.h>
+#include <crm/common/xml_internal.h>
#include "crmcommon_private.h"
/*
@@ -297,3 +298,34 @@ xml_get_path(xmlNode *xml)
}
return NULL;
}
+
+char *
+pcmk__xpath_node_id(const char *xpath, const char *node)
+{
+ char *retval = NULL;
+ char *patt = NULL;
+ char *start = NULL;
+ char *end = NULL;
+
+ if (node == NULL || xpath == NULL) {
+ return retval;
+ }
+
+ patt = crm_strdup_printf("/%s[@id=", node);
+ start = strstr(xpath, patt);
+
+ if (!start) {
+ free(patt);
+ return retval;
+ }
+
+ start += strlen(patt);
+ start++;
+
+ end = strstr(start, "\'");
+ CRM_ASSERT(end);
+ retval = strndup(start, end-start);
+
+ free(patt);
+ return retval;
+}
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index 8b47bbc..ff1b86b 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -1719,25 +1719,6 @@ mon_trigger_refresh(gpointer user_data)
return FALSE;
}
-#define NODE_PATT "/lrm[@id="
-static char *
-get_node_from_xpath(const char *xpath)
-{
- char *nodeid = NULL;
- char *tmp = strstr(xpath, NODE_PATT);
-
- if(tmp) {
- tmp += strlen(NODE_PATT);
- tmp += 1;
-
- nodeid = strdup(tmp);
- tmp = strstr(nodeid, "\'");
- CRM_ASSERT(tmp);
- tmp[0] = 0;
- }
- return nodeid;
-}
-
static void
crm_diff_update_v2(const char *event, xmlNode * msg)
{
@@ -1822,19 +1803,19 @@ crm_diff_update_v2(const char *event, xmlNode * msg)
handle_rsc_op(match, node);
} else if(strcmp(name, XML_LRM_TAG_RESOURCES) == 0) {
- char *local_node = get_node_from_xpath(xpath);
+ char *local_node = pcmk__xpath_node_id(xpath, "lrm");
handle_rsc_op(match, local_node);
free(local_node);
} else if(strcmp(name, XML_LRM_TAG_RESOURCE) == 0) {
- char *local_node = get_node_from_xpath(xpath);
+ char *local_node = pcmk__xpath_node_id(xpath, "lrm");
handle_rsc_op(match, local_node);
free(local_node);
} else if(strcmp(name, XML_LRM_TAG_RSC_OP) == 0) {
- char *local_node = get_node_from_xpath(xpath);
+ char *local_node = pcmk__xpath_node_id(xpath, "lrm");
handle_rsc_op(match, local_node);
free(local_node);
--
1.8.3.1
From b0126373d8b2a739ec5b985a7e1f530e850618d3 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 11 Jan 2021 10:20:11 -0500
Subject: [PATCH 09/10] Refactor: libpacemaker: Move reduce_stonith_history
into the library.
And also rename it to pcmk__reduce_fence_history. I don't see anywhere
else that could use this function at the moment, but it seems too
generic to keep in crm_mon.
---
include/pcmki/pcmki_fence.h | 16 +++++++++++++-
lib/pacemaker/pcmk_fence.c | 45 ++++++++++++++++++++++++++++++++++++++-
tools/crm_mon.c | 52 +--------------------------------------------
3 files changed, 60 insertions(+), 53 deletions(-)
diff --git a/include/pcmki/pcmki_fence.h b/include/pcmki/pcmki_fence.h
index 241d030..d4cef68 100644
--- a/include/pcmki/pcmki_fence.h
+++ b/include/pcmki/pcmki_fence.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2020 the Pacemaker project contributors
+ * Copyright 2019-2021 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -219,4 +219,18 @@ int pcmk__fence_validate(pcmk__output_t *out, stonith_t *st, const char *agent,
const char *id, stonith_key_value_t *params,
unsigned int timeout);
+/**
+ * \brief Reduce the STONITH history
+ *
+ * STONITH history is reduced as follows:
+ * - The last successful action of every action-type and target is kept
+ * - For failed actions, who failed is kept
+ * - All actions in progress are kept
+ *
+ * \param[in] history List of STONITH actions
+ *
+ * \return The reduced history
+ */
+stonith_history_t *
+pcmk__reduce_fence_history(stonith_history_t *history);
#endif
diff --git a/lib/pacemaker/pcmk_fence.c b/lib/pacemaker/pcmk_fence.c
index d591379..34540cc 100644
--- a/lib/pacemaker/pcmk_fence.c
+++ b/lib/pacemaker/pcmk_fence.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2020 the Pacemaker project contributors
+ * Copyright 2009-2021 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -520,3 +520,46 @@ pcmk_fence_validate(xmlNodePtr *xml, stonith_t *st, const char *agent,
return rc;
}
#endif
+
+stonith_history_t *
+pcmk__reduce_fence_history(stonith_history_t *history)
+{
+ stonith_history_t *new, *hp, *np;
+
+ if (!history) {
+ return history;
+ }
+
+ new = history;
+ hp = new->next;
+ new->next = NULL;
+
+ while (hp) {
+ stonith_history_t *hp_next = hp->next;
+
+ hp->next = NULL;
+
+ for (np = new; ; np = np->next) {
+ if ((hp->state == st_done) || (hp->state == st_failed)) {
+ /* action not in progress */
+ if (pcmk__str_eq(hp->target, np->target, pcmk__str_casei) &&
+ pcmk__str_eq(hp->action, np->action, pcmk__str_casei) &&
+ (hp->state == np->state) &&
+ ((hp->state == st_done) ||
+ pcmk__str_eq(hp->delegate, np->delegate, pcmk__str_casei))) {
+ /* purge older hp */
+ stonith_history_free(hp);
+ break;
+ }
+ }
+
+ if (!np->next) {
+ np->next = hp;
+ break;
+ }
+ }
+ hp = hp_next;
+ }
+
+ return new;
+}
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index ff1b86b..2179f53 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -1520,56 +1520,6 @@ print_simple_status(pcmk__output_t *out, pe_working_set_t * data_set,
/* coverity[leaked_storage] False positive */
}
-/*!
- * \internal
- * \brief Reduce the stonith-history
- * for successful actions we keep the last of every action-type & target
- * for failed actions we record as well who had failed
- * for actions in progress we keep full track
- *
- * \param[in] history List of stonith actions
- *
- */
-static stonith_history_t *
-reduce_stonith_history(stonith_history_t *history)
-{
- stonith_history_t *new = history, *hp, *np;
-
- if (new) {
- hp = new->next;
- new->next = NULL;
-
- while (hp) {
- stonith_history_t *hp_next = hp->next;
-
- hp->next = NULL;
-
- for (np = new; ; np = np->next) {
- if ((hp->state == st_done) || (hp->state == st_failed)) {
- /* action not in progress */
- if (pcmk__str_eq(hp->target, np->target, pcmk__str_casei) &&
- pcmk__str_eq(hp->action, np->action, pcmk__str_casei) &&
- (hp->state == np->state) &&
- ((hp->state == st_done) ||
- pcmk__str_eq(hp->delegate, np->delegate, pcmk__str_casei))) {
- /* purge older hp */
- stonith_history_free(hp);
- break;
- }
- }
-
- if (!np->next) {
- np->next = hp;
- break;
- }
- }
- hp = hp_next;
- }
- }
-
- return new;
-}
-
static int
send_custom_trap(const char *node, const char *rsc, const char *task, int target_rc, int rc,
int status, const char *desc)
@@ -1935,7 +1885,7 @@ mon_refresh_display(gpointer user_data)
if (!pcmk_is_set(options.mon_ops, mon_op_fence_full_history)
&& (output_format != mon_output_xml)) {
- stonith_history = reduce_stonith_history(stonith_history);
+ stonith_history = pcmk__reduce_fence_history(stonith_history);
}
break; /* all other cases are errors */
}
--
1.8.3.1
From af3f1368bc76eb498c2c96b3eda9324b579c9380 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Tue, 12 Jan 2021 15:46:55 -0500
Subject: [PATCH 10/10] Low: tools: Adjust fencing shown indicator in crm_mon.
If any of the various fencing flags are set, but not all of them, no '*'
will be shown next to the fencing line in the interactive change screen.
This makes it seem like fencing should not be shown, and hitting 'm'
should toggle the fencing display on. However, that's not the case and
hitting 'm' will actually toggle fencing off. Hitting it again will
toggle it on and the '*' will appear.
This is confusing, so just display the '*' if any fencing flag is set.
---
tools/crm_mon.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index 2179f53..8ec97bb 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -984,7 +984,10 @@ detect_user_input(GIOChannel *channel, GIOCondition condition, gpointer user_dat
print_option_help(out, 'R', pcmk_is_set(options.mon_ops, mon_op_print_clone_detail));
print_option_help(out, 'b', pcmk_is_set(options.mon_ops, mon_op_print_brief));
print_option_help(out, 'j', pcmk_is_set(options.mon_ops, mon_op_print_pending));
- print_option_help(out, 'm', pcmk_is_set(show, mon_show_fencing_all));
+ print_option_help(out, 'm', pcmk_any_flags_set(show,
+ mon_show_fence_failed
+ |mon_show_fence_pending
+ |mon_show_fence_worked));
out->info(out, "%s", "\nToggle fields via field letter, type any other key to return");
}
--
1.8.3.1

File diff suppressed because it is too large Load Diff

View File

@ -1,202 +0,0 @@
From bc60f9c84bd6f0fa4d73db8d140030dfcdbf4f5e Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Tue, 19 Jan 2021 15:58:36 -0500
Subject: [PATCH 1/2] Fix: tools: Describe interactive crm_mon use in help and
man page.
---
tools/crm_mon.8.inc | 3 +++
tools/crm_mon.c | 4 ++++
tools/fix-manpages | 2 +-
3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/tools/crm_mon.8.inc b/tools/crm_mon.8.inc
index e4cd7e3..6b46d7b 100644
--- a/tools/crm_mon.8.inc
+++ b/tools/crm_mon.8.inc
@@ -12,3 +12,6 @@ crm_mon mode [options]
/command line arguments./
.SH TIME SPECIFICATION
+
+/or --exclude=list./
+.SH INTERACTIVE USE
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index 083b7ae..aafc80f 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -1062,6 +1062,10 @@ build_arg_context(pcmk__common_args_t *args, GOptionGroup **group) {
"times on the command line, and each can give a comma-separated list of sections.\n"
"The options are applied to the default set, from left to right as seen on the\n"
"command line. For a list of valid sections, pass --include=list or --exclude=list.\n\n"
+ "Interactive Use:\n\n"
+ "When run interactively, crm_mon can be told to hide and display various sections\n"
+ "of output. To see a help screen explaining the options, hit '?'. Any key stroke\n"
+ "aside from those listed will cause the screen to refresh.\n\n"
"Examples:\n\n"
"Display the cluster status on the console with updates as they occur:\n\n"
"\tcrm_mon\n\n"
diff --git a/tools/fix-manpages b/tools/fix-manpages
index 714ecce..f1f6f0d 100644
--- a/tools/fix-manpages
+++ b/tools/fix-manpages
@@ -26,7 +26,7 @@
# This leaves the --help-all output looking good and removes redundant
# stuff from the man page. Feel free to add additional headers here.
# Not all tools will have all headers.
-/.SH NOTES\|.SH OPERATION SPECIFICATION\|.SH OUTPUT CONTROL\|.SH TIME SPECIFICATION/{ n
+/.SH NOTES\|.SH INTERACTIVE USE\|.SH OPERATION SPECIFICATION\|.SH OUTPUT CONTROL\|.SH TIME SPECIFICATION/{ n
N
N
d
--
1.8.3.1
From ed4e4370dc97bc220878db89d69c71426b9458a3 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Tue, 19 Jan 2021 17:02:45 -0500
Subject: [PATCH 2/2] Fix: tools: The 'm' key in crm_mon is a cycle, not a
toggle.
Each time it's pressed, a different amount of fencing information should
be shown, cycling back to nothing after level 3.
---
tools/crm_mon.c | 76 +++++++++++++++++++++++++++++++++++++++++----------------
1 file changed, 55 insertions(+), 21 deletions(-)
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index aafc80f..0981634 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -83,6 +83,8 @@ static gchar **processed_args = NULL;
static time_t last_refresh = 0;
crm_trigger_t *refresh_trigger = NULL;
+int interactive_fence_level = 0;
+
static pcmk__supported_format_t formats[] = {
#if CURSES_ENABLED
CRM_MON_SUPPORTED_FORMAT_CURSES,
@@ -382,9 +384,9 @@ as_xml_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError *
static gboolean
fence_history_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError **err) {
- int rc = crm_atoi(optarg, "2");
+ interactive_fence_level = crm_atoi(optarg, "2");
- switch (rc) {
+ switch (interactive_fence_level) {
case 3:
options.mon_ops |= mon_op_fence_full_history | mon_op_fence_history | mon_op_fence_connect;
return include_exclude_cb("--include", "fencing", data, err);
@@ -862,6 +864,38 @@ cib_connect(gboolean full)
return rc;
}
+/* This is used to set up the fencing options after the interactive UI has been stared.
+ * fence_history_cb can't be used because it builds up a list of includes/excludes that
+ * then have to be processed with apply_include_exclude and that could affect other
+ * things.
+ */
+static void
+set_fencing_options(int level)
+{
+ switch (level) {
+ case 3:
+ options.mon_ops |= mon_op_fence_full_history | mon_op_fence_history | mon_op_fence_connect;
+ show |= mon_show_fencing_all;
+ break;
+
+ case 2:
+ options.mon_ops |= mon_op_fence_history | mon_op_fence_connect;
+ show |= mon_show_fencing_all;
+ break;
+
+ case 1:
+ options.mon_ops |= mon_op_fence_history | mon_op_fence_connect;
+ show |= mon_show_fence_failed | mon_show_fence_pending;
+ break;
+
+ default:
+ level = 0;
+ options.mon_ops &= ~(mon_op_fence_history | mon_op_fence_connect);
+ show &= ~mon_show_fencing_all;
+ break;
+ }
+}
+
#if CURSES_ENABLED
static const char *
get_option_desc(char c)
@@ -900,23 +934,12 @@ detect_user_input(GIOChannel *channel, GIOCondition condition, gpointer user_dat
switch (c) {
case 'm':
- if (!pcmk_is_set(show, mon_show_fencing_all)) {
- options.mon_ops |= mon_op_fence_history;
- options.mon_ops |= mon_op_fence_connect;
- if (st == NULL) {
- mon_cib_connection_destroy(NULL);
- }
- }
-
- if (pcmk_any_flags_set(show,
- mon_show_fence_failed
- |mon_show_fence_pending
- |mon_show_fence_worked)) {
- show &= ~mon_show_fencing_all;
- } else {
- show |= mon_show_fencing_all;
+ interactive_fence_level++;
+ if (interactive_fence_level > 3) {
+ interactive_fence_level = 0;
}
+ set_fencing_options(interactive_fence_level);
break;
case 'c':
show ^= mon_show_tickets;
@@ -997,10 +1020,7 @@ detect_user_input(GIOChannel *channel, GIOCondition condition, gpointer user_dat
print_option_help(out, 'R', pcmk_is_set(options.mon_ops, mon_op_print_clone_detail));
print_option_help(out, 'b', pcmk_is_set(options.mon_ops, mon_op_print_brief));
print_option_help(out, 'j', pcmk_is_set(options.mon_ops, mon_op_print_pending));
- print_option_help(out, 'm', pcmk_any_flags_set(show,
- mon_show_fence_failed
- |mon_show_fence_pending
- |mon_show_fence_worked));
+ out->info(out, "%d m: \t%s", interactive_fence_level, get_option_desc('m'));
out->info(out, "%s", "\nToggle fields via field letter, type any other key to return");
}
@@ -1400,6 +1420,19 @@ main(int argc, char **argv)
return clean_up(CRM_EX_USAGE);
}
+ /* Sync up the initial value of interactive_fence_level with whatever was set with
+ * --include/--exclude= options.
+ */
+ if (pcmk_is_set(show, mon_show_fencing_all)) {
+ interactive_fence_level = 3;
+ } else if (pcmk_is_set(show, mon_show_fence_worked)) {
+ interactive_fence_level = 2;
+ } else if (pcmk_any_flags_set(show, mon_show_fence_failed | mon_show_fence_pending)) {
+ interactive_fence_level = 1;
+ } else {
+ interactive_fence_level = 0;
+ }
+
crm_mon_register_messages(out);
pe__register_messages(out);
stonith__register_messages(out);
@@ -1460,6 +1493,7 @@ main(int argc, char **argv)
} while (rc == -ENOTCONN);
handle_connection_failures(rc);
+ set_fencing_options(interactive_fence_level);
mon_refresh_display(NULL);
mainloop = g_main_loop_new(NULL, FALSE);
--
1.8.3.1

File diff suppressed because it is too large Load Diff

View File

@ -1,29 +0,0 @@
From 240b9ec01e6a6e6554f0ae13d759c01339835a40 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Wed, 27 Jan 2021 10:10:03 +0100
Subject: [PATCH] Feature: cibsecret: use crmadmin -N (which also lists guest
and remote nodes) to get nodes to sync to
---
tools/cibsecret.in | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/cibsecret.in b/tools/cibsecret.in
index 8923a70..6326bf0 100644
--- a/tools/cibsecret.in
+++ b/tools/cibsecret.in
@@ -182,9 +182,9 @@ get_live_peers() {
[ $? -eq 0 ] || fatal $CRM_EX_UNAVAILABLE "couldn't get local node name"
# Get a list of all other cluster nodes
- GLP_ALL_PEERS="$(crm_node -l)"
+ GLP_ALL_PEERS="$(crmadmin -N -q)"
[ $? -eq 0 ] || fatal $CRM_EX_UNAVAILABLE "couldn't determine cluster nodes"
- GLP_ALL_PEERS="$(echo "$GLP_ALL_PEERS" | awk '{print $2}' | grep -v "^${GLP_LOCAL_NODE}$")"
+ GLP_ALL_PEERS="$(echo "$GLP_ALL_PEERS" | grep -v "^${GLP_LOCAL_NODE}$")"
# Make a list of those that respond to pings
if [ "$(id -u)" = "0" ] && which fping >/dev/null 2>&1; then
--
1.8.3.1

File diff suppressed because it is too large Load Diff

View File

@ -1,26 +0,0 @@
From 494eebe33d56b24e1f3a13ebe6c0ec651c99a2af Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Wed, 3 Feb 2021 09:47:39 -0600
Subject: [PATCH] Fix: tools: get cibsecret stash working again
Broke with dfe636c4
---
tools/cibsecret.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/cibsecret.in b/tools/cibsecret.in
index 6326bf0..ce57a18 100644
--- a/tools/cibsecret.in
+++ b/tools/cibsecret.in
@@ -393,7 +393,7 @@ cibsecret_stash() {
fatal $CRM_EX_NOSUCH "nothing to stash for resource $rsc parameter $param"
is_secret "$CIBSTASH_CURRENT" &&
fatal $CRM_EX_EXISTS "resource $rsc parameter $param already set as secret, nothing to stash"
- cibsecret_set "$CIBSTASH_CURRENT"
+ cibsecret_set "$CIBSTASH_CURRENT" 4
}
cibsecret_unstash() {
--
1.8.3.1

View File

@ -1,709 +0,0 @@
From 68139dc8ff5efbfd81d3b5e868462e7eaefa2c74 Mon Sep 17 00:00:00 2001
From: Klaus Wenninger <klaus.wenninger@aon.at>
Date: Mon, 25 Jan 2021 15:35:33 +0100
Subject: [PATCH 1/7] Fix: crm_mon: add explicit void to one_shot prototype for
compat
---
tools/crm_mon.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index 0981634..1eca1b7 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -1226,7 +1226,7 @@ handle_connection_failures(int rc)
}
static void
-one_shot()
+one_shot(void)
{
int rc;
--
1.8.3.1
From 8c7a01f8880efff8457e8421c381082b250d4512 Mon Sep 17 00:00:00 2001
From: Klaus Wenninger <klaus.wenninger@aon.at>
Date: Mon, 25 Jan 2021 16:26:30 +0100
Subject: [PATCH 2/7] Refactor: crm_mon: cib_connect &
handle_connection_failures -> new rc
---
tools/crm_mon.c | 62 ++++++++++++++++++++++++++++++++-------------------------
1 file changed, 35 insertions(+), 27 deletions(-)
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index 1eca1b7..3fbac5f 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -690,7 +690,7 @@ reconnect_after_timeout(gpointer data)
print_as(output_format, "Reconnecting...\n");
fencing_connect();
- if (cib_connect(TRUE) == pcmk_ok) {
+ if (cib_connect(TRUE) == pcmk_rc_ok) {
/* Redraw the screen and reinstall ourselves to get called after another reconnect_msec. */
mon_refresh_display(NULL);
return FALSE;
@@ -804,16 +804,17 @@ fencing_connect(void)
static int
cib_connect(gboolean full)
{
- int rc = pcmk_ok;
+ int rc = pcmk_rc_ok;
static gboolean need_pass = TRUE;
- CRM_CHECK(cib != NULL, return -EINVAL);
+ CRM_CHECK(cib != NULL, return EINVAL);
if (getenv("CIB_passwd") != NULL) {
need_pass = FALSE;
}
- if (cib->state == cib_connected_query || cib->state == cib_connected_command) {
+ if (cib->state == cib_connected_query ||
+ cib->state == cib_connected_command) {
return rc;
}
@@ -825,37 +826,44 @@ cib_connect(gboolean full)
* @TODO Add a password prompt (maybe including input) function to
* pcmk__output_t and use it in libcib.
*/
- if ((output_format == mon_output_console) && need_pass && (cib->variant == cib_remote)) {
+ if ((output_format == mon_output_console) &&
+ need_pass &&
+ (cib->variant == cib_remote)) {
need_pass = FALSE;
print_as(output_format, "Password:");
}
- rc = cib->cmds->signon(cib, crm_system_name, cib_query);
- if (rc != pcmk_ok) {
+ rc = pcmk_legacy2rc(cib->cmds->signon(cib, crm_system_name, cib_query));
+ if (rc != pcmk_rc_ok) {
out->err(out, "Could not connect to the CIB: %s",
- pcmk_strerror(rc));
+ pcmk_rc_str(rc));
return rc;
}
- rc = cib->cmds->query(cib, NULL, &current_cib, cib_scope_local | cib_sync_call);
+ rc = pcmk_legacy2rc(cib->cmds->query(cib, NULL, &current_cib,
+ cib_scope_local | cib_sync_call));
- if (rc == pcmk_ok && full) {
- rc = cib->cmds->set_connection_dnotify(cib, mon_cib_connection_destroy);
- if (rc == -EPROTONOSUPPORT) {
- print_as
- (output_format, "Notification setup not supported, won't be able to reconnect after failure");
+ if (rc == pcmk_rc_ok && full) {
+ rc = pcmk_legacy2rc(cib->cmds->set_connection_dnotify(cib,
+ mon_cib_connection_destroy));
+ if (rc == EPROTONOSUPPORT) {
+ print_as(output_format,
+ "Notification setup not supported, won't be "
+ "able to reconnect after failure");
if (output_format == mon_output_console) {
sleep(2);
}
- rc = pcmk_ok;
+ rc = pcmk_rc_ok;
}
- if (rc == pcmk_ok) {
- cib->cmds->del_notify_callback(cib, T_CIB_DIFF_NOTIFY, crm_diff_update);
- rc = cib->cmds->add_notify_callback(cib, T_CIB_DIFF_NOTIFY, crm_diff_update);
+ if (rc == pcmk_rc_ok) {
+ cib->cmds->del_notify_callback(cib, T_CIB_DIFF_NOTIFY,
+ crm_diff_update);
+ rc = pcmk_legacy2rc(cib->cmds->add_notify_callback(cib,
+ T_CIB_DIFF_NOTIFY, crm_diff_update));
}
- if (rc != pcmk_ok) {
+ if (rc != pcmk_rc_ok) {
out->err(out, "Notification setup failed, could not monitor CIB actions");
clean_up_cib_connection();
clean_up_fencing_connection();
@@ -1206,20 +1214,20 @@ reconcile_output_format(pcmk__common_args_t *args) {
static void
handle_connection_failures(int rc)
{
- if (rc == pcmk_ok) {
+ if (rc == pcmk_rc_ok) {
return;
}
if (output_format == mon_output_monitor) {
g_set_error(&error, PCMK__EXITC_ERROR, CRM_EX_ERROR, "CLUSTER CRIT: Connection to cluster failed: %s",
- pcmk_strerror(rc));
+ pcmk_rc_str(rc));
rc = MON_STATUS_CRIT;
- } else if (rc == -ENOTCONN) {
+ } else if (rc == ENOTCONN) {
g_set_error(&error, PCMK__EXITC_ERROR, CRM_EX_ERROR, "Error: cluster is not available on this node");
- rc = crm_errno2exit(rc);
+ rc = pcmk_rc2exitc(rc);
} else {
- g_set_error(&error, PCMK__EXITC_ERROR, CRM_EX_ERROR, "Connection to cluster failed: %s", pcmk_strerror(rc));
- rc = crm_errno2exit(rc);
+ g_set_error(&error, PCMK__EXITC_ERROR, CRM_EX_ERROR, "Connection to cluster failed: %s", pcmk_rc_str(rc));
+ rc = pcmk_rc2exitc(rc);
}
clean_up(rc);
@@ -1478,7 +1486,7 @@ main(int argc, char **argv)
fencing_connect();
rc = cib_connect(TRUE);
- if (rc != pcmk_ok) {
+ if (rc != pcmk_rc_ok) {
sleep(options.reconnect_msec / 1000);
#if CURSES_ENABLED
if (output_format == mon_output_console) {
@@ -1490,7 +1498,7 @@ main(int argc, char **argv)
printf("Writing html to %s ...\n", args->output_dest);
}
- } while (rc == -ENOTCONN);
+ } while (rc == ENOTCONN);
handle_connection_failures(rc);
set_fencing_options(interactive_fence_level);
--
1.8.3.1
From 9b8fb7b608280f65a3b76d66a99b575a4da70944 Mon Sep 17 00:00:00 2001
From: Klaus Wenninger <klaus.wenninger@aon.at>
Date: Mon, 25 Jan 2021 18:26:04 +0100
Subject: [PATCH 3/7] Fix: tools: Report pacemakerd in state waiting for sbd
Waiting for pacemakerd to report that all subdaemons are started
before trying to connect to cib and fencer should remove the
potential race introduced by making fencer connection failure
non fatal when cib is faster to come up.
---
tools/crm_mon.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
tools/crm_mon.h | 1 +
2 files changed, 148 insertions(+), 11 deletions(-)
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index 3fbac5f..61f070d 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -132,6 +132,7 @@ static void handle_connection_failures(int rc);
static int mon_refresh_display(gpointer user_data);
static int cib_connect(gboolean full);
static int fencing_connect(void);
+static int pacemakerd_status(void);
static void mon_st_callback_event(stonith_t * st, stonith_event_t * e);
static void mon_st_callback_display(stonith_t * st, stonith_event_t * e);
static void refresh_after_event(gboolean data_updated);
@@ -689,11 +690,13 @@ reconnect_after_timeout(gpointer data)
}
print_as(output_format, "Reconnecting...\n");
- fencing_connect();
- if (cib_connect(TRUE) == pcmk_rc_ok) {
- /* Redraw the screen and reinstall ourselves to get called after another reconnect_msec. */
- mon_refresh_display(NULL);
- return FALSE;
+ if (pacemakerd_status() == pcmk_rc_ok) {
+ fencing_connect();
+ if (cib_connect(TRUE) == pcmk_rc_ok) {
+ /* Redraw the screen and reinstall ourselves to get called after another reconnect_msec. */
+ mon_refresh_display(NULL);
+ return FALSE;
+ }
}
reconnect_timer = g_timeout_add(options.reconnect_msec, reconnect_after_timeout, NULL);
@@ -840,6 +843,13 @@ cib_connect(gboolean full)
return rc;
}
+#if CURSES_ENABLED
+ /* just show this if refresh is gonna remove all traces */
+ if (output_format == mon_output_console) {
+ print_as(output_format ,"Waiting for CIB ...\n");
+ }
+#endif
+
rc = pcmk_legacy2rc(cib->cmds->query(cib, NULL, &current_cib,
cib_scope_local | cib_sync_call));
@@ -904,6 +914,121 @@ set_fencing_options(int level)
}
}
+/* Before trying to connect to fencer or cib check for state of
+ pacemakerd - just no sense in trying till pacemakerd has
+ taken care of starting all the sub-processes
+
+ Only noteworthy thing to show here is when pacemakerd is
+ waiting for startup-trigger from SBD.
+ */
+static void
+pacemakerd_event_cb(pcmk_ipc_api_t *pacemakerd_api,
+ enum pcmk_ipc_event event_type, crm_exit_t status,
+ void *event_data, void *user_data)
+{
+ pcmk_pacemakerd_api_reply_t *reply = event_data;
+ enum pcmk_pacemakerd_state *state =
+ (enum pcmk_pacemakerd_state *) user_data;
+
+ /* we are just interested in the latest reply */
+ *state = pcmk_pacemakerd_state_invalid;
+
+ switch (event_type) {
+ case pcmk_ipc_event_reply:
+ break;
+
+ default:
+ return;
+ }
+
+ if (status != CRM_EX_OK) {
+ out->err(out, "Bad reply from pacemakerd: %s",
+ crm_exit_str(status));
+ return;
+ }
+
+ if (reply->reply_type != pcmk_pacemakerd_reply_ping) {
+ out->err(out, "Unknown reply type %d from pacemakerd",
+ reply->reply_type);
+ } else {
+ if ((reply->data.ping.last_good != (time_t) 0) &&
+ (reply->data.ping.status == pcmk_rc_ok)) {
+ *state = reply->data.ping.state;
+ }
+ }
+}
+
+static int
+pacemakerd_status(void)
+{
+ int rc = pcmk_rc_ok;
+ pcmk_ipc_api_t *pacemakerd_api = NULL;
+ enum pcmk_pacemakerd_state state = pcmk_pacemakerd_state_invalid;
+
+ if (!pcmk_is_set(options.mon_ops, mon_op_cib_native)) {
+ /* we don't need fully functional pacemakerd otherwise */
+ return rc;
+ }
+ if (cib != NULL &&
+ (cib->state == cib_connected_query ||
+ cib->state == cib_connected_command)) {
+ /* As long as we have a cib-connection let's go with
+ * that to fetch further cluster-status and avoid
+ * unnecessary pings to pacemakerd.
+ * If cluster is going down and fencer is down already
+ * this will lead to a silently failing fencer reconnect.
+ * On cluster startup we shouldn't see this situation
+ * as first we do is wait for pacemakerd to report all
+ * daemons running.
+ */
+ return rc;
+ }
+ rc = pcmk_new_ipc_api(&pacemakerd_api, pcmk_ipc_pacemakerd);
+ if (pacemakerd_api == NULL) {
+ out->err(out, "Could not connect to pacemakerd: %s",
+ pcmk_rc_str(rc));
+ /* this is unrecoverable so return with rc we have */
+ return rc;
+ }
+ pcmk_register_ipc_callback(pacemakerd_api, pacemakerd_event_cb, (void *) &state);
+ rc = pcmk_connect_ipc(pacemakerd_api, pcmk_ipc_dispatch_poll);
+ if (rc == pcmk_rc_ok) {
+ rc = pcmk_pacemakerd_api_ping(pacemakerd_api, crm_system_name);
+ if (rc == pcmk_rc_ok) {
+ rc = pcmk_poll_ipc(pacemakerd_api, options.reconnect_msec/2);
+ if (rc == pcmk_rc_ok) {
+ pcmk_dispatch_ipc(pacemakerd_api);
+ rc = ENOTCONN;
+ switch (state) {
+ case pcmk_pacemakerd_state_running:
+ rc = pcmk_rc_ok;
+ break;
+ case pcmk_pacemakerd_state_starting_daemons:
+ print_as(output_format ,"Pacemaker daemons starting ...\n");
+ break;
+ case pcmk_pacemakerd_state_wait_for_ping:
+ print_as(output_format ,"Waiting for startup-trigger from SBD ...\n");
+ break;
+ case pcmk_pacemakerd_state_shutting_down:
+ print_as(output_format ,"Pacemaker daemons shutting down ...\n");
+ break;
+ case pcmk_pacemakerd_state_shutdown_complete:
+ /* assuming pacemakerd doesn't dispatch any pings after entering
+ * that state unless it is waiting for SBD
+ */
+ print_as(output_format ,"Pacemaker daemons shut down - reporting to SBD ...\n");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ pcmk_free_ipc_api(pacemakerd_api);
+ /* returning with ENOTCONN triggers a retry */
+ return (rc == pcmk_rc_ok)?rc:ENOTCONN;
+}
+
#if CURSES_ENABLED
static const char *
get_option_desc(char c)
@@ -1033,8 +1158,11 @@ detect_user_input(GIOChannel *channel, GIOCondition condition, gpointer user_dat
}
refresh:
- fencing_connect();
- rc = cib_connect(FALSE);
+ rc = pacemakerd_status();
+ if (rc == pcmk_rc_ok) {
+ fencing_connect();
+ rc = cib_connect(FALSE);
+ }
if (rc == pcmk_rc_ok) {
mon_refresh_display(NULL);
} else {
@@ -1238,9 +1366,13 @@ one_shot(void)
{
int rc;
- fencing_connect();
+ rc = pacemakerd_status();
+
+ if (rc == pcmk_rc_ok) {
+ fencing_connect();
+ rc = cib_connect(FALSE);
+ }
- rc = cib_connect(FALSE);
if (rc == pcmk_rc_ok) {
mon_refresh_display(NULL);
} else {
@@ -1316,6 +1448,7 @@ main(int argc, char **argv)
case cib_native:
/* cib & fencing - everything available */
+ options.mon_ops |= mon_op_cib_native;
break;
case cib_file:
@@ -1483,8 +1616,11 @@ main(int argc, char **argv)
do {
print_as(output_format ,"Waiting until cluster is available on this node ...\n");
- fencing_connect();
- rc = cib_connect(TRUE);
+ rc = pacemakerd_status();
+ if (rc == pcmk_rc_ok) {
+ fencing_connect();
+ rc = cib_connect(TRUE);
+ }
if (rc != pcmk_rc_ok) {
sleep(options.reconnect_msec / 1000);
diff --git a/tools/crm_mon.h b/tools/crm_mon.h
index 73c926d..b556913 100644
--- a/tools/crm_mon.h
+++ b/tools/crm_mon.h
@@ -91,6 +91,7 @@ typedef enum mon_output_format_e {
#define mon_op_print_brief (0x0200U)
#define mon_op_print_pending (0x0400U)
#define mon_op_print_clone_detail (0x0800U)
+#define mon_op_cib_native (0x1000U)
#define mon_op_default (mon_op_print_pending | mon_op_fence_history | mon_op_fence_connect)
--
1.8.3.1
From 046516dbe66fb2c52b90f36215cf60c5ad3c269b Mon Sep 17 00:00:00 2001
From: Klaus Wenninger <klaus.wenninger@aon.at>
Date: Thu, 28 Jan 2021 16:38:22 +0100
Subject: [PATCH 4/7] Refactor: crm_mon: do refreshes rather via
refresh_after_event
---
tools/crm_mon.c | 35 ++++++++++++++---------------------
1 file changed, 14 insertions(+), 21 deletions(-)
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index 61f070d..195e7b5 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -135,7 +135,7 @@ static int fencing_connect(void);
static int pacemakerd_status(void);
static void mon_st_callback_event(stonith_t * st, stonith_event_t * e);
static void mon_st_callback_display(stonith_t * st, stonith_event_t * e);
-static void refresh_after_event(gboolean data_updated);
+static void refresh_after_event(gboolean data_updated, gboolean enforce);
static unsigned int
all_includes(mon_output_format_t fmt) {
@@ -694,13 +694,13 @@ reconnect_after_timeout(gpointer data)
fencing_connect();
if (cib_connect(TRUE) == pcmk_rc_ok) {
/* Redraw the screen and reinstall ourselves to get called after another reconnect_msec. */
- mon_refresh_display(NULL);
+ refresh_after_event(FALSE, TRUE);
return FALSE;
}
}
reconnect_timer = g_timeout_add(options.reconnect_msec, reconnect_after_timeout, NULL);
- return TRUE;
+ return FALSE;
}
/* Called from various places when we are disconnected from the CIB or from the
@@ -1057,7 +1057,6 @@ static gboolean
detect_user_input(GIOChannel *channel, GIOCondition condition, gpointer user_data)
{
int c;
- int rc;
gboolean config_mode = FALSE;
while (1) {
@@ -1158,16 +1157,7 @@ detect_user_input(GIOChannel *channel, GIOCondition condition, gpointer user_dat
}
refresh:
- rc = pacemakerd_status();
- if (rc == pcmk_rc_ok) {
- fencing_connect();
- rc = cib_connect(FALSE);
- }
- if (rc == pcmk_rc_ok) {
- mon_refresh_display(NULL);
- } else {
- handle_connection_failures(rc);
- }
+ refresh_after_event(FALSE, TRUE);
return TRUE;
}
@@ -2087,7 +2077,7 @@ crm_diff_update(const char *event, xmlNode * msg)
}
stale = FALSE;
- refresh_after_event(cib_updated);
+ refresh_after_event(cib_updated, FALSE);
}
static int
@@ -2246,7 +2236,7 @@ mon_st_callback_event(stonith_t * st, stonith_event_t * e)
* fencing event is received or a CIB diff occurrs.
*/
static void
-refresh_after_event(gboolean data_updated)
+refresh_after_event(gboolean data_updated, gboolean enforce)
{
static int updates = 0;
time_t now = time(NULL);
@@ -2259,12 +2249,15 @@ refresh_after_event(gboolean data_updated)
refresh_timer = mainloop_timer_add("refresh", 2000, FALSE, mon_trigger_refresh, NULL);
}
- if ((now - last_refresh) > (options.reconnect_msec / 1000)) {
- mainloop_set_trigger(refresh_trigger);
+ if (reconnect_timer > 0) {
+ /* we will receive a refresh request after successful reconnect */
mainloop_timer_stop(refresh_timer);
- updates = 0;
+ return;
+ }
- } else if(updates >= 10) {
+ if (enforce ||
+ now - last_refresh > options.reconnect_msec / 1000 ||
+ updates >= 10) {
mainloop_set_trigger(refresh_trigger);
mainloop_timer_stop(refresh_timer);
updates = 0;
@@ -2285,7 +2278,7 @@ mon_st_callback_display(stonith_t * st, stonith_event_t * e)
mon_cib_connection_destroy(NULL);
} else {
print_dot(output_format);
- refresh_after_event(TRUE);
+ refresh_after_event(TRUE, FALSE);
}
}
--
1.8.3.1
From a63af2713f96719fc1d5ef594eb033d0f251187f Mon Sep 17 00:00:00 2001
From: Klaus Wenninger <klaus.wenninger@aon.at>
Date: Thu, 28 Jan 2021 16:52:57 +0100
Subject: [PATCH 5/7] Fix: crm_mon: retry fencer connection as not fatal
initially
and cleanup fencer api to not leak memory on multiple reconnects
---
tools/crm_mon.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index 195e7b5..a768ca9 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -798,7 +798,7 @@ fencing_connect(void)
st->cmds->register_notification(st, T_STONITH_NOTIFY_HISTORY, mon_st_callback_display);
}
} else {
- st = NULL;
+ clean_up_fencing_connection();
}
return rc;
@@ -2255,6 +2255,12 @@ refresh_after_event(gboolean data_updated, gboolean enforce)
return;
}
+ /* as we're not handling initial failure of fencer-connection as
+ * fatal give it a retry here
+ * not getting here if cib-reconnection is already on the way
+ */
+ fencing_connect();
+
if (enforce ||
now - last_refresh > options.reconnect_msec / 1000 ||
updates >= 10) {
--
1.8.3.1
From b6f4b5dfc0b5fec8cdc029409fc61252de019415 Mon Sep 17 00:00:00 2001
From: Klaus Wenninger <klaus.wenninger@aon.at>
Date: Thu, 28 Jan 2021 18:08:43 +0100
Subject: [PATCH 6/7] Refactor: crm_mon: have reconnect-timer removed
implicitly
---
tools/crm_mon.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index a768ca9..4f73379 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -684,23 +684,19 @@ reconnect_after_timeout(gpointer data)
}
#endif
- if (reconnect_timer > 0) {
- g_source_remove(reconnect_timer);
- reconnect_timer = 0;
- }
-
print_as(output_format, "Reconnecting...\n");
if (pacemakerd_status() == pcmk_rc_ok) {
fencing_connect();
if (cib_connect(TRUE) == pcmk_rc_ok) {
- /* Redraw the screen and reinstall ourselves to get called after another reconnect_msec. */
+ /* trigger redrawing the screen (needs reconnect_timer == 0) */
+ reconnect_timer = 0;
refresh_after_event(FALSE, TRUE);
- return FALSE;
+ return G_SOURCE_REMOVE;
}
}
reconnect_timer = g_timeout_add(options.reconnect_msec, reconnect_after_timeout, NULL);
- return FALSE;
+ return G_SOURCE_REMOVE;
}
/* Called from various places when we are disconnected from the CIB or from the
--
1.8.3.1
From 586e69ec38d5273b348c42a61b9bc7bbcc2b93b3 Mon Sep 17 00:00:00 2001
From: Klaus Wenninger <klaus.wenninger@aon.at>
Date: Thu, 28 Jan 2021 21:08:16 +0100
Subject: [PATCH 7/7] Fix: crm_mon: suppress pacemakerd-status for non-text
output
---
tools/crm_mon.c | 53 ++++++++++++++++++++++++++++++++---------------------
1 file changed, 32 insertions(+), 21 deletions(-)
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index 4f73379..d4d4ac3 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -995,27 +995,38 @@ pacemakerd_status(void)
if (rc == pcmk_rc_ok) {
pcmk_dispatch_ipc(pacemakerd_api);
rc = ENOTCONN;
- switch (state) {
- case pcmk_pacemakerd_state_running:
- rc = pcmk_rc_ok;
- break;
- case pcmk_pacemakerd_state_starting_daemons:
- print_as(output_format ,"Pacemaker daemons starting ...\n");
- break;
- case pcmk_pacemakerd_state_wait_for_ping:
- print_as(output_format ,"Waiting for startup-trigger from SBD ...\n");
- break;
- case pcmk_pacemakerd_state_shutting_down:
- print_as(output_format ,"Pacemaker daemons shutting down ...\n");
- break;
- case pcmk_pacemakerd_state_shutdown_complete:
- /* assuming pacemakerd doesn't dispatch any pings after entering
- * that state unless it is waiting for SBD
- */
- print_as(output_format ,"Pacemaker daemons shut down - reporting to SBD ...\n");
- break;
- default:
- break;
+ if ((output_format == mon_output_console) ||
+ (output_format == mon_output_plain)) {
+ switch (state) {
+ case pcmk_pacemakerd_state_running:
+ rc = pcmk_rc_ok;
+ break;
+ case pcmk_pacemakerd_state_starting_daemons:
+ print_as(output_format ,"Pacemaker daemons starting ...\n");
+ break;
+ case pcmk_pacemakerd_state_wait_for_ping:
+ print_as(output_format ,"Waiting for startup-trigger from SBD ...\n");
+ break;
+ case pcmk_pacemakerd_state_shutting_down:
+ print_as(output_format ,"Pacemaker daemons shutting down ...\n");
+ break;
+ case pcmk_pacemakerd_state_shutdown_complete:
+ /* assuming pacemakerd doesn't dispatch any pings after entering
+ * that state unless it is waiting for SBD
+ */
+ print_as(output_format ,"Pacemaker daemons shut down - reporting to SBD ...\n");
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (state) {
+ case pcmk_pacemakerd_state_running:
+ rc = pcmk_rc_ok;
+ break;
+ default:
+ break;
+ }
}
}
}
--
1.8.3.1

View File

@ -1,267 +0,0 @@
From f4e3d77c94906a062641c7bf34243049de521a87 Mon Sep 17 00:00:00 2001
From: Klaus Wenninger <klaus.wenninger@aon.at>
Date: Wed, 3 Feb 2021 13:25:22 +0100
Subject: [PATCH] Fix: crm_mon: detect when run on remote-node
---
daemons/execd/remoted_proxy.c | 17 +++++++
daemons/pacemakerd/pacemakerd.c | 6 +--
include/crm/common/ipc_internal.h | 2 +
lib/common/ipc_server.c | 26 ++++++++++
tools/crm_mon.c | 99 ++++++++++++++++++++++++---------------
5 files changed, 106 insertions(+), 44 deletions(-)
diff --git a/daemons/execd/remoted_proxy.c b/daemons/execd/remoted_proxy.c
index 9329fa6..0fe39bf 100644
--- a/daemons/execd/remoted_proxy.c
+++ b/daemons/execd/remoted_proxy.c
@@ -29,6 +29,7 @@ static qb_ipcs_service_t *cib_shm = NULL;
static qb_ipcs_service_t *attrd_ipcs = NULL;
static qb_ipcs_service_t *crmd_ipcs = NULL;
static qb_ipcs_service_t *stonith_ipcs = NULL;
+static qb_ipcs_service_t *pacemakerd_ipcs = NULL;
// An IPC provider is a cluster node controller connecting as a client
static GList *ipc_providers = NULL;
@@ -126,6 +127,12 @@ stonith_proxy_accept(qb_ipcs_connection_t * c, uid_t uid, gid_t gid)
}
static int32_t
+pacemakerd_proxy_accept(qb_ipcs_connection_t * c, uid_t uid, gid_t gid)
+{
+ return -EREMOTEIO;
+}
+
+static int32_t
cib_proxy_accept_rw(qb_ipcs_connection_t * c, uid_t uid, gid_t gid)
{
return ipc_proxy_accept(c, uid, gid, PCMK__SERVER_BASED_RW);
@@ -356,6 +363,14 @@ static struct qb_ipcs_service_handlers stonith_proxy_callbacks = {
.connection_destroyed = ipc_proxy_destroy
};
+static struct qb_ipcs_service_handlers pacemakerd_proxy_callbacks = {
+ .connection_accept = pacemakerd_proxy_accept,
+ .connection_created = NULL,
+ .msg_process = NULL,
+ .connection_closed = NULL,
+ .connection_destroyed = NULL
+};
+
static struct qb_ipcs_service_handlers cib_proxy_callbacks_ro = {
.connection_accept = cib_proxy_accept_ro,
.connection_created = NULL,
@@ -422,6 +437,7 @@ ipc_proxy_init(void)
&cib_proxy_callbacks_rw);
pcmk__serve_attrd_ipc(&attrd_ipcs, &attrd_proxy_callbacks);
pcmk__serve_fenced_ipc(&stonith_ipcs, &stonith_proxy_callbacks);
+ pcmk__serve_pacemakerd_ipc(&pacemakerd_ipcs, &pacemakerd_proxy_callbacks);
crmd_ipcs = pcmk__serve_controld_ipc(&crmd_proxy_callbacks);
if (crmd_ipcs == NULL) {
crm_err("Failed to create controller: exiting and inhibiting respawn");
@@ -444,6 +460,7 @@ ipc_proxy_cleanup(void)
pcmk__stop_based_ipc(cib_ro, cib_rw, cib_shm);
qb_ipcs_destroy(attrd_ipcs);
qb_ipcs_destroy(stonith_ipcs);
+ qb_ipcs_destroy(pacemakerd_ipcs);
qb_ipcs_destroy(crmd_ipcs);
cib_ro = NULL;
cib_rw = NULL;
diff --git a/daemons/pacemakerd/pacemakerd.c b/daemons/pacemakerd/pacemakerd.c
index 509b0f8..4572b70 100644
--- a/daemons/pacemakerd/pacemakerd.c
+++ b/daemons/pacemakerd/pacemakerd.c
@@ -1287,11 +1287,7 @@ main(int argc, char **argv)
// Don't build CRM_RSCTMP_DIR, pacemaker-execd will do it
- ipcs = mainloop_add_ipc_server(CRM_SYSTEM_MCP, QB_IPC_NATIVE, &mcp_ipc_callbacks);
- if (ipcs == NULL) {
- crm_err("Couldn't start IPC server");
- crm_exit(CRM_EX_OSERR);
- }
+ pcmk__serve_pacemakerd_ipc(&ipcs, &mcp_ipc_callbacks);
#ifdef SUPPORT_COROSYNC
/* Allows us to block shutdown */
diff --git a/include/crm/common/ipc_internal.h b/include/crm/common/ipc_internal.h
index cf935f3..fb82ce1 100644
--- a/include/crm/common/ipc_internal.h
+++ b/include/crm/common/ipc_internal.h
@@ -221,6 +221,8 @@ void pcmk__serve_attrd_ipc(qb_ipcs_service_t **ipcs,
struct qb_ipcs_service_handlers *cb);
void pcmk__serve_fenced_ipc(qb_ipcs_service_t **ipcs,
struct qb_ipcs_service_handlers *cb);
+void pcmk__serve_pacemakerd_ipc(qb_ipcs_service_t **ipcs,
+ struct qb_ipcs_service_handlers *cb);
qb_ipcs_service_t *pcmk__serve_controld_ipc(struct qb_ipcs_service_handlers *cb);
void pcmk__serve_based_ipc(qb_ipcs_service_t **ipcs_ro,
diff --git a/lib/common/ipc_server.c b/lib/common/ipc_server.c
index 4d3e954..b3aaf8e 100644
--- a/lib/common/ipc_server.c
+++ b/lib/common/ipc_server.c
@@ -922,6 +922,32 @@ pcmk__serve_fenced_ipc(qb_ipcs_service_t **ipcs,
}
/*!
+ * \internal
+ * \brief Add an IPC server to the main loop for the pacemakerd API
+ *
+ * \param[in] cb IPC callbacks
+ *
+ * \note This function exits with CRM_EX_OSERR if unable to create the servers.
+ */
+void
+pcmk__serve_pacemakerd_ipc(qb_ipcs_service_t **ipcs,
+ struct qb_ipcs_service_handlers *cb)
+{
+ *ipcs = mainloop_add_ipc_server(CRM_SYSTEM_MCP, QB_IPC_NATIVE, cb);
+
+ if (*ipcs == NULL) {
+ crm_err("Couldn't start pacemakerd IPC server");
+ crm_warn("Verify pacemaker and pacemaker_remote are not both enabled.");
+ /* sub-daemons are observed by pacemakerd. Thus we exit CRM_EX_FATAL
+ * if we want to prevent pacemakerd from restarting them.
+ * With pacemakerd we leave the exit-code shown to e.g. systemd
+ * to what it was prior to moving the code here from pacemakerd.c
+ */
+ crm_exit(CRM_EX_OSERR);
+ }
+}
+
+/*!
* \brief Check whether string represents a client name used by cluster daemons
*
* \param[in] name String to check
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
index d4d4ac3..e58fed2 100644
--- a/tools/crm_mon.c
+++ b/tools/crm_mon.c
@@ -83,6 +83,8 @@ static gchar **processed_args = NULL;
static time_t last_refresh = 0;
crm_trigger_t *refresh_trigger = NULL;
+static gboolean on_remote_node = FALSE;
+
int interactive_fence_level = 0;
static pcmk__supported_format_t formats[] = {
@@ -988,48 +990,63 @@ pacemakerd_status(void)
}
pcmk_register_ipc_callback(pacemakerd_api, pacemakerd_event_cb, (void *) &state);
rc = pcmk_connect_ipc(pacemakerd_api, pcmk_ipc_dispatch_poll);
- if (rc == pcmk_rc_ok) {
- rc = pcmk_pacemakerd_api_ping(pacemakerd_api, crm_system_name);
- if (rc == pcmk_rc_ok) {
- rc = pcmk_poll_ipc(pacemakerd_api, options.reconnect_msec/2);
+ switch (rc) {
+ case pcmk_rc_ok:
+ rc = pcmk_pacemakerd_api_ping(pacemakerd_api, crm_system_name);
if (rc == pcmk_rc_ok) {
- pcmk_dispatch_ipc(pacemakerd_api);
- rc = ENOTCONN;
- if ((output_format == mon_output_console) ||
- (output_format == mon_output_plain)) {
- switch (state) {
- case pcmk_pacemakerd_state_running:
- rc = pcmk_rc_ok;
- break;
- case pcmk_pacemakerd_state_starting_daemons:
- print_as(output_format ,"Pacemaker daemons starting ...\n");
- break;
- case pcmk_pacemakerd_state_wait_for_ping:
- print_as(output_format ,"Waiting for startup-trigger from SBD ...\n");
- break;
- case pcmk_pacemakerd_state_shutting_down:
- print_as(output_format ,"Pacemaker daemons shutting down ...\n");
- break;
- case pcmk_pacemakerd_state_shutdown_complete:
- /* assuming pacemakerd doesn't dispatch any pings after entering
- * that state unless it is waiting for SBD
- */
- print_as(output_format ,"Pacemaker daemons shut down - reporting to SBD ...\n");
- break;
- default:
- break;
- }
- } else {
- switch (state) {
- case pcmk_pacemakerd_state_running:
- rc = pcmk_rc_ok;
- break;
- default:
- break;
+ rc = pcmk_poll_ipc(pacemakerd_api, options.reconnect_msec/2);
+ if (rc == pcmk_rc_ok) {
+ pcmk_dispatch_ipc(pacemakerd_api);
+ rc = ENOTCONN;
+ if ((output_format == mon_output_console) ||
+ (output_format == mon_output_plain)) {
+ switch (state) {
+ case pcmk_pacemakerd_state_running:
+ rc = pcmk_rc_ok;
+ break;
+ case pcmk_pacemakerd_state_starting_daemons:
+ print_as(output_format ,"Pacemaker daemons starting ...\n");
+ break;
+ case pcmk_pacemakerd_state_wait_for_ping:
+ print_as(output_format ,"Waiting for startup-trigger from SBD ...\n");
+ break;
+ case pcmk_pacemakerd_state_shutting_down:
+ print_as(output_format ,"Pacemaker daemons shutting down ...\n");
+ break;
+ case pcmk_pacemakerd_state_shutdown_complete:
+ /* assuming pacemakerd doesn't dispatch any pings after entering
+ * that state unless it is waiting for SBD
+ */
+ print_as(output_format ,"Pacemaker daemons shut down - reporting to SBD ...\n");
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (state) {
+ case pcmk_pacemakerd_state_running:
+ rc = pcmk_rc_ok;
+ break;
+ default:
+ break;
+ }
}
}
}
- }
+ break;
+ case EREMOTEIO:
+ rc = pcmk_rc_ok;
+ on_remote_node = TRUE;
+#if CURSES_ENABLED
+ /* just show this if refresh is gonna remove all traces */
+ if (output_format == mon_output_console) {
+ print_as(output_format ,
+ "Running on remote-node waiting to be connected by cluster ...\n");
+ }
+#endif
+ break;
+ default:
+ break;
}
pcmk_free_ipc_api(pacemakerd_api);
/* returning with ENOTCONN triggers a retry */
@@ -1348,7 +1365,11 @@ handle_connection_failures(int rc)
pcmk_rc_str(rc));
rc = MON_STATUS_CRIT;
} else if (rc == ENOTCONN) {
- g_set_error(&error, PCMK__EXITC_ERROR, CRM_EX_ERROR, "Error: cluster is not available on this node");
+ if (on_remote_node) {
+ g_set_error(&error, PCMK__EXITC_ERROR, CRM_EX_ERROR, "Error: remote-node not connected to cluster");
+ } else {
+ g_set_error(&error, PCMK__EXITC_ERROR, CRM_EX_ERROR, "Error: cluster is not available on this node");
+ }
rc = pcmk_rc2exitc(rc);
} else {
g_set_error(&error, PCMK__EXITC_ERROR, CRM_EX_ERROR, "Connection to cluster failed: %s", pcmk_rc_str(rc));
--
1.8.3.1

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,62 +0,0 @@
From 98589d8e1ef9b57d806702b9968ff7e5560e9c8f Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Fri, 12 Feb 2021 11:51:16 -0500
Subject: [PATCH] Low: Fix a problem with crm_resource exit code handling.
If no output is produced but an error message is printed (like, when an
inactive resource is provided on the command line), don't print the
error message for the pcmk_rc_no_output error code. It's weird to see
output and a message about no output at the same time.
Similarly, don't print an "Error: OK" message when usage is printed.
---
tools/crm_resource.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/tools/crm_resource.c b/tools/crm_resource.c
index 7d2f0f6..29b0a04 100644
--- a/tools/crm_resource.c
+++ b/tools/crm_resource.c
@@ -1534,9 +1534,9 @@ main(int argc, char **argv)
rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
if (rc != pcmk_rc_ok) {
- fprintf(stderr, "Error creating output format %s: %s\n",
- args->output_ty, pcmk_rc_str(rc));
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;
}
@@ -2039,7 +2039,12 @@ main(int argc, char **argv)
*/
done:
- if (rc != pcmk_rc_ok) {
+ /* Don't do any of this for pcmk_rc_no_output (doesn't make sense to show an
+ * error message for no output) or for CRM_EX_USAGE (we don't want to show
+ * an "error: OK" message from pcmk_rc_str).
+ */
+ if ((rc != pcmk_rc_ok && rc != pcmk_rc_no_output) ||
+ (exit_code != CRM_EX_OK && exit_code != CRM_EX_USAGE)) {
if (rc == pcmk_rc_no_quorum) {
g_prefix_error(&error, "To ignore quorum, use the force option.\n");
}
@@ -2054,10 +2059,10 @@ done:
g_set_error(&error, PCMK__RC_ERROR, rc,
"Error performing operation: %s", pcmk_rc_str(rc));
}
+ }
- if (exit_code == CRM_EX_OK) {
- exit_code = pcmk_rc2exitc(rc);
- }
+ if (exit_code == CRM_EX_OK) {
+ exit_code = pcmk_rc2exitc(rc);
}
g_free(options.host_uname);
--
1.8.3.1

View File

@ -1,36 +0,0 @@
From 34b2d8ab82dcdf49535c74e6a580240455498759 Mon Sep 17 00:00:00 2001
From: Klaus Wenninger <klaus.wenninger@aon.at>
Date: Wed, 2 Dec 2020 22:51:33 +0100
Subject: [PATCH] default to syncing with sbd
---
lib/common/watchdog.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/lib/common/watchdog.c b/lib/common/watchdog.c
index 03ee7f1..bf5df18 100644
--- a/lib/common/watchdog.c
+++ b/lib/common/watchdog.c
@@ -244,12 +244,16 @@ pcmk__get_sbd_timeout(void)
bool
pcmk__get_sbd_sync_resource_startup(void)
{
- static bool sync_resource_startup = false;
+ static bool sync_resource_startup = true; // default overruled by env
static bool checked_sync_resource_startup = false;
if (!checked_sync_resource_startup) {
- sync_resource_startup =
- crm_is_true(getenv("SBD_SYNC_RESOURCE_STARTUP"));
+ gboolean ret = FALSE;
+ const char *s = getenv("SBD_SYNC_RESOURCE_STARTUP");
+
+ if ((s != NULL) && (crm_str_to_boolean(s, &ret) > 0)) {
+ sync_resource_startup = ret;
+ }
checked_sync_resource_startup = true;
}
--
1.8.3.1

View File

@ -19,20 +19,35 @@
## GitHub entity that distributes source (for ease of using a fork)
%global github_owner ClusterLabs
## 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/
%else
%if 0%{?fedora}
%global bug_url https://bugz.fedoraproject.org/%{name}
%endif
%endif
## What to use as the OCF resource agent root directory
%global ocf_root %{_prefix}/lib/ocf
## 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.0.5
%global pcmkversion 2.1.0
%global specversion 8
## Upstream commit (full commit ID, abbreviated commit ID, or tag) to build
%global commit ba59be71228fed04f78ab374dfac748d314d0e89
%global commit 7c3f660707a495a1331716ad32cd3ac9d9f8ff58
## 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.
%if (0%{?fedora} >= 26) || (0%{?rhel} >= 9)
%global commit_abbrev 9
%else
%global commit_abbrev 7
## Python major version to use (2, 3, or 0 for auto-detect)
%global python_major 0
%endif
## Nagios source control identifiers
%global nagios_name nagios-agents-metadata
@ -45,7 +60,7 @@
## Add option to enable support for stonith/external fencing agents
%bcond_with stonithd
## Add option to disable support for storing sensitive information outside CIB
## Add option for whether to support storing sensitive information outside CIB
%bcond_without cibsecrets
## Add option to create binaries suitable for use with profiling tools
@ -54,8 +69,22 @@
## Add option to create binaries with coverage analysis
%bcond_with coverage
## Add option to generate documentation (requires Publican, Asciidoc and Inkscape)
## Add option to skip (or enable, on RHEL) generating documentation
## (the build tools aren't available everywhere)
%if 0%{?rhel}
%bcond_with doc
%else
%bcond_without doc
%endif
## Add option to default to start-up synchronization with SBD.
##
## If enabled, SBD *MUST* be built to default similarly, otherwise data
## corruption could occur. Building both Pacemaker and SBD to default
## to synchronization improves safety, without requiring higher-level tools
## to be aware of the setting or requiring users to modify configurations
## after upgrading to versions that support synchronization.
%bcond_without sbd_sync
## Add option to prefix package version with "0."
## (so later "official" packages will be considered updates)
@ -67,9 +96,12 @@
## Add option to turn off hardening of libraries and daemon executables
%bcond_without hardening
## Add option to disable links for legacy daemon names
## Add option to enable (or disable, on RHEL 8) links for legacy daemon names
%if 0%{?rhel} && 0%{?rhel} <= 8
%bcond_without legacy_links
%else
%bcond_with legacy_links
%endif
# Define globals for convenient use later
@ -89,13 +121,9 @@
%define archive_version %(c=%{commit}; echo ${c:0:%{commit_abbrev}})
%define archive_github_url %{archive_version}#/%{name}-%{archive_version}.tar.gz
%endif
# RHEL always uses a simple release number
### Always use a simple release number
%define pcmk_release %{specversion}
## Heuristic used to infer bleeding-edge deployments that are
## less likely to have working versions of the documentation tools
%define bleeding %(test ! -e /etc/yum.repos.d/fedora-rawhide.repo; echo $?)
## Whether this platform defaults to using systemd as an init system
## (needs to be evaluated prior to BuildRequires being enumerated and
## installed as it's intended to conditionally select some of these, and
@ -122,14 +150,6 @@
%define gnutls_priorities %{?pcmk_gnutls_priorities}%{!?pcmk_gnutls_priorities:@SYSTEM}
%endif
%if !%{defined _rundir}
%if 0%{?fedora} >= 15 || 0%{?rhel} >= 7 || 0%{?suse_version} >= 1200
%define _rundir /run
%else
%define _rundir /var/run
%endif
%endif
%if 0%{?fedora} > 22 || 0%{?rhel} > 7
%global supports_recommends 1
%endif
@ -153,21 +173,31 @@
%global pkgname_gnutls_devel gnutls-devel
%global pkgname_shadow_utils shadow-utils
%global pkgname_procps procps-ng
%global pkgname_publican publican
%global pkgname_glue_libs cluster-glue-libs
%global pkgname_pcmk_libs %{name}-libs
%global hacluster_id 189
%endif
# Python-related definitions
## Distro-specific configuration choices
## Use Python 3 on certain platforms if major version not specified
%if %{?python_major} == 0
%if 0%{?fedora} > 26 || 0%{?rhel} > 7
%global python_major 3
### Use 2.0-style output when other distro packages don't support current output
%if 0%{?fedora} || ( 0%{?rhel} && 0%{?rhel} <= 8 )
%global compat20 --enable-compat-2.0
%endif
### Default concurrent-fencing to true when distro prefers that
%if 0%{?rhel} >= 7
%global concurrent_fencing --with-concurrent-fencing-default=true
%endif
### Default resource-stickiness to 1 when distro prefers that
%if 0%{?fedora} >= 35 || 0%{?rhel} >= 9
%global resource_stickiness --with-resource-stickiness-default=1
%endif
# Python-related definitions
## Turn off auto-compilation of Python files outside Python specific paths,
## so there's no risk that unexpected "__python" macro gets picked to do the
## RPM-native byte-compiling there (only "{_datadir}/pacemaker/tests" affected)
@ -181,39 +211,25 @@
sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g'; })
%endif
## Values that differ by Python major version
%if 0%{?python_major} > 2
## Prefer Python 3 definitions explicitly, in case 2 is also available
%if %{defined __python3}
%global python_name python3
%global python_path %{?__python3}%{!?__python3:/usr/bin/python%{?python3_pkgversion}%{!?python3_pkgversion:3}}
%global python_path %{__python3}
%define python_site %{?python3_sitelib}%{!?python3_sitelib:%(
%{python_path} -c 'from distutils.sysconfig import get_python_lib as gpl; print(gpl(1))' 2>/dev/null)}
%else
%if 0%{?python_major} > 1
%global python_name python2
%global python_path %{?__python2}%{!?__python2:/usr/bin/python%{?python2_pkgversion}%{!?python2_pkgversion:2}}
%define python_site %{?python2_sitelib}%{!?python2_sitelib:%(
%{python_path} -c 'from distutils.sysconfig import get_python_lib as gpl; print(gpl(1))' 2>/dev/null)}
%if %{defined python_version}
%global python_name python%(echo %{python_version} | cut -d'.' -f1)
%define python_path %{?__python}%{!?__python:/usr/bin/%{python_name}}
%else
%global python_name python
%global python_path %{?__python}%{!?__python:/usr/bin/python%{?python_pkgversion}}
%endif
%define python_site %{?python_sitelib}%{!?python_sitelib:%(
python -c 'from distutils.sysconfig import get_python_lib as gpl; print(gpl(1))' 2>/dev/null)}
%endif
%{python_name} -c 'from distutils.sysconfig import get_python_lib as gpl; print(gpl(1))' 2>/dev/null)}
%endif
# Definitions for backward compatibility with older RPM versions
## Ensure the license macro behaves consistently (older RPM will otherwise
## overwrite it once it encounters "License:"). Courtesy Jason Tibbitts:
## https://pkgs.fedoraproject.org/cgit/rpms/epel-rpm-macros.git/tree/macros.zzz-epel?h=el6&id=e1adcb77
%if !%{defined _licensedir}
%define description %{lua:
rpm.define("license %doc")
print("%description")
}
%endif
# Keep sane profiling data if requested
%if %{with profiling}
@ -234,7 +250,6 @@ License: GPLv2+ and LGPLv2+
License: GPLv2+ and LGPLv2+ and BSD
%endif
Url: https://www.clusterlabs.org/
Group: System Environment/Daemons
# Example: https://codeload.github.com/ClusterLabs/pacemaker/tar.gz/e91769e
# will download pacemaker-e91769e.tar.gz
@ -248,47 +263,29 @@ Source0: https://codeload.github.com/%{github_owner}/%{name}/tar.gz/%{arch
Source1: nagios-agents-metadata-%{nagios_hash}.tar.gz
# upstream commits
Patch1: 001-feature-set.patch
Patch2: 002-feature-set.patch
Patch3: 003-feature-set.patch
Patch4: 004-feature-set.patch
Patch5: 005-feature-set.patch
Patch6: 006-digests.patch
Patch7: 007-feature-set.patch
Patch8: 008-digests.patch
Patch9: 009-digests.patch
Patch10: 010-feature-set.patch
Patch11: 011-feature-set.patch
Patch12: 012-feature-set.patch
Patch13: 013-feature-set.patch
Patch14: 014-feature-set.patch
Patch15: 015-feature-set.patch
Patch16: 016-feature-set.patch
Patch17: 017-feature-set.patch
Patch18: 018-rhbz1907726.patch
Patch19: 019-rhbz1371576.patch
Patch20: 020-rhbz1872376.patch
Patch21: 021-rhbz1872376.patch
Patch22: 022-rhbz1872376.patch
Patch23: 023-rhbz1872376.patch
Patch24: 024-rhbz1371576.patch
Patch25: 025-feature-set.patch
Patch26: 026-tests.patch
Patch27: 027-crm_mon.patch
Patch28: 028-crm_mon.patch
Patch29: 029-crm_mon.patch
Patch30: 030-crmadmin.patch
Patch31: 031-cibsecret.patch
Patch32: 032-rhbz1898457.patch
Patch33: 033-cibsecret.patch
Patch34: 034-crm_mon.patch
Patch35: 035-crm_mon.patch
Patch36: 036-crm_resource.patch
Patch37: 037-scheduler.patch
Patch38: 038-feature-set.patch
Patch1: 001-ping-agent.patch
Patch2: 002-pacemakerd-options.patch
Patch3: 003-pacemakerd-output.patch
Patch4: 004-check-level.patch
Patch5: 005-crm_resource.patch
Patch6: 006-crm_simulate.patch
Patch7: 007-unfencing-loop.patch
Patch8: 008-dynamic-list-fencing.patch
Patch9: 009-crm_resource-messages.patch
Patch10: 010-probe-pending.patch
Patch11: 011-crm_attribute-regression.patch
Patch12: 012-string-arguments.patch
Patch13: 013-leaks.patch
Patch14: 014-str-list.patch
Patch15: 015-sbd.patch
Patch16: 016-cts.patch
Patch17: 017-watchdog-fixes.patch
Patch18: 018-controller.patch
Patch19: 019-crm_resource.patch
Patch20: 020-fence_watchdog.patch
# downstream-only commits
Patch100: 100-default-to-syncing-with-sbd.patch
#Patch1xx: 1xx-xxxx.patch
Requires: resource-agents
Requires: %{pkgname_pcmk_libs}%{?_isa} = %{version}-%{release}
@ -303,8 +300,10 @@ Requires: psmisc
%if %{defined centos}
ExclusiveArch: aarch64 i686 ppc64le s390x x86_64 %{arm}
%else
%if 0%{?rhel}
ExclusiveArch: aarch64 i686 ppc64le s390x x86_64
%endif
%endif
Requires: %{python_path}
BuildRequires: %{python_name}-devel
@ -313,18 +312,35 @@ BuildRequires: %{python_name}-devel
Requires: libqb >= 0.17.0
BuildRequires: libqb-devel >= 0.17.0
# Basics required for the build (even if usually satisfied through other BRs)
BuildRequires: coreutils findutils grep sed
# Required basic build tools
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: coreutils
BuildRequires: findutils
BuildRequires: gcc
BuildRequires: grep
BuildRequires: libtool
%if %{defined pkgname_libtool_devel}
BuildRequires: %{?pkgname_libtool_devel}
%endif
BuildRequires: make
BuildRequires: pkgconfig
BuildRequires: sed
# Required for core functionality
BuildRequires: automake autoconf gcc libtool pkgconfig %{?pkgname_libtool_devel}
BuildRequires: pkgconfig(glib-2.0) >= 2.16
BuildRequires: libxml2-devel libxslt-devel libuuid-devel
BuildRequires: pkgconfig(glib-2.0) >= 2.42
BuildRequires: libxml2-devel
BuildRequires: libxslt-devel
BuildRequires: libuuid-devel
BuildRequires: %{pkgname_bzip2_devel}
# Enables optional functionality
BuildRequires: ncurses-devel %{pkgname_docbook_xsl}
BuildRequires: help2man %{pkgname_gnutls_devel} pam-devel pkgconfig(dbus-1)
BuildRequires: pkgconfig(dbus-1)
BuildRequires: %{pkgname_docbook_xsl}
BuildRequires: %{pkgname_gnutls_devel}
BuildRequires: help2man
BuildRequires: ncurses-devel
BuildRequires: pam-devel
%if %{systemd_native}
BuildRequires: pkgconfig(systemd)
@ -340,11 +356,10 @@ BuildRequires: corosync-devel >= 2.0.0
BuildRequires: %{pkgname_glue_libs}-devel
%endif
## (note no avoiding effect when building through non-customized mock)
%if !%{bleeding}
%if %{with doc}
BuildRequires: inkscape asciidoc %{?pkgname_publican}
%endif
BuildRequires: asciidoc
BuildRequires: inkscape
BuildRequires: %{python_name}-sphinx
%endif
Provides: pcmk-cluster-manager = %{version}-%{release}
@ -368,20 +383,15 @@ when related resources fail and can be configured to periodically check
resource health.
Available rpmbuild rebuild options:
--with(out) : cibsecrets coverage doc stonithd hardening pre_release
profiling
--with(out) : cibsecrets coverage doc hardening pre_release profiling stonithd
%package cli
License: GPLv2+ and LGPLv2+
Summary: Command line tools for controlling Pacemaker clusters
Group: System Environment/Daemons
Requires: %{pkgname_pcmk_libs}%{?_isa} = %{version}-%{release}
%if 0%{?supports_recommends}
#Recommends: pcmk-cluster-manager = %{version}-%{release}
# For crm_report
Requires: tar
Requires: bzip2
%endif
Requires: perl-TimeDate
Requires: %{pkgname_procps}
Requires: psmisc
@ -398,13 +408,11 @@ be part of the cluster.
%package -n %{pkgname_pcmk_libs}
License: GPLv2+ and LGPLv2+
Summary: Core Pacemaker libraries
Group: System Environment/Daemons
Requires(pre): %{pkgname_shadow_utils}
Requires: %{name}-schemas = %{version}-%{release}
# sbd 1.4.0+ supports the libpe_status API for pe_working_set_t
# sbd 1.4.2+ supports startup/shutdown handshake via pacemakerd-api
# and handshake defaults to enabled with rhel-builds
# applying 100-default-to-syncing-with-sbd.patch
# and handshake defaults to enabled in this spec
Conflicts: sbd < 1.4.2
%description -n %{pkgname_pcmk_libs}
@ -417,7 +425,6 @@ nodes and those just running the CLI tools.
%package cluster-libs
License: GPLv2+ and LGPLv2+
Summary: Cluster Libraries used by Pacemaker
Group: System Environment/Daemons
Requires: %{pkgname_pcmk_libs}%{?_isa} = %{version}-%{release}
%description cluster-libs
@ -434,8 +441,7 @@ License: GPLv2+ and LGPLv2+
# initscript is Revised BSD
License: GPLv2+ and LGPLv2+ and BSD
%endif
Summary: Pacemaker remote daemon for non-cluster nodes
Group: System Environment/Daemons
Summary: Pacemaker remote executor daemon for non-cluster nodes
Requires: %{pkgname_pcmk_libs}%{?_isa} = %{version}-%{release}
Requires: %{name}-cli = %{version}-%{release}
Requires: resource-agents
@ -458,14 +464,18 @@ nodes not running the full corosync/cluster stack.
%package -n %{pkgname_pcmk_libs}-devel
License: GPLv2+ and LGPLv2+
Summary: Pacemaker development package
Group: Development/Libraries
Requires: %{pkgname_pcmk_libs}%{?_isa} = %{version}-%{release}
Requires: %{name}-cluster-libs%{?_isa} = %{version}-%{release}
Requires: libuuid-devel%{?_isa} %{?pkgname_libtool_devel_arch}
Requires: libxml2-devel%{?_isa} libxslt-devel%{?_isa}
Requires: %{pkgname_bzip2_devel}%{?_isa} glib2-devel%{?_isa}
Requires: libqb-devel%{?_isa}
Requires: %{pkgname_bzip2_devel}%{?_isa}
Requires: corosync-devel >= 2.0.0
Requires: glib2-devel%{?_isa}
Requires: libqb-devel%{?_isa}
%if %{defined pkgname_libtool_devel_arch}
Requires: %{?pkgname_libtool_devel_arch}
%endif
Requires: libuuid-devel%{?_isa}
Requires: libxml2-devel%{?_isa}
Requires: libxslt-devel%{?_isa}
%description -n %{pkgname_pcmk_libs}-devel
Pacemaker is an advanced, scalable High-Availability cluster resource
@ -477,7 +487,6 @@ for developing tools for Pacemaker.
%package cts
License: GPLv2+ and LGPLv2+
Summary: Test framework for cluster-related technologies like Pacemaker
Group: System Environment/Daemons
Requires: %{python_path}
Requires: %{pkgname_pcmk_libs} = %{version}-%{release}
Requires: %{name}-cli = %{version}-%{release}
@ -485,26 +494,19 @@ Requires: %{pkgname_procps}
Requires: psmisc
BuildArch: noarch
# systemd python bindings are separate package in some distros
# systemd Python bindings are a separate package in some distros
%if %{defined systemd_requires}
%if 0%{?fedora} > 22 || 0%{?rhel} > 7
Requires: %{python_name}-systemd
%else
%if 0%{?fedora} > 20 || 0%{?rhel} > 6
Requires: systemd-python
%endif
%endif
%endif
%description cts
Test framework for cluster-related technologies like Pacemaker
%package doc
License: CC-BY-SA-4.0
Summary: Documentation for Pacemaker
Group: Documentation
BuildArch: noarch
%description doc
@ -527,7 +529,6 @@ manager.
%package nagios-plugins-metadata
License: GPLv3
Summary: Pacemaker Nagios Metadata
Group: System Environment/Daemons
# NOTE below are the plugins this metadata uses.
# These packages are not requirements because RHEL does not ship these plugins.
# This metadata provides third-party support for nagios. Users may install the
@ -552,9 +553,6 @@ monitor resources.
export systemdsystemunitdir=%{?_unitdir}%{!?_unitdir:no}
# RHEL changes pacemaker's concurrent-fencing default to true
export CPPFLAGS="-DDEFAULT_CONCURRENT_FENCING_TRUE"
%if %{with hardening}
# prefer distro-provided hardening flags in case they are defined
# through _hardening_{c,ld}flags macros, configure script will
@ -572,16 +570,21 @@ export LDFLAGS_HARDENED_LIB="%{?_hardening_ldflags}"
%{configure} \
PYTHON=%{python_path} \
%{!?with_hardening: --disable-hardening} \
%{!?with_legacy_links: --disable-legacy-links} \
%{?with_legacy_links: --enable-legacy-links} \
%{?with_profiling: --with-profiling} \
%{?with_coverage: --with-coverage} \
%{?with_cibsecrets: --with-cibsecrets} \
%{!?with_doc: --with-brand=} \
%{?with_sbd_sync: --with-sbd-sync-default="true"} \
%{?gnutls_priorities: --with-gnutls-priorities="%{gnutls_priorities}"} \
%{?bug_url: --with-bug-url=%{bug_url}} \
%{?ocf_root: --with-ocfdir=%{ocf_root}} \
%{?concurrent_fencing} \
%{?resource_stickiness} \
%{?compat20} \
--disable-static \
--with-initdir=%{_initrddir} \
--with-runstatedir=%{_rundir} \
--localstatedir=%{_var} \
--with-bug-url=https://bugzilla.redhat.com/ \
--with-nagios \
--with-nagios-metadata-dir=%{_datadir}/pacemaker/nagios/plugins-metadata/ \
--with-nagios-plugin-dir=%{_libdir}/nagios/plugins/ \
@ -613,10 +616,6 @@ make install \
DESTDIR=%{buildroot} V=1 docdir=%{pcmk_docdir} \
%{?_python_bytecompile_extra:%{?py_byte_compile:am__py_compile=true}}
mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig
install -m 644 daemons/pacemakerd/pacemaker.sysconfig ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig/pacemaker
install -m 644 tools/crm_mon.sysconfig ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig/crm_mon
%if %{with upstart_job}
mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/init
install -m 644 pacemakerd/pacemaker.upstart ${RPM_BUILD_ROOT}%{_sysconfdir}/init/pacemaker.conf
@ -633,8 +632,7 @@ done
mkdir -p ${RPM_BUILD_ROOT}%{_localstatedir}/lib/rpm-state/%{name}
%endif
# Don't package static libs
find %{buildroot} -name '*.a' -type f -print0 | xargs -0 rm -f
# Don't package libtool archives
find %{buildroot} -name '*.la' -type f -print0 | xargs -0 rm -f
# Do not package these either
@ -800,14 +798,13 @@ exit 0
%exclude %{_libexecdir}/pacemaker/cts-log-watcher
%exclude %{_libexecdir}/pacemaker/cts-support
%exclude %{_sbindir}/pacemaker-remoted
%if %{with legacy_links}
%exclude %{_sbindir}/pacemaker_remoted
%endif
%exclude %{_datadir}/pacemaker/nagios
%{_libexecdir}/pacemaker/*
%{_sbindir}/crm_attribute
%{_sbindir}/crm_master
%{_sbindir}/fence_watchdog
%doc %{_mandir}/man7/pacemaker-controld.*
%doc %{_mandir}/man7/pacemaker-schedulerd.*
@ -816,6 +813,7 @@ exit 0
%doc %{_mandir}/man7/ocf_pacemaker_remote.*
%doc %{_mandir}/man8/crm_attribute.*
%doc %{_mandir}/man8/crm_master.*
%doc %{_mandir}/man8/fence_watchdog.*
%doc %{_mandir}/man8/pacemakerd.*
%doc %{_datadir}/pacemaker/alerts
@ -826,8 +824,8 @@ exit 0
%dir %attr (750, %{uname}, %{gname}) %{_var}/lib/pacemaker/cib
%dir %attr (750, %{uname}, %{gname}) %{_var}/lib/pacemaker/pengine
/usr/lib/ocf/resource.d/pacemaker/controld
/usr/lib/ocf/resource.d/pacemaker/remote
%{ocf_root}/resource.d/pacemaker/controld
%{ocf_root}/resource.d/pacemaker/remote
%if %{with upstart_job}
%config(noreplace) %{_sysconfdir}/init/pacemaker.conf
@ -874,12 +872,12 @@ exit 0
# XXX "dirname" is not owned by any prerequisite
%{_datadir}/snmp/mibs/PCMK-MIB.txt
%exclude /usr/lib/ocf/resource.d/pacemaker/controld
%exclude /usr/lib/ocf/resource.d/pacemaker/remote
%exclude %{ocf_root}/resource.d/pacemaker/controld
%exclude %{ocf_root}/resource.d/pacemaker/remote
%dir /usr/lib/ocf
%dir /usr/lib/ocf/resource.d
/usr/lib/ocf/resource.d/pacemaker
%dir %{ocf_root}
%dir %{ocf_root}/resource.d
%{ocf_root}/resource.d/pacemaker
%doc %{_mandir}/man7/*
%exclude %{_mandir}/man7/pacemaker-controld.*
@ -890,6 +888,7 @@ exit 0
%doc %{_mandir}/man8/*
%exclude %{_mandir}/man8/crm_attribute.*
%exclude %{_mandir}/man8/crm_master.*
%exclude %{_mandir}/man8/fence_watchdog.*
%exclude %{_mandir}/man8/pacemakerd.*
%exclude %{_mandir}/man8/pacemaker-remoted.*
@ -935,9 +934,7 @@ exit 0
%endif
%{_sbindir}/pacemaker-remoted
%if %{with legacy_links}
%{_sbindir}/pacemaker_remoted
%endif
%{_mandir}/man8/pacemaker-remoted.*
%license licenses/GPLv2
%doc COPYING
@ -983,8 +980,66 @@ exit 0
%license %{nagios_name}-%{nagios_hash}/COPYING
%changelog
* Fri Aug 20 2021 Ken Gaillot <kgaillot@redhat.com> - 2.1.0-8
- Fix XML issue in fence_watchdog meta-data
- Resolves: rhbz1443666
* Thu Aug 12 2021 Ken Gaillot <kgaillot@redhat.com> - 2.1.0-7
- Fix minor issue with crm_resource error message change
- Resolves: rhbz1447918
* Tue Aug 10 2021 Ken Gaillot <kgaillot@redhat.com> - 2.1.0-6
- Fix watchdog agent version information
- Ensure transient attributes are cleared when multiple nodes are lost
- Resolves: rhbz1443666
- Resolves: rhbz1986998
* Fri Aug 06 2021 Ken Gaillot <kgaillot@redhat.com> - 2.1.0-5
- Allow configuring specific nodes to use watchdog-only sbd for fencing
- Resolves: rhbz1443666
* Fri Jul 30 2021 Ken Gaillot <kgaillot@redhat.com> - 2.1.0-4
- Show better error messages in crm_resource with invalid resource types
- Avoid selecting wrong device when dynamic-list fencing is used with host map
- Do not schedule probes of unmanaged resources on pending nodes
- Fix regressions in crm_attribute and crm_master argument handling
- Resolves: rhbz1447918
- Resolves: rhbz1978010
- Resolves: rhbz1982453
- Resolves: rhbz1984120
* Tue Jun 22 2021 Ken Gaillot <kgaillot@redhat.com> - 2.1.0-3
- crm_resource now supports XML output from resource agent actions
- Correct output for crm_simulate --show-failcounts
- Avoid remote node unfencing loop
- Resolves: rhbz1644628
- Resolves: rhbz1686426
- Resolves: rhbz1961857
* Wed Jun 9 2021 Ken Gaillot <kgaillot@redhat.com> - 2.1.0-2
- Rebase on upstream 2.1.0 final release
- Correct schema for crm_resource XML output
- Resolves: rhbz1935464
- Resolves: rhbz1967087
* Thu May 20 2021 Ken Gaillot <kgaillot@redhat.com> - 2.1.0-1
- Add crm_simulate --show-attrs and --show-failcounts options
- Retry getting fence agent meta-data after initial failure
- Add debug option for more verbose ocf:pacemaker:ping logs
- Rebase on upstream 2.1.0-rc2 release
- Support OCF Resource Agent API 1.1 standard
- Fix crm_mon regression that could cause certain agents to fail at shutdown
- Allow setting OCF check level for crm_resource --validate and --force-check
- Resolves: rhbz1686426
- Resolves: rhbz1797579
- Resolves: rhbz1843177
- Resolves: rhbz1935464
- Resolves: rhbz1936696
- Resolves: rhbz1948620
- Resolves: rhbz1955792
* Mon Feb 15 2021 Ken Gaillot <kgaillot@redhat.com> - 2.0.5-8
- Route cancellations through correct node when remote connectin is moving
- Route cancellations through correct node when remote connection is moving
- Resolves: rhbz1928762
* Fri Feb 12 2021 Ken Gaillot <kgaillot@redhat.com> - 2.0.5-7