import pacemaker-2.0.5-9.el8
This commit is contained in:
parent
98caf1a2ae
commit
65c2d339aa
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,2 @@
|
||||
SOURCES/nagios-agents-metadata-105ab8a.tar.gz
|
||||
SOURCES/pacemaker-2deceaa.tar.gz
|
||||
SOURCES/pacemaker-ba59be7.tar.gz
|
||||
|
@ -1,2 +1,2 @@
|
||||
ea6c0a27fd0ae8ce02f84a11f08a0d79377041c3 SOURCES/nagios-agents-metadata-105ab8a.tar.gz
|
||||
78c94fdcf59cfb064d4433e1b8f71fd856eeec5f SOURCES/pacemaker-2deceaa.tar.gz
|
||||
268769bcd0d6c2ea2d50db92aaea0f31637775d0 SOURCES/pacemaker-ba59be7.tar.gz
|
||||
|
704
SOURCES/001-feature-set.patch
Normal file
704
SOURCES/001-feature-set.patch
Normal file
@ -0,0 +1,704 @@
|
||||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
165
SOURCES/002-feature-set.patch
Normal file
165
SOURCES/002-feature-set.patch
Normal file
@ -0,0 +1,165 @@
|
||||
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
|
||||
|
208
SOURCES/003-feature-set.patch
Normal file
208
SOURCES/003-feature-set.patch
Normal file
@ -0,0 +1,208 @@
|
||||
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
|
||||
|
@ -1,30 +0,0 @@
|
||||
From 47c3e06b098c7e148c54675588d03b4d2bea40b5 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Mon, 22 Jun 2020 16:20:01 -0400
|
||||
Subject: [PATCH] Fix: libpacemaker: Don't allow a potential NULL in a format
|
||||
string.
|
||||
|
||||
This is only tripping up F32 s390x builds, but I don't suppose there's
|
||||
any reason it couldn't come up elsewhere later.
|
||||
---
|
||||
lib/pacemaker/pcmk_sched_constraints.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/lib/pacemaker/pcmk_sched_constraints.c b/lib/pacemaker/pcmk_sched_constraints.c
|
||||
index 9c3a88d..d8c3e69 100644
|
||||
--- a/lib/pacemaker/pcmk_sched_constraints.c
|
||||
+++ b/lib/pacemaker/pcmk_sched_constraints.c
|
||||
@@ -1595,8 +1595,8 @@ custom_action_order(pe_resource_t * lh_rsc, char *lh_action_task, pe_action_t *
|
||||
order = calloc(1, sizeof(pe__ordering_t));
|
||||
|
||||
crm_trace("Creating[%d] %s %s %s - %s %s %s", data_set->order_id,
|
||||
- lh_rsc?lh_rsc->id:"NA", lh_action_task, lh_action?lh_action->uuid:"NA",
|
||||
- rh_rsc?rh_rsc->id:"NA", rh_action_task, rh_action?rh_action->uuid:"NA");
|
||||
+ lh_rsc?lh_rsc->id:"NA", lh_action_task?lh_action_task:"NA", lh_action?lh_action->uuid:"NA",
|
||||
+ rh_rsc?rh_rsc->id:"NA", rh_action_task?rh_action_task:"NA", rh_action?rh_action->uuid:"NA");
|
||||
|
||||
/* CRM_ASSERT(data_set->order_id != 291); */
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
771
SOURCES/004-feature-set.patch
Normal file
771
SOURCES/004-feature-set.patch
Normal file
@ -0,0 +1,771 @@
|
||||
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
|
||||
|
@ -1,27 +0,0 @@
|
||||
From 7ed7675615ada7d0be5654e0dcb26de60cf5b5e9 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Mon, 22 Jun 2020 20:03:56 -0500
|
||||
Subject: [PATCH] Test: scheduler: explicitly disable concurrent-fencing in
|
||||
on_fail_demote4
|
||||
|
||||
... so the expected output is the same regardless of what default the build was
|
||||
compiled with
|
||||
---
|
||||
cts/scheduler/on_fail_demote4.xml | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/cts/scheduler/on_fail_demote4.xml b/cts/scheduler/on_fail_demote4.xml
|
||||
index eb4c4cc..1082266 100644
|
||||
--- a/cts/scheduler/on_fail_demote4.xml
|
||||
+++ b/cts/scheduler/on_fail_demote4.xml
|
||||
@@ -8,6 +8,7 @@
|
||||
<nvpair id="cts-shutdown-escalation" name="shutdown-escalation" value="5min"/>
|
||||
<nvpair id="cts-batch-limit" name="batch-limit" value="10"/>
|
||||
<nvpair id="cts-dc-deadtime" name="dc-deadtime" value="5s"/>
|
||||
+ <nvpair id="cts-concurrent-fencing" name="concurrent-fencing" value="false"/>
|
||||
<nvpair id="cib-bootstrap-options-have-watchdog" name="have-watchdog" value="false"/>
|
||||
<nvpair id="cib-bootstrap-options-dc-version" name="dc-version" value="2.0.4-578.6e1b582.git.el7_8-6e1b582"/>
|
||||
<nvpair id="cib-bootstrap-options-cluster-infrastructure" name="cluster-infrastructure" value="corosync"/>
|
||||
--
|
||||
1.8.3.1
|
||||
|
210
SOURCES/005-feature-set.patch
Normal file
210
SOURCES/005-feature-set.patch
Normal file
@ -0,0 +1,210 @@
|
||||
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
|
||||
|
@ -1,32 +0,0 @@
|
||||
From 85040eb19b9405464b01a7e67eb6769d2a03c611 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Fri, 19 Jun 2020 17:49:22 -0500
|
||||
Subject: [PATCH] Doc: sysconfig: remove outdated reference to wildcards in
|
||||
PCMK_trace_files
|
||||
|
||||
Wildcards stopped working when the log filtering implementation changed in
|
||||
1.1.8 to support PCMK_trace_tags. It's not worth the effort to fix at this
|
||||
point, so just update the comment in the sysconfig file.
|
||||
---
|
||||
daemons/pacemakerd/pacemaker.sysconfig | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/daemons/pacemakerd/pacemaker.sysconfig b/daemons/pacemakerd/pacemaker.sysconfig
|
||||
index c7745d8..e4a5c4d 100644
|
||||
--- a/daemons/pacemakerd/pacemaker.sysconfig
|
||||
+++ b/daemons/pacemakerd/pacemaker.sysconfig
|
||||
@@ -34,9 +34,8 @@
|
||||
# Log all messages from a comma-separated list of functions.
|
||||
# PCMK_trace_functions=function1,function2,function3
|
||||
|
||||
-# Log all messages from a comma-separated list of files (no path).
|
||||
-# Wildcards are supported, e.g. PCMK_trace_files=prefix*.c
|
||||
-# PCMK_trace_files=file.c,other.h
|
||||
+# Log all messages from a comma-separated list of file names (without path).
|
||||
+# PCMK_trace_files=file1.c,file2.c
|
||||
|
||||
# Log all messages matching comma-separated list of formats.
|
||||
# PCMK_trace_formats="Sent delete %d"
|
||||
--
|
||||
1.8.3.1
|
||||
|
7903
SOURCES/006-digests.patch
Normal file
7903
SOURCES/006-digests.patch
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
5949
SOURCES/007-feature-set.patch
Normal file
5949
SOURCES/007-feature-set.patch
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,685 +0,0 @@
|
||||
From e01a1178fd8f5b99895683b3af9998e9485d12a4 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Fri, 24 Apr 2020 16:42:02 -0500
|
||||
Subject: [PATCH 1/3] Feature: controller: add new IPC API command for getting
|
||||
node list
|
||||
|
||||
This is based on and will replace the corresponding functionality in
|
||||
pacemakerd.
|
||||
---
|
||||
daemons/controld/controld_messages.c | 44 ++++++++++++++++++++++++++++--
|
||||
include/crm/common/ipc_controld.h | 13 +++++++++
|
||||
include/crm_internal.h | 1 +
|
||||
lib/common/ipc_controld.c | 53 ++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 109 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/daemons/controld/controld_messages.c b/daemons/controld/controld_messages.c
|
||||
index 0be04d0..423f006 100644
|
||||
--- a/daemons/controld/controld_messages.c
|
||||
+++ b/daemons/controld/controld_messages.c
|
||||
@@ -375,10 +375,11 @@ relay_message(xmlNode * msg, gboolean originated_locally)
|
||||
is_local = 0;
|
||||
|
||||
} else if (is_for_crm) {
|
||||
- if (safe_str_eq(task, CRM_OP_NODE_INFO)) {
|
||||
+ if (safe_str_eq(task, CRM_OP_NODE_INFO)
|
||||
+ || safe_str_eq(task, PCMK__CONTROLD_CMD_NODES)) {
|
||||
/* Node info requests do not specify a host, which is normally
|
||||
* treated as "all hosts", because the whole point is that the
|
||||
- * client doesn't know the local node name. Always handle these
|
||||
+ * client may not know the local node name. Always handle these
|
||||
* requests locally.
|
||||
*/
|
||||
is_local = 1;
|
||||
@@ -784,6 +785,42 @@ handle_ping(xmlNode *msg)
|
||||
}
|
||||
|
||||
/*!
|
||||
+ * \brief Handle a PCMK__CONTROLD_CMD_NODES message
|
||||
+ *
|
||||
+ * \return Next FSA input
|
||||
+ */
|
||||
+static enum crmd_fsa_input
|
||||
+handle_node_list(xmlNode *request)
|
||||
+{
|
||||
+ GHashTableIter iter;
|
||||
+ crm_node_t *node = NULL;
|
||||
+ xmlNode *reply = NULL;
|
||||
+ xmlNode *reply_data = NULL;
|
||||
+
|
||||
+ // Create message data for reply
|
||||
+ reply_data = create_xml_node(NULL, XML_CIB_TAG_NODES);
|
||||
+ g_hash_table_iter_init(&iter, crm_peer_cache);
|
||||
+ while (g_hash_table_iter_next(&iter, NULL, (gpointer *) & node)) {
|
||||
+ xmlNode *xml = create_xml_node(reply_data, XML_CIB_TAG_NODE);
|
||||
+
|
||||
+ crm_xml_add_ll(xml, XML_ATTR_ID, (long long) node->id); // uint32_t
|
||||
+ crm_xml_add(xml, XML_ATTR_UNAME, node->uname);
|
||||
+ crm_xml_add(xml, XML_NODE_IN_CLUSTER, node->state);
|
||||
+ }
|
||||
+
|
||||
+ // Create and send reply
|
||||
+ reply = create_reply(request, reply_data);
|
||||
+ free_xml(reply_data);
|
||||
+ if (reply) {
|
||||
+ (void) relay_message(reply, TRUE);
|
||||
+ free_xml(reply);
|
||||
+ }
|
||||
+
|
||||
+ // Nothing further to do
|
||||
+ return I_NULL;
|
||||
+}
|
||||
+
|
||||
+/*!
|
||||
* \brief Handle a CRM_OP_NODE_INFO request
|
||||
*
|
||||
* \param[in] msg Message XML
|
||||
@@ -1080,6 +1117,9 @@ handle_request(xmlNode *stored_msg, enum crmd_fsa_cause cause)
|
||||
|
||||
remote_ra_process_maintenance_nodes(xml);
|
||||
|
||||
+ } else if (strcmp(op, PCMK__CONTROLD_CMD_NODES) == 0) {
|
||||
+ return handle_node_list(stored_msg);
|
||||
+
|
||||
/*========== (NOT_DC)-Only Actions ==========*/
|
||||
} else if (!AM_I_DC) {
|
||||
|
||||
diff --git a/include/crm/common/ipc_controld.h b/include/crm/common/ipc_controld.h
|
||||
index 0ebabfc..b817357 100644
|
||||
--- a/include/crm/common/ipc_controld.h
|
||||
+++ b/include/crm/common/ipc_controld.h
|
||||
@@ -22,6 +22,7 @@ extern "C" {
|
||||
*/
|
||||
|
||||
#include <stdbool.h> // bool
|
||||
+#include <glib.h> // GList
|
||||
#include <libxml/tree.h> // xmlNode
|
||||
#include <crm/common/ipc.h> // pcmk_ipc_api_t
|
||||
|
||||
@@ -32,8 +33,16 @@ enum pcmk_controld_api_reply {
|
||||
pcmk_controld_reply_info,
|
||||
pcmk_controld_reply_resource,
|
||||
pcmk_controld_reply_ping,
|
||||
+ pcmk_controld_reply_nodes,
|
||||
};
|
||||
|
||||
+// Node information passed with pcmk_controld_reply_nodes
|
||||
+typedef struct {
|
||||
+ uint32_t id;
|
||||
+ const char *uname;
|
||||
+ const char *state;
|
||||
+} pcmk_controld_api_node_t;
|
||||
+
|
||||
/*!
|
||||
* Controller reply passed to event callback
|
||||
*
|
||||
@@ -72,6 +81,9 @@ typedef struct {
|
||||
const char *fsa_state;
|
||||
const char *result;
|
||||
} ping;
|
||||
+
|
||||
+ // pcmk_controld_reply_nodes
|
||||
+ GList *nodes; // list of pcmk_controld_api_node_t *
|
||||
} data;
|
||||
} pcmk_controld_api_reply_t;
|
||||
|
||||
@@ -88,6 +100,7 @@ int pcmk_controld_api_refresh(pcmk_ipc_api_t *api, const char *target_node,
|
||||
const char *provider, const char *type,
|
||||
bool cib_only);
|
||||
int pcmk_controld_api_ping(pcmk_ipc_api_t *api, const char *node_name);
|
||||
+int pcmk_controld_api_list_nodes(pcmk_ipc_api_t *api);
|
||||
int pcmk_controld_api_shutdown(pcmk_ipc_api_t *api, const char *node_name);
|
||||
int pcmk_controld_api_start_election(pcmk_ipc_api_t *api);
|
||||
unsigned int pcmk_controld_api_replies_expected(pcmk_ipc_api_t *api);
|
||||
diff --git a/include/crm_internal.h b/include/crm_internal.h
|
||||
index fd56fc6..cf8999f 100644
|
||||
--- a/include/crm_internal.h
|
||||
+++ b/include/crm_internal.h
|
||||
@@ -122,6 +122,7 @@ pid_t pcmk_locate_sbd(void);
|
||||
#define PCMK__ATTRD_CMD_SYNC_RESPONSE "sync-response"
|
||||
#define PCMK__ATTRD_CMD_CLEAR_FAILURE "clear-failure"
|
||||
|
||||
+#define PCMK__CONTROLD_CMD_NODES "list-nodes"
|
||||
|
||||
/*
|
||||
* Environment variables used by Pacemaker
|
||||
diff --git a/lib/common/ipc_controld.c b/lib/common/ipc_controld.c
|
||||
index 22bb733..a733dd3 100644
|
||||
--- a/lib/common/ipc_controld.c
|
||||
+++ b/lib/common/ipc_controld.c
|
||||
@@ -120,6 +120,28 @@ set_ping_data(pcmk_controld_api_reply_t *data, xmlNode *msg_data)
|
||||
data->data.ping.result = crm_element_value(msg_data, XML_PING_ATTR_STATUS);
|
||||
}
|
||||
|
||||
+static void
|
||||
+set_nodes_data(pcmk_controld_api_reply_t *data, xmlNode *msg_data)
|
||||
+{
|
||||
+ pcmk_controld_api_node_t *node_info;
|
||||
+
|
||||
+ data->reply_type = pcmk_controld_reply_nodes;
|
||||
+ for (xmlNode *node = first_named_child(msg_data, XML_CIB_TAG_NODE);
|
||||
+ node != NULL; node = crm_next_same_xml(node)) {
|
||||
+
|
||||
+ long long id_ll = 0;
|
||||
+
|
||||
+ node_info = calloc(1, sizeof(pcmk_controld_api_node_t));
|
||||
+ crm_element_value_ll(node, XML_ATTR_ID, &id_ll);
|
||||
+ if (id_ll > 0) {
|
||||
+ node_info->id = id_ll;
|
||||
+ }
|
||||
+ node_info->uname = crm_element_value(node, XML_ATTR_UNAME);
|
||||
+ node_info->state = crm_element_value(node, XML_NODE_IN_CLUSTER);
|
||||
+ data->data.nodes = g_list_prepend(data->data.nodes, node_info);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static bool
|
||||
reply_expected(pcmk_ipc_api_t *api, xmlNode *request)
|
||||
{
|
||||
@@ -201,6 +223,9 @@ dispatch(pcmk_ipc_api_t *api, xmlNode *reply)
|
||||
} else if (!strcmp(value, CRM_OP_PING)) {
|
||||
set_ping_data(&reply_data, msg_data);
|
||||
|
||||
+ } else if (!strcmp(value, PCMK__CONTROLD_CMD_NODES)) {
|
||||
+ set_nodes_data(&reply_data, msg_data);
|
||||
+
|
||||
} else {
|
||||
crm_debug("Unrecognizable controller message: unknown command '%s'",
|
||||
value);
|
||||
@@ -210,6 +235,11 @@ dispatch(pcmk_ipc_api_t *api, xmlNode *reply)
|
||||
}
|
||||
|
||||
pcmk__call_ipc_callback(api, pcmk_ipc_event_reply, status, &reply_data);
|
||||
+
|
||||
+ // Free any reply data that was allocated
|
||||
+ if (safe_str_eq(value, PCMK__CONTROLD_CMD_NODES)) {
|
||||
+ g_list_free_full(reply_data.data.nodes, free);
|
||||
+ }
|
||||
}
|
||||
|
||||
pcmk__ipc_methods_t *
|
||||
@@ -376,6 +406,29 @@ pcmk_controld_api_ping(pcmk_ipc_api_t *api, const char *node_name)
|
||||
}
|
||||
|
||||
/*!
|
||||
+ * \brief Ask the controller for cluster information
|
||||
+ *
|
||||
+ * \param[in] api Controller connection
|
||||
+ *
|
||||
+ * \return Standard Pacemaker return code
|
||||
+ * \note Event callback will get a reply of type pcmk_controld_reply_nodes.
|
||||
+ */
|
||||
+int
|
||||
+pcmk_controld_api_list_nodes(pcmk_ipc_api_t *api)
|
||||
+{
|
||||
+ xmlNode *request;
|
||||
+ int rc = EINVAL;
|
||||
+
|
||||
+ request = create_controller_request(api, PCMK__CONTROLD_CMD_NODES, NULL,
|
||||
+ NULL);
|
||||
+ if (request != NULL) {
|
||||
+ rc = send_controller_request(api, request, true);
|
||||
+ free_xml(request);
|
||||
+ }
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/*!
|
||||
* \internal
|
||||
* \brief Ask the controller to shut down
|
||||
*
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
From 74e2d8d18bf534c1ec6f0e0f44a90772d393a553 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Thu, 2 Jul 2020 11:51:56 -0500
|
||||
Subject: [PATCH 2/3] Refactor: functionize numeric comparisons of strings
|
||||
|
||||
This moves the guts of sort_node_uname() from libpe_status to a new function,
|
||||
pcmk_numeric_strcasecmp(), in libcrmcommon, so it can be used with strings and
|
||||
not just pe_node_t objects.
|
||||
---
|
||||
include/crm/common/util.h | 1 +
|
||||
lib/common/strings.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
lib/pengine/utils.c | 50 ++----------------------------------
|
||||
3 files changed, 68 insertions(+), 48 deletions(-)
|
||||
|
||||
diff --git a/include/crm/common/util.h b/include/crm/common/util.h
|
||||
index 67d74d2..bb97b0a 100644
|
||||
--- a/include/crm/common/util.h
|
||||
+++ b/include/crm/common/util.h
|
||||
@@ -59,6 +59,7 @@ gboolean crm_strcase_equal(gconstpointer a, gconstpointer b);
|
||||
char *crm_strdup_printf(char const *format, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
|
||||
int pcmk__parse_ll_range(const char *srcstring, long long *start, long long *end);
|
||||
gboolean pcmk__str_in_list(GList *lst, const gchar *s);
|
||||
+int pcmk_numeric_strcasecmp(const char *s1, const char *s2);
|
||||
|
||||
# define safe_str_eq(a, b) crm_str_eq(a, b, FALSE)
|
||||
# define crm_str_hash g_str_hash_traditional
|
||||
diff --git a/lib/common/strings.c b/lib/common/strings.c
|
||||
index 4562738..bd68ccf 100644
|
||||
--- a/lib/common/strings.c
|
||||
+++ b/lib/common/strings.c
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
+#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <bzlib.h>
|
||||
#include <sys/types.h>
|
||||
@@ -715,3 +716,67 @@ pcmk__str_none_of(const char *s, ...)
|
||||
|
||||
return g_list_find_custom(lst, s, (GCompareFunc) strcmp) != NULL;
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * \brief Sort strings, with numeric portions sorted numerically
|
||||
+ *
|
||||
+ * Sort two strings case-insensitively like strcasecmp(), but with any numeric
|
||||
+ * portions of the string sorted numerically. This is particularly useful for
|
||||
+ * node names (for example, "node10" will sort higher than "node9" but lower
|
||||
+ * than "remotenode9").
|
||||
+ *
|
||||
+ * \param[in] s1 First string to compare (must not be NULL)
|
||||
+ * \param[in] s2 Second string to compare (must not be NULL)
|
||||
+ *
|
||||
+ * \retval -1 \p s1 comes before \p s2
|
||||
+ * \retval 0 \p s1 and \p s2 are equal
|
||||
+ * \retval 1 \p s1 comes after \p s2
|
||||
+ */
|
||||
+int
|
||||
+pcmk_numeric_strcasecmp(const char *s1, const char *s2)
|
||||
+{
|
||||
+ while (*s1 && *s2) {
|
||||
+ if (isdigit(*s1) && isdigit(*s2)) {
|
||||
+ // If node names contain a number, sort numerically
|
||||
+
|
||||
+ char *end1 = NULL;
|
||||
+ char *end2 = NULL;
|
||||
+ long num1 = strtol(s1, &end1, 10);
|
||||
+ long num2 = strtol(s2, &end2, 10);
|
||||
+
|
||||
+ // allow ordering e.g. 007 > 7
|
||||
+ size_t len1 = end1 - s1;
|
||||
+ size_t len2 = end2 - s2;
|
||||
+
|
||||
+ if (num1 < num2) {
|
||||
+ return -1;
|
||||
+ } else if (num1 > num2) {
|
||||
+ return 1;
|
||||
+ } else if (len1 < len2) {
|
||||
+ return -1;
|
||||
+ } else if (len1 > len2) {
|
||||
+ return 1;
|
||||
+ }
|
||||
+ s1 = end1;
|
||||
+ s2 = end2;
|
||||
+ } else {
|
||||
+ // Compare non-digits case-insensitively
|
||||
+ int lower1 = tolower(*s1);
|
||||
+ int lower2 = tolower(*s2);
|
||||
+
|
||||
+ if (lower1 < lower2) {
|
||||
+ return -1;
|
||||
+ } else if (lower1 > lower2) {
|
||||
+ return 1;
|
||||
+ }
|
||||
+ ++s1;
|
||||
+ ++s2;
|
||||
+ }
|
||||
+ }
|
||||
+ if (!*s1 && *s2) {
|
||||
+ return -1;
|
||||
+ } else if (*s1 && !*s2) {
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c
|
||||
index ce3c260..584def4 100644
|
||||
--- a/lib/pengine/utils.c
|
||||
+++ b/lib/pengine/utils.c
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <crm/common/xml.h>
|
||||
#include <crm/common/util.h>
|
||||
|
||||
-#include <ctype.h>
|
||||
#include <glib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
@@ -214,53 +213,8 @@ pe__node_list2table(GList *list)
|
||||
gint
|
||||
sort_node_uname(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
- const char *name_a = ((const pe_node_t *) a)->details->uname;
|
||||
- const char *name_b = ((const pe_node_t *) b)->details->uname;
|
||||
-
|
||||
- while (*name_a && *name_b) {
|
||||
- if (isdigit(*name_a) && isdigit(*name_b)) {
|
||||
- // If node names contain a number, sort numerically
|
||||
-
|
||||
- char *end_a = NULL;
|
||||
- char *end_b = NULL;
|
||||
- long num_a = strtol(name_a, &end_a, 10);
|
||||
- long num_b = strtol(name_b, &end_b, 10);
|
||||
-
|
||||
- // allow ordering e.g. 007 > 7
|
||||
- size_t len_a = end_a - name_a;
|
||||
- size_t len_b = end_b - name_b;
|
||||
-
|
||||
- if (num_a < num_b) {
|
||||
- return -1;
|
||||
- } else if (num_a > num_b) {
|
||||
- return 1;
|
||||
- } else if (len_a < len_b) {
|
||||
- return -1;
|
||||
- } else if (len_a > len_b) {
|
||||
- return 1;
|
||||
- }
|
||||
- name_a = end_a;
|
||||
- name_b = end_b;
|
||||
- } else {
|
||||
- // Compare non-digits case-insensitively
|
||||
- int lower_a = tolower(*name_a);
|
||||
- int lower_b = tolower(*name_b);
|
||||
-
|
||||
- if (lower_a < lower_b) {
|
||||
- return -1;
|
||||
- } else if (lower_a > lower_b) {
|
||||
- return 1;
|
||||
- }
|
||||
- ++name_a;
|
||||
- ++name_b;
|
||||
- }
|
||||
- }
|
||||
- if (!*name_a && *name_b) {
|
||||
- return -1;
|
||||
- } else if (*name_a && !*name_b) {
|
||||
- return 1;
|
||||
- }
|
||||
- return 0;
|
||||
+ return pcmk_numeric_strcasecmp(((const pe_node_t *) a)->details->uname,
|
||||
+ ((const pe_node_t *) b)->details->uname);
|
||||
}
|
||||
|
||||
/*!
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
From 8461509158e06365122dc741c527c83c94e966ce Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Fri, 24 Apr 2020 19:35:19 -0500
|
||||
Subject: [PATCH 3/3] Fix: tools: crm_node -l and -p now work from Pacemaker
|
||||
Remote nodes
|
||||
|
||||
crm_node now asks the controller for the cluster node list, instead of
|
||||
pacemakerd. This allows it to work from Pacemaker Remote nodes, since
|
||||
controller IPC is proxied but pacemakerd IPC is not.
|
||||
---
|
||||
tools/crm_node.c | 176 +++++++++++++++++++++----------------------------------
|
||||
1 file changed, 67 insertions(+), 109 deletions(-)
|
||||
|
||||
diff --git a/tools/crm_node.c b/tools/crm_node.c
|
||||
index 57c2ee5..146454d 100644
|
||||
--- a/tools/crm_node.c
|
||||
+++ b/tools/crm_node.c
|
||||
@@ -130,6 +130,16 @@ remove_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError *
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+static gint
|
||||
+sort_node(gconstpointer a, gconstpointer b)
|
||||
+{
|
||||
+ const pcmk_controld_api_node_t *node_a = a;
|
||||
+ const pcmk_controld_api_node_t *node_b = b;
|
||||
+
|
||||
+ return pcmk_numeric_strcasecmp((node_a->uname? node_a->uname : ""),
|
||||
+ (node_b->uname? node_b->uname : ""));
|
||||
+}
|
||||
+
|
||||
static void
|
||||
controller_event_cb(pcmk_ipc_api_t *controld_api,
|
||||
enum pcmk_ipc_event event_type, crm_exit_t status,
|
||||
@@ -157,15 +167,16 @@ controller_event_cb(pcmk_ipc_api_t *controld_api,
|
||||
crm_exit_str(status));
|
||||
goto done;
|
||||
}
|
||||
- if (reply->reply_type != pcmk_controld_reply_info) {
|
||||
- fprintf(stderr, "error: Unknown reply type %d from controller\n",
|
||||
- reply->reply_type);
|
||||
- goto done;
|
||||
- }
|
||||
|
||||
// Parse desired info from reply and display to user
|
||||
switch (options.command) {
|
||||
case 'i':
|
||||
+ if (reply->reply_type != pcmk_controld_reply_info) {
|
||||
+ fprintf(stderr,
|
||||
+ "error: Unknown reply type %d from controller\n",
|
||||
+ reply->reply_type);
|
||||
+ goto done;
|
||||
+ }
|
||||
if (reply->data.node_info.id == 0) {
|
||||
fprintf(stderr,
|
||||
"error: Controller reply did not contain node ID\n");
|
||||
@@ -177,6 +188,12 @@ controller_event_cb(pcmk_ipc_api_t *controld_api,
|
||||
|
||||
case 'n':
|
||||
case 'N':
|
||||
+ if (reply->reply_type != pcmk_controld_reply_info) {
|
||||
+ fprintf(stderr,
|
||||
+ "error: Unknown reply type %d from controller\n",
|
||||
+ reply->reply_type);
|
||||
+ goto done;
|
||||
+ }
|
||||
if (reply->data.node_info.uname == NULL) {
|
||||
fprintf(stderr, "Node is not known to cluster\n");
|
||||
exit_code = CRM_EX_NOHOST;
|
||||
@@ -186,6 +203,12 @@ controller_event_cb(pcmk_ipc_api_t *controld_api,
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
+ if (reply->reply_type != pcmk_controld_reply_info) {
|
||||
+ fprintf(stderr,
|
||||
+ "error: Unknown reply type %d from controller\n",
|
||||
+ reply->reply_type);
|
||||
+ goto done;
|
||||
+ }
|
||||
printf("%d\n", reply->data.node_info.have_quorum);
|
||||
if (!(reply->data.node_info.have_quorum)) {
|
||||
exit_code = CRM_EX_QUORUM;
|
||||
@@ -193,6 +216,36 @@ controller_event_cb(pcmk_ipc_api_t *controld_api,
|
||||
}
|
||||
break;
|
||||
|
||||
+ case 'l':
|
||||
+ case 'p':
|
||||
+ if (reply->reply_type != pcmk_controld_reply_nodes) {
|
||||
+ fprintf(stderr,
|
||||
+ "error: Unknown reply type %d from controller\n",
|
||||
+ reply->reply_type);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ reply->data.nodes = g_list_sort(reply->data.nodes, sort_node);
|
||||
+ for (GList *node_iter = reply->data.nodes;
|
||||
+ node_iter != NULL; node_iter = node_iter->next) {
|
||||
+
|
||||
+ pcmk_controld_api_node_t *node = node_iter->data;
|
||||
+ const char *uname = (node->uname? node->uname : "");
|
||||
+ const char *state = (node->state? node->state : "");
|
||||
+
|
||||
+ if (options.command == 'l') {
|
||||
+ printf("%lu %s %s\n",
|
||||
+ (unsigned long) node->id, uname, state);
|
||||
+
|
||||
+ // i.e. CRM_NODE_MEMBER, but we don't want to include cluster.h
|
||||
+ } else if (!strcmp(state, "member")) {
|
||||
+ printf("%s ", uname);
|
||||
+ }
|
||||
+ }
|
||||
+ if (options.command == 'p') {
|
||||
+ printf("\n");
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
fprintf(stderr, "internal error: Controller reply not expected\n");
|
||||
exit_code = CRM_EX_SOFTWARE;
|
||||
@@ -207,7 +260,7 @@ done:
|
||||
}
|
||||
|
||||
static void
|
||||
-run_controller_mainloop(uint32_t nodeid)
|
||||
+run_controller_mainloop(uint32_t nodeid, bool list_nodes)
|
||||
{
|
||||
pcmk_ipc_api_t *controld_api = NULL;
|
||||
int rc;
|
||||
@@ -233,7 +286,11 @@ run_controller_mainloop(uint32_t nodeid)
|
||||
return;
|
||||
}
|
||||
|
||||
- rc = pcmk_controld_api_node_info(controld_api, nodeid);
|
||||
+ if (list_nodes) {
|
||||
+ rc = pcmk_controld_api_list_nodes(controld_api);
|
||||
+ } else {
|
||||
+ rc = pcmk_controld_api_node_info(controld_api, nodeid);
|
||||
+ }
|
||||
if (rc != pcmk_rc_ok) {
|
||||
fprintf(stderr, "error: Could not ping controller: %s\n",
|
||||
pcmk_rc_str(rc));
|
||||
@@ -263,7 +320,7 @@ print_node_name(void)
|
||||
|
||||
} else {
|
||||
// Otherwise ask the controller
|
||||
- run_controller_mainloop(0);
|
||||
+ run_controller_mainloop(0, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,105 +501,6 @@ remove_node(const char *target_uname)
|
||||
exit_code = CRM_EX_OK;
|
||||
}
|
||||
|
||||
-static gint
|
||||
-compare_node_xml(gconstpointer a, gconstpointer b)
|
||||
-{
|
||||
- const char *a_name = crm_element_value((xmlNode*) a, "uname");
|
||||
- const char *b_name = crm_element_value((xmlNode*) b, "uname");
|
||||
-
|
||||
- return strcmp((a_name? a_name : ""), (b_name? b_name : ""));
|
||||
-}
|
||||
-
|
||||
-static int
|
||||
-node_mcp_dispatch(const char *buffer, ssize_t length, gpointer userdata)
|
||||
-{
|
||||
- GList *nodes = NULL;
|
||||
- xmlNode *node = NULL;
|
||||
- xmlNode *msg = string2xml(buffer);
|
||||
- const char *uname;
|
||||
- const char *state;
|
||||
-
|
||||
- if (msg == NULL) {
|
||||
- fprintf(stderr, "error: Could not understand pacemakerd response\n");
|
||||
- exit_code = CRM_EX_PROTOCOL;
|
||||
- g_main_loop_quit(mainloop);
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- crm_log_xml_trace(msg, "message");
|
||||
-
|
||||
- for (node = __xml_first_child(msg); node != NULL; node = __xml_next(node)) {
|
||||
- nodes = g_list_insert_sorted(nodes, node, compare_node_xml);
|
||||
- }
|
||||
-
|
||||
- for (GList *iter = nodes; iter; iter = iter->next) {
|
||||
- node = (xmlNode*) iter->data;
|
||||
- uname = crm_element_value(node, "uname");
|
||||
- state = crm_element_value(node, "state");
|
||||
-
|
||||
- if (options.command == 'l') {
|
||||
- int id = 0;
|
||||
-
|
||||
- crm_element_value_int(node, "id", &id);
|
||||
- printf("%d %s %s\n", id, (uname? uname : ""), (state? state : ""));
|
||||
-
|
||||
- // This is CRM_NODE_MEMBER but we don't want to include cluster header
|
||||
- } else if ((options.command == 'p') && safe_str_eq(state, "member")) {
|
||||
- printf("%s ", (uname? uname : ""));
|
||||
- }
|
||||
- }
|
||||
- if (options.command == 'p') {
|
||||
- fprintf(stdout, "\n");
|
||||
- }
|
||||
-
|
||||
- free_xml(msg);
|
||||
- exit_code = CRM_EX_OK;
|
||||
- g_main_loop_quit(mainloop);
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-lost_pacemakerd(gpointer user_data)
|
||||
-{
|
||||
- fprintf(stderr, "error: Lost connection to cluster\n");
|
||||
- exit_code = CRM_EX_DISCONNECT;
|
||||
- g_main_loop_quit(mainloop);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-run_pacemakerd_mainloop(void)
|
||||
-{
|
||||
- crm_ipc_t *ipc = NULL;
|
||||
- xmlNode *poke = NULL;
|
||||
- mainloop_io_t *source = NULL;
|
||||
-
|
||||
- struct ipc_client_callbacks ipc_callbacks = {
|
||||
- .dispatch = node_mcp_dispatch,
|
||||
- .destroy = lost_pacemakerd
|
||||
- };
|
||||
-
|
||||
- source = mainloop_add_ipc_client(CRM_SYSTEM_MCP, G_PRIORITY_DEFAULT, 0,
|
||||
- NULL, &ipc_callbacks);
|
||||
- ipc = mainloop_get_ipc_client(source);
|
||||
- if (ipc == NULL) {
|
||||
- fprintf(stderr,
|
||||
- "error: Could not connect to cluster (is it running?)\n");
|
||||
- exit_code = CRM_EX_DISCONNECT;
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- // Sending anything will get us a list of nodes
|
||||
- poke = create_xml_node(NULL, "poke");
|
||||
- crm_ipc_send(ipc, poke, 0, 0, NULL);
|
||||
- free_xml(poke);
|
||||
-
|
||||
- // Handle reply via node_mcp_dispatch()
|
||||
- mainloop = g_main_loop_new(NULL, FALSE);
|
||||
- g_main_loop_run(mainloop);
|
||||
- g_main_loop_unref(mainloop);
|
||||
- mainloop = NULL;
|
||||
-}
|
||||
-
|
||||
static GOptionContext *
|
||||
build_arg_context(pcmk__common_args_t *args, GOptionGroup *group) {
|
||||
GOptionContext *context = NULL;
|
||||
@@ -627,11 +585,11 @@ main(int argc, char **argv)
|
||||
case 'i':
|
||||
case 'q':
|
||||
case 'N':
|
||||
- run_controller_mainloop(options.nodeid);
|
||||
+ run_controller_mainloop(options.nodeid, false);
|
||||
break;
|
||||
case 'l':
|
||||
case 'p':
|
||||
- run_pacemakerd_mainloop();
|
||||
+ run_controller_mainloop(0, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
--
|
||||
1.8.3.1
|
||||
|
1764
SOURCES/008-digests.patch
Normal file
1764
SOURCES/008-digests.patch
Normal file
File diff suppressed because it is too large
Load Diff
846
SOURCES/009-digests.patch
Normal file
846
SOURCES/009-digests.patch
Normal file
@ -0,0 +1,846 @@
|
||||
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
|
||||
|
@ -1,34 +0,0 @@
|
||||
From b542a8f667002519fbc07693a796553746c43c12 Mon Sep 17 00:00:00 2001
|
||||
From: Reid Wahl <nrwahl@protonmail.com>
|
||||
Date: Sat, 11 Jul 2020 18:31:55 -0700
|
||||
Subject: [PATCH] Log: controld: Show action timer plus cluster-delay in
|
||||
action_timer cb
|
||||
|
||||
`action_timer_callback()` prints a misleading error message. If it
|
||||
times out waiting for an action result, the error message prints the
|
||||
timeout value followed by "(action timeout plus cluster-delay)".
|
||||
However, only the `action->timeout` value is displayed. `cluster-delay`
|
||||
is not added in.
|
||||
|
||||
Resolves: RHBZ#1856035
|
||||
---
|
||||
daemons/controld/controld_te_callbacks.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/daemons/controld/controld_te_callbacks.c b/daemons/controld/controld_te_callbacks.c
|
||||
index 8506f26..6ddaffe 100644
|
||||
--- a/daemons/controld/controld_te_callbacks.c
|
||||
+++ b/daemons/controld/controld_te_callbacks.c
|
||||
@@ -697,7 +697,8 @@ action_timer_callback(gpointer data)
|
||||
crm_err("Node %s did not send %s result (via %s) within %dms "
|
||||
"(action timeout plus cluster-delay)",
|
||||
(on_node? on_node : ""), (task? task : "unknown action"),
|
||||
- (via_node? via_node : "controller"), timer->timeout);
|
||||
+ (via_node? via_node : "controller"),
|
||||
+ timer->timeout + transition_graph->network_delay);
|
||||
print_action(LOG_ERR, "Aborting transition, action lost: ", timer->action);
|
||||
|
||||
timer->action->failed = TRUE;
|
||||
--
|
||||
1.8.3.1
|
||||
|
@ -1,476 +0,0 @@
|
||||
From 7056ae08bfa5cafeec9c454cb40aefa7553af6df Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Thu, 16 Jul 2020 12:53:24 -0400
|
||||
Subject: [PATCH 1/4] Fix: libcrmcommon: Set out->priv to NULL in free_priv.
|
||||
|
||||
init won't do anything if priv is not NULL, so when the private data is
|
||||
freed, also set it to NULL. This prevents segfaults when reset is
|
||||
called.
|
||||
---
|
||||
lib/common/output_html.c | 1 +
|
||||
lib/common/output_log.c | 1 +
|
||||
lib/common/output_text.c | 1 +
|
||||
lib/common/output_xml.c | 1 +
|
||||
tools/crm_mon_curses.c | 1 +
|
||||
5 files changed, 5 insertions(+)
|
||||
|
||||
diff --git a/lib/common/output_html.c b/lib/common/output_html.c
|
||||
index c8f0088..fc06641 100644
|
||||
--- a/lib/common/output_html.c
|
||||
+++ b/lib/common/output_html.c
|
||||
@@ -72,6 +72,7 @@ html_free_priv(pcmk__output_t *out) {
|
||||
g_queue_free(priv->parent_q);
|
||||
g_slist_free(priv->errors);
|
||||
free(priv);
|
||||
+ out->priv = NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
diff --git a/lib/common/output_log.c b/lib/common/output_log.c
|
||||
index 5b45ce4..0208046 100644
|
||||
--- a/lib/common/output_log.c
|
||||
+++ b/lib/common/output_log.c
|
||||
@@ -44,6 +44,7 @@ log_free_priv(pcmk__output_t *out) {
|
||||
|
||||
g_queue_free(priv->prefixes);
|
||||
free(priv);
|
||||
+ out->priv = NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
diff --git a/lib/common/output_text.c b/lib/common/output_text.c
|
||||
index 54c409a..8f15849 100644
|
||||
--- a/lib/common/output_text.c
|
||||
+++ b/lib/common/output_text.c
|
||||
@@ -43,6 +43,7 @@ text_free_priv(pcmk__output_t *out) {
|
||||
|
||||
g_queue_free(priv->parent_q);
|
||||
free(priv);
|
||||
+ out->priv = NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
diff --git a/lib/common/output_xml.c b/lib/common/output_xml.c
|
||||
index 8565bfe..858da3f 100644
|
||||
--- a/lib/common/output_xml.c
|
||||
+++ b/lib/common/output_xml.c
|
||||
@@ -54,6 +54,7 @@ xml_free_priv(pcmk__output_t *out) {
|
||||
g_queue_free(priv->parent_q);
|
||||
g_slist_free(priv->errors);
|
||||
free(priv);
|
||||
+ out->priv = NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
diff --git a/tools/crm_mon_curses.c b/tools/crm_mon_curses.c
|
||||
index d93b847..e9cc023 100644
|
||||
--- a/tools/crm_mon_curses.c
|
||||
+++ b/tools/crm_mon_curses.c
|
||||
@@ -46,6 +46,7 @@ curses_free_priv(pcmk__output_t *out) {
|
||||
|
||||
g_queue_free(priv->parent_q);
|
||||
free(priv);
|
||||
+ out->priv = NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
From 3779152993ca0e88dc407c918882568217f1b630 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Thu, 16 Jul 2020 13:50:24 -0400
|
||||
Subject: [PATCH 2/4] Fix: libcrmcommon: Make reset and finish work more
|
||||
similarly.
|
||||
|
||||
When finish is called for HTML and XML output formats, various extra
|
||||
nodes and headers are added, errors are added, etc. None of this stuff
|
||||
happens on reset. For the HTML format, this also means things like the
|
||||
CGI headers and title don't get added when reset is called. Make these
|
||||
two functions much more similar.
|
||||
|
||||
Regression in 2.0.3.
|
||||
|
||||
See: rhbz#1857728
|
||||
---
|
||||
lib/common/output_html.c | 26 ++++++++++++++++----------
|
||||
lib/common/output_xml.c | 30 ++++++++++++++++--------------
|
||||
2 files changed, 32 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/lib/common/output_html.c b/lib/common/output_html.c
|
||||
index fc06641..6127df2 100644
|
||||
--- a/lib/common/output_html.c
|
||||
+++ b/lib/common/output_html.c
|
||||
@@ -113,18 +113,11 @@ add_error_node(gpointer data, gpointer user_data) {
|
||||
}
|
||||
|
||||
static void
|
||||
-html_finish(pcmk__output_t *out, crm_exit_t exit_status, bool print, void **copy_dest) {
|
||||
+finish_reset_common(pcmk__output_t *out, crm_exit_t exit_status, bool print) {
|
||||
private_data_t *priv = out->priv;
|
||||
htmlNodePtr head_node = NULL;
|
||||
htmlNodePtr charset_node = NULL;
|
||||
|
||||
- /* If root is NULL, html_init failed and we are being called from pcmk__output_free
|
||||
- * in the pcmk__output_new path.
|
||||
- */
|
||||
- if (priv == NULL || priv->root == NULL) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
if (cgi_output && print) {
|
||||
fprintf(out->dest, "Content-Type: text/html\n\n");
|
||||
}
|
||||
@@ -174,6 +167,20 @@ html_finish(pcmk__output_t *out, crm_exit_t exit_status, bool print, void **copy
|
||||
if (print) {
|
||||
htmlDocDump(out->dest, priv->root->doc);
|
||||
}
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+html_finish(pcmk__output_t *out, crm_exit_t exit_status, bool print, void **copy_dest) {
|
||||
+ private_data_t *priv = out->priv;
|
||||
+
|
||||
+ /* If root is NULL, html_init failed and we are being called from pcmk__output_free
|
||||
+ * in the pcmk__output_new path.
|
||||
+ */
|
||||
+ if (priv == NULL || priv->root == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ finish_reset_common(out, exit_status, print);
|
||||
|
||||
if (copy_dest != NULL) {
|
||||
*copy_dest = copy_xml(priv->root);
|
||||
@@ -185,8 +192,7 @@ html_reset(pcmk__output_t *out) {
|
||||
CRM_ASSERT(out != NULL);
|
||||
|
||||
if (out->priv != NULL) {
|
||||
- private_data_t *priv = out->priv;
|
||||
- htmlDocDump(out->dest, priv->root->doc);
|
||||
+ finish_reset_common(out, CRM_EX_OK, true);
|
||||
}
|
||||
|
||||
html_free_priv(out);
|
||||
diff --git a/lib/common/output_xml.c b/lib/common/output_xml.c
|
||||
index 858da3f..b64a71d 100644
|
||||
--- a/lib/common/output_xml.c
|
||||
+++ b/lib/common/output_xml.c
|
||||
@@ -106,17 +106,10 @@ add_error_node(gpointer data, gpointer user_data) {
|
||||
}
|
||||
|
||||
static void
|
||||
-xml_finish(pcmk__output_t *out, crm_exit_t exit_status, bool print, void **copy_dest) {
|
||||
+finish_reset_common(pcmk__output_t *out, crm_exit_t exit_status, bool print) {
|
||||
xmlNodePtr node;
|
||||
private_data_t *priv = out->priv;
|
||||
|
||||
- /* If root is NULL, xml_init failed and we are being called from pcmk__output_free
|
||||
- * in the pcmk__output_new path.
|
||||
- */
|
||||
- if (priv == NULL || priv->root == NULL) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
if (legacy_xml) {
|
||||
GSList *node = priv->errors;
|
||||
|
||||
@@ -148,6 +141,20 @@ xml_finish(pcmk__output_t *out, crm_exit_t exit_status, bool print, void **copy_
|
||||
fprintf(out->dest, "%s", buf);
|
||||
free(buf);
|
||||
}
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+xml_finish(pcmk__output_t *out, crm_exit_t exit_status, bool print, void **copy_dest) {
|
||||
+ private_data_t *priv = out->priv;
|
||||
+
|
||||
+ /* If root is NULL, xml_init failed and we are being called from pcmk__output_free
|
||||
+ * in the pcmk__output_new path.
|
||||
+ */
|
||||
+ if (priv == NULL || priv->root == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ finish_reset_common(out, exit_status, print);
|
||||
|
||||
if (copy_dest != NULL) {
|
||||
*copy_dest = copy_xml(priv->root);
|
||||
@@ -156,15 +163,10 @@ xml_finish(pcmk__output_t *out, crm_exit_t exit_status, bool print, void **copy_
|
||||
|
||||
static void
|
||||
xml_reset(pcmk__output_t *out) {
|
||||
- char *buf = NULL;
|
||||
-
|
||||
CRM_ASSERT(out != NULL);
|
||||
|
||||
if (out->priv != NULL) {
|
||||
- private_data_t *priv = out->priv;
|
||||
- buf = dump_xml_formatted_with_text(priv->root);
|
||||
- fprintf(out->dest, "%s", buf);
|
||||
- free(buf);
|
||||
+ finish_reset_common(out, CRM_EX_OK, true);
|
||||
}
|
||||
|
||||
xml_free_priv(out);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
From 0f8e4ca5d9a429c934f1e91a1bdf572efd07e0db Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Thu, 16 Jul 2020 16:09:08 -0400
|
||||
Subject: [PATCH 3/4] Fix: tools, libcrmcommon: Reopen the output dest on
|
||||
reset.
|
||||
|
||||
This is needed when running crm_mon as a daemon. When we do a reset,
|
||||
we need to clear out any existing output destination and start writing
|
||||
again from the beginning. This really only matters when the destination
|
||||
is a file.
|
||||
|
||||
The extra freopen at the end of crm_mon is to handle when crm_mon is
|
||||
killed. We need to reset the output file to its beginning before
|
||||
calling finish.
|
||||
---
|
||||
lib/common/output_html.c | 3 +++
|
||||
lib/common/output_log.c | 3 +++
|
||||
lib/common/output_text.c | 3 +++
|
||||
lib/common/output_xml.c | 3 +++
|
||||
tools/crm_mon.c | 9 +++++++++
|
||||
5 files changed, 21 insertions(+)
|
||||
|
||||
diff --git a/lib/common/output_html.c b/lib/common/output_html.c
|
||||
index 6127df2..6e21031 100644
|
||||
--- a/lib/common/output_html.c
|
||||
+++ b/lib/common/output_html.c
|
||||
@@ -191,6 +191,9 @@ static void
|
||||
html_reset(pcmk__output_t *out) {
|
||||
CRM_ASSERT(out != NULL);
|
||||
|
||||
+ out->dest = freopen(NULL, "w", out->dest);
|
||||
+ CRM_ASSERT(out->dest != NULL);
|
||||
+
|
||||
if (out->priv != NULL) {
|
||||
finish_reset_common(out, CRM_EX_OK, true);
|
||||
}
|
||||
diff --git a/lib/common/output_log.c b/lib/common/output_log.c
|
||||
index 0208046..8422ac2 100644
|
||||
--- a/lib/common/output_log.c
|
||||
+++ b/lib/common/output_log.c
|
||||
@@ -72,6 +72,9 @@ static void
|
||||
log_reset(pcmk__output_t *out) {
|
||||
CRM_ASSERT(out != NULL);
|
||||
|
||||
+ out->dest = freopen(NULL, "w", out->dest);
|
||||
+ CRM_ASSERT(out->dest != NULL);
|
||||
+
|
||||
log_free_priv(out);
|
||||
log_init(out);
|
||||
}
|
||||
diff --git a/lib/common/output_text.c b/lib/common/output_text.c
|
||||
index 8f15849..2f7e5b0 100644
|
||||
--- a/lib/common/output_text.c
|
||||
+++ b/lib/common/output_text.c
|
||||
@@ -75,6 +75,9 @@ static void
|
||||
text_reset(pcmk__output_t *out) {
|
||||
CRM_ASSERT(out != NULL);
|
||||
|
||||
+ out->dest = freopen(NULL, "w", out->dest);
|
||||
+ CRM_ASSERT(out->dest != NULL);
|
||||
+
|
||||
text_free_priv(out);
|
||||
text_init(out);
|
||||
}
|
||||
diff --git a/lib/common/output_xml.c b/lib/common/output_xml.c
|
||||
index b64a71d..9f8e01b 100644
|
||||
--- a/lib/common/output_xml.c
|
||||
+++ b/lib/common/output_xml.c
|
||||
@@ -165,6 +165,9 @@ static void
|
||||
xml_reset(pcmk__output_t *out) {
|
||||
CRM_ASSERT(out != NULL);
|
||||
|
||||
+ out->dest = freopen(NULL, "w", out->dest);
|
||||
+ CRM_ASSERT(out->dest != NULL);
|
||||
+
|
||||
if (out->priv != NULL) {
|
||||
finish_reset_common(out, CRM_EX_OK, true);
|
||||
}
|
||||
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
|
||||
index b2e143b..10624c1 100644
|
||||
--- a/tools/crm_mon.c
|
||||
+++ b/tools/crm_mon.c
|
||||
@@ -2014,6 +2014,10 @@ mon_refresh_display(gpointer user_data)
|
||||
break;
|
||||
}
|
||||
|
||||
+ if (options.daemonize) {
|
||||
+ out->reset(out);
|
||||
+ }
|
||||
+
|
||||
stonith_history_free(stonith_history);
|
||||
stonith_history = NULL;
|
||||
pe_reset_working_set(mon_data_set);
|
||||
@@ -2179,6 +2183,11 @@ clean_up(crm_exit_t exit_code)
|
||||
* crm_mon to be able to do so.
|
||||
*/
|
||||
if (out != NULL) {
|
||||
+ if (options.daemonize) {
|
||||
+ out->dest = freopen(NULL, "w", out->dest);
|
||||
+ CRM_ASSERT(out->dest != NULL);
|
||||
+ }
|
||||
+
|
||||
switch (output_format) {
|
||||
case mon_output_cgi:
|
||||
case mon_output_html:
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
From b655c039414d2c7af77c3532222b04684ef1f3d0 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Fri, 17 Jul 2020 10:58:32 -0400
|
||||
Subject: [PATCH 4/4] Fix: tools: Add the http-equiv header to crm_mon at the
|
||||
right time.
|
||||
|
||||
This header is only getting added on termination, which is not a lot of
|
||||
help if you're running crm_mon in daemonize mode. Putting this header
|
||||
in at the right time requires a couple changes:
|
||||
|
||||
* pcmk__html_add_header doesn't need a parent argument. It was not
|
||||
being used in the first place.
|
||||
|
||||
* The extra_headers list in output_html.c should not be freed in the
|
||||
reset function. This means it would get freed after every time the
|
||||
daemonized output is refreshed, which means the header would have to be
|
||||
added every time too. extra_headers will now only be freed when the
|
||||
program exits. This is a behavior change, but I can't see why it's
|
||||
going to be a problem.
|
||||
|
||||
* To support that, we need to copy each item in the extra_headers list
|
||||
when it gets added to the output XML document. This prevents segfaults
|
||||
when we later free that document.
|
||||
|
||||
* handle_html_output no longer needs to exist. That function only
|
||||
existed to add the http-equiv header at the end, which is wrong.
|
||||
---
|
||||
include/crm/common/output.h | 5 ++---
|
||||
lib/common/output_html.c | 7 ++++---
|
||||
tools/crm_mon.c | 26 +++++++-------------------
|
||||
3 files changed, 13 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/include/crm/common/output.h b/include/crm/common/output.h
|
||||
index e7c9417..186bcfe 100644
|
||||
--- a/include/crm/common/output.h
|
||||
+++ b/include/crm/common/output.h
|
||||
@@ -703,15 +703,14 @@ pcmk__output_create_html_node(pcmk__output_t *out, const char *element_name, con
|
||||
* the following code would generate the tag "<meta http-equiv='refresh' content='19'>":
|
||||
*
|
||||
* \code
|
||||
- * pcmk__html_add_header(parent, "meta", "http-equiv", "refresh", "content", "19", NULL);
|
||||
+ * pcmk__html_add_header("meta", "http-equiv", "refresh", "content", "19", NULL);
|
||||
* \endcode
|
||||
*
|
||||
- * \param[in,out] parent The node that will be the parent of the new node.
|
||||
* \param[in] name The HTML tag for the new node.
|
||||
* \param[in] ... A NULL-terminated key/value list of attributes.
|
||||
*/
|
||||
void
|
||||
-pcmk__html_add_header(xmlNodePtr parent, const char *name, ...)
|
||||
+pcmk__html_add_header(const char *name, ...)
|
||||
G_GNUC_NULL_TERMINATED;
|
||||
|
||||
#ifdef __cplusplus
|
||||
diff --git a/lib/common/output_html.c b/lib/common/output_html.c
|
||||
index 6e21031..259e412 100644
|
||||
--- a/lib/common/output_html.c
|
||||
+++ b/lib/common/output_html.c
|
||||
@@ -139,7 +139,7 @@ finish_reset_common(pcmk__output_t *out, crm_exit_t exit_status, bool print) {
|
||||
|
||||
/* Add any extra header nodes the caller might have created. */
|
||||
for (int i = 0; i < g_slist_length(extra_headers); i++) {
|
||||
- xmlAddChild(head_node, g_slist_nth_data(extra_headers, i));
|
||||
+ xmlAddChild(head_node, xmlCopyNode(g_slist_nth_data(extra_headers, i), 1));
|
||||
}
|
||||
|
||||
/* Stylesheets are included two different ways. The first is via a built-in
|
||||
@@ -185,6 +185,8 @@ html_finish(pcmk__output_t *out, crm_exit_t exit_status, bool print, void **copy
|
||||
if (copy_dest != NULL) {
|
||||
*copy_dest = copy_xml(priv->root);
|
||||
}
|
||||
+
|
||||
+ g_slist_free_full(extra_headers, (GDestroyNotify) xmlFreeNode);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -199,7 +201,6 @@ html_reset(pcmk__output_t *out) {
|
||||
}
|
||||
|
||||
html_free_priv(out);
|
||||
- g_slist_free_full(extra_headers, (GDestroyNotify) xmlFreeNode);
|
||||
html_init(out);
|
||||
}
|
||||
|
||||
@@ -412,7 +413,7 @@ pcmk__output_create_html_node(pcmk__output_t *out, const char *element_name, con
|
||||
}
|
||||
|
||||
void
|
||||
-pcmk__html_add_header(xmlNodePtr parent, const char *name, ...) {
|
||||
+pcmk__html_add_header(const char *name, ...) {
|
||||
htmlNodePtr header_node;
|
||||
va_list ap;
|
||||
|
||||
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
|
||||
index 10624c1..7fd2b9c 100644
|
||||
--- a/tools/crm_mon.c
|
||||
+++ b/tools/crm_mon.c
|
||||
@@ -1346,6 +1346,12 @@ main(int argc, char **argv)
|
||||
options.mon_ops |= mon_op_print_timing | mon_op_inactive_resources;
|
||||
}
|
||||
|
||||
+ if ((output_format == mon_output_html || output_format == mon_output_cgi) &&
|
||||
+ out->dest != stdout) {
|
||||
+ pcmk__html_add_header("meta", "http-equiv", "refresh", "content",
|
||||
+ crm_itoa(options.reconnect_msec/1000), NULL);
|
||||
+ }
|
||||
+
|
||||
crm_info("Starting %s", crm_system_name);
|
||||
|
||||
if (cib) {
|
||||
@@ -2106,15 +2112,6 @@ clean_up_connections(void)
|
||||
}
|
||||
}
|
||||
|
||||
-static void
|
||||
-handle_html_output(crm_exit_t exit_code) {
|
||||
- xmlNodePtr html = NULL;
|
||||
-
|
||||
- pcmk__html_add_header(html, "meta", "http-equiv", "refresh", "content",
|
||||
- crm_itoa(options.reconnect_msec/1000), NULL);
|
||||
- out->finish(out, exit_code, true, (void **) &html);
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* De-init ncurses, disconnect from the CIB manager, disconnect fencing,
|
||||
* deallocate memory and show usage-message if requested.
|
||||
@@ -2188,16 +2185,7 @@ clean_up(crm_exit_t exit_code)
|
||||
CRM_ASSERT(out->dest != NULL);
|
||||
}
|
||||
|
||||
- switch (output_format) {
|
||||
- case mon_output_cgi:
|
||||
- case mon_output_html:
|
||||
- handle_html_output(exit_code);
|
||||
- break;
|
||||
-
|
||||
- default:
|
||||
- out->finish(out, exit_code, true, NULL);
|
||||
- break;
|
||||
- }
|
||||
+ out->finish(out, exit_code, true, NULL);
|
||||
|
||||
pcmk__output_free(out);
|
||||
pcmk__unregister_formats();
|
||||
--
|
||||
1.8.3.1
|
||||
|
26
SOURCES/010-feature-set.patch
Normal file
26
SOURCES/010-feature-set.patch
Normal file
@ -0,0 +1,26 @@
|
||||
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
|
||||
|
@ -1,270 +0,0 @@
|
||||
From 4e190ebc5460563bae2586b28afb0415f2eb3d1a Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Wed, 1 Jul 2020 20:38:16 -0500
|
||||
Subject: [PATCH 1/4] Test: CTS: libqb shared memory creates directories now
|
||||
|
||||
... so use "rm -rf" instead of "rm -f"
|
||||
---
|
||||
cts/CTS.py.in | 2 +-
|
||||
cts/CTSaudits.py | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/cts/CTS.py.in b/cts/CTS.py.in
|
||||
index c418318..091bb1f 100644
|
||||
--- a/cts/CTS.py.in
|
||||
+++ b/cts/CTS.py.in
|
||||
@@ -546,7 +546,7 @@ class ClusterManager(UserDict):
|
||||
if self.rsh(node, self.templates["StopCmd"]) == 0:
|
||||
# Make sure we can continue even if corosync leaks
|
||||
# fdata-* is the old name
|
||||
- #self.rsh(node, "rm -f /dev/shm/qb-* /dev/shm/fdata-*")
|
||||
+ #self.rsh(node, "rm -rf /dev/shm/qb-* /dev/shm/fdata-*")
|
||||
self.ShouldBeStatus[node] = "down"
|
||||
self.cluster_stable(self.Env["DeadTime"])
|
||||
return 1
|
||||
diff --git a/cts/CTSaudits.py b/cts/CTSaudits.py
|
||||
index b7e0827..cc82171 100755
|
||||
--- a/cts/CTSaudits.py
|
||||
+++ b/cts/CTSaudits.py
|
||||
@@ -233,7 +233,7 @@ class FileAudit(ClusterAudit):
|
||||
for line in lsout:
|
||||
self.CM.debug("ps[%s]: %s" % (node, line))
|
||||
|
||||
- self.CM.rsh(node, "rm -f /dev/shm/qb-*")
|
||||
+ self.CM.rsh(node, "rm -rf /dev/shm/qb-*")
|
||||
|
||||
else:
|
||||
self.CM.debug("Skipping %s" % node)
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
From 4316507d50d51c7864d8d34aac1da31a232b9f42 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Thu, 2 Jul 2020 16:09:20 -0500
|
||||
Subject: [PATCH 2/4] Test: CTS: ignore error logged by recent pcs versions
|
||||
|
||||
... because it is expected when a node is fenced, and we should already see
|
||||
pacemaker errors if a node is unexpectedly fenced
|
||||
---
|
||||
cts/patterns.py | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/cts/patterns.py b/cts/patterns.py
|
||||
index 96d6471..7eed90c 100644
|
||||
--- a/cts/patterns.py
|
||||
+++ b/cts/patterns.py
|
||||
@@ -21,6 +21,10 @@ class BasePatterns(object):
|
||||
|
||||
# Logging bug in some versions of libvirtd
|
||||
r"libvirtd.*: internal error: Failed to parse PCI config address",
|
||||
+
|
||||
+ # pcs can log this when node is fenced, but fencing is OK in some
|
||||
+ # tests (and we will catch it in pacemaker logs when not OK)
|
||||
+ r"pcs.daemon:No response from: .* request: get_configs, error:",
|
||||
]
|
||||
self.BadNews = []
|
||||
self.components = {}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
From 598ae0f65bad6ed16978d1ab6e24e8e358e0a1a4 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Thu, 2 Jul 2020 20:40:00 -0500
|
||||
Subject: [PATCH 3/4] Low: libcrmcommon: avoid assertion on controller protocol
|
||||
errors
|
||||
|
||||
Previously, after a protocol error, we would set reply to NULL and then try to
|
||||
call crm_element_value() on it, which would log an assertion.
|
||||
---
|
||||
lib/common/ipc_controld.c | 46 ++++++++++++++++++++++------------------------
|
||||
1 file changed, 22 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/lib/common/ipc_controld.c b/lib/common/ipc_controld.c
|
||||
index 5917cc5..22cb9e0 100644
|
||||
--- a/lib/common/ipc_controld.c
|
||||
+++ b/lib/common/ipc_controld.c
|
||||
@@ -187,53 +187,51 @@ dispatch(pcmk_ipc_api_t *api, xmlNode *reply)
|
||||
crm_debug("Unrecognizable controller message: invalid message type '%s'",
|
||||
crm_str(value));
|
||||
status = CRM_EX_PROTOCOL;
|
||||
- reply = NULL;
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
if (crm_element_value(reply, XML_ATTR_REFERENCE) == NULL) {
|
||||
crm_debug("Unrecognizable controller message: no reference");
|
||||
status = CRM_EX_PROTOCOL;
|
||||
- reply = NULL;
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
value = crm_element_value(reply, F_CRM_TASK);
|
||||
if (value == NULL) {
|
||||
crm_debug("Unrecognizable controller message: no command name");
|
||||
status = CRM_EX_PROTOCOL;
|
||||
- reply = NULL;
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
// Parse useful info from reply
|
||||
|
||||
- if (reply != NULL) {
|
||||
- reply_data.feature_set = crm_element_value(reply, XML_ATTR_VERSION);
|
||||
- reply_data.host_from = crm_element_value(reply, F_CRM_HOST_FROM);
|
||||
- msg_data = get_message_xml(reply, F_CRM_DATA);
|
||||
+ reply_data.feature_set = crm_element_value(reply, XML_ATTR_VERSION);
|
||||
+ reply_data.host_from = crm_element_value(reply, F_CRM_HOST_FROM);
|
||||
+ msg_data = get_message_xml(reply, F_CRM_DATA);
|
||||
|
||||
- if (!strcmp(value, CRM_OP_REPROBE)) {
|
||||
- reply_data.reply_type = pcmk_controld_reply_reprobe;
|
||||
+ if (!strcmp(value, CRM_OP_REPROBE)) {
|
||||
+ reply_data.reply_type = pcmk_controld_reply_reprobe;
|
||||
|
||||
- } else if (!strcmp(value, CRM_OP_NODE_INFO)) {
|
||||
- set_node_info_data(&reply_data, msg_data);
|
||||
+ } else if (!strcmp(value, CRM_OP_NODE_INFO)) {
|
||||
+ set_node_info_data(&reply_data, msg_data);
|
||||
|
||||
- } else if (!strcmp(value, CRM_OP_INVOKE_LRM)) {
|
||||
- reply_data.reply_type = pcmk_controld_reply_resource;
|
||||
- reply_data.data.resource.node_state = msg_data;
|
||||
+ } else if (!strcmp(value, CRM_OP_INVOKE_LRM)) {
|
||||
+ reply_data.reply_type = pcmk_controld_reply_resource;
|
||||
+ reply_data.data.resource.node_state = msg_data;
|
||||
|
||||
- } else if (!strcmp(value, CRM_OP_PING)) {
|
||||
- set_ping_data(&reply_data, msg_data);
|
||||
+ } else if (!strcmp(value, CRM_OP_PING)) {
|
||||
+ set_ping_data(&reply_data, msg_data);
|
||||
|
||||
- } else if (!strcmp(value, PCMK__CONTROLD_CMD_NODES)) {
|
||||
- set_nodes_data(&reply_data, msg_data);
|
||||
+ } else if (!strcmp(value, PCMK__CONTROLD_CMD_NODES)) {
|
||||
+ set_nodes_data(&reply_data, msg_data);
|
||||
|
||||
- } else {
|
||||
- crm_debug("Unrecognizable controller message: unknown command '%s'",
|
||||
- value);
|
||||
- status = CRM_EX_PROTOCOL;
|
||||
- reply = NULL;
|
||||
- }
|
||||
+ } else {
|
||||
+ crm_debug("Unrecognizable controller message: unknown command '%s'",
|
||||
+ value);
|
||||
+ status = CRM_EX_PROTOCOL;
|
||||
}
|
||||
|
||||
+done:
|
||||
pcmk__call_ipc_callback(api, pcmk_ipc_event_reply, status, &reply_data);
|
||||
|
||||
// Free any reply data that was allocated
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
From 5ae4101b60f8c0cd96eb2097a65a59aaa1750d73 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Fri, 17 Jul 2020 17:20:23 -0500
|
||||
Subject: [PATCH 4/4] Log: fencer: don't log assertion if unable to create full
|
||||
request reply
|
||||
|
||||
Previously, we would log an assertion and a warning if asked to create a reply
|
||||
to a NULL request. However there is a possible sequence for this to happen:
|
||||
|
||||
- Some nodes are up and some down at cluster start-up
|
||||
- One node is elected DC and schedules fencing of the down nodes
|
||||
- Fencing is initiated for one of the down nodes
|
||||
- One of the other down nodes comes up and is elected DC
|
||||
- The fencing result comes back and all peers (including new DC) are notified
|
||||
- New DC tries to create a notification for its client (the controller)
|
||||
but doesn't know anything about the initial request
|
||||
|
||||
For now, just log a warning and drop the assertion. Longer term, maybe we
|
||||
should synchronize in-flight request information when a fencer joins the
|
||||
process group.
|
||||
---
|
||||
daemons/fenced/fenced_commands.c | 55 +++++++++++++++++++++++-----------------
|
||||
1 file changed, 32 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/daemons/fenced/fenced_commands.c b/daemons/fenced/fenced_commands.c
|
||||
index 05c5437..9c27d61 100644
|
||||
--- a/daemons/fenced/fenced_commands.c
|
||||
+++ b/daemons/fenced/fenced_commands.c
|
||||
@@ -2336,22 +2336,8 @@ stonith_fence(xmlNode * msg)
|
||||
xmlNode *
|
||||
stonith_construct_reply(xmlNode * request, const char *output, xmlNode * data, int rc)
|
||||
{
|
||||
- int lpc = 0;
|
||||
xmlNode *reply = NULL;
|
||||
|
||||
- const char *name = NULL;
|
||||
- const char *value = NULL;
|
||||
-
|
||||
- const char *names[] = {
|
||||
- F_STONITH_OPERATION,
|
||||
- F_STONITH_CALLID,
|
||||
- F_STONITH_CLIENTID,
|
||||
- F_STONITH_CLIENTNAME,
|
||||
- F_STONITH_REMOTE_OP_ID,
|
||||
- F_STONITH_CALLOPTS
|
||||
- };
|
||||
-
|
||||
- crm_trace("Creating a basic reply");
|
||||
reply = create_xml_node(NULL, T_STONITH_REPLY);
|
||||
|
||||
crm_xml_add(reply, "st_origin", __FUNCTION__);
|
||||
@@ -2359,16 +2345,39 @@ stonith_construct_reply(xmlNode * request, const char *output, xmlNode * data, i
|
||||
crm_xml_add(reply, "st_output", output);
|
||||
crm_xml_add_int(reply, F_STONITH_RC, rc);
|
||||
|
||||
- CRM_CHECK(request != NULL, crm_warn("Can't create a sane reply"); return reply);
|
||||
- for (lpc = 0; lpc < DIMOF(names); lpc++) {
|
||||
- name = names[lpc];
|
||||
- value = crm_element_value(request, name);
|
||||
- crm_xml_add(reply, name, value);
|
||||
- }
|
||||
+ if (request == NULL) {
|
||||
+ /* Most likely, this is the result of a stonith operation that was
|
||||
+ * initiated before we came up. Unfortunately that means we lack enough
|
||||
+ * information to provide clients with a full result.
|
||||
+ *
|
||||
+ * @TODO Maybe synchronize this information at start-up?
|
||||
+ */
|
||||
+ crm_warn("Missing request information for client notifications for "
|
||||
+ "operation with result %d (initiated before we came up?)", rc);
|
||||
|
||||
- if (data != NULL) {
|
||||
- crm_trace("Attaching reply output");
|
||||
- add_message_xml(reply, F_STONITH_CALLDATA, data);
|
||||
+ } else {
|
||||
+ const char *name = NULL;
|
||||
+ const char *value = NULL;
|
||||
+
|
||||
+ const char *names[] = {
|
||||
+ F_STONITH_OPERATION,
|
||||
+ F_STONITH_CALLID,
|
||||
+ F_STONITH_CLIENTID,
|
||||
+ F_STONITH_CLIENTNAME,
|
||||
+ F_STONITH_REMOTE_OP_ID,
|
||||
+ F_STONITH_CALLOPTS
|
||||
+ };
|
||||
+
|
||||
+ crm_trace("Creating a result reply with%s reply output (rc=%d)",
|
||||
+ (data? "" : "out"), rc);
|
||||
+ for (int lpc = 0; lpc < DIMOF(names); lpc++) {
|
||||
+ name = names[lpc];
|
||||
+ value = crm_element_value(request, name);
|
||||
+ crm_xml_add(reply, name, value);
|
||||
+ }
|
||||
+ if (data != NULL) {
|
||||
+ add_message_xml(reply, F_STONITH_CALLDATA, data);
|
||||
+ }
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
1900
SOURCES/011-feature-set.patch
Normal file
1900
SOURCES/011-feature-set.patch
Normal file
File diff suppressed because it is too large
Load Diff
2355
SOURCES/012-feature-set.patch
Normal file
2355
SOURCES/012-feature-set.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,85 +0,0 @@
|
||||
From f7389ac6f67804f20393951462a59a0b505dfe03 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Tue, 21 Jul 2020 16:41:18 -0500
|
||||
Subject: [PATCH] Fix: executor: only send executor notifications to executor
|
||||
clients
|
||||
|
||||
This bug has existed since Pacemaker Remote was first implemented, but was
|
||||
hidden until crm_node -l/-p was recently modified to go through controller IPC,
|
||||
because other command-line IPC API clients either fire-and-forget IPC requests
|
||||
or merely count replies, rather than parse the content of replies.
|
||||
|
||||
Previously, when the executor sent notifications of results, it broadcast the
|
||||
notification to all IPC clients. Normally this behavior makes sense, but for
|
||||
the executor in particular, it may be running as pacemaker-remoted, in which
|
||||
case its IPC clients include not only clients that connected to the executor
|
||||
IPC, but clients that connected via proxy to other IPC APIs on the cluster node
|
||||
hosting the remote connection.
|
||||
|
||||
With crm_node -l/-p, this meant that it was possible for an executor API
|
||||
notification to arrive while crm_node was waiting for a controller IPC reply.
|
||||
It would not find the information it needed and would report a protocol
|
||||
violation error.
|
||||
|
||||
The fix is to send executor notifications only to executor clients.
|
||||
---
|
||||
daemons/execd/execd_commands.c | 9 +++++++++
|
||||
daemons/execd/remoted_proxy.c | 5 +++++
|
||||
include/crm/common/ipc_internal.h | 5 +++--
|
||||
3 files changed, 17 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/daemons/execd/execd_commands.c b/daemons/execd/execd_commands.c
|
||||
index aaf2976..685fcc7 100644
|
||||
--- a/daemons/execd/execd_commands.c
|
||||
+++ b/daemons/execd/execd_commands.c
|
||||
@@ -507,6 +507,15 @@ send_client_notify(gpointer key, gpointer value, gpointer user_data)
|
||||
crm_trace("Skipping notification to client without name");
|
||||
return;
|
||||
}
|
||||
+ if (is_set(client->flags, pcmk__client_to_proxy)) {
|
||||
+ /* We only want to notify clients of the executor IPC API. If we are
|
||||
+ * running as Pacemaker Remote, we may have clients proxied to other
|
||||
+ * IPC services in the cluster, so skip those.
|
||||
+ */
|
||||
+ crm_trace("Skipping executor API notification to %s IPC client",
|
||||
+ client->name);
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
rc = lrmd_server_send_notify(client, update_msg);
|
||||
if (rc == pcmk_rc_ok) {
|
||||
diff --git a/daemons/execd/remoted_proxy.c b/daemons/execd/remoted_proxy.c
|
||||
index dda7eed..5c58de4 100644
|
||||
--- a/daemons/execd/remoted_proxy.c
|
||||
+++ b/daemons/execd/remoted_proxy.c
|
||||
@@ -88,6 +88,11 @@ ipc_proxy_accept(qb_ipcs_connection_t * c, uid_t uid, gid_t gid, const char *ipc
|
||||
client->userdata = strdup(ipc_proxy->id);
|
||||
client->name = crm_strdup_printf("proxy-%s-%d-%.8s", ipc_channel, client->pid, client->id);
|
||||
|
||||
+ /* Allow remote executor to distinguish between proxied local clients and
|
||||
+ * actual executor API clients
|
||||
+ */
|
||||
+ set_bit(client->flags, pcmk__client_to_proxy);
|
||||
+
|
||||
g_hash_table_insert(ipc_clients, client->id, client);
|
||||
|
||||
msg = create_xml_node(NULL, T_LRMD_IPC_PROXY);
|
||||
diff --git a/include/crm/common/ipc_internal.h b/include/crm/common/ipc_internal.h
|
||||
index 6a1fcf3..91b3435 100644
|
||||
--- a/include/crm/common/ipc_internal.h
|
||||
+++ b/include/crm/common/ipc_internal.h
|
||||
@@ -121,8 +121,9 @@ struct pcmk__remote_s {
|
||||
};
|
||||
|
||||
enum pcmk__client_flags {
|
||||
- pcmk__client_proxied = 0x00001, /* ipc_proxy code only */
|
||||
- pcmk__client_privileged = 0x00002, /* root or cluster user */
|
||||
+ pcmk__client_proxied = (1 << 0), // Remote client behind proxy
|
||||
+ pcmk__client_privileged = (1 << 1), // root or cluster user
|
||||
+ pcmk__client_to_proxy = (1 << 2), // Local client to be proxied
|
||||
};
|
||||
|
||||
struct pcmk__client_s {
|
||||
--
|
||||
1.8.3.1
|
||||
|
2808
SOURCES/013-feature-set.patch
Normal file
2808
SOURCES/013-feature-set.patch
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
285
SOURCES/014-feature-set.patch
Normal file
285
SOURCES/014-feature-set.patch
Normal file
@ -0,0 +1,285 @@
|
||||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,123 +0,0 @@
|
||||
From 2e7a40570d6b21534ec0215ac5ebc174796cf17c Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Thu, 20 Aug 2020 10:02:20 -0500
|
||||
Subject: [PATCH 1/2] Refactor: tools: rename function in cibsecret to be more
|
||||
clear
|
||||
|
||||
It led me to initially misdiagnose a problem.
|
||||
---
|
||||
tools/cibsecret.in | 26 +++++++++++++-------------
|
||||
1 file changed, 13 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/tools/cibsecret.in b/tools/cibsecret.in
|
||||
index 9b74ba3..dabbfc0 100644
|
||||
--- a/tools/cibsecret.in
|
||||
+++ b/tools/cibsecret.in
|
||||
@@ -162,28 +162,28 @@ check_env() {
|
||||
}
|
||||
|
||||
# This must be called (and return success) before calling $rsh or $rcp_to_from
|
||||
-get_live_nodes() {
|
||||
- # Get a list of all cluster nodes
|
||||
+get_live_peers() {
|
||||
+ # Get a list of all other cluster nodes
|
||||
GLN_ALL_NODES="$(crm_node -l | awk '{print $2}' | grep -v "$(uname -n)")"
|
||||
|
||||
# Make a list of those that respond to pings
|
||||
if [ "$(id -u)" = "0" ] && which fping >/dev/null 2>&1; then
|
||||
- LIVE_NODES=$(fping -a $GLN_ALL_NODES 2>/dev/null)
|
||||
+ LIVE_NODES=$(fping -a $GLP_ALL_PEERS 2>/dev/null)
|
||||
else
|
||||
LIVE_NODES=""
|
||||
- for GLN_NODE in $GLN_ALL_NODES; do \
|
||||
- ping -c 2 -q "$GLN_NODE" >/dev/null 2>&1 &&
|
||||
- LIVE_NODES="$LIVE_NODES $GLN_NODE"
|
||||
+ for GLP_NODE in $GLP_ALL_PEERS; do \
|
||||
+ ping -c 2 -q "$GLP_NODE" >/dev/null 2>&1 &&
|
||||
+ LIVE_NODES="$LIVE_NODES $GLP_NODE"
|
||||
done
|
||||
fi
|
||||
|
||||
# Warn the user about any that didn't respond to pings
|
||||
- GLN_DOWN="$( (for GLN_NODE in $LIVE_NODES $GLN_ALL_NODES; do echo "$GLN_NODE"; done) | sort | uniq -u)"
|
||||
- if [ "$(echo "$GLN_DOWN" | wc -w)" = "1" ]; then
|
||||
- warn "node $GLN_DOWN is down"
|
||||
+ GLP_DOWN="$( (for GLP_NODE in $LIVE_NODES $GLP_ALL_PEERS; do echo "$GLP_NODE"; done) | sort | uniq -u)"
|
||||
+ if [ "$(echo "$GLP_DOWN" | wc -w)" = "1" ]; then
|
||||
+ warn "node $GLP_DOWN is down"
|
||||
warn "you'll need to update it using \"$PROG sync\" later"
|
||||
- elif [ -n "$GLN_DOWN" ]; then
|
||||
- warn "nodes $(echo "$GLN_DOWN" | tr '\n' ' ')are down"
|
||||
+ elif [ -n "$GLP_DOWN" ]; then
|
||||
+ warn "nodes $(echo "$GLP_DOWN" | tr '\n' ' ')are down"
|
||||
warn "you'll need to update them using \"$PROG sync\" later"
|
||||
fi
|
||||
|
||||
@@ -235,7 +235,7 @@ scp_fun() {
|
||||
# TODO: this procedure should be replaced with csync2
|
||||
# provided that csync2 has already been configured
|
||||
sync_files() {
|
||||
- get_live_nodes || return
|
||||
+ get_live_peers || return
|
||||
info "syncing $LRM_CIBSECRETS to $(echo "$LIVE_NODES" | tr '\n' ' ') ..."
|
||||
$rsh rm -rf "$LRM_CIBSECRETS" &&
|
||||
$rsh mkdir -p "$(dirname "$LRM_CIBSECRETS")" &&
|
||||
@@ -244,7 +244,7 @@ sync_files() {
|
||||
|
||||
sync_one() {
|
||||
SO_FILE="$1"
|
||||
- get_live_nodes || return
|
||||
+ get_live_peers || return
|
||||
info "syncing $SO_FILE to $(echo "$LIVE_NODES" | tr '\n' ' ') ..."
|
||||
$rsh mkdir -p "$(dirname "$SO_FILE")" &&
|
||||
if [ -f "$SO_FILE" ]; then
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
From 9c1517e6a681f35d62b4714e854b258c17ab5e59 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Thu, 20 Aug 2020 10:03:23 -0500
|
||||
Subject: [PATCH 2/2] Fix: tools: properly detect local node name
|
||||
|
||||
cibsecret had two serious problems when generating a list of other nodes to
|
||||
sync secrets to:
|
||||
|
||||
* It used `uname -n` to remove the local node from the list. If the local node
|
||||
name is different from its uname, this could cause local secrets to be
|
||||
removed from the local node rather than synced to other nodes.
|
||||
|
||||
* It removed not just the local node name, but any node name that contained
|
||||
the local node name as a substring (e.g. "node1" and "node10"). This could
|
||||
cause secrets to not be synced to such nodes.
|
||||
|
||||
Now, use `crm_node -n` to determine the local node name, check crm_node for
|
||||
errors to get better error messages, and remove only the node name that matches
|
||||
the local node name in its entirety.
|
||||
---
|
||||
tools/cibsecret.in | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/cibsecret.in b/tools/cibsecret.in
|
||||
index dabbfc0..568833c 100644
|
||||
--- a/tools/cibsecret.in
|
||||
+++ b/tools/cibsecret.in
|
||||
@@ -163,8 +163,14 @@ check_env() {
|
||||
|
||||
# This must be called (and return success) before calling $rsh or $rcp_to_from
|
||||
get_live_peers() {
|
||||
+ # Get local node name
|
||||
+ GLP_LOCAL_NODE="$(crm_node -n)"
|
||||
+ [ $? -eq 0 ] || fatal "couldn't get local node name"
|
||||
+
|
||||
# Get a list of all other cluster nodes
|
||||
- GLN_ALL_NODES="$(crm_node -l | awk '{print $2}' | grep -v "$(uname -n)")"
|
||||
+ GLP_ALL_PEERS="$(crm_node -l)"
|
||||
+ [ $? -eq 0 ] || fatal "couldn't determine cluster nodes"
|
||||
+ GLP_ALL_PEERS="$(echo "$GLP_ALL_PEERS" | awk '{print $2}' | 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
|
||||
|
114
SOURCES/015-feature-set.patch
Normal file
114
SOURCES/015-feature-set.patch
Normal file
@ -0,0 +1,114 @@
|
||||
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
|
||||
|
@ -1,513 +0,0 @@
|
||||
From 3aa33bcc9c70d197b5ed0760b12d65dfab4d4da5 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Fri, 9 Oct 2020 09:56:03 -0500
|
||||
Subject: [PATCH 1/7] Log: executor: show CRM_OP_REGISTER rc in debug message
|
||||
|
||||
Previously, process_lrmd_signon() would add the rc to the client reply
|
||||
but not pass it back to process_lrmd_message(), which would always log "OK" in
|
||||
its debug message, even if the sign-on was rejected.
|
||||
---
|
||||
daemons/execd/execd_commands.c | 21 +++++++++++----------
|
||||
1 file changed, 11 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/daemons/execd/execd_commands.c b/daemons/execd/execd_commands.c
|
||||
index 4d0e457..8487dd4 100644
|
||||
--- a/daemons/execd/execd_commands.c
|
||||
+++ b/daemons/execd/execd_commands.c
|
||||
@@ -1494,10 +1494,10 @@ free_rsc(gpointer data)
|
||||
free(rsc);
|
||||
}
|
||||
|
||||
-static xmlNode *
|
||||
-process_lrmd_signon(pcmk__client_t *client, xmlNode *request, int call_id)
|
||||
+static int
|
||||
+process_lrmd_signon(pcmk__client_t *client, xmlNode *request, int call_id,
|
||||
+ xmlNode **reply)
|
||||
{
|
||||
- xmlNode *reply = NULL;
|
||||
int rc = pcmk_ok;
|
||||
const char *is_ipc_provider = crm_element_value(request, F_LRMD_IS_IPC_PROVIDER);
|
||||
const char *protocol_version = crm_element_value(request, F_LRMD_PROTOCOL_VERSION);
|
||||
@@ -1508,18 +1508,19 @@ process_lrmd_signon(pcmk__client_t *client, xmlNode *request, int call_id)
|
||||
rc = -EPROTO;
|
||||
}
|
||||
|
||||
- reply = create_lrmd_reply(__FUNCTION__, rc, call_id);
|
||||
- crm_xml_add(reply, F_LRMD_OPERATION, CRM_OP_REGISTER);
|
||||
- crm_xml_add(reply, F_LRMD_CLIENTID, client->id);
|
||||
- crm_xml_add(reply, F_LRMD_PROTOCOL_VERSION, LRMD_PROTOCOL_VERSION);
|
||||
-
|
||||
if (crm_is_true(is_ipc_provider)) {
|
||||
// This is a remote connection from a cluster node's controller
|
||||
#ifdef SUPPORT_REMOTE
|
||||
ipc_proxy_add_provider(client);
|
||||
#endif
|
||||
}
|
||||
- return reply;
|
||||
+
|
||||
+ *reply = create_lrmd_reply(__func__, rc, call_id);
|
||||
+ crm_xml_add(*reply, F_LRMD_OPERATION, CRM_OP_REGISTER);
|
||||
+ crm_xml_add(*reply, F_LRMD_CLIENTID, client->id);
|
||||
+ crm_xml_add(*reply, F_LRMD_PROTOCOL_VERSION, LRMD_PROTOCOL_VERSION);
|
||||
+
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1832,7 +1833,7 @@ process_lrmd_message(pcmk__client_t *client, uint32_t id, xmlNode *request)
|
||||
#endif
|
||||
do_reply = 1;
|
||||
} else if (crm_str_eq(op, CRM_OP_REGISTER, TRUE)) {
|
||||
- reply = process_lrmd_signon(client, request, call_id);
|
||||
+ rc = process_lrmd_signon(client, request, call_id, &reply);
|
||||
do_reply = 1;
|
||||
} else if (crm_str_eq(op, LRMD_OP_RSC_REG, TRUE)) {
|
||||
rc = process_lrmd_rsc_register(client, id, request);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
From d0002343faa4595e42b790119b7f3037db1130c4 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Fri, 9 Oct 2020 15:16:39 -0500
|
||||
Subject: [PATCH 2/7] Low: executor: mark controller connections to
|
||||
pacemaker-remoted as privileged
|
||||
|
||||
Previously, pcmk__client_privileged was only set when local clients connected
|
||||
(as root or hacluster). Now, set it when pacemaker-remoted successfully
|
||||
completes the TLS handshake with a remote client (i.e., the controller on a
|
||||
cluster node).
|
||||
|
||||
This has no effect as of this commit but will with later commits.
|
||||
---
|
||||
daemons/execd/remoted_tls.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/daemons/execd/remoted_tls.c b/daemons/execd/remoted_tls.c
|
||||
index 1a1f8b2..c835549 100644
|
||||
--- a/daemons/execd/remoted_tls.c
|
||||
+++ b/daemons/execd/remoted_tls.c
|
||||
@@ -72,6 +72,11 @@ remoted__read_handshake_data(pcmk__client_t *client)
|
||||
client->remote->tls_handshake_complete = TRUE;
|
||||
crm_notice("Remote client connection accepted");
|
||||
|
||||
+ /* Only a client with access to the TLS key can connect, so we can treat
|
||||
+ * it as privileged.
|
||||
+ */
|
||||
+ set_bit(client->flags, pcmk__client_privileged);
|
||||
+
|
||||
// Alert other clients of the new connection
|
||||
notify_of_new_client(client);
|
||||
return 0;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
From 3db100d775aee214fff8f54eae0076a5fcc41c56 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Thu, 15 Oct 2020 15:33:13 -0500
|
||||
Subject: [PATCH 3/7] Low: executor: return appropriate error code when no
|
||||
remote support
|
||||
|
||||
---
|
||||
daemons/execd/execd_commands.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/daemons/execd/execd_commands.c b/daemons/execd/execd_commands.c
|
||||
index 8487dd4..41c8169 100644
|
||||
--- a/daemons/execd/execd_commands.c
|
||||
+++ b/daemons/execd/execd_commands.c
|
||||
@@ -1509,9 +1509,11 @@ process_lrmd_signon(pcmk__client_t *client, xmlNode *request, int call_id,
|
||||
}
|
||||
|
||||
if (crm_is_true(is_ipc_provider)) {
|
||||
- // This is a remote connection from a cluster node's controller
|
||||
#ifdef SUPPORT_REMOTE
|
||||
+ // This is a remote connection from a cluster node's controller
|
||||
ipc_proxy_add_provider(client);
|
||||
+#else
|
||||
+ rc = -EPROTONOSUPPORT;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1830,6 +1832,8 @@ process_lrmd_message(pcmk__client_t *client, uint32_t id, xmlNode *request)
|
||||
if (crm_str_eq(op, CRM_OP_IPC_FWD, TRUE)) {
|
||||
#ifdef SUPPORT_REMOTE
|
||||
ipc_proxy_forward_client(client, request);
|
||||
+#else
|
||||
+ rc = -EPROTONOSUPPORT;
|
||||
#endif
|
||||
do_reply = 1;
|
||||
} else if (crm_str_eq(op, CRM_OP_REGISTER, TRUE)) {
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
From f273f1c16f21ff96983797ed5ceb2978dafe545a Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Thu, 15 Oct 2020 15:33:57 -0500
|
||||
Subject: [PATCH 4/7] High: executor: restrict certain IPC requests to
|
||||
Pacemaker daemons
|
||||
|
||||
The executor IPC API allows clients to register resources, request agent
|
||||
execution, and so forth.
|
||||
|
||||
If ACLs are enabled, this could allow an ACL-restricted user to bypass ACLs and
|
||||
execute any code as root. (If ACLs are not enabled, users in the haclient group
|
||||
have full access to the CIB, which already gives them that ability, so there is
|
||||
no additional exposure in that case.)
|
||||
|
||||
When ACLs are supported, this commit effectively disables the executor IPC API
|
||||
for clients that aren't connecting as root or hacluster. Such clients can only
|
||||
register and poke now.
|
||||
---
|
||||
daemons/execd/execd_commands.c | 91 +++++++++++++++++++++++++++++++++---------
|
||||
1 file changed, 73 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/daemons/execd/execd_commands.c b/daemons/execd/execd_commands.c
|
||||
index 41c8169..207eb6a 100644
|
||||
--- a/daemons/execd/execd_commands.c
|
||||
+++ b/daemons/execd/execd_commands.c
|
||||
@@ -1510,8 +1510,12 @@ process_lrmd_signon(pcmk__client_t *client, xmlNode *request, int call_id,
|
||||
|
||||
if (crm_is_true(is_ipc_provider)) {
|
||||
#ifdef SUPPORT_REMOTE
|
||||
- // This is a remote connection from a cluster node's controller
|
||||
- ipc_proxy_add_provider(client);
|
||||
+ if ((client->remote != NULL) && client->remote->tls_handshake_complete) {
|
||||
+ // This is a remote connection from a cluster node's controller
|
||||
+ ipc_proxy_add_provider(client);
|
||||
+ } else {
|
||||
+ rc = -EACCES;
|
||||
+ }
|
||||
#else
|
||||
rc = -EPROTONOSUPPORT;
|
||||
#endif
|
||||
@@ -1826,12 +1830,26 @@ process_lrmd_message(pcmk__client_t *client, uint32_t id, xmlNode *request)
|
||||
int do_notify = 0;
|
||||
xmlNode *reply = NULL;
|
||||
|
||||
+ bool allowed = true;
|
||||
+
|
||||
+#if ENABLE_ACL
|
||||
+ /* Certain IPC commands may be done only by privileged users (i.e. root or
|
||||
+ * hacluster) when ACLs are enabled, because they would otherwise provide a
|
||||
+ * means of bypassing ACLs.
|
||||
+ */
|
||||
+ allowed = is_set(client->flags, pcmk__client_privileged);
|
||||
+#endif
|
||||
+
|
||||
crm_trace("Processing %s operation from %s", op, client->id);
|
||||
crm_element_value_int(request, F_LRMD_CALLID, &call_id);
|
||||
|
||||
if (crm_str_eq(op, CRM_OP_IPC_FWD, TRUE)) {
|
||||
#ifdef SUPPORT_REMOTE
|
||||
- ipc_proxy_forward_client(client, request);
|
||||
+ if (allowed) {
|
||||
+ ipc_proxy_forward_client(client, request);
|
||||
+ } else {
|
||||
+ rc = -EACCES;
|
||||
+ }
|
||||
#else
|
||||
rc = -EPROTONOSUPPORT;
|
||||
#endif
|
||||
@@ -1840,38 +1858,70 @@ process_lrmd_message(pcmk__client_t *client, uint32_t id, xmlNode *request)
|
||||
rc = process_lrmd_signon(client, request, call_id, &reply);
|
||||
do_reply = 1;
|
||||
} else if (crm_str_eq(op, LRMD_OP_RSC_REG, TRUE)) {
|
||||
- rc = process_lrmd_rsc_register(client, id, request);
|
||||
- do_notify = 1;
|
||||
+ if (allowed) {
|
||||
+ rc = process_lrmd_rsc_register(client, id, request);
|
||||
+ do_notify = 1;
|
||||
+ } else {
|
||||
+ rc = -EACCES;
|
||||
+ }
|
||||
do_reply = 1;
|
||||
} else if (crm_str_eq(op, LRMD_OP_RSC_INFO, TRUE)) {
|
||||
- reply = process_lrmd_get_rsc_info(request, call_id);
|
||||
+ if (allowed) {
|
||||
+ reply = process_lrmd_get_rsc_info(request, call_id);
|
||||
+ } else {
|
||||
+ rc = -EACCES;
|
||||
+ }
|
||||
do_reply = 1;
|
||||
} else if (crm_str_eq(op, LRMD_OP_RSC_UNREG, TRUE)) {
|
||||
- rc = process_lrmd_rsc_unregister(client, id, request);
|
||||
- /* don't notify anyone about failed un-registers */
|
||||
- if (rc == pcmk_ok || rc == -EINPROGRESS) {
|
||||
- do_notify = 1;
|
||||
+ if (allowed) {
|
||||
+ rc = process_lrmd_rsc_unregister(client, id, request);
|
||||
+ /* don't notify anyone about failed un-registers */
|
||||
+ if (rc == pcmk_ok || rc == -EINPROGRESS) {
|
||||
+ do_notify = 1;
|
||||
+ }
|
||||
+ } else {
|
||||
+ rc = -EACCES;
|
||||
}
|
||||
do_reply = 1;
|
||||
} else if (crm_str_eq(op, LRMD_OP_RSC_EXEC, TRUE)) {
|
||||
- rc = process_lrmd_rsc_exec(client, id, request);
|
||||
+ if (allowed) {
|
||||
+ rc = process_lrmd_rsc_exec(client, id, request);
|
||||
+ } else {
|
||||
+ rc = -EACCES;
|
||||
+ }
|
||||
do_reply = 1;
|
||||
} else if (crm_str_eq(op, LRMD_OP_RSC_CANCEL, TRUE)) {
|
||||
- rc = process_lrmd_rsc_cancel(client, id, request);
|
||||
+ if (allowed) {
|
||||
+ rc = process_lrmd_rsc_cancel(client, id, request);
|
||||
+ } else {
|
||||
+ rc = -EACCES;
|
||||
+ }
|
||||
do_reply = 1;
|
||||
} else if (crm_str_eq(op, LRMD_OP_POKE, TRUE)) {
|
||||
do_notify = 1;
|
||||
do_reply = 1;
|
||||
} else if (crm_str_eq(op, LRMD_OP_CHECK, TRUE)) {
|
||||
- xmlNode *data = get_message_xml(request, F_LRMD_CALLDATA);
|
||||
- const char *timeout = crm_element_value(data, F_LRMD_WATCHDOG);
|
||||
- CRM_LOG_ASSERT(data != NULL);
|
||||
- pcmk__valid_sbd_timeout(timeout);
|
||||
+ if (allowed) {
|
||||
+ xmlNode *data = get_message_xml(request, F_LRMD_CALLDATA);
|
||||
+
|
||||
+ CRM_LOG_ASSERT(data != NULL);
|
||||
+ pcmk__valid_sbd_timeout(crm_element_value(data, F_LRMD_WATCHDOG));
|
||||
+ } else {
|
||||
+ rc = -EACCES;
|
||||
+ }
|
||||
} else if (crm_str_eq(op, LRMD_OP_ALERT_EXEC, TRUE)) {
|
||||
- rc = process_lrmd_alert_exec(client, id, request);
|
||||
+ if (allowed) {
|
||||
+ rc = process_lrmd_alert_exec(client, id, request);
|
||||
+ } else {
|
||||
+ rc = -EACCES;
|
||||
+ }
|
||||
do_reply = 1;
|
||||
} else if (crm_str_eq(op, LRMD_OP_GET_RECURRING, TRUE)) {
|
||||
- reply = process_lrmd_get_recurring(request, call_id);
|
||||
+ if (allowed) {
|
||||
+ reply = process_lrmd_get_recurring(request, call_id);
|
||||
+ } else {
|
||||
+ rc = -EACCES;
|
||||
+ }
|
||||
do_reply = 1;
|
||||
} else {
|
||||
rc = -EOPNOTSUPP;
|
||||
@@ -1879,6 +1929,11 @@ process_lrmd_message(pcmk__client_t *client, uint32_t id, xmlNode *request)
|
||||
crm_err("Unknown IPC request '%s' from %s", op, client->name);
|
||||
}
|
||||
|
||||
+ if (rc == -EACCES) {
|
||||
+ crm_warn("Rejecting IPC request '%s' from unprivileged client %s",
|
||||
+ op, pcmk__client_name(client));
|
||||
+ }
|
||||
+
|
||||
crm_debug("Processed %s operation from %s: rc=%d, reply=%d, notify=%d",
|
||||
op, client->id, rc, do_reply, do_notify);
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
From f13759f6971402dac3bea1aac45214a84d838728 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Fri, 9 Oct 2020 11:16:43 -0500
|
||||
Subject: [PATCH 5/7] Low: pacemakerd: check client for NULL before using it
|
||||
|
||||
... to guard against bugs in client tracking
|
||||
---
|
||||
daemons/pacemakerd/pacemakerd.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/daemons/pacemakerd/pacemakerd.c b/daemons/pacemakerd/pacemakerd.c
|
||||
index 5ed4626..573ea5a 100644
|
||||
--- a/daemons/pacemakerd/pacemakerd.c
|
||||
+++ b/daemons/pacemakerd/pacemakerd.c
|
||||
@@ -553,9 +553,12 @@ pcmk_ipc_dispatch(qb_ipcs_connection_t * qbc, void *data, size_t size)
|
||||
uint32_t id = 0;
|
||||
uint32_t flags = 0;
|
||||
const char *task = NULL;
|
||||
+ xmlNode *msg = NULL;
|
||||
pcmk__client_t *c = pcmk__find_client(qbc);
|
||||
- xmlNode *msg = pcmk__client_data2xml(c, data, &id, &flags);
|
||||
|
||||
+ CRM_CHECK(c != NULL, return 0);
|
||||
+
|
||||
+ msg = pcmk__client_data2xml(c, data, &id, &flags);
|
||||
pcmk__ipc_send_ack(c, id, flags, "ack");
|
||||
if (msg == NULL) {
|
||||
return 0;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
From 021081c1e28b254a0f68143fa55e517f0fcc4edb Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Fri, 9 Oct 2020 11:17:18 -0500
|
||||
Subject: [PATCH 6/7] High: pacemakerd: ignore shutdown requests from
|
||||
unprivileged users
|
||||
|
||||
The pacemakerd IPC API supports a shutdown request, along with a
|
||||
command-line interface for using it (pacemakerd --shutdown).
|
||||
|
||||
Only the haclient group has access to the IPC. Without ACLs, that group can
|
||||
already shut down Pacemaker via the CIB, so there's no security implication.
|
||||
|
||||
However, it might not be desired to allow ACL-restricted users to shut down
|
||||
Pacemaker, so block users other than root or hacluster if ACLs are supported.
|
||||
---
|
||||
daemons/pacemakerd/pacemakerd.c | 24 ++++++++++++++++++++----
|
||||
1 file changed, 20 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/daemons/pacemakerd/pacemakerd.c b/daemons/pacemakerd/pacemakerd.c
|
||||
index 573ea5a..2e69bd1 100644
|
||||
--- a/daemons/pacemakerd/pacemakerd.c
|
||||
+++ b/daemons/pacemakerd/pacemakerd.c
|
||||
@@ -566,9 +566,26 @@ pcmk_ipc_dispatch(qb_ipcs_connection_t * qbc, void *data, size_t size)
|
||||
|
||||
task = crm_element_value(msg, F_CRM_TASK);
|
||||
if (crm_str_eq(task, CRM_OP_QUIT, TRUE)) {
|
||||
- crm_notice("Shutting down in response to IPC request %s from %s",
|
||||
- crm_element_value(msg, F_CRM_REFERENCE), crm_element_value(msg, F_CRM_ORIGIN));
|
||||
- pcmk_shutdown(15);
|
||||
+ bool allowed = true;
|
||||
+
|
||||
+#if ENABLE_ACL
|
||||
+ /* Only allow privileged users (i.e. root or hacluster)
|
||||
+ * to shut down Pacemaker from the command line (or direct IPC).
|
||||
+ *
|
||||
+ * We only check when ACLs are enabled, because without them, any client
|
||||
+ * with IPC access could shut down Pacemaker via the CIB anyway.
|
||||
+ */
|
||||
+ allowed = is_set(c->flags, pcmk__client_privileged);
|
||||
+#endif
|
||||
+ if (allowed) {
|
||||
+ crm_notice("Shutting down in response to IPC request %s from %s",
|
||||
+ crm_element_value(msg, F_CRM_REFERENCE),
|
||||
+ crm_element_value(msg, F_CRM_ORIGIN));
|
||||
+ pcmk_shutdown(15);
|
||||
+ } else {
|
||||
+ crm_warn("Ignoring shutdown request from unprivileged client %s",
|
||||
+ pcmk__client_name(c));
|
||||
+ }
|
||||
|
||||
} else if (crm_str_eq(task, CRM_OP_RM_NODE_CACHE, TRUE)) {
|
||||
crm_trace("Ignoring IPC request to purge node "
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
From 80eb5ddfd529be02214f38669f1b177535186fbc Mon Sep 17 00:00:00 2001
|
||||
From: Ken Gaillot <kgaillot@redhat.com>
|
||||
Date: Fri, 9 Oct 2020 11:55:26 -0500
|
||||
Subject: [PATCH 7/7] Fix: fencer: restrict certain IPC requests to privileged
|
||||
users
|
||||
|
||||
The fencer IPC API allows clients to register fence devices.
|
||||
|
||||
If ACLs are enabled, this could allow an ACL-restricted user to bypass ACLs to
|
||||
configure fencing. If the user is able to install executables to the standard
|
||||
fencing agent locations, have arbitrary code executed as root (the standard
|
||||
locations generally require root for write access, so that is unlikely to be an
|
||||
issue).
|
||||
|
||||
If ACLs are not enabled, users in the haclient group have full access to the
|
||||
CIB, which already gives them these capabilities, so there is no additional
|
||||
exposure in that case.
|
||||
|
||||
This commit does not restrict unprivileged users from using other fencing API,
|
||||
such as requesting actual fencing.
|
||||
---
|
||||
daemons/fenced/fenced_commands.c | 41 ++++++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 37 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/daemons/fenced/fenced_commands.c b/daemons/fenced/fenced_commands.c
|
||||
index 859e7b7..a8c90a6 100644
|
||||
--- a/daemons/fenced/fenced_commands.c
|
||||
+++ b/daemons/fenced/fenced_commands.c
|
||||
@@ -2531,6 +2531,18 @@ handle_request(pcmk__client_t *client, uint32_t id, uint32_t flags,
|
||||
const char *op = crm_element_value(request, F_STONITH_OPERATION);
|
||||
const char *client_id = crm_element_value(request, F_STONITH_CLIENTID);
|
||||
|
||||
+ bool allowed = true;
|
||||
+
|
||||
+#if ENABLE_ACL
|
||||
+ /* IPC commands related to fencing configuration may be done only by
|
||||
+ * privileged users (i.e. root or hacluster) when ACLs are supported,
|
||||
+ * because all other users should go through the CIB to have ACLs applied.
|
||||
+ */
|
||||
+ if (client != NULL) {
|
||||
+ allowed = is_set(client->flags, pcmk__client_privileged);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
crm_element_value_int(request, F_STONITH_CALLOPTS, &call_options);
|
||||
|
||||
if (is_set(call_options, st_opt_sync_call)) {
|
||||
@@ -2687,27 +2699,43 @@ handle_request(pcmk__client_t *client, uint32_t id, uint32_t flags,
|
||||
} else if (crm_str_eq(op, STONITH_OP_DEVICE_ADD, TRUE)) {
|
||||
const char *device_id = NULL;
|
||||
|
||||
- rc = stonith_device_register(request, &device_id, FALSE);
|
||||
+ if (allowed) {
|
||||
+ rc = stonith_device_register(request, &device_id, FALSE);
|
||||
+ } else {
|
||||
+ rc = -EACCES;
|
||||
+ }
|
||||
do_stonith_notify_device(call_options, op, rc, device_id);
|
||||
|
||||
} else if (crm_str_eq(op, STONITH_OP_DEVICE_DEL, TRUE)) {
|
||||
xmlNode *dev = get_xpath_object("//" F_STONITH_DEVICE, request, LOG_ERR);
|
||||
const char *device_id = crm_element_value(dev, XML_ATTR_ID);
|
||||
|
||||
- rc = stonith_device_remove(device_id, FALSE);
|
||||
+ if (allowed) {
|
||||
+ rc = stonith_device_remove(device_id, FALSE);
|
||||
+ } else {
|
||||
+ rc = -EACCES;
|
||||
+ }
|
||||
do_stonith_notify_device(call_options, op, rc, device_id);
|
||||
|
||||
} else if (crm_str_eq(op, STONITH_OP_LEVEL_ADD, TRUE)) {
|
||||
char *device_id = NULL;
|
||||
|
||||
- rc = stonith_level_register(request, &device_id);
|
||||
+ if (allowed) {
|
||||
+ rc = stonith_level_register(request, &device_id);
|
||||
+ } else {
|
||||
+ rc = -EACCES;
|
||||
+ }
|
||||
do_stonith_notify_level(call_options, op, rc, device_id);
|
||||
free(device_id);
|
||||
|
||||
} else if (crm_str_eq(op, STONITH_OP_LEVEL_DEL, TRUE)) {
|
||||
char *device_id = NULL;
|
||||
|
||||
- rc = stonith_level_remove(request, &device_id);
|
||||
+ if (allowed) {
|
||||
+ rc = stonith_level_remove(request, &device_id);
|
||||
+ } else {
|
||||
+ rc = -EACCES;
|
||||
+ }
|
||||
do_stonith_notify_level(call_options, op, rc, device_id);
|
||||
|
||||
} else if(safe_str_eq(op, CRM_OP_RM_NODE_CACHE)) {
|
||||
@@ -2727,6 +2755,11 @@ handle_request(pcmk__client_t *client, uint32_t id, uint32_t flags,
|
||||
|
||||
done:
|
||||
|
||||
+ if (rc == -EACCES) {
|
||||
+ crm_warn("Rejecting IPC request '%s' from unprivileged client %s",
|
||||
+ crm_str(op), pcmk__client_name(client));
|
||||
+ }
|
||||
+
|
||||
/* Always reply unless the request is in process still.
|
||||
* If in progress, a reply will happen async after the request
|
||||
* processing is finished */
|
||||
--
|
||||
1.8.3.1
|
||||
|
5133
SOURCES/016-feature-set.patch
Normal file
5133
SOURCES/016-feature-set.patch
Normal file
File diff suppressed because it is too large
Load Diff
26
SOURCES/017-feature-set.patch
Normal file
26
SOURCES/017-feature-set.patch
Normal file
@ -0,0 +1,26 @@
|
||||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,167 +0,0 @@
|
||||
From bd4f396f267d8ef8f9c9bcbf286a77dc78d4e1b0 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Tue, 2 Mar 2021 10:26:13 -0500
|
||||
Subject: [PATCH 1/2] Med: Generate xml/crm_mon.rng from the contents of
|
||||
xml/crm_mon*.
|
||||
|
||||
This prevents the version reference in it from getting out of sync.
|
||||
|
||||
See: rhbz#1931332
|
||||
---
|
||||
xml/Makefile.am | 28 +++++++++++++++++++++++-----
|
||||
xml/crm_mon.rng | 16 ----------------
|
||||
3 files changed, 24 insertions(+), 21 deletions(-)
|
||||
delete mode 100644 xml/crm_mon.rng
|
||||
|
||||
diff --git a/xml/Makefile.am b/xml/Makefile.am
|
||||
index cb6cfa0..c52b968 100644
|
||||
--- a/xml/Makefile.am
|
||||
+++ b/xml/Makefile.am
|
||||
@@ -76,22 +76,24 @@ CIB_abs_xsl = $(abs_srcdir)/upgrade-1.3.xsl \
|
||||
$(abs_srcdir)/upgrade-2.10.xsl \
|
||||
$(wildcard $(abs_srcdir)/upgrade-*enter.xsl) \
|
||||
$(wildcard $(abs_srcdir)/upgrade-*leave.xsl)
|
||||
-MON_abs_files = $(abs_srcdir)/crm_mon.rng
|
||||
+MON_abs_files = $(abs_srcdir)/crm_mon.rng
|
||||
API_files = $(foreach base,$(API_base),$(wildcard $(srcdir)/api/$(base)*.rng))
|
||||
CIB_files = $(foreach base,$(CIB_base),$(wildcard $(srcdir)/$(base).rng $(srcdir)/$(base)-*.rng))
|
||||
CIB_xsl = $(srcdir)/upgrade-1.3.xsl \
|
||||
$(srcdir)/upgrade-2.10.xsl \
|
||||
$(wildcard $(srcdir)/upgrade-*enter.xsl) \
|
||||
$(wildcard $(srcdir)/upgrade-*leave.xsl)
|
||||
-MON_files = $(srcdir)/crm_mon.rng
|
||||
+MON_files = $(srcdir)/crm_mon.rng
|
||||
|
||||
# Sorted lists of all numeric schema versions
|
||||
API_numeric_versions = $(call numeric_versions,${API_files})
|
||||
CIB_numeric_versions = $(call numeric_versions,${CIB_files})
|
||||
+MON_numeric_versions = $(call numeric_versions,$(wildcard $(srcdir)/api/crm_mon*.rng))
|
||||
|
||||
# The highest numeric schema version
|
||||
API_max ?= $(lastword $(API_numeric_versions))
|
||||
CIB_max ?= $(lastword $(CIB_numeric_versions))
|
||||
+MON_max ?= $(lastword $(MON_numeric_versions))
|
||||
|
||||
# Sorted lists of all schema versions (including "next")
|
||||
API_versions = next $(API_numeric_versions)
|
||||
@@ -100,11 +102,12 @@ CIB_versions = next $(CIB_numeric_versions)
|
||||
# Build tree locations of static schema files and transforms (for VPATH builds)
|
||||
API_build_copies = $(foreach f,$(API_abs_files),$(subst $(abs_srcdir),$(abs_builddir),$(f)))
|
||||
CIB_build_copies = $(foreach f,$(CIB_abs_files) $(CIB_abs_xsl),$(subst $(abs_srcdir),$(abs_builddir),$(f)))
|
||||
-MON_build_copies = $(foreach f,$(MON_abs_files),$(subst $(abs_srcdir),$(abs_builddir),$(f)))
|
||||
+MON_build_copies = $(foreach f,$(MON_abs_files),$(subst $(abs_srcdir),$(abs_builddir),$(f)))
|
||||
|
||||
# Dynamically generated schema files
|
||||
API_generated = api/api-result.rng $(foreach base,$(API_versions),api/api-result-$(base).rng)
|
||||
CIB_generated = pacemaker.rng $(foreach base,$(CIB_versions),pacemaker-$(base).rng) versions.rng
|
||||
+MON_generated = crm_mon.rng
|
||||
|
||||
CIB_version_pairs = $(call version_pairs,${CIB_numeric_versions})
|
||||
CIB_version_pairs_cnt = $(words ${CIB_version_pairs})
|
||||
@@ -112,10 +115,10 @@ CIB_version_pairs_last = $(call version_pairs_last,${CIB_version_pairs_cnt},${C
|
||||
|
||||
dist_API_DATA = $(API_files)
|
||||
dist_CIB_DATA = $(CIB_files) $(CIB_xsl)
|
||||
-dist_MON_DATA = $(MON_files)
|
||||
|
||||
nodist_API_DATA = $(API_generated)
|
||||
nodist_CIB_DATA = $(CIB_generated)
|
||||
+nodist_MON_DATA = $(MON_generated)
|
||||
|
||||
EXTRA_DIST = Readme.md \
|
||||
best-match.sh \
|
||||
@@ -162,6 +165,21 @@ api/api-result-%.rng: $(API_build_copies) best-match.sh Makefile.am
|
||||
$(AM_V_at)echo ' </start>' >> $@
|
||||
$(AM_V_SCHEMA)echo '</grammar>' >> $@
|
||||
|
||||
+crm_mon.rng: api/crm_mon-$(MON_max).rng
|
||||
+ $(AM_V_at)echo '<?xml version="1.0" encoding="UTF-8"?>' > $@
|
||||
+ $(AM_V_at)echo '<grammar xmlns="http://relaxng.org/ns/structure/1.0"' >> $@
|
||||
+ $(AM_V_at)echo ' datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">' >> $@
|
||||
+ $(AM_V_at)echo ' <start>' >> $@
|
||||
+ $(AM_V_at)echo ' <ref name="element-crm_mon-old"/>' >> $@
|
||||
+ $(AM_V_at)echo ' </start>' >> $@
|
||||
+ $(AM_V_at)echo ' <define name="element-crm_mon-old">' >> $@
|
||||
+ $(AM_V_at)echo ' <element name="crm_mon">' >> $@
|
||||
+ $(AM_V_at)echo ' <attribute name="version"> <text/> </attribute>' >> $@
|
||||
+ $(AM_V_at)echo ' <externalRef href="$(<)" />' >> $@
|
||||
+ $(AM_V_at)echo ' </element>' >> $@
|
||||
+ $(AM_V_at)echo ' </define>' >> $@
|
||||
+ $(AM_V_SCHEMA)echo '</grammar>' >> $@
|
||||
+
|
||||
# Dynamically generated top-level CIB schema
|
||||
pacemaker.rng: pacemaker-$(CIB_max).rng
|
||||
$(AM_V_SCHEMA)cp $(top_builddir)/xml/$< $@
|
||||
@@ -256,7 +274,7 @@ fulldiff: best-match.sh
|
||||
@echo "# Comparing all changes across all the subsequent increments"
|
||||
$(call version_diff,${CIB_version_pairs})
|
||||
|
||||
-CLEANFILES = $(API_generated) $(CIB_generated)
|
||||
+CLEANFILES = $(API_generated) $(CIB_generated) $(MON_generated)
|
||||
|
||||
clean-local:
|
||||
if [ "x$(srcdir)" != "x$(builddir)" ]; then \
|
||||
diff --git a/xml/crm_mon.rng b/xml/crm_mon.rng
|
||||
deleted file mode 100644
|
||||
index be87fba..0000000
|
||||
--- a/xml/crm_mon.rng
|
||||
+++ /dev/null
|
||||
@@ -1,16 +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_mon-old"/>
|
||||
- </start>
|
||||
-
|
||||
- <define name="element-crm_mon-old">
|
||||
- <element name="crm_mon">
|
||||
- <attribute name="version"> <text/> </attribute>
|
||||
- <externalRef href="api/crm_mon-2.2.rng" />
|
||||
- </element>
|
||||
- </define>
|
||||
-
|
||||
-</grammar>
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
From 9b6ee6eb5aa1008beebae9d9f6c3889c81c3bbb6 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Tue, 2 Mar 2021 10:58:15 -0500
|
||||
Subject: [PATCH 2/2] Med: Change the schema type of 'expected' and 'call' to
|
||||
integer.
|
||||
|
||||
Regression in 2.0.3.
|
||||
|
||||
See: rhbz#1931332
|
||||
---
|
||||
xml/api/crm_mon-2.2.rng | 4 ++--
|
||||
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/xml/api/crm_mon-2.2.rng b/xml/api/crm_mon-2.2.rng
|
||||
index 88973a4..8e6792b 100644
|
||||
--- a/xml/api/crm_mon-2.2.rng
|
||||
+++ b/xml/api/crm_mon-2.2.rng
|
||||
@@ -198,7 +198,7 @@
|
||||
<attribute name="name"> <text /> </attribute>
|
||||
<attribute name="value"> <text /> </attribute>
|
||||
<optional>
|
||||
- <attribute name="expected"> <data type="nonNegativeInteger" /> </attribute>
|
||||
+ <attribute name="expected"> <data type="integer" /> </attribute>
|
||||
</optional>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
@@ -269,7 +269,7 @@
|
||||
<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="call"> <data type="integer" /> </attribute>
|
||||
<attribute name="status"> <text /> </attribute>
|
||||
<optional>
|
||||
<group>
|
||||
--
|
||||
1.8.3.1
|
||||
|
47
SOURCES/018-rhbz1907726.patch
Normal file
47
SOURCES/018-rhbz1907726.patch
Normal file
@ -0,0 +1,47 @@
|
||||
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
|
||||
|
1174
SOURCES/019-rhbz1371576.patch
Normal file
1174
SOURCES/019-rhbz1371576.patch
Normal file
File diff suppressed because it is too large
Load Diff
1529
SOURCES/020-rhbz1872376.patch
Normal file
1529
SOURCES/020-rhbz1872376.patch
Normal file
File diff suppressed because it is too large
Load Diff
2082
SOURCES/021-rhbz1872376.patch
Normal file
2082
SOURCES/021-rhbz1872376.patch
Normal file
File diff suppressed because it is too large
Load Diff
1452
SOURCES/022-rhbz1872376.patch
Normal file
1452
SOURCES/022-rhbz1872376.patch
Normal file
File diff suppressed because it is too large
Load Diff
26
SOURCES/023-rhbz1872376.patch
Normal file
26
SOURCES/023-rhbz1872376.patch
Normal file
@ -0,0 +1,26 @@
|
||||
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
|
||||
|
4354
SOURCES/024-rhbz1371576.patch
Normal file
4354
SOURCES/024-rhbz1371576.patch
Normal file
File diff suppressed because it is too large
Load Diff
505
SOURCES/025-feature-set.patch
Normal file
505
SOURCES/025-feature-set.patch
Normal file
@ -0,0 +1,505 @@
|
||||
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
|
||||
|
26
SOURCES/026-tests.patch
Normal file
26
SOURCES/026-tests.patch
Normal file
@ -0,0 +1,26 @@
|
||||
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
|
||||
|
962
SOURCES/027-crm_mon.patch
Normal file
962
SOURCES/027-crm_mon.patch
Normal file
@ -0,0 +1,962 @@
|
||||
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, ¤t_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, ¤t_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, ¤t_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
|
||||
|
1305
SOURCES/028-crm_mon.patch
Normal file
1305
SOURCES/028-crm_mon.patch
Normal file
File diff suppressed because it is too large
Load Diff
202
SOURCES/029-crm_mon.patch
Normal file
202
SOURCES/029-crm_mon.patch
Normal file
@ -0,0 +1,202 @@
|
||||
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
|
||||
|
1505
SOURCES/030-crmadmin.patch
Normal file
1505
SOURCES/030-crmadmin.patch
Normal file
File diff suppressed because it is too large
Load Diff
29
SOURCES/031-cibsecret.patch
Normal file
29
SOURCES/031-cibsecret.patch
Normal file
@ -0,0 +1,29 @@
|
||||
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
|
||||
|
6801
SOURCES/032-rhbz1898457.patch
Normal file
6801
SOURCES/032-rhbz1898457.patch
Normal file
File diff suppressed because it is too large
Load Diff
26
SOURCES/033-cibsecret.patch
Normal file
26
SOURCES/033-cibsecret.patch
Normal file
@ -0,0 +1,26 @@
|
||||
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
|
||||
|
709
SOURCES/034-crm_mon.patch
Normal file
709
SOURCES/034-crm_mon.patch
Normal file
@ -0,0 +1,709 @@
|
||||
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, ¤t_cib, cib_scope_local | cib_sync_call);
|
||||
+ rc = pcmk_legacy2rc(cib->cmds->query(cib, NULL, ¤t_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, ¤t_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
|
||||
|
267
SOURCES/035-crm_mon.patch
Normal file
267
SOURCES/035-crm_mon.patch
Normal file
@ -0,0 +1,267 @@
|
||||
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
|
||||
|
1676
SOURCES/036-crm_resource.patch
Normal file
1676
SOURCES/036-crm_resource.patch
Normal file
File diff suppressed because it is too large
Load Diff
6493
SOURCES/037-scheduler.patch
Normal file
6493
SOURCES/037-scheduler.patch
Normal file
File diff suppressed because it is too large
Load Diff
62
SOURCES/038-feature-set.patch
Normal file
62
SOURCES/038-feature-set.patch
Normal file
@ -0,0 +1,62 @@
|
||||
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
|
||||
|
760
SOURCES/039-crm_mon.patch
Normal file
760
SOURCES/039-crm_mon.patch
Normal file
@ -0,0 +1,760 @@
|
||||
From bd4f396f267d8ef8f9c9bcbf286a77dc78d4e1b0 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Tue, 2 Mar 2021 10:26:13 -0500
|
||||
Subject: [PATCH 1/3] Med: Generate xml/crm_mon.rng from the contents of
|
||||
xml/crm_mon*.
|
||||
|
||||
This prevents the version reference in it from getting out of sync.
|
||||
|
||||
See: rhbz#1931332
|
||||
---
|
||||
xml/Makefile.am | 28 +++++++++++++++++++++++-----
|
||||
xml/crm_mon.rng | 16 ----------------
|
||||
3 files changed, 24 insertions(+), 21 deletions(-)
|
||||
delete mode 100644 xml/crm_mon.rng
|
||||
|
||||
diff --git a/xml/Makefile.am b/xml/Makefile.am
|
||||
index cb6cfa0..c52b968 100644
|
||||
--- a/xml/Makefile.am
|
||||
+++ b/xml/Makefile.am
|
||||
@@ -76,22 +76,24 @@ CIB_abs_xsl = $(abs_srcdir)/upgrade-1.3.xsl \
|
||||
$(abs_srcdir)/upgrade-2.10.xsl \
|
||||
$(wildcard $(abs_srcdir)/upgrade-*enter.xsl) \
|
||||
$(wildcard $(abs_srcdir)/upgrade-*leave.xsl)
|
||||
-MON_abs_files = $(abs_srcdir)/crm_mon.rng
|
||||
+MON_abs_files = $(abs_srcdir)/crm_mon.rng
|
||||
API_files = $(foreach base,$(API_base),$(wildcard $(srcdir)/api/$(base)*.rng))
|
||||
CIB_files = $(foreach base,$(CIB_base),$(wildcard $(srcdir)/$(base).rng $(srcdir)/$(base)-*.rng))
|
||||
CIB_xsl = $(srcdir)/upgrade-1.3.xsl \
|
||||
$(srcdir)/upgrade-2.10.xsl \
|
||||
$(wildcard $(srcdir)/upgrade-*enter.xsl) \
|
||||
$(wildcard $(srcdir)/upgrade-*leave.xsl)
|
||||
-MON_files = $(srcdir)/crm_mon.rng
|
||||
+MON_files = $(srcdir)/crm_mon.rng
|
||||
|
||||
# Sorted lists of all numeric schema versions
|
||||
API_numeric_versions = $(call numeric_versions,${API_files})
|
||||
CIB_numeric_versions = $(call numeric_versions,${CIB_files})
|
||||
+MON_numeric_versions = $(call numeric_versions,$(wildcard $(srcdir)/api/crm_mon*.rng))
|
||||
|
||||
# The highest numeric schema version
|
||||
API_max ?= $(lastword $(API_numeric_versions))
|
||||
CIB_max ?= $(lastword $(CIB_numeric_versions))
|
||||
+MON_max ?= $(lastword $(MON_numeric_versions))
|
||||
|
||||
# Sorted lists of all schema versions (including "next")
|
||||
API_versions = next $(API_numeric_versions)
|
||||
@@ -100,11 +102,12 @@ CIB_versions = next $(CIB_numeric_versions)
|
||||
# Build tree locations of static schema files and transforms (for VPATH builds)
|
||||
API_build_copies = $(foreach f,$(API_abs_files),$(subst $(abs_srcdir),$(abs_builddir),$(f)))
|
||||
CIB_build_copies = $(foreach f,$(CIB_abs_files) $(CIB_abs_xsl),$(subst $(abs_srcdir),$(abs_builddir),$(f)))
|
||||
-MON_build_copies = $(foreach f,$(MON_abs_files),$(subst $(abs_srcdir),$(abs_builddir),$(f)))
|
||||
+MON_build_copies = $(foreach f,$(MON_abs_files),$(subst $(abs_srcdir),$(abs_builddir),$(f)))
|
||||
|
||||
# Dynamically generated schema files
|
||||
API_generated = api/api-result.rng $(foreach base,$(API_versions),api/api-result-$(base).rng)
|
||||
CIB_generated = pacemaker.rng $(foreach base,$(CIB_versions),pacemaker-$(base).rng) versions.rng
|
||||
+MON_generated = crm_mon.rng
|
||||
|
||||
CIB_version_pairs = $(call version_pairs,${CIB_numeric_versions})
|
||||
CIB_version_pairs_cnt = $(words ${CIB_version_pairs})
|
||||
@@ -112,10 +115,10 @@ CIB_version_pairs_last = $(call version_pairs_last,${CIB_version_pairs_cnt},${C
|
||||
|
||||
dist_API_DATA = $(API_files)
|
||||
dist_CIB_DATA = $(CIB_files) $(CIB_xsl)
|
||||
-dist_MON_DATA = $(MON_files)
|
||||
|
||||
nodist_API_DATA = $(API_generated)
|
||||
nodist_CIB_DATA = $(CIB_generated)
|
||||
+nodist_MON_DATA = $(MON_generated)
|
||||
|
||||
EXTRA_DIST = Readme.md \
|
||||
best-match.sh \
|
||||
@@ -162,6 +165,21 @@ api/api-result-%.rng: $(API_build_copies) best-match.sh Makefile.am
|
||||
$(AM_V_at)echo ' </start>' >> $@
|
||||
$(AM_V_SCHEMA)echo '</grammar>' >> $@
|
||||
|
||||
+crm_mon.rng: api/crm_mon-$(MON_max).rng
|
||||
+ $(AM_V_at)echo '<?xml version="1.0" encoding="UTF-8"?>' > $@
|
||||
+ $(AM_V_at)echo '<grammar xmlns="http://relaxng.org/ns/structure/1.0"' >> $@
|
||||
+ $(AM_V_at)echo ' datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">' >> $@
|
||||
+ $(AM_V_at)echo ' <start>' >> $@
|
||||
+ $(AM_V_at)echo ' <ref name="element-crm_mon-old"/>' >> $@
|
||||
+ $(AM_V_at)echo ' </start>' >> $@
|
||||
+ $(AM_V_at)echo ' <define name="element-crm_mon-old">' >> $@
|
||||
+ $(AM_V_at)echo ' <element name="crm_mon">' >> $@
|
||||
+ $(AM_V_at)echo ' <attribute name="version"> <text/> </attribute>' >> $@
|
||||
+ $(AM_V_at)echo ' <externalRef href="$(<)" />' >> $@
|
||||
+ $(AM_V_at)echo ' </element>' >> $@
|
||||
+ $(AM_V_at)echo ' </define>' >> $@
|
||||
+ $(AM_V_SCHEMA)echo '</grammar>' >> $@
|
||||
+
|
||||
# Dynamically generated top-level CIB schema
|
||||
pacemaker.rng: pacemaker-$(CIB_max).rng
|
||||
$(AM_V_SCHEMA)cp $(top_builddir)/xml/$< $@
|
||||
@@ -256,7 +274,7 @@ fulldiff: best-match.sh
|
||||
@echo "# Comparing all changes across all the subsequent increments"
|
||||
$(call version_diff,${CIB_version_pairs})
|
||||
|
||||
-CLEANFILES = $(API_generated) $(CIB_generated)
|
||||
+CLEANFILES = $(API_generated) $(CIB_generated) $(MON_generated)
|
||||
|
||||
clean-local:
|
||||
if [ "x$(srcdir)" != "x$(builddir)" ]; then \
|
||||
diff --git a/xml/crm_mon.rng b/xml/crm_mon.rng
|
||||
deleted file mode 100644
|
||||
index be87fba..0000000
|
||||
--- a/xml/crm_mon.rng
|
||||
+++ /dev/null
|
||||
@@ -1,16 +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_mon-old"/>
|
||||
- </start>
|
||||
-
|
||||
- <define name="element-crm_mon-old">
|
||||
- <element name="crm_mon">
|
||||
- <attribute name="version"> <text/> </attribute>
|
||||
- <externalRef href="api/crm_mon-2.3.rng" />
|
||||
- </element>
|
||||
- </define>
|
||||
-
|
||||
-</grammar>
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
From 0cbc5b0a66ac0bf206ff45f36206253a60620e07 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Tue, 2 Mar 2021 10:53:17 -0500
|
||||
Subject: [PATCH 2/3] Med: Copy crm_mon.rng and crm_resource.rng in preparation
|
||||
for updates.
|
||||
|
||||
See: rhbz#1931332
|
||||
---
|
||||
xml/api/crm_mon-2.7.rng | 311 +++++++++++++++++++++++++++++++++++++++++++
|
||||
xml/api/crm_resource-2.7.rng | 238 +++++++++++++++++++++++++++++++++
|
||||
2 files changed, 549 insertions(+)
|
||||
create mode 100644 xml/api/crm_mon-2.7.rng
|
||||
create mode 100644 xml/api/crm_resource-2.7.rng
|
||||
|
||||
diff --git a/xml/api/crm_mon-2.7.rng b/xml/api/crm_mon-2.7.rng
|
||||
new file mode 100644
|
||||
index 0000000..88973a4
|
||||
--- /dev/null
|
||||
+++ b/xml/api/crm_mon-2.7.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/crm_resource-2.7.rng b/xml/api/crm_resource-2.7.rng
|
||||
new file mode 100644
|
||||
index 0000000..b49e24c
|
||||
--- /dev/null
|
||||
+++ b/xml/api/crm_resource-2.7.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
|
||||
|
||||
|
||||
From 9b6ee6eb5aa1008beebae9d9f6c3889c81c3bbb6 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Lumens <clumens@redhat.com>
|
||||
Date: Tue, 2 Mar 2021 10:58:15 -0500
|
||||
Subject: [PATCH 3/3] Med: Change the schema type of 'expected' and 'call' to
|
||||
integer.
|
||||
|
||||
Regression in 2.0.3.
|
||||
|
||||
See: rhbz#1931332
|
||||
---
|
||||
xml/api/crm_mon-2.7.rng | 4 ++--
|
||||
xml/api/crm_resource-2.7.rng | 2 +-
|
||||
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/xml/api/crm_mon-2.7.rng b/xml/api/crm_mon-2.7.rng
|
||||
index 88973a4..8e6792b 100644
|
||||
--- a/xml/api/crm_mon-2.7.rng
|
||||
+++ b/xml/api/crm_mon-2.7.rng
|
||||
@@ -198,7 +198,7 @@
|
||||
<attribute name="name"> <text /> </attribute>
|
||||
<attribute name="value"> <text /> </attribute>
|
||||
<optional>
|
||||
- <attribute name="expected"> <data type="nonNegativeInteger" /> </attribute>
|
||||
+ <attribute name="expected"> <data type="integer" /> </attribute>
|
||||
</optional>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
@@ -269,7 +269,7 @@
|
||||
<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="call"> <data type="integer" /> </attribute>
|
||||
<attribute name="status"> <text /> </attribute>
|
||||
<optional>
|
||||
<group>
|
||||
diff --git a/xml/api/crm_resource-2.7.rng b/xml/api/crm_resource-2.7.rng
|
||||
index b49e24c..8e386db 100644
|
||||
--- a/xml/api/crm_resource-2.7.rng
|
||||
+++ b/xml/api/crm_resource-2.7.rng
|
||||
@@ -217,7 +217,7 @@
|
||||
</optional>
|
||||
<attribute name="op"> <text/> </attribute>
|
||||
<attribute name="node"> <text/> </attribute>
|
||||
- <attribute name="call"> <data type="nonNegativeInteger" /> </attribute>
|
||||
+ <attribute name="call"> <data type="integer" /> </attribute>
|
||||
<attribute name="rc"> <data type="nonNegativeInteger" /> </attribute>
|
||||
<optional>
|
||||
<attribute name="last-rc-change"> <text/> </attribute>
|
||||
--
|
||||
1.8.3.1
|
||||
|
36
SOURCES/100-default-to-syncing-with-sbd.patch
Normal file
36
SOURCES/100-default-to-syncing-with-sbd.patch
Normal file
@ -0,0 +1,36 @@
|
||||
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
|
||||
|
@ -22,11 +22,11 @@
|
||||
## Upstream pacemaker version, and its package version (specversion
|
||||
## can be incremented to build packages reliably considered "newer"
|
||||
## than previously built packages with the same pcmkversion)
|
||||
%global pcmkversion 2.0.4
|
||||
%global specversion 6
|
||||
%global pcmkversion 2.0.5
|
||||
%global specversion 9
|
||||
|
||||
## Upstream commit (full commit ID, abbreviated commit ID, or tag) to build
|
||||
%global commit 2deceaa3ae1fbadd844f5c5b47fd33129fa2c227
|
||||
%global commit ba59be71228fed04f78ab374dfac748d314d0e89
|
||||
## 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.
|
||||
%global commit_abbrev 7
|
||||
@ -214,7 +214,6 @@
|
||||
}
|
||||
%endif
|
||||
|
||||
|
||||
# Keep sane profiling data if requested
|
||||
%if %{with profiling}
|
||||
|
||||
@ -227,14 +226,14 @@
|
||||
Name: pacemaker
|
||||
Summary: Scalable High-Availability cluster resource manager
|
||||
Version: %{pcmkversion}
|
||||
Release: %{pcmk_release}%{?dist}.2
|
||||
Release: %{pcmk_release}%{?dist}
|
||||
%if %{defined _unitdir}
|
||||
License: GPLv2+ and LGPLv2+
|
||||
%else
|
||||
# initscript is Revised BSD
|
||||
License: GPLv2+ and LGPLv2+ and BSD
|
||||
%endif
|
||||
Url: http://www.clusterlabs.org
|
||||
Url: https://www.clusterlabs.org/
|
||||
Group: System Environment/Daemons
|
||||
|
||||
# Example: https://codeload.github.com/ClusterLabs/pacemaker/tar.gz/e91769e
|
||||
@ -249,27 +248,48 @@ Source0: https://codeload.github.com/%{github_owner}/%{name}/tar.gz/%{arch
|
||||
Source1: nagios-agents-metadata-%{nagios_hash}.tar.gz
|
||||
|
||||
# upstream commits
|
||||
Patch1: 001-rules.patch
|
||||
Patch2: 002-demote.patch
|
||||
Patch3: 003-trace.patch
|
||||
Patch4: 004-test.patch
|
||||
Patch5: 005-sysconfig.patch
|
||||
Patch6: 006-ipc_refactor.patch
|
||||
Patch7: 007-ipc_model.patch
|
||||
Patch8: 008-crm_node.patch
|
||||
Patch9: 009-timeout-log.patch
|
||||
Patch10: 010-crm_mon.patch
|
||||
Patch11: 011-cts.patch
|
||||
Patch12: 012-ipc_fix.patch
|
||||
Patch13: 013-pacemakerd.patch
|
||||
Patch14: 014-sbd.patch
|
||||
Patch15: 015-cibsecret.patch
|
||||
Patch16: 016-CVE-2020-25654.patch
|
||||
Patch17: 017-promotion.patch
|
||||
Patch18: 018-api-schema.patch
|
||||
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
|
||||
Patch39: 039-crm_mon.patch
|
||||
|
||||
# downstream-only commits
|
||||
#Patch100: xxx.patch
|
||||
Patch100: 100-default-to-syncing-with-sbd.patch
|
||||
|
||||
Requires: resource-agents
|
||||
Requires: %{pkgname_pcmk_libs}%{?_isa} = %{version}-%{release}
|
||||
@ -383,7 +403,10 @@ 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
|
||||
Conflicts: sbd < 1.4.0
|
||||
# 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
|
||||
Conflicts: sbd < 1.4.2
|
||||
|
||||
%description -n %{pkgname_pcmk_libs}
|
||||
Pacemaker is an advanced, scalable High-Availability cluster resource
|
||||
@ -528,9 +551,6 @@ monitor resources.
|
||||
|
||||
%build
|
||||
|
||||
# Early versions of autotools (e.g. RHEL <= 5) do not support --docdir
|
||||
export docdir=%{pcmk_docdir}
|
||||
|
||||
export systemdsystemunitdir=%{?_unitdir}%{!?_unitdir:no}
|
||||
|
||||
# RHEL changes pacemaker's concurrent-fencing default to true
|
||||
@ -964,15 +984,75 @@ exit 0
|
||||
%license %{nagios_name}-%{nagios_hash}/COPYING
|
||||
|
||||
%changelog
|
||||
* Thu Mar 4 2021 Ken Gaillot <kgaillot@redhat.com> - 2.0.4-6.2
|
||||
- Avoid situation where promotion is not scheduled until next transition
|
||||
* Tue Mar 2 2021 Ken Gaillot <kgaillot@redhat.com> - 2.0.5-9
|
||||
- Avoid pcs failures when Pacemaker records negative call ID in history
|
||||
- Resolves: rhbz1935240
|
||||
- Resolves: rhbz1939533
|
||||
- Resolves: rhbz1931332
|
||||
|
||||
* Mon Oct 26 2020 Ken Gaillot <kgaillot@redhat.com> - 2.0.4-6.1
|
||||
- Prevent users from bypassing ACLs by using IPC directly (CVE-2020-25654)
|
||||
- Resolves: rhbz1891528
|
||||
* Mon Feb 15 2021 Ken Gaillot <kgaillot@redhat.com> - 2.0.5-8
|
||||
- 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
|
||||
- Do not introduce regression in crm_resource --locate
|
||||
- Resolves: rhbz1925681
|
||||
|
||||
* Wed Feb 3 2021 Ken Gaillot <kgaillot@redhat.com> - 2.0.5-6
|
||||
- crm_mon --daemonize should reconnect if cluster restarts
|
||||
- crm_mon should show more informative messages when cluster is starting
|
||||
- crm_mon should show rest of status if fencing history is unavailable
|
||||
- cibsecret now works on remote nodes (as long as name can be reached via ssh)
|
||||
- Stop remote nodes correctly when connection history is later than node history
|
||||
- Resolves: rhbz1466875
|
||||
- Resolves: rhbz1872490
|
||||
- Resolves: rhbz1880426
|
||||
- Resolves: rhbz1881537
|
||||
- Resolves: rhbz1898457
|
||||
|
||||
* Thu Jan 14 2021 Ken Gaillot <kgaillot@redhat.com> - 2.0.5-5
|
||||
- Allow non-critical resources that stop rather than make another resource move
|
||||
- Support crm_resource --digests option for showing operation digests
|
||||
- Clean-up of all resources should work from remote nodes
|
||||
- Resolves: rhbz1371576
|
||||
- Resolves: rhbz1872376
|
||||
- Resolves: rhbz1907726
|
||||
|
||||
* Wed Dec 2 2020 Klaus Wenninger <kwenning@redhat.com> - 2.0.5-4
|
||||
- Rebase on upstream 2.0.5 release
|
||||
- Make waiting to be pinged by sbd via pacemakerd-api the default
|
||||
- Resolves: rhbz1885645
|
||||
- Resolves: rhbz1873138
|
||||
|
||||
* Wed Nov 18 2020 Ken Gaillot <kgaillot@redhat.com> - 2.0.5-3
|
||||
- Rebase on upstream 2.0.5-rc3 release
|
||||
- Resolves: rhbz1885645
|
||||
|
||||
* Wed Oct 28 2020 Ken Gaillot <kgaillot@redhat.com> - 2.0.5-2
|
||||
- Rebase on upstream 2.0.5-rc2 release
|
||||
- Prevent ACL bypass (CVE-2020-25654)
|
||||
- Resolves: rhbz1885645
|
||||
- Resolves: rhbz1889582
|
||||
|
||||
* Tue Oct 20 2020 Ken Gaillot <kgaillot@redhat.com> - 2.0.5-1
|
||||
- crm_mon --resource option to filter output by resource
|
||||
- Avoid filling /dev/shm after frequent corosync errors
|
||||
- Allow configurable permissions for log files
|
||||
- Ensure ACL write permission always supersedes read
|
||||
- Use fence device monitor timeout for starts and probes
|
||||
- Allow type="integer" in rule expressions
|
||||
- Avoid error messages when running crm_node inside bundles
|
||||
- Avoid situation where promotion is not scheduled until next transition
|
||||
- crm_mon should show more clearly when an entire group is disabled
|
||||
- Rebase on upstream 2.0.5-rc1 release
|
||||
- Resolves: rhbz1300597
|
||||
- Resolves: rhbz1614166
|
||||
- Resolves: rhbz1647136
|
||||
- Resolves: rhbz1833173
|
||||
- Resolves: rhbz1856015
|
||||
- Resolves: rhbz1866573
|
||||
- Resolves: rhbz1874391
|
||||
- Resolves: rhbz1835717
|
||||
- Resolves: rhbz1748139
|
||||
- Resolves: rhbz1885645
|
||||
|
||||
* Thu Aug 20 2020 Ken Gaillot <kgaillot@redhat.com> - 2.0.4-6
|
||||
- Fix cibsecret bug when node name is different from hostname
|
||||
|
Loading…
Reference in New Issue
Block a user