diff --git a/SOURCES/008-dynamic-list-fencing.patch b/SOURCES/008-dynamic-list-fencing.patch new file mode 100644 index 0000000..4a56117 --- /dev/null +++ b/SOURCES/008-dynamic-list-fencing.patch @@ -0,0 +1,140 @@ +From 2d15fb37525f88ec8d5acb689b698044c4bb69b1 Mon Sep 17 00:00:00 2001 +From: Hideo Yamauchi +Date: Thu, 17 Jun 2021 22:39:12 +0900 +Subject: [PATCH 1/2] Low: fenced: Low: fenced: Remove unnecessary release. + +--- + daemons/fenced/fenced_commands.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/daemons/fenced/fenced_commands.c b/daemons/fenced/fenced_commands.c +index fee55a7..35aec06 100644 +--- a/daemons/fenced/fenced_commands.c ++++ b/daemons/fenced/fenced_commands.c +@@ -1104,9 +1104,6 @@ dynamic_list_search_cb(GPid pid, int rc, const char *output, gpointer user_data) + /* Fall back to status */ + g_hash_table_replace(dev->params, + strdup(PCMK_STONITH_HOST_CHECK), strdup("status")); +- +- g_list_free_full(dev->targets, free); +- dev->targets = NULL; + } else if (!rc) { + crm_info("Refreshing port list for %s", dev->id); + g_list_free_full(dev->targets, free); +-- +1.8.3.1 + + +From a29f88f6020aac5f1ac32072942eb5713d7be50d Mon Sep 17 00:00:00 2001 +From: Hideo Yamauchi +Date: Thu, 17 Jun 2021 22:40:40 +0900 +Subject: [PATCH 2/2] High: fenced: Wrong device may be selected when + "dynamic-list" is specified. + +--- + daemons/fenced/fenced_commands.c | 67 +++++++++++++++++++++++----------------- + 1 file changed, 38 insertions(+), 29 deletions(-) + +diff --git a/daemons/fenced/fenced_commands.c b/daemons/fenced/fenced_commands.c +index 35aec06..da076fb 100644 +--- a/daemons/fenced/fenced_commands.c ++++ b/daemons/fenced/fenced_commands.c +@@ -904,6 +904,31 @@ xml2device_params(const char *name, xmlNode *dev) + return params; + } + ++static const char * ++target_list_type(stonith_device_t * dev) ++{ ++ const char *check_type = NULL; ++ ++ check_type = g_hash_table_lookup(dev->params, PCMK_STONITH_HOST_CHECK); ++ ++ if (check_type == NULL) { ++ ++ if (g_hash_table_lookup(dev->params, PCMK_STONITH_HOST_LIST)) { ++ check_type = "static-list"; ++ } else if (g_hash_table_lookup(dev->params, PCMK_STONITH_HOST_MAP)) { ++ check_type = "static-list"; ++ } else if (pcmk_is_set(dev->flags, st_device_supports_list)) { ++ check_type = "dynamic-list"; ++ } else if (pcmk_is_set(dev->flags, st_device_supports_status)) { ++ check_type = "status"; ++ } else { ++ check_type = "none"; ++ } ++ } ++ ++ return check_type; ++} ++ + static stonith_device_t * + build_device_from_xml(xmlNode * msg) + { +@@ -931,6 +956,12 @@ build_device_from_xml(xmlNode * msg) + value = g_hash_table_lookup(device->params, PCMK_STONITH_HOST_MAP); + device->aliases = build_port_aliases(value, &(device->targets)); + ++ value = target_list_type(device); ++ if (!pcmk__str_eq(value, "static-list", pcmk__str_casei) && device->targets) { ++ /* Other than "static-list", dev-> targets is unnecessary. */ ++ g_list_free_full(device->targets, free); ++ device->targets = NULL; ++ } + device->agent_metadata = get_agent_metadata(device->agent); + if (device->agent_metadata) { + read_action_metadata(device); +@@ -971,31 +1002,6 @@ build_device_from_xml(xmlNode * msg) + return device; + } + +-static const char * +-target_list_type(stonith_device_t * dev) +-{ +- const char *check_type = NULL; +- +- check_type = g_hash_table_lookup(dev->params, PCMK_STONITH_HOST_CHECK); +- +- if (check_type == NULL) { +- +- if (g_hash_table_lookup(dev->params, PCMK_STONITH_HOST_LIST)) { +- check_type = "static-list"; +- } else if (g_hash_table_lookup(dev->params, PCMK_STONITH_HOST_MAP)) { +- check_type = "static-list"; +- } else if (pcmk_is_set(dev->flags, st_device_supports_list)) { +- check_type = "dynamic-list"; +- } else if (pcmk_is_set(dev->flags, st_device_supports_status)) { +- check_type = "status"; +- } else { +- check_type = "none"; +- } +- } +- +- return check_type; +-} +- + static void + schedule_internal_command(const char *origin, + stonith_device_t * device, +@@ -1099,11 +1105,14 @@ dynamic_list_search_cb(GPid pid, int rc, const char *output, gpointer user_data) + + /* If we successfully got the targets earlier, don't disable. */ + if (rc != 0 && !dev->targets) { +- crm_notice("Disabling port list queries for %s: %s " +- CRM_XS " rc=%d", dev->id, output, rc); +- /* Fall back to status */ +- g_hash_table_replace(dev->params, ++ if (g_hash_table_lookup(dev->params, PCMK_STONITH_HOST_CHECK) == NULL) { ++ /* ++ If the operation fails if the user does not explicitly specify "dynamic-list", it will fall back to "status". ++ */ ++ crm_notice("Disabling port list queries for %s (%d): %s", dev->id, rc, output); ++ g_hash_table_replace(dev->params, + strdup(PCMK_STONITH_HOST_CHECK), strdup("status")); ++ } + } else if (!rc) { + crm_info("Refreshing port list for %s", dev->id); + g_list_free_full(dev->targets, free); +-- +1.8.3.1 + diff --git a/SOURCES/009-crm_resource-messages.patch b/SOURCES/009-crm_resource-messages.patch new file mode 100644 index 0000000..bdbcf03 --- /dev/null +++ b/SOURCES/009-crm_resource-messages.patch @@ -0,0 +1,229 @@ +From 5bcab230ad4c647ca78b18bd4a66e30a4bb4417f Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen +Date: Wed, 16 Jun 2021 11:19:03 +0200 +Subject: [PATCH 1/2] Feature: crm_resource: report not supported for --force-* + w/systemd, upstart, nagios and bundled resources + +--- + tools/crm_resource.c | 21 ++++---------- + tools/crm_resource_runtime.c | 67 +++++++++++++++++++++++++++++--------------- + 2 files changed, 51 insertions(+), 37 deletions(-) + +diff --git a/tools/crm_resource.c b/tools/crm_resource.c +index 4abdd03..fa7902c 100644 +--- a/tools/crm_resource.c ++++ b/tools/crm_resource.c +@@ -660,21 +660,12 @@ attr_set_type_cb(const gchar *option_name, const gchar *optarg, gpointer data, G + + gboolean + class_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError **error) { +- if (!(pcmk_get_ra_caps(optarg) & pcmk_ra_cap_params)) { +- if (!args->quiet) { +- g_set_error(error, G_OPTION_ERROR, CRM_EX_INVALID_PARAM, +- "Standard %s does not support parameters\n", optarg); +- } +- return FALSE; +- +- } else { +- if (options.v_class != NULL) { +- free(options.v_class); +- } +- +- options.v_class = strdup(optarg); ++ if (options.v_class != NULL) { ++ free(options.v_class); + } + ++ options.v_class = strdup(optarg); ++ + options.cmdline_config = TRUE; + options.require_resource = FALSE; + return TRUE; +@@ -1422,7 +1413,7 @@ validate_cmdline_config(void) + } else if (options.rsc_cmd != cmd_execute_agent) { + g_set_error(&error, PCMK__EXITC_ERROR, CRM_EX_USAGE, + "--class, --agent, and --provider can only be used with " +- "--validate"); ++ "--validate and --force-*"); + + // Not all of --class, --agent, and --provider need to be given. Not all + // classes support the concept of a provider. Check that what we were given +@@ -1841,7 +1832,7 @@ main(int argc, char **argv) + if (options.cmdline_config) { + exit_code = cli_resource_execute_from_params(out, NULL, + options.v_class, options.v_provider, options.v_agent, +- "validate-all", options.cmdline_params, ++ options.operation, options.cmdline_params, + options.override_params, options.timeout_ms, + args->verbosity, options.force, options.check_level); + } else { +diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c +index fe42e60..59e6df5 100644 +--- a/tools/crm_resource_runtime.c ++++ b/tools/crm_resource_runtime.c +@@ -1674,24 +1674,59 @@ wait_till_stable(pcmk__output_t *out, int timeout_ms, cib_t * cib) + return rc; + } + ++static const char * ++get_action(const char *rsc_action) { ++ const char *action = NULL; ++ ++ if (pcmk__str_eq(rsc_action, "validate", pcmk__str_casei)) { ++ action = "validate-all"; ++ ++ } else if (pcmk__str_eq(rsc_action, "force-check", pcmk__str_casei)) { ++ action = "monitor"; ++ ++ } else if (pcmk__strcase_any_of(rsc_action, "force-start", "force-stop", ++ "force-demote", "force-promote", NULL)) { ++ action = rsc_action+6; ++ } else { ++ action = rsc_action; ++ } ++ ++ return action; ++} ++ + crm_exit_t + cli_resource_execute_from_params(pcmk__output_t *out, const char *rsc_name, + const char *rsc_class, const char *rsc_prov, +- const char *rsc_type, const char *action, ++ const char *rsc_type, const char *rsc_action, + GHashTable *params, GHashTable *override_hash, + int timeout_ms, int resource_verbose, gboolean force, + int check_level) + { ++ const char *action = NULL; + GHashTable *params_copy = NULL; + crm_exit_t exit_code = CRM_EX_OK; + svc_action_t *op = NULL; + + if (pcmk__str_eq(rsc_class, PCMK_RESOURCE_CLASS_STONITH, pcmk__str_casei)) { + out->err(out, "Sorry, the %s option doesn't support %s resources yet", +- action, rsc_class); ++ rsc_action, rsc_class); ++ crm_exit(CRM_EX_UNIMPLEMENT_FEATURE); ++ } else if (pcmk__strcase_any_of(rsc_class, PCMK_RESOURCE_CLASS_SYSTEMD, ++ PCMK_RESOURCE_CLASS_UPSTART, PCMK_RESOURCE_CLASS_NAGIOS, NULL)) { ++ out->err(out, "Sorry, the %s option doesn't support %s resources", ++ rsc_action, rsc_class); ++ crm_exit(CRM_EX_UNIMPLEMENT_FEATURE); ++ } else if (pcmk__str_eq(rsc_class, PCMK_RESOURCE_CLASS_SERVICE, ++ pcmk__str_casei) && !pcmk__str_eq( ++ resources_find_service_class(rsc_name), PCMK_RESOURCE_CLASS_LSB, ++ pcmk__str_casei)) { ++ out->err(out, "Sorry, the %s option doesn't support %s resources", ++ rsc_action, resources_find_service_class(rsc_name)); + crm_exit(CRM_EX_UNIMPLEMENT_FEATURE); + } + ++ action = get_action(rsc_action); ++ + /* If no timeout was provided, grab the default. */ + if (timeout_ms == 0) { + timeout_ms = crm_get_msec(CRM_DEFAULT_OP_TIMEOUT_S); +@@ -1766,7 +1801,7 @@ cli_resource_execute_from_params(pcmk__output_t *out, const char *rsc_name, + exit_code = op->rc; + + out->message(out, "resource-agent-action", resource_verbose, rsc_class, +- rsc_prov, rsc_type, rsc_name, action, override_hash, op->rc, ++ rsc_prov, rsc_type, rsc_name, rsc_action, override_hash, op->rc, + op->status, op->stdout_data, op->stderr_data); + } else { + exit_code = op->rc == 0 ? CRM_EX_ERROR : op->rc; +@@ -1790,27 +1825,15 @@ cli_resource_execute(pe_resource_t *rsc, const char *requested_name, + const char *rtype = NULL; + const char *rprov = NULL; + const char *rclass = NULL; +- const char *action = NULL; + GHashTable *params = NULL; + +- if (pcmk__str_eq(rsc_action, "validate", pcmk__str_casei)) { +- action = "validate-all"; +- +- } else if (pcmk__str_eq(rsc_action, "force-check", pcmk__str_casei)) { +- action = "monitor"; +- +- } else if (pcmk__str_eq(rsc_action, "force-stop", pcmk__str_casei)) { +- action = rsc_action+6; +- +- } else if (pcmk__strcase_any_of(rsc_action, "force-start", "force-demote", ++ if (pcmk__strcase_any_of(rsc_action, "force-start", "force-demote", + "force-promote", NULL)) { +- action = rsc_action+6; +- + if(pe_rsc_is_clone(rsc)) { + GList *nodes = cli_resource_search(rsc, requested_name, data_set); + if(nodes != NULL && force == FALSE) { + out->err(out, "It is not safe to %s %s here: the cluster claims it is already active", +- action, rsc->id); ++ rsc_action, rsc->id); + out->err(out, "Try setting target-role=Stopped first or specifying " + "the force option"); + return CRM_EX_UNSAFE; +@@ -1818,9 +1841,6 @@ cli_resource_execute(pe_resource_t *rsc, const char *requested_name, + + g_list_free_full(nodes, free); + } +- +- } else { +- action = rsc_action; + } + + if(pe_rsc_is_clone(rsc)) { +@@ -1831,6 +1851,9 @@ cli_resource_execute(pe_resource_t *rsc, const char *requested_name, + if(rsc->variant == pe_group) { + out->err(out, "Sorry, the %s option doesn't support group resources", rsc_action); + return CRM_EX_UNIMPLEMENT_FEATURE; ++ } else if (rsc->variant == pe_container || pe_rsc_is_bundled(rsc)) { ++ out->err(out, "Sorry, the %s option doesn't support bundled resources", rsc_action); ++ return CRM_EX_UNIMPLEMENT_FEATURE; + } + + rclass = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS); +@@ -1841,12 +1864,12 @@ cli_resource_execute(pe_resource_t *rsc, const char *requested_name, + data_set); + + if (timeout_ms == 0) { +- timeout_ms = pe_get_configured_timeout(rsc, action, data_set); ++ timeout_ms = pe_get_configured_timeout(rsc, get_action(rsc_action), data_set); + } + + rid = pe_rsc_is_anon_clone(rsc->parent)? requested_name : rsc->id; + +- exit_code = cli_resource_execute_from_params(out, rid, rclass, rprov, rtype, action, ++ exit_code = cli_resource_execute_from_params(out, rid, rclass, rprov, rtype, rsc_action, + params, override_hash, timeout_ms, + resource_verbose, force, check_level); + return exit_code; +-- +1.8.3.1 + + +From 289cd231186755d99c1262eb9f968dc852409588 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen +Date: Fri, 16 Jul 2021 13:20:55 +0200 +Subject: [PATCH 2/2] Refactor: crm_resource: remove duplicate Overriding + message that's handled elsewhere + +--- + tools/crm_resource_runtime.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c +index 59e6df5..ce037c5 100644 +--- a/tools/crm_resource_runtime.c ++++ b/tools/crm_resource_runtime.c +@@ -1791,8 +1791,6 @@ cli_resource_execute_from_params(pcmk__output_t *out, const char *rsc_name, + + g_hash_table_iter_init(&iter, override_hash); + while (g_hash_table_iter_next(&iter, (gpointer *) & name, (gpointer *) & value)) { +- out->info(out, "Overriding the cluster configuration for '%s' with '%s' = '%s'", +- rsc_name, name, value); + g_hash_table_replace(op->params, strdup(name), strdup(value)); + } + } +-- +1.8.3.1 + diff --git a/SOURCES/010-probe-pending.patch b/SOURCES/010-probe-pending.patch new file mode 100644 index 0000000..336c33e --- /dev/null +++ b/SOURCES/010-probe-pending.patch @@ -0,0 +1,715 @@ +From b0347f7b8e609420a7055d5fe537cc40ac0d1bb2 Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Fri, 16 Jul 2021 11:08:05 -0500 +Subject: [PATCH 1/3] Fix: scheduler: don't schedule probes of unmanaged + resources on pending nodes + +Previously, custom_action() would set an action's optional or runnable flag in +the same, exclusive if-else sequence. This means that if an action should be +optional *and* runnable, only one would be set. In particular, this meant that +if a resource is unmanaged *and* its allocated node is pending, any probe would +be set to optional, but not unrunnable, and the controller could wrongly +attempt the probe before the join completed. + +Now, optional is checked separately. +--- + lib/pengine/utils.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c +index 5ef742e..965824b 100644 +--- a/lib/pengine/utils.c ++++ b/lib/pengine/utils.c +@@ -541,6 +541,20 @@ custom_action(pe_resource_t * rsc, char *key, const char *task, + FALSE, data_set); + } + ++ // Make the action optional if its resource is unmanaged ++ if (!pcmk_is_set(action->flags, pe_action_pseudo) ++ && (action->node != NULL) ++ && !pcmk_is_set(action->rsc->flags, pe_rsc_managed) ++ && (g_hash_table_lookup(action->meta, ++ XML_LRM_ATTR_INTERVAL_MS) == NULL)) { ++ pe_rsc_debug(rsc, "%s on %s is optional (%s is unmanaged)", ++ action->uuid, action->node->details->uname, ++ action->rsc->id); ++ pe__set_action_flags(action, pe_action_optional); ++ // We shouldn't clear runnable here because ... something ++ } ++ ++ // Make the action runnable or unrunnable as appropriate + if (pcmk_is_set(action->flags, pe_action_pseudo)) { + /* leave untouched */ + +@@ -549,14 +563,6 @@ custom_action(pe_resource_t * rsc, char *key, const char *task, + action->uuid); + pe__clear_action_flags(action, pe_action_runnable); + +- } else if (!pcmk_is_set(rsc->flags, pe_rsc_managed) +- && g_hash_table_lookup(action->meta, +- XML_LRM_ATTR_INTERVAL_MS) == NULL) { +- pe_rsc_debug(rsc, "%s on %s is optional (%s is unmanaged)", +- action->uuid, action->node->details->uname, rsc->id); +- pe__set_action_flags(action, pe_action_optional); +- //pe__clear_action_flags(action, pe_action_runnable); +- + } else if (!pcmk_is_set(action->flags, pe_action_dc) + && !(action->node->details->online) + && (!pe__is_guest_node(action->node) +-- +1.8.3.1 + + +From 520303b90eb707f5b7a9afa9b106e4a38b90f0f9 Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Wed, 14 Jul 2021 17:18:44 -0500 +Subject: [PATCH 2/3] Test: scheduler: update existing tests for probe + scheduling change + +This is an improvement. Looking at bundle-probe-order-2 for example, +the bundle's first instance has this status to start: + + * Replica[0] + * galera (ocf::heartbeat:galera): Stopped (unmanaged) + * galera-bundle-docker-0 (ocf::heartbeat:docker): Started centos2 (unmanaged) + * galera-bundle-0 (ocf::pacemaker:remote): Started centos2 (unmanaged) + +After the changes, we now schedule recurring monitors for +galera-bundle-docker-0 and galera-bundle-0 on centos2, and a probe of galera:0 +on galera-bundle-0, all of which are possible. +--- + cts/scheduler/dot/bundle-probe-order-2.dot | 3 ++ + cts/scheduler/dot/bundle-probe-order-3.dot | 1 + + cts/scheduler/exp/bundle-probe-order-2.exp | 33 ++++++++++++++++++++-- + cts/scheduler/exp/bundle-probe-order-3.exp | 21 ++++++++++---- + cts/scheduler/summary/bundle-probe-order-2.summary | 3 ++ + cts/scheduler/summary/bundle-probe-order-3.summary | 1 + + 6 files changed, 53 insertions(+), 9 deletions(-) + +diff --git a/cts/scheduler/dot/bundle-probe-order-2.dot b/cts/scheduler/dot/bundle-probe-order-2.dot +index 0cce3fd..7706195 100644 +--- a/cts/scheduler/dot/bundle-probe-order-2.dot ++++ b/cts/scheduler/dot/bundle-probe-order-2.dot +@@ -1,6 +1,9 @@ + digraph "g" { ++"galera-bundle-0_monitor_30000 centos2" [ style=bold color="green" fontcolor="black"] ++"galera-bundle-docker-0_monitor_60000 centos2" [ style=bold color="green" fontcolor="black"] + "galera-bundle-docker-1_monitor_0 centos2" [ style=bold color="green" fontcolor="black"] + "galera-bundle-docker-2_monitor_0 centos1" [ style=bold color="green" fontcolor="black"] + "galera-bundle-docker-2_monitor_0 centos2" [ style=bold color="green" fontcolor="black"] + "galera-bundle-docker-2_monitor_0 centos3" [ style=bold color="green" fontcolor="black"] ++"galera:0_monitor_0 galera-bundle-0" [ style=bold color="green" fontcolor="black"] + } +diff --git a/cts/scheduler/dot/bundle-probe-order-3.dot b/cts/scheduler/dot/bundle-probe-order-3.dot +index a4b109f..53a384b 100644 +--- a/cts/scheduler/dot/bundle-probe-order-3.dot ++++ b/cts/scheduler/dot/bundle-probe-order-3.dot +@@ -2,6 +2,7 @@ + "galera-bundle-0_monitor_0 centos1" [ style=bold color="green" fontcolor="black"] + "galera-bundle-0_monitor_0 centos2" [ style=bold color="green" fontcolor="black"] + "galera-bundle-0_monitor_0 centos3" [ style=bold color="green" fontcolor="black"] ++"galera-bundle-docker-0_monitor_60000 centos2" [ style=bold color="green" fontcolor="black"] + "galera-bundle-docker-1_monitor_0 centos2" [ style=bold color="green" fontcolor="black"] + "galera-bundle-docker-2_monitor_0 centos1" [ style=bold color="green" fontcolor="black"] + "galera-bundle-docker-2_monitor_0 centos2" [ style=bold color="green" fontcolor="black"] +diff --git a/cts/scheduler/exp/bundle-probe-order-2.exp b/cts/scheduler/exp/bundle-probe-order-2.exp +index d6174e7..5b28050 100644 +--- a/cts/scheduler/exp/bundle-probe-order-2.exp ++++ b/cts/scheduler/exp/bundle-probe-order-2.exp +@@ -1,6 +1,33 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -8,7 +35,7 @@ + + + +- ++ + + + +@@ -17,7 +44,7 @@ + + + +- ++ + + + +@@ -26,7 +53,7 @@ + + + +- ++ + + + +diff --git a/cts/scheduler/exp/bundle-probe-order-3.exp b/cts/scheduler/exp/bundle-probe-order-3.exp +index e1f60e7..69140a4 100644 +--- a/cts/scheduler/exp/bundle-probe-order-3.exp ++++ b/cts/scheduler/exp/bundle-probe-order-3.exp +@@ -1,6 +1,15 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -8,7 +17,7 @@ + + + +- ++ + + + +@@ -17,7 +26,7 @@ + + + +- ++ + + + +@@ -26,7 +35,7 @@ + + + +- ++ + + + +@@ -35,7 +44,7 @@ + + + +- ++ + + + +@@ -44,7 +53,7 @@ + + + +- ++ + + + +@@ -53,7 +62,7 @@ + + + +- ++ + + + +diff --git a/cts/scheduler/summary/bundle-probe-order-2.summary b/cts/scheduler/summary/bundle-probe-order-2.summary +index 681d607..024c472 100644 +--- a/cts/scheduler/summary/bundle-probe-order-2.summary ++++ b/cts/scheduler/summary/bundle-probe-order-2.summary +@@ -13,6 +13,9 @@ Current cluster status: + Transition Summary: + + Executing Cluster Transition: ++ * Resource action: galera:0 monitor on galera-bundle-0 ++ * Resource action: galera-bundle-docker-0 monitor=60000 on centos2 ++ * Resource action: galera-bundle-0 monitor=30000 on centos2 + * Resource action: galera-bundle-docker-1 monitor on centos2 + * Resource action: galera-bundle-docker-2 monitor on centos3 + * Resource action: galera-bundle-docker-2 monitor on centos2 +diff --git a/cts/scheduler/summary/bundle-probe-order-3.summary b/cts/scheduler/summary/bundle-probe-order-3.summary +index f089618..331bd87 100644 +--- a/cts/scheduler/summary/bundle-probe-order-3.summary ++++ b/cts/scheduler/summary/bundle-probe-order-3.summary +@@ -12,6 +12,7 @@ Current cluster status: + Transition Summary: + + Executing Cluster Transition: ++ * Resource action: galera-bundle-docker-0 monitor=60000 on centos2 + * Resource action: galera-bundle-0 monitor on centos3 + * Resource action: galera-bundle-0 monitor on centos2 + * Resource action: galera-bundle-0 monitor on centos1 +-- +1.8.3.1 + + +From cb9c294a7ef22916866e0e42e51e88c2b1a61c2e Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Wed, 14 Jul 2021 17:23:11 -0500 +Subject: [PATCH 3/3] Test: scheduler: add test for probe of unmanaged resource + on pending node + +No probes should be scheduled in this case +--- + cts/cts-scheduler.in | 1 + + cts/scheduler/dot/probe-pending-node.dot | 2 + + cts/scheduler/exp/probe-pending-node.exp | 1 + + cts/scheduler/scores/probe-pending-node.scores | 61 ++++++ + cts/scheduler/summary/probe-pending-node.summary | 55 +++++ + cts/scheduler/xml/probe-pending-node.xml | 247 +++++++++++++++++++++++ + 6 files changed, 367 insertions(+) + create mode 100644 cts/scheduler/dot/probe-pending-node.dot + create mode 100644 cts/scheduler/exp/probe-pending-node.exp + create mode 100644 cts/scheduler/scores/probe-pending-node.scores + create mode 100644 cts/scheduler/summary/probe-pending-node.summary + create mode 100644 cts/scheduler/xml/probe-pending-node.xml + +diff --git a/cts/cts-scheduler.in b/cts/cts-scheduler.in +index fc9790b..7ba2415 100644 +--- a/cts/cts-scheduler.in ++++ b/cts/cts-scheduler.in +@@ -110,6 +110,7 @@ TESTS = [ + [ "probe-2", "Correctly re-probe cloned groups" ], + [ "probe-3", "Probe (pending node)" ], + [ "probe-4", "Probe (pending node + stopped resource)" ], ++ [ "probe-pending-node", "Probe (pending node + unmanaged resource)" ], + [ "standby", "Standby" ], + [ "comments", "Comments" ], + ], +diff --git a/cts/scheduler/dot/probe-pending-node.dot b/cts/scheduler/dot/probe-pending-node.dot +new file mode 100644 +index 0000000..d8f1c9f +--- /dev/null ++++ b/cts/scheduler/dot/probe-pending-node.dot +@@ -0,0 +1,2 @@ ++ digraph "g" { ++} +diff --git a/cts/scheduler/exp/probe-pending-node.exp b/cts/scheduler/exp/probe-pending-node.exp +new file mode 100644 +index 0000000..56e315f +--- /dev/null ++++ b/cts/scheduler/exp/probe-pending-node.exp +@@ -0,0 +1 @@ ++ +diff --git a/cts/scheduler/scores/probe-pending-node.scores b/cts/scheduler/scores/probe-pending-node.scores +new file mode 100644 +index 0000000..020a1a0 +--- /dev/null ++++ b/cts/scheduler/scores/probe-pending-node.scores +@@ -0,0 +1,61 @@ ++ ++pcmk__clone_allocate: fs_UC5_SAPMNT-clone allocation score on gcdoubwap01: 0 ++pcmk__clone_allocate: fs_UC5_SAPMNT-clone allocation score on gcdoubwap02: 0 ++pcmk__clone_allocate: fs_UC5_SAPMNT:0 allocation score on gcdoubwap01: 0 ++pcmk__clone_allocate: fs_UC5_SAPMNT:0 allocation score on gcdoubwap02: 0 ++pcmk__clone_allocate: fs_UC5_SAPMNT:1 allocation score on gcdoubwap01: 0 ++pcmk__clone_allocate: fs_UC5_SAPMNT:1 allocation score on gcdoubwap02: 0 ++pcmk__clone_allocate: fs_UC5_SYS-clone allocation score on gcdoubwap01: 0 ++pcmk__clone_allocate: fs_UC5_SYS-clone allocation score on gcdoubwap02: 0 ++pcmk__clone_allocate: fs_UC5_SYS:0 allocation score on gcdoubwap01: 0 ++pcmk__clone_allocate: fs_UC5_SYS:0 allocation score on gcdoubwap02: 0 ++pcmk__clone_allocate: fs_UC5_SYS:1 allocation score on gcdoubwap01: 0 ++pcmk__clone_allocate: fs_UC5_SYS:1 allocation score on gcdoubwap02: 0 ++pcmk__group_allocate: fs_UC5_ascs allocation score on gcdoubwap01: 0 ++pcmk__group_allocate: fs_UC5_ascs allocation score on gcdoubwap02: 0 ++pcmk__group_allocate: fs_UC5_ers allocation score on gcdoubwap01: 0 ++pcmk__group_allocate: fs_UC5_ers allocation score on gcdoubwap02: 0 ++pcmk__group_allocate: grp_UC5_ascs allocation score on gcdoubwap01: 0 ++pcmk__group_allocate: grp_UC5_ascs allocation score on gcdoubwap02: 0 ++pcmk__group_allocate: grp_UC5_ers allocation score on gcdoubwap01: 0 ++pcmk__group_allocate: grp_UC5_ers allocation score on gcdoubwap02: 0 ++pcmk__group_allocate: rsc_sap_UC5_ASCS11 allocation score on gcdoubwap01: 0 ++pcmk__group_allocate: rsc_sap_UC5_ASCS11 allocation score on gcdoubwap02: 0 ++pcmk__group_allocate: rsc_sap_UC5_ERS12 allocation score on gcdoubwap01: 0 ++pcmk__group_allocate: rsc_sap_UC5_ERS12 allocation score on gcdoubwap02: 0 ++pcmk__group_allocate: rsc_vip_gcp_ascs allocation score on gcdoubwap01: INFINITY ++pcmk__group_allocate: rsc_vip_gcp_ascs allocation score on gcdoubwap02: 0 ++pcmk__group_allocate: rsc_vip_gcp_ers allocation score on gcdoubwap01: 0 ++pcmk__group_allocate: rsc_vip_gcp_ers allocation score on gcdoubwap02: 0 ++pcmk__group_allocate: rsc_vip_init_ers allocation score on gcdoubwap01: 0 ++pcmk__group_allocate: rsc_vip_init_ers allocation score on gcdoubwap02: 0 ++pcmk__group_allocate: rsc_vip_int_ascs allocation score on gcdoubwap01: 0 ++pcmk__group_allocate: rsc_vip_int_ascs allocation score on gcdoubwap02: 0 ++pcmk__native_allocate: fs_UC5_SAPMNT:0 allocation score on gcdoubwap01: 0 ++pcmk__native_allocate: fs_UC5_SAPMNT:0 allocation score on gcdoubwap02: -INFINITY ++pcmk__native_allocate: fs_UC5_SAPMNT:1 allocation score on gcdoubwap01: 0 ++pcmk__native_allocate: fs_UC5_SAPMNT:1 allocation score on gcdoubwap02: -INFINITY ++pcmk__native_allocate: fs_UC5_SYS:0 allocation score on gcdoubwap01: 0 ++pcmk__native_allocate: fs_UC5_SYS:0 allocation score on gcdoubwap02: -INFINITY ++pcmk__native_allocate: fs_UC5_SYS:1 allocation score on gcdoubwap01: 0 ++pcmk__native_allocate: fs_UC5_SYS:1 allocation score on gcdoubwap02: -INFINITY ++pcmk__native_allocate: fs_UC5_ascs allocation score on gcdoubwap01: 0 ++pcmk__native_allocate: fs_UC5_ascs allocation score on gcdoubwap02: -INFINITY ++pcmk__native_allocate: fs_UC5_ers allocation score on gcdoubwap01: -INFINITY ++pcmk__native_allocate: fs_UC5_ers allocation score on gcdoubwap02: -INFINITY ++pcmk__native_allocate: rsc_sap_UC5_ASCS11 allocation score on gcdoubwap01: -INFINITY ++pcmk__native_allocate: rsc_sap_UC5_ASCS11 allocation score on gcdoubwap02: -INFINITY ++pcmk__native_allocate: rsc_sap_UC5_ERS12 allocation score on gcdoubwap01: -INFINITY ++pcmk__native_allocate: rsc_sap_UC5_ERS12 allocation score on gcdoubwap02: -INFINITY ++pcmk__native_allocate: rsc_vip_gcp_ascs allocation score on gcdoubwap01: -INFINITY ++pcmk__native_allocate: rsc_vip_gcp_ascs allocation score on gcdoubwap02: -INFINITY ++pcmk__native_allocate: rsc_vip_gcp_ers allocation score on gcdoubwap01: -INFINITY ++pcmk__native_allocate: rsc_vip_gcp_ers allocation score on gcdoubwap02: -INFINITY ++pcmk__native_allocate: rsc_vip_init_ers allocation score on gcdoubwap01: 0 ++pcmk__native_allocate: rsc_vip_init_ers allocation score on gcdoubwap02: -INFINITY ++pcmk__native_allocate: rsc_vip_int_ascs allocation score on gcdoubwap01: INFINITY ++pcmk__native_allocate: rsc_vip_int_ascs allocation score on gcdoubwap02: -INFINITY ++pcmk__native_allocate: stonith_gcdoubwap01 allocation score on gcdoubwap01: -INFINITY ++pcmk__native_allocate: stonith_gcdoubwap01 allocation score on gcdoubwap02: 0 ++pcmk__native_allocate: stonith_gcdoubwap02 allocation score on gcdoubwap01: 0 ++pcmk__native_allocate: stonith_gcdoubwap02 allocation score on gcdoubwap02: -INFINITY +diff --git a/cts/scheduler/summary/probe-pending-node.summary b/cts/scheduler/summary/probe-pending-node.summary +new file mode 100644 +index 0000000..208186b +--- /dev/null ++++ b/cts/scheduler/summary/probe-pending-node.summary +@@ -0,0 +1,55 @@ ++Using the original execution date of: 2021-06-11 13:55:24Z ++ ++ *** Resource management is DISABLED *** ++ The cluster will not attempt to start, stop or recover services ++ ++Current cluster status: ++ * Node List: ++ * Node gcdoubwap02: pending ++ * Online: [ gcdoubwap01 ] ++ ++ * Full List of Resources: ++ * stonith_gcdoubwap01 (stonith:fence_gce): Stopped (unmanaged) ++ * stonith_gcdoubwap02 (stonith:fence_gce): Stopped (unmanaged) ++ * Clone Set: fs_UC5_SAPMNT-clone [fs_UC5_SAPMNT] (unmanaged): ++ * Stopped: [ gcdoubwap01 gcdoubwap02 ] ++ * Clone Set: fs_UC5_SYS-clone [fs_UC5_SYS] (unmanaged): ++ * Stopped: [ gcdoubwap01 gcdoubwap02 ] ++ * Resource Group: grp_UC5_ascs (unmanaged): ++ * rsc_vip_int_ascs (ocf:heartbeat:IPaddr2): Stopped (unmanaged) ++ * rsc_vip_gcp_ascs (ocf:heartbeat:gcp-vpc-move-vip): Started gcdoubwap01 (unmanaged) ++ * fs_UC5_ascs (ocf:heartbeat:Filesystem): Stopped (unmanaged) ++ * rsc_sap_UC5_ASCS11 (ocf:heartbeat:SAPInstance): Stopped (unmanaged) ++ * Resource Group: grp_UC5_ers (unmanaged): ++ * rsc_vip_init_ers (ocf:heartbeat:IPaddr2): Stopped (unmanaged) ++ * rsc_vip_gcp_ers (ocf:heartbeat:gcp-vpc-move-vip): Stopped (unmanaged) ++ * fs_UC5_ers (ocf:heartbeat:Filesystem): Stopped (unmanaged) ++ * rsc_sap_UC5_ERS12 (ocf:heartbeat:SAPInstance): Stopped (unmanaged) ++ ++Transition Summary: ++ ++Executing Cluster Transition: ++Using the original execution date of: 2021-06-11 13:55:24Z ++ ++Revised Cluster Status: ++ * Node List: ++ * Node gcdoubwap02: pending ++ * Online: [ gcdoubwap01 ] ++ ++ * Full List of Resources: ++ * stonith_gcdoubwap01 (stonith:fence_gce): Stopped (unmanaged) ++ * stonith_gcdoubwap02 (stonith:fence_gce): Stopped (unmanaged) ++ * Clone Set: fs_UC5_SAPMNT-clone [fs_UC5_SAPMNT] (unmanaged): ++ * Stopped: [ gcdoubwap01 gcdoubwap02 ] ++ * Clone Set: fs_UC5_SYS-clone [fs_UC5_SYS] (unmanaged): ++ * Stopped: [ gcdoubwap01 gcdoubwap02 ] ++ * Resource Group: grp_UC5_ascs (unmanaged): ++ * rsc_vip_int_ascs (ocf:heartbeat:IPaddr2): Stopped (unmanaged) ++ * rsc_vip_gcp_ascs (ocf:heartbeat:gcp-vpc-move-vip): Started gcdoubwap01 (unmanaged) ++ * fs_UC5_ascs (ocf:heartbeat:Filesystem): Stopped (unmanaged) ++ * rsc_sap_UC5_ASCS11 (ocf:heartbeat:SAPInstance): Stopped (unmanaged) ++ * Resource Group: grp_UC5_ers (unmanaged): ++ * rsc_vip_init_ers (ocf:heartbeat:IPaddr2): Stopped (unmanaged) ++ * rsc_vip_gcp_ers (ocf:heartbeat:gcp-vpc-move-vip): Stopped (unmanaged) ++ * fs_UC5_ers (ocf:heartbeat:Filesystem): Stopped (unmanaged) ++ * rsc_sap_UC5_ERS12 (ocf:heartbeat:SAPInstance): Stopped (unmanaged) +diff --git a/cts/scheduler/xml/probe-pending-node.xml b/cts/scheduler/xml/probe-pending-node.xml +new file mode 100644 +index 0000000..9f55c92 +--- /dev/null ++++ b/cts/scheduler/xml/probe-pending-node.xml +@@ -0,0 +1,247 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +1.8.3.1 + diff --git a/SOURCES/011-crm_attribute-regression.patch b/SOURCES/011-crm_attribute-regression.patch new file mode 100644 index 0000000..7263313 --- /dev/null +++ b/SOURCES/011-crm_attribute-regression.patch @@ -0,0 +1,150 @@ +From ea5510dd979bb6d375324cda26925d9e7c4362f5 Mon Sep 17 00:00:00 2001 +From: Chris Lumens +Date: Mon, 19 Jul 2021 10:04:16 -0400 +Subject: [PATCH 1/2] Low: tools: The --get-value option does not require an + arg. + +Regression in 2.1.0 introduced by 15f5c2901. +--- + tools/crm_attribute.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/crm_attribute.c b/tools/crm_attribute.c +index 2cc8d26..8a5b4e4 100644 +--- a/tools/crm_attribute.c ++++ b/tools/crm_attribute.c +@@ -242,7 +242,7 @@ static GOptionEntry deprecated_entries[] = { + NULL, NULL + }, + +- { "get-value", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_CALLBACK, value_cb, ++ { "get-value", 0, G_OPTION_FLAG_HIDDEN|G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, value_cb, + NULL, NULL + }, + +-- +1.8.3.1 + + +From ef054d943afe8e60017f6adc4e25f88a59ac91a4 Mon Sep 17 00:00:00 2001 +From: Chris Lumens +Date: Mon, 19 Jul 2021 11:37:04 -0400 +Subject: [PATCH 2/2] Low: libcrmcommon: Allow negative numbers as cmdline + options. + +The bug here is that negative numbers (for instance, negative scores) +are not supported as command line arguments. Because we break up a +string that starts with a single dash into multiple arguments, "-1000" +becomes "-1", "-0", "-0", and "-0". + +Because we don't have enough information about what is happening on the +command line, the best we can do here is recognize something as a +negative number and pass it on. Any errors will have to be detected at +a later step. + +Also note that we only recognize negative numbers if they start with +1-9. Starting with 0 will be recognized as some sort of string. + +Regression in 2.1.0 caused by a long-standing bug in +pcmk__cmdline_preproc_test. +--- + lib/common/cmdline.c | 29 ++++++++++++++++++++++ + .../tests/cmdline/pcmk__cmdline_preproc_test.c | 24 +++++++++++++++++- + 2 files changed, 52 insertions(+), 1 deletion(-) + +diff --git a/lib/common/cmdline.c b/lib/common/cmdline.c +index 7c95d02..9c1b810 100644 +--- a/lib/common/cmdline.c ++++ b/lib/common/cmdline.c +@@ -9,6 +9,7 @@ + + #include + ++#include + #include + + #include +@@ -189,6 +190,34 @@ pcmk__cmdline_preproc(char **argv, const char *special) { + /* Skip over leading dash */ + char *ch = argv[i]+1; + ++ /* This looks like the start of a number, which means it is a negative ++ * number. It's probably the argument to the preceeding option, but ++ * we can't know that here. Copy it over and let whatever handles ++ * arguments next figure it out. ++ */ ++ if (*ch != '\0' && *ch >= '1' && *ch <= '9') { ++ bool is_numeric = true; ++ ++ while (*ch != '\0') { ++ if (!isdigit(*ch)) { ++ is_numeric = false; ++ break; ++ } ++ ++ ch++; ++ } ++ ++ if (is_numeric) { ++ g_ptr_array_add(arr, g_strdup_printf("%s", argv[i])); ++ continue; ++ } else { ++ /* This argument wasn't entirely numeric. Reset ch to the ++ * beginning so we can process it one character at a time. ++ */ ++ ch = argv[i]+1; ++ } ++ } ++ + while (*ch != '\0') { + /* This is a special short argument that takes an option. getopt + * allows values to be interspersed with a list of arguments, but +diff --git a/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c b/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c +index b8506c6..9a752ef 100644 +--- a/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c ++++ b/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c +@@ -1,5 +1,5 @@ + /* +- * Copyright 2020 the Pacemaker project contributors ++ * Copyright 2020-2021 the Pacemaker project contributors + * + * The version control history for this file may have further details. + * +@@ -86,6 +86,26 @@ long_arg(void) { + g_strfreev(processed); + } + ++static void ++negative_score(void) { ++ const char *argv[] = { "-v", "-1000", NULL }; ++ const gchar *expected[] = { "-v", "-1000", NULL }; ++ ++ gchar **processed = pcmk__cmdline_preproc((char **) argv, "v"); ++ LISTS_EQ(processed, expected); ++ g_strfreev(processed); ++} ++ ++static void ++negative_score_2(void) { ++ const char *argv[] = { "-1i3", NULL }; ++ const gchar *expected[] = { "-1", "-i", "-3", NULL }; ++ ++ gchar **processed = pcmk__cmdline_preproc((char **) argv, NULL); ++ LISTS_EQ(processed, expected); ++ g_strfreev(processed); ++} ++ + int + main(int argc, char **argv) + { +@@ -98,5 +118,7 @@ main(int argc, char **argv) + g_test_add_func("/common/cmdline/preproc/special_args", special_args); + g_test_add_func("/common/cmdline/preproc/special_arg_at_end", special_arg_at_end); + g_test_add_func("/common/cmdline/preproc/long_arg", long_arg); ++ g_test_add_func("/common/cmdline/preproc/negative_score", negative_score); ++ g_test_add_func("/common/cmdline/preproc/negative_score_2", negative_score_2); + return g_test_run(); + } +-- +1.8.3.1 + diff --git a/SOURCES/012-string-arguments.patch b/SOURCES/012-string-arguments.patch new file mode 100644 index 0000000..6419117 --- /dev/null +++ b/SOURCES/012-string-arguments.patch @@ -0,0 +1,221 @@ +From 2eee93e8f9ea2daa81769bc69843d63ced1a7112 Mon Sep 17 00:00:00 2001 +From: Chris Lumens +Date: Tue, 20 Jul 2021 16:39:07 -0400 +Subject: [PATCH 1/2] Low: tools: Audit command line options. + +This just goes through and makes sure the command line options that take +arguments are in the special parameter to pcmk__cmdline_preproc, and +that options that do not take arguments are not. +--- + tools/crm_attribute.c | 2 +- + tools/crm_error.c | 2 +- + tools/crm_resource.c | 2 +- + tools/crm_rule.c | 2 +- + tools/crm_simulate.c | 2 +- + tools/crmadmin.c | 2 +- + tools/stonith_admin.c | 2 +- + 7 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/tools/crm_attribute.c b/tools/crm_attribute.c +index 8a5b4e4..6bd4e2a 100644 +--- a/tools/crm_attribute.c ++++ b/tools/crm_attribute.c +@@ -312,7 +312,7 @@ main(int argc, char **argv) + + GOptionGroup *output_group = NULL; + pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY); +- gchar **processed_args = pcmk__cmdline_preproc(argv, "DGNPdilnpstv"); ++ gchar **processed_args = pcmk__cmdline_preproc(argv, "NPUdilnpstv"); + GOptionContext *context = build_arg_context(args, &output_group); + + if (!g_option_context_parse_strv(context, &processed_args, &error)) { +diff --git a/tools/crm_error.c b/tools/crm_error.c +index b4328ce..923f393 100644 +--- a/tools/crm_error.c ++++ b/tools/crm_error.c +@@ -79,7 +79,7 @@ main(int argc, char **argv) + + GOptionGroup *output_group = NULL; + pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY); +- gchar **processed_args = pcmk__cmdline_preproc(argv, "lrnX"); ++ gchar **processed_args = pcmk__cmdline_preproc(argv, NULL); + GOptionContext *context = build_arg_context(args, &output_group); + + if (!g_option_context_parse_strv(context, &processed_args, &error)) { +diff --git a/tools/crm_resource.c b/tools/crm_resource.c +index fa7902c..d8e140f 100644 +--- a/tools/crm_resource.c ++++ b/tools/crm_resource.c +@@ -1530,7 +1530,7 @@ main(int argc, char **argv) + */ + + args = pcmk__new_common_args(SUMMARY); +- processed_args = pcmk__cmdline_preproc(argv, "GINSTdginpstuv"); ++ processed_args = pcmk__cmdline_preproc(argv, "GHINSTdginpstuvx"); + context = build_arg_context(args, &output_group); + + pcmk__register_formats(output_group, formats); +diff --git a/tools/crm_rule.c b/tools/crm_rule.c +index 8b19bcd..30c5155 100644 +--- a/tools/crm_rule.c ++++ b/tools/crm_rule.c +@@ -239,7 +239,7 @@ main(int argc, char **argv) + + pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY); + GOptionContext *context = build_arg_context(args); +- gchar **processed_args = pcmk__cmdline_preproc(argv, "nopNO"); ++ gchar **processed_args = pcmk__cmdline_preproc(argv, "drX"); + + if (!g_option_context_parse_strv(context, &processed_args, &error)) { + exit_code = CRM_EX_USAGE; +diff --git a/tools/crm_simulate.c b/tools/crm_simulate.c +index 0406bff..c83b1b1 100644 +--- a/tools/crm_simulate.c ++++ b/tools/crm_simulate.c +@@ -865,7 +865,7 @@ main(int argc, char **argv) + + GOptionGroup *output_group = NULL; + pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY); +- gchar **processed_args = pcmk__cmdline_preproc(argv, "bdefgiqrtuwxDFGINO"); ++ gchar **processed_args = pcmk__cmdline_preproc(argv, "bdefgiqrtuwxDFGINOP"); + GOptionContext *context = build_arg_context(args, &output_group); + + /* This must come before g_option_context_parse_strv. */ +diff --git a/tools/crmadmin.c b/tools/crmadmin.c +index 5cbde1b..b98f282 100644 +--- a/tools/crmadmin.c ++++ b/tools/crmadmin.c +@@ -188,7 +188,7 @@ main(int argc, char **argv) + + GOptionGroup *output_group = NULL; + pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY); +- gchar **processed_args = pcmk__cmdline_preproc(argv, "itBDEHKNPS"); ++ gchar **processed_args = pcmk__cmdline_preproc(argv, "itKNS"); + GOptionContext *context = build_arg_context(args, &output_group); + + pcmk__register_formats(output_group, formats); +diff --git a/tools/stonith_admin.c b/tools/stonith_admin.c +index 6773cea..2d48326 100644 +--- a/tools/stonith_admin.c ++++ b/tools/stonith_admin.c +@@ -349,7 +349,7 @@ main(int argc, char **argv) + + GOptionGroup *output_group = NULL; + pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY); +- gchar **processed_args = pcmk__cmdline_preproc(argv, "adehilorstvBCDFHQRTU"); ++ gchar **processed_args = pcmk__cmdline_preproc(argv, "adehilorstvyBCDFHQRTU"); + GOptionContext *context = build_arg_context(args, &output_group); + + pcmk__register_formats(output_group, formats); +-- +1.8.3.1 + + +From 8301678ad1162450814d2fea5288aefe47a67a74 Mon Sep 17 00:00:00 2001 +From: Chris Lumens +Date: Tue, 20 Jul 2021 16:40:58 -0400 +Subject: [PATCH 2/2] Low: libcrmcommon: Also allow string arguments that start + with a dash. + +There's various places where an option to a command line argument could +itself be a valid command line argument. For instance: + + crm_attribute -n crm_mon_options -v "-1i3" + +The previous patching to pcmk__cmdline_preproc did not take this into +account. With this patch, options that are last in a string (or by +themselves) and take an argument will have the next command line option +grabbed and copied straight through without processing. + +Regression in 2.1.0 caused by a long-standing bug in pcmk__cmdline_preproc. +--- + lib/common/cmdline.c | 8 ++++++ + .../tests/cmdline/pcmk__cmdline_preproc_test.c | 33 ++++++++++++++++++++++ + 2 files changed, 41 insertions(+) + +diff --git a/lib/common/cmdline.c b/lib/common/cmdline.c +index 9c1b810..1ca6147 100644 +--- a/lib/common/cmdline.c ++++ b/lib/common/cmdline.c +@@ -146,6 +146,7 @@ gchar ** + pcmk__cmdline_preproc(char **argv, const char *special) { + GPtrArray *arr = NULL; + bool saw_dash_dash = false; ++ bool copy_option = false; + + if (argv == NULL) { + return NULL; +@@ -175,6 +176,12 @@ pcmk__cmdline_preproc(char **argv, const char *special) { + continue; + } + ++ if (copy_option == true) { ++ g_ptr_array_add(arr, g_strdup(argv[i])); ++ copy_option = false; ++ continue; ++ } ++ + /* This is just a dash by itself. That could indicate stdin/stdout, or + * it could be user error. Copy it over and let glib figure it out. + */ +@@ -239,6 +246,7 @@ pcmk__cmdline_preproc(char **argv, const char *special) { + */ + } else { + g_ptr_array_add(arr, g_strdup_printf("-%c", *ch)); ++ copy_option = true; + ch++; + } + +diff --git a/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c b/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c +index 9a752ef..edc5640 100644 +--- a/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c ++++ b/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c +@@ -106,6 +106,36 @@ negative_score_2(void) { + g_strfreev(processed); + } + ++static void ++string_arg_with_dash(void) { ++ const char *argv[] = { "-n", "crm_mon_options", "-v", "--opt1 --opt2", NULL }; ++ const gchar *expected[] = { "-n", "crm_mon_options", "-v", "--opt1 --opt2", NULL }; ++ ++ gchar **processed = pcmk__cmdline_preproc((char **) argv, "v"); ++ LISTS_EQ(processed, expected); ++ g_strfreev(processed); ++} ++ ++static void ++string_arg_with_dash_2(void) { ++ const char *argv[] = { "-n", "crm_mon_options", "-v", "-1i3", NULL }; ++ const gchar *expected[] = { "-n", "crm_mon_options", "-v", "-1i3", NULL }; ++ ++ gchar **processed = pcmk__cmdline_preproc((char **) argv, "v"); ++ LISTS_EQ(processed, expected); ++ g_strfreev(processed); ++} ++ ++static void ++string_arg_with_dash_3(void) { ++ const char *argv[] = { "-abc", "-1i3", NULL }; ++ const gchar *expected[] = { "-a", "-b", "-c", "-1i3", NULL }; ++ ++ gchar **processed = pcmk__cmdline_preproc((char **) argv, "c"); ++ LISTS_EQ(processed, expected); ++ g_strfreev(processed); ++} ++ + int + main(int argc, char **argv) + { +@@ -120,5 +150,8 @@ main(int argc, char **argv) + g_test_add_func("/common/cmdline/preproc/long_arg", long_arg); + g_test_add_func("/common/cmdline/preproc/negative_score", negative_score); + g_test_add_func("/common/cmdline/preproc/negative_score_2", negative_score_2); ++ g_test_add_func("/common/cmdline/preproc/string_arg_with_dash", string_arg_with_dash); ++ g_test_add_func("/common/cmdline/preproc/string_arg_with_dash_2", string_arg_with_dash_2); ++ g_test_add_func("/common/cmdline/preproc/string_arg_with_dash_3", string_arg_with_dash_3); + return g_test_run(); + } +-- +1.8.3.1 + diff --git a/SOURCES/013-leaks.patch b/SOURCES/013-leaks.patch new file mode 100644 index 0000000..daa42b8 --- /dev/null +++ b/SOURCES/013-leaks.patch @@ -0,0 +1,241 @@ +From bee54eba4d9c28d3a7907a3e13a5deeee6bc0916 Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Tue, 27 Jul 2021 11:01:04 -0500 +Subject: [PATCH 1/2] Low: tools: avoid (insignificant) memory leaks + +detected by valgrind +--- + lib/pacemaker/pcmk_cluster_queries.c | 2 ++ + tools/crm_diff.c | 2 +- + tools/crm_resource.c | 33 ++++++++++++++++++++------------- + tools/crm_resource_ban.c | 2 +- + 4 files changed, 24 insertions(+), 15 deletions(-) + +diff --git a/lib/pacemaker/pcmk_cluster_queries.c b/lib/pacemaker/pcmk_cluster_queries.c +index c68cf9d..46e5538 100644 +--- a/lib/pacemaker/pcmk_cluster_queries.c ++++ b/lib/pacemaker/pcmk_cluster_queries.c +@@ -440,6 +440,7 @@ pcmk__list_nodes(pcmk__output_t *out, char *node_types, gboolean BASH_EXPORT) + } + rc = the_cib->cmds->signon(the_cib, crm_system_name, cib_command); + if (rc != pcmk_ok) { ++ cib_delete(the_cib); + return pcmk_legacy2rc(rc); + } + +@@ -488,6 +489,7 @@ pcmk__list_nodes(pcmk__output_t *out, char *node_types, gboolean BASH_EXPORT) + free_xml(xml_node); + } + the_cib->cmds->signoff(the_cib); ++ cib_delete(the_cib); + return pcmk_legacy2rc(rc); + } + +diff --git a/tools/crm_diff.c b/tools/crm_diff.c +index b37f0ea..9890c10 100644 +--- a/tools/crm_diff.c ++++ b/tools/crm_diff.c +@@ -383,5 +383,5 @@ done: + free_xml(object_2); + + pcmk__output_and_clear_error(error, NULL); +- return exit_code; ++ crm_exit(exit_code); + } +diff --git a/tools/crm_resource.c b/tools/crm_resource.c +index d8e140f..8ca90cb 100644 +--- a/tools/crm_resource.c ++++ b/tools/crm_resource.c +@@ -1081,6 +1081,8 @@ clear_constraints(pcmk__output_t *out, xmlNodePtr *cib_xml_copy) + g_set_error(&error, PCMK__RC_ERROR, rc, + "Could not get modified CIB: %s\n", pcmk_strerror(rc)); + g_list_free(before); ++ free_xml(*cib_xml_copy); ++ *cib_xml_copy = NULL; + return rc; + } + +@@ -1232,29 +1234,34 @@ populate_working_set(xmlNodePtr *cib_xml_copy) + + if (options.xml_file != NULL) { + *cib_xml_copy = filename2xml(options.xml_file); ++ if (*cib_xml_copy == NULL) { ++ rc = pcmk_rc_cib_corrupt; ++ } + } else { + rc = cib_conn->cmds->query(cib_conn, NULL, cib_xml_copy, cib_scope_local | cib_sync_call); + rc = pcmk_legacy2rc(rc); + } + +- if(rc != pcmk_rc_ok) { +- return rc; ++ if (rc == pcmk_rc_ok) { ++ data_set = pe_new_working_set(); ++ if (data_set == NULL) { ++ rc = ENOMEM; ++ } else { ++ pe__set_working_set_flags(data_set, ++ pe_flag_no_counts|pe_flag_no_compat); ++ data_set->priv = out; ++ rc = update_working_set_xml(data_set, cib_xml_copy); ++ } + } + +- /* Populate the working set instance */ +- data_set = pe_new_working_set(); +- if (data_set == NULL) { +- rc = ENOMEM; ++ if (rc != pcmk_rc_ok) { ++ free_xml(*cib_xml_copy); ++ *cib_xml_copy = NULL; + return rc; + } + +- pe__set_working_set_flags(data_set, pe_flag_no_counts|pe_flag_no_compat); +- data_set->priv = out; +- rc = update_working_set_xml(data_set, cib_xml_copy); +- if (rc == pcmk_rc_ok) { +- cluster_status(data_set); +- } +- return rc; ++ cluster_status(data_set); ++ return pcmk_rc_ok; + } + + static int +diff --git a/tools/crm_resource_ban.c b/tools/crm_resource_ban.c +index a297d49..2c4f48d 100644 +--- a/tools/crm_resource_ban.c ++++ b/tools/crm_resource_ban.c +@@ -292,7 +292,7 @@ resource_clear_node_in_location(const char *rsc_id, const char *host, cib_t * ci + rc = pcmk_legacy2rc(rc); + } + +- free(fragment); ++ free_xml(fragment); + return rc; + } + +-- +1.8.3.1 + + +From a30ff4a87f291a0c9e03c4efb9c9046d2ac594f1 Mon Sep 17 00:00:00 2001 +From: Ken Gaillot +Date: Tue, 27 Jul 2021 11:26:59 -0500 +Subject: [PATCH 2/2] Fix: tools: avoid memory leaks in crm_mon + +could be significant in an interactive session + +regressions introduced in 2.0.4 and 2.0.5 +--- + lib/pengine/bundle.c | 3 ++- + lib/pengine/clone.c | 5 ++--- + lib/pengine/pe_output.c | 3 +++ + 3 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/lib/pengine/bundle.c b/lib/pengine/bundle.c +index 6ba786a..7e1d428 100644 +--- a/lib/pengine/bundle.c ++++ b/lib/pengine/bundle.c +@@ -1497,7 +1497,7 @@ pe__bundle_xml(pcmk__output_t *out, va_list args) + for (GList *gIter = bundle_data->replicas; gIter != NULL; + gIter = gIter->next) { + pe__bundle_replica_t *replica = gIter->data; +- char *id = pcmk__itoa(replica->offset); ++ char *id = NULL; + gboolean print_ip, print_child, print_ctnr, print_remote; + + CRM_ASSERT(replica); +@@ -1531,6 +1531,7 @@ pe__bundle_xml(pcmk__output_t *out, va_list args) + CRM_ASSERT(rc == pcmk_rc_ok); + } + ++ id = pcmk__itoa(replica->offset); + rc = pe__name_and_nvpairs_xml(out, true, "replica", 1, "id", id); + free(id); + CRM_ASSERT(rc == pcmk_rc_ok); +diff --git a/lib/pengine/clone.c b/lib/pengine/clone.c +index 6323692..ab91fd1 100644 +--- a/lib/pengine/clone.c ++++ b/lib/pengine/clone.c +@@ -807,10 +807,10 @@ pe__clone_html(pcmk__output_t *out, va_list args) + pcmk__add_word(&list_text, &list_text_len, host->details->uname); + active_instances++; + } ++ g_list_free(promoted_list); + + if (list_text != NULL) { + out->list_item(out, NULL, PROMOTED_INSTANCES ": [ %s ]", list_text); +- g_list_free(promoted_list); + free(list_text); + list_text = NULL; + list_text_len = 0; +@@ -828,6 +828,7 @@ pe__clone_html(pcmk__output_t *out, va_list args) + pcmk__add_word(&list_text, &list_text_len, host->details->uname); + active_instances++; + } ++ g_list_free(started_list); + + if (list_text != NULL) { + if (pcmk_is_set(rsc->flags, pe_rsc_promotable)) { +@@ -847,7 +848,6 @@ pe__clone_html(pcmk__output_t *out, va_list args) + out->list_item(out, NULL, "Started: [ %s ]", list_text); + } + +- g_list_free(started_list); + free(list_text); + list_text = NULL; + list_text_len = 0; +@@ -1048,10 +1048,10 @@ pe__clone_text(pcmk__output_t *out, va_list args) + pcmk__add_word(&list_text, &list_text_len, host->details->uname); + active_instances++; + } ++ g_list_free(promoted_list); + + if (list_text != NULL) { + out->list_item(out, PROMOTED_INSTANCES, "[ %s ]", list_text); +- g_list_free(promoted_list); + free(list_text); + list_text = NULL; + list_text_len = 0; +@@ -1069,6 +1069,7 @@ pe__clone_text(pcmk__output_t *out, va_list args) + pcmk__add_word(&list_text, &list_text_len, host->details->uname); + active_instances++; + } ++ g_list_free(started_list); + + if (list_text != NULL) { + if (pcmk_is_set(rsc->flags, pe_rsc_promotable)) { +@@ -1084,7 +1085,6 @@ pe__clone_text(pcmk__output_t *out, va_list args) + out->list_item(out, "Started", "[ %s ]", list_text); + } + +- g_list_free(started_list); + free(list_text); + list_text = NULL; + } +diff --git a/lib/pengine/pe_output.c b/lib/pengine/pe_output.c +index b8997c4..20bd1a9 100644 +--- a/lib/pengine/pe_output.c ++++ b/lib/pengine/pe_output.c +@@ -1410,6 +1410,8 @@ node_text(pcmk__output_t *out, va_list args) { + + out->end_list(out); + out->end_list(out); ++ ++ g_list_free(rscs); + } + + } else { +@@ -1739,6 +1741,7 @@ node_attribute_list(pcmk__output_t *out, va_list args) { + } + + if (!pcmk__str_in_list(only_node, node->details->uname)) { ++ g_list_free(attr_list); + continue; + } + +-- +1.8.3.1 + diff --git a/SPECS/pacemaker.spec b/SPECS/pacemaker.spec index 531910b..41f71c5 100644 --- a/SPECS/pacemaker.spec +++ b/SPECS/pacemaker.spec @@ -36,7 +36,7 @@ ## can be incremented to build packages reliably considered "newer" ## than previously built packages with the same pcmkversion) %global pcmkversion 2.1.0 -%global specversion 3 +%global specversion 4 ## Upstream commit (full commit ID, abbreviated commit ID, or tag) to build %global commit 7c3f660707a495a1331716ad32cd3ac9d9f8ff58 @@ -274,6 +274,12 @@ Patch4: 004-check-level.patch Patch5: 005-crm_resource.patch Patch6: 006-crm_simulate.patch Patch7: 007-unfencing-loop.patch +Patch8: 008-dynamic-list-fencing.patch +Patch9: 009-crm_resource-messages.patch +Patch10: 010-probe-pending.patch +Patch11: 011-crm_attribute-regression.patch +Patch12: 012-string-arguments.patch +Patch13: 013-leaks.patch # downstream-only commits #Patch1xx: 1xx-xxxx.patch @@ -949,6 +955,16 @@ exit 0 %license %{nagios_name}-%{nagios_hash}/COPYING %changelog +* Fri Jul 30 2021 Ken Gaillot - 2.1.0-4 +- Show better error messages in crm_resource with invalid resource types +- Avoid selecting wrong device when dynamic-list fencing is used with host map +- Do not schedule probes of unmanaged resources on pending nodes +- Fix regressions in crm_attribute and crm_master argument handling +- Resolves: rhbz1447918 +- Resolves: rhbz1978010 +- Resolves: rhbz1982453 +- Resolves: rhbz1984120 + * Tue Jun 22 2021 Ken Gaillot - 2.1.0-3 - crm_resource now supports XML output from resource agent actions - Correct output for crm_simulate --show-failcounts