diff options
Diffstat (limited to 'lib/pengine')
30 files changed, 3500 insertions, 4603 deletions
diff --git a/lib/pengine/Makefile.am b/lib/pengine/Makefile.am index 9ffc745..2bb50da 100644 --- a/lib/pengine/Makefile.am +++ b/lib/pengine/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2004-2023 the Pacemaker project contributors +# Copyright 2004-2024 the Pacemaker project contributors # # The version control history for this file may have further details. # @@ -17,12 +17,11 @@ SUBDIRS = . tests ## libraries lib_LTLIBRARIES = libpe_rules.la \ libpe_status.la -check_LTLIBRARIES = libpe_rules_test.la \ - libpe_status_test.la +check_LTLIBRARIES = libpe_status_test.la noinst_HEADERS = pe_status_private.h -libpe_rules_la_LDFLAGS = -version-info 30:1:4 +libpe_rules_la_LDFLAGS = -version-info 30:2:4 libpe_rules_la_CFLAGS = $(CFLAGS_HARDENED_LIB) libpe_rules_la_LDFLAGS += $(LDFLAGS_HARDENED_LIB) @@ -34,7 +33,7 @@ libpe_rules_la_SOURCES = common.c libpe_rules_la_SOURCES += rules.c libpe_rules_la_SOURCES += rules_alerts.c -libpe_status_la_LDFLAGS = -version-info 35:0:7 +libpe_status_la_LDFLAGS = -version-info 35:1:7 libpe_status_la_CFLAGS = $(CFLAGS_HARDENED_LIB) libpe_status_la_LDFLAGS += $(LDFLAGS_HARDENED_LIB) @@ -63,24 +62,12 @@ libpe_status_la_SOURCES += unpack.c libpe_status_la_SOURCES += utils.c # -# libpe_rules_test and libpe_status_test are only used with unit tests, so we can +# libpe_status_test is only used with unit tests, so we can # mock system calls. See lib/common/mock.c for details. # include $(top_srcdir)/mk/tap.mk -libpe_rules_test_la_SOURCES = $(libpe_rules_la_SOURCES) -libpe_rules_test_la_LDFLAGS = $(libpe_rules_la_LDFLAGS) \ - -rpath $(libdir) \ - $(LDFLAGS_WRAP) -# See comments on libcrmcommon_test_la in lib/common/Makefile.am regarding these flags. -libpe_rules_test_la_CFLAGS = $(libpe_rules_la_CFLAGS) \ - -DPCMK__UNIT_TESTING \ - -fno-builtin -fno-inline -libpe_rules_test_la_LIBADD = $(top_builddir)/lib/common/libcrmcommon_test.la \ - -lcmocka \ - -lm - libpe_status_test_la_SOURCES = $(libpe_status_la_SOURCES) libpe_status_test_la_LDFLAGS = $(libpe_status_la_LDFLAGS) \ -rpath $(libdir) \ diff --git a/lib/pengine/bundle.c b/lib/pengine/bundle.c index fd859d5..8967f30 100644 --- a/lib/pengine/bundle.c +++ b/lib/pengine/bundle.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2023 the Pacemaker project contributors + * Copyright 2004-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -15,7 +15,7 @@ #include <crm/pengine/rules.h> #include <crm/pengine/status.h> #include <crm/pengine/internal.h> -#include <crm/msg_xml.h> +#include <crm/common/xml.h> #include <crm/common/output.h> #include <crm/common/xml_internal.h> #include <pe_status_private.h> @@ -71,17 +71,15 @@ typedef struct pe__bundle_variant_data_s { pcmk_resource_t *child; - GList *replicas; // pe__bundle_replica_t * + GList *replicas; // pcmk__bundle_replica_t * GList *ports; // pe__bundle_port_t * GList *mounts; // pe__bundle_mount_t * enum pe__container_agent agent_type; } pe__bundle_variant_data_t; -#define get_bundle_variant_data(data, rsc) \ - CRM_ASSERT(rsc != NULL); \ - CRM_ASSERT(rsc->variant == pcmk_rsc_variant_bundle); \ - CRM_ASSERT(rsc->variant_opaque != NULL); \ +#define get_bundle_variant_data(data, rsc) \ + CRM_ASSERT(pcmk__is_bundle(rsc) && (rsc->variant_opaque != NULL)); \ data = (pe__bundle_variant_data_t *) rsc->variant_opaque; /*! @@ -133,13 +131,13 @@ pe__get_rsc_in_container(const pcmk_resource_t *instance) const pe__bundle_variant_data_t *data = NULL; const pcmk_resource_t *top = pe__const_top_resource(instance, true); - if ((top == NULL) || (top->variant != pcmk_rsc_variant_bundle)) { + if (!pcmk__is_bundle(top)) { return NULL; } get_bundle_variant_data(data, top); for (const GList *iter = data->replicas; iter != NULL; iter = iter->next) { - const pe__bundle_replica_t *replica = iter->data; + const pcmk__bundle_replica_t *replica = iter->data; if (instance == replica->container) { return replica->child; @@ -165,9 +163,9 @@ pe__node_is_bundle_instance(const pcmk_resource_t *bundle, get_bundle_variant_data(bundle_data, bundle); for (GList *iter = bundle_data->replicas; iter != NULL; iter = iter->next) { - pe__bundle_replica_t *replica = iter->data; + pcmk__bundle_replica_t *replica = iter->data; - if (pe__same_node(node, replica->node)) { + if (pcmk__same_node(node, replica->node)) { return true; } } @@ -187,7 +185,7 @@ pcmk_resource_t * pe__first_container(const pcmk_resource_t *bundle) { const pe__bundle_variant_data_t *bundle_data = NULL; - const pe__bundle_replica_t *replica = NULL; + const pcmk__bundle_replica_t *replica = NULL; get_bundle_variant_data(bundle_data, bundle); if (bundle_data->replicas == NULL) { @@ -208,14 +206,14 @@ pe__first_container(const pcmk_resource_t *bundle) */ void pe__foreach_bundle_replica(pcmk_resource_t *bundle, - bool (*fn)(pe__bundle_replica_t *, void *), + bool (*fn)(pcmk__bundle_replica_t *, void *), void *user_data) { const pe__bundle_variant_data_t *bundle_data = NULL; get_bundle_variant_data(bundle_data, bundle); for (GList *iter = bundle_data->replicas; iter != NULL; iter = iter->next) { - if (!fn((pe__bundle_replica_t *) iter->data, user_data)) { + if (!fn((pcmk__bundle_replica_t *) iter->data, user_data)) { break; } } @@ -232,7 +230,7 @@ pe__foreach_bundle_replica(pcmk_resource_t *bundle, */ void pe__foreach_const_bundle_replica(const pcmk_resource_t *bundle, - bool (*fn)(const pe__bundle_replica_t *, + bool (*fn)(const pcmk__bundle_replica_t *, void *), void *user_data) { @@ -242,7 +240,7 @@ pe__foreach_const_bundle_replica(const pcmk_resource_t *bundle, for (const GList *iter = bundle_data->replicas; iter != NULL; iter = iter->next) { - if (!fn((const pe__bundle_replica_t *) iter->data, user_data)) { + if (!fn((const pcmk__bundle_replica_t *) iter->data, user_data)) { break; } } @@ -276,7 +274,7 @@ next_ip(const char *last_ip) } static void -allocate_ip(pe__bundle_variant_data_t *data, pe__bundle_replica_t *replica, +allocate_ip(pe__bundle_variant_data_t *data, pcmk__bundle_replica_t *replica, GString *buffer) { if(data->ip_range_start == NULL) { @@ -318,12 +316,12 @@ allocate_ip(pe__bundle_variant_data_t *data, pe__bundle_replica_t *replica, static xmlNode * create_resource(const char *name, const char *provider, const char *kind) { - xmlNode *rsc = create_xml_node(NULL, XML_CIB_TAG_RESOURCE); + xmlNode *rsc = pcmk__xe_create(NULL, PCMK_XE_PRIMITIVE); - crm_xml_add(rsc, XML_ATTR_ID, name); - crm_xml_add(rsc, XML_AGENT_ATTR_CLASS, PCMK_RESOURCE_CLASS_OCF); - crm_xml_add(rsc, XML_AGENT_ATTR_PROVIDER, provider); - crm_xml_add(rsc, XML_ATTR_TYPE, kind); + crm_xml_add(rsc, PCMK_XA_ID, name); + crm_xml_add(rsc, PCMK_XA_CLASS, PCMK_RESOURCE_CLASS_OCF); + crm_xml_add(rsc, PCMK_XA_PROVIDER, provider); + crm_xml_add(rsc, PCMK_XA_TYPE, kind); return rsc; } @@ -348,10 +346,12 @@ valid_network(pe__bundle_variant_data_t *data) } if(data->control_port) { if(data->nreplicas_per_host > 1) { - pe_err("Specifying the 'control-port' for %s requires 'replicas-per-host=1'", data->prefix); + pcmk__config_err("Specifying the '" PCMK_XA_CONTROL_PORT "' for %s " + "requires '" PCMK_XA_REPLICAS_PER_HOST "=1'", + data->prefix); data->nreplicas_per_host = 1; // @TODO to be sure: - // pe__clear_resource_flags(rsc, pcmk_rsc_unique); + // pcmk__clear_rsc_flags(rsc, pcmk_rsc_unique); } return TRUE; } @@ -360,7 +360,7 @@ valid_network(pe__bundle_variant_data_t *data) static int create_ip_resource(pcmk_resource_t *parent, pe__bundle_variant_data_t *data, - pe__bundle_replica_t *replica) + pcmk__bundle_replica_t *replica) { if(data->ip_range_start) { char *id = NULL; @@ -372,7 +372,7 @@ create_ip_resource(pcmk_resource_t *parent, pe__bundle_variant_data_t *data, xml_ip = create_resource(id, "heartbeat", "IPaddr2"); free(id); - xml_obj = create_xml_node(xml_ip, XML_TAG_ATTR_SETS); + xml_obj = pcmk__xe_create(xml_ip, PCMK_XE_INSTANCE_ATTRIBUTES); crm_xml_set_id(xml_obj, "%s-attributes-%d", data->prefix, replica->offset); @@ -389,9 +389,9 @@ create_ip_resource(pcmk_resource_t *parent, pe__bundle_variant_data_t *data, crm_create_nvpair_xml(xml_obj, NULL, "cidr_netmask", "32"); } - xml_obj = create_xml_node(xml_ip, "operations"); - crm_create_op_xml(xml_obj, ID(xml_ip), PCMK_ACTION_MONITOR, "60s", - NULL); + xml_obj = pcmk__xe_create(xml_ip, PCMK_XE_OPERATIONS); + crm_create_op_xml(xml_obj, pcmk__xe_id(xml_ip), PCMK_ACTION_MONITOR, + "60s", NULL); // TODO: Other ops? Timeouts and intervals from underlying resource? @@ -421,7 +421,7 @@ container_agent_str(enum pe__container_agent t) static int create_container_resource(pcmk_resource_t *parent, const pe__bundle_variant_data_t *data, - pe__bundle_replica_t *replica) + pcmk__bundle_replica_t *replica) { char *id = NULL; xmlNode *xml_container = NULL; @@ -460,13 +460,13 @@ create_container_resource(pcmk_resource_t *parent, xml_container = create_resource(id, "heartbeat", agent_str); free(id); - xml_obj = create_xml_node(xml_container, XML_TAG_ATTR_SETS); + xml_obj = pcmk__xe_create(xml_container, PCMK_XE_INSTANCE_ATTRIBUTES); crm_xml_set_id(xml_obj, "%s-attributes-%d", data->prefix, replica->offset); crm_create_nvpair_xml(xml_obj, NULL, "image", data->image); - crm_create_nvpair_xml(xml_obj, NULL, "allow_pull", XML_BOOLEAN_TRUE); - crm_create_nvpair_xml(xml_obj, NULL, "force_kill", XML_BOOLEAN_FALSE); - crm_create_nvpair_xml(xml_obj, NULL, "reuse", XML_BOOLEAN_FALSE); + crm_create_nvpair_xml(xml_obj, NULL, "allow_pull", PCMK_VALUE_TRUE); + crm_create_nvpair_xml(xml_obj, NULL, "force_kill", PCMK_VALUE_FALSE); + crm_create_nvpair_xml(xml_obj, NULL, "reuse", PCMK_VALUE_FALSE); if (data->agent_type == PE__CONTAINER_AGENT_DOCKER) { g_string_append(buffer, " --restart=no"); @@ -544,8 +544,8 @@ create_container_resource(pcmk_resource_t *parent, " -p ", replica->ipaddr, ":", port->source, ":", port->target, NULL); - } else if (!pcmk__str_eq(data->container_network, "host", - pcmk__str_none)) { + } else if (!pcmk__str_eq(data->container_network, + PCMK_VALUE_HOST, pcmk__str_none)) { // No need to do port mapping if net == host pcmk__g_strcat(buffer, " -p ", port->source, ":", port->target, @@ -641,16 +641,16 @@ create_container_resource(pcmk_resource_t *parent, crm_create_nvpair_xml(xml_obj, NULL, "monitor_cmd", "/bin/true"); } - xml_obj = create_xml_node(xml_container, "operations"); - crm_create_op_xml(xml_obj, ID(xml_container), PCMK_ACTION_MONITOR, "60s", - NULL); + xml_obj = pcmk__xe_create(xml_container, PCMK_XE_OPERATIONS); + crm_create_op_xml(xml_obj, pcmk__xe_id(xml_container), PCMK_ACTION_MONITOR, + "60s", NULL); // TODO: Other ops? Timeouts and intervals from underlying resource? if (pe__unpack_resource(xml_container, &replica->container, parent, parent->cluster) != pcmk_rc_ok) { return pcmk_rc_unpack_error; } - pe__set_resource_flags(replica->container, pcmk_rsc_replica_container); + pcmk__set_rsc_flags(replica->container, pcmk_rsc_replica_container); parent->children = g_list_append(parent->children, replica->container); return pcmk_rc_ok; @@ -668,7 +668,7 @@ disallow_node(pcmk_resource_t *rsc, const char *uname) gpointer match = g_hash_table_lookup(rsc->allowed_nodes, uname); if (match) { - ((pcmk_node_t *) match)->weight = -INFINITY; + ((pcmk_node_t *) match)->weight = -PCMK_SCORE_INFINITY; ((pcmk_node_t *) match)->rsc_discover_mode = pcmk_probe_never; } if (rsc->children) { @@ -678,7 +678,7 @@ disallow_node(pcmk_resource_t *rsc, const char *uname) static int create_remote_resource(pcmk_resource_t *parent, pe__bundle_variant_data_t *data, - pe__bundle_replica_t *replica) + pcmk__bundle_replica_t *replica) { if (replica->child && valid_network(data)) { GHashTableIter gIter; @@ -726,18 +726,18 @@ create_remote_resource(pcmk_resource_t *parent, pe__bundle_variant_data_t *data, */ free(id); id = NULL; - uname = ID(xml_remote); + uname = pcmk__xe_id(xml_remote); /* Ensure a node has been created for the guest (it may have already * been, if it has a permanent node attribute), and ensure its weight is * -INFINITY so no other resources can run on it. */ - node = pe_find_node(parent->cluster->nodes, uname); + node = pcmk_find_node(parent->cluster, uname); if (node == NULL) { - node = pe_create_node(uname, uname, "remote", "-INFINITY", - parent->cluster); + node = pe_create_node(uname, uname, PCMK_VALUE_REMOTE, + PCMK_VALUE_MINUS_INFINITY, parent->cluster); } else { - node->weight = -INFINITY; + node->weight = -PCMK_SCORE_INFINITY; } node->rsc_discover_mode = pcmk_probe_never; @@ -776,7 +776,7 @@ create_remote_resource(pcmk_resource_t *parent, pe__bundle_variant_data_t *data, { pcmk_node_t *copy = pe__copy_node(replica->node); - copy->weight = -INFINITY; + copy->weight = -PCMK_SCORE_INFINITY; g_hash_table_insert(replica->child->parent->allowed_nodes, (gpointer) replica->node->details->id, copy); } @@ -787,22 +787,22 @@ create_remote_resource(pcmk_resource_t *parent, pe__bundle_variant_data_t *data, g_hash_table_iter_init(&gIter, replica->remote->allowed_nodes); while (g_hash_table_iter_next(&gIter, NULL, (void **)&node)) { - if (pe__is_guest_or_remote_node(node)) { + if (pcmk__is_pacemaker_remote_node(node)) { /* Remote resources can only run on 'normal' cluster node */ - node->weight = -INFINITY; + node->weight = -PCMK_SCORE_INFINITY; } } replica->node->details->remote_rsc = replica->remote; - // Ensure pe__is_guest_node() functions correctly immediately + // Ensure pcmk__is_guest_or_bundle_node() functions correctly replica->remote->container = replica->container; /* A bundle's #kind is closer to "container" (guest node) than the * "remote" set by pe_create_node(). */ - g_hash_table_insert(replica->node->details->attrs, - strdup(CRM_ATTR_KIND), strdup("container")); + pcmk__insert_dup(replica->node->details->attrs, + CRM_ATTR_KIND, "container"); /* One effect of this is that setup_container() will add * replica->remote to replica->container's fillers, which will make @@ -819,8 +819,9 @@ create_remote_resource(pcmk_resource_t *parent, pe__bundle_variant_data_t *data, } static int -create_replica_resources(pcmk_resource_t *parent, pe__bundle_variant_data_t *data, - pe__bundle_replica_t *replica) +create_replica_resources(pcmk_resource_t *parent, + pe__bundle_variant_data_t *data, + pcmk__bundle_replica_t *replica) { int rc = pcmk_rc_ok; @@ -840,7 +841,7 @@ create_replica_resources(pcmk_resource_t *parent, pe__bundle_variant_data_t *dat } if ((replica->child != NULL) && (replica->ipaddr != NULL)) { - add_hash_param(replica->child->meta, "external-ip", replica->ipaddr); + pcmk__insert_meta(replica->child, "external-ip", replica->ipaddr); } if (replica->remote != NULL) { @@ -852,8 +853,7 @@ create_replica_resources(pcmk_resource_t *parent, pe__bundle_variant_data_t *dat * containers with pacemaker-remoted inside in order to start * services inside those containers. */ - pe__set_resource_flags(replica->remote, - pcmk_rsc_remote_nesting_allowed); + pcmk__set_rsc_flags(replica->remote, pcmk_rsc_remote_nesting_allowed); } return rc; } @@ -862,12 +862,12 @@ static void mount_add(pe__bundle_variant_data_t *bundle_data, const char *source, const char *target, const char *options, uint32_t flags) { - pe__bundle_mount_t *mount = calloc(1, sizeof(pe__bundle_mount_t)); + pe__bundle_mount_t *mount = pcmk__assert_alloc(1, + sizeof(pe__bundle_mount_t)); - CRM_ASSERT(mount != NULL); - mount->source = strdup(source); - mount->target = strdup(target); - pcmk__str_update(&mount->options, options); + mount->source = pcmk__str_copy(source); + mount->target = pcmk__str_copy(target); + mount->options = pcmk__str_copy(options); mount->flags = flags; bundle_data->mounts = g_list_append(bundle_data->mounts, mount); } @@ -889,7 +889,7 @@ port_free(pe__bundle_port_t *port) free(port); } -static pe__bundle_replica_t * +static pcmk__bundle_replica_t * replica_for_remote(pcmk_resource_t *remote) { pcmk_resource_t *top = remote; @@ -906,7 +906,7 @@ replica_for_remote(pcmk_resource_t *remote) get_bundle_variant_data(bundle_data, top); for (GList *gIter = bundle_data->replicas; gIter != NULL; gIter = gIter->next) { - pe__bundle_replica_t *replica = gIter->data; + pcmk__bundle_replica_t *replica = gIter->data; if (replica->remote == remote) { return replica; @@ -928,20 +928,20 @@ pe__bundle_needs_remote_name(pcmk_resource_t *rsc) // Use NULL node since pcmk__bundle_expand() uses that to set value params = pe_rsc_params(rsc, NULL, rsc->cluster); - value = g_hash_table_lookup(params, XML_RSC_ATTR_REMOTE_RA_ADDR); + value = g_hash_table_lookup(params, PCMK_REMOTE_RA_ADDR); return pcmk__str_eq(value, "#uname", pcmk__str_casei) && xml_contains_remote_node(rsc->xml); } const char * -pe__add_bundle_remote_name(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler, - xmlNode *xml, const char *field) +pe__add_bundle_remote_name(pcmk_resource_t *rsc, xmlNode *xml, + const char *field) { // REMOTE_CONTAINER_HACK: Allow remote nodes that start containers with pacemaker remote inside pcmk_node_t *node = NULL; - pe__bundle_replica_t *replica = NULL; + pcmk__bundle_replica_t *replica = NULL; if (!pe__bundle_needs_remote_name(rsc)) { return NULL; @@ -957,7 +957,7 @@ pe__add_bundle_remote_name(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler, /* If it won't be running anywhere after the * transition, go with where it's running now. */ - node = pe__current_node(replica->container); + node = pcmk__current_node(replica->container); } if(node == NULL) { @@ -966,7 +966,7 @@ pe__add_bundle_remote_name(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler, } crm_trace("Setting address for bundle connection %s to bundle host %s", - rsc->id, pe__node_name(node)); + rsc->id, pcmk__node_name(node)); if(xml != NULL && field != NULL) { crm_xml_add(xml, field, node->details->uname); } @@ -976,8 +976,8 @@ pe__add_bundle_remote_name(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler, #define pe__set_bundle_mount_flags(mount_xml, flags, flags_to_set) do { \ flags = pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE, \ - "Bundle mount", ID(mount_xml), flags, \ - (flags_to_set), #flags_to_set); \ + "Bundle mount", pcmk__xe_id(mount_xml), \ + flags, (flags_to_set), #flags_to_set); \ } while (0) gboolean @@ -985,26 +985,32 @@ pe__unpack_bundle(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) { const char *value = NULL; xmlNode *xml_obj = NULL; + const xmlNode *xml_child = NULL; xmlNode *xml_resource = NULL; pe__bundle_variant_data_t *bundle_data = NULL; bool need_log_mount = TRUE; CRM_ASSERT(rsc != NULL); - pe_rsc_trace(rsc, "Processing resource %s...", rsc->id); + pcmk__rsc_trace(rsc, "Processing resource %s...", rsc->id); - bundle_data = calloc(1, sizeof(pe__bundle_variant_data_t)); + bundle_data = pcmk__assert_alloc(1, sizeof(pe__bundle_variant_data_t)); rsc->variant_opaque = bundle_data; bundle_data->prefix = strdup(rsc->id); - xml_obj = first_named_child(rsc->xml, PE__CONTAINER_AGENT_DOCKER_S); + xml_obj = pcmk__xe_first_child(rsc->xml, PCMK_XE_DOCKER, NULL, NULL); if (xml_obj != NULL) { bundle_data->agent_type = PE__CONTAINER_AGENT_DOCKER; } else { - xml_obj = first_named_child(rsc->xml, PE__CONTAINER_AGENT_RKT_S); + xml_obj = pcmk__xe_first_child(rsc->xml, PCMK__XE_RKT, NULL, NULL); if (xml_obj != NULL) { + pcmk__warn_once(pcmk__wo_rkt, + "Support for " PCMK__XE_RKT " in bundles " + "(such as %s) is deprecated and will be " + "removed in a future release", rsc->id); bundle_data->agent_type = PE__CONTAINER_AGENT_RKT; } else { - xml_obj = first_named_child(rsc->xml, PE__CONTAINER_AGENT_PODMAN_S); + xml_obj = pcmk__xe_first_child(rsc->xml, PCMK_XE_PODMAN, NULL, + NULL); if (xml_obj != NULL) { bundle_data->agent_type = PE__CONTAINER_AGENT_PODMAN; } else { @@ -1013,16 +1019,27 @@ pe__unpack_bundle(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) } } - // Use 0 for default, minimum, and invalid promoted-max - value = crm_element_value(xml_obj, PCMK_META_PROMOTED_MAX); + // Use 0 for default, minimum, and invalid PCMK_XA_PROMOTED_MAX + value = crm_element_value(xml_obj, PCMK_XA_PROMOTED_MAX); if (value == NULL) { // @COMPAT deprecated since 2.0.0 - value = crm_element_value(xml_obj, "masters"); + value = crm_element_value(xml_obj, PCMK__XA_PROMOTED_MAX_LEGACY); + + if (value != NULL) { + pcmk__warn_once(pcmk__wo_bundle_master, + "Support for the " PCMK__XA_PROMOTED_MAX_LEGACY + " attribute (such as in %s) is deprecated and " + "will be removed in a future release. Use " + PCMK_XA_PROMOTED_MAX " instead.", + rsc->id); + } } pcmk__scan_min_int(value, &bundle_data->promoted_max, 0); - // Default replicas to promoted-max if it was specified and 1 otherwise - value = crm_element_value(xml_obj, "replicas"); + /* Default replicas to PCMK_XA_PROMOTED_MAX if it was specified and 1 + * otherwise + */ + value = crm_element_value(xml_obj, PCMK_XA_REPLICAS); if ((value == NULL) && (bundle_data->promoted_max > 0)) { bundle_data->nreplicas = bundle_data->promoted_max; } else { @@ -1034,39 +1051,49 @@ pe__unpack_bundle(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) * floating IPs only works if the container is started with: * --userland-proxy=false --ip-masq=false */ - value = crm_element_value(xml_obj, "replicas-per-host"); + value = crm_element_value(xml_obj, PCMK_XA_REPLICAS_PER_HOST); pcmk__scan_min_int(value, &bundle_data->nreplicas_per_host, 1); if (bundle_data->nreplicas_per_host == 1) { - pe__clear_resource_flags(rsc, pcmk_rsc_unique); + pcmk__clear_rsc_flags(rsc, pcmk_rsc_unique); } - bundle_data->container_command = crm_element_value_copy(xml_obj, "run-command"); - bundle_data->launcher_options = crm_element_value_copy(xml_obj, "options"); - bundle_data->image = crm_element_value_copy(xml_obj, "image"); - bundle_data->container_network = crm_element_value_copy(xml_obj, "network"); + bundle_data->container_command = + crm_element_value_copy(xml_obj, PCMK_XA_RUN_COMMAND); + bundle_data->launcher_options = crm_element_value_copy(xml_obj, + PCMK_XA_OPTIONS); + bundle_data->image = crm_element_value_copy(xml_obj, PCMK_XA_IMAGE); + bundle_data->container_network = crm_element_value_copy(xml_obj, + PCMK_XA_NETWORK); - xml_obj = first_named_child(rsc->xml, "network"); + xml_obj = pcmk__xe_first_child(rsc->xml, PCMK_XE_NETWORK, NULL, NULL); if(xml_obj) { - - bundle_data->ip_range_start = crm_element_value_copy(xml_obj, "ip-range-start"); - bundle_data->host_netmask = crm_element_value_copy(xml_obj, "host-netmask"); - bundle_data->host_network = crm_element_value_copy(xml_obj, "host-interface"); - bundle_data->control_port = crm_element_value_copy(xml_obj, "control-port"); - value = crm_element_value(xml_obj, "add-host"); + bundle_data->ip_range_start = + crm_element_value_copy(xml_obj, PCMK_XA_IP_RANGE_START); + bundle_data->host_netmask = + crm_element_value_copy(xml_obj, PCMK_XA_HOST_NETMASK); + bundle_data->host_network = + crm_element_value_copy(xml_obj, PCMK_XA_HOST_INTERFACE); + bundle_data->control_port = + crm_element_value_copy(xml_obj, PCMK_XA_CONTROL_PORT); + value = crm_element_value(xml_obj, PCMK_XA_ADD_HOST); if (crm_str_to_boolean(value, &bundle_data->add_host) != 1) { bundle_data->add_host = TRUE; } - for (xmlNode *xml_child = pcmk__xe_first_child(xml_obj); xml_child != NULL; - xml_child = pcmk__xe_next(xml_child)) { + for (xml_child = pcmk__xe_first_child(xml_obj, PCMK_XE_PORT_MAPPING, + NULL, NULL); + xml_child != NULL; xml_child = pcmk__xe_next_same(xml_child)) { - pe__bundle_port_t *port = calloc(1, sizeof(pe__bundle_port_t)); - port->source = crm_element_value_copy(xml_child, "port"); + pe__bundle_port_t *port = + pcmk__assert_alloc(1, sizeof(pe__bundle_port_t)); + + port->source = crm_element_value_copy(xml_child, PCMK_XA_PORT); if(port->source == NULL) { - port->source = crm_element_value_copy(xml_child, "range"); + port->source = crm_element_value_copy(xml_child, PCMK_XA_RANGE); } else { - port->target = crm_element_value_copy(xml_child, "internal-port"); + port->target = crm_element_value_copy(xml_child, + PCMK_XA_INTERNAL_PORT); } if(port->source != NULL && strlen(port->source) > 0) { @@ -1076,23 +1103,25 @@ pe__unpack_bundle(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) bundle_data->ports = g_list_append(bundle_data->ports, port); } else { - pe_err("Invalid port directive %s", ID(xml_child)); + pcmk__config_err("Invalid " PCMK_XA_PORT " directive %s", + pcmk__xe_id(xml_child)); port_free(port); } } } - xml_obj = first_named_child(rsc->xml, "storage"); - for (xmlNode *xml_child = pcmk__xe_first_child(xml_obj); xml_child != NULL; - xml_child = pcmk__xe_next(xml_child)) { + xml_obj = pcmk__xe_first_child(rsc->xml, PCMK_XE_STORAGE, NULL, NULL); + for (xml_child = pcmk__xe_first_child(xml_obj, PCMK_XE_STORAGE_MAPPING, + NULL, NULL); + xml_child != NULL; xml_child = pcmk__xe_next_same(xml_child)) { - const char *source = crm_element_value(xml_child, "source-dir"); - const char *target = crm_element_value(xml_child, "target-dir"); - const char *options = crm_element_value(xml_child, "options"); + const char *source = crm_element_value(xml_child, PCMK_XA_SOURCE_DIR); + const char *target = crm_element_value(xml_child, PCMK_XA_TARGET_DIR); + const char *options = crm_element_value(xml_child, PCMK_XA_OPTIONS); int flags = pe__bundle_mount_none; if (source == NULL) { - source = crm_element_value(xml_child, "source-dir-root"); + source = crm_element_value(xml_child, PCMK_XA_SOURCE_DIR_ROOT); pe__set_bundle_mount_flags(xml_child, flags, pe__bundle_mount_subdir); } @@ -1103,16 +1132,17 @@ pe__unpack_bundle(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) need_log_mount = FALSE; } } else { - pe_err("Invalid mount directive %s", ID(xml_child)); + pcmk__config_err("Invalid mount directive %s", + pcmk__xe_id(xml_child)); } } - xml_obj = first_named_child(rsc->xml, "primitive"); + xml_obj = pcmk__xe_first_child(rsc->xml, PCMK_XE_PRIMITIVE, NULL, NULL); if (xml_obj && valid_network(bundle_data)) { char *value = NULL; xmlNode *xml_set = NULL; - xml_resource = create_xml_node(NULL, XML_CIB_TAG_INCARNATION); + xml_resource = pcmk__xe_create(NULL, PCMK_XE_CLONE); /* @COMPAT We no longer use the <master> tag, but we need to keep it as * part of the resource name, so that bundles don't restart in a rolling @@ -1122,11 +1152,11 @@ pe__unpack_bundle(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) (bundle_data->promoted_max? "master" : (const char *)xml_resource->name)); - xml_set = create_xml_node(xml_resource, XML_TAG_META_SETS); + xml_set = pcmk__xe_create(xml_resource, PCMK_XE_META_ATTRIBUTES); crm_xml_set_id(xml_set, "%s-%s-meta", bundle_data->prefix, xml_resource->name); crm_create_nvpair_xml(xml_set, NULL, - XML_RSC_ATTR_ORDERED, XML_BOOLEAN_TRUE); + PCMK_META_ORDERED, PCMK_VALUE_TRUE); value = pcmk__itoa(bundle_data->nreplicas); crm_create_nvpair_xml(xml_set, NULL, PCMK_META_CLONE_MAX, value); @@ -1136,24 +1166,25 @@ pe__unpack_bundle(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) crm_create_nvpair_xml(xml_set, NULL, PCMK_META_CLONE_NODE_MAX, value); free(value); - crm_create_nvpair_xml(xml_set, NULL, XML_RSC_ATTR_UNIQUE, + crm_create_nvpair_xml(xml_set, NULL, PCMK_META_GLOBALLY_UNIQUE, pcmk__btoa(bundle_data->nreplicas_per_host > 1)); if (bundle_data->promoted_max) { crm_create_nvpair_xml(xml_set, NULL, - XML_RSC_ATTR_PROMOTABLE, XML_BOOLEAN_TRUE); + PCMK_META_PROMOTABLE, PCMK_VALUE_TRUE); value = pcmk__itoa(bundle_data->promoted_max); crm_create_nvpair_xml(xml_set, NULL, PCMK_META_PROMOTED_MAX, value); free(value); } - //crm_xml_add(xml_obj, XML_ATTR_ID, bundle_data->prefix); - add_node_copy(xml_resource, xml_obj); + //crm_xml_add(xml_obj, PCMK_XA_ID, bundle_data->prefix); + pcmk__xml_copy(xml_resource, xml_obj); } else if(xml_obj) { - pe_err("Cannot control %s inside %s without either ip-range-start or control-port", - rsc->id, ID(xml_obj)); + pcmk__config_err("Cannot control %s inside %s without either " + PCMK_XA_IP_RANGE_START " or " PCMK_XA_CONTROL_PORT, + rsc->id, pcmk__xe_id(xml_obj)); return FALSE; } @@ -1197,7 +1228,7 @@ pe__unpack_bundle(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) pe__bundle_mount_subdir); } - port = calloc(1, sizeof(pe__bundle_port_t)); + port = pcmk__assert_alloc(1, sizeof(pe__bundle_port_t)); if(bundle_data->control_port) { port->source = strdup(bundle_data->control_port); } else { @@ -1207,7 +1238,8 @@ pe__unpack_bundle(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) * * However, it gains nothing, since we control both the container * environment and the connection resource parameters, and the user - * can use a different port if desired by setting control-port. + * can use a different port if desired by setting + * PCMK_XA_CONTROL_PORT. */ port->source = pcmk__itoa(DEFAULT_REMOTE_PORT); } @@ -1218,31 +1250,33 @@ pe__unpack_bundle(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) for (childIter = bundle_data->child->children; childIter != NULL; childIter = childIter->next) { - pe__bundle_replica_t *replica = calloc(1, sizeof(pe__bundle_replica_t)); + pcmk__bundle_replica_t *replica = NULL; + replica = pcmk__assert_alloc(1, sizeof(pcmk__bundle_replica_t)); replica->child = childIter->data; replica->child->exclusive_discover = TRUE; replica->offset = lpc++; // Ensure the child's notify gets set based on the underlying primitive's value if (pcmk_is_set(replica->child->flags, pcmk_rsc_notify)) { - pe__set_resource_flags(bundle_data->child, pcmk_rsc_notify); + pcmk__set_rsc_flags(bundle_data->child, pcmk_rsc_notify); } allocate_ip(bundle_data, replica, buffer); bundle_data->replicas = g_list_append(bundle_data->replicas, replica); - bundle_data->attribute_target = g_hash_table_lookup(replica->child->meta, - XML_RSC_ATTR_TARGET); + bundle_data->attribute_target = + g_hash_table_lookup(replica->child->meta, + PCMK_META_CONTAINER_ATTRIBUTE_TARGET); } bundle_data->container_host_options = g_string_free(buffer, FALSE); if (bundle_data->attribute_target) { - g_hash_table_replace(rsc->meta, strdup(XML_RSC_ATTR_TARGET), - strdup(bundle_data->attribute_target)); - g_hash_table_replace(bundle_data->child->meta, - strdup(XML_RSC_ATTR_TARGET), - strdup(bundle_data->attribute_target)); + pcmk__insert_dup(rsc->meta, PCMK_META_CONTAINER_ATTRIBUTE_TARGET, + bundle_data->attribute_target); + pcmk__insert_dup(bundle_data->child->meta, + PCMK_META_CONTAINER_ATTRIBUTE_TARGET, + bundle_data->attribute_target); } } else { @@ -1250,8 +1284,9 @@ pe__unpack_bundle(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) GString *buffer = g_string_sized_new(1024); for (int lpc = 0; lpc < bundle_data->nreplicas; lpc++) { - pe__bundle_replica_t *replica = calloc(1, sizeof(pe__bundle_replica_t)); + pcmk__bundle_replica_t *replica = NULL; + replica = pcmk__assert_alloc(1, sizeof(pcmk__bundle_replica_t)); replica->offset = lpc; allocate_ip(bundle_data, replica, buffer); bundle_data->replicas = g_list_append(bundle_data->replicas, @@ -1262,10 +1297,10 @@ pe__unpack_bundle(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) for (GList *gIter = bundle_data->replicas; gIter != NULL; gIter = gIter->next) { - pe__bundle_replica_t *replica = gIter->data; + pcmk__bundle_replica_t *replica = gIter->data; if (create_replica_resources(rsc, bundle_data, replica) != pcmk_rc_ok) { - pe_err("Failed unpacking resource %s", rsc->id); + pcmk__config_err("Failed unpacking resource %s", rsc->id); rsc->fns->free(rsc); return FALSE; } @@ -1323,7 +1358,7 @@ pe__bundle_active(pcmk_resource_t *rsc, gboolean all) get_bundle_variant_data(bundle_data, rsc); for (iter = bundle_data->replicas; iter != NULL; iter = iter->next) { - pe__bundle_replica_t *replica = iter->data; + pcmk__bundle_replica_t *replica = iter->data; int rsc_active; rsc_active = replica_resource_active(replica->ip, all); @@ -1372,10 +1407,10 @@ pe__find_bundle_replica(const pcmk_resource_t *bundle, const pcmk_node_t *node) get_bundle_variant_data(bundle_data, bundle); for (GList *gIter = bundle_data->replicas; gIter != NULL; gIter = gIter->next) { - pe__bundle_replica_t *replica = gIter->data; + pcmk__bundle_replica_t *replica = gIter->data; CRM_ASSERT(replica && replica->node); - if (replica->node->details == node->details) { + if (pcmk__same_node(replica->node, node)) { return replica->child; } } @@ -1421,21 +1456,23 @@ bundle_print_xml(pcmk_resource_t *rsc, const char *pre_text, long options, get_bundle_variant_data(bundle_data, rsc); status_print("%s<bundle ", pre_text); - status_print(XML_ATTR_ID "=\"%s\" ", rsc->id); + status_print(PCMK_XA_ID "=\"%s\" ", rsc->id); status_print("type=\"%s\" ", container_agent_str(bundle_data->agent_type)); status_print("image=\"%s\" ", bundle_data->image); - status_print("unique=\"%s\" ", pe__rsc_bool_str(rsc, pcmk_rsc_unique)); + status_print("unique=\"%s\" ", + pcmk__flag_text(rsc->flags, pcmk_rsc_unique)); status_print("managed=\"%s\" ", - pe__rsc_bool_str(rsc, pcmk_rsc_managed)); - status_print("failed=\"%s\" ", pe__rsc_bool_str(rsc, pcmk_rsc_failed)); + pcmk__flag_text(rsc->flags, pcmk_rsc_managed)); + status_print("failed=\"%s\" ", + pcmk__flag_text(rsc->flags, pcmk_rsc_failed)); status_print(">\n"); for (GList *gIter = bundle_data->replicas; gIter != NULL; gIter = gIter->next) { - pe__bundle_replica_t *replica = gIter->data; + pcmk__bundle_replica_t *replica = gIter->data; CRM_ASSERT(replica); - status_print("%s <replica " XML_ATTR_ID "=\"%d\">\n", + status_print("%s <replica " PCMK_XA_ID "=\"%d\">\n", pre_text, replica->offset); print_rsc_in_list(replica->ip, child_text, options, print_data); print_rsc_in_list(replica->child, child_text, options, print_data); @@ -1476,7 +1513,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; + pcmk__bundle_replica_t *replica = gIter->data; char *id = NULL; gboolean print_ip, print_child, print_ctnr, print_remote; @@ -1499,46 +1536,55 @@ pe__bundle_xml(pcmk__output_t *out, va_list args) } if (!printed_header) { + const char *type = container_agent_str(bundle_data->agent_type); + const char *unique = pcmk__flag_text(rsc->flags, pcmk_rsc_unique); + const char *maintenance = pcmk__flag_text(rsc->flags, + pcmk_rsc_maintenance); + const char *managed = pcmk__flag_text(rsc->flags, pcmk_rsc_managed); + const char *failed = pcmk__flag_text(rsc->flags, pcmk_rsc_failed); + printed_header = TRUE; desc = pe__resource_description(rsc, show_opts); - rc = pe__name_and_nvpairs_xml(out, true, "bundle", 8, - "id", rsc->id, - "type", container_agent_str(bundle_data->agent_type), - "image", bundle_data->image, - "unique", pe__rsc_bool_str(rsc, pcmk_rsc_unique), - "maintenance", - pe__rsc_bool_str(rsc, pcmk_rsc_maintenance), - "managed", pe__rsc_bool_str(rsc, pcmk_rsc_managed), - "failed", pe__rsc_bool_str(rsc, pcmk_rsc_failed), - "description", desc); + rc = pe__name_and_nvpairs_xml(out, true, PCMK_XE_BUNDLE, + PCMK_XA_ID, rsc->id, + PCMK_XA_TYPE, type, + PCMK_XA_IMAGE, bundle_data->image, + PCMK_XA_UNIQUE, unique, + PCMK_XA_MAINTENANCE, maintenance, + PCMK_XA_MANAGED, managed, + PCMK_XA_FAILED, failed, + PCMK_XA_DESCRIPTION, desc, + NULL); CRM_ASSERT(rc == pcmk_rc_ok); } id = pcmk__itoa(replica->offset); - rc = pe__name_and_nvpairs_xml(out, true, "replica", 1, "id", id); + rc = pe__name_and_nvpairs_xml(out, true, PCMK_XE_REPLICA, + PCMK_XA_ID, id, + NULL); free(id); CRM_ASSERT(rc == pcmk_rc_ok); if (print_ip) { - out->message(out, crm_map_element_name(replica->ip->xml), show_opts, + out->message(out, (const char *) replica->ip->xml->name, show_opts, replica->ip, only_node, only_rsc); } if (print_child) { - out->message(out, crm_map_element_name(replica->child->xml), show_opts, - replica->child, only_node, only_rsc); + out->message(out, (const char *) replica->child->xml->name, + show_opts, replica->child, only_node, only_rsc); } if (print_ctnr) { - out->message(out, crm_map_element_name(replica->container->xml), show_opts, - replica->container, only_node, only_rsc); + out->message(out, (const char *) replica->container->xml->name, + show_opts, replica->container, only_node, only_rsc); } if (print_remote) { - out->message(out, crm_map_element_name(replica->remote->xml), show_opts, - replica->remote, only_node, only_rsc); + out->message(out, (const char *) replica->remote->xml->name, + show_opts, replica->remote, only_node, only_rsc); } pcmk__output_xml_pop_parent(out); // replica @@ -1552,7 +1598,8 @@ pe__bundle_xml(pcmk__output_t *out, va_list args) } static void -pe__bundle_replica_output_html(pcmk__output_t *out, pe__bundle_replica_t *replica, +pe__bundle_replica_output_html(pcmk__output_t *out, + pcmk__bundle_replica_t *replica, pcmk_node_t *node, uint32_t show_opts) { pcmk_resource_t *rsc = replica->child; @@ -1629,7 +1676,7 @@ pe__bundle_html(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; + pcmk__bundle_replica_t *replica = gIter->data; gboolean print_ip, print_child, print_ctnr, print_remote; CRM_ASSERT(replica); @@ -1665,23 +1712,26 @@ pe__bundle_html(pcmk__output_t *out, va_list args) } if (print_ip) { - out->message(out, crm_map_element_name(replica->ip->xml), + out->message(out, (const char *) replica->ip->xml->name, new_show_opts, replica->ip, only_node, only_rsc); } if (print_child) { - out->message(out, crm_map_element_name(replica->child->xml), - new_show_opts, replica->child, only_node, only_rsc); + out->message(out, (const char *) replica->child->xml->name, + new_show_opts, replica->child, only_node, + only_rsc); } if (print_ctnr) { - out->message(out, crm_map_element_name(replica->container->xml), - new_show_opts, replica->container, only_node, only_rsc); + out->message(out, (const char *) replica->container->xml->name, + new_show_opts, replica->container, only_node, + only_rsc); } if (print_remote) { - out->message(out, crm_map_element_name(replica->remote->xml), - new_show_opts, replica->remote, only_node, only_rsc); + out->message(out, (const char *) replica->remote->xml->name, + new_show_opts, replica->remote, only_node, + only_rsc); } if (pcmk__list_of_multiple(bundle_data->replicas)) { @@ -1697,7 +1747,8 @@ pe__bundle_html(pcmk__output_t *out, va_list args) desc ? " (" : "", desc ? desc : "", desc ? ")" : "", get_unmanaged_str(rsc)); - pe__bundle_replica_output_html(out, replica, pe__current_node(replica->container), + pe__bundle_replica_output_html(out, replica, + pcmk__current_node(replica->container), show_opts); } } @@ -1707,7 +1758,8 @@ pe__bundle_html(pcmk__output_t *out, va_list args) } static void -pe__bundle_replica_output_text(pcmk__output_t *out, pe__bundle_replica_t *replica, +pe__bundle_replica_output_text(pcmk__output_t *out, + pcmk__bundle_replica_t *replica, pcmk_node_t *node, uint32_t show_opts) { const pcmk_resource_t *rsc = replica->child; @@ -1763,7 +1815,7 @@ pe__bundle_text(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; + pcmk__bundle_replica_t *replica = gIter->data; gboolean print_ip, print_child, print_ctnr, print_remote; CRM_ASSERT(replica); @@ -1801,23 +1853,26 @@ pe__bundle_text(pcmk__output_t *out, va_list args) out->begin_list(out, NULL, NULL, NULL); if (print_ip) { - out->message(out, crm_map_element_name(replica->ip->xml), + out->message(out, (const char *) replica->ip->xml->name, new_show_opts, replica->ip, only_node, only_rsc); } if (print_child) { - out->message(out, crm_map_element_name(replica->child->xml), - new_show_opts, replica->child, only_node, only_rsc); + out->message(out, (const char *) replica->child->xml->name, + new_show_opts, replica->child, only_node, + only_rsc); } if (print_ctnr) { - out->message(out, crm_map_element_name(replica->container->xml), - new_show_opts, replica->container, only_node, only_rsc); + out->message(out, (const char *) replica->container->xml->name, + new_show_opts, replica->container, only_node, + only_rsc); } if (print_remote) { - out->message(out, crm_map_element_name(replica->remote->xml), - new_show_opts, replica->remote, only_node, only_rsc); + out->message(out, (const char *) replica->remote->xml->name, + new_show_opts, replica->remote, only_node, + only_rsc); } out->end_list(out); @@ -1831,7 +1886,8 @@ pe__bundle_text(pcmk__output_t *out, va_list args) desc ? " (" : "", desc ? desc : "", desc ? ")" : "", get_unmanaged_str(rsc)); - pe__bundle_replica_output_text(out, replica, pe__current_node(replica->container), + pe__bundle_replica_output_text(out, replica, + pcmk__current_node(replica->container), show_opts); } } @@ -1845,7 +1901,7 @@ pe__bundle_text(pcmk__output_t *out, va_list args) * \deprecated This function will be removed in a future release */ static void -print_bundle_replica(pe__bundle_replica_t *replica, const char *pre_text, +print_bundle_replica(pcmk__bundle_replica_t *replica, const char *pre_text, long options, void *print_data) { pcmk_node_t *node = NULL; @@ -1870,7 +1926,7 @@ print_bundle_replica(pe__bundle_replica_t *replica, const char *pre_text, replica->ipaddr); } - node = pe__current_node(replica->container); + node = pcmk__current_node(replica->container); common_print(rsc, pre_text, buffer, node, options, print_data); } @@ -1909,7 +1965,7 @@ pe__print_bundle(pcmk_resource_t *rsc, const char *pre_text, long options, for (GList *gIter = bundle_data->replicas; gIter != NULL; gIter = gIter->next) { - pe__bundle_replica_t *replica = gIter->data; + pcmk__bundle_replica_t *replica = gIter->data; CRM_ASSERT(replica); if (options & pe_print_html) { @@ -1947,7 +2003,7 @@ pe__print_bundle(pcmk_resource_t *rsc, const char *pre_text, long options, } static void -free_bundle_replica(pe__bundle_replica_t *replica) +free_bundle_replica(pcmk__bundle_replica_t *replica) { if (replica == NULL) { return; @@ -1987,7 +2043,7 @@ pe__free_bundle(pcmk_resource_t *rsc) CRM_CHECK(rsc != NULL, return); get_bundle_variant_data(bundle_data, rsc); - pe_rsc_trace(rsc, "Freeing %s", rsc->id); + pcmk__rsc_trace(rsc, "Freeing %s", rsc->id); free(bundle_data->prefix); free(bundle_data->image); @@ -2031,14 +2087,13 @@ pe__bundle_resource_state(const pcmk_resource_t *rsc, gboolean current) int pe_bundle_replicas(const pcmk_resource_t *rsc) { - if ((rsc == NULL) || (rsc->variant != pcmk_rsc_variant_bundle)) { - return 0; - } else { + if (pcmk__is_bundle(rsc)) { pe__bundle_variant_data_t *bundle_data = NULL; get_bundle_variant_data(bundle_data, rsc); return bundle_data->nreplicas; } + return 0; } void @@ -2048,7 +2103,7 @@ pe__count_bundle(pcmk_resource_t *rsc) get_bundle_variant_data(bundle_data, rsc); for (GList *item = bundle_data->replicas; item != NULL; item = item->next) { - pe__bundle_replica_t *replica = item->data; + pcmk__bundle_replica_t *replica = item->data; if (replica->ip) { replica->ip->fns->count(replica->ip); @@ -2078,7 +2133,7 @@ pe__bundle_is_filtered(const pcmk_resource_t *rsc, GList *only_rsc, get_bundle_variant_data(bundle_data, rsc); for (GList *gIter = bundle_data->replicas; gIter != NULL; gIter = gIter->next) { - pe__bundle_replica_t *replica = gIter->data; + pcmk__bundle_replica_t *replica = gIter->data; if (replica->ip != NULL && !replica->ip->fns->is_filtered(replica->ip, only_rsc, FALSE)) { passes = TRUE; @@ -2117,7 +2172,7 @@ pe__bundle_containers(const pcmk_resource_t *bundle) get_bundle_variant_data(data, bundle); for (GList *iter = data->replicas; iter != NULL; iter = iter->next) { - pe__bundle_replica_t *replica = iter->data; + pcmk__bundle_replica_t *replica = iter->data; containers = g_list_append(containers, replica->container); } @@ -2152,7 +2207,7 @@ pe__bundle_active_node(const pcmk_resource_t *rsc, unsigned int *count_all, */ get_bundle_variant_data(data, rsc); for (iter = data->replicas; iter != NULL; iter = iter->next) { - pe__bundle_replica_t *replica = iter->data; + pcmk__bundle_replica_t *replica = iter->data; if (replica->container->running_on != NULL) { containers = g_list_append(containers, replica->container); diff --git a/lib/pengine/clone.c b/lib/pengine/clone.c index a92a4b7..596b00e 100644 --- a/lib/pengine/clone.c +++ b/lib/pengine/clone.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2023 the Pacemaker project contributors + * Copyright 2004-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -15,7 +15,7 @@ #include <crm/pengine/status.h> #include <crm/pengine/internal.h> #include <pe_status_private.h> -#include <crm/msg_xml.h> +#include <crm/common/xml.h> #include <crm/common/output.h> #include <crm/common/xml_internal.h> #include <crm/common/scheduler_internal.h> @@ -24,8 +24,8 @@ #define PROMOTED_INSTANCES PCMK__ROLE_PROMOTED_LEGACY "s" #define UNPROMOTED_INSTANCES PCMK__ROLE_UNPROMOTED_LEGACY "s" #else -#define PROMOTED_INSTANCES PCMK__ROLE_PROMOTED -#define UNPROMOTED_INSTANCES PCMK__ROLE_UNPROMOTED +#define PROMOTED_INSTANCES PCMK_ROLE_PROMOTED +#define UNPROMOTED_INSTANCES PCMK_ROLE_UNPROMOTED #endif typedef struct clone_variant_data_s { @@ -47,8 +47,8 @@ typedef struct clone_variant_data_s { xmlNode *xml_obj_child; } clone_variant_data_t; -#define get_clone_variant_data(data, rsc) \ - CRM_ASSERT((rsc != NULL) && (rsc->variant == pcmk_rsc_variant_clone)); \ +#define get_clone_variant_data(data, rsc) \ + CRM_ASSERT(pcmk__is_clone(rsc) && (rsc->variant_opaque != NULL)); \ data = (clone_variant_data_t *) rsc->variant_opaque; /*! @@ -194,13 +194,15 @@ clone_header(pcmk__output_t *out, int *rc, const pcmk_resource_t *rsc, if (attrs != NULL) { PCMK__OUTPUT_LIST_HEADER(out, FALSE, *rc, "Clone Set: %s [%s] (%s)%s%s%s", - rsc->id, ID(clone_data->xml_obj_child), + rsc->id, + pcmk__xe_id(clone_data->xml_obj_child), (const char *) attrs->str, desc ? " (" : "", desc ? desc : "", desc ? ")" : ""); g_string_free(attrs, TRUE); } else { PCMK__OUTPUT_LIST_HEADER(out, FALSE, *rc, "Clone Set: %s [%s]%s%s%s", - rsc->id, ID(clone_data->xml_obj_child), + rsc->id, + pcmk__xe_id(clone_data->xml_obj_child), desc ? " (" : "", desc ? desc : "", desc ? ")" : ""); } @@ -210,12 +212,12 @@ void pe__force_anon(const char *standard, pcmk_resource_t *rsc, const char *rid, pcmk_scheduler_t *scheduler) { - if (pe_rsc_is_clone(rsc)) { + if (pcmk__is_clone(rsc)) { clone_variant_data_t *clone_data = rsc->variant_opaque; - pe_warn("Ignoring " XML_RSC_ATTR_UNIQUE " for %s because %s resources " - "such as %s can be used only as anonymous clones", - rsc->id, standard, rid); + pcmk__config_warn("Ignoring " PCMK_META_GLOBALLY_UNIQUE " for %s " + "because %s resources such as %s can be used only as " + "anonymous clones", rsc->id, standard, rid); clone_data->clone_node_max = 1; clone_data->clone_max = QB_MIN(clone_data->clone_max, @@ -233,7 +235,7 @@ find_clone_instance(const pcmk_resource_t *rsc, const char *sub_id) get_clone_variant_data(clone_data, rsc); - child_base = ID(clone_data->xml_obj_child); + child_base = pcmk__xe_id(clone_data->xml_obj_child); child_id = crm_strdup_printf("%s:%s", child_base, sub_id); child = pe_find_resource(rsc->children, child_id); @@ -264,9 +266,9 @@ pe__create_clone_child(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) inc_num = pcmk__itoa(clone_data->total_clones); inc_max = pcmk__itoa(clone_data->clone_max); - child_copy = copy_xml(clone_data->xml_obj_child); + child_copy = pcmk__xml_copy(NULL, clone_data->xml_obj_child); - crm_xml_add(child_copy, XML_RSC_ATTR_INCARNATION, inc_num); + crm_xml_add(child_copy, PCMK__META_CLONE, inc_num); if (pe__unpack_resource(child_copy, &child_rsc, rsc, scheduler) != pcmk_rc_ok) { @@ -276,14 +278,15 @@ pe__create_clone_child(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) CRM_ASSERT(child_rsc); clone_data->total_clones += 1; - pe_rsc_trace(child_rsc, "Setting clone attributes for: %s", child_rsc->id); + pcmk__rsc_trace(child_rsc, "Setting clone attributes for: %s", + child_rsc->id); rsc->children = g_list_append(rsc->children, child_rsc); if (as_orphan) { pe__set_resource_flags_recursive(child_rsc, pcmk_rsc_removed); } - add_hash_param(child_rsc->meta, PCMK_META_CLONE_MAX, inc_max); - pe_rsc_trace(rsc, "Added %s instance %s", rsc->id, child_rsc->id); + pcmk__insert_meta(child_rsc, PCMK_META_CLONE_MAX, inc_max); + pcmk__rsc_trace(rsc, "Added %s instance %s", rsc->id, child_rsc->id); bail: free(inc_num); @@ -314,6 +317,26 @@ unpack_meta_int(const pcmk_resource_t *rsc, const char *meta_name, if ((value == NULL) && (deprecated_name != NULL)) { value = g_hash_table_lookup(rsc->meta, deprecated_name); + + if (value != NULL) { + if (pcmk__str_eq(deprecated_name, PCMK__META_PROMOTED_MAX_LEGACY, + pcmk__str_none)) { + pcmk__warn_once(pcmk__wo_clone_master_max, + "Support for the " PCMK__META_PROMOTED_MAX_LEGACY + " meta-attribute (such as in %s) is deprecated " + "and will be removed in a future release. Use the " + PCMK_META_PROMOTED_MAX " meta-attribute instead.", + rsc->id); + } else if (pcmk__str_eq(deprecated_name, PCMK__META_PROMOTED_NODE_MAX_LEGACY, + pcmk__str_none)) { + pcmk__warn_once(pcmk__wo_clone_master_node_max, + "Support for the " PCMK__META_PROMOTED_NODE_MAX_LEGACY + " meta-attribute (such as in %s) is deprecated " + "and will be removed in a future release. Use the " + PCMK_META_PROMOTED_NODE_MAX " meta-attribute instead.", + rsc->id); + } + } } if (value != NULL) { pcmk__scan_min_int(value, &integer, 0); @@ -329,28 +352,25 @@ clone_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) xmlNode *xml_obj = rsc->xml; clone_variant_data_t *clone_data = NULL; - pe_rsc_trace(rsc, "Processing resource %s...", rsc->id); + pcmk__rsc_trace(rsc, "Processing resource %s...", rsc->id); - clone_data = calloc(1, sizeof(clone_variant_data_t)); + clone_data = pcmk__assert_alloc(1, sizeof(clone_variant_data_t)); rsc->variant_opaque = clone_data; if (pcmk_is_set(rsc->flags, pcmk_rsc_promotable)) { // Use 1 as default but 0 for minimum and invalid - // @COMPAT PCMK_XA_PROMOTED_MAX_LEGACY deprecated since 2.0.0 - clone_data->promoted_max = unpack_meta_int(rsc, PCMK_META_PROMOTED_MAX, - PCMK_XA_PROMOTED_MAX_LEGACY, - 1); + // @COMPAT PCMK__META_PROMOTED_MAX_LEGACY deprecated since 2.0.0 + clone_data->promoted_max = + unpack_meta_int(rsc, PCMK_META_PROMOTED_MAX, + PCMK__META_PROMOTED_MAX_LEGACY, 1); // Use 1 as default but 0 for minimum and invalid - // @COMPAT PCMK_XA_PROMOTED_NODE_MAX_LEGACY deprecated since 2.0.0 + // @COMPAT PCMK__META_PROMOTED_NODE_MAX_LEGACY deprecated since 2.0.0 clone_data->promoted_node_max = unpack_meta_int(rsc, PCMK_META_PROMOTED_NODE_MAX, - PCMK_XA_PROMOTED_NODE_MAX_LEGACY, 1); + PCMK__META_PROMOTED_NODE_MAX_LEGACY, 1); } - // Implied by calloc() - /* clone_data->xml_obj_child = NULL; */ - // Use 1 as default but 0 for minimum and invalid clone_data->clone_node_max = unpack_meta_int(rsc, PCMK_META_CLONE_NODE_MAX, NULL, 1); @@ -361,7 +381,7 @@ clone_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) clone_data->clone_max = unpack_meta_int(rsc, PCMK_META_CLONE_MAX, NULL, QB_MAX(1, g_list_length(scheduler->nodes))); - if (crm_is_true(g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_ORDERED))) { + if (crm_is_true(g_hash_table_lookup(rsc->meta, PCMK_META_ORDERED))) { clone_data->flags = pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE, "Clone", rsc->id, clone_data->flags, @@ -378,19 +398,20 @@ clone_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) clone_data->clone_node_max = 1; } - pe_rsc_trace(rsc, "Options for %s", rsc->id); - pe_rsc_trace(rsc, "\tClone max: %d", clone_data->clone_max); - pe_rsc_trace(rsc, "\tClone node max: %d", clone_data->clone_node_max); - pe_rsc_trace(rsc, "\tClone is unique: %s", - pe__rsc_bool_str(rsc, pcmk_rsc_unique)); - pe_rsc_trace(rsc, "\tClone is promotable: %s", - pe__rsc_bool_str(rsc, pcmk_rsc_promotable)); + pcmk__rsc_trace(rsc, "Options for %s", rsc->id); + pcmk__rsc_trace(rsc, "\tClone max: %d", clone_data->clone_max); + pcmk__rsc_trace(rsc, "\tClone node max: %d", clone_data->clone_node_max); + pcmk__rsc_trace(rsc, "\tClone is unique: %s", + pcmk__flag_text(rsc->flags, pcmk_rsc_unique)); + pcmk__rsc_trace(rsc, "\tClone is promotable: %s", + pcmk__flag_text(rsc->flags, pcmk_rsc_promotable)); // Clones may contain a single group or primitive - for (a_child = pcmk__xe_first_child(xml_obj); a_child != NULL; - a_child = pcmk__xe_next(a_child)) { + for (a_child = pcmk__xe_first_child(xml_obj, NULL, NULL, NULL); + a_child != NULL; a_child = pcmk__xe_next(a_child)) { - if (pcmk__str_any_of((const char *)a_child->name, XML_CIB_TAG_RESOURCE, XML_CIB_TAG_GROUP, NULL)) { + if (pcmk__str_any_of((const char *) a_child->name, + PCMK_XE_PRIMITIVE, PCMK_XE_GROUP, NULL)) { clone_data->xml_obj_child = a_child; break; } @@ -407,15 +428,16 @@ clone_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) * This helps ensure clone instances are not shuffled around the cluster * for no benefit in situations when pre-allocation is not appropriate */ - if (g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_STICKINESS) == NULL) { - add_hash_param(rsc->meta, XML_RSC_ATTR_STICKINESS, "1"); + if (g_hash_table_lookup(rsc->meta, PCMK_META_RESOURCE_STICKINESS) == NULL) { + pcmk__insert_meta(rsc, PCMK_META_RESOURCE_STICKINESS, "1"); } - /* This ensures that the globally-unique value always exists for children to - * inherit when being unpacked, as well as in resource agents' environment. + /* This ensures that the PCMK_META_GLOBALLY_UNIQUE value always exists for + * children to inherit when being unpacked, as well as in resource agents' + * environment. */ - add_hash_param(rsc->meta, XML_RSC_ATTR_UNIQUE, - pe__rsc_bool_str(rsc, pcmk_rsc_unique)); + pcmk__insert_meta(rsc, PCMK_META_GLOBALLY_UNIQUE, + pcmk__flag_text(rsc->flags, pcmk_rsc_unique)); if (clone_data->clone_max <= 0) { /* Create one child instance so that unpack_find_resource() will hook up @@ -434,7 +456,8 @@ clone_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) } } - pe_rsc_trace(rsc, "Added %d children to resource %s...", clone_data->clone_max, rsc->id); + pcmk__rsc_trace(rsc, "Added %d children to resource %s...", + clone_data->clone_max, rsc->id); return TRUE; } @@ -495,13 +518,13 @@ static const char * configured_role_str(pcmk_resource_t * rsc) { const char *target_role = g_hash_table_lookup(rsc->meta, - XML_RSC_ATTR_TARGET_ROLE); + PCMK_META_TARGET_ROLE); if ((target_role == NULL) && rsc->children && rsc->children->data) { pcmk_resource_t *instance = rsc->children->data; // Any instance will do target_role = g_hash_table_lookup(instance->meta, - XML_RSC_ATTR_TARGET_ROLE); + PCMK_META_TARGET_ROLE); } return target_role; } @@ -509,12 +532,17 @@ configured_role_str(pcmk_resource_t * rsc) static enum rsc_role_e configured_role(pcmk_resource_t *rsc) { + enum rsc_role_e role = pcmk_role_unknown; const char *target_role = configured_role_str(rsc); - if (target_role) { - return text2role(target_role); + if (target_role != NULL) { + role = pcmk_parse_role(target_role); + if (role == pcmk_role_unknown) { + pcmk__config_err("Invalid " PCMK_META_TARGET_ROLE + " for resource %s", rsc->id); + } } - return pcmk_role_unknown; + return role; } /*! @@ -530,15 +558,17 @@ clone_print_xml(pcmk_resource_t *rsc, const char *pre_text, long options, GList *gIter = rsc->children; status_print("%s<clone ", pre_text); - status_print(XML_ATTR_ID "=\"%s\" ", rsc->id); + status_print(PCMK_XA_ID "=\"%s\" ", rsc->id); status_print("multi_state=\"%s\" ", - pe__rsc_bool_str(rsc, pcmk_rsc_promotable)); - status_print("unique=\"%s\" ", pe__rsc_bool_str(rsc, pcmk_rsc_unique)); + pcmk__flag_text(rsc->flags, pcmk_rsc_promotable)); + status_print("unique=\"%s\" ", + pcmk__flag_text(rsc->flags, pcmk_rsc_unique)); status_print("managed=\"%s\" ", - pe__rsc_bool_str(rsc, pcmk_rsc_managed)); - status_print("failed=\"%s\" ", pe__rsc_bool_str(rsc, pcmk_rsc_failed)); + pcmk__flag_text(rsc->flags, pcmk_rsc_managed)); + status_print("failed=\"%s\" ", + pcmk__flag_text(rsc->flags, pcmk_rsc_failed)); status_print("failure_ignored=\"%s\" ", - pe__rsc_bool_str(rsc, pcmk_rsc_ignore_failure)); + pcmk__flag_text(rsc->flags, pcmk_rsc_ignore_failure)); if (target_role) { status_print("target_role=\"%s\" ", target_role); } @@ -618,7 +648,8 @@ clone_print(pcmk_resource_t *rsc, const char *pre_text, long options, child_text = crm_strdup_printf("%s ", pre_text); status_print("%sClone Set: %s [%s]%s%s%s", - pre_text ? pre_text : "", rsc->id, ID(clone_data->xml_obj_child), + pcmk__s(pre_text, ""), rsc->id, + pcmk__xe_id(clone_data->xml_obj_child), pcmk_is_set(rsc->flags, pcmk_rsc_promotable)? " (promotable)" : "", pcmk_is_set(rsc->flags, pcmk_rsc_unique)? " (unique)" : "", pcmk_is_set(rsc->flags, pcmk_rsc_managed)? "" : " (unmanaged)"); @@ -742,8 +773,8 @@ clone_print(pcmk_resource_t *rsc, const char *pre_text, long options, if (role == pcmk_role_unpromoted) { short_print((const char *) list_text->str, child_text, - UNPROMOTED_INSTANCES " (target-role)", NULL, - options, print_data); + UNPROMOTED_INSTANCES " (" PCMK_META_TARGET_ROLE ")", + NULL, options, print_data); } else { short_print((const char *) list_text->str, child_text, UNPROMOTED_INSTANCES, NULL, options, print_data); @@ -777,8 +808,9 @@ clone_print(pcmk_resource_t *rsc, const char *pre_text, long options, } if (list == NULL) { - /* Clusters with symmetrical=false haven't calculated allowed_nodes yet - * If we've not probed for them yet, the Stopped list will be empty + /* Clusters with PCMK_OPT_SYMMETRIC_CLUSTER=false haven't + * calculated allowed_nodes yet. If we've not probed for them + * yet, the Stopped list will be empty. */ list = g_hash_table_get_values(rsc->known_on); } @@ -787,7 +819,8 @@ clone_print(pcmk_resource_t *rsc, const char *pre_text, long options, for (nIter = list; nIter != NULL; nIter = nIter->next) { pcmk_node_t *node = (pcmk_node_t *) nIter->data; - if (pe_find_node(rsc->running_on, node->details->uname) == NULL) { + if (pcmk__find_node_in_list(rsc->running_on, + node->details->uname) == NULL) { pcmk__add_word(&stopped_list, 1024, node->details->uname); } } @@ -824,16 +857,12 @@ pe__clone_xml(pcmk__output_t *out, va_list args) GList *only_node = va_arg(args, GList *); GList *only_rsc = va_arg(args, GList *); - - const char *desc = NULL; GList *gIter = rsc->children; GList *all = NULL; int rc = pcmk_rc_no_output; gboolean printed_header = FALSE; gboolean print_everything = TRUE; - - if (rsc->fns->is_filtered(rsc, only_rsc, TRUE)) { return rc; } @@ -855,27 +884,37 @@ pe__clone_xml(pcmk__output_t *out, va_list args) } if (!printed_header) { + const char *multi_state = pcmk__flag_text(rsc->flags, + pcmk_rsc_promotable); + const char *unique = pcmk__flag_text(rsc->flags, pcmk_rsc_unique); + const char *maintenance = pcmk__flag_text(rsc->flags, + pcmk_rsc_maintenance); + const char *managed = pcmk__flag_text(rsc->flags, pcmk_rsc_managed); + const char *disabled = pcmk__btoa(pe__resource_is_disabled(rsc)); + const char *failed = pcmk__flag_text(rsc->flags, pcmk_rsc_failed); + const char *ignored = pcmk__flag_text(rsc->flags, + pcmk_rsc_ignore_failure); + const char *target_role = configured_role_str(rsc); + const char *desc = pe__resource_description(rsc, show_opts); + printed_header = TRUE; - desc = pe__resource_description(rsc, show_opts); - rc = pe__name_and_nvpairs_xml(out, true, "clone", 10, - "id", rsc->id, - "multi_state", - pe__rsc_bool_str(rsc, pcmk_rsc_promotable), - "unique", pe__rsc_bool_str(rsc, pcmk_rsc_unique), - "maintenance", - pe__rsc_bool_str(rsc, pcmk_rsc_maintenance), - "managed", pe__rsc_bool_str(rsc, pcmk_rsc_managed), - "disabled", pcmk__btoa(pe__resource_is_disabled(rsc)), - "failed", pe__rsc_bool_str(rsc, pcmk_rsc_failed), - "failure_ignored", - pe__rsc_bool_str(rsc, pcmk_rsc_ignore_failure), - "target_role", configured_role_str(rsc), - "description", desc); + rc = pe__name_and_nvpairs_xml(out, true, PCMK_XE_CLONE, + PCMK_XA_ID, rsc->id, + PCMK_XA_MULTI_STATE, multi_state, + PCMK_XA_UNIQUE, unique, + PCMK_XA_MAINTENANCE, maintenance, + PCMK_XA_MANAGED, managed, + PCMK_XA_DISABLED, disabled, + PCMK_XA_FAILED, failed, + PCMK_XA_FAILURE_IGNORED, ignored, + PCMK_XA_TARGET_ROLE, target_role, + PCMK_XA_DESCRIPTION, desc, + NULL); CRM_ASSERT(rc == pcmk_rc_ok); } - out->message(out, crm_map_element_name(child_rsc->xml), show_opts, + out->message(out, (const char *) child_rsc->xml->name, show_opts, child_rsc, only_node, all); } @@ -963,7 +1002,7 @@ pe__clone_default(pcmk__output_t *out, va_list args) if (stopped == NULL) { stopped = pcmk__strkey_table(free, free); } - g_hash_table_insert(stopped, strdup(child_rsc->id), strdup("Stopped")); + pcmk__insert_dup(stopped, child_rsc->id, "Stopped"); } } else if (is_set_recursive(child_rsc, pcmk_rsc_removed, TRUE) @@ -1011,7 +1050,7 @@ pe__clone_default(pcmk__output_t *out, va_list args) /* Print every resource that's a child of this clone. */ all = g_list_prepend(all, (gpointer) "*"); - out->message(out, crm_map_element_name(child_rsc->xml), show_opts, + out->message(out, (const char *) child_rsc->xml->name, show_opts, child_rsc, only_node, all); g_list_free(all); } @@ -1068,7 +1107,8 @@ pe__clone_default(pcmk__output_t *out, va_list args) if (role == pcmk_role_unpromoted) { out->list_item(out, NULL, - UNPROMOTED_INSTANCES " (target-role): [ %s ]", + UNPROMOTED_INSTANCES + " (" PCMK_META_TARGET_ROLE "): [ %s ]", (const char *) list_text->str); } else { out->list_item(out, NULL, UNPROMOTED_INSTANCES ": [ %s ]", @@ -1099,8 +1139,9 @@ pe__clone_default(pcmk__output_t *out, va_list args) } if (list == NULL) { - /* Clusters with symmetrical=false haven't calculated allowed_nodes yet - * If we've not probed for them yet, the Stopped list will be empty + /* Clusters with PCMK_OPT_SYMMETRIC_CLUSTER=false haven't + * calculated allowed_nodes yet. If we've not probed for them + * yet, the Stopped list will be empty. */ list = g_hash_table_get_values(rsc->known_on); } @@ -1109,9 +1150,10 @@ pe__clone_default(pcmk__output_t *out, va_list args) for (nIter = list; nIter != NULL; nIter = nIter->next) { pcmk_node_t *node = (pcmk_node_t *) nIter->data; - if (pe_find_node(rsc->running_on, node->details->uname) == NULL && - pcmk__str_in_list(node->details->uname, only_node, - pcmk__str_star_matches|pcmk__str_casei)) { + if ((pcmk__find_node_in_list(rsc->running_on, + node->details->uname) == NULL) + && pcmk__str_in_list(node->details->uname, only_node, + pcmk__str_star_matches|pcmk__str_casei)) { xmlNode *probe_op = pe__failed_probe_for_rsc(rsc, node->details->uname); const char *state = "Stopped"; @@ -1125,12 +1167,13 @@ pe__clone_default(pcmk__output_t *out, va_list args) if (probe_op != NULL) { int rc; - pcmk__scan_min_int(crm_element_value(probe_op, XML_LRM_ATTR_RC), &rc, 0); + pcmk__scan_min_int(crm_element_value(probe_op, + PCMK__XA_RC_CODE), + &rc, 0); g_hash_table_insert(stopped, strdup(node->details->uname), crm_strdup_printf("Stopped (%s)", services_ocf_exitcode_str(rc))); } else { - g_hash_table_insert(stopped, strdup(node->details->uname), - strdup(state)); + pcmk__insert_dup(stopped, node->details->uname, state); } } } @@ -1183,13 +1226,13 @@ clone_free(pcmk_resource_t * rsc) get_clone_variant_data(clone_data, rsc); - pe_rsc_trace(rsc, "Freeing %s", rsc->id); + pcmk__rsc_trace(rsc, "Freeing %s", rsc->id); for (GList *gIter = rsc->children; gIter != NULL; gIter = gIter->next) { pcmk_resource_t *child_rsc = (pcmk_resource_t *) gIter->data; CRM_ASSERT(child_rsc); - pe_rsc_trace(child_rsc, "Freeing child %s", child_rsc->id); + pcmk__rsc_trace(child_rsc, "Freeing child %s", child_rsc->id); free_xml(child_rsc->xml); child_rsc->xml = NULL; /* There could be a saved unexpanded xml */ @@ -1225,7 +1268,7 @@ clone_resource_state(const pcmk_resource_t * rsc, gboolean current) } } - pe_rsc_trace(rsc, "%s role: %s", rsc->id, role2text(clone_role)); + pcmk__rsc_trace(rsc, "%s role: %s", rsc->id, pcmk_role_text(clone_role)); return clone_role; } @@ -1240,7 +1283,7 @@ bool pe__is_universal_clone(const pcmk_resource_t *rsc, const pcmk_scheduler_t *scheduler) { - if (pe_rsc_is_clone(rsc)) { + if (pcmk__is_clone(rsc)) { clone_variant_data_t *clone_data = rsc->variant_opaque; if (clone_data->clone_max == g_list_length(scheduler->nodes)) { @@ -1261,7 +1304,8 @@ pe__clone_is_filtered(const pcmk_resource_t *rsc, GList *only_rsc, passes = TRUE; } else { get_clone_variant_data(clone_data, rsc); - passes = pcmk__str_in_list(ID(clone_data->xml_obj_child), only_rsc, pcmk__str_star_matches); + passes = pcmk__str_in_list(pcmk__xe_id(clone_data->xml_obj_child), + only_rsc, pcmk__str_star_matches); if (!passes) { for (const GList *iter = rsc->children; @@ -1285,7 +1329,7 @@ pe__clone_child_id(const pcmk_resource_t *rsc) { clone_variant_data_t *clone_data = NULL; get_clone_variant_data(clone_data, rsc); - return ID(clone_data->xml_obj_child); + return pcmk__xe_id(clone_data->xml_obj_child); } /*! @@ -1375,7 +1419,7 @@ pe__create_promotable_pseudo_ops(pcmk_resource_t *clone, bool any_promoting, // Create a "promoted" action for when all promotions are done action_complete = pe__new_rsc_pseudo_action(clone, PCMK_ACTION_PROMOTED, !any_promoting, true); - action_complete->priority = INFINITY; + action_complete->priority = PCMK_SCORE_INFINITY; // Create notification pseudo-actions for promotion if (clone_data->promote_notify == NULL) { @@ -1392,7 +1436,7 @@ pe__create_promotable_pseudo_ops(pcmk_resource_t *clone, bool any_promoting, // Create a "demoted" action for when all demotions are done action_complete = pe__new_rsc_pseudo_action(clone, PCMK_ACTION_DEMOTED, !any_demoting, true); - action_complete->priority = INFINITY; + action_complete->priority = PCMK_SCORE_INFINITY; // Create notification pseudo-actions for demotion if (clone_data->demote_notify == NULL) { diff --git a/lib/pengine/common.c b/lib/pengine/common.c index 0fdd5a1..6351bac 100644 --- a/lib/pengine/common.c +++ b/lib/pengine/common.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2023 the Pacemaker project contributors + * Copyright 2004-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -9,7 +9,6 @@ #include <crm_internal.h> #include <crm/crm.h> -#include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crm/common/util.h> @@ -18,610 +17,46 @@ #include <crm/common/scheduler_internal.h> #include <crm/pengine/internal.h> -gboolean was_processing_error = FALSE; -gboolean was_processing_warning = FALSE; +// Deprecated functions kept only for backward API compatibility +// LCOV_EXCL_START -static bool -check_placement_strategy(const char *value) -{ - return pcmk__strcase_any_of(value, "default", "utilization", "minimal", - "balanced", NULL); -} - -static pcmk__cluster_option_t pe_opts[] = { - /* name, old name, type, allowed values, - * default value, validator, - * short description, - * long description - */ - { - "no-quorum-policy", NULL, "select", "stop, freeze, ignore, demote, suicide", - "stop", pcmk__valid_quorum, - N_("What to do when the cluster does not have quorum"), - NULL - }, - { - "symmetric-cluster", NULL, "boolean", NULL, - "true", pcmk__valid_boolean, - N_("Whether resources can run on any node by default"), - NULL - }, - { - "maintenance-mode", NULL, "boolean", NULL, - "false", pcmk__valid_boolean, - N_("Whether the cluster should refrain from monitoring, starting, " - "and stopping resources"), - NULL - }, - { - "start-failure-is-fatal", NULL, "boolean", NULL, - "true", pcmk__valid_boolean, - N_("Whether a start failure should prevent a resource from being " - "recovered on the same node"), - N_("When true, the cluster will immediately ban a resource from a node " - "if it fails to start there. When false, the cluster will instead " - "check the resource's fail count against its migration-threshold.") - }, - { - "enable-startup-probes", NULL, "boolean", NULL, - "true", pcmk__valid_boolean, - N_("Whether the cluster should check for active resources during start-up"), - NULL - }, - { - XML_CONFIG_ATTR_SHUTDOWN_LOCK, NULL, "boolean", NULL, - "false", pcmk__valid_boolean, - N_("Whether to lock resources to a cleanly shut down node"), - N_("When true, resources active on a node when it is cleanly shut down " - "are kept \"locked\" to that node (not allowed to run elsewhere) " - "until they start again on that node after it rejoins (or for at " - "most shutdown-lock-limit, if set). Stonith resources and " - "Pacemaker Remote connections are never locked. Clone and bundle " - "instances and the promoted role of promotable clones are " - "currently never locked, though support could be added in a future " - "release.") - }, - { - XML_CONFIG_ATTR_SHUTDOWN_LOCK_LIMIT, NULL, "time", NULL, - "0", pcmk__valid_interval_spec, - N_("Do not lock resources to a cleanly shut down node longer than " - "this"), - N_("If shutdown-lock is true and this is set to a nonzero time " - "duration, shutdown locks will expire after this much time has " - "passed since the shutdown was initiated, even if the node has not " - "rejoined.") - }, - - // Fencing-related options - { - "stonith-enabled", NULL, "boolean", NULL, - "true", pcmk__valid_boolean, - N_("*** Advanced Use Only *** " - "Whether nodes may be fenced as part of recovery"), - N_("If false, unresponsive nodes are immediately assumed to be harmless, " - "and resources that were active on them may be recovered " - "elsewhere. This can result in a \"split-brain\" situation, " - "potentially leading to data loss and/or service unavailability.") - }, - { - "stonith-action", NULL, "select", "reboot, off, poweroff", - PCMK_ACTION_REBOOT, pcmk__is_fencing_action, - N_("Action to send to fence device when a node needs to be fenced " - "(\"poweroff\" is a deprecated alias for \"off\")"), - NULL - }, - { - "stonith-timeout", NULL, "time", NULL, - "60s", pcmk__valid_interval_spec, - N_("*** Advanced Use Only *** Unused by Pacemaker"), - N_("This value is not used by Pacemaker, but is kept for backward " - "compatibility, and certain legacy fence agents might use it.") - }, - { - XML_ATTR_HAVE_WATCHDOG, NULL, "boolean", NULL, - "false", pcmk__valid_boolean, - N_("Whether watchdog integration is enabled"), - N_("This is set automatically by the cluster according to whether SBD " - "is detected to be in use. User-configured values are ignored. " - "The value `true` is meaningful if diskless SBD is used and " - "`stonith-watchdog-timeout` is nonzero. In that case, if fencing " - "is required, watchdog-based self-fencing will be performed via " - "SBD without requiring a fencing resource explicitly configured.") - }, - { - "concurrent-fencing", NULL, "boolean", NULL, - PCMK__CONCURRENT_FENCING_DEFAULT, pcmk__valid_boolean, - N_("Allow performing fencing operations in parallel"), - NULL - }, - { - "startup-fencing", NULL, "boolean", NULL, - "true", pcmk__valid_boolean, - N_("*** Advanced Use Only *** Whether to fence unseen nodes at start-up"), - N_("Setting this to false may lead to a \"split-brain\" situation," - "potentially leading to data loss and/or service unavailability.") - }, - { - XML_CONFIG_ATTR_PRIORITY_FENCING_DELAY, NULL, "time", NULL, - "0", pcmk__valid_interval_spec, - N_("Apply fencing delay targeting the lost nodes with the highest total resource priority"), - N_("Apply specified delay for the fencings that are targeting the lost " - "nodes with the highest total resource priority in case we don't " - "have the majority of the nodes in our cluster partition, so that " - "the more significant nodes potentially win any fencing match, " - "which is especially meaningful under split-brain of 2-node " - "cluster. A promoted resource instance takes the base priority + 1 " - "on calculation if the base priority is not 0. Any static/random " - "delays that are introduced by `pcmk_delay_base/max` configured " - "for the corresponding fencing resources will be added to this " - "delay. This delay should be significantly greater than, safely " - "twice, the maximum `pcmk_delay_base/max`. By default, priority " - "fencing delay is disabled.") - }, - { - XML_CONFIG_ATTR_NODE_PENDING_TIMEOUT, NULL, "time", NULL, - "0", pcmk__valid_interval_spec, - N_("How long to wait for a node that has joined the cluster to join " - "the controller process group"), - N_("Fence nodes that do not join the controller process group within " - "this much time after joining the cluster, to allow the cluster " - "to continue managing resources. A value of 0 means never fence " - "pending nodes. Setting the value to 2h means fence nodes after " - "2 hours.") - }, - { - "cluster-delay", NULL, "time", NULL, - "60s", pcmk__valid_interval_spec, - N_("Maximum time for node-to-node communication"), - N_("The node elected Designated Controller (DC) will consider an action " - "failed if it does not get a response from the node executing the " - "action within this time (after considering the action's own " - "timeout). The \"correct\" value will depend on the speed and " - "load of your network and cluster nodes.") - }, - { - "batch-limit", NULL, "integer", NULL, - "0", pcmk__valid_number, - N_("Maximum number of jobs that the cluster may execute in parallel " - "across all nodes"), - N_("The \"correct\" value will depend on the speed and load of your " - "network and cluster nodes. If set to 0, the cluster will " - "impose a dynamically calculated limit when any node has a " - "high load.") - }, - { - "migration-limit", NULL, "integer", NULL, - "-1", pcmk__valid_number, - N_("The number of live migration actions that the cluster is allowed " - "to execute in parallel on a node (-1 means no limit)") - }, - - /* Orphans and stopping */ - { - "stop-all-resources", NULL, "boolean", NULL, - "false", pcmk__valid_boolean, - N_("Whether the cluster should stop all active resources"), - NULL - }, - { - "stop-orphan-resources", NULL, "boolean", NULL, - "true", pcmk__valid_boolean, - N_("Whether to stop resources that were removed from the configuration"), - NULL - }, - { - "stop-orphan-actions", NULL, "boolean", NULL, - "true", pcmk__valid_boolean, - N_("Whether to cancel recurring actions removed from the configuration"), - NULL - }, - { - "remove-after-stop", NULL, "boolean", NULL, - "false", pcmk__valid_boolean, - N_("*** Deprecated *** Whether to remove stopped resources from " - "the executor"), - N_("Values other than default are poorly tested and potentially dangerous." - " This option will be removed in a future release.") - }, +#include <crm/pengine/common_compat.h> - /* Storing inputs */ - { - "pe-error-series-max", NULL, "integer", NULL, - "-1", pcmk__valid_number, - N_("The number of scheduler inputs resulting in errors to save"), - N_("Zero to disable, -1 to store unlimited.") - }, - { - "pe-warn-series-max", NULL, "integer", NULL, - "5000", pcmk__valid_number, - N_("The number of scheduler inputs resulting in warnings to save"), - N_("Zero to disable, -1 to store unlimited.") - }, - { - "pe-input-series-max", NULL, "integer", NULL, - "4000", pcmk__valid_number, - N_("The number of scheduler inputs without errors or warnings to save"), - N_("Zero to disable, -1 to store unlimited.") - }, - - /* Node health */ - { - PCMK__OPT_NODE_HEALTH_STRATEGY, NULL, "select", - PCMK__VALUE_NONE ", " PCMK__VALUE_MIGRATE_ON_RED ", " - PCMK__VALUE_ONLY_GREEN ", " PCMK__VALUE_PROGRESSIVE ", " - PCMK__VALUE_CUSTOM, - PCMK__VALUE_NONE, pcmk__validate_health_strategy, - N_("How cluster should react to node health attributes"), - N_("Requires external entities to create node attributes (named with " - "the prefix \"#health\") with values \"red\", " - "\"yellow\", or \"green\".") - }, - { - PCMK__OPT_NODE_HEALTH_BASE, NULL, "integer", NULL, - "0", pcmk__valid_number, - N_("Base health score assigned to a node"), - N_("Only used when \"node-health-strategy\" is set to \"progressive\".") - }, - { - PCMK__OPT_NODE_HEALTH_GREEN, NULL, "integer", NULL, - "0", pcmk__valid_number, - N_("The score to use for a node health attribute whose value is \"green\""), - N_("Only used when \"node-health-strategy\" is set to \"custom\" or \"progressive\".") - }, - { - PCMK__OPT_NODE_HEALTH_YELLOW, NULL, "integer", NULL, - "0", pcmk__valid_number, - N_("The score to use for a node health attribute whose value is \"yellow\""), - N_("Only used when \"node-health-strategy\" is set to \"custom\" or \"progressive\".") - }, - { - PCMK__OPT_NODE_HEALTH_RED, NULL, "integer", NULL, - "-INFINITY", pcmk__valid_number, - N_("The score to use for a node health attribute whose value is \"red\""), - N_("Only used when \"node-health-strategy\" is set to \"custom\" or \"progressive\".") - }, - - /*Placement Strategy*/ - { - "placement-strategy", NULL, "select", - "default, utilization, minimal, balanced", - "default", check_placement_strategy, - N_("How the cluster should allocate resources to nodes"), - NULL - }, -}; - -void -pe_metadata(pcmk__output_t *out) +const char * +role2text(enum rsc_role_e role) { - const char *desc_short = "Pacemaker scheduler options"; - const char *desc_long = "Cluster options used by Pacemaker's scheduler"; - - gchar *s = pcmk__format_option_metadata("pacemaker-schedulerd", desc_short, - desc_long, pe_opts, - PCMK__NELEM(pe_opts)); - out->output_xml(out, "metadata", s); - g_free(s); + return pcmk_role_text(role); } -void -verify_pe_options(GHashTable * options) +enum rsc_role_e +text2role(const char *role) { - pcmk__validate_cluster_options(options, pe_opts, PCMK__NELEM(pe_opts)); + return pcmk_parse_role(role); } const char * -pe_pref(GHashTable * options, const char *name) +task2text(enum action_tasks task) { - return pcmk__cluster_option(options, pe_opts, PCMK__NELEM(pe_opts), name); -} - -const char * -fail2text(enum action_fail_response fail) -{ - const char *result = "<unknown>"; - - switch (fail) { - case pcmk_on_fail_ignore: - result = "ignore"; - break; - case pcmk_on_fail_demote: - result = "demote"; - break; - case pcmk_on_fail_block: - result = "block"; - break; - case pcmk_on_fail_restart: - result = "recover"; - break; - case pcmk_on_fail_ban: - result = "migrate"; - break; - case pcmk_on_fail_stop: - result = "stop"; - break; - case pcmk_on_fail_fence_node: - result = "fence"; - break; - case pcmk_on_fail_standby_node: - result = "standby"; - break; - case pcmk_on_fail_restart_container: - result = "restart-container"; - break; - case pcmk_on_fail_reset_remote: - result = "reset-remote"; - break; - } - return result; + return pcmk_action_text(task); } enum action_tasks text2task(const char *task) { - if (pcmk__str_eq(task, PCMK_ACTION_STOP, pcmk__str_casei)) { - return pcmk_action_stop; - - } else if (pcmk__str_eq(task, PCMK_ACTION_STOPPED, pcmk__str_casei)) { - return pcmk_action_stopped; - - } else if (pcmk__str_eq(task, PCMK_ACTION_START, pcmk__str_casei)) { - return pcmk_action_start; - - } else if (pcmk__str_eq(task, PCMK_ACTION_RUNNING, pcmk__str_casei)) { - return pcmk_action_started; - - } else if (pcmk__str_eq(task, PCMK_ACTION_DO_SHUTDOWN, pcmk__str_casei)) { - return pcmk_action_shutdown; - - } else if (pcmk__str_eq(task, PCMK_ACTION_STONITH, pcmk__str_casei)) { - return pcmk_action_fence; - - } else if (pcmk__str_eq(task, PCMK_ACTION_MONITOR, pcmk__str_casei)) { - return pcmk_action_monitor; - - } else if (pcmk__str_eq(task, PCMK_ACTION_NOTIFY, pcmk__str_casei)) { - return pcmk_action_notify; - - } else if (pcmk__str_eq(task, PCMK_ACTION_NOTIFIED, pcmk__str_casei)) { - return pcmk_action_notified; - - } else if (pcmk__str_eq(task, PCMK_ACTION_PROMOTE, pcmk__str_casei)) { - return pcmk_action_promote; - - } else if (pcmk__str_eq(task, PCMK_ACTION_DEMOTE, pcmk__str_casei)) { - return pcmk_action_demote; - - } else if (pcmk__str_eq(task, PCMK_ACTION_PROMOTED, pcmk__str_casei)) { - return pcmk_action_promoted; - - } else if (pcmk__str_eq(task, PCMK_ACTION_DEMOTED, pcmk__str_casei)) { - return pcmk_action_demoted; - } - return pcmk_action_unspecified; + return pcmk_parse_action(task); } const char * -task2text(enum action_tasks task) -{ - const char *result = "<unknown>"; - - switch (task) { - case pcmk_action_unspecified: - result = "no_action"; - break; - case pcmk_action_stop: - result = PCMK_ACTION_STOP; - break; - case pcmk_action_stopped: - result = PCMK_ACTION_STOPPED; - break; - case pcmk_action_start: - result = PCMK_ACTION_START; - break; - case pcmk_action_started: - result = PCMK_ACTION_RUNNING; - break; - case pcmk_action_shutdown: - result = PCMK_ACTION_DO_SHUTDOWN; - break; - case pcmk_action_fence: - result = PCMK_ACTION_STONITH; - break; - case pcmk_action_monitor: - result = PCMK_ACTION_MONITOR; - break; - case pcmk_action_notify: - result = PCMK_ACTION_NOTIFY; - break; - case pcmk_action_notified: - result = PCMK_ACTION_NOTIFIED; - break; - case pcmk_action_promote: - result = PCMK_ACTION_PROMOTE; - break; - case pcmk_action_promoted: - result = PCMK_ACTION_PROMOTED; - break; - case pcmk_action_demote: - result = PCMK_ACTION_DEMOTE; - break; - case pcmk_action_demoted: - result = PCMK_ACTION_DEMOTED; - break; - } - - return result; -} - -const char * -role2text(enum rsc_role_e role) -{ - switch (role) { - case pcmk_role_stopped: - return PCMK__ROLE_STOPPED; - - case pcmk_role_started: - return PCMK__ROLE_STARTED; - - case pcmk_role_unpromoted: -#ifdef PCMK__COMPAT_2_0 - return PCMK__ROLE_UNPROMOTED_LEGACY; -#else - return PCMK__ROLE_UNPROMOTED; -#endif - - case pcmk_role_promoted: -#ifdef PCMK__COMPAT_2_0 - return PCMK__ROLE_PROMOTED_LEGACY; -#else - return PCMK__ROLE_PROMOTED; -#endif - - default: // pcmk_role_unknown - return PCMK__ROLE_UNKNOWN; - } -} - -enum rsc_role_e -text2role(const char *role) +pe_pref(GHashTable * options, const char *name) { - CRM_ASSERT(role != NULL); - if (pcmk__str_eq(role, PCMK__ROLE_STOPPED, pcmk__str_casei)) { - return pcmk_role_stopped; - } else if (pcmk__str_eq(role, PCMK__ROLE_STARTED, pcmk__str_casei)) { - return pcmk_role_started; - } else if (pcmk__strcase_any_of(role, PCMK__ROLE_UNPROMOTED, - PCMK__ROLE_UNPROMOTED_LEGACY, NULL)) { - return pcmk_role_unpromoted; - } else if (pcmk__strcase_any_of(role, PCMK__ROLE_PROMOTED, - PCMK__ROLE_PROMOTED_LEGACY, NULL)) { - return pcmk_role_promoted; - } else if (pcmk__str_eq(role, PCMK__ROLE_UNKNOWN, pcmk__str_casei)) { - return pcmk_role_unknown; - } - crm_err("Unknown role: %s", role); - return pcmk_role_unknown; + return pcmk__cluster_option(options, name); } -void -add_hash_param(GHashTable * hash, const char *name, const char *value) -{ - CRM_CHECK(hash != NULL, return); - - crm_trace("Adding name='%s' value='%s' to hash table", - pcmk__s(name, "<null>"), pcmk__s(value, "<null>")); - if (name == NULL || value == NULL) { - return; - - } else if (pcmk__str_eq(value, "#default", pcmk__str_casei)) { - return; - - } else if (g_hash_table_lookup(hash, name) == NULL) { - g_hash_table_insert(hash, strdup(name), strdup(value)); - } -} - -/*! - * \internal - * \brief Look up an attribute value on the appropriate node - * - * If \p node is a guest node and either the \c XML_RSC_ATTR_TARGET meta - * attribute is set to "host" for \p rsc or \p force_host is \c true, query the - * attribute on the node's host. Otherwise, query the attribute on \p node - * itself. - * - * \param[in] node Node to query attribute value on by default - * \param[in] name Name of attribute to query - * \param[in] rsc Resource on whose behalf we're querying - * \param[in] node_type Type of resource location lookup - * \param[in] force_host Force a lookup on the guest node's host, regardless of - * the \c XML_RSC_ATTR_TARGET value - * - * \return Value of the attribute on \p node or on the host of \p node - * - * \note If \p force_host is \c true, \p node \e must be a guest node. - */ const char * -pe__node_attribute_calculated(const pcmk_node_t *node, const char *name, - const pcmk_resource_t *rsc, - enum pcmk__rsc_node node_type, - bool force_host) +fail2text(enum action_fail_response fail) { - // @TODO: Use pe__is_guest_node() after merging libpe_{rules,status} - bool is_guest = (node != NULL) - && (node->details->type == pcmk_node_variant_remote) - && (node->details->remote_rsc != NULL) - && (node->details->remote_rsc->container != NULL); - const char *source = NULL; - const char *node_type_s = NULL; - const char *reason = NULL; - - const pcmk_resource_t *container = NULL; - const pcmk_node_t *host = NULL; - - CRM_ASSERT((node != NULL) && (name != NULL) && (rsc != NULL) - && (!force_host || is_guest)); - - /* Ignore XML_RSC_ATTR_TARGET if node is not a guest node. This represents a - * user configuration error. - */ - source = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_TARGET); - if (!force_host - && (!is_guest || !pcmk__str_eq(source, "host", pcmk__str_casei))) { - - return g_hash_table_lookup(node->details->attrs, name); - } - - container = node->details->remote_rsc->container; - - switch (node_type) { - case pcmk__rsc_node_assigned: - node_type_s = "assigned"; - host = container->allocated_to; - if (host == NULL) { - reason = "not assigned"; - } - break; - - case pcmk__rsc_node_current: - node_type_s = "current"; - - if (container->running_on != NULL) { - host = container->running_on->data; - } - if (host == NULL) { - reason = "inactive"; - } - break; - - default: - // Add support for other enum pcmk__rsc_node values if needed - CRM_ASSERT(false); - break; - } - - if (host != NULL) { - const char *value = g_hash_table_lookup(host->details->attrs, name); - - pe_rsc_trace(rsc, - "%s: Value lookup for %s on %s container host %s %s%s", - rsc->id, name, node_type_s, pe__node_name(host), - ((value != NULL)? "succeeded: " : "failed"), - pcmk__s(value, "")); - return value; - } - pe_rsc_trace(rsc, - "%s: Not looking for %s on %s container host: %s is %s", - rsc->id, name, node_type_s, container->id, reason); - return NULL; + return pcmk_on_fail_text(fail); } -const char * -pe_node_attribute_raw(const pcmk_node_t *node, const char *name) -{ - if(node == NULL) { - return NULL; - } - return g_hash_table_lookup(node->details->attrs, name); -} +// LCOV_EXCL_STOP +// End deprecated API diff --git a/lib/pengine/complex.c b/lib/pengine/complex.c index 0ab2e04..bd141fb 100644 --- a/lib/pengine/complex.c +++ b/lib/pengine/complex.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2023 the Pacemaker project contributors + * Copyright 2004-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -11,7 +11,7 @@ #include <crm/pengine/rules.h> #include <crm/pengine/internal.h> -#include <crm/msg_xml.h> +#include <crm/common/xml.h> #include <crm/common/xml_internal.h> #include <crm/common/scheduler_internal.h> @@ -85,30 +85,53 @@ pcmk_rsc_methods_t resource_class_functions[] = { static enum pe_obj_types get_resource_type(const char *name) { - if (pcmk__str_eq(name, XML_CIB_TAG_RESOURCE, pcmk__str_casei)) { + if (pcmk__str_eq(name, PCMK_XE_PRIMITIVE, pcmk__str_casei)) { return pcmk_rsc_variant_primitive; - } else if (pcmk__str_eq(name, XML_CIB_TAG_GROUP, pcmk__str_casei)) { + } else if (pcmk__str_eq(name, PCMK_XE_GROUP, pcmk__str_casei)) { return pcmk_rsc_variant_group; - } else if (pcmk__str_eq(name, XML_CIB_TAG_INCARNATION, pcmk__str_casei)) { + } else if (pcmk__str_eq(name, PCMK_XE_CLONE, pcmk__str_casei)) { return pcmk_rsc_variant_clone; - } else if (pcmk__str_eq(name, PCMK_XE_PROMOTABLE_LEGACY, pcmk__str_casei)) { + } else if (pcmk__str_eq(name, PCMK__XE_PROMOTABLE_LEGACY, + pcmk__str_casei)) { // @COMPAT deprecated since 2.0.0 return pcmk_rsc_variant_clone; - } else if (pcmk__str_eq(name, XML_CIB_TAG_CONTAINER, pcmk__str_casei)) { + } else if (pcmk__str_eq(name, PCMK_XE_BUNDLE, pcmk__str_casei)) { return pcmk_rsc_variant_bundle; } return pcmk_rsc_variant_unknown; } +/*! + * \internal + * \brief Insert a meta-attribute if not already present + * + * \param[in] key Meta-attribute name + * \param[in] value Meta-attribute value to add if not already present + * \param[in,out] table Meta-attribute hash table to insert into + * + * \note This is like pcmk__insert_meta() except it won't overwrite existing + * values. + */ static void dup_attr(gpointer key, gpointer value, gpointer user_data) { - add_hash_param(user_data, key, value); + GHashTable *table = user_data; + + CRM_CHECK((key != NULL) && (table != NULL), return); + if (pcmk__str_eq((const char *) value, "#default", pcmk__str_casei)) { + // @COMPAT Deprecated since 2.1.8 + pcmk__config_warn("Support for setting meta-attributes (such as %s) to " + "the explicit value '#default' is deprecated and " + "will be removed in a future release", + (const char *) key); + } else if ((value != NULL) && (g_hash_table_lookup(table, key) == NULL)) { + pcmk__insert_dup(table, (const char *) key, (const char *) value); + } } static void @@ -123,27 +146,21 @@ expand_parents_fixed_nvpairs(pcmk_resource_t *rsc, return ; } - /* Search all parent resources, get the fixed value of "meta_attributes" set only in the original xml, and stack it in the hash table. */ - /* The fixed value of the lower parent resource takes precedence and is not overwritten. */ + /* Search all parent resources, get the fixed value of + * PCMK_XE_META_ATTRIBUTES set only in the original xml, and stack it in the + * hash table. The fixed value of the lower parent resource takes precedence + * and is not overwritten. + */ while(p != NULL) { /* A hash table for comparison is generated, including the id-ref. */ - pe__unpack_dataset_nvpairs(p->xml, XML_TAG_META_SETS, rule_data, + pe__unpack_dataset_nvpairs(p->xml, PCMK_XE_META_ATTRIBUTES, rule_data, parent_orig_meta, NULL, FALSE, scheduler); p = p->parent; } - /* If there is a fixed value of "meta_attributes" of the parent resource, it will be processed. */ if (parent_orig_meta != NULL) { - GHashTableIter iter; - char *key = NULL; - char *value = NULL; - - g_hash_table_iter_init(&iter, parent_orig_meta); - while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) { - /* Parameters set in the original xml of the parent resource will also try to overwrite the child resource. */ - /* Attributes that already exist in the child lease are not updated. */ - dup_attr(key, value, meta_hash); - } + // This will not overwrite any values already existing for child + g_hash_table_foreach(parent_orig_meta, dup_attr, meta_hash); } if (parent_orig_meta != NULL) { @@ -158,14 +175,13 @@ get_meta_attributes(GHashTable * meta_hash, pcmk_resource_t * rsc, pcmk_node_t *node, pcmk_scheduler_t *scheduler) { pe_rsc_eval_data_t rsc_rule_data = { - .standard = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS), - .provider = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER), - .agent = crm_element_value(rsc->xml, XML_EXPR_ATTR_TYPE) + .standard = crm_element_value(rsc->xml, PCMK_XA_CLASS), + .provider = crm_element_value(rsc->xml, PCMK_XA_PROVIDER), + .agent = crm_element_value(rsc->xml, PCMK_XA_TYPE) }; pe_rule_eval_data_t rule_data = { .node_hash = NULL, - .role = pcmk_role_unknown, .now = scheduler->now, .match_data = NULL, .rsc_data = &rsc_rule_data, @@ -173,31 +189,39 @@ get_meta_attributes(GHashTable * meta_hash, pcmk_resource_t * rsc, }; if (node) { + /* @COMPAT Support for node attribute expressions in rules for + * meta-attributes is deprecated. When we can break behavioral backward + * compatibility, drop this block. + */ rule_data.node_hash = node->details->attrs; } for (xmlAttrPtr a = pcmk__xe_first_attr(rsc->xml); a != NULL; a = a->next) { - const char *prop_name = (const char *) a->name; - const char *prop_value = pcmk__xml_attr_value(a); - - add_hash_param(meta_hash, prop_name, prop_value); + if (a->children != NULL) { + dup_attr((gpointer) a->name, (gpointer) a->children->content, + meta_hash); + } } - pe__unpack_dataset_nvpairs(rsc->xml, XML_TAG_META_SETS, &rule_data, + pe__unpack_dataset_nvpairs(rsc->xml, PCMK_XE_META_ATTRIBUTES, &rule_data, meta_hash, NULL, FALSE, scheduler); - /* Set the "meta_attributes" explicitly set in the parent resource to the hash table of the child resource. */ - /* If it is already explicitly set as a child, it will not be overwritten. */ + /* Set the PCMK_XE_META_ATTRIBUTES explicitly set in the parent resource to + * the hash table of the child resource. If it is already explicitly set as + * a child, it will not be overwritten. + */ if (rsc->parent != NULL) { expand_parents_fixed_nvpairs(rsc, &rule_data, meta_hash, scheduler); } /* check the defaults */ - pe__unpack_dataset_nvpairs(scheduler->rsc_defaults, XML_TAG_META_SETS, + pe__unpack_dataset_nvpairs(scheduler->rsc_defaults, PCMK_XE_META_ATTRIBUTES, &rule_data, meta_hash, NULL, FALSE, scheduler); - /* If there is "meta_attributes" that the parent resource has not explicitly set, set a value that is not set from rsc_default either. */ - /* The values already set up to this point will not be overwritten. */ + /* If there is PCMK_XE_META_ATTRIBUTES that the parent resource has not + * explicitly set, set a value that is not set from PCMK_XE_RSC_DEFAULTS + * either. The values already set up to this point will not be overwritten. + */ if (rsc->parent) { g_hash_table_foreach(rsc->parent->meta, dup_attr, meta_hash); } @@ -209,7 +233,6 @@ get_rsc_attributes(GHashTable *meta_hash, const pcmk_resource_t *rsc, { pe_rule_eval_data_t rule_data = { .node_hash = NULL, - .role = pcmk_role_unknown, .now = scheduler->now, .match_data = NULL, .rsc_data = NULL, @@ -220,30 +243,44 @@ get_rsc_attributes(GHashTable *meta_hash, const pcmk_resource_t *rsc, rule_data.node_hash = node->details->attrs; } - pe__unpack_dataset_nvpairs(rsc->xml, XML_TAG_ATTR_SETS, &rule_data, - meta_hash, NULL, FALSE, scheduler); + pe__unpack_dataset_nvpairs(rsc->xml, PCMK_XE_INSTANCE_ATTRIBUTES, + &rule_data, meta_hash, NULL, FALSE, scheduler); /* set anything else based on the parent */ if (rsc->parent != NULL) { get_rsc_attributes(meta_hash, rsc->parent, node, scheduler); } else { + if (pcmk__xe_first_child(scheduler->rsc_defaults, + PCMK_XE_INSTANCE_ATTRIBUTES, NULL, + NULL) != NULL) { + /* Not possible with schema validation enabled + * + * @COMPAT Drop support when we can break behavioral + * backward compatibility + */ + pcmk__warn_once(pcmk__wo_instance_defaults, + "Support for " PCMK_XE_INSTANCE_ATTRIBUTES " in " + PCMK_XE_RSC_DEFAULTS " is deprecated and will be " + "removed in a future release"); + } + /* and finally check the defaults */ - pe__unpack_dataset_nvpairs(scheduler->rsc_defaults, XML_TAG_ATTR_SETS, - &rule_data, meta_hash, NULL, FALSE, - scheduler); + pe__unpack_dataset_nvpairs(scheduler->rsc_defaults, + PCMK_XE_INSTANCE_ATTRIBUTES, &rule_data, + meta_hash, NULL, FALSE, scheduler); } } static char * template_op_key(xmlNode * op) { - const char *name = crm_element_value(op, "name"); - const char *role = crm_element_value(op, "role"); + const char *name = crm_element_value(op, PCMK_XA_NAME); + const char *role = crm_element_value(op, PCMK_XA_ROLE); char *key = NULL; if ((role == NULL) - || pcmk__strcase_any_of(role, PCMK__ROLE_STARTED, PCMK__ROLE_UNPROMOTED, + || pcmk__strcase_any_of(role, PCMK_ROLE_STARTED, PCMK_ROLE_UNPROMOTED, PCMK__ROLE_UNPROMOTED_LEGACY, NULL)) { role = PCMK__ROLE_UNKNOWN; } @@ -263,62 +300,59 @@ unpack_template(xmlNode *xml_obj, xmlNode **expanded_xml, xmlNode *rsc_ops = NULL; xmlNode *template_ops = NULL; const char *template_ref = NULL; - const char *clone = NULL; const char *id = NULL; if (xml_obj == NULL) { - pe_err("No resource object for template unpacking"); + pcmk__config_err("No resource object for template unpacking"); return FALSE; } - template_ref = crm_element_value(xml_obj, XML_CIB_TAG_RSC_TEMPLATE); + template_ref = crm_element_value(xml_obj, PCMK_XA_TEMPLATE); if (template_ref == NULL) { return TRUE; } - id = ID(xml_obj); + id = pcmk__xe_id(xml_obj); if (id == NULL) { - pe_err("'%s' object must have a id", xml_obj->name); + pcmk__config_err("'%s' object must have a id", xml_obj->name); return FALSE; } if (pcmk__str_eq(template_ref, id, pcmk__str_none)) { - pe_err("The resource object '%s' should not reference itself", id); + pcmk__config_err("The resource object '%s' should not reference itself", + id); return FALSE; } - cib_resources = get_xpath_object("//" XML_CIB_TAG_RESOURCES, - scheduler->input, LOG_TRACE); + cib_resources = get_xpath_object("//" PCMK_XE_RESOURCES, scheduler->input, + LOG_TRACE); if (cib_resources == NULL) { - pe_err("No resources configured"); + pcmk__config_err("No resources configured"); return FALSE; } - template = pcmk__xe_match(cib_resources, XML_CIB_TAG_RSC_TEMPLATE, - XML_ATTR_ID, template_ref); + template = pcmk__xe_first_child(cib_resources, PCMK_XE_TEMPLATE, + PCMK_XA_ID, template_ref); if (template == NULL) { - pe_err("No template named '%s'", template_ref); + pcmk__config_err("No template named '%s'", template_ref); return FALSE; } - new_xml = copy_xml(template); + new_xml = pcmk__xml_copy(NULL, template); xmlNodeSetName(new_xml, xml_obj->name); - crm_xml_add(new_xml, XML_ATTR_ID, id); - - clone = crm_element_value(xml_obj, XML_RSC_ATTR_INCARNATION); - if(clone) { - crm_xml_add(new_xml, XML_RSC_ATTR_INCARNATION, clone); - } + crm_xml_add(new_xml, PCMK_XA_ID, id); + crm_xml_add(new_xml, PCMK__META_CLONE, + crm_element_value(xml_obj, PCMK__META_CLONE)); - template_ops = find_xml_node(new_xml, "operations", FALSE); + template_ops = pcmk__xe_first_child(new_xml, PCMK_XE_OPERATIONS, NULL, + NULL); - for (child_xml = pcmk__xe_first_child(xml_obj); child_xml != NULL; - child_xml = pcmk__xe_next(child_xml)) { - xmlNode *new_child = NULL; + for (child_xml = pcmk__xe_first_child(xml_obj, NULL, NULL, NULL); + child_xml != NULL; child_xml = pcmk__xe_next(child_xml)) { - new_child = add_node_copy(new_xml, child_xml); + xmlNode *new_child = pcmk__xml_copy(new_xml, child_xml); - if (pcmk__str_eq((const char *)new_child->name, "operations", pcmk__str_none)) { + if (pcmk__xe_is(new_child, PCMK_XE_OPERATIONS)) { rsc_ops = new_child; } } @@ -327,7 +361,7 @@ unpack_template(xmlNode *xml_obj, xmlNode **expanded_xml, xmlNode *op = NULL; GHashTable *rsc_ops_hash = pcmk__strkey_table(free, NULL); - for (op = pcmk__xe_first_child(rsc_ops); op != NULL; + for (op = pcmk__xe_first_child(rsc_ops, NULL, NULL, NULL); op != NULL; op = pcmk__xe_next(op)) { char *key = template_op_key(op); @@ -335,13 +369,13 @@ unpack_template(xmlNode *xml_obj, xmlNode **expanded_xml, g_hash_table_insert(rsc_ops_hash, key, op); } - for (op = pcmk__xe_first_child(template_ops); op != NULL; - op = pcmk__xe_next(op)) { + for (op = pcmk__xe_first_child(template_ops, NULL, NULL, NULL); + op != NULL; op = pcmk__xe_next(op)) { char *key = template_op_key(op); if (g_hash_table_lookup(rsc_ops_hash, key) == NULL) { - add_node_copy(rsc_ops, op); + pcmk__xml_copy(rsc_ops, op); } free(key); @@ -375,23 +409,25 @@ add_template_rsc(xmlNode *xml_obj, pcmk_scheduler_t *scheduler) const char *id = NULL; if (xml_obj == NULL) { - pe_err("No resource object for processing resource list of template"); + pcmk__config_err("No resource object for processing resource list " + "of template"); return FALSE; } - template_ref = crm_element_value(xml_obj, XML_CIB_TAG_RSC_TEMPLATE); + template_ref = crm_element_value(xml_obj, PCMK_XA_TEMPLATE); if (template_ref == NULL) { return TRUE; } - id = ID(xml_obj); + id = pcmk__xe_id(xml_obj); if (id == NULL) { - pe_err("'%s' object must have a id", xml_obj->name); + pcmk__config_err("'%s' object must have a id", xml_obj->name); return FALSE; } if (pcmk__str_eq(template_ref, id, pcmk__str_none)) { - pe_err("The resource object '%s' should not reference itself", id); + pcmk__config_err("The resource object '%s' should not reference itself", + id); return FALSE; } @@ -406,19 +442,21 @@ static bool detect_promotable(pcmk_resource_t *rsc) { const char *promotable = g_hash_table_lookup(rsc->meta, - XML_RSC_ATTR_PROMOTABLE); + PCMK_META_PROMOTABLE); if (crm_is_true(promotable)) { return TRUE; } // @COMPAT deprecated since 2.0.0 - if (pcmk__xe_is(rsc->xml, PCMK_XE_PROMOTABLE_LEGACY)) { - /* @TODO in some future version, pe_warn_once() here, - * then drop support in even later version - */ - g_hash_table_insert(rsc->meta, strdup(XML_RSC_ATTR_PROMOTABLE), - strdup(XML_BOOLEAN_TRUE)); + if (pcmk__xe_is(rsc->xml, PCMK__XE_PROMOTABLE_LEGACY)) { + pcmk__warn_once(pcmk__wo_master_element, + "Support for <" PCMK__XE_PROMOTABLE_LEGACY "> (such " + "as in %s) is deprecated and will be removed in a " + "future release. Use <" PCMK_XE_CLONE "> with a " + PCMK_META_PROMOTABLE " meta-attribute instead.", + rsc->id); + pcmk__insert_dup(rsc->meta, PCMK_META_PROMOTABLE, PCMK_VALUE_TRUE); return TRUE; } return FALSE; @@ -481,75 +519,75 @@ pe_rsc_params(pcmk_resource_t *rsc, const pcmk_node_t *node, /*! * \internal - * \brief Unpack a resource's "requires" meta-attribute + * \brief Unpack a resource's \c PCMK_META_REQUIRES meta-attribute * * \param[in,out] rsc Resource being unpacked - * \param[in] value Value of "requires" meta-attribute + * \param[in] value Value of \c PCMK_META_REQUIRES meta-attribute * \param[in] is_default Whether \p value was selected by default */ static void unpack_requires(pcmk_resource_t *rsc, const char *value, bool is_default) { - if (pcmk__str_eq(value, PCMK__VALUE_NOTHING, pcmk__str_casei)) { + if (pcmk__str_eq(value, PCMK_VALUE_NOTHING, pcmk__str_casei)) { - } else if (pcmk__str_eq(value, PCMK__VALUE_QUORUM, pcmk__str_casei)) { - pe__set_resource_flags(rsc, pcmk_rsc_needs_quorum); + } else if (pcmk__str_eq(value, PCMK_VALUE_QUORUM, pcmk__str_casei)) { + pcmk__set_rsc_flags(rsc, pcmk_rsc_needs_quorum); - } else if (pcmk__str_eq(value, PCMK__VALUE_FENCING, pcmk__str_casei)) { - pe__set_resource_flags(rsc, pcmk_rsc_needs_fencing); + } else if (pcmk__str_eq(value, PCMK_VALUE_FENCING, pcmk__str_casei)) { + pcmk__set_rsc_flags(rsc, pcmk_rsc_needs_fencing); if (!pcmk_is_set(rsc->cluster->flags, pcmk_sched_fencing_enabled)) { pcmk__config_warn("%s requires fencing but fencing is disabled", rsc->id); } - } else if (pcmk__str_eq(value, PCMK__VALUE_UNFENCING, pcmk__str_casei)) { + } else if (pcmk__str_eq(value, PCMK_VALUE_UNFENCING, pcmk__str_casei)) { if (pcmk_is_set(rsc->flags, pcmk_rsc_fence_device)) { - pcmk__config_warn("Resetting \"" XML_RSC_ATTR_REQUIRES "\" for %s " - "to \"" PCMK__VALUE_QUORUM "\" because fencing " + pcmk__config_warn("Resetting \"" PCMK_META_REQUIRES "\" for %s " + "to \"" PCMK_VALUE_QUORUM "\" because fencing " "devices cannot require unfencing", rsc->id); - unpack_requires(rsc, PCMK__VALUE_QUORUM, true); + unpack_requires(rsc, PCMK_VALUE_QUORUM, true); return; } else if (!pcmk_is_set(rsc->cluster->flags, pcmk_sched_fencing_enabled)) { - pcmk__config_warn("Resetting \"" XML_RSC_ATTR_REQUIRES "\" for %s " - "to \"" PCMK__VALUE_QUORUM "\" because fencing " - "is disabled", rsc->id); - unpack_requires(rsc, PCMK__VALUE_QUORUM, true); + pcmk__config_warn("Resetting \"" PCMK_META_REQUIRES "\" for %s " + "to \"" PCMK_VALUE_QUORUM "\" because fencing is " + "disabled", rsc->id); + unpack_requires(rsc, PCMK_VALUE_QUORUM, true); return; } else { - pe__set_resource_flags(rsc, pcmk_rsc_needs_fencing - |pcmk_rsc_needs_unfencing); + pcmk__set_rsc_flags(rsc, pcmk_rsc_needs_fencing + |pcmk_rsc_needs_unfencing); } } else { const char *orig_value = value; if (pcmk_is_set(rsc->flags, pcmk_rsc_fence_device)) { - value = PCMK__VALUE_QUORUM; + value = PCMK_VALUE_QUORUM; - } else if ((rsc->variant == pcmk_rsc_variant_primitive) + } else if (pcmk__is_primitive(rsc) && xml_contains_remote_node(rsc->xml)) { - value = PCMK__VALUE_QUORUM; + value = PCMK_VALUE_QUORUM; } else if (pcmk_is_set(rsc->cluster->flags, pcmk_sched_enable_unfencing)) { - value = PCMK__VALUE_UNFENCING; + value = PCMK_VALUE_UNFENCING; } else if (pcmk_is_set(rsc->cluster->flags, pcmk_sched_fencing_enabled)) { - value = PCMK__VALUE_FENCING; + value = PCMK_VALUE_FENCING; } else if (rsc->cluster->no_quorum_policy == pcmk_no_quorum_ignore) { - value = PCMK__VALUE_NOTHING; + value = PCMK_VALUE_NOTHING; } else { - value = PCMK__VALUE_QUORUM; + value = PCMK_VALUE_QUORUM; } if (orig_value != NULL) { - pcmk__config_err("Resetting '" XML_RSC_ATTR_REQUIRES "' for %s " + pcmk__config_err("Resetting '" PCMK_META_REQUIRES "' for %s " "to '%s' because '%s' is not valid", rsc->id, value, orig_value); } @@ -557,30 +595,28 @@ unpack_requires(pcmk_resource_t *rsc, const char *value, bool is_default) return; } - pe_rsc_trace(rsc, "\tRequired to start: %s%s", value, - (is_default? " (default)" : "")); + pcmk__rsc_trace(rsc, "\tRequired to start: %s%s", value, + (is_default? " (default)" : "")); } -#ifndef PCMK__COMPAT_2_0 static void warn_about_deprecated_classes(pcmk_resource_t *rsc) { - const char *std = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS); + const char *std = crm_element_value(rsc->xml, PCMK_XA_CLASS); if (pcmk__str_eq(std, PCMK_RESOURCE_CLASS_UPSTART, pcmk__str_none)) { - pe_warn_once(pcmk__wo_upstart, - "Support for Upstart resources (such as %s) is deprecated " - "and will be removed in a future release of Pacemaker", - rsc->id); + pcmk__warn_once(pcmk__wo_upstart, + "Support for Upstart resources (such as %s) is " + "deprecated and will be removed in a future release", + rsc->id); } else if (pcmk__str_eq(std, PCMK_RESOURCE_CLASS_NAGIOS, pcmk__str_none)) { - pe_warn_once(pcmk__wo_nagios, - "Support for Nagios resources (such as %s) is deprecated " - "and will be removed in a future release of Pacemaker", - rsc->id); + pcmk__warn_once(pcmk__wo_nagios, + "Support for Nagios resources (such as %s) is " + "deprecated and will be removed in a future release", + rsc->id); } } -#endif /*! * \internal @@ -612,7 +648,6 @@ pe__unpack_resource(xmlNode *xml_obj, pcmk_resource_t **rsc, pe_rule_eval_data_t rule_data = { .node_hash = NULL, - .role = pcmk_role_unknown, .now = NULL, .match_data = NULL, .rsc_data = NULL, @@ -628,10 +663,10 @@ pe__unpack_resource(xmlNode *xml_obj, pcmk_resource_t **rsc, crm_log_xml_trace(xml_obj, "[raw XML]"); - id = crm_element_value(xml_obj, XML_ATTR_ID); + id = crm_element_value(xml_obj, PCMK_XA_ID); if (id == NULL) { - pe_err("Ignoring <%s> configuration without " XML_ATTR_ID, - xml_obj->name); + pcmk__config_err("Ignoring <%s> configuration without " PCMK_XA_ID, + xml_obj->name); return pcmk_rc_unpack_error; } @@ -641,7 +676,7 @@ pe__unpack_resource(xmlNode *xml_obj, pcmk_resource_t **rsc, *rsc = calloc(1, sizeof(pcmk_resource_t)); if (*rsc == NULL) { - crm_crit("Unable to allocate memory for resource '%s'", id); + pcmk__sched_err("Unable to allocate memory for resource '%s'", id); return ENOMEM; } (*rsc)->cluster = scheduler; @@ -660,45 +695,43 @@ pe__unpack_resource(xmlNode *xml_obj, pcmk_resource_t **rsc, (*rsc)->parent = parent; - ops = find_xml_node((*rsc)->xml, "operations", FALSE); + ops = pcmk__xe_first_child((*rsc)->xml, PCMK_XE_OPERATIONS, NULL, NULL); (*rsc)->ops_xml = expand_idref(ops, scheduler->input); (*rsc)->variant = get_resource_type((const char *) (*rsc)->xml->name); if ((*rsc)->variant == pcmk_rsc_variant_unknown) { - pe_err("Ignoring resource '%s' of unknown type '%s'", - id, (*rsc)->xml->name); + pcmk__config_err("Ignoring resource '%s' of unknown type '%s'", + id, (*rsc)->xml->name); common_free(*rsc); *rsc = NULL; return pcmk_rc_unpack_error; } -#ifndef PCMK__COMPAT_2_0 - warn_about_deprecated_classes(*rsc); -#endif - (*rsc)->meta = pcmk__strkey_table(free, free); (*rsc)->allowed_nodes = pcmk__strkey_table(NULL, free); (*rsc)->known_on = pcmk__strkey_table(NULL, free); - value = crm_element_value((*rsc)->xml, XML_RSC_ATTR_INCARNATION); + value = crm_element_value((*rsc)->xml, PCMK__META_CLONE); if (value) { (*rsc)->id = crm_strdup_printf("%s:%s", id, value); - add_hash_param((*rsc)->meta, XML_RSC_ATTR_INCARNATION, value); + pcmk__insert_meta(*rsc, PCMK__META_CLONE, value); } else { (*rsc)->id = strdup(id); } + warn_about_deprecated_classes(*rsc); + (*rsc)->fns = &resource_class_functions[(*rsc)->variant]; get_meta_attributes((*rsc)->meta, *rsc, NULL, scheduler); (*rsc)->parameters = pe_rsc_params(*rsc, NULL, scheduler); // \deprecated (*rsc)->flags = 0; - pe__set_resource_flags(*rsc, pcmk_rsc_runnable|pcmk_rsc_unassigned); + pcmk__set_rsc_flags(*rsc, pcmk_rsc_runnable|pcmk_rsc_unassigned); if (!pcmk_is_set(scheduler->flags, pcmk_sched_in_maintenance)) { - pe__set_resource_flags(*rsc, pcmk_rsc_managed); + pcmk__set_rsc_flags(*rsc, pcmk_rsc_managed); } (*rsc)->rsc_cons = NULL; @@ -709,151 +742,186 @@ pe__unpack_resource(xmlNode *xml_obj, pcmk_resource_t **rsc, (*rsc)->recovery_type = pcmk_multiply_active_restart; (*rsc)->stickiness = 0; - (*rsc)->migration_threshold = INFINITY; + (*rsc)->migration_threshold = PCMK_SCORE_INFINITY; (*rsc)->failure_timeout = 0; - value = g_hash_table_lookup((*rsc)->meta, XML_CIB_ATTR_PRIORITY); + value = g_hash_table_lookup((*rsc)->meta, PCMK_META_PRIORITY); (*rsc)->priority = char2score(value); - value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_CRITICAL); + value = g_hash_table_lookup((*rsc)->meta, PCMK_META_CRITICAL); if ((value == NULL) || crm_is_true(value)) { - pe__set_resource_flags(*rsc, pcmk_rsc_critical); + pcmk__set_rsc_flags(*rsc, pcmk_rsc_critical); } - value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_NOTIFY); + value = g_hash_table_lookup((*rsc)->meta, PCMK_META_NOTIFY); if (crm_is_true(value)) { - pe__set_resource_flags(*rsc, pcmk_rsc_notify); + pcmk__set_rsc_flags(*rsc, pcmk_rsc_notify); } if (xml_contains_remote_node((*rsc)->xml)) { (*rsc)->is_remote_node = TRUE; - if (g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_CONTAINER)) { + if (g_hash_table_lookup((*rsc)->meta, PCMK__META_CONTAINER)) { guest_node = true; } else { remote_node = true; } } - value = g_hash_table_lookup((*rsc)->meta, XML_OP_ATTR_ALLOW_MIGRATE); + value = g_hash_table_lookup((*rsc)->meta, PCMK_META_ALLOW_MIGRATE); if (crm_is_true(value)) { - pe__set_resource_flags(*rsc, pcmk_rsc_migratable); + pcmk__set_rsc_flags(*rsc, pcmk_rsc_migratable); } else if ((value == NULL) && remote_node) { /* By default, we want remote nodes to be able * to float around the cluster without having to stop all the * resources within the remote-node before moving. Allowing * migration support enables this feature. If this ever causes * problems, migration support can be explicitly turned off with - * allow-migrate=false. + * PCMK_META_ALLOW_MIGRATE=false. */ - pe__set_resource_flags(*rsc, pcmk_rsc_migratable); + pcmk__set_rsc_flags(*rsc, pcmk_rsc_migratable); } - value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_MANAGED); - if (value != NULL && !pcmk__str_eq("default", value, pcmk__str_casei)) { - if (crm_is_true(value)) { - pe__set_resource_flags(*rsc, pcmk_rsc_managed); + value = g_hash_table_lookup((*rsc)->meta, PCMK_META_IS_MANAGED); + if (value != NULL) { + if (pcmk__str_eq(PCMK_VALUE_DEFAULT, value, pcmk__str_casei)) { + // @COMPAT Deprecated since 2.1.8 + pcmk__config_warn("Support for setting " PCMK_META_IS_MANAGED + " to the explicit value '" PCMK_VALUE_DEFAULT + "' is deprecated and will be removed in a " + "future release (just leave it unset)"); + } else if (crm_is_true(value)) { + pcmk__set_rsc_flags(*rsc, pcmk_rsc_managed); } else { - pe__clear_resource_flags(*rsc, pcmk_rsc_managed); + pcmk__clear_rsc_flags(*rsc, pcmk_rsc_managed); } } - value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_MAINTENANCE); + value = g_hash_table_lookup((*rsc)->meta, PCMK_META_MAINTENANCE); if (crm_is_true(value)) { - pe__clear_resource_flags(*rsc, pcmk_rsc_managed); - pe__set_resource_flags(*rsc, pcmk_rsc_maintenance); + pcmk__clear_rsc_flags(*rsc, pcmk_rsc_managed); + pcmk__set_rsc_flags(*rsc, pcmk_rsc_maintenance); } if (pcmk_is_set(scheduler->flags, pcmk_sched_in_maintenance)) { - pe__clear_resource_flags(*rsc, pcmk_rsc_managed); - pe__set_resource_flags(*rsc, pcmk_rsc_maintenance); + pcmk__clear_rsc_flags(*rsc, pcmk_rsc_managed); + pcmk__set_rsc_flags(*rsc, pcmk_rsc_maintenance); } - if (pe_rsc_is_clone(pe__const_top_resource(*rsc, false))) { - value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_UNIQUE); + if (pcmk__is_clone(pe__const_top_resource(*rsc, false))) { + value = g_hash_table_lookup((*rsc)->meta, PCMK_META_GLOBALLY_UNIQUE); if (crm_is_true(value)) { - pe__set_resource_flags(*rsc, pcmk_rsc_unique); + pcmk__set_rsc_flags(*rsc, pcmk_rsc_unique); } if (detect_promotable(*rsc)) { - pe__set_resource_flags(*rsc, pcmk_rsc_promotable); + pcmk__set_rsc_flags(*rsc, pcmk_rsc_promotable); } } else { - pe__set_resource_flags(*rsc, pcmk_rsc_unique); + pcmk__set_rsc_flags(*rsc, pcmk_rsc_unique); } - value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_RESTART); - if (pcmk__str_eq(value, "restart", pcmk__str_casei)) { + // @COMPAT Deprecated meta-attribute + value = g_hash_table_lookup((*rsc)->meta, PCMK__META_RESTART_TYPE); + if (pcmk__str_eq(value, PCMK_VALUE_RESTART, pcmk__str_casei)) { (*rsc)->restart_type = pe_restart_restart; - pe_rsc_trace((*rsc), "%s dependency restart handling: restart", - (*rsc)->id); - pe_warn_once(pcmk__wo_restart_type, - "Support for restart-type is deprecated and will be removed in a future release"); + pcmk__rsc_trace(*rsc, "%s dependency restart handling: restart", + (*rsc)->id); + pcmk__warn_once(pcmk__wo_restart_type, + "Support for " PCMK__META_RESTART_TYPE " is deprecated " + "and will be removed in a future release"); } else { (*rsc)->restart_type = pe_restart_ignore; - pe_rsc_trace((*rsc), "%s dependency restart handling: ignore", - (*rsc)->id); + pcmk__rsc_trace(*rsc, "%s dependency restart handling: ignore", + (*rsc)->id); } - value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_MULTIPLE); - if (pcmk__str_eq(value, "stop_only", pcmk__str_casei)) { + value = g_hash_table_lookup((*rsc)->meta, PCMK_META_MULTIPLE_ACTIVE); + if (pcmk__str_eq(value, PCMK_VALUE_STOP_ONLY, pcmk__str_casei)) { (*rsc)->recovery_type = pcmk_multiply_active_stop; - pe_rsc_trace((*rsc), "%s multiple running resource recovery: stop only", - (*rsc)->id); + pcmk__rsc_trace(*rsc, "%s multiple running resource recovery: stop only", + (*rsc)->id); - } else if (pcmk__str_eq(value, "block", pcmk__str_casei)) { + } else if (pcmk__str_eq(value, PCMK_VALUE_BLOCK, pcmk__str_casei)) { (*rsc)->recovery_type = pcmk_multiply_active_block; - pe_rsc_trace((*rsc), "%s multiple running resource recovery: block", - (*rsc)->id); + pcmk__rsc_trace(*rsc, "%s multiple running resource recovery: block", + (*rsc)->id); - } else if (pcmk__str_eq(value, "stop_unexpected", pcmk__str_casei)) { + } else if (pcmk__str_eq(value, PCMK_VALUE_STOP_UNEXPECTED, + pcmk__str_casei)) { (*rsc)->recovery_type = pcmk_multiply_active_unexpected; - pe_rsc_trace((*rsc), "%s multiple running resource recovery: " - "stop unexpected instances", - (*rsc)->id); + pcmk__rsc_trace(*rsc, + "%s multiple running resource recovery: " + "stop unexpected instances", + (*rsc)->id); - } else { // "stop_start" - if (!pcmk__str_eq(value, "stop_start", + } else { // PCMK_VALUE_STOP_START + if (!pcmk__str_eq(value, PCMK_VALUE_STOP_START, pcmk__str_casei|pcmk__str_null_matches)) { - pe_warn("%s is not a valid value for " XML_RSC_ATTR_MULTIPLE - ", using default of \"stop_start\"", value); + pcmk__config_warn("%s is not a valid value for " + PCMK_META_MULTIPLE_ACTIVE + ", using default of " + "\"" PCMK_VALUE_STOP_START "\"", + value); } (*rsc)->recovery_type = pcmk_multiply_active_restart; - pe_rsc_trace((*rsc), "%s multiple running resource recovery: " - "stop/start", (*rsc)->id); + pcmk__rsc_trace(*rsc, + "%s multiple running resource recovery: stop/start", + (*rsc)->id); } - value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_STICKINESS); - if (value != NULL && !pcmk__str_eq("default", value, pcmk__str_casei)) { - (*rsc)->stickiness = char2score(value); + value = g_hash_table_lookup((*rsc)->meta, PCMK_META_RESOURCE_STICKINESS); + if (value != NULL) { + if (pcmk__str_eq(PCMK_VALUE_DEFAULT, value, pcmk__str_casei)) { + // @COMPAT Deprecated since 2.1.8 + pcmk__config_warn("Support for setting " + PCMK_META_RESOURCE_STICKINESS + " to the explicit value '" PCMK_VALUE_DEFAULT + "' is deprecated and will be removed in a " + "future release (just leave it unset)"); + } else { + (*rsc)->stickiness = char2score(value); + } } value = g_hash_table_lookup((*rsc)->meta, PCMK_META_MIGRATION_THRESHOLD); - if (value != NULL && !pcmk__str_eq("default", value, pcmk__str_casei)) { - (*rsc)->migration_threshold = char2score(value); - if ((*rsc)->migration_threshold < 0) { - /* @TODO We use 1 here to preserve previous behavior, but this - * should probably use the default (INFINITY) or 0 (to disable) - * instead. - */ - pe_warn_once(pcmk__wo_neg_threshold, - PCMK_META_MIGRATION_THRESHOLD - " must be non-negative, using 1 instead"); - (*rsc)->migration_threshold = 1; + if (value != NULL) { + if (pcmk__str_eq(PCMK_VALUE_DEFAULT, value, pcmk__str_casei)) { + // @COMPAT Deprecated since 2.1.8 + pcmk__config_warn("Support for setting " + PCMK_META_MIGRATION_THRESHOLD + " to the explicit value '" PCMK_VALUE_DEFAULT + "' is deprecated and will be removed in a " + "future release (just leave it unset)"); + } else { + (*rsc)->migration_threshold = char2score(value); + if ((*rsc)->migration_threshold < 0) { + /* @COMPAT We use 1 here to preserve previous behavior, but this + * should probably use the default (INFINITY) or 0 (to disable) + * instead. + */ + pcmk__warn_once(pcmk__wo_neg_threshold, + PCMK_META_MIGRATION_THRESHOLD + " must be non-negative, using 1 instead"); + (*rsc)->migration_threshold = 1; + } } } - if (pcmk__str_eq(crm_element_value((*rsc)->xml, XML_AGENT_ATTR_CLASS), + if (pcmk__str_eq(crm_element_value((*rsc)->xml, PCMK_XA_CLASS), PCMK_RESOURCE_CLASS_STONITH, pcmk__str_casei)) { - pe__set_working_set_flags(scheduler, pcmk_sched_have_fencing); - pe__set_resource_flags(*rsc, pcmk_rsc_fence_device); + pcmk__set_scheduler_flags(scheduler, pcmk_sched_have_fencing); + pcmk__set_rsc_flags(*rsc, pcmk_rsc_fence_device); } - value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_REQUIRES); + value = g_hash_table_lookup((*rsc)->meta, PCMK_META_REQUIRES); unpack_requires(*rsc, value, false); value = g_hash_table_lookup((*rsc)->meta, PCMK_META_FAILURE_TIMEOUT); if (value != NULL) { + guint interval_ms = 0U; + // Stored as seconds - (*rsc)->failure_timeout = (int) (crm_parse_interval_spec(value) / 1000); + pcmk_parse_interval_spec(value, &interval_ms); + (*rsc)->failure_timeout = (int) (interval_ms / 1000); } if (remote_node) { @@ -861,24 +929,27 @@ pe__unpack_resource(xmlNode *xml_obj, pcmk_resource_t **rsc, /* Grabbing the value now means that any rules based on node attributes * will evaluate to false, so such rules should not be used with - * reconnect_interval. + * PCMK_REMOTE_RA_RECONNECT_INTERVAL. * * @TODO Evaluate per node before using */ - value = g_hash_table_lookup(params, XML_REMOTE_ATTR_RECONNECT_INTERVAL); + value = g_hash_table_lookup(params, PCMK_REMOTE_RA_RECONNECT_INTERVAL); if (value) { /* reconnect delay works by setting failure_timeout and preventing the * connection from starting until the failure is cleared. */ - (*rsc)->remote_reconnect_ms = crm_parse_interval_spec(value); - /* we want to override any default failure_timeout in use when remote - * reconnect_interval is in use. */ + pcmk_parse_interval_spec(value, &((*rsc)->remote_reconnect_ms)); + + /* We want to override any default failure_timeout in use when remote + * PCMK_REMOTE_RA_RECONNECT_INTERVAL is in use. + */ (*rsc)->failure_timeout = (*rsc)->remote_reconnect_ms / 1000; } } get_target_role(*rsc, &((*rsc)->next_role)); - pe_rsc_trace((*rsc), "%s desired next state: %s", (*rsc)->id, - (*rsc)->next_role != pcmk_role_unknown? role2text((*rsc)->next_role) : "default"); + pcmk__rsc_trace(*rsc, "%s desired next state: %s", (*rsc)->id, + ((*rsc)->next_role == pcmk_role_unknown)? + "default" : pcmk_role_text((*rsc)->next_role)); if ((*rsc)->fns->unpack(*rsc, scheduler) == FALSE) { (*rsc)->fns->free(*rsc); @@ -897,12 +968,12 @@ pe__unpack_resource(xmlNode *xml_obj, pcmk_resource_t **rsc, scheduler); } - pe_rsc_trace((*rsc), "%s action notification: %s", (*rsc)->id, - pcmk_is_set((*rsc)->flags, pcmk_rsc_notify)? "required" : "not required"); + pcmk__rsc_trace(*rsc, "%s action notification: %s", (*rsc)->id, + pcmk_is_set((*rsc)->flags, pcmk_rsc_notify)? "required" : "not required"); (*rsc)->utilization = pcmk__strkey_table(free, free); - pe__unpack_dataset_nvpairs((*rsc)->xml, XML_TAG_UTILIZATION, &rule_data, + pe__unpack_dataset_nvpairs((*rsc)->xml, PCMK_XE_UTILIZATION, &rule_data, (*rsc)->utilization, NULL, FALSE, scheduler); if (expanded_xml) { @@ -940,8 +1011,7 @@ uber_parent(pcmk_resource_t *rsc) if (parent == NULL) { return NULL; } - while ((parent->parent != NULL) - && (parent->parent->variant != pcmk_rsc_variant_bundle)) { + while ((parent->parent != NULL) && !pcmk__is_bundle(parent->parent)) { parent = parent->parent; } return parent; @@ -967,8 +1037,7 @@ pe__const_top_resource(const pcmk_resource_t *rsc, bool include_bundle) return NULL; } while (parent->parent != NULL) { - if (!include_bundle - && (parent->parent->variant == pcmk_rsc_variant_bundle)) { + if (!include_bundle && pcmk__is_bundle(parent->parent)) { break; } parent = parent->parent; @@ -983,7 +1052,7 @@ common_free(pcmk_resource_t * rsc) return; } - pe_rsc_trace(rsc, "Freeing %s %d", rsc->id, rsc->variant); + pcmk__rsc_trace(rsc, "Freeing %s %d", rsc->id, rsc->variant); g_list_free(rsc->rsc_cons); g_list_free(rsc->rsc_cons_lhs); @@ -1031,7 +1100,7 @@ common_free(pcmk_resource_t * rsc) } g_list_free(rsc->fillers); g_list_free(rsc->rsc_location); - pe_rsc_trace(rsc, "Resource freed"); + pcmk__rsc_trace(rsc, "Resource freed"); free(rsc->id); free(rsc->clone_name); free(rsc->allocated_to); @@ -1078,7 +1147,7 @@ pe__count_active_node(const pcmk_resource_t *rsc, pcmk_node_t *node, } if (rsc->partial_migration_source != NULL) { - if (node->details == rsc->partial_migration_source->details) { + if (pcmk__same_node(node, rsc->partial_migration_source)) { *active = node; // This is the migration source } else { keep_looking = true; @@ -1124,7 +1193,7 @@ active_node(const pcmk_resource_t *rsc, unsigned int *count_all, /*! * \brief - * \internal Find and count active nodes according to "requires" + * \internal Find and count active nodes according to \c PCMK_META_REQUIRES * * \param[in] rsc Resource to check * \param[out] count If not NULL, will be set to count of active nodes @@ -1133,7 +1202,7 @@ active_node(const pcmk_resource_t *rsc, unsigned int *count_all, * * \note This is a convenience wrapper for active_node() where the count of all * active nodes or only clean active nodes is desired according to the - * "requires" meta-attribute. + * \c PCMK_META_REQUIRES meta-attribute. */ pcmk_node_t * pe__find_active_requires(const pcmk_resource_t *rsc, unsigned int *count) @@ -1185,8 +1254,9 @@ pe__set_next_role(pcmk_resource_t *rsc, enum rsc_role_e role, const char *why) { CRM_ASSERT((rsc != NULL) && (why != NULL)); if (rsc->next_role != role) { - pe_rsc_trace(rsc, "Resetting next role for %s from %s to %s (%s)", - rsc->id, role2text(rsc->next_role), role2text(role), why); + pcmk__rsc_trace(rsc, "Resetting next role for %s from %s to %s (%s)", + rsc->id, pcmk_role_text(rsc->next_role), + pcmk_role_text(role), why); rsc->next_role = role; } } diff --git a/lib/pengine/failcounts.c b/lib/pengine/failcounts.c index 6990d3d..f33b90f 100644 --- a/lib/pengine/failcounts.c +++ b/lib/pengine/failcounts.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2023 the Pacemaker project contributors + * Copyright 2008-2024 the Pacemaker project contributors * * This source code is licensed under the GNU Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. @@ -12,7 +12,6 @@ #include <glib.h> #include <crm/crm.h> -#include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crm/common/util.h> #include <crm/pengine/internal.h> @@ -35,22 +34,20 @@ is_matched_failure(const char *rsc_id, const xmlNode *conf_op_xml, } // Get name and interval from configured op - conf_op_name = crm_element_value(conf_op_xml, "name"); - conf_op_interval_spec = crm_element_value(conf_op_xml, - XML_LRM_ATTR_INTERVAL); - conf_op_interval_ms = crm_parse_interval_spec(conf_op_interval_spec); + conf_op_name = crm_element_value(conf_op_xml, PCMK_XA_NAME); + conf_op_interval_spec = crm_element_value(conf_op_xml, PCMK_META_INTERVAL); + pcmk_parse_interval_spec(conf_op_interval_spec, &conf_op_interval_ms); // Get name and interval from op history entry - lrm_op_task = crm_element_value(lrm_op_xml, XML_LRM_ATTR_TASK); - crm_element_value_ms(lrm_op_xml, XML_LRM_ATTR_INTERVAL_MS, - &lrm_op_interval_ms); + lrm_op_task = crm_element_value(lrm_op_xml, PCMK_XA_OPERATION); + crm_element_value_ms(lrm_op_xml, PCMK_META_INTERVAL, &lrm_op_interval_ms); if ((conf_op_interval_ms != lrm_op_interval_ms) || !pcmk__str_eq(conf_op_name, lrm_op_task, pcmk__str_casei)) { return FALSE; } - lrm_op_id = ID(lrm_op_xml); + lrm_op_id = pcmk__xe_id(lrm_op_xml); last_failure_key = pcmk__op_key(rsc_id, "last_failure", 0); if (pcmk__str_eq(last_failure_key, lrm_op_id, pcmk__str_casei)) { @@ -64,7 +61,7 @@ is_matched_failure(const char *rsc_id, const xmlNode *conf_op_xml, int rc = 0; int target_rc = pe__target_rc_from_xml(lrm_op_xml); - crm_element_value_int(lrm_op_xml, XML_LRM_ATTR_RC, &rc); + crm_element_value_int(lrm_op_xml, PCMK__XA_RC_CODE, &rc); if (rc != target_rc) { matched = TRUE; } @@ -86,16 +83,17 @@ block_failure(const pcmk_node_t *node, pcmk_resource_t *rsc, * to properly detect on-fail in id-ref, operation meta-attributes, or * op_defaults, or evaluate rules. * - * Also, on-fail defaults to block (in unpack_operation()) for stop actions - * when stonith is disabled. + * Also, PCMK_META_ON_FAIL defaults to PCMK_VALUE_BLOCK (in + * unpack_operation()) for stop actions when stonith is disabled. * * Ideally, we'd unpack the operation before this point, and pass in a * meta-attributes table that takes all that into consideration. */ - char *xpath = crm_strdup_printf("//" XML_CIB_TAG_RESOURCE - "[@" XML_ATTR_ID "='%s']" - "//" XML_ATTR_OP - "[@" XML_OP_ATTR_ON_FAIL "='block']", + char *xpath = crm_strdup_printf("//" PCMK_XE_PRIMITIVE + "[@" PCMK_XA_ID "='%s']" + "//" PCMK_XE_OP + "[@" PCMK_META_ON_FAIL + "='" PCMK_VALUE_BLOCK "']", xml_name); xmlXPathObject *xpathObj = xpath_search(rsc->xml, xpath); @@ -124,14 +122,16 @@ block_failure(const pcmk_node_t *node, pcmk_resource_t *rsc, xmlXPathObject *lrm_op_xpathObj = NULL; // Get name and interval from configured op - conf_op_name = crm_element_value(pref, "name"); - conf_op_interval_spec = crm_element_value(pref, XML_LRM_ATTR_INTERVAL); - conf_op_interval_ms = crm_parse_interval_spec(conf_op_interval_spec); + conf_op_name = crm_element_value(pref, PCMK_XA_NAME); + conf_op_interval_spec = crm_element_value(pref, + PCMK_META_INTERVAL); + pcmk_parse_interval_spec(conf_op_interval_spec, + &conf_op_interval_ms); -#define XPATH_FMT "//" XML_CIB_TAG_STATE "[@" XML_ATTR_UNAME "='%s']" \ - "//" XML_LRM_TAG_RESOURCE "[@" XML_ATTR_ID "='%s']" \ - "/" XML_LRM_TAG_RSC_OP "[@" XML_LRM_ATTR_TASK "='%s']" \ - "[@" XML_LRM_ATTR_INTERVAL "='%u']" +#define XPATH_FMT "//" PCMK__XE_NODE_STATE "[@" PCMK_XA_UNAME "='%s']" \ + "//" PCMK__XE_LRM_RESOURCE "[@" PCMK_XA_ID "='%s']" \ + "/" PCMK__XE_LRM_RSC_OP "[@" PCMK_XA_OPERATION "='%s']" \ + "[@" PCMK_META_INTERVAL "='%u']" lrm_op_xpath = crm_strdup_printf(XPATH_FMT, node->details->uname, xml_name, @@ -251,7 +251,7 @@ generate_fail_regexes(const pcmk_resource_t *rsc, int rc = pcmk_rc_ok; char *rsc_name = rsc_fail_name(rsc); const char *version = crm_element_value(rsc->cluster->input, - XML_ATTR_CRM_VERSION); + PCMK_XA_CRM_FEATURE_SET); // @COMPAT Pacemaker <= 1.1.16 used a single fail count per resource gboolean is_legacy = (compare_version(version, "3.0.13") < 0); @@ -302,9 +302,10 @@ update_failcount_for_attr(gpointer key, gpointer value, gpointer user_data) if (regexec(&(fc_data->failcount_re), (const char *) key, 0, NULL, 0) == 0) { fc_data->failcount = pcmk__add_scores(fc_data->failcount, char2score(value)); - pe_rsc_trace(fc_data->rsc, "Added %s (%s) to %s fail count (now %s)", - (const char *) key, (const char *) value, fc_data->rsc->id, - pcmk_readable_score(fc_data->failcount)); + pcmk__rsc_trace(fc_data->rsc, "Added %s (%s) to %s fail count (now %s)", + (const char *) key, (const char *) value, + fc_data->rsc->id, + pcmk_readable_score(fc_data->failcount)); return; } @@ -382,9 +383,10 @@ pe_get_failcount(const pcmk_node_t *node, pcmk_resource_t *rsc, if ((fc_data.failcount > 0) && (rsc->failure_timeout > 0) && block_failure(node, rsc, xml_op)) { - pe_warn("Ignoring failure timeout %d for %s " - "because it conflicts with on-fail=block", - rsc->failure_timeout, rsc->id); + pcmk__config_warn("Ignoring failure timeout %d for %s " + "because it conflicts with " + PCMK_META_ON_FAIL "=" PCMK_VALUE_BLOCK, + rsc->failure_timeout, rsc->id); rsc->failure_timeout = 0; } @@ -395,8 +397,9 @@ pe_get_failcount(const pcmk_node_t *node, pcmk_resource_t *rsc, time_t now = get_effective_time(rsc->cluster); if (now > (fc_data.last_failure + rsc->failure_timeout)) { - pe_rsc_debug(rsc, "Failcount for %s on %s expired after %ds", - rsc->id, pe__node_name(node), rsc->failure_timeout); + pcmk__rsc_debug(rsc, "Failcount for %s on %s expired after %ds", + rsc->id, pcmk__node_name(node), + rsc->failure_timeout); fc_data.failcount = 0; } } @@ -412,21 +415,23 @@ pe_get_failcount(const pcmk_node_t *node, pcmk_resource_t *rsc, * container on the wrong node. */ if (pcmk_is_set(flags, pcmk__fc_fillers) && (rsc->fillers != NULL) - && !pe_rsc_is_bundled(rsc)) { + && !pcmk__is_bundled(rsc)) { g_list_foreach(rsc->fillers, update_failcount_for_filler, &fc_data); if (fc_data.failcount > 0) { - pe_rsc_info(rsc, - "Container %s and the resources within it " - "have failed %s time%s on %s", - rsc->id, pcmk_readable_score(fc_data.failcount), - pcmk__plural_s(fc_data.failcount), pe__node_name(node)); + pcmk__rsc_info(rsc, + "Container %s and the resources within it " + "have failed %s time%s on %s", + rsc->id, pcmk_readable_score(fc_data.failcount), + pcmk__plural_s(fc_data.failcount), + pcmk__node_name(node)); } } else if (fc_data.failcount > 0) { - pe_rsc_info(rsc, "%s has failed %s time%s on %s", - rsc->id, pcmk_readable_score(fc_data.failcount), - pcmk__plural_s(fc_data.failcount), pe__node_name(node)); + pcmk__rsc_info(rsc, "%s has failed %s time%s on %s", + rsc->id, pcmk_readable_score(fc_data.failcount), + pcmk__plural_s(fc_data.failcount), + pcmk__node_name(node)); } if (last_failure != NULL) { @@ -461,8 +466,8 @@ pe__clear_failcount(pcmk_resource_t *rsc, const pcmk_node_t *node, key = pcmk__op_key(rsc->id, PCMK_ACTION_CLEAR_FAILCOUNT, 0); clear = custom_action(rsc, key, PCMK_ACTION_CLEAR_FAILCOUNT, node, FALSE, scheduler); - add_hash_param(clear->meta, XML_ATTR_TE_NOWAIT, XML_BOOLEAN_TRUE); + pcmk__insert_meta(clear, PCMK__META_OP_NO_WAIT, PCMK_VALUE_TRUE); crm_notice("Clearing failure of %s on %s because %s " CRM_XS " %s", - rsc->id, pe__node_name(node), reason, clear->uuid); + rsc->id, pcmk__node_name(node), reason, clear->uuid); return clear; } diff --git a/lib/pengine/group.c b/lib/pengine/group.c index dad610c..143956b 100644 --- a/lib/pengine/group.c +++ b/lib/pengine/group.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2023 the Pacemaker project contributors + * Copyright 2004-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -14,7 +14,7 @@ #include <crm/pengine/rules.h> #include <crm/pengine/status.h> #include <crm/pengine/internal.h> -#include <crm/msg_xml.h> +#include <crm/common/xml.h> #include <crm/common/output.h> #include <crm/common/strings_internal.h> #include <crm/common/xml_internal.h> @@ -37,8 +37,8 @@ pcmk_resource_t * pe__last_group_member(const pcmk_resource_t *group) { if (group != NULL) { - CRM_CHECK((group->variant == pcmk_rsc_variant_group) - && (group->variant_opaque != NULL), return NULL); + CRM_CHECK(pcmk__is_group(group) && (group->variant_opaque != NULL), + return NULL); return ((group_variant_data_t *) group->variant_opaque)->last_child; } return NULL; @@ -58,8 +58,8 @@ pe__group_flag_is_set(const pcmk_resource_t *group, uint32_t flags) { group_variant_data_t *group_data = NULL; - CRM_CHECK((group != NULL) && (group->variant == pcmk_rsc_variant_group) - && (group->variant_opaque != NULL), return false); + CRM_CHECK(pcmk__is_group(group) && (group->variant_opaque != NULL), + return false); group_data = (group_variant_data_t *) group->variant_opaque; return pcmk_all_flags_set(group_data->flags, flags); } @@ -89,10 +89,10 @@ set_group_flag(pcmk_resource_t *group, const char *option, uint32_t flag, ((group_variant_data_t *) group->variant_opaque)->flags |= flag; } else { - pe_warn_once(wo_bit, - "Support for the '%s' group meta-attribute is deprecated " - "and will be removed in a future release " - "(use a resource set instead)", option); + pcmk__warn_once(wo_bit, + "Support for the '%s' group meta-attribute is " + "deprecated and will be removed in a future release " + "(use a resource set instead)", option); } } @@ -184,28 +184,28 @@ group_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) group_variant_data_t *group_data = NULL; const char *clone_id = NULL; - pe_rsc_trace(rsc, "Processing resource %s...", rsc->id); + pcmk__rsc_trace(rsc, "Processing resource %s...", rsc->id); - group_data = calloc(1, sizeof(group_variant_data_t)); + group_data = pcmk__assert_alloc(1, sizeof(group_variant_data_t)); group_data->last_child = NULL; rsc->variant_opaque = group_data; // @COMPAT These are deprecated since 2.1.5 - set_group_flag(rsc, XML_RSC_ATTR_ORDERED, pcmk__group_ordered, + set_group_flag(rsc, PCMK_META_ORDERED, pcmk__group_ordered, pcmk__wo_group_order); set_group_flag(rsc, "collocated", pcmk__group_colocated, pcmk__wo_group_coloc); - clone_id = crm_element_value(rsc->xml, XML_RSC_ATTR_INCARNATION); + clone_id = crm_element_value(rsc->xml, PCMK__META_CLONE); - for (xml_native_rsc = pcmk__xe_first_child(xml_obj); xml_native_rsc != NULL; + for (xml_native_rsc = pcmk__xe_first_child(xml_obj, NULL, NULL, NULL); + xml_native_rsc != NULL; xml_native_rsc = pcmk__xe_next(xml_native_rsc)) { - if (pcmk__str_eq((const char *)xml_native_rsc->name, - XML_CIB_TAG_RESOURCE, pcmk__str_none)) { + if (pcmk__xe_is(xml_native_rsc, PCMK_XE_PRIMITIVE)) { pcmk_resource_t *new_rsc = NULL; - crm_xml_add(xml_native_rsc, XML_RSC_ATTR_INCARNATION, clone_id); + crm_xml_add(xml_native_rsc, PCMK__META_CLONE, clone_id); if (pe__unpack_resource(xml_native_rsc, &new_rsc, rsc, scheduler) != pcmk_rc_ok) { continue; @@ -213,7 +213,7 @@ group_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) rsc->children = g_list_append(rsc->children, new_rsc); group_data->last_child = new_rsc; - pe_rsc_trace(rsc, "Added %s member %s", rsc->id, new_rsc->id); + pcmk__rsc_trace(rsc, "Added %s member %s", rsc->id, new_rsc->id); } } @@ -268,7 +268,7 @@ group_print_xml(pcmk_resource_t *rsc, const char *pre_text, long options, GList *gIter = rsc->children; char *child_text = crm_strdup_printf("%s ", pre_text); - status_print("%s<group " XML_ATTR_ID "=\"%s\" ", pre_text, rsc->id); + status_print("%s<group " PCMK_XA_ID "=\"%s\" ", pre_text, rsc->id); status_print("number_resources=\"%d\" ", g_list_length(rsc->children)); status_print(">\n"); @@ -369,23 +369,25 @@ pe__group_xml(pcmk__output_t *out, va_list args) if (rc == pcmk_rc_no_output) { char *count = pcmk__itoa(g_list_length(gIter)); - const char *maint_s = pe__rsc_bool_str(rsc, pcmk_rsc_maintenance); - const char *managed_s = pe__rsc_bool_str(rsc, pcmk_rsc_managed); - const char *disabled_s = pcmk__btoa(pe__resource_is_disabled(rsc)); - - rc = pe__name_and_nvpairs_xml(out, true, "group", 5, - XML_ATTR_ID, rsc->id, - "number_resources", count, - "maintenance", maint_s, - "managed", managed_s, - "disabled", disabled_s, - "description", desc); + const char *maintenance = pcmk__flag_text(rsc->flags, + pcmk_rsc_maintenance); + const char *managed = pcmk__flag_text(rsc->flags, pcmk_rsc_managed); + const char *disabled = pcmk__btoa(pe__resource_is_disabled(rsc)); + + rc = pe__name_and_nvpairs_xml(out, true, PCMK_XE_GROUP, + PCMK_XA_ID, rsc->id, + PCMK_XA_NUMBER_RESOURCES, count, + PCMK_XA_MAINTENANCE, maintenance, + PCMK_XA_MANAGED, managed, + PCMK_XA_DISABLED, disabled, + PCMK_XA_DESCRIPTION, desc, + NULL); free(count); CRM_ASSERT(rc == pcmk_rc_ok); } - out->message(out, crm_map_element_name(child_rsc->xml), show_opts, child_rsc, - only_node, only_rsc); + out->message(out, (const char *) child_rsc->xml->name, show_opts, + child_rsc, only_node, only_rsc); } if (rc == pcmk_rc_ok) { @@ -442,7 +444,7 @@ pe__group_default(pcmk__output_t *out, va_list args) group_header(out, &rc, rsc, !active && partially_active ? inactive_resources(rsc) : 0, pcmk_is_set(show_opts, pcmk_show_inactive_rscs), desc); - out->message(out, crm_map_element_name(child_rsc->xml), show_opts, + out->message(out, (const char *) child_rsc->xml->name, show_opts, child_rsc, only_node, only_rsc); } } @@ -457,17 +459,17 @@ group_free(pcmk_resource_t * rsc) { CRM_CHECK(rsc != NULL, return); - pe_rsc_trace(rsc, "Freeing %s", rsc->id); + pcmk__rsc_trace(rsc, "Freeing %s", rsc->id); for (GList *gIter = rsc->children; gIter != NULL; gIter = gIter->next) { pcmk_resource_t *child_rsc = (pcmk_resource_t *) gIter->data; CRM_ASSERT(child_rsc); - pe_rsc_trace(child_rsc, "Freeing child %s", child_rsc->id); + pcmk__rsc_trace(child_rsc, "Freeing child %s", child_rsc->id); child_rsc->fns->free(child_rsc); } - pe_rsc_trace(rsc, "Freeing child list"); + pcmk__rsc_trace(rsc, "Freeing child list"); g_list_free(rsc->children); common_free(rsc); @@ -488,7 +490,7 @@ group_resource_state(const pcmk_resource_t * rsc, gboolean current) } } - pe_rsc_trace(rsc, "%s role: %s", rsc->id, role2text(group_role)); + pcmk__rsc_trace(rsc, "%s role: %s", rsc->id, pcmk_role_text(group_role)); return group_role; } @@ -534,6 +536,6 @@ pe__group_is_filtered(const pcmk_resource_t *rsc, GList *only_rsc, unsigned int pe__group_max_per_node(const pcmk_resource_t *rsc) { - CRM_ASSERT((rsc != NULL) && (rsc->variant == pcmk_rsc_variant_group)); + CRM_ASSERT(pcmk__is_group(rsc)); return 1U; } diff --git a/lib/pengine/native.c b/lib/pengine/native.c index 48b1a6a..053ffda 100644 --- a/lib/pengine/native.c +++ b/lib/pengine/native.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2023 the Pacemaker project contributors + * Copyright 2004-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -16,7 +16,7 @@ #include <crm/pengine/status.h> #include <crm/pengine/complex.h> #include <crm/pengine/internal.h> -#include <crm/msg_xml.h> +#include <crm/common/xml.h> #include <pe_status_private.h> #ifdef PCMK__COMPAT_2_0 @@ -34,7 +34,7 @@ is_multiply_active(const pcmk_resource_t *rsc) { unsigned int count = 0; - if (rsc->variant == pcmk_rsc_variant_primitive) { + if (pcmk__is_primitive(rsc)) { pe__find_active_requires(rsc, &count); } return count > 1; @@ -59,11 +59,11 @@ native_priority_to_node(pcmk_resource_t *rsc, pcmk_node_t *node, } node->details->priority += priority; - pe_rsc_trace(rsc, "%s now has priority %d with %s'%s' (priority: %d%s)", - pe__node_name(node), node->details->priority, - (rsc->role == pcmk_role_promoted)? "promoted " : "", - rsc->id, rsc->priority, - (rsc->role == pcmk_role_promoted)? " + 1" : ""); + pcmk__rsc_trace(rsc, "%s now has priority %d with %s'%s' (priority: %d%s)", + pcmk__node_name(node), node->details->priority, + (rsc->role == pcmk_role_promoted)? "promoted " : "", + rsc->id, rsc->priority, + (rsc->role == pcmk_role_promoted)? " + 1" : ""); /* Priority of a resource running on a guest node is added to the cluster * node as well. */ @@ -75,13 +75,14 @@ native_priority_to_node(pcmk_resource_t *rsc, pcmk_node_t *node, pcmk_node_t *a_node = gIter->data; a_node->details->priority += priority; - pe_rsc_trace(rsc, "%s now has priority %d with %s'%s' (priority: %d%s) " - "from guest node %s", - pe__node_name(a_node), a_node->details->priority, - (rsc->role == pcmk_role_promoted)? "promoted " : "", - rsc->id, rsc->priority, - (rsc->role == pcmk_role_promoted)? " + 1" : "", - pe__node_name(node)); + pcmk__rsc_trace(rsc, + "%s now has priority %d with %s'%s' " + "(priority: %d%s) from guest node %s", + pcmk__node_name(a_node), a_node->details->priority, + (rsc->role == pcmk_role_promoted)? "promoted " : "", + rsc->id, rsc->priority, + (rsc->role == pcmk_role_promoted)? " + 1" : "", + pcmk__node_name(node)); } } } @@ -102,28 +103,25 @@ native_add_running(pcmk_resource_t *rsc, pcmk_node_t *node, } } - pe_rsc_trace(rsc, "Adding %s to %s %s", rsc->id, pe__node_name(node), - pcmk_is_set(rsc->flags, pcmk_rsc_managed)? "" : "(unmanaged)"); + pcmk__rsc_trace(rsc, "Adding %s to %s %s", rsc->id, pcmk__node_name(node), + pcmk_is_set(rsc->flags, pcmk_rsc_managed)? "" : "(unmanaged)"); rsc->running_on = g_list_append(rsc->running_on, node); - if (rsc->variant == pcmk_rsc_variant_primitive) { + if (pcmk__is_primitive(rsc)) { node->details->running_rsc = g_list_append(node->details->running_rsc, rsc); - native_priority_to_node(rsc, node, failed); - } - - if ((rsc->variant == pcmk_rsc_variant_primitive) - && node->details->maintenance) { - pe__clear_resource_flags(rsc, pcmk_rsc_managed); - pe__set_resource_flags(rsc, pcmk_rsc_maintenance); + if (node->details->maintenance) { + pcmk__clear_rsc_flags(rsc, pcmk_rsc_managed); + pcmk__set_rsc_flags(rsc, pcmk_rsc_maintenance); + } } if (!pcmk_is_set(rsc->flags, pcmk_rsc_managed)) { pcmk_resource_t *p = rsc->parent; - pe_rsc_info(rsc, "resource %s isn't managed", rsc->id); - resource_location(rsc, node, INFINITY, "not_managed_default", - scheduler); + pcmk__rsc_info(rsc, "resource %s isn't managed", rsc->id); + resource_location(rsc, node, PCMK_SCORE_INFINITY, + "not_managed_default", scheduler); while(p && node->details->online) { /* add without the additional location constraint */ @@ -147,28 +145,28 @@ native_add_running(pcmk_resource_t *rsc, pcmk_node_t *node, rsc->allowed_nodes = pe__node_list2table(scheduler->nodes); g_hash_table_iter_init(&gIter, rsc->allowed_nodes); while (g_hash_table_iter_next(&gIter, NULL, (void **)&local_node)) { - local_node->weight = -INFINITY; + local_node->weight = -PCMK_SCORE_INFINITY; } } break; case pcmk_multiply_active_block: - pe__clear_resource_flags(rsc, pcmk_rsc_managed); - pe__set_resource_flags(rsc, pcmk_rsc_blocked); + pcmk__clear_rsc_flags(rsc, pcmk_rsc_managed); + pcmk__set_rsc_flags(rsc, pcmk_rsc_blocked); /* If the resource belongs to a group or bundle configured with - * multiple-active=block, block the entire entity. + * PCMK_META_MULTIPLE_ACTIVE=PCMK_VALUE_BLOCK, block the entire + * entity. */ - if (rsc->parent - && ((rsc->parent->variant == pcmk_rsc_variant_group) - || (rsc->parent->variant == pcmk_rsc_variant_bundle)) + if ((pcmk__is_group(rsc->parent) + || pcmk__is_bundle(rsc->parent)) && (rsc->parent->recovery_type == pcmk_multiply_active_block)) { GList *gIter = rsc->parent->children; for (; gIter != NULL; gIter = gIter->next) { pcmk_resource_t *child = gIter->data; - pe__clear_resource_flags(child, pcmk_rsc_managed); - pe__set_resource_flags(child, pcmk_rsc_blocked); + pcmk__clear_rsc_flags(child, pcmk_rsc_managed); + pcmk__set_rsc_flags(child, pcmk_rsc_blocked); } } break; @@ -181,12 +179,12 @@ native_add_running(pcmk_resource_t *rsc, pcmk_node_t *node, break; } crm_debug("%s is active on multiple nodes including %s: %s", - rsc->id, pe__node_name(node), - recovery2text(rsc->recovery_type)); + rsc->id, pcmk__node_name(node), + pcmk__multiply_active_text(rsc->recovery_type)); } else { - pe_rsc_trace(rsc, "Resource %s is active on %s", - rsc->id, pe__node_name(node)); + pcmk__rsc_trace(rsc, "Resource %s is active on %s", + rsc->id, pcmk__node_name(node)); } if (rsc->parent != NULL) { @@ -197,8 +195,8 @@ native_add_running(pcmk_resource_t *rsc, pcmk_node_t *node, static void recursive_clear_unique(pcmk_resource_t *rsc, gpointer user_data) { - pe__clear_resource_flags(rsc, pcmk_rsc_unique); - add_hash_param(rsc->meta, XML_RSC_ATTR_UNIQUE, XML_BOOLEAN_FALSE); + pcmk__clear_rsc_flags(rsc, pcmk_rsc_unique); + pcmk__insert_meta(rsc, PCMK_META_GLOBALLY_UNIQUE, PCMK_VALUE_FALSE); g_list_foreach(rsc->children, (GFunc) recursive_clear_unique, NULL); } @@ -206,15 +204,15 @@ gboolean native_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) { pcmk_resource_t *parent = uber_parent(rsc); - const char *standard = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS); + const char *standard = crm_element_value(rsc->xml, PCMK_XA_CLASS); uint32_t ra_caps = pcmk_get_ra_caps(standard); - pe_rsc_trace(rsc, "Processing resource %s...", rsc->id); + pcmk__rsc_trace(rsc, "Processing resource %s...", rsc->id); // Only some agent standards support unique and promotable clones if (!pcmk_is_set(ra_caps, pcmk_ra_cap_unique) && pcmk_is_set(rsc->flags, pcmk_rsc_unique) - && pe_rsc_is_clone(parent)) { + && pcmk__is_clone(parent)) { /* @COMPAT We should probably reject this situation as an error (as we * do for promotable below) rather than warn and convert, but that would @@ -223,10 +221,10 @@ native_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) */ pe__force_anon(standard, parent, rsc->id, scheduler); - /* Clear globally-unique on the parent and all its descendants unpacked - * so far (clearing the parent should make any future children unpacking - * correct). We have to clear this resource explicitly because it isn't - * hooked into the parent's children yet. + /* Clear PCMK_META_GLOBALLY_UNIQUE on the parent and all its descendants + * unpacked so far (clearing the parent should make any future children + * unpacking correct). We have to clear this resource explicitly because + * it isn't hooked into the parent's children yet. */ recursive_clear_unique(parent, NULL); recursive_clear_unique(rsc, NULL); @@ -234,9 +232,9 @@ native_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) if (!pcmk_is_set(ra_caps, pcmk_ra_cap_promotable) && pcmk_is_set(parent->flags, pcmk_rsc_promotable)) { - pe_err("Resource %s is of type %s and therefore " - "cannot be used as a promotable clone resource", - rsc->id, standard); + pcmk__config_err("Resource %s is of type %s and therefore " + "cannot be used as a promotable clone resource", + rsc->id, standard); return FALSE; } return TRUE; @@ -245,16 +243,14 @@ native_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) static bool rsc_is_on_node(pcmk_resource_t *rsc, const pcmk_node_t *node, int flags) { - pe_rsc_trace(rsc, "Checking whether %s is on %s", - rsc->id, pe__node_name(node)); + pcmk__rsc_trace(rsc, "Checking whether %s is on %s", + rsc->id, pcmk__node_name(node)); if (pcmk_is_set(flags, pcmk_rsc_match_current_node) && (rsc->running_on != NULL)) { for (GList *iter = rsc->running_on; iter; iter = iter->next) { - pcmk_node_t *loc = (pcmk_node_t *) iter->data; - - if (loc->details == node->details) { + if (pcmk__same_node((pcmk_node_t *) iter->data, node)) { return true; } } @@ -265,7 +261,7 @@ rsc_is_on_node(pcmk_resource_t *rsc, const pcmk_node_t *node, int flags) } else if (!pcmk_is_set(flags, pcmk_rsc_match_current_node) && (rsc->allocated_to != NULL) - && (rsc->allocated_to->details == node->details)) { + && pcmk__same_node(rsc->allocated_to, node)) { return true; } return false; @@ -281,9 +277,9 @@ native_find_rsc(pcmk_resource_t *rsc, const char *id, CRM_CHECK(id && rsc && rsc->id, return NULL); if (pcmk_is_set(flags, pcmk_rsc_match_clone_only)) { - const char *rid = ID(rsc->xml); + const char *rid = pcmk__xe_id(rsc->xml); - if (!pe_rsc_is_clone(pe__const_top_resource(rsc, false))) { + if (!pcmk__is_clone(pe__const_top_resource(rsc, false))) { match = false; } else if (!strcmp(id, rsc->id) || pcmk__str_eq(id, rid, pcmk__str_none)) { @@ -329,22 +325,20 @@ char * native_parameter(pcmk_resource_t *rsc, pcmk_node_t *node, gboolean create, const char *name, pcmk_scheduler_t *scheduler) { - char *value_copy = NULL; const char *value = NULL; GHashTable *params = NULL; CRM_CHECK(rsc != NULL, return NULL); CRM_CHECK(name != NULL && strlen(name) != 0, return NULL); - pe_rsc_trace(rsc, "Looking up %s in %s", name, rsc->id); + pcmk__rsc_trace(rsc, "Looking up %s in %s", name, rsc->id); params = pe_rsc_params(rsc, node, scheduler); value = g_hash_table_lookup(params, name); if (value == NULL) { /* try meta attributes instead */ value = g_hash_table_lookup(rsc->meta, name); } - pcmk__str_update(&value_copy, value); - return value_copy; + return pcmk__str_copy(value); } gboolean @@ -354,16 +348,16 @@ native_active(pcmk_resource_t * rsc, gboolean all) pcmk_node_t *a_node = (pcmk_node_t *) gIter->data; if (a_node->details->unclean) { - pe_rsc_trace(rsc, "Resource %s: %s is unclean", - rsc->id, pe__node_name(a_node)); + pcmk__rsc_trace(rsc, "Resource %s: %s is unclean", + rsc->id, pcmk__node_name(a_node)); return TRUE; } else if (!a_node->details->online && pcmk_is_set(rsc->flags, pcmk_rsc_managed)) { - pe_rsc_trace(rsc, "Resource %s: %s is offline", - rsc->id, pe__node_name(a_node)); + pcmk__rsc_trace(rsc, "Resource %s: %s is offline", + rsc->id, pcmk__node_name(a_node)); } else { - pe_rsc_trace(rsc, "Resource %s active on %s", - rsc->id, pe__node_name(a_node)); + pcmk__rsc_trace(rsc, "Resource %s active on %s", + rsc->id, pcmk__node_name(a_node)); return TRUE; } } @@ -453,7 +447,7 @@ native_displayable_state(const pcmk_resource_t *rsc, bool print_pending) rsc_state = native_pending_state(rsc); } if (rsc_state == NULL) { - rsc_state = role2text(native_displayable_role(rsc)); + rsc_state = pcmk_role_text(native_displayable_role(rsc)); } return rsc_state; } @@ -466,35 +460,37 @@ static void native_print_xml(pcmk_resource_t *rsc, const char *pre_text, long options, void *print_data) { - const char *class = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS); - const char *prov = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER); + const char *class = crm_element_value(rsc->xml, PCMK_XA_CLASS); + const char *prov = crm_element_value(rsc->xml, PCMK_XA_PROVIDER); const char *rsc_state = native_displayable_state(rsc, pcmk_is_set(options, pe_print_pending)); const char *target_role = NULL; /* resource information. */ status_print("%s<resource ", pre_text); - status_print(XML_ATTR_ID "=\"%s\" ", rsc_printable_id(rsc)); + status_print(PCMK_XA_ID "=\"%s\" ", rsc_printable_id(rsc)); status_print("resource_agent=\"%s%s%s:%s\" ", class, ((prov == NULL)? "" : PROVIDER_SEP), ((prov == NULL)? "" : prov), - crm_element_value(rsc->xml, XML_ATTR_TYPE)); + crm_element_value(rsc->xml, PCMK_XA_TYPE)); status_print("role=\"%s\" ", rsc_state); if (rsc->meta) { - target_role = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_TARGET_ROLE); + target_role = g_hash_table_lookup(rsc->meta, PCMK_META_TARGET_ROLE); } if (target_role) { status_print("target_role=\"%s\" ", target_role); } status_print("active=\"%s\" ", pcmk__btoa(rsc->fns->active(rsc, TRUE))); - status_print("orphaned=\"%s\" ", pe__rsc_bool_str(rsc, pcmk_rsc_removed)); + status_print("orphaned=\"%s\" ", + pcmk__flag_text(rsc->flags, pcmk_rsc_removed)); status_print("blocked=\"%s\" ", - pe__rsc_bool_str(rsc, pcmk_rsc_blocked)); + pcmk__flag_text(rsc->flags, pcmk_rsc_blocked)); status_print("managed=\"%s\" ", - pe__rsc_bool_str(rsc, pcmk_rsc_managed)); - status_print("failed=\"%s\" ", pe__rsc_bool_str(rsc, pcmk_rsc_failed)); + pcmk__flag_text(rsc->flags, pcmk_rsc_managed)); + status_print("failed=\"%s\" ", + pcmk__flag_text(rsc->flags, pcmk_rsc_failed)); status_print("failure_ignored=\"%s\" ", - pe__rsc_bool_str(rsc, pcmk_rsc_ignore_failure)); + pcmk__flag_text(rsc->flags, pcmk_rsc_ignore_failure)); status_print("nodes_running_on=\"%d\" ", g_list_length(rsc->running_on)); if (options & pe_print_pending) { @@ -516,8 +512,8 @@ native_print_xml(pcmk_resource_t *rsc, const char *pre_text, long options, for (; gIter != NULL; gIter = gIter->next) { pcmk_node_t *node = (pcmk_node_t *) gIter->data; - status_print("%s <node name=\"%s\" " XML_ATTR_ID "=\"%s\" " - "cached=\"%s\"/>\n", + status_print("%s <node " PCMK_XA_NAME "=\"%s\" " + PCMK_XA_ID "=\"%s\" cached=\"%s\"/>\n", pre_text, pcmk__s(node->details->uname, ""), node->details->id, pcmk__btoa(!node->details->online)); } @@ -564,13 +560,13 @@ pcmk__native_output_string(const pcmk_resource_t *rsc, const char *name, const pcmk_node_t *node, uint32_t show_opts, const char *target_role, bool show_nodes) { - const char *class = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS); + const char *class = crm_element_value(rsc->xml, PCMK_XA_CLASS); const char *provider = NULL; - const char *kind = crm_element_value(rsc->xml, XML_ATTR_TYPE); + const char *kind = crm_element_value(rsc->xml, PCMK_XA_TYPE); GString *outstr = NULL; bool have_flags = false; - if (rsc->variant != pcmk_rsc_variant_primitive) { + if (!pcmk__is_primitive(rsc)) { return NULL; } @@ -579,7 +575,7 @@ pcmk__native_output_string(const pcmk_resource_t *rsc, const char *name, CRM_CHECK(class != NULL, class = "unknown"); if (pcmk_is_set(pcmk_get_ra_caps(class), pcmk_ra_cap_provider)) { - provider = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER); + provider = crm_element_value(rsc->xml, PCMK_XA_PROVIDER); } if ((node == NULL) && (rsc->lock_node != NULL)) { @@ -606,7 +602,7 @@ pcmk__native_output_string(const pcmk_resource_t *rsc, const char *name, g_string_append(outstr, " FAILED"); if (role > pcmk_role_unpromoted) { - pcmk__add_word(&outstr, 0, role2text(role)); + pcmk__add_word(&outstr, 0, pcmk_role_text(role)); } } else { bool show_pending = pcmk_is_set(show_opts, pcmk_show_pending); @@ -614,7 +610,7 @@ pcmk__native_output_string(const pcmk_resource_t *rsc, const char *name, pcmk__add_word(&outstr, 0, native_displayable_state(rsc, show_pending)); } if (node) { - pcmk__add_word(&outstr, 0, pe__node_name(node)); + pcmk__add_word(&outstr, 0, pcmk__node_name(node)); } // Failed probe operation @@ -623,7 +619,8 @@ pcmk__native_output_string(const pcmk_resource_t *rsc, const char *name, if (probe_op != NULL) { int rc; - pcmk__scan_min_int(crm_element_value(probe_op, XML_LRM_ATTR_RC), &rc, 0); + pcmk__scan_min_int(crm_element_value(probe_op, PCMK__XA_RC_CODE), + &rc, 0); pcmk__g_strcat(outstr, " (", services_ocf_exitcode_str(rc), ") ", NULL); } @@ -643,21 +640,33 @@ pcmk__native_output_string(const pcmk_resource_t *rsc, const char *name, have_flags = add_output_flag(outstr, pending_task, have_flags); } } - if (target_role) { - enum rsc_role_e target_role_e = text2role(target_role); + if (target_role != NULL) { + switch (pcmk_parse_role(target_role)) { + case pcmk_role_unknown: + pcmk__config_err("Invalid " PCMK_META_TARGET_ROLE + " %s for resource %s", target_role, rsc->id); + break; - /* Only show target role if it limits our abilities (i.e. ignore - * Started, as it is the default anyways, and doesn't prevent the - * resource from becoming promoted). - */ - if (target_role_e == pcmk_role_stopped) { - have_flags = add_output_flag(outstr, "disabled", have_flags); - - } else if (pcmk_is_set(pe__const_top_resource(rsc, false)->flags, - pcmk_rsc_promotable) - && (target_role_e == pcmk_role_unpromoted)) { - have_flags = add_output_flag(outstr, "target-role:", have_flags); - g_string_append(outstr, target_role); + case pcmk_role_stopped: + have_flags = add_output_flag(outstr, "disabled", have_flags); + break; + + case pcmk_role_unpromoted: + if (pcmk_is_set(pe__const_top_resource(rsc, false)->flags, + pcmk_rsc_promotable)) { + have_flags = add_output_flag(outstr, + PCMK_META_TARGET_ROLE ":", + have_flags); + g_string_append(outstr, target_role); + } + break; + + default: + /* Only show target role if it limits our abilities (i.e. ignore + * Started, as it is the default anyways, and doesn't prevent + * the resource from becoming promoted). + */ + break; } } @@ -686,7 +695,7 @@ pcmk__native_output_string(const pcmk_resource_t *rsc, const char *name, // User-supplied description if (pcmk_any_flags_set(show_opts, pcmk_show_rsc_only|pcmk_show_description) || pcmk__list_of_multiple(rsc->running_on)) { - const char *desc = crm_element_value(rsc->xml, XML_ATTR_DESC); + const char *desc = crm_element_value(rsc->xml, PCMK_XA_DESCRIPTION); if (desc) { g_string_append(outstr, " ("); @@ -718,17 +727,18 @@ pe__common_output_html(pcmk__output_t *out, const pcmk_resource_t *rsc, const char *name, const pcmk_node_t *node, uint32_t show_opts) { - const char *kind = crm_element_value(rsc->xml, XML_ATTR_TYPE); + const char *kind = crm_element_value(rsc->xml, PCMK_XA_TYPE); const char *target_role = NULL; - - xmlNodePtr list_node = NULL; const char *cl = NULL; - CRM_ASSERT(rsc->variant == pcmk_rsc_variant_primitive); - CRM_ASSERT(kind != NULL); + xmlNode *child = NULL; + gchar *content = NULL; + + CRM_ASSERT((kind != NULL) && pcmk__is_primitive(rsc)); if (rsc->meta) { - const char *is_internal = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_INTERNAL_RSC); + const char *is_internal = g_hash_table_lookup(rsc->meta, + PCMK__META_INTERNAL_RSC); if (crm_is_true(is_internal) && !pcmk_is_set(show_opts, pcmk_show_implicit_rscs)) { @@ -736,37 +746,34 @@ pe__common_output_html(pcmk__output_t *out, const pcmk_resource_t *rsc, crm_trace("skipping print of internal resource %s", rsc->id); return pcmk_rc_no_output; } - target_role = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_TARGET_ROLE); + target_role = g_hash_table_lookup(rsc->meta, PCMK_META_TARGET_ROLE); } if (!pcmk_is_set(rsc->flags, pcmk_rsc_managed)) { - cl = "rsc-managed"; + cl = PCMK__VALUE_RSC_MANAGED; } else if (pcmk_is_set(rsc->flags, pcmk_rsc_failed)) { - cl = "rsc-failed"; + cl = PCMK__VALUE_RSC_FAILED; - } else if ((rsc->variant == pcmk_rsc_variant_primitive) - && (rsc->running_on == NULL)) { - cl = "rsc-failed"; + } else if (pcmk__is_primitive(rsc) && (rsc->running_on == NULL)) { + cl = PCMK__VALUE_RSC_FAILED; } else if (pcmk__list_of_multiple(rsc->running_on)) { - cl = "rsc-multiple"; + cl = PCMK__VALUE_RSC_MULTIPLE; } else if (pcmk_is_set(rsc->flags, pcmk_rsc_ignore_failure)) { - cl = "rsc-failure-ignored"; + cl = PCMK__VALUE_RSC_FAILURE_IGNORED; } else { - cl = "rsc-ok"; + cl = PCMK__VALUE_RSC_OK; } - { - gchar *s = pcmk__native_output_string(rsc, name, node, show_opts, - 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); - g_free(s); - } + child = pcmk__output_create_html_node(out, "li", NULL, NULL, NULL); + child = pcmk__html_create(child, PCMK__XE_SPAN, NULL, cl); + content = pcmk__native_output_string(rsc, name, node, show_opts, + target_role, true); + pcmk__xe_set_content(child, "%s", content); + g_free(content); return pcmk_rc_ok; } @@ -778,10 +785,11 @@ pe__common_output_text(pcmk__output_t *out, const pcmk_resource_t *rsc, { const char *target_role = NULL; - CRM_ASSERT(rsc->variant == pcmk_rsc_variant_primitive); + CRM_ASSERT(pcmk__is_primitive(rsc)); if (rsc->meta) { - const char *is_internal = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_INTERNAL_RSC); + const char *is_internal = g_hash_table_lookup(rsc->meta, + PCMK__META_INTERNAL_RSC); if (crm_is_true(is_internal) && !pcmk_is_set(show_opts, pcmk_show_implicit_rscs)) { @@ -789,7 +797,7 @@ pe__common_output_text(pcmk__output_t *out, const pcmk_resource_t *rsc, crm_trace("skipping print of internal resource %s", rsc->id); return pcmk_rc_no_output; } - target_role = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_TARGET_ROLE); + target_role = g_hash_table_lookup(rsc->meta, PCMK_META_TARGET_ROLE); } { @@ -813,11 +821,11 @@ common_print(pcmk_resource_t *rsc, const char *pre_text, const char *name, { const char *target_role = NULL; - CRM_ASSERT(rsc->variant == pcmk_rsc_variant_primitive); + CRM_ASSERT(pcmk__is_primitive(rsc)); if (rsc->meta) { const char *is_internal = g_hash_table_lookup(rsc->meta, - XML_RSC_ATTR_INTERNAL_RSC); + PCMK__META_INTERNAL_RSC); if (crm_is_true(is_internal) && !pcmk_is_set(options, pe_print_implicit)) { @@ -825,7 +833,7 @@ common_print(pcmk_resource_t *rsc, const char *pre_text, const char *name, crm_trace("skipping print of internal resource %s", rsc->id); return; } - target_role = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_TARGET_ROLE); + target_role = g_hash_table_lookup(rsc->meta, PCMK_META_TARGET_ROLE); } if (options & pe_print_xml) { @@ -888,17 +896,17 @@ common_print(pcmk_resource_t *rsc, const char *pre_text, const char *name, counter++; if (options & pe_print_html) { - status_print("<li>\n%s", pe__node_name(n)); + status_print("<li>\n%s", pcmk__node_name(n)); } else if ((options & pe_print_printf) || (options & pe_print_ncurses)) { - status_print(" %s", pe__node_name(n)); + status_print(" %s", pcmk__node_name(n)); } else if ((options & pe_print_log)) { - status_print("\t%d : %s", counter, pe__node_name(n)); + status_print("\t%d : %s", counter, pcmk__node_name(n)); } else { - status_print("%s", pe__node_name(n)); + status_print("%s", pcmk__node_name(n)); } if (options & pe_print_html) { status_print("</li>\n"); @@ -933,13 +941,14 @@ native_print(pcmk_resource_t *rsc, const char *pre_text, long options, { const pcmk_node_t *node = NULL; - CRM_ASSERT(rsc->variant == pcmk_rsc_variant_primitive); + CRM_ASSERT(pcmk__is_primitive(rsc)); + if (options & pe_print_xml) { native_print_xml(rsc, pre_text, options, print_data); return; } - node = pe__current_node(rsc); + node = pcmk__current_node(rsc); if (node == NULL) { // This is set only if a non-probe action is pending on this node @@ -959,57 +968,64 @@ pe__resource_xml(pcmk__output_t *out, va_list args) GList *only_node G_GNUC_UNUSED = va_arg(args, GList *); GList *only_rsc = va_arg(args, GList *); + int rc = pcmk_rc_no_output; bool print_pending = pcmk_is_set(show_opts, pcmk_show_pending); - const char *class = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS); - const char *prov = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER); - const char *rsc_state = native_displayable_state(rsc, print_pending); + const char *class = crm_element_value(rsc->xml, PCMK_XA_CLASS); + const char *prov = crm_element_value(rsc->xml, PCMK_XA_PROVIDER); - const char *desc = NULL; char ra_name[LINE_MAX]; - char *nodes_running_on = NULL; - const char *lock_node_name = NULL; - int rc = pcmk_rc_no_output; + const char *rsc_state = native_displayable_state(rsc, print_pending); const char *target_role = NULL; + const char *active = pcmk__btoa(rsc->fns->active(rsc, TRUE)); + const char *orphaned = pcmk__flag_text(rsc->flags, pcmk_rsc_removed); + const char *blocked = pcmk__flag_text(rsc->flags, pcmk_rsc_blocked); + const char *maintenance = pcmk__flag_text(rsc->flags, pcmk_rsc_maintenance); + const char *managed = pcmk__flag_text(rsc->flags, pcmk_rsc_managed); + const char *failed = pcmk__flag_text(rsc->flags, pcmk_rsc_failed); + const char *ignored = pcmk__flag_text(rsc->flags, pcmk_rsc_ignore_failure); + char *nodes_running_on = NULL; + const char *pending = print_pending? native_pending_task(rsc) : NULL; + const char *locked_to = NULL; + const char *desc = pe__resource_description(rsc, show_opts); - desc = pe__resource_description(rsc, show_opts); - - if (rsc->meta != NULL) { - target_role = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_TARGET_ROLE); - } - - CRM_ASSERT(rsc->variant == pcmk_rsc_variant_primitive); + CRM_ASSERT(pcmk__is_primitive(rsc)); if (rsc->fns->is_filtered(rsc, only_rsc, TRUE)) { return pcmk_rc_no_output; } - /* resource information. */ + // Resource information snprintf(ra_name, LINE_MAX, "%s%s%s:%s", class, ((prov == NULL)? "" : PROVIDER_SEP), ((prov == NULL)? "" : prov), - crm_element_value(rsc->xml, XML_ATTR_TYPE)); + crm_element_value(rsc->xml, PCMK_XA_TYPE)); + + if (rsc->meta != NULL) { + target_role = g_hash_table_lookup(rsc->meta, PCMK_META_TARGET_ROLE); + } nodes_running_on = pcmk__itoa(g_list_length(rsc->running_on)); if (rsc->lock_node != NULL) { - lock_node_name = rsc->lock_node->details->uname; - } - - rc = pe__name_and_nvpairs_xml(out, true, "resource", 15, - "id", rsc_printable_id(rsc), - "resource_agent", ra_name, - "role", rsc_state, - "target_role", target_role, - "active", pcmk__btoa(rsc->fns->active(rsc, TRUE)), - "orphaned", pe__rsc_bool_str(rsc, pcmk_rsc_removed), - "blocked", pe__rsc_bool_str(rsc, pcmk_rsc_blocked), - "maintenance", pe__rsc_bool_str(rsc, pcmk_rsc_maintenance), - "managed", pe__rsc_bool_str(rsc, pcmk_rsc_managed), - "failed", pe__rsc_bool_str(rsc, pcmk_rsc_failed), - "failure_ignored", pe__rsc_bool_str(rsc, pcmk_rsc_ignore_failure), - "nodes_running_on", nodes_running_on, - "pending", (print_pending? native_pending_task(rsc) : NULL), - "locked_to", lock_node_name, - "description", desc); + locked_to = rsc->lock_node->details->uname; + } + + rc = pe__name_and_nvpairs_xml(out, true, PCMK_XE_RESOURCE, + PCMK_XA_ID, rsc_printable_id(rsc), + PCMK_XA_RESOURCE_AGENT, ra_name, + PCMK_XA_ROLE, rsc_state, + PCMK_XA_TARGET_ROLE, target_role, + PCMK_XA_ACTIVE, active, + PCMK_XA_ORPHANED, orphaned, + PCMK_XA_BLOCKED, blocked, + PCMK_XA_MAINTENANCE, maintenance, + PCMK_XA_MANAGED, managed, + PCMK_XA_FAILED, failed, + PCMK_XA_FAILURE_IGNORED, ignored, + PCMK_XA_NODES_RUNNING_ON, nodes_running_on, + PCMK_XA_PENDING, pending, + PCMK_XA_LOCKED_TO, locked_to, + PCMK_XA_DESCRIPTION, desc, + NULL); free(nodes_running_on); CRM_ASSERT(rc == pcmk_rc_ok); @@ -1019,11 +1035,13 @@ pe__resource_xml(pcmk__output_t *out, va_list args) for (; gIter != NULL; gIter = gIter->next) { pcmk_node_t *node = (pcmk_node_t *) gIter->data; + const char *cached = pcmk__btoa(node->details->online); - rc = pe__name_and_nvpairs_xml(out, false, "node", 3, - "name", node->details->uname, - "id", node->details->id, - "cached", pcmk__btoa(node->details->online)); + rc = pe__name_and_nvpairs_xml(out, false, PCMK_XE_NODE, + PCMK_XA_NAME, node->details->uname, + PCMK_XA_ID, node->details->id, + PCMK_XA_CACHED, cached, + NULL); CRM_ASSERT(rc == pcmk_rc_ok); } } @@ -1042,13 +1060,13 @@ pe__resource_html(pcmk__output_t *out, va_list args) GList *only_node G_GNUC_UNUSED = va_arg(args, GList *); GList *only_rsc = va_arg(args, GList *); - const pcmk_node_t *node = pe__current_node(rsc); + const pcmk_node_t *node = pcmk__current_node(rsc); if (rsc->fns->is_filtered(rsc, only_rsc, TRUE)) { return pcmk_rc_no_output; } - CRM_ASSERT(rsc->variant == pcmk_rsc_variant_primitive); + CRM_ASSERT(pcmk__is_primitive(rsc)); if (node == NULL) { // This is set only if a non-probe action is pending on this node @@ -1067,9 +1085,9 @@ pe__resource_text(pcmk__output_t *out, va_list args) GList *only_node G_GNUC_UNUSED = va_arg(args, GList *); GList *only_rsc = va_arg(args, GList *); - const pcmk_node_t *node = pe__current_node(rsc); + const pcmk_node_t *node = pcmk__current_node(rsc); - CRM_ASSERT(rsc->variant == pcmk_rsc_variant_primitive); + CRM_ASSERT(pcmk__is_primitive(rsc)); if (rsc->fns->is_filtered(rsc, only_rsc, TRUE)) { return pcmk_rc_no_output; @@ -1085,7 +1103,7 @@ pe__resource_text(pcmk__output_t *out, va_list args) void native_free(pcmk_resource_t * rsc) { - pe_rsc_trace(rsc, "Freeing resource action list (not the data)"); + pcmk__rsc_trace(rsc, "Freeing resource action list (not the data)"); common_free(rsc); } @@ -1097,7 +1115,7 @@ native_resource_state(const pcmk_resource_t * rsc, gboolean current) if (current) { role = rsc->role; } - pe_rsc_trace(rsc, "%s state: %s", rsc->id, role2text(role)); + pcmk__rsc_trace(rsc, "%s state: %s", rsc->id, pcmk_role_text(role)); return role; } @@ -1170,8 +1188,8 @@ get_rscs_brief(GList *rsc_list, GHashTable * rsc_table, GHashTable * active_tabl for (; gIter != NULL; gIter = gIter->next) { pcmk_resource_t *rsc = (pcmk_resource_t *) gIter->data; - const char *class = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS); - const char *kind = crm_element_value(rsc->xml, XML_ATTR_TYPE); + const char *class = crm_element_value(rsc->xml, PCMK_XA_CLASS); + const char *kind = crm_element_value(rsc->xml, PCMK_XA_TYPE); int offset = 0; char buffer[LINE_MAX]; @@ -1179,13 +1197,13 @@ get_rscs_brief(GList *rsc_list, GHashTable * rsc_table, GHashTable * active_tabl int *rsc_counter = NULL; int *active_counter = NULL; - if (rsc->variant != pcmk_rsc_variant_primitive) { + if (!pcmk__is_primitive(rsc)) { continue; } offset += snprintf(buffer + offset, LINE_MAX - offset, "%s", class); if (pcmk_is_set(pcmk_get_ra_caps(class), pcmk_ra_cap_provider)) { - const char *prov = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER); + const char *prov = crm_element_value(rsc->xml, PCMK_XA_PROVIDER); if (prov != NULL) { offset += snprintf(buffer + offset, LINE_MAX - offset, @@ -1198,7 +1216,7 @@ get_rscs_brief(GList *rsc_list, GHashTable * rsc_table, GHashTable * active_tabl if (rsc_table) { rsc_counter = g_hash_table_lookup(rsc_table, buffer); if (rsc_counter == NULL) { - rsc_counter = calloc(1, sizeof(int)); + rsc_counter = pcmk__assert_alloc(1, sizeof(int)); *rsc_counter = 0; g_hash_table_insert(rsc_table, strdup(buffer), rsc_counter); } @@ -1225,7 +1243,7 @@ get_rscs_brief(GList *rsc_list, GHashTable * rsc_table, GHashTable * active_tabl active_counter = g_hash_table_lookup(node_table, buffer); if (active_counter == NULL) { - active_counter = calloc(1, sizeof(int)); + active_counter = pcmk__assert_alloc(1, sizeof(int)); *active_counter = 0; g_hash_table_insert(node_table, strdup(buffer), active_counter); } @@ -1448,6 +1466,6 @@ pe__native_is_filtered(const pcmk_resource_t *rsc, GList *only_rsc, unsigned int pe__primitive_max_per_node(const pcmk_resource_t *rsc) { - CRM_ASSERT((rsc != NULL) && (rsc->variant == pcmk_rsc_variant_primitive)); + CRM_ASSERT(pcmk__is_primitive(rsc)); return 1U; } diff --git a/lib/pengine/pe_actions.c b/lib/pengine/pe_actions.c index aaa6598..b866db6 100644 --- a/lib/pengine/pe_actions.c +++ b/lib/pengine/pe_actions.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2023 the Pacemaker project contributors + * Copyright 2004-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -13,7 +13,7 @@ #include <stdbool.h> #include <crm/crm.h> -#include <crm/msg_xml.h> +#include <crm/common/xml.h> #include <crm/common/scheduler_internal.h> #include <crm/pengine/internal.h> #include <crm/common/xml_internal.h> @@ -87,26 +87,29 @@ static xmlNode * find_exact_action_config(const pcmk_resource_t *rsc, const char *action_name, guint interval_ms, bool include_disabled) { - for (xmlNode *operation = first_named_child(rsc->ops_xml, XML_ATTR_OP); - operation != NULL; operation = crm_next_same_xml(operation)) { + for (xmlNode *operation = pcmk__xe_first_child(rsc->ops_xml, PCMK_XE_OP, + NULL, NULL); + operation != NULL; operation = pcmk__xe_next_same(operation)) { bool enabled = false; const char *config_name = NULL; const char *interval_spec = NULL; + guint tmp_ms = 0U; - // @TODO This does not consider rules, defaults, etc. + // @TODO This does not consider meta-attributes, rules, defaults, etc. if (!include_disabled - && (pcmk__xe_get_bool_attr(operation, "enabled", + && (pcmk__xe_get_bool_attr(operation, PCMK_META_ENABLED, &enabled) == pcmk_rc_ok) && !enabled) { continue; } - interval_spec = crm_element_value(operation, XML_LRM_ATTR_INTERVAL); - if (crm_parse_interval_spec(interval_spec) != interval_ms) { + interval_spec = crm_element_value(operation, PCMK_META_INTERVAL); + pcmk_parse_interval_spec(interval_spec, &tmp_ms); + if (tmp_ms != interval_ms) { continue; } - config_name = crm_element_value(operation, "name"); + config_name = crm_element_value(operation, PCMK_XA_NAME); if (pcmk__str_eq(action_name, config_name, pcmk__str_none)) { return operation; } @@ -166,12 +169,10 @@ static pcmk_action_t * new_action(char *key, const char *task, pcmk_resource_t *rsc, const pcmk_node_t *node, bool optional, pcmk_scheduler_t *scheduler) { - pcmk_action_t *action = calloc(1, sizeof(pcmk_action_t)); - - CRM_ASSERT(action != NULL); + pcmk_action_t *action = pcmk__assert_alloc(1, sizeof(pcmk_action_t)); action->rsc = rsc; - action->task = strdup(task); CRM_ASSERT(action->task != NULL); + action->task = pcmk__str_copy(task); action->uuid = key; if (node) { @@ -180,14 +181,14 @@ new_action(char *key, const char *task, pcmk_resource_t *rsc, if (pcmk__str_eq(task, PCMK_ACTION_LRM_DELETE, pcmk__str_casei)) { // Resource history deletion for a node can be done on the DC - pe__set_action_flags(action, pcmk_action_on_dc); + pcmk__set_action_flags(action, pcmk_action_on_dc); } - pe__set_action_flags(action, pcmk_action_runnable); + pcmk__set_action_flags(action, pcmk_action_runnable); if (optional) { - pe__set_action_flags(action, pcmk_action_optional); + pcmk__set_action_flags(action, pcmk_action_optional); } else { - pe__clear_action_flags(action, pcmk_action_optional); + pcmk__clear_action_flags(action, pcmk_action_optional); } if (rsc == NULL) { @@ -210,11 +211,11 @@ new_action(char *key, const char *task, pcmk_resource_t *rsc, unpack_operation(action, action->op_entry, interval_ms); } - pe_rsc_trace(rsc, "Created %s action %d (%s): %s for %s on %s", - (optional? "optional" : "required"), - scheduler->action_id, key, task, - ((rsc == NULL)? "no resource" : rsc->id), - pe__node_name(node)); + pcmk__rsc_trace(rsc, "Created %s action %d (%s): %s for %s on %s", + (optional? "optional" : "required"), + scheduler->action_id, key, task, + ((rsc == NULL)? "no resource" : rsc->id), + pcmk__node_name(node)); action->id = scheduler->action_id++; scheduler->actions = g_list_prepend(scheduler->actions, action); @@ -245,14 +246,13 @@ pcmk__unpack_action_rsc_params(const xmlNode *action_xml, pe_rule_eval_data_t rule_data = { .node_hash = node_attrs, - .role = pcmk_role_unknown, .now = scheduler->now, .match_data = NULL, .rsc_data = NULL, .op_data = NULL }; - pe__unpack_dataset_nvpairs(action_xml, XML_TAG_ATTR_SETS, + pe__unpack_dataset_nvpairs(action_xml, PCMK_XE_INSTANCE_ATTRIBUTES, &rule_data, params, NULL, FALSE, scheduler); return params; @@ -272,17 +272,17 @@ update_action_optional(pcmk_action_t *action, gboolean optional) if ((action->rsc != NULL) && (action->node != NULL) && !pcmk_is_set(action->flags, pcmk_action_pseudo) && !pcmk_is_set(action->rsc->flags, pcmk_rsc_managed) - && (g_hash_table_lookup(action->meta, - XML_LRM_ATTR_INTERVAL_MS) == NULL)) { - pe_rsc_debug(action->rsc, "%s on %s is optional (%s is unmanaged)", - action->uuid, pe__node_name(action->node), - action->rsc->id); - pe__set_action_flags(action, pcmk_action_optional); + && (g_hash_table_lookup(action->meta, PCMK_META_INTERVAL) == NULL)) { + pcmk__rsc_debug(action->rsc, + "%s on %s is optional (%s is unmanaged)", + action->uuid, pcmk__node_name(action->node), + action->rsc->id); + pcmk__set_action_flags(action, pcmk_action_optional); // We shouldn't clear runnable here because ... something // Otherwise require the action if requested } else if (!optional) { - pe__clear_action_flags(action, pcmk_action_optional); + pcmk__clear_action_flags(action, pcmk_action_optional); } } @@ -300,7 +300,7 @@ effective_quorum_policy(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) case pcmk_role_unpromoted: if (rsc->next_role > pcmk_role_unpromoted) { pe__set_next_role(rsc, pcmk_role_unpromoted, - "no-quorum-policy=demote"); + PCMK_OPT_NO_QUORUM_POLICY "=demote"); } policy = pcmk_no_quorum_ignore; break; @@ -330,17 +330,17 @@ update_resource_action_runnable(pcmk_action_t *action, } if (action->node == NULL) { - pe_rsc_trace(action->rsc, "%s is unrunnable (unallocated)", - action->uuid); - pe__clear_action_flags(action, pcmk_action_runnable); + pcmk__rsc_trace(action->rsc, "%s is unrunnable (unallocated)", + action->uuid); + pcmk__clear_action_flags(action, pcmk_action_runnable); } else if (!pcmk_is_set(action->flags, pcmk_action_on_dc) && !(action->node->details->online) - && (!pe__is_guest_node(action->node) + && (!pcmk__is_guest_or_bundle_node(action->node) || action->node->details->remote_requires_reset)) { - pe__clear_action_flags(action, pcmk_action_runnable); + pcmk__clear_action_flags(action, pcmk_action_runnable); do_crm_log(LOG_WARNING, "%s on %s is unrunnable (node is offline)", - action->uuid, pe__node_name(action->node)); + action->uuid, pcmk__node_name(action->node)); if (pcmk_is_set(action->rsc->flags, pcmk_rsc_managed) && pcmk__str_eq(action->task, PCMK_ACTION_STOP, pcmk__str_casei) && !(action->node->details->unclean)) { @@ -349,54 +349,57 @@ update_resource_action_runnable(pcmk_action_t *action, } else if (!pcmk_is_set(action->flags, pcmk_action_on_dc) && action->node->details->pending) { - pe__clear_action_flags(action, pcmk_action_runnable); + pcmk__clear_action_flags(action, pcmk_action_runnable); do_crm_log(LOG_WARNING, "Action %s on %s is unrunnable (node is pending)", - action->uuid, pe__node_name(action->node)); + action->uuid, pcmk__node_name(action->node)); } else if (action->needs == pcmk_requires_nothing) { pe_action_set_reason(action, NULL, TRUE); - if (pe__is_guest_node(action->node) + if (pcmk__is_guest_or_bundle_node(action->node) && !pe_can_fence(scheduler, action->node)) { /* An action that requires nothing usually does not require any * fencing in order to be runnable. However, there is an exception: * such an action cannot be completed if it is on a guest node whose * host is unclean and cannot be fenced. */ - pe_rsc_debug(action->rsc, "%s on %s is unrunnable " - "(node's host cannot be fenced)", - action->uuid, pe__node_name(action->node)); - pe__clear_action_flags(action, pcmk_action_runnable); + pcmk__rsc_debug(action->rsc, + "%s on %s is unrunnable " + "(node's host cannot be fenced)", + action->uuid, pcmk__node_name(action->node)); + pcmk__clear_action_flags(action, pcmk_action_runnable); } else { - pe_rsc_trace(action->rsc, - "%s on %s does not require fencing or quorum", - action->uuid, pe__node_name(action->node)); - pe__set_action_flags(action, pcmk_action_runnable); + pcmk__rsc_trace(action->rsc, + "%s on %s does not require fencing or quorum", + action->uuid, pcmk__node_name(action->node)); + pcmk__set_action_flags(action, pcmk_action_runnable); } } else { switch (effective_quorum_policy(action->rsc, scheduler)) { case pcmk_no_quorum_stop: - pe_rsc_debug(action->rsc, "%s on %s is unrunnable (no quorum)", - action->uuid, pe__node_name(action->node)); - pe__clear_action_flags(action, pcmk_action_runnable); + pcmk__rsc_debug(action->rsc, + "%s on %s is unrunnable (no quorum)", + action->uuid, pcmk__node_name(action->node)); + pcmk__clear_action_flags(action, pcmk_action_runnable); pe_action_set_reason(action, "no quorum", true); break; case pcmk_no_quorum_freeze: if (!action->rsc->fns->active(action->rsc, TRUE) || (action->rsc->next_role > action->rsc->role)) { - pe_rsc_debug(action->rsc, - "%s on %s is unrunnable (no quorum)", - action->uuid, pe__node_name(action->node)); - pe__clear_action_flags(action, pcmk_action_runnable); + pcmk__rsc_debug(action->rsc, + "%s on %s is unrunnable (no quorum)", + action->uuid, + pcmk__node_name(action->node)); + pcmk__clear_action_flags(action, pcmk_action_runnable); pe_action_set_reason(action, "quorum freeze", true); } break; default: //pe_action_set_reason(action, NULL, TRUE); - pe__set_action_flags(action, pcmk_action_runnable); + pcmk__set_action_flags(action, pcmk_action_runnable); break; } } @@ -417,13 +420,13 @@ update_resource_flags_for_action(pcmk_resource_t *rsc, * within Pacemaker, and will eventually be removed */ if (pcmk__str_eq(action->task, PCMK_ACTION_STOP, pcmk__str_casei)) { - pe__set_resource_flags(rsc, pcmk_rsc_stopping); + pcmk__set_rsc_flags(rsc, pcmk_rsc_stopping); } else if (pcmk__str_eq(action->task, PCMK_ACTION_START, pcmk__str_casei)) { if (pcmk_is_set(action->flags, pcmk_action_runnable)) { - pe__set_resource_flags(rsc, pcmk_rsc_starting); + pcmk__set_rsc_flags(rsc, pcmk_rsc_starting); } else { - pe__clear_resource_flags(rsc, pcmk_rsc_starting); + pcmk__clear_rsc_flags(rsc, pcmk_rsc_starting); } } } @@ -431,7 +434,9 @@ update_resource_flags_for_action(pcmk_resource_t *rsc, static bool valid_stop_on_fail(const char *value) { - return !pcmk__strcase_any_of(value, "standby", "demote", "stop", NULL); + return !pcmk__strcase_any_of(value, + PCMK_VALUE_STANDBY, PCMK_VALUE_DEMOTE, + PCMK_VALUE_STOP, NULL); } /*! @@ -450,18 +455,17 @@ validate_on_fail(const pcmk_resource_t *rsc, const char *action_name, const char *name = NULL; const char *role = NULL; const char *interval_spec = NULL; - const char *value = g_hash_table_lookup(meta, XML_OP_ATTR_ON_FAIL); - char *key = NULL; - char *new_value = NULL; + const char *value = g_hash_table_lookup(meta, PCMK_META_ON_FAIL); + guint interval_ms = 0U; // Stop actions can only use certain on-fail values if (pcmk__str_eq(action_name, PCMK_ACTION_STOP, pcmk__str_none) && !valid_stop_on_fail(value)) { - pcmk__config_err("Resetting '" XML_OP_ATTR_ON_FAIL "' for %s stop " + pcmk__config_err("Resetting '" PCMK_META_ON_FAIL "' for %s stop " "action to default value because '%s' is not " "allowed for stop", rsc->id, value); - g_hash_table_remove(meta, XML_OP_ATTR_ON_FAIL); + g_hash_table_remove(meta, PCMK_META_ON_FAIL); return; } @@ -475,77 +479,79 @@ validate_on_fail(const pcmk_resource_t *rsc, const char *action_name, * block (which may have rules that need to be evaluated) rather than * XML properties. */ - for (xmlNode *operation = first_named_child(rsc->ops_xml, XML_ATTR_OP); - operation != NULL; operation = crm_next_same_xml(operation)) { + for (xmlNode *operation = pcmk__xe_first_child(rsc->ops_xml, PCMK_XE_OP, + NULL, NULL); + operation != NULL; operation = pcmk__xe_next_same(operation)) { + bool enabled = false; const char *promote_on_fail = NULL; /* We only care about explicit on-fail (if promote uses default, so * can demote) */ - promote_on_fail = crm_element_value(operation, XML_OP_ATTR_ON_FAIL); + promote_on_fail = crm_element_value(operation, PCMK_META_ON_FAIL); if (promote_on_fail == NULL) { continue; } // We only care about recurring monitors for the promoted role - name = crm_element_value(operation, "name"); - role = crm_element_value(operation, "role"); + name = crm_element_value(operation, PCMK_XA_NAME); + role = crm_element_value(operation, PCMK_XA_ROLE); if (!pcmk__str_eq(name, PCMK_ACTION_MONITOR, pcmk__str_none) - || !pcmk__strcase_any_of(role, PCMK__ROLE_PROMOTED, + || !pcmk__strcase_any_of(role, PCMK_ROLE_PROMOTED, PCMK__ROLE_PROMOTED_LEGACY, NULL)) { continue; } - interval_spec = crm_element_value(operation, XML_LRM_ATTR_INTERVAL); - if (crm_parse_interval_spec(interval_spec) == 0) { + interval_spec = crm_element_value(operation, PCMK_META_INTERVAL); + pcmk_parse_interval_spec(interval_spec, &interval_ms); + if (interval_ms == 0U) { continue; } // We only care about enabled monitors - if ((pcmk__xe_get_bool_attr(operation, "enabled", + if ((pcmk__xe_get_bool_attr(operation, PCMK_META_ENABLED, &enabled) == pcmk_rc_ok) && !enabled) { continue; } - // Demote actions can't default to on-fail="demote" - if (pcmk__str_eq(promote_on_fail, "demote", pcmk__str_casei)) { + /* Demote actions can't default to + * PCMK_META_ON_FAIL=PCMK_VALUE_DEMOTE + */ + if (pcmk__str_eq(promote_on_fail, PCMK_VALUE_DEMOTE, + pcmk__str_casei)) { continue; } // Use value from first applicable promote action found - key = strdup(XML_OP_ATTR_ON_FAIL); - new_value = strdup(promote_on_fail); - CRM_ASSERT((key != NULL) && (new_value != NULL)); - g_hash_table_insert(meta, key, new_value); + pcmk__insert_dup(meta, PCMK_META_ON_FAIL, promote_on_fail); } return; } if (pcmk__str_eq(action_name, PCMK_ACTION_LRM_DELETE, pcmk__str_none) - && !pcmk__str_eq(value, "ignore", pcmk__str_casei)) { - key = strdup(XML_OP_ATTR_ON_FAIL); - new_value = strdup("ignore"); - CRM_ASSERT((key != NULL) && (new_value != NULL)); - g_hash_table_insert(meta, key, new_value); + && !pcmk__str_eq(value, PCMK_VALUE_IGNORE, pcmk__str_casei)) { + + pcmk__insert_dup(meta, PCMK_META_ON_FAIL, PCMK_VALUE_IGNORE); return; } - // on-fail="demote" is allowed only for certain actions - if (pcmk__str_eq(value, "demote", pcmk__str_casei)) { - name = crm_element_value(action_config, "name"); - role = crm_element_value(action_config, "role"); - interval_spec = crm_element_value(action_config, - XML_LRM_ATTR_INTERVAL); + // PCMK_META_ON_FAIL=PCMK_VALUE_DEMOTE is allowed only for certain actions + if (pcmk__str_eq(value, PCMK_VALUE_DEMOTE, pcmk__str_casei)) { + name = crm_element_value(action_config, PCMK_XA_NAME); + role = crm_element_value(action_config, PCMK_XA_ROLE); + interval_spec = crm_element_value(action_config, PCMK_META_INTERVAL); + pcmk_parse_interval_spec(interval_spec, &interval_ms); if (!pcmk__str_eq(name, PCMK_ACTION_PROMOTE, pcmk__str_none) - && (!pcmk__str_eq(name, PCMK_ACTION_MONITOR, pcmk__str_none) - || !pcmk__strcase_any_of(role, PCMK__ROLE_PROMOTED, - PCMK__ROLE_PROMOTED_LEGACY, NULL) - || (crm_parse_interval_spec(interval_spec) == 0))) { - pcmk__config_err("Resetting '" XML_OP_ATTR_ON_FAIL "' for %s %s " + && ((interval_ms == 0U) + || !pcmk__str_eq(name, PCMK_ACTION_MONITOR, pcmk__str_none) + || !pcmk__strcase_any_of(role, PCMK_ROLE_PROMOTED, + PCMK__ROLE_PROMOTED_LEGACY, NULL))) { + + pcmk__config_err("Resetting '" PCMK_META_ON_FAIL "' for %s %s " "action to default value because 'demote' is not " "allowed for it", rsc->id, name); - g_hash_table_remove(meta, XML_OP_ATTR_ON_FAIL); + g_hash_table_remove(meta, PCMK_META_ON_FAIL); return; } } @@ -554,12 +560,12 @@ validate_on_fail(const pcmk_resource_t *rsc, const char *action_name, static int unpack_timeout(const char *value) { - int timeout_ms = crm_get_msec(value); + long long timeout_ms = crm_get_msec(value); - if (timeout_ms < 0) { + if (timeout_ms <= 0) { timeout_ms = PCMK_DEFAULT_ACTION_TIMEOUT_MS; } - return timeout_ms; + return (int) QB_MIN(timeout_ms, INT_MAX); } // true if value contains valid, non-NULL interval origin for recurring op @@ -580,9 +586,9 @@ unpack_interval_origin(const char *value, const xmlNode *xml_obj, // Parse interval origin from text origin = crm_time_new(value); if (origin == NULL) { - pcmk__config_err("Ignoring '" XML_OP_ATTR_ORIGIN "' for operation " - "'%s' because '%s' is not valid", - (ID(xml_obj)? ID(xml_obj) : "(missing ID)"), value); + pcmk__config_err("Ignoring '" PCMK_META_INTERVAL_ORIGIN "' for " + "operation '%s' because '%s' is not valid", + pcmk__s(pcmk__xe_id(xml_obj), "(missing ID)"), value); return false; } @@ -596,8 +602,7 @@ unpack_interval_origin(const char *value, const xmlNode *xml_obj, // Calculate seconds remaining until next interval result = ((result <= 0)? 0 : interval_sec) - result; crm_info("Calculated a start delay of %llds for operation '%s'", - result, - (ID(xml_obj)? ID(xml_obj) : "(unspecified)")); + result, pcmk__s(pcmk__xe_id(xml_obj), "(unspecified)")); if (start_delay != NULL) { *start_delay = result * 1000; // milliseconds @@ -608,22 +613,24 @@ unpack_interval_origin(const char *value, const xmlNode *xml_obj, static int unpack_start_delay(const char *value, GHashTable *meta) { - int start_delay = 0; + long long start_delay_ms = 0; - if (value != NULL) { - start_delay = crm_get_msec(value); + if (value == NULL) { + return 0; + } - if (start_delay < 0) { - start_delay = 0; - } + start_delay_ms = crm_get_msec(value); + start_delay_ms = QB_MIN(start_delay_ms, INT_MAX); + if (start_delay_ms < 0) { + start_delay_ms = 0; + } - if (meta) { - g_hash_table_replace(meta, strdup(XML_OP_ATTR_START_DELAY), - pcmk__itoa(start_delay)); - } + if (meta != NULL) { + g_hash_table_replace(meta, strdup(PCMK_META_START_DELAY), + pcmk__itoa(start_delay_ms)); } - return start_delay; + return (int) start_delay_ms; } /*! @@ -641,25 +648,28 @@ most_frequent_monitor(const pcmk_resource_t *rsc) guint min_interval_ms = G_MAXUINT; xmlNode *op = NULL; - for (xmlNode *operation = first_named_child(rsc->ops_xml, XML_ATTR_OP); - operation != NULL; operation = crm_next_same_xml(operation)) { + for (xmlNode *operation = pcmk__xe_first_child(rsc->ops_xml, PCMK_XE_OP, + NULL, NULL); + operation != NULL; operation = pcmk__xe_next_same(operation)) { + bool enabled = false; - guint interval_ms = 0; + guint interval_ms = 0U; const char *interval_spec = crm_element_value(operation, - XML_LRM_ATTR_INTERVAL); + PCMK_META_INTERVAL); // We only care about enabled recurring monitors - if (!pcmk__str_eq(crm_element_value(operation, "name"), + if (!pcmk__str_eq(crm_element_value(operation, PCMK_XA_NAME), PCMK_ACTION_MONITOR, pcmk__str_none)) { continue; } - interval_ms = crm_parse_interval_spec(interval_spec); - if (interval_ms == 0) { + + pcmk_parse_interval_spec(interval_spec, &interval_ms); + if (interval_ms == 0U) { continue; } - // @TODO This does not account for rules, defaults, etc. - if ((pcmk__xe_get_bool_attr(operation, "enabled", + // @TODO This does not consider meta-attributes, rules, defaults, etc. + if ((pcmk__xe_get_bool_attr(operation, PCMK_META_ENABLED, &enabled) == pcmk_rc_ok) && !enabled) { continue; } @@ -694,15 +704,13 @@ pcmk__unpack_action_meta(pcmk_resource_t *rsc, const pcmk_node_t *node, const xmlNode *action_config) { GHashTable *meta = NULL; - char *name = NULL; - char *value = NULL; const char *timeout_spec = NULL; const char *str = NULL; pe_rsc_eval_data_t rsc_rule_data = { - .standard = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS), - .provider = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER), - .agent = crm_element_value(rsc->xml, XML_EXPR_ATTR_TYPE), + .standard = crm_element_value(rsc->xml, PCMK_XA_CLASS), + .provider = crm_element_value(rsc->xml, PCMK_XA_PROVIDER), + .agent = crm_element_value(rsc->xml, PCMK_XA_TYPE), }; pe_op_eval_data_t op_rule_data = { @@ -711,8 +719,13 @@ pcmk__unpack_action_meta(pcmk_resource_t *rsc, const pcmk_node_t *node, }; pe_rule_eval_data_t rule_data = { + /* @COMPAT Support for node attribute expressions in operation + * meta-attributes (whether in the operation configuration or operation + * defaults) is deprecated. When we can break behavioral backward + * compatibility, drop this line. + */ .node_hash = (node == NULL)? NULL : node->details->attrs, - .role = pcmk_role_unknown, + .now = rsc->cluster->now, .match_data = NULL, .rsc_data = &rsc_rule_data, @@ -722,36 +735,35 @@ pcmk__unpack_action_meta(pcmk_resource_t *rsc, const pcmk_node_t *node, meta = pcmk__strkey_table(free, free); // Cluster-wide <op_defaults> <meta_attributes> - pe__unpack_dataset_nvpairs(rsc->cluster->op_defaults, XML_TAG_META_SETS, - &rule_data, meta, NULL, FALSE, rsc->cluster); + pe__unpack_dataset_nvpairs(rsc->cluster->op_defaults, + PCMK_XE_META_ATTRIBUTES, &rule_data, meta, NULL, + FALSE, rsc->cluster); // Derive default timeout for probes from recurring monitor timeouts if (pcmk_is_probe(action_name, interval_ms)) { xmlNode *min_interval_mon = most_frequent_monitor(rsc); if (min_interval_mon != NULL) { - /* @TODO This does not consider timeouts set in meta_attributes - * blocks (which may also have rules that need to be evaluated). + /* @TODO This does not consider timeouts set in + * PCMK_XE_META_ATTRIBUTES blocks (which may also have rules that + * need to be evaluated). */ timeout_spec = crm_element_value(min_interval_mon, - XML_ATTR_TIMEOUT); + PCMK_META_TIMEOUT); if (timeout_spec != NULL) { - pe_rsc_trace(rsc, - "Setting default timeout for %s probe to " - "most frequent monitor's timeout '%s'", - rsc->id, timeout_spec); - name = strdup(XML_ATTR_TIMEOUT); - value = strdup(timeout_spec); - CRM_ASSERT((name != NULL) && (value != NULL)); - g_hash_table_insert(meta, name, value); + pcmk__rsc_trace(rsc, + "Setting default timeout for %s probe to " + "most frequent monitor's timeout '%s'", + rsc->id, timeout_spec); + pcmk__insert_dup(meta, PCMK_META_TIMEOUT, timeout_spec); } } } if (action_config != NULL) { // <op> <meta_attributes> take precedence over defaults - pe__unpack_dataset_nvpairs(action_config, XML_TAG_META_SETS, &rule_data, - meta, NULL, TRUE, rsc->cluster); + pe__unpack_dataset_nvpairs(action_config, PCMK_XE_META_ATTRIBUTES, + &rule_data, meta, NULL, TRUE, rsc->cluster); /* Anything set as an <op> XML property has highest precedence. * This ensures we use the name and interval from the <op> tag. @@ -759,24 +771,19 @@ pcmk__unpack_action_meta(pcmk_resource_t *rsc, const pcmk_node_t *node, */ for (xmlAttrPtr attr = action_config->properties; attr != NULL; attr = attr->next) { - name = strdup((const char *) attr->name); - value = strdup(pcmk__xml_attr_value(attr)); - - CRM_ASSERT((name != NULL) && (value != NULL)); - g_hash_table_insert(meta, name, value); + pcmk__insert_dup(meta, (const char *) attr->name, + pcmk__xml_attr_value(attr)); } } - g_hash_table_remove(meta, XML_ATTR_ID); + g_hash_table_remove(meta, PCMK_XA_ID); // Normalize interval to milliseconds if (interval_ms > 0) { - name = strdup(XML_LRM_ATTR_INTERVAL); - CRM_ASSERT(name != NULL); - value = crm_strdup_printf("%u", interval_ms); - g_hash_table_insert(meta, name, value); + g_hash_table_insert(meta, pcmk__str_copy(PCMK_META_INTERVAL), + crm_strdup_printf("%u", interval_ms)); } else { - g_hash_table_remove(meta, XML_LRM_ATTR_INTERVAL); + g_hash_table_remove(meta, PCMK_META_INTERVAL); } /* Timeout order of precedence (highest to lowest): @@ -799,39 +806,33 @@ pcmk__unpack_action_meta(pcmk_resource_t *rsc, const pcmk_node_t *node, timeout_spec = g_hash_table_lookup(params, "pcmk_monitor_timeout"); if (timeout_spec != NULL) { - pe_rsc_trace(rsc, - "Setting timeout for %s %s to " - "pcmk_monitor_timeout (%s)", - rsc->id, action_name, timeout_spec); - name = strdup(XML_ATTR_TIMEOUT); - value = strdup(timeout_spec); - CRM_ASSERT((name != NULL) && (value != NULL)); - g_hash_table_insert(meta, name, value); + pcmk__rsc_trace(rsc, + "Setting timeout for %s %s to " + "pcmk_monitor_timeout (%s)", + rsc->id, action_name, timeout_spec); + pcmk__insert_dup(meta, PCMK_META_TIMEOUT, timeout_spec); } } // Normalize timeout to positive milliseconds - name = strdup(XML_ATTR_TIMEOUT); - CRM_ASSERT(name != NULL); - timeout_spec = g_hash_table_lookup(meta, XML_ATTR_TIMEOUT); - g_hash_table_insert(meta, name, pcmk__itoa(unpack_timeout(timeout_spec))); + timeout_spec = g_hash_table_lookup(meta, PCMK_META_TIMEOUT); + g_hash_table_insert(meta, pcmk__str_copy(PCMK_META_TIMEOUT), + pcmk__itoa(unpack_timeout(timeout_spec))); // Ensure on-fail has a valid value validate_on_fail(rsc, action_name, action_config, meta); - // Normalize start-delay - str = g_hash_table_lookup(meta, XML_OP_ATTR_START_DELAY); + // Normalize PCMK_META_START_DELAY + str = g_hash_table_lookup(meta, PCMK_META_START_DELAY); if (str != NULL) { unpack_start_delay(str, meta); } else { long long start_delay = 0; - str = g_hash_table_lookup(meta, XML_OP_ATTR_ORIGIN); + str = g_hash_table_lookup(meta, PCMK_META_INTERVAL_ORIGIN); if (unpack_interval_origin(str, action_config, interval_ms, rsc->cluster->now, &start_delay)) { - name = strdup(XML_OP_ATTR_START_DELAY); - CRM_ASSERT(name != NULL); - g_hash_table_insert(meta, name, + g_hash_table_insert(meta, pcmk__str_copy(PCMK_META_START_DELAY), crm_strdup_printf("%lld", start_delay)); } } @@ -870,7 +871,7 @@ pcmk__action_requires(const pcmk_resource_t *rsc, const char *action_name) } else { value = "nothing"; } - pe_rsc_trace(rsc, "%s of %s requires %s", action_name, rsc->id, value); + pcmk__rsc_trace(rsc, "%s of %s requires %s", action_name, rsc->id, value); return requires; } @@ -893,19 +894,22 @@ pcmk__parse_on_fail(const pcmk_resource_t *rsc, const char *action_name, bool needs_remote_reset = false; enum action_fail_response on_fail = pcmk_on_fail_ignore; + // There's no enum value for unknown or invalid, so assert + CRM_ASSERT((rsc != NULL) && (action_name != NULL)); + if (value == NULL) { // Use default - } else if (pcmk__str_eq(value, "block", pcmk__str_casei)) { + } else if (pcmk__str_eq(value, PCMK_VALUE_BLOCK, pcmk__str_casei)) { on_fail = pcmk_on_fail_block; desc = "block"; - } else if (pcmk__str_eq(value, "fence", pcmk__str_casei)) { + } else if (pcmk__str_eq(value, PCMK_VALUE_FENCE, pcmk__str_casei)) { if (pcmk_is_set(rsc->cluster->flags, pcmk_sched_fencing_enabled)) { on_fail = pcmk_on_fail_fence_node; desc = "node fencing"; } else { - pcmk__config_err("Resetting '" XML_OP_ATTR_ON_FAIL "' for " + pcmk__config_err("Resetting '" PCMK_META_ON_FAIL "' for " "%s of %s to 'stop' because 'fence' is not " "valid when fencing is disabled", action_name, rsc->id); @@ -913,11 +917,12 @@ pcmk__parse_on_fail(const pcmk_resource_t *rsc, const char *action_name, desc = "stop resource"; } - } else if (pcmk__str_eq(value, "standby", pcmk__str_casei)) { + } else if (pcmk__str_eq(value, PCMK_VALUE_STANDBY, pcmk__str_casei)) { on_fail = pcmk_on_fail_standby_node; desc = "node standby"; - } else if (pcmk__strcase_any_of(value, "ignore", PCMK__VALUE_NOTHING, + } else if (pcmk__strcase_any_of(value, + PCMK_VALUE_IGNORE, PCMK_VALUE_NOTHING, NULL)) { desc = "ignore"; @@ -925,31 +930,32 @@ pcmk__parse_on_fail(const pcmk_resource_t *rsc, const char *action_name, on_fail = pcmk_on_fail_ban; desc = "force migration"; - } else if (pcmk__str_eq(value, "stop", pcmk__str_casei)) { + } else if (pcmk__str_eq(value, PCMK_VALUE_STOP, pcmk__str_casei)) { on_fail = pcmk_on_fail_stop; desc = "stop resource"; - } else if (pcmk__str_eq(value, "restart", pcmk__str_casei)) { + } else if (pcmk__str_eq(value, PCMK_VALUE_RESTART, pcmk__str_casei)) { on_fail = pcmk_on_fail_restart; desc = "restart (and possibly migrate)"; - } else if (pcmk__str_eq(value, "restart-container", pcmk__str_casei)) { + } else if (pcmk__str_eq(value, PCMK_VALUE_RESTART_CONTAINER, + pcmk__str_casei)) { if (rsc->container == NULL) { - pe_rsc_debug(rsc, - "Using default " XML_OP_ATTR_ON_FAIL - " for %s of %s because it does not have a container", - action_name, rsc->id); + pcmk__rsc_debug(rsc, + "Using default " PCMK_META_ON_FAIL " for %s " + "of %s because it does not have a container", + action_name, rsc->id); } else { on_fail = pcmk_on_fail_restart_container; desc = "restart container (and possibly migrate)"; } - } else if (pcmk__str_eq(value, "demote", pcmk__str_casei)) { + } else if (pcmk__str_eq(value, PCMK_VALUE_DEMOTE, pcmk__str_casei)) { on_fail = pcmk_on_fail_demote; desc = "demote instance"; } else { - pcmk__config_err("Using default '" XML_OP_ATTR_ON_FAIL "' for " + pcmk__config_err("Using default '" PCMK_META_ON_FAIL "' for " "%s of %s because '%s' is not valid", action_name, rsc->id, value); } @@ -957,9 +963,10 @@ pcmk__parse_on_fail(const pcmk_resource_t *rsc, const char *action_name, /* Remote node connections are handled specially. Failures that result * in dropping an active connection must result in fencing. The only * failures that don't are probes and starts. The user can explicitly set - * on-fail="fence" to fence after start failures. + * PCMK_META_ON_FAIL=PCMK_VALUE_FENCE to fence after start failures. */ - if (pe__resource_is_remote_conn(rsc) + if (rsc->is_remote_node + && pcmk__is_remote_node(pcmk_find_node(rsc->cluster, rsc->id)) && !pcmk_is_probe(action_name, interval_ms) && !pcmk__str_eq(action_name, PCMK_ACTION_START, pcmk__str_none)) { needs_remote_reset = true; @@ -1003,9 +1010,9 @@ pcmk__parse_on_fail(const pcmk_resource_t *rsc, const char *action_name, desc = "restart (and possibly migrate) (default)"; } - pe_rsc_trace(rsc, "Failure handling for %s-interval %s of %s: %s", - pcmk__readable_interval(interval_ms), action_name, - rsc->id, desc); + pcmk__rsc_trace(rsc, "Failure handling for %s-interval %s of %s: %s", + pcmk__readable_interval(interval_ms), action_name, + rsc->id, desc); return on_fail; } @@ -1044,13 +1051,18 @@ pcmk__role_after_failure(const pcmk_resource_t *rsc, const char *action_name, } // @COMPAT Check for explicitly configured role (deprecated) - value = g_hash_table_lookup(meta, "role_after_failure"); + value = g_hash_table_lookup(meta, PCMK__META_ROLE_AFTER_FAILURE); if (value != NULL) { - pe_warn_once(pcmk__wo_role_after, - "Support for role_after_failure is deprecated " - "and will be removed in a future release"); + pcmk__warn_once(pcmk__wo_role_after, + "Support for " PCMK__META_ROLE_AFTER_FAILURE " is " + "deprecated and will be removed in a future release"); if (role == pcmk_role_unknown) { - role = text2role(value); + role = pcmk_parse_role(value); + if (role == pcmk_role_unknown) { + pcmk__config_err("Ignoring invalid value %s for " + PCMK__META_ROLE_AFTER_FAILURE, + value); + } } } @@ -1062,8 +1074,8 @@ pcmk__role_after_failure(const pcmk_resource_t *rsc, const char *action_name, role = pcmk_role_started; } } - pe_rsc_trace(rsc, "Role after %s %s failure is: %s", - rsc->id, action_name, role2text(role)); + pcmk__rsc_trace(rsc, "Role after %s %s failure is: %s", + rsc->id, action_name, pcmk_role_text(role)); return role; } @@ -1089,7 +1101,7 @@ unpack_operation(pcmk_action_t *action, const xmlNode *xml_obj, action->task, interval_ms, xml_obj); action->needs = pcmk__action_requires(action->rsc, action->task); - value = g_hash_table_lookup(action->meta, XML_OP_ATTR_ON_FAIL); + value = g_hash_table_lookup(action->meta, PCMK_META_ON_FAIL); action->on_fail = pcmk__parse_on_fail(action->rsc, action->task, interval_ms, value); @@ -1132,6 +1144,11 @@ custom_action(pcmk_resource_t *rsc, char *key, const char *task, update_action_optional(action, optional); if (rsc != NULL) { + /* An action can be initially created with a NULL node, and later have + * the node added via find_existing_action() (above) -> find_actions(). + * That is why the extra parameters are unpacked here rather than in + * new_action(). + */ if ((action->node != NULL) && (action->op_entry != NULL) && !pcmk_is_set(action->flags, pcmk_action_attrs_evaluated)) { @@ -1142,7 +1159,7 @@ custom_action(pcmk_resource_t *rsc, char *key, const char *task, } action->extra = pcmk__unpack_action_rsc_params(action->op_entry, attrs, scheduler); - pe__set_action_flags(action, pcmk_action_attrs_evaluated); + pcmk__set_action_flags(action, pcmk_action_attrs_evaluated); } update_resource_action_runnable(action, scheduler); @@ -1163,7 +1180,7 @@ get_pseudo_op(const char *name, pcmk_scheduler_t *scheduler) if (op == NULL) { op = custom_action(NULL, strdup(name), name, NULL, TRUE, scheduler); - pe__set_action_flags(op, pcmk_action_pseudo|pcmk_action_runnable); + pcmk__set_action_flags(op, pcmk_action_pseudo|pcmk_action_runnable); } return op; } @@ -1185,8 +1202,7 @@ find_unfencing_devices(GList *candidates, GList *matches) } else if (pcmk__str_eq(g_hash_table_lookup(candidate->meta, PCMK_STONITH_PROVIDES), - PCMK__VALUE_UNFENCING, - pcmk__str_casei)) { + PCMK_VALUE_UNFENCING, pcmk__str_casei)) { matches = g_list_prepend(matches, candidate); } } @@ -1203,7 +1219,7 @@ node_priority_fencing_delay(const pcmk_node_t *node, int lowest_priority = 0; GList *gIter = NULL; - // `priority-fencing-delay` is disabled + // PCMK_OPT_PRIORITY_FENCING_DELAY is disabled if (scheduler->priority_fencing_delay <= 0) { return 0; } @@ -1281,9 +1297,10 @@ pe_fence_op(pcmk_node_t *node, const char *op, bool optional, stonith_op = custom_action(NULL, op_key, PCMK_ACTION_STONITH, node, TRUE, scheduler); - add_hash_param(stonith_op->meta, XML_LRM_ATTR_TARGET, node->details->uname); - add_hash_param(stonith_op->meta, XML_LRM_ATTR_TARGET_UUID, node->details->id); - add_hash_param(stonith_op->meta, "stonith_action", op); + pcmk__insert_meta(stonith_op, PCMK__META_ON_NODE, node->details->uname); + pcmk__insert_meta(stonith_op, PCMK__META_ON_NODE_UUID, + node->details->id); + pcmk__insert_meta(stonith_op, PCMK__META_STONITH_ACTION, op); if (pcmk_is_set(scheduler->flags, pcmk_sched_enable_unfencing)) { /* Extra work to detect device changes @@ -1293,28 +1310,25 @@ pe_fence_op(pcmk_node_t *node, const char *op, bool optional, GList *matches = find_unfencing_devices(scheduler->resources, NULL); - char *key = NULL; - char *value = NULL; - for (GList *gIter = matches; gIter != NULL; gIter = gIter->next) { pcmk_resource_t *match = gIter->data; const char *agent = g_hash_table_lookup(match->meta, - XML_ATTR_TYPE); - op_digest_cache_t *data = NULL; + PCMK_XA_TYPE); + pcmk__op_digest_t *data = NULL; data = pe__compare_fencing_digest(match, agent, node, scheduler); if (data->rc == pcmk__digest_mismatch) { optional = FALSE; crm_notice("Unfencing node %s because the definition of " - "%s changed", pe__node_name(node), match->id); + "%s changed", pcmk__node_name(node), match->id); if (!pcmk__is_daemon && scheduler->priv != NULL) { pcmk__output_t *out = scheduler->priv; out->info(out, "notice: Unfencing node %s because the " "definition of %s changed", - pe__node_name(node), match->id); + pcmk__node_name(node), match->id); } } @@ -1325,16 +1339,12 @@ pe_fence_op(pcmk_node_t *node, const char *op, bool optional, match->id, ":", agent, ":", data->digest_secure_calc, ",", NULL); } - key = strdup(XML_OP_ATTR_DIGESTS_ALL); - value = strdup((const char *) digests_all->str); - CRM_ASSERT((key != NULL) && (value != NULL)); - g_hash_table_insert(stonith_op->meta, key, value); + pcmk__insert_dup(stonith_op->meta, PCMK__META_DIGESTS_ALL, + digests_all->str); g_string_free(digests_all, TRUE); - key = strdup(XML_OP_ATTR_DIGESTS_SECURE); - value = strdup((const char *) digests_secure->str); - CRM_ASSERT((key != NULL) && (value != NULL)); - g_hash_table_insert(stonith_op->meta, key, value); + pcmk__insert_dup(stonith_op->meta, PCMK__META_DIGESTS_SECURE, + digests_secure->str); g_string_free(digests_secure, TRUE); } @@ -1344,8 +1354,10 @@ pe_fence_op(pcmk_node_t *node, const char *op, bool optional, if (scheduler->priority_fencing_delay > 0 - /* It's a suitable case where `priority-fencing-delay` applies. - * At least add `priority-fencing-delay` field as an indicator. */ + /* It's a suitable case where PCMK_OPT_PRIORITY_FENCING_DELAY + * applies. At least add PCMK_OPT_PRIORITY_FENCING_DELAY field as + * an indicator. + */ && (priority_delay /* The priority delay needs to be recalculated if this function has @@ -1353,22 +1365,22 @@ pe_fence_op(pcmk_node_t *node, const char *op, bool optional, * priority has already been calculated by native_add_running(). */ || g_hash_table_lookup(stonith_op->meta, - XML_CONFIG_ATTR_PRIORITY_FENCING_DELAY) != NULL)) { + PCMK_OPT_PRIORITY_FENCING_DELAY) != NULL)) { - /* Add `priority-fencing-delay` to the fencing op even if it's 0 for - * the targeting node. So that it takes precedence over any possible - * `pcmk_delay_base/max`. + /* Add PCMK_OPT_PRIORITY_FENCING_DELAY to the fencing op even if + * it's 0 for the targeting node. So that it takes precedence over + * any possible `pcmk_delay_base/max`. */ char *delay_s = pcmk__itoa(node_priority_fencing_delay(node, scheduler)); g_hash_table_insert(stonith_op->meta, - strdup(XML_CONFIG_ATTR_PRIORITY_FENCING_DELAY), + strdup(PCMK_OPT_PRIORITY_FENCING_DELAY), delay_s); } if(optional == FALSE && pe_can_fence(scheduler, node)) { - pe__clear_action_flags(stonith_op, pcmk_action_optional); + pcmk__clear_action_flags(stonith_op, pcmk_action_optional); pe_action_set_reason(stonith_op, reason, false); } else if(reason && stonith_op->reason == NULL) { @@ -1400,61 +1412,12 @@ pe_free_action(pcmk_action_t *action) free(action); } -int -pe_get_configured_timeout(pcmk_resource_t *rsc, const char *action, - pcmk_scheduler_t *scheduler) -{ - xmlNode *child = NULL; - GHashTable *action_meta = NULL; - const char *timeout_spec = NULL; - int timeout_ms = 0; - - pe_rule_eval_data_t rule_data = { - .node_hash = NULL, - .role = pcmk_role_unknown, - .now = scheduler->now, - .match_data = NULL, - .rsc_data = NULL, - .op_data = NULL - }; - - for (child = first_named_child(rsc->ops_xml, XML_ATTR_OP); - child != NULL; child = crm_next_same_xml(child)) { - if (pcmk__str_eq(action, crm_element_value(child, XML_NVPAIR_ATTR_NAME), - pcmk__str_casei)) { - timeout_spec = crm_element_value(child, XML_ATTR_TIMEOUT); - break; - } - } - - if (timeout_spec == NULL && scheduler->op_defaults) { - action_meta = pcmk__strkey_table(free, free); - pe__unpack_dataset_nvpairs(scheduler->op_defaults, XML_TAG_META_SETS, - &rule_data, action_meta, NULL, FALSE, - scheduler); - timeout_spec = g_hash_table_lookup(action_meta, XML_ATTR_TIMEOUT); - } - - // @TODO check meta-attributes - // @TODO maybe use min-interval monitor timeout as default for monitors - - timeout_ms = crm_get_msec(timeout_spec); - if (timeout_ms < 0) { - timeout_ms = PCMK_DEFAULT_ACTION_TIMEOUT_MS; - } - - if (action_meta != NULL) { - g_hash_table_destroy(action_meta); - } - return timeout_ms; -} - enum action_tasks get_complex_task(const pcmk_resource_t *rsc, const char *name) { - enum action_tasks task = text2task(name); + enum action_tasks task = pcmk_parse_action(name); - if ((rsc != NULL) && (rsc->variant == pcmk_rsc_variant_primitive)) { + if (pcmk__is_primitive(rsc)) { switch (task) { case pcmk_action_stopped: case pcmk_action_started: @@ -1503,7 +1466,7 @@ find_first_action(const GList *input, const char *uuid, const char *task, } else if (action->node == NULL) { continue; - } else if (on_node->details == action->node->details) { + } else if (pcmk__same_node(on_node, action->node)) { return action; } } @@ -1531,13 +1494,13 @@ find_actions(GList *input, const char *key, const pcmk_node_t *on_node) } else if (action->node == NULL) { crm_trace("Action %s matches (unallocated, assigning to %s)", - key, pe__node_name(on_node)); + key, pcmk__node_name(on_node)); action->node = pe__copy_node(on_node); result = g_list_prepend(result, action); - } else if (on_node->details == action->node->details) { - crm_trace("Action %s on %s matches", key, pe__node_name(on_node)); + } else if (pcmk__same_node(on_node, action->node)) { + crm_trace("Action %s on %s matches", key, pcmk__node_name(on_node)); result = g_list_prepend(result, action); } } @@ -1564,7 +1527,7 @@ find_actions_exact(GList *input, const char *key, const pcmk_node_t *on_node) && pcmk__str_eq(on_node->details->id, action->node->details->id, pcmk__str_casei)) { - crm_trace("Action %s on %s matches", key, pe__node_name(on_node)); + crm_trace("Action %s on %s matches", key, pcmk__node_name(on_node)); result = g_list_prepend(result, action); } } @@ -1640,11 +1603,12 @@ void pe_action_set_reason(pcmk_action_t *action, const char *reason, bool overwrite) { if (action->reason != NULL && overwrite) { - pe_rsc_trace(action->rsc, "Changing %s reason from '%s' to '%s'", - action->uuid, action->reason, pcmk__s(reason, "(none)")); + pcmk__rsc_trace(action->rsc, "Changing %s reason from '%s' to '%s'", + action->uuid, action->reason, + pcmk__s(reason, "(none)")); } else if (action->reason == NULL) { - pe_rsc_trace(action->rsc, "Set %s reason to '%s'", - action->uuid, pcmk__s(reason, "(none)")); + pcmk__rsc_trace(action->rsc, "Set %s reason to '%s'", + action->uuid, pcmk__s(reason, "(none)")); } else { // crm_assert(action->reason != NULL && !overwrite); return; @@ -1688,17 +1652,17 @@ pe__is_newer_op(const xmlNode *xml_a, const xmlNode *xml_b, char *a_uuid = NULL; char *b_uuid = NULL; - const char *a_xml_id = crm_element_value(xml_a, XML_ATTR_ID); - const char *b_xml_id = crm_element_value(xml_b, XML_ATTR_ID); + const char *a_xml_id = crm_element_value(xml_a, PCMK_XA_ID); + const char *b_xml_id = crm_element_value(xml_b, PCMK_XA_ID); - const char *a_node = crm_element_value(xml_a, XML_LRM_ATTR_TARGET); - const char *b_node = crm_element_value(xml_b, XML_LRM_ATTR_TARGET); + const char *a_node = crm_element_value(xml_a, PCMK__META_ON_NODE); + const char *b_node = crm_element_value(xml_b, PCMK__META_ON_NODE); bool same_node = true; /* @COMPAT The on_node attribute was added to last_failure as of 1.1.13 (via * 8b3ca1c) and the other entries as of 1.1.12 (via 0b07b5c). * - * In case that any of the lrm_rsc_op entries doesn't have on_node + * In case that any of the PCMK__XE_LRM_RSC_OP entries doesn't have on_node * attribute, we need to explicitly tell whether the two operations are on * the same node. */ @@ -1710,17 +1674,18 @@ pe__is_newer_op(const xmlNode *xml_a, const xmlNode *xml_b, } if (same_node && pcmk__str_eq(a_xml_id, b_xml_id, pcmk__str_none)) { - /* We have duplicate lrm_rsc_op entries in the status + /* We have duplicate PCMK__XE_LRM_RSC_OP entries in the status * section which is unlikely to be a good thing * - we can handle it easily enough, but we need to get * to the bottom of why it's happening. */ - pe_err("Duplicate lrm_rsc_op entries named %s", a_xml_id); + pcmk__config_err("Duplicate " PCMK__XE_LRM_RSC_OP " entries named %s", + a_xml_id); sort_return(0, "duplicate"); } - crm_element_value_int(xml_a, XML_LRM_ATTR_CALLID, &a_call_id); - crm_element_value_int(xml_b, XML_LRM_ATTR_CALLID, &b_call_id); + crm_element_value_int(xml_a, PCMK__XA_CALL_ID, &a_call_id); + crm_element_value_int(xml_b, PCMK__XA_CALL_ID, &b_call_id); if (a_call_id == -1 && b_call_id == -1) { /* both are pending ops so it doesn't matter since @@ -1736,15 +1701,14 @@ pe__is_newer_op(const xmlNode *xml_a, const xmlNode *xml_b, } else if (a_call_id >= 0 && b_call_id >= 0 && (!same_node || a_call_id == b_call_id)) { - /* - * The op and last_failed_op are the same - * Order on last-rc-change + /* The op and last_failed_op are the same. Order on + * PCMK_XA_LAST_RC_CHANGE. */ time_t last_a = -1; time_t last_b = -1; - crm_element_value_epoch(xml_a, XML_RSC_OP_LAST_CHANGE, &last_a); - crm_element_value_epoch(xml_b, XML_RSC_OP_LAST_CHANGE, &last_b); + crm_element_value_epoch(xml_a, PCMK_XA_LAST_RC_CHANGE, &last_a); + crm_element_value_epoch(xml_b, PCMK_XA_LAST_RC_CHANGE, &last_b); crm_trace("rc-change: %lld vs %lld", (long long) last_a, (long long) last_b); @@ -1757,15 +1721,18 @@ pe__is_newer_op(const xmlNode *xml_a, const xmlNode *xml_b, sort_return(0, "rc-change"); } else { - /* One of the inputs is a pending operation - * Attempt to use XML_ATTR_TRANSITION_MAGIC to determine its age relative to the other + /* One of the inputs is a pending operation. + * Attempt to use PCMK__XA_TRANSITION_MAGIC to determine its age relative + * to the other. */ int a_id = -1; int b_id = -1; - const char *a_magic = crm_element_value(xml_a, XML_ATTR_TRANSITION_MAGIC); - const char *b_magic = crm_element_value(xml_b, XML_ATTR_TRANSITION_MAGIC); + const char *a_magic = crm_element_value(xml_a, + PCMK__XA_TRANSITION_MAGIC); + const char *b_magic = crm_element_value(xml_b, + PCMK__XA_TRANSITION_MAGIC); CRM_CHECK(a_magic != NULL && b_magic != NULL, sort_return(0, "No magic")); if (!decode_transition_magic(a_magic, &a_uuid, &a_id, NULL, NULL, NULL, @@ -1841,9 +1808,9 @@ pe__new_rsc_pseudo_action(pcmk_resource_t *rsc, const char *task, bool optional, action = custom_action(rsc, pcmk__op_key(rsc->id, task, 0), task, NULL, optional, rsc->cluster); - pe__set_action_flags(action, pcmk_action_pseudo); + pcmk__set_action_flags(action, pcmk_action_pseudo); if (runnable) { - pe__set_action_flags(action, pcmk_action_runnable); + pcmk__set_action_flags(action, pcmk_action_runnable); } return action; } @@ -1855,17 +1822,13 @@ pe__new_rsc_pseudo_action(pcmk_resource_t *rsc, const char *task, bool optional, * \param[in,out] action Action to add expected result to * \param[in] expected_result Expected result to add * - * \note This is more efficient than calling add_hash_param(). + * \note This is more efficient than calling pcmk__insert_meta(). */ void pe__add_action_expected_result(pcmk_action_t *action, int expected_result) { - char *name = NULL; - CRM_ASSERT((action != NULL) && (action->meta != NULL)); - name = strdup(XML_ATTR_TE_TARGET_RC); - CRM_ASSERT (name != NULL); - - g_hash_table_insert(action->meta, name, pcmk__itoa(expected_result)); + g_hash_table_insert(action->meta, pcmk__str_copy(PCMK__META_OP_TARGET_RC), + pcmk__itoa(expected_result)); } diff --git a/lib/pengine/pe_digest.c b/lib/pengine/pe_digest.c index 546a2a7..6000b27 100644 --- a/lib/pengine/pe_digest.c +++ b/lib/pengine/pe_digest.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2023 the Pacemaker project contributors + * Copyright 2004-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -13,7 +13,6 @@ #include <stdbool.h> #include <crm/crm.h> -#include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crm/common/xml_internal.h> #include <crm/pengine/internal.h> @@ -33,7 +32,7 @@ extern bool pcmk__is_daemon; void pe__free_digests(gpointer ptr) { - op_digest_cache_t *data = ptr; + pcmk__op_digest_t *data = ptr; if (data != NULL) { free_xml(data->params_all); @@ -96,7 +95,7 @@ attr_in_string(xmlAttrPtr a, void *user_data) * \param[in,out] scheduler Scheduler data */ static void -calculate_main_digest(op_digest_cache_t *data, pcmk_resource_t *rsc, +calculate_main_digest(pcmk__op_digest_t *data, pcmk_resource_t *rsc, const pcmk_node_t *node, GHashTable *params, const char *task, guint *interval_ms, const xmlNode *xml_op, const char *op_version, @@ -104,18 +103,18 @@ calculate_main_digest(op_digest_cache_t *data, pcmk_resource_t *rsc, { xmlNode *action_config = NULL; - data->params_all = create_xml_node(NULL, XML_TAG_PARAMS); + data->params_all = pcmk__xe_create(NULL, PCMK_XE_PARAMETERS); /* REMOTE_CONTAINER_HACK: Allow Pacemaker Remote nodes to run containers * that themselves are Pacemaker Remote nodes */ - (void) pe__add_bundle_remote_name(rsc, scheduler, data->params_all, - XML_RSC_ATTR_REMOTE_RA_ADDR); + (void) pe__add_bundle_remote_name(rsc, data->params_all, + PCMK_REMOTE_RA_ADDR); if (overrides != NULL) { // If interval was overridden, reset it - const char *interval_s = g_hash_table_lookup(overrides, CRM_META "_" - XML_LRM_ATTR_INTERVAL); + const char *meta_name = CRM_META "_" PCMK_META_INTERVAL; + const char *interval_s = g_hash_table_lookup(overrides, meta_name); if (interval_s != NULL) { long long value_ll; @@ -185,22 +184,22 @@ is_fence_param(xmlAttrPtr attr, void *user_data) * \param[in] overrides Key/value hash table to override resource parameters */ static void -calculate_secure_digest(op_digest_cache_t *data, const pcmk_resource_t *rsc, +calculate_secure_digest(pcmk__op_digest_t *data, const pcmk_resource_t *rsc, GHashTable *params, const xmlNode *xml_op, const char *op_version, GHashTable *overrides) { - const char *class = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS); + const char *class = crm_element_value(rsc->xml, PCMK_XA_CLASS); const char *secure_list = NULL; bool old_version = (compare_version(op_version, "3.16.0") < 0); if (xml_op == NULL) { secure_list = " passwd password user "; } else { - secure_list = crm_element_value(xml_op, XML_LRM_ATTR_OP_SECURE); + secure_list = crm_element_value(xml_op, PCMK__XA_OP_SECURE_PARAMS); } if (old_version) { - data->params_secure = create_xml_node(NULL, XML_TAG_PARAMS); + data->params_secure = pcmk__xe_create(NULL, PCMK_XE_PARAMETERS); if (overrides != NULL) { g_hash_table_foreach(overrides, hash2field, data->params_secure); } @@ -209,7 +208,7 @@ calculate_secure_digest(op_digest_cache_t *data, const pcmk_resource_t *rsc, } else { // Start with a copy of all parameters - data->params_secure = copy_xml(data->params_all); + data->params_secure = pcmk__xml_copy(NULL, data->params_all); } if (secure_list != NULL) { @@ -236,7 +235,8 @@ calculate_secure_digest(op_digest_cache_t *data, const pcmk_resource_t *rsc, * Remove any timeout that made it this far, to match. */ if (old_version) { - xml_remove_prop(data->params_secure, CRM_META "_" XML_ATTR_TIMEOUT); + pcmk__xe_remove_attr(data->params_secure, + CRM_META "_" PCMK_META_TIMEOUT); } data->digest_secure_calc = calculate_operation_digest(data->params_secure, @@ -255,7 +255,7 @@ calculate_secure_digest(op_digest_cache_t *data, const pcmk_resource_t *rsc, * data->params_all, which already has overrides applied. */ static void -calculate_restart_digest(op_digest_cache_t *data, const xmlNode *xml_op, +calculate_restart_digest(pcmk__op_digest_t *data, const xmlNode *xml_op, const char *op_version) { const char *value = NULL; @@ -266,21 +266,21 @@ calculate_restart_digest(op_digest_cache_t *data, const xmlNode *xml_op, } // And the history must have a restart digest to compare against - if (crm_element_value(xml_op, XML_LRM_ATTR_RESTART_DIGEST) == NULL) { + if (crm_element_value(xml_op, PCMK__XA_OP_RESTART_DIGEST) == NULL) { return; } // Start with a copy of all parameters - data->params_restart = copy_xml(data->params_all); + data->params_restart = pcmk__xml_copy(NULL, data->params_all); // Then filter out reloadable parameters, if any - value = crm_element_value(xml_op, XML_LRM_ATTR_OP_RESTART); + value = crm_element_value(xml_op, PCMK__XA_OP_FORCE_RESTART); if (value != NULL) { pcmk__xe_remove_matching_attrs(data->params_restart, attr_not_in_string, (void *) value); } - value = crm_element_value(xml_op, XML_ATTR_CRM_VERSION); + value = crm_element_value(xml_op, PCMK_XA_CRM_FEATURE_SET); data->digest_restart_calc = calculate_operation_digest(data->params_restart, value); } @@ -302,28 +302,33 @@ calculate_restart_digest(op_digest_cache_t *data, const xmlNode *xml_op, * \note It is the caller's responsibility to free the result using * pe__free_digests(). */ -op_digest_cache_t * +pcmk__op_digest_t * pe__calculate_digests(pcmk_resource_t *rsc, const char *task, guint *interval_ms, const pcmk_node_t *node, const xmlNode *xml_op, GHashTable *overrides, bool calc_secure, pcmk_scheduler_t *scheduler) { - op_digest_cache_t *data = calloc(1, sizeof(op_digest_cache_t)); + pcmk__op_digest_t *data = NULL; const char *op_version = NULL; GHashTable *params = NULL; + CRM_CHECK(scheduler != NULL, return NULL); + + data = calloc(1, sizeof(pcmk__op_digest_t)); if (data == NULL) { + pcmk__sched_err("Could not allocate memory for operation digest"); return NULL; } data->rc = pcmk__digest_match; if (xml_op != NULL) { - op_version = crm_element_value(xml_op, XML_ATTR_CRM_VERSION); + op_version = crm_element_value(xml_op, PCMK_XA_CRM_FEATURE_SET); } - if (op_version == NULL && scheduler != NULL && scheduler->input != NULL) { - op_version = crm_element_value(scheduler->input, XML_ATTR_CRM_VERSION); + if ((op_version == NULL) && (scheduler->input != NULL)) { + op_version = crm_element_value(scheduler->input, + PCMK_XA_CRM_FEATURE_SET); } if (op_version == NULL) { @@ -355,12 +360,12 @@ pe__calculate_digests(pcmk_resource_t *rsc, const char *task, * * \return Pointer to node's digest cache entry */ -static op_digest_cache_t * +static pcmk__op_digest_t * rsc_action_digest(pcmk_resource_t *rsc, const char *task, guint interval_ms, pcmk_node_t *node, const xmlNode *xml_op, bool calc_secure, pcmk_scheduler_t *scheduler) { - op_digest_cache_t *data = NULL; + pcmk__op_digest_t *data = NULL; char *key = pcmk__op_key(rsc->id, task, interval_ms); data = g_hash_table_lookup(node->details->digest_cache, key); @@ -385,38 +390,38 @@ rsc_action_digest(pcmk_resource_t *rsc, const char *task, guint interval_ms, * * \return Pointer to node's digest cache entry, with comparison result set */ -op_digest_cache_t * +pcmk__op_digest_t * rsc_action_digest_cmp(pcmk_resource_t *rsc, const xmlNode *xml_op, pcmk_node_t *node, pcmk_scheduler_t *scheduler) { - op_digest_cache_t *data = NULL; + pcmk__op_digest_t *data = NULL; guint interval_ms = 0; const char *op_version; - const char *task = crm_element_value(xml_op, XML_LRM_ATTR_TASK); + const char *task = crm_element_value(xml_op, PCMK_XA_OPERATION); const char *digest_all; const char *digest_restart; CRM_ASSERT(node != NULL); - op_version = crm_element_value(xml_op, XML_ATTR_CRM_VERSION); - digest_all = crm_element_value(xml_op, XML_LRM_ATTR_OP_DIGEST); - digest_restart = crm_element_value(xml_op, XML_LRM_ATTR_RESTART_DIGEST); + op_version = crm_element_value(xml_op, PCMK_XA_CRM_FEATURE_SET); + digest_all = crm_element_value(xml_op, PCMK__XA_OP_DIGEST); + digest_restart = crm_element_value(xml_op, PCMK__XA_OP_RESTART_DIGEST); - crm_element_value_ms(xml_op, XML_LRM_ATTR_INTERVAL_MS, &interval_ms); + crm_element_value_ms(xml_op, PCMK_META_INTERVAL, &interval_ms); data = rsc_action_digest(rsc, task, interval_ms, node, xml_op, pcmk_is_set(scheduler->flags, pcmk_sched_sanitized), scheduler); if (digest_restart && data->digest_restart_calc && strcmp(data->digest_restart_calc, digest_restart) != 0) { - pe_rsc_info(rsc, "Parameters to %ums-interval %s action for %s on %s " - "changed: hash was %s vs. now %s (restart:%s) %s", - interval_ms, task, rsc->id, pe__node_name(node), - pcmk__s(digest_restart, "missing"), - data->digest_restart_calc, - op_version, - crm_element_value(xml_op, XML_ATTR_TRANSITION_MAGIC)); + pcmk__rsc_info(rsc, + "Parameters to %ums-interval %s action for %s on %s " + "changed: hash was %s vs. now %s (restart:%s) %s", + interval_ms, task, rsc->id, pcmk__node_name(node), + pcmk__s(digest_restart, "missing"), + data->digest_restart_calc, op_version, + crm_element_value(xml_op, PCMK__XA_TRANSITION_MAGIC)); data->rc = pcmk__digest_restart; } else if (digest_all == NULL) { @@ -429,27 +434,32 @@ rsc_action_digest_cmp(pcmk_resource_t *rsc, const xmlNode *xml_op, * digest matches, enforce a restart rather than a reload-agent anyway. * So that it ensures any changes of the extra parameters get applied * for this specific operation, and the digests calculated for the - * resulting lrm_rsc_op will be correct. + * resulting PCMK__XE_LRM_RSC_OP will be correct. * Preserve the implied rc pcmk__digest_restart for the case that the * main digest doesn't match. */ if ((interval_ms == 0) && (data->rc == pcmk__digest_restart)) { - pe_rsc_info(rsc, "Parameters containing extra ones to %ums-interval" - " %s action for %s on %s " - "changed: hash was %s vs. now %s (restart:%s) %s", - interval_ms, task, rsc->id, pe__node_name(node), - pcmk__s(digest_all, "missing"), data->digest_all_calc, - op_version, - crm_element_value(xml_op, XML_ATTR_TRANSITION_MAGIC)); + pcmk__rsc_info(rsc, + "Parameters containing extra ones to %ums-interval" + " %s action for %s on %s " + "changed: hash was %s vs. now %s (restart:%s) %s", + interval_ms, task, rsc->id, pcmk__node_name(node), + pcmk__s(digest_all, "missing"), + data->digest_all_calc, op_version, + crm_element_value(xml_op, + PCMK__XA_TRANSITION_MAGIC)); } else { - pe_rsc_info(rsc, "Parameters to %ums-interval %s action for %s on %s " - "changed: hash was %s vs. now %s (%s:%s) %s", - interval_ms, task, rsc->id, pe__node_name(node), - pcmk__s(digest_all, "missing"), data->digest_all_calc, - (interval_ms > 0)? "reschedule" : "reload", - op_version, - crm_element_value(xml_op, XML_ATTR_TRANSITION_MAGIC)); + pcmk__rsc_info(rsc, + "Parameters to %ums-interval %s action for %s on %s " + "changed: hash was %s vs. now %s (%s:%s) %s", + interval_ms, task, rsc->id, pcmk__node_name(node), + pcmk__s(digest_all, "missing"), + data->digest_all_calc, + (interval_ms > 0)? "reschedule" : "reload", + op_version, + crm_element_value(xml_op, + PCMK__XA_TRANSITION_MAGIC)); data->rc = pcmk__digest_mismatch; } @@ -537,18 +547,19 @@ unfencing_digest_matches(const char *rsc_id, const char *agent, * * \return Node's digest cache entry */ -op_digest_cache_t * +pcmk__op_digest_t * pe__compare_fencing_digest(pcmk_resource_t *rsc, const char *agent, pcmk_node_t *node, pcmk_scheduler_t *scheduler) { const char *node_summary = NULL; // Calculate device's current parameter digests - op_digest_cache_t *data = rsc_action_digest(rsc, STONITH_DIGEST_TASK, 0U, + pcmk__op_digest_t *data = rsc_action_digest(rsc, STONITH_DIGEST_TASK, 0U, node, NULL, TRUE, scheduler); // Check whether node has special unfencing summary node attribute - node_summary = pe_node_attribute_raw(node, CRM_ATTR_DIGESTS_ALL); + node_summary = pcmk__node_attr(node, CRM_ATTR_DIGESTS_ALL, NULL, + pcmk__rsc_node_current); if (node_summary == NULL) { data->rc = pcmk__digest_unknown; return data; @@ -562,7 +573,8 @@ pe__compare_fencing_digest(pcmk_resource_t *rsc, const char *agent, } // Check whether secure parameter digest matches - node_summary = pe_node_attribute_raw(node, CRM_ATTR_DIGESTS_SECURE); + node_summary = pcmk__node_attr(node, CRM_ATTR_DIGESTS_SECURE, NULL, + pcmk__rsc_node_current); if (unfencing_digest_matches(rsc->id, agent, data->digest_secure_calc, node_summary)) { data->rc = pcmk__digest_match; @@ -570,7 +582,7 @@ pe__compare_fencing_digest(pcmk_resource_t *rsc, const char *agent, pcmk__output_t *out = scheduler->priv; out->info(out, "Only 'private' parameters to %s " "for unfencing %s changed", rsc->id, - pe__node_name(node)); + pcmk__node_name(node)); } return data; } @@ -587,14 +599,14 @@ pe__compare_fencing_digest(pcmk_resource_t *rsc, const char *agent, out->info(out, "Parameters to %s for unfencing " "%s changed, try '%s'", rsc->id, - pe__node_name(node), digest); + pcmk__node_name(node), digest); free(digest); } else if (!pcmk__is_daemon) { char *digest = create_unfencing_summary(rsc->id, agent, data->digest_secure_calc); printf("Parameters to %s for unfencing %s changed, try '%s'\n", - rsc->id, pe__node_name(node), digest); + rsc->id, pcmk__node_name(node), digest); free(digest); } } diff --git a/lib/pengine/pe_health.c b/lib/pengine/pe_health.c index 93028ae..4f7eb10 100644 --- a/lib/pengine/pe_health.c +++ b/lib/pengine/pe_health.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2023 the Pacemaker project contributors + * Copyright 2004-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -15,7 +15,8 @@ /*! * \internal - * \brief Set the node health values to use for "red", "yellow", and "green" + * \brief Set the node health values to use for \c PCMK_VALUE_RED, + * \c PCMK_VALUE_YELLOW, and \c PCMK_VALUE_GREEN * * \param[in,out] scheduler Scheduler data */ @@ -30,23 +31,23 @@ pe__unpack_node_health_scores(pcmk_scheduler_t *scheduler) break; case pcmk__health_strategy_no_red: - pcmk__score_red = -INFINITY; + pcmk__score_red = -PCMK_SCORE_INFINITY; pcmk__score_yellow = 0; pcmk__score_green = 0; break; case pcmk__health_strategy_only_green: - pcmk__score_red = -INFINITY; - pcmk__score_yellow = -INFINITY; + pcmk__score_red = -PCMK_SCORE_INFINITY; + pcmk__score_yellow = -PCMK_SCORE_INFINITY; pcmk__score_green = 0; break; default: // progressive or custom - pcmk__score_red = pe__health_score(PCMK__OPT_NODE_HEALTH_RED, + pcmk__score_red = pe__health_score(PCMK_OPT_NODE_HEALTH_RED, scheduler); - pcmk__score_green = pe__health_score(PCMK__OPT_NODE_HEALTH_GREEN, + pcmk__score_green = pe__health_score(PCMK_OPT_NODE_HEALTH_GREEN, scheduler); - pcmk__score_yellow = pe__health_score(PCMK__OPT_NODE_HEALTH_YELLOW, + pcmk__score_yellow = pe__health_score(PCMK_OPT_NODE_HEALTH_YELLOW, scheduler); break; } @@ -54,9 +55,9 @@ pe__unpack_node_health_scores(pcmk_scheduler_t *scheduler) if ((pcmk__score_red != 0) || (pcmk__score_yellow != 0) || (pcmk__score_green != 0)) { crm_debug("Values of node health scores: " - PCMK__VALUE_RED "=%d " - PCMK__VALUE_YELLOW "=%d " - PCMK__VALUE_GREEN "=%d", + PCMK_VALUE_RED "=%d " + PCMK_VALUE_YELLOW "=%d " + PCMK_VALUE_GREEN "=%d", pcmk__score_red, pcmk__score_yellow, pcmk__score_green); } } @@ -135,9 +136,9 @@ pe__node_health(pcmk_node_t *node) * or pcmk__score_yellow equals pcmk__score_green, so check the * textual value first to be able to distinguish those. */ - if (pcmk__str_eq(value, PCMK__VALUE_RED, pcmk__str_casei)) { + if (pcmk__str_eq(value, PCMK_VALUE_RED, pcmk__str_casei)) { return -1; - } else if (pcmk__str_eq(value, PCMK__VALUE_YELLOW, + } else if (pcmk__str_eq(value, PCMK_VALUE_YELLOW, pcmk__str_casei)) { rc = 0; continue; diff --git a/lib/pengine/pe_notif.c b/lib/pengine/pe_notif.c index 0e1e239..c13637b 100644 --- a/lib/pengine/pe_notif.c +++ b/lib/pengine/pe_notif.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2023 the Pacemaker project contributors + * Copyright 2004-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -8,7 +8,7 @@ */ #include <crm_internal.h> -#include <crm/msg_xml.h> +#include <crm/common/xml.h> #include <crm/pengine/internal.h> #include <pacemaker-internal.h> @@ -95,9 +95,8 @@ compare_notify_entries(gconstpointer a, gconstpointer b) static notify_entry_t * dup_notify_entry(const notify_entry_t *entry) { - notify_entry_t *dup = calloc(1, sizeof(notify_entry_t)); + notify_entry_t *dup = pcmk__assert_alloc(1, sizeof(notify_entry_t)); - CRM_ASSERT(dup != NULL); dup->rsc = entry->rsc; dup->node = entry->node; return dup; @@ -141,9 +140,9 @@ get_node_names(const GList *list, GString **all_node_names, // Add to host node name list if appropriate if (host_node_names != NULL) { - if (pe__is_guest_node(node) + if (pcmk__is_guest_or_bundle_node(node) && (node->details->remote_rsc->container->running_on != NULL)) { - node = pe__current_node(node->details->remote_rsc->container); + node = pcmk__current_node(node->details->remote_rsc->container); if (node->details->uname == NULL) { continue; } @@ -253,8 +252,7 @@ copy_meta_to_notify(gpointer key, gpointer value, gpointer user_data) return; } - g_hash_table_insert(notify->meta, strdup((const char *) key), - strdup((const char *) value)); + pcmk__insert_dup(notify->meta, (const char *) key, (const char *) value); } static void @@ -264,7 +262,7 @@ add_notify_data_to_action_meta(const notify_data_t *n_data, for (const GSList *item = n_data->keys; item; item = item->next) { const pcmk_nvpair_t *nvpair = (const pcmk_nvpair_t *) item->data; - add_hash_param(action->meta, nvpair->name, nvpair->value); + pcmk__insert_meta(action, nvpair->name, nvpair->value); } } @@ -290,9 +288,9 @@ new_notify_pseudo_action(pcmk_resource_t *rsc, const pcmk_action_t *action, notif_action, NULL, pcmk_is_set(action->flags, pcmk_action_optional), rsc->cluster); - pe__set_action_flags(notify, pcmk_action_pseudo); - add_hash_param(notify->meta, "notify_key_type", notif_type); - add_hash_param(notify->meta, "notify_key_operation", action->task); + pcmk__set_action_flags(notify, pcmk_action_pseudo); + pcmk__insert_meta(notify, "notify_key_type", notif_type); + pcmk__insert_meta(notify, "notify_key_operation", action->task); return notify; } @@ -332,16 +330,16 @@ new_notify_action(pcmk_resource_t *rsc, const pcmk_node_t *node, skip_reason = "original action not runnable"; } if (skip_reason != NULL) { - pe_rsc_trace(rsc, "Skipping notify action for %s on %s: %s", - rsc->id, pe__node_name(node), skip_reason); + pcmk__rsc_trace(rsc, "Skipping notify action for %s on %s: %s", + rsc->id, pcmk__node_name(node), skip_reason); return NULL; } value = g_hash_table_lookup(op->meta, "notify_type"); // "pre" or "post" task = g_hash_table_lookup(op->meta, "notify_operation"); // original action - pe_rsc_trace(rsc, "Creating notify action for %s on %s (%s-%s)", - rsc->id, pe__node_name(node), value, task); + pcmk__rsc_trace(rsc, "Creating notify action for %s on %s (%s-%s)", + rsc->id, pcmk__node_name(node), value, task); // Create the notify action key = pcmk__notify_key(rsc->id, value, task); @@ -379,7 +377,7 @@ new_post_notify_action(pcmk_resource_t *rsc, const pcmk_node_t *node, notify = new_notify_action(rsc, node, n_data->post, n_data->post_done, n_data); if (notify != NULL) { - notify->priority = INFINITY; + notify->priority = PCMK_SCORE_INFINITY; } // Order recurring monitors after all "post-" notifications complete @@ -390,8 +388,7 @@ new_post_notify_action(pcmk_resource_t *rsc, const pcmk_node_t *node, pcmk_action_t *mon = (pcmk_action_t *) iter->data; const char *interval_ms_s = NULL; - interval_ms_s = g_hash_table_lookup(mon->meta, - XML_LRM_ATTR_INTERVAL_MS); + interval_ms_s = g_hash_table_lookup(mon->meta, PCMK_META_INTERVAL); if (pcmk__str_eq(interval_ms_s, "0", pcmk__str_null_matches) || pcmk__str_eq(mon->task, PCMK_ACTION_CANCEL, pcmk__str_none)) { continue; // Not a recurring monitor @@ -441,8 +438,7 @@ pe__action_notif_pseudo_ops(pcmk_resource_t *rsc, const char *task, return NULL; } - n_data = calloc(1, sizeof(notify_data_t)); - CRM_ASSERT(n_data != NULL); + n_data = pcmk__assert_alloc(1, sizeof(notify_data_t)); n_data->action = task; @@ -451,18 +447,17 @@ pe__action_notif_pseudo_ops(pcmk_resource_t *rsc, const char *task, // Create "pre-" notify pseudo-action for clone n_data->pre = new_notify_pseudo_action(rsc, action, PCMK_ACTION_NOTIFY, "pre"); - pe__set_action_flags(n_data->pre, pcmk_action_runnable); - add_hash_param(n_data->pre->meta, "notify_type", "pre"); - add_hash_param(n_data->pre->meta, "notify_operation", n_data->action); + pcmk__set_action_flags(n_data->pre, pcmk_action_runnable); + pcmk__insert_meta(n_data->pre, "notify_type", "pre"); + pcmk__insert_meta(n_data->pre, "notify_operation", n_data->action); // Create "pre-" notifications complete pseudo-action for clone n_data->pre_done = new_notify_pseudo_action(rsc, action, PCMK_ACTION_NOTIFIED, "confirmed-pre"); - pe__set_action_flags(n_data->pre_done, pcmk_action_runnable); - add_hash_param(n_data->pre_done->meta, "notify_type", "pre"); - add_hash_param(n_data->pre_done->meta, - "notify_operation", n_data->action); + pcmk__set_action_flags(n_data->pre_done, pcmk_action_runnable); + pcmk__insert_meta(n_data->pre_done, "notify_type", "pre"); + pcmk__insert_meta(n_data->pre_done, "notify_operation", n_data->action); // Order "pre-" -> "pre-" complete -> original action order_actions(n_data->pre, n_data->pre_done, pcmk__ar_ordered); @@ -474,28 +469,28 @@ pe__action_notif_pseudo_ops(pcmk_resource_t *rsc, const char *task, // Create "post-" notify pseudo-action for clone n_data->post = new_notify_pseudo_action(rsc, complete, PCMK_ACTION_NOTIFY, "post"); - n_data->post->priority = INFINITY; + n_data->post->priority = PCMK_SCORE_INFINITY; if (pcmk_is_set(complete->flags, pcmk_action_runnable)) { - pe__set_action_flags(n_data->post, pcmk_action_runnable); + pcmk__set_action_flags(n_data->post, pcmk_action_runnable); } else { - pe__clear_action_flags(n_data->post, pcmk_action_runnable); + pcmk__clear_action_flags(n_data->post, pcmk_action_runnable); } - add_hash_param(n_data->post->meta, "notify_type", "post"); - add_hash_param(n_data->post->meta, "notify_operation", n_data->action); + pcmk__insert_meta(n_data->post, "notify_type", "post"); + pcmk__insert_meta(n_data->post, "notify_operation", n_data->action); // Create "post-" notifications complete pseudo-action for clone n_data->post_done = new_notify_pseudo_action(rsc, complete, PCMK_ACTION_NOTIFIED, "confirmed-post"); - n_data->post_done->priority = INFINITY; + n_data->post_done->priority = PCMK_SCORE_INFINITY; if (pcmk_is_set(complete->flags, pcmk_action_runnable)) { - pe__set_action_flags(n_data->post_done, pcmk_action_runnable); + pcmk__set_action_flags(n_data->post_done, pcmk_action_runnable); } else { - pe__clear_action_flags(n_data->post_done, pcmk_action_runnable); + pcmk__clear_action_flags(n_data->post_done, pcmk_action_runnable); } - add_hash_param(n_data->post_done->meta, "notify_type", "post"); - add_hash_param(n_data->post_done->meta, - "notify_operation", n_data->action); + pcmk__insert_meta(n_data->post_done, "notify_type", "post"); + pcmk__insert_meta(n_data->post_done, + "notify_operation", n_data->action); // Order original action complete -> "post-" -> "post-" complete order_actions(complete, n_data->post, pcmk__ar_first_implies_then); @@ -523,9 +518,8 @@ pe__action_notif_pseudo_ops(pcmk_resource_t *rsc, const char *task, static notify_entry_t * new_notify_entry(const pcmk_resource_t *rsc, const pcmk_node_t *node) { - notify_entry_t *entry = calloc(1, sizeof(notify_entry_t)); + notify_entry_t *entry = pcmk__assert_alloc(1, sizeof(notify_entry_t)); - CRM_ASSERT(entry != NULL); entry->rsc = rsc; entry->node = node; return entry; @@ -595,9 +589,10 @@ collect_resource_data(const pcmk_resource_t *rsc, bool activity, break; default: - crm_err("Resource %s role on %s (%s) is not supported for " - "notifications (bug?)", - rsc->id, pe__node_name(node), role2text(rsc->role)); + pcmk__sched_err("Resource %s role on %s (%s) is not supported for " + "notifications (bug?)", + rsc->id, pcmk__node_name(node), + pcmk_role_text(rsc->role)); free(entry); break; } @@ -612,7 +607,7 @@ collect_resource_data(const pcmk_resource_t *rsc, bool activity, if (!pcmk_is_set(op->flags, pcmk_action_optional) && (op->node != NULL)) { - enum action_tasks task = text2task(op->task); + enum action_tasks task = pcmk_parse_action(op->task); if ((task == pcmk_action_stop) && op->node->details->unclean) { // Create anyway (additional noise if node can't be fenced) @@ -753,8 +748,9 @@ add_notif_keys(const pcmk_resource_t *rsc, notify_data_t *n_data) add_notify_env_free_gs(n_data, "notify_available_uname", node_list); g_list_free(nodes); - source = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_TARGET); - if (pcmk__str_eq("host", source, pcmk__str_none)) { + source = g_hash_table_lookup(rsc->meta, + PCMK_META_CONTAINER_ATTRIBUTE_TARGET); + if (pcmk__str_eq(PCMK_VALUE_HOST, source, pcmk__str_none)) { get_node_names(rsc->cluster->nodes, &node_list, &metal_list); add_notify_env_free_gs(n_data, "notify_all_hosts", metal_list); } else { @@ -763,13 +759,13 @@ add_notif_keys(const pcmk_resource_t *rsc, notify_data_t *n_data) add_notify_env_free_gs(n_data, "notify_all_uname", node_list); if (required && (n_data->pre != NULL)) { - pe__clear_action_flags(n_data->pre, pcmk_action_optional); - pe__clear_action_flags(n_data->pre_done, pcmk_action_optional); + pcmk__clear_action_flags(n_data->pre, pcmk_action_optional); + pcmk__clear_action_flags(n_data->pre_done, pcmk_action_optional); } if (required && (n_data->post != NULL)) { - pe__clear_action_flags(n_data->post, pcmk_action_optional); - pe__clear_action_flags(n_data->post_done, pcmk_action_optional); + pcmk__clear_action_flags(n_data->post, pcmk_action_optional); + pcmk__clear_action_flags(n_data->post_done, pcmk_action_optional); } } @@ -809,7 +805,7 @@ create_notify_actions(pcmk_resource_t *rsc, notify_data_t *n_data) GList *iter = NULL; pcmk_action_t *stop = NULL; pcmk_action_t *start = NULL; - enum action_tasks task = text2task(n_data->action); + enum action_tasks task = pcmk_parse_action(n_data->action); // If this is a clone, call recursively for each instance if (rsc->children != NULL) { @@ -823,7 +819,7 @@ create_notify_actions(pcmk_resource_t *rsc, notify_data_t *n_data) if (!pcmk_is_set(op->flags, pcmk_action_optional) && (op->node != NULL)) { - switch (text2task(op->task)) { + switch (pcmk_parse_action(op->task)) { case pcmk_action_start: case pcmk_action_stop: case pcmk_action_promote: @@ -840,24 +836,24 @@ create_notify_actions(pcmk_resource_t *rsc, notify_data_t *n_data) switch (task) { case pcmk_action_start: if (n_data->start == NULL) { - pe_rsc_trace(rsc, "No notify action needed for %s %s", - rsc->id, n_data->action); + pcmk__rsc_trace(rsc, "No notify action needed for %s %s", + rsc->id, n_data->action); return; } break; case pcmk_action_promote: if (n_data->promote == NULL) { - pe_rsc_trace(rsc, "No notify action needed for %s %s", - rsc->id, n_data->action); + pcmk__rsc_trace(rsc, "No notify action needed for %s %s", + rsc->id, n_data->action); return; } break; case pcmk_action_demote: if (n_data->demote == NULL) { - pe_rsc_trace(rsc, "No notify action needed for %s %s", - rsc->id, n_data->action); + pcmk__rsc_trace(rsc, "No notify action needed for %s %s", + rsc->id, n_data->action); return; } break; @@ -867,8 +863,8 @@ create_notify_actions(pcmk_resource_t *rsc, notify_data_t *n_data) break; } - pe_rsc_trace(rsc, "Creating notify actions for %s %s", - rsc->id, n_data->action); + pcmk__rsc_trace(rsc, "Creating notify actions for %s %s", + rsc->id, n_data->action); // Create notify actions for stop or demote if ((rsc->role != pcmk_role_stopped) @@ -918,8 +914,8 @@ create_notify_actions(pcmk_resource_t *rsc, notify_data_t *n_data) } } if (rsc->allocated_to == NULL) { - pe_proc_err("Next role '%s' but %s is not allocated", - role2text(rsc->next_role), rsc->id); + pcmk__sched_err("Next role '%s' but %s is not allocated", + pcmk_role_text(rsc->next_role), rsc->id); return; } if ((task != pcmk_action_start) || (start == NULL) diff --git a/lib/pengine/pe_output.c b/lib/pengine/pe_output.c index 65f3c18..b1cd8cc 100644 --- a/lib/pengine/pe_output.c +++ b/lib/pengine/pe_output.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 the Pacemaker project contributors + * Copyright 2019-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -15,7 +15,7 @@ #include <crm/common/output.h> #include <crm/common/scheduler_internal.h> #include <crm/cib/util.h> -#include <crm/msg_xml.h> +#include <crm/common/xml.h> #include <crm/pengine/internal.h> const char * @@ -24,15 +24,15 @@ pe__resource_description(const pcmk_resource_t *rsc, uint32_t show_opts) const char * desc = NULL; // User-supplied description if (pcmk_any_flags_set(show_opts, pcmk_show_rsc_only|pcmk_show_description)) { - desc = crm_element_value(rsc->xml, XML_ATTR_DESC); + desc = crm_element_value(rsc->xml, PCMK_XA_DESCRIPTION); } return desc; } /* Never display node attributes whose name starts with one of these prefixes */ #define FILTER_STR { PCMK__FAIL_COUNT_PREFIX, PCMK__LAST_FAILURE_PREFIX, \ - "shutdown", PCMK_NODE_ATTR_TERMINATE, "standby", "#", \ - NULL } + PCMK__NODE_ATTR_SHUTDOWN, PCMK_NODE_ATTR_TERMINATE, \ + PCMK_NODE_ATTR_STANDBY, "#", NULL } static int compare_attribute(gconstpointer a, gconstpointer b) @@ -68,7 +68,7 @@ add_extra_info(const pcmk_node_t *node, GList *rsc_list, for (gIter = rsc_list; gIter != NULL; gIter = gIter->next) { pcmk_resource_t *rsc = (pcmk_resource_t *) gIter->data; - const char *type = g_hash_table_lookup(rsc->meta, "type"); + const char *type = g_hash_table_lookup(rsc->meta, PCMK_XA_TYPE); const char *name = NULL; GHashTable *params = NULL; @@ -84,7 +84,7 @@ add_extra_info(const pcmk_node_t *node, GList *rsc_list, } params = pe_rsc_params(rsc, node, scheduler); - name = g_hash_table_lookup(params, "name"); + name = g_hash_table_lookup(params, PCMK_XA_NAME); if (name == NULL) { name = "pingd"; @@ -143,12 +143,13 @@ get_operation_list(xmlNode *rsc_entry) { GList *op_list = NULL; xmlNode *rsc_op = NULL; - for (rsc_op = pcmk__xe_first_child(rsc_entry); rsc_op != NULL; - rsc_op = pcmk__xe_next(rsc_op)) { - const char *task = crm_element_value(rsc_op, XML_LRM_ATTR_TASK); + for (rsc_op = pcmk__xe_first_child(rsc_entry, NULL, NULL, NULL); + rsc_op != NULL; rsc_op = pcmk__xe_next(rsc_op)) { + + const char *task = crm_element_value(rsc_op, PCMK_XA_OPERATION); const char *interval_ms_s = crm_element_value(rsc_op, - XML_LRM_ATTR_INTERVAL_MS); - const char *op_rc = crm_element_value(rsc_op, XML_LRM_ATTR_RC); + PCMK_META_INTERVAL); + const char *op_rc = crm_element_value(rsc_op, PCMK__XA_RC_CODE); int op_rc_i; pcmk__scan_min_int(op_rc, &op_rc_i, 0); @@ -166,7 +167,7 @@ get_operation_list(xmlNode *rsc_entry) { continue; } - if (pcmk__str_eq((const char *)rsc_op->name, XML_LRM_TAG_RSC_OP, pcmk__str_none)) { + if (pcmk__xe_is(rsc_op, PCMK__XE_LRM_RSC_OP)) { op_list = g_list_append(op_list, rsc_op); } } @@ -179,7 +180,9 @@ static void add_dump_node(gpointer key, gpointer value, gpointer user_data) { xmlNodePtr node = user_data; - pcmk_create_xml_text_node(node, (const char *) key, (const char *) value); + + node = pcmk__xe_create(node, (const char *) key); + pcmk__xe_set_content(node, "%s", (const char *) value); } static void @@ -193,12 +196,19 @@ append_dump_text(gpointer key, gpointer value, gpointer user_data) *dump_text = new_text; } +#define XPATH_STACK "//" PCMK_XE_NVPAIR \ + "[@" PCMK_XA_NAME "='" \ + PCMK_OPT_CLUSTER_INFRASTRUCTURE "']" + static const char * get_cluster_stack(pcmk_scheduler_t *scheduler) { - xmlNode *stack = get_xpath_object("//nvpair[@name='cluster-infrastructure']", - scheduler->input, LOG_DEBUG); - return stack? crm_element_value(stack, XML_NVPAIR_ATTR_VALUE) : "unknown"; + xmlNode *stack = get_xpath_object(XPATH_STACK, scheduler->input, LOG_DEBUG); + + if (stack != NULL) { + return crm_element_value(stack, PCMK_XA_VALUE); + } + return PCMK_VALUE_UNKNOWN; } static char * @@ -221,12 +231,12 @@ last_changed_string(const char *last_written, const char *user, static char * op_history_string(xmlNode *xml_op, const char *task, const char *interval_ms_s, int rc, bool print_timing) { - const char *call = crm_element_value(xml_op, XML_LRM_ATTR_CALLID); + const char *call = crm_element_value(xml_op, PCMK__XA_CALL_ID); char *interval_str = NULL; char *buf = NULL; if (interval_ms_s && !pcmk__str_eq(interval_ms_s, "0", pcmk__str_casei)) { - char *pair = pcmk__format_nvpair("interval", interval_ms_s, "ms"); + char *pair = pcmk__format_nvpair(PCMK_XA_INTERVAL, interval_ms_s, "ms"); interval_str = crm_strdup_printf(" %s", pair); free(pair); } @@ -240,26 +250,27 @@ op_history_string(xmlNode *xml_op, const char *task, const char *interval_ms_s, time_t epoch = 0; - if ((crm_element_value_epoch(xml_op, XML_RSC_OP_LAST_CHANGE, &epoch) == pcmk_ok) + if ((crm_element_value_epoch(xml_op, PCMK_XA_LAST_RC_CHANGE, + &epoch) == pcmk_ok) && (epoch > 0)) { char *epoch_str = pcmk__epoch2str(&epoch, 0); last_change_str = crm_strdup_printf(" %s=\"%s\"", - XML_RSC_OP_LAST_CHANGE, + PCMK_XA_LAST_RC_CHANGE, pcmk__s(epoch_str, "")); free(epoch_str); } - value = crm_element_value(xml_op, XML_RSC_OP_T_EXEC); + value = crm_element_value(xml_op, PCMK_XA_EXEC_TIME); if (value) { - char *pair = pcmk__format_nvpair(XML_RSC_OP_T_EXEC, value, "ms"); + char *pair = pcmk__format_nvpair(PCMK_XA_EXEC_TIME, value, "ms"); exec_str = crm_strdup_printf(" %s", pair); free(pair); } - value = crm_element_value(xml_op, XML_RSC_OP_T_QUEUE); + value = crm_element_value(xml_op, PCMK_XA_QUEUE_TIME); if (value) { - char *pair = pcmk__format_nvpair(XML_RSC_OP_T_QUEUE, value, "ms"); + char *pair = pcmk__format_nvpair(PCMK_XA_QUEUE_TIME, value, "ms"); queue_str = crm_strdup_printf(" %s", pair); free(pair); } @@ -307,19 +318,19 @@ resource_history_string(pcmk_resource_t *rsc, const char *rsc_id, bool all, char *lastfail_s = NULL; if (failcount > 0) { - failcount_s = crm_strdup_printf(" %s=%d", PCMK__FAIL_COUNT_PREFIX, - failcount); + failcount_s = crm_strdup_printf(" %s=%d", + PCMK_XA_FAIL_COUNT, failcount); } else { failcount_s = strdup(""); } if (last_failure > 0) { buf = pcmk__epoch2str(&last_failure, 0); lastfail_s = crm_strdup_printf(" %s='%s'", - PCMK__LAST_FAILURE_PREFIX, buf); + PCMK_XA_LAST_FAILURE, buf); free(buf); } - buf = crm_strdup_printf("%s: migration-threshold=%d%s%s", + buf = crm_strdup_printf("%s: " PCMK_META_MIGRATION_THRESHOLD "=%d%s%s", rsc_id, rsc->migration_threshold, failcount_s, lastfail_s? lastfail_s : ""); free(failcount_s); @@ -345,7 +356,7 @@ static const char * get_node_feature_set(const pcmk_node_t *node) { if (node->details->online && node->details->expected_up - && !pe__is_guest_or_remote_node(node)) { + && !pcmk__is_pacemaker_remote_node(node)) { const char *feature_set = g_hash_table_lookup(node->details->attrs, CRM_ATTR_FEATURE_SET); @@ -376,16 +387,19 @@ is_mixed_version(pcmk_scheduler_t *scheduler) return false; } -static char * -formatted_xml_buf(const pcmk_resource_t *rsc, bool raw) +static void +formatted_xml_buf(const pcmk_resource_t *rsc, GString *xml_buf, bool raw) { - if (raw) { - return dump_xml_formatted(rsc->orig_xml ? rsc->orig_xml : rsc->xml); + if (raw && (rsc->orig_xml != NULL)) { + pcmk__xml_string(rsc->orig_xml, pcmk__xml_fmt_pretty, xml_buf, 0); } else { - return dump_xml_formatted(rsc->xml); + pcmk__xml_string(rsc->xml, pcmk__xml_fmt_pretty, xml_buf, 0); } } +#define XPATH_DC_VERSION "//" PCMK_XE_NVPAIR \ + "[@" PCMK_XA_NAME "='" PCMK_OPT_DC_VERSION "']" + PCMK__OUTPUT_ARGS("cluster-summary", "pcmk_scheduler_t *", "enum pcmk_pacemakerd_state", "uint32_t", "uint32_t") static int @@ -405,13 +419,13 @@ cluster_summary(pcmk__output_t *out, va_list args) { } if (pcmk_is_set(section_opts, pcmk_section_dc)) { - xmlNode *dc_version = get_xpath_object("//nvpair[@name='dc-version']", + xmlNode *dc_version = get_xpath_object(XPATH_DC_VERSION, scheduler->input, LOG_DEBUG); const char *dc_version_s = dc_version? - crm_element_value(dc_version, XML_NVPAIR_ATTR_VALUE) + crm_element_value(dc_version, PCMK_XA_VALUE) : NULL; const char *quorum = crm_element_value(scheduler->input, - XML_ATTR_HAVE_QUORUM); + PCMK_XA_HAVE_QUORUM); char *dc_name = scheduler->dc_node? pe__node_display_name(scheduler->dc_node, pcmk_is_set(show_opts, pcmk_show_node_id)) : NULL; bool mixed_version = is_mixed_version(scheduler); @@ -423,13 +437,13 @@ cluster_summary(pcmk__output_t *out, va_list args) { if (pcmk_is_set(section_opts, pcmk_section_times)) { const char *last_written = crm_element_value(scheduler->input, - XML_CIB_ATTR_WRITTEN); + PCMK_XA_CIB_LAST_WRITTEN); const char *user = crm_element_value(scheduler->input, - XML_ATTR_UPDATE_USER); + PCMK_XA_UPDATE_USER); const char *client = crm_element_value(scheduler->input, - XML_ATTR_UPDATE_CLIENT); + PCMK_XA_UPDATE_CLIENT); const char *origin = crm_element_value(scheduler->input, - XML_ATTR_UPDATE_ORIG); + PCMK_XA_UPDATE_ORIGIN); PCMK__OUTPUT_LIST_HEADER(out, false, rc, "Cluster Summary"); out->message(out, "cluster-times", @@ -480,13 +494,13 @@ cluster_summary_html(pcmk__output_t *out, va_list args) { /* Always print DC if none, even if not requested */ if ((scheduler->dc_node == NULL) || pcmk_is_set(section_opts, pcmk_section_dc)) { - xmlNode *dc_version = get_xpath_object("//nvpair[@name='dc-version']", + xmlNode *dc_version = get_xpath_object(XPATH_DC_VERSION, scheduler->input, LOG_DEBUG); const char *dc_version_s = dc_version? - crm_element_value(dc_version, XML_NVPAIR_ATTR_VALUE) + crm_element_value(dc_version, PCMK_XA_VALUE) : NULL; const char *quorum = crm_element_value(scheduler->input, - XML_ATTR_HAVE_QUORUM); + PCMK_XA_HAVE_QUORUM); char *dc_name = scheduler->dc_node? pe__node_display_name(scheduler->dc_node, pcmk_is_set(show_opts, pcmk_show_node_id)) : NULL; bool mixed_version = is_mixed_version(scheduler); @@ -498,13 +512,13 @@ cluster_summary_html(pcmk__output_t *out, va_list args) { if (pcmk_is_set(section_opts, pcmk_section_times)) { const char *last_written = crm_element_value(scheduler->input, - XML_CIB_ATTR_WRITTEN); + PCMK_XA_CIB_LAST_WRITTEN); const char *user = crm_element_value(scheduler->input, - XML_ATTR_UPDATE_USER); + PCMK_XA_UPDATE_USER); const char *client = crm_element_value(scheduler->input, - XML_ATTR_UPDATE_CLIENT); + PCMK_XA_UPDATE_CLIENT); const char *origin = crm_element_value(scheduler->input, - XML_ATTR_UPDATE_ORIG); + PCMK_XA_UPDATE_ORIGIN); PCMK__OUTPUT_LIST_HEADER(out, false, rc, "Cluster Summary"); out->message(out, "cluster-times", @@ -551,9 +565,9 @@ pe__node_display_name(pcmk_node_t *node, bool print_detail) CRM_ASSERT((node != NULL) && (node->details != NULL) && (node->details->uname != NULL)); /* Host is displayed only if this is a guest node and detail is requested */ - if (print_detail && pe__is_guest_node(node)) { + if (print_detail && pcmk__is_guest_or_bundle_node(node)) { const pcmk_resource_t *container = node->details->remote_rsc->container; - const pcmk_node_t *host_node = pe__current_node(container); + const pcmk_node_t *host_node = pcmk__current_node(container); if (host_node && host_node->details) { node_host = host_node->details->uname; @@ -578,8 +592,7 @@ pe__node_display_name(pcmk_node_t *node, bool print_detail) } /* Allocate and populate display name */ - node_name = malloc(name_len); - CRM_ASSERT(node_name != NULL); + node_name = pcmk__assert_alloc(name_len, sizeof(char)); strcpy(node_name, node->details->uname); if (node_host) { strcat(node_name, "@"); @@ -594,27 +607,21 @@ pe__node_display_name(pcmk_node_t *node, bool print_detail) } int -pe__name_and_nvpairs_xml(pcmk__output_t *out, bool is_list, const char *tag_name - , size_t pairs_count, ...) +pe__name_and_nvpairs_xml(pcmk__output_t *out, bool is_list, const char *tag_name, + ...) { xmlNodePtr xml_node = NULL; - va_list args; + va_list pairs; CRM_ASSERT(tag_name != NULL); xml_node = pcmk__output_xml_peek_parent(out); CRM_ASSERT(xml_node != NULL); - xml_node = create_xml_node(xml_node, tag_name); + xml_node = pcmk__xe_create(xml_node, tag_name); - va_start(args, pairs_count); - while(pairs_count--) { - const char *param_name = va_arg(args, const char *); - const char *param_value = va_arg(args, const char *); - if (param_name && param_value) { - crm_xml_add(xml_node, param_name, param_value); - } - }; - va_end(args); + va_start(pairs, tag_name); + pcmk__xe_set_propv(xml_node, pairs); + va_end(pairs); if (is_list) { pcmk__output_xml_push_parent(out, xml_node); @@ -629,23 +636,23 @@ role_desc(enum rsc_role_e role) #ifdef PCMK__COMPAT_2_0 return "as " PCMK__ROLE_PROMOTED_LEGACY " "; #else - return "in " PCMK__ROLE_PROMOTED " role "; + return "in " PCMK_ROLE_PROMOTED " role "; #endif } return ""; } -PCMK__OUTPUT_ARGS("ban", "pcmk_node_t *", "pe__location_t *", "uint32_t") +PCMK__OUTPUT_ARGS("ban", "pcmk_node_t *", "pcmk__location_t *", "uint32_t") static int ban_html(pcmk__output_t *out, va_list args) { pcmk_node_t *pe_node = va_arg(args, pcmk_node_t *); - pe__location_t *location = va_arg(args, pe__location_t *); + pcmk__location_t *location = va_arg(args, pcmk__location_t *); uint32_t show_opts = va_arg(args, uint32_t); char *node_name = pe__node_display_name(pe_node, pcmk_is_set(show_opts, pcmk_show_node_id)); char *buf = crm_strdup_printf("%s\tprevents %s from running %son %s", - location->id, location->rsc_lh->id, + location->id, location->rsc->id, role_desc(location->role_filter), node_name); pcmk__output_create_html_node(out, "li", NULL, NULL, buf); @@ -655,46 +662,46 @@ ban_html(pcmk__output_t *out, va_list args) { return pcmk_rc_ok; } -PCMK__OUTPUT_ARGS("ban", "pcmk_node_t *", "pe__location_t *", "uint32_t") +PCMK__OUTPUT_ARGS("ban", "pcmk_node_t *", "pcmk__location_t *", "uint32_t") static int ban_text(pcmk__output_t *out, va_list args) { pcmk_node_t *pe_node = va_arg(args, pcmk_node_t *); - pe__location_t *location = va_arg(args, pe__location_t *); + pcmk__location_t *location = va_arg(args, pcmk__location_t *); uint32_t show_opts = va_arg(args, uint32_t); char *node_name = pe__node_display_name(pe_node, pcmk_is_set(show_opts, pcmk_show_node_id)); out->list_item(out, NULL, "%s\tprevents %s from running %son %s", - location->id, location->rsc_lh->id, + location->id, location->rsc->id, role_desc(location->role_filter), node_name); free(node_name); return pcmk_rc_ok; } -PCMK__OUTPUT_ARGS("ban", "pcmk_node_t *", "pe__location_t *", "uint32_t") +PCMK__OUTPUT_ARGS("ban", "pcmk_node_t *", "pcmk__location_t *", "uint32_t") static int ban_xml(pcmk__output_t *out, va_list args) { pcmk_node_t *pe_node = va_arg(args, pcmk_node_t *); - pe__location_t *location = va_arg(args, pe__location_t *); + pcmk__location_t *location = va_arg(args, pcmk__location_t *); uint32_t show_opts G_GNUC_UNUSED = va_arg(args, uint32_t); const char *promoted_only = pcmk__btoa(location->role_filter == pcmk_role_promoted); char *weight_s = pcmk__itoa(pe_node->weight); - pcmk__output_create_xml_node(out, "ban", - "id", location->id, - "resource", location->rsc_lh->id, - "node", pe_node->details->uname, - "weight", weight_s, - "promoted-only", promoted_only, + pcmk__output_create_xml_node(out, PCMK_XE_BAN, + PCMK_XA_ID, location->id, + PCMK_XA_RESOURCE, location->rsc->id, + PCMK_XA_NODE, pe_node->details->uname, + PCMK_XA_WEIGHT, weight_s, + PCMK_XA_PROMOTED_ONLY, promoted_only, /* This is a deprecated alias for * promoted_only. Removing it will break * backward compatibility of the API schema, * which will require an API schema major * version bump. */ - "master_only", promoted_only, + PCMK__XA_PROMOTED_ONLY_LEGACY, promoted_only, NULL); free(weight_s); @@ -717,8 +724,8 @@ ban_list(pcmk__output_t *out, va_list args) { /* Print each ban */ for (gIter = scheduler->placement_constraints; gIter != NULL; gIter = gIter->next) { - pe__location_t *location = gIter->data; - const pcmk_resource_t *rsc = location->rsc_lh; + pcmk__location_t *location = gIter->data; + const pcmk_resource_t *rsc = location->rsc; if (prefix != NULL && !g_str_has_prefix(location->id, prefix)) { continue; @@ -731,7 +738,7 @@ ban_list(pcmk__output_t *out, va_list args) { continue; } - for (gIter2 = location->node_list_rh; gIter2 != NULL; gIter2 = gIter2->next) { + for (gIter2 = location->nodes; gIter2 != NULL; gIter2 = gIter2->next) { pcmk_node_t *node = (pcmk_node_t *) gIter2->data; if (node->weight < 0) { @@ -755,53 +762,61 @@ cluster_counts_html(pcmk__output_t *out, va_list args) { xmlNodePtr nodes_node = pcmk__output_create_xml_node(out, "li", NULL); xmlNodePtr resources_node = pcmk__output_create_xml_node(out, "li", NULL); + xmlNode *child = NULL; - char *nnodes_str = crm_strdup_printf("%d node%s configured", - nnodes, pcmk__plural_s(nnodes)); - - pcmk_create_html_node(nodes_node, "span", NULL, NULL, nnodes_str); - free(nnodes_str); + child = pcmk__html_create(nodes_node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, "%d node%s configured", + nnodes, pcmk__plural_s(nnodes)); if (ndisabled && nblocked) { - char *s = crm_strdup_printf("%d resource instance%s configured (%d ", - nresources, pcmk__plural_s(nresources), - ndisabled); - pcmk_create_html_node(resources_node, "span", NULL, NULL, s); - free(s); + child = pcmk__html_create(resources_node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, "%d resource instance%s configured (%d ", + nresources, pcmk__plural_s(nresources), ndisabled); - pcmk_create_html_node(resources_node, "span", NULL, "bold", "DISABLED"); + child = pcmk__html_create(resources_node, PCMK__XE_SPAN, NULL, + PCMK__VALUE_BOLD); + pcmk__xe_set_content(child, "DISABLED"); - s = crm_strdup_printf(", %d ", nblocked); - pcmk_create_html_node(resources_node, "span", NULL, NULL, s); - free(s); + child = pcmk__html_create(resources_node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, ", %d ", nblocked); + + child = pcmk__html_create(resources_node, PCMK__XE_SPAN, NULL, + PCMK__VALUE_BOLD); + pcmk__xe_set_content(child, "BLOCKED"); + + child = pcmk__html_create(resources_node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, " from further action due to failure)"); - pcmk_create_html_node(resources_node, "span", NULL, "bold", "BLOCKED"); - pcmk_create_html_node(resources_node, "span", NULL, NULL, - " from further action due to failure)"); } else if (ndisabled && !nblocked) { - char *s = crm_strdup_printf("%d resource instance%s configured (%d ", - nresources, pcmk__plural_s(nresources), - ndisabled); - pcmk_create_html_node(resources_node, "span", NULL, NULL, s); - free(s); + child = pcmk__html_create(resources_node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, "%d resource instance%s configured (%d ", + nresources, pcmk__plural_s(nresources), + ndisabled); + + child = pcmk__html_create(resources_node, PCMK__XE_SPAN, NULL, + PCMK__VALUE_BOLD); + pcmk__xe_set_content(child, "DISABLED"); + + child = pcmk__html_create(resources_node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, ")"); - pcmk_create_html_node(resources_node, "span", NULL, "bold", "DISABLED"); - pcmk_create_html_node(resources_node, "span", NULL, NULL, ")"); } else if (!ndisabled && nblocked) { - char *s = crm_strdup_printf("%d resource instance%s configured (%d ", - nresources, pcmk__plural_s(nresources), - nblocked); - pcmk_create_html_node(resources_node, "span", NULL, NULL, s); - free(s); + child = pcmk__html_create(resources_node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, "%d resource instance%s configured (%d ", + nresources, pcmk__plural_s(nresources), + nblocked); + + child = pcmk__html_create(resources_node, PCMK__XE_SPAN, NULL, + PCMK__VALUE_BOLD); + pcmk__xe_set_content(child, "BLOCKED"); + + child = pcmk__html_create(resources_node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, " from further action due to failure)"); - pcmk_create_html_node(resources_node, "span", NULL, "bold", "BLOCKED"); - pcmk_create_html_node(resources_node, "span", NULL, NULL, - " from further action due to failure)"); } else { - char *s = crm_strdup_printf("%d resource instance%s configured", - nresources, pcmk__plural_s(nresources)); - pcmk_create_html_node(resources_node, "span", NULL, NULL, s); - free(s); + child = pcmk__html_create(resources_node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, "%d resource instance%s configured", + nresources, pcmk__plural_s(nresources)); } return pcmk_rc_ok; @@ -849,23 +864,30 @@ cluster_counts_xml(pcmk__output_t *out, va_list args) { int ndisabled = va_arg(args, int); int nblocked = va_arg(args, int); - xmlNodePtr nodes_node = pcmk__output_create_xml_node(out, "nodes_configured", NULL); - xmlNodePtr resources_node = pcmk__output_create_xml_node(out, "resources_configured", NULL); + xmlNodePtr nodes_node = NULL; + xmlNodePtr resources_node = NULL; + char *s = NULL; - char *s = pcmk__itoa(nnodes); - crm_xml_add(nodes_node, "number", s); + nodes_node = pcmk__output_create_xml_node(out, PCMK_XE_NODES_CONFIGURED, + NULL); + resources_node = pcmk__output_create_xml_node(out, + PCMK_XE_RESOURCES_CONFIGURED, + NULL); + + s = pcmk__itoa(nnodes); + crm_xml_add(nodes_node, PCMK_XA_NUMBER, s); free(s); s = pcmk__itoa(nresources); - crm_xml_add(resources_node, "number", s); + crm_xml_add(resources_node, PCMK_XA_NUMBER, s); free(s); s = pcmk__itoa(ndisabled); - crm_xml_add(resources_node, "disabled", s); + crm_xml_add(resources_node, PCMK_XA_DISABLED, s); free(s); s = pcmk__itoa(nblocked); - crm_xml_add(resources_node, "blocked", s); + crm_xml_add(resources_node, PCMK_XA_BLOCKED, s); free(s); return pcmk_rc_ok; @@ -882,28 +904,42 @@ cluster_dc_html(pcmk__output_t *out, va_list args) { bool mixed_version = va_arg(args, int); xmlNodePtr node = pcmk__output_create_xml_node(out, "li", NULL); + xmlNode *child = NULL; - pcmk_create_html_node(node, "span", NULL, "bold", "Current DC: "); + child = pcmk__html_create(node, PCMK__XE_SPAN, NULL, PCMK__VALUE_BOLD); + pcmk__xe_set_content(child, "Current DC: "); if (dc) { - char *buf = crm_strdup_printf("%s (version %s) -", dc_name, - dc_version_s ? dc_version_s : "unknown"); - pcmk_create_html_node(node, "span", NULL, NULL, buf); - free(buf); + child = pcmk__html_create(node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, "%s (version %s) -", + dc_name, pcmk__s(dc_version_s, "unknown")); if (mixed_version) { - pcmk_create_html_node(node, "span", NULL, "warning", - " MIXED-VERSION"); + child = pcmk__html_create(node, PCMK__XE_SPAN, NULL, + PCMK__VALUE_WARNING); + pcmk__xe_set_content(child, " MIXED-VERSION"); } - pcmk_create_html_node(node, "span", NULL, NULL, " partition"); + + child = pcmk__html_create(node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, " partition"); + if (crm_is_true(quorum)) { - pcmk_create_html_node(node, "span", NULL, NULL, " with"); + child = pcmk__html_create(node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, " with"); + } else { - pcmk_create_html_node(node, "span", NULL, "warning", " WITHOUT"); + child = pcmk__html_create(node, PCMK__XE_SPAN, NULL, + PCMK__VALUE_WARNING); + pcmk__xe_set_content(child, " WITHOUT"); } - pcmk_create_html_node(node, "span", NULL, NULL, " quorum"); + + child = pcmk__html_create(node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, " quorum"); + } else { - pcmk_create_html_node(node, "span", NULL, "warning", "NONE"); + child = pcmk__html_create(node, PCMK__XE_SPAN, NULL, + PCMK__VALUE_WARNING); + pcmk__xe_set_content(child, "NONE"); } return pcmk_rc_ok; @@ -943,17 +979,20 @@ cluster_dc_xml(pcmk__output_t *out, va_list args) { bool mixed_version = va_arg(args, int); if (dc) { - pcmk__output_create_xml_node(out, "current_dc", - "present", "true", - "version", dc_version_s ? dc_version_s : "", - "name", dc->details->uname, - "id", dc->details->id, - "with_quorum", pcmk__btoa(crm_is_true(quorum)), - "mixed_version", pcmk__btoa(mixed_version), + const char *with_quorum = pcmk__btoa(crm_is_true(quorum)); + const char *mixed_version_s = pcmk__btoa(mixed_version); + + pcmk__output_create_xml_node(out, PCMK_XE_CURRENT_DC, + PCMK_XA_PRESENT, PCMK_VALUE_TRUE, + PCMK_XA_VERSION, pcmk__s(dc_version_s, ""), + PCMK_XA_NAME, dc->details->uname, + PCMK_XA_ID, dc->details->id, + PCMK_XA_WITH_QUORUM, with_quorum, + PCMK_XA_MIXED_VERSION, mixed_version_s, NULL); } else { - pcmk__output_create_xml_node(out, "current_dc", - "present", "false", + pcmk__output_create_xml_node(out, PCMK_XE_CURRENT_DC, + PCMK_XA_PRESENT, PCMK_VALUE_FALSE, NULL); } @@ -1020,18 +1059,33 @@ cluster_options_html(pcmk__output_t *out, va_list args) { if (pcmk_is_set(scheduler->flags, pcmk_sched_in_maintenance)) { xmlNodePtr node = pcmk__output_create_xml_node(out, "li", NULL); + xmlNode *child = NULL; + + child = pcmk__html_create(node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, "Resource management: "); + + child = pcmk__html_create(node, PCMK__XE_SPAN, NULL, PCMK__VALUE_BOLD); + pcmk__xe_set_content(child, "DISABLED"); + + child = pcmk__html_create(node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, + " (the cluster will not attempt to start, stop," + " or recover services)"); - pcmk_create_html_node(node, "span", NULL, NULL, "Resource management: "); - pcmk_create_html_node(node, "span", NULL, "bold", "DISABLED"); - pcmk_create_html_node(node, "span", NULL, NULL, - " (the cluster will not attempt to start, stop, or recover services)"); } else if (pcmk_is_set(scheduler->flags, pcmk_sched_stop_all)) { xmlNodePtr node = pcmk__output_create_xml_node(out, "li", NULL); + xmlNode *child = NULL; + + child = pcmk__html_create(node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, "Resource management: "); + + child = pcmk__html_create(node, PCMK__XE_SPAN, NULL, PCMK__VALUE_BOLD); + pcmk__xe_set_content(child, "STOPPED"); + + child = pcmk__html_create(node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, + " (the cluster will keep all resources stopped)"); - pcmk_create_html_node(node, "span", NULL, NULL, "Resource management: "); - pcmk_create_html_node(node, "span", NULL, "bold", "STOPPED"); - pcmk_create_html_node(node, "span", NULL, NULL, - " (the cluster will keep all resources stopped)"); } else { out->list_item(out, NULL, "Resource management: enabled"); } @@ -1096,53 +1150,70 @@ cluster_options_text(pcmk__output_t *out, va_list args) { return pcmk_rc_ok; } -#define bv(flag) pcmk__btoa(pcmk_is_set(scheduler->flags, (flag))) - -PCMK__OUTPUT_ARGS("cluster-options", "pcmk_scheduler_t *") -static int -cluster_options_xml(pcmk__output_t *out, va_list args) { - pcmk_scheduler_t *scheduler = va_arg(args, pcmk_scheduler_t *); - - const char *no_quorum_policy = NULL; - char *stonith_timeout_str = pcmk__itoa(scheduler->stonith_timeout); - char *priority_fencing_delay_str = pcmk__itoa(scheduler->priority_fencing_delay * 1000); - - switch (scheduler->no_quorum_policy) { +/*! + * \internal + * \brief Get readable string representation of a no-quorum policy + * + * \param[in] policy No-quorum policy + * + * \return String representation of \p policy + */ +static const char * +no_quorum_policy_text(enum pe_quorum_policy policy) +{ + switch (policy) { case pcmk_no_quorum_freeze: - no_quorum_policy = "freeze"; - break; + return PCMK_VALUE_FREEZE; case pcmk_no_quorum_stop: - no_quorum_policy = "stop"; - break; + return PCMK_VALUE_STOP; case pcmk_no_quorum_demote: - no_quorum_policy = "demote"; - break; + return PCMK_VALUE_DEMOTE; case pcmk_no_quorum_ignore: - no_quorum_policy = "ignore"; - break; + return PCMK_VALUE_IGNORE; case pcmk_no_quorum_fence: - no_quorum_policy = "suicide"; - break; + return PCMK_VALUE_FENCE_LEGACY; + + default: + return PCMK_VALUE_UNKNOWN; } +} - pcmk__output_create_xml_node(out, "cluster_options", - "stonith-enabled", - bv(pcmk_sched_fencing_enabled), - "symmetric-cluster", - bv(pcmk_sched_symmetric_cluster), - "no-quorum-policy", no_quorum_policy, - "maintenance-mode", - bv(pcmk_sched_in_maintenance), - "stop-all-resources", bv(pcmk_sched_stop_all), - "stonith-timeout-ms", stonith_timeout_str, - "priority-fencing-delay-ms", priority_fencing_delay_str, +PCMK__OUTPUT_ARGS("cluster-options", "pcmk_scheduler_t *") +static int +cluster_options_xml(pcmk__output_t *out, va_list args) { + pcmk_scheduler_t *scheduler = va_arg(args, pcmk_scheduler_t *); + + const char *stonith_enabled = pcmk__flag_text(scheduler->flags, + pcmk_sched_fencing_enabled); + const char *symmetric_cluster = + pcmk__flag_text(scheduler->flags, pcmk_sched_symmetric_cluster); + const char *no_quorum_policy = + no_quorum_policy_text(scheduler->no_quorum_policy); + const char *maintenance_mode = pcmk__flag_text(scheduler->flags, + pcmk_sched_in_maintenance); + const char *stop_all_resources = pcmk__flag_text(scheduler->flags, + pcmk_sched_stop_all); + char *stonith_timeout_ms_s = pcmk__itoa(scheduler->stonith_timeout); + char *priority_fencing_delay_ms_s = + pcmk__itoa(scheduler->priority_fencing_delay * 1000); + + pcmk__output_create_xml_node(out, PCMK_XE_CLUSTER_OPTIONS, + PCMK_XA_STONITH_ENABLED, stonith_enabled, + PCMK_XA_SYMMETRIC_CLUSTER, symmetric_cluster, + PCMK_XA_NO_QUORUM_POLICY, no_quorum_policy, + PCMK_XA_MAINTENANCE_MODE, maintenance_mode, + PCMK_XA_STOP_ALL_RESOURCES, stop_all_resources, + PCMK_XA_STONITH_TIMEOUT_MS, + stonith_timeout_ms_s, + PCMK_XA_PRIORITY_FENCING_DELAY_MS, + priority_fencing_delay_ms_s, NULL); - free(stonith_timeout_str); - free(priority_fencing_delay_str); + free(stonith_timeout_ms_s); + free(priority_fencing_delay_ms_s); return pcmk_rc_ok; } @@ -1155,15 +1226,24 @@ cluster_stack_html(pcmk__output_t *out, va_list args) { (enum pcmk_pacemakerd_state) va_arg(args, int); xmlNodePtr node = pcmk__output_create_xml_node(out, "li", NULL); + xmlNode *child = NULL; + + child = pcmk__html_create(node, PCMK__XE_SPAN, NULL, PCMK__VALUE_BOLD); + pcmk__xe_set_content(child, "Stack: "); - pcmk_create_html_node(node, "span", NULL, "bold", "Stack: "); - pcmk_create_html_node(node, "span", NULL, NULL, stack_s); + child = pcmk__html_create(node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, "%s", stack_s); if (pcmkd_state != pcmk_pacemakerd_state_invalid) { - pcmk_create_html_node(node, "span", NULL, NULL, " ("); - pcmk_create_html_node(node, "span", NULL, NULL, - pcmk__pcmkd_state_enum2friendly(pcmkd_state)); - pcmk_create_html_node(node, "span", NULL, NULL, ")"); + child = pcmk__html_create(node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, " ("); + + child = pcmk__html_create(node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, "%s", + pcmk__pcmkd_state_enum2friendly(pcmkd_state)); + + child = pcmk__html_create(node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, ")"); } return pcmk_rc_ok; } @@ -1198,9 +1278,9 @@ cluster_stack_xml(pcmk__output_t *out, va_list args) { state_s = pcmk_pacemakerd_api_daemon_state_enum2text(pcmkd_state); } - pcmk__output_create_xml_node(out, "stack", - "type", stack_s, - "pacemakerd-state", state_s, + pcmk__output_create_xml_node(out, PCMK_XE_STACK, + PCMK_XA_TYPE, stack_s, + PCMK_XA_PACEMAKERD_STATE, state_s, NULL); return pcmk_rc_ok; @@ -1218,24 +1298,36 @@ cluster_times_html(pcmk__output_t *out, va_list args) { xmlNodePtr updated_node = pcmk__output_create_xml_node(out, "li", NULL); xmlNodePtr changed_node = pcmk__output_create_xml_node(out, "li", NULL); + xmlNode *child = NULL; - char *time_s = pcmk__epoch2str(NULL, 0); + char *time_s = NULL; - pcmk_create_html_node(updated_node, "span", NULL, "bold", "Last updated: "); - pcmk_create_html_node(updated_node, "span", NULL, NULL, time_s); + child = pcmk__html_create(updated_node, PCMK__XE_SPAN, NULL, + PCMK__VALUE_BOLD); + pcmk__xe_set_content(child, "Last updated: "); + + child = pcmk__html_create(updated_node, PCMK__XE_SPAN, NULL, NULL); + time_s = pcmk__epoch2str(NULL, 0); + pcmk__xe_set_content(child, "%s", time_s); + free(time_s); if (our_nodename != NULL) { - pcmk_create_html_node(updated_node, "span", NULL, NULL, " on "); - pcmk_create_html_node(updated_node, "span", NULL, NULL, our_nodename); - } + child = pcmk__html_create(updated_node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, " on "); - free(time_s); - time_s = last_changed_string(last_written, user, client, origin); + child = pcmk__html_create(updated_node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, "%s", our_nodename); + } - pcmk_create_html_node(changed_node, "span", NULL, "bold", "Last change: "); - pcmk_create_html_node(changed_node, "span", NULL, NULL, time_s); + child = pcmk__html_create(changed_node, PCMK__XE_SPAN, NULL, + PCMK__VALUE_BOLD); + pcmk__xe_set_content(child, "Last change: "); + child = pcmk__html_create(changed_node, PCMK__XE_SPAN, NULL, NULL); + time_s = last_changed_string(last_written, user, client, origin); + pcmk__xe_set_content(child, "%s", time_s); free(time_s); + return pcmk_rc_ok; } @@ -1251,16 +1343,16 @@ cluster_times_xml(pcmk__output_t *out, va_list args) { char *time_s = pcmk__epoch2str(NULL, 0); - pcmk__output_create_xml_node(out, "last_update", - "time", time_s, - "origin", our_nodename, + pcmk__output_create_xml_node(out, PCMK_XE_LAST_UPDATE, + PCMK_XA_TIME, time_s, + PCMK_XA_ORIGIN, our_nodename, NULL); - pcmk__output_create_xml_node(out, "last_change", - "time", last_written ? last_written : "", - "user", user ? user : "", - "client", client ? client : "", - "origin", origin ? origin : "", + pcmk__output_create_xml_node(out, PCMK_XE_LAST_CHANGE, + PCMK_XA_TIME, pcmk__s(last_written, ""), + PCMK_XA_USER, pcmk__s(user, ""), + PCMK_XA_CLIENT, pcmk__s(client, ""), + PCMK_XA_ORIGIN, pcmk__s(origin, ""), NULL); free(time_s); @@ -1319,8 +1411,9 @@ failed_action_friendly(pcmk__output_t *out, const xmlNode *xml_op, if (pcmk__str_empty(op_key) || !parse_op_key(op_key, &rsc_id, &task, &interval_ms)) { - rsc_id = strdup("unknown resource"); - task = strdup("unknown action"); + + pcmk__str_update(&rsc_id, "unknown resource"); + pcmk__str_update(&task, "unknown action"); interval_ms = 0; } CRM_ASSERT((rsc_id != NULL) && (task != NULL)); @@ -1353,7 +1446,7 @@ failed_action_friendly(pcmk__output_t *out, const xmlNode *xml_op, } - if (crm_element_value_epoch(xml_op, XML_RSC_OP_LAST_CHANGE, + if (crm_element_value_epoch(xml_op, PCMK_XA_LAST_RC_CHANGE, &last_change_epoch) == pcmk_ok) { char *s = pcmk__epoch2str(&last_change_epoch, 0); @@ -1396,8 +1489,8 @@ failed_action_technical(pcmk__output_t *out, const xmlNode *xml_op, int status, const char *exit_reason, const char *exec_time) { - const char *call_id = crm_element_value(xml_op, XML_LRM_ATTR_CALLID); - const char *queue_time = crm_element_value(xml_op, XML_RSC_OP_T_QUEUE); + const char *call_id = crm_element_value(xml_op, PCMK__XA_CALL_ID); + const char *queue_time = crm_element_value(xml_op, PCMK_XA_QUEUE_TIME); const char *exit_status = services_ocf_exitcode_str(rc); const char *lrm_status = pcmk_exec_status_str(status); time_t last_change_epoch = 0; @@ -1423,12 +1516,12 @@ failed_action_technical(pcmk__output_t *out, const xmlNode *xml_op, pcmk__g_strcat(str, ", exitreason='", exit_reason, "'", NULL); } - if (crm_element_value_epoch(xml_op, XML_RSC_OP_LAST_CHANGE, + if (crm_element_value_epoch(xml_op, PCMK_XA_LAST_RC_CHANGE, &last_change_epoch) == pcmk_ok) { char *last_change_str = pcmk__epoch2str(&last_change_epoch, 0); pcmk__g_strcat(str, - ", " XML_RSC_OP_LAST_CHANGE "=" + ", " PCMK_XA_LAST_RC_CHANGE "=" "'", last_change_str, "'", NULL); free(last_change_str); } @@ -1443,26 +1536,25 @@ failed_action_technical(pcmk__output_t *out, const xmlNode *xml_op, g_string_free(str, TRUE); } -PCMK__OUTPUT_ARGS("failed-action", "xmlNodePtr", "uint32_t") +PCMK__OUTPUT_ARGS("failed-action", "xmlNode *", "uint32_t") static int failed_action_default(pcmk__output_t *out, va_list args) { xmlNodePtr xml_op = va_arg(args, xmlNodePtr); uint32_t show_opts = va_arg(args, uint32_t); - const char *op_key = pe__xe_history_key(xml_op); - const char *node_name = crm_element_value(xml_op, XML_ATTR_UNAME); - const char *exit_reason = crm_element_value(xml_op, - XML_LRM_ATTR_EXIT_REASON); - const char *exec_time = crm_element_value(xml_op, XML_RSC_OP_T_EXEC); + const char *op_key = pcmk__xe_history_key(xml_op); + const char *node_name = crm_element_value(xml_op, PCMK_XA_UNAME); + const char *exit_reason = crm_element_value(xml_op, PCMK_XA_EXIT_REASON); + const char *exec_time = crm_element_value(xml_op, PCMK_XA_EXEC_TIME); int rc; int status; - pcmk__scan_min_int(crm_element_value(xml_op, XML_LRM_ATTR_RC), &rc, 0); + pcmk__scan_min_int(crm_element_value(xml_op, PCMK__XA_RC_CODE), &rc, 0); - pcmk__scan_min_int(crm_element_value(xml_op, XML_LRM_ATTR_OPSTATUS), - &status, 0); + pcmk__scan_min_int(crm_element_value(xml_op, PCMK__XA_OP_STATUS), &status, + 0); if (pcmk__str_empty(node_name)) { node_name = "unknown node"; @@ -1478,44 +1570,60 @@ failed_action_default(pcmk__output_t *out, va_list args) return pcmk_rc_ok; } -PCMK__OUTPUT_ARGS("failed-action", "xmlNodePtr", "uint32_t") +PCMK__OUTPUT_ARGS("failed-action", "xmlNode *", "uint32_t") static int failed_action_xml(pcmk__output_t *out, va_list args) { xmlNodePtr xml_op = va_arg(args, xmlNodePtr); uint32_t show_opts G_GNUC_UNUSED = va_arg(args, uint32_t); - const char *op_key = pe__xe_history_key(xml_op); - const char *op_key_name = "op_key"; + const char *op_key = pcmk__xe_history_key(xml_op); + const char *op_key_name = PCMK_XA_OP_KEY; int rc; int status; - const char *exit_reason = crm_element_value(xml_op, XML_LRM_ATTR_EXIT_REASON); + const char *uname = crm_element_value(xml_op, PCMK_XA_UNAME); + const char *call_id = crm_element_value(xml_op, PCMK__XA_CALL_ID); + const char *exitstatus = NULL; + const char *exit_reason = pcmk__s(crm_element_value(xml_op, + PCMK_XA_EXIT_REASON), + "none"); + const char *status_s = NULL; time_t epoch = 0; + gchar *exit_reason_esc = NULL; char *rc_s = NULL; - char *reason_s = crm_xml_escape(exit_reason ? exit_reason : "none"); xmlNodePtr node = NULL; - pcmk__scan_min_int(crm_element_value(xml_op, XML_LRM_ATTR_RC), &rc, 0); - pcmk__scan_min_int(crm_element_value(xml_op, XML_LRM_ATTR_OPSTATUS), - &status, 0); + if (pcmk__xml_needs_escape(exit_reason, pcmk__xml_escape_attr)) { + exit_reason_esc = pcmk__xml_escape(exit_reason, pcmk__xml_escape_attr); + exit_reason = exit_reason_esc; + } + pcmk__scan_min_int(crm_element_value(xml_op, PCMK__XA_RC_CODE), &rc, 0); + pcmk__scan_min_int(crm_element_value(xml_op, PCMK__XA_OP_STATUS), &status, + 0); - rc_s = pcmk__itoa(rc); - if (crm_element_value(xml_op, XML_LRM_ATTR_TASK_KEY) == NULL) { - op_key_name = "id"; + if (crm_element_value(xml_op, PCMK__XA_OPERATION_KEY) == NULL) { + op_key_name = PCMK_XA_ID; } - node = pcmk__output_create_xml_node(out, "failure", + exitstatus = services_ocf_exitcode_str(rc); + rc_s = pcmk__itoa(rc); + status_s = pcmk_exec_status_str(status); + node = pcmk__output_create_xml_node(out, PCMK_XE_FAILURE, op_key_name, op_key, - "node", crm_element_value(xml_op, XML_ATTR_UNAME), - "exitstatus", services_ocf_exitcode_str(rc), - "exitreason", pcmk__s(reason_s, ""), - "exitcode", rc_s, - "call", crm_element_value(xml_op, XML_LRM_ATTR_CALLID), - "status", pcmk_exec_status_str(status), + PCMK_XA_NODE, uname, + PCMK_XA_EXITSTATUS, exitstatus, + PCMK_XA_EXITREASON, exit_reason, + PCMK_XA_EXITCODE, rc_s, + PCMK_XA_CALL, call_id, + PCMK_XA_STATUS, status_s, NULL); free(rc_s); - if ((crm_element_value_epoch(xml_op, XML_RSC_OP_LAST_CHANGE, + if ((crm_element_value_epoch(xml_op, PCMK_XA_LAST_RC_CHANGE, &epoch) == pcmk_ok) && (epoch > 0)) { + + const char *queue_time = crm_element_value(xml_op, PCMK_XA_QUEUE_TIME); + const char *exec = crm_element_value(xml_op, PCMK_XA_EXEC_TIME); + const char *task = crm_element_value(xml_op, PCMK_XA_OPERATION); guint interval_ms = 0; char *interval_ms_s = NULL; char *rc_change = pcmk__epoch2str(&epoch, @@ -1523,21 +1631,22 @@ failed_action_xml(pcmk__output_t *out, va_list args) { |crm_time_log_timeofday |crm_time_log_with_timezone); - crm_element_value_ms(xml_op, XML_LRM_ATTR_INTERVAL_MS, &interval_ms); + crm_element_value_ms(xml_op, PCMK_META_INTERVAL, &interval_ms); interval_ms_s = crm_strdup_printf("%u", interval_ms); - pcmk__xe_set_props(node, XML_RSC_OP_LAST_CHANGE, rc_change, - "queued", crm_element_value(xml_op, XML_RSC_OP_T_QUEUE), - "exec", crm_element_value(xml_op, XML_RSC_OP_T_EXEC), - "interval", interval_ms_s, - "task", crm_element_value(xml_op, XML_LRM_ATTR_TASK), + pcmk__xe_set_props(node, + PCMK_XA_LAST_RC_CHANGE, rc_change, + PCMK_XA_QUEUED, queue_time, + PCMK_XA_EXEC, exec, + PCMK_XA_INTERVAL, interval_ms_s, + PCMK_XA_TASK, task, NULL); free(interval_ms_s); free(rc_change); } - free(reason_s); + g_free(exit_reason_esc); return pcmk_rc_ok; } @@ -1558,11 +1667,13 @@ failed_action_list(pcmk__output_t *out, va_list args) { return rc; } - for (xml_op = pcmk__xml_first_child(scheduler->failed); xml_op != NULL; - xml_op = pcmk__xml_next(xml_op)) { + for (xml_op = pcmk__xe_first_child(scheduler->failed, NULL, NULL, NULL); + xml_op != NULL; xml_op = pcmk__xe_next(xml_op)) { + char *rsc = NULL; - if (!pcmk__str_in_list(crm_element_value(xml_op, XML_ATTR_UNAME), only_node, + if (!pcmk__str_in_list(crm_element_value(xml_op, PCMK_XA_UNAME), + only_node, pcmk__str_star_matches|pcmk__str_casei)) { continue; } @@ -1571,7 +1682,7 @@ failed_action_list(pcmk__output_t *out, va_list args) { continue; } - if (!parse_op_key(pe__xe_history_key(xml_op), &rsc, NULL, NULL)) { + if (!parse_op_key(pcmk__xe_history_key(xml_op), &rsc, NULL, NULL)) { continue; } @@ -1594,51 +1705,71 @@ static void status_node(pcmk_node_t *node, xmlNodePtr parent, uint32_t show_opts) { int health = pe__node_health(node); + xmlNode *child = NULL; // Cluster membership if (node->details->online) { - pcmk_create_html_node(parent, "span", NULL, "online", " online"); + child = pcmk__html_create(parent, PCMK__XE_SPAN, NULL, + PCMK_VALUE_ONLINE); + pcmk__xe_set_content(child, " online"); + } else { - pcmk_create_html_node(parent, "span", NULL, "offline", " OFFLINE"); + child = pcmk__html_create(parent, PCMK__XE_SPAN, NULL, + PCMK_VALUE_OFFLINE); + pcmk__xe_set_content(child, " OFFLINE"); } // Standby mode if (node->details->standby_onfail && (node->details->running_rsc != NULL)) { - pcmk_create_html_node(parent, "span", NULL, "standby", - " (in standby due to on-fail," - " with active resources)"); + child = pcmk__html_create(parent, PCMK__XE_SPAN, NULL, + PCMK_VALUE_STANDBY); + pcmk__xe_set_content(child, + " (in standby due to " PCMK_META_ON_FAIL "," + " with active resources)"); + } else if (node->details->standby_onfail) { - pcmk_create_html_node(parent, "span", NULL, "standby", - " (in standby due to on-fail)"); + child = pcmk__html_create(parent, PCMK__XE_SPAN, NULL, + PCMK_VALUE_STANDBY); + pcmk__xe_set_content(child, + " (in standby due to " PCMK_META_ON_FAIL ")"); + } else if (node->details->standby && (node->details->running_rsc != NULL)) { - pcmk_create_html_node(parent, "span", NULL, "standby", - " (in standby, with active resources)"); + child = pcmk__html_create(parent, PCMK__XE_SPAN, NULL, + PCMK_VALUE_STANDBY); + pcmk__xe_set_content(child, + " (in standby, with active resources)"); + } else if (node->details->standby) { - pcmk_create_html_node(parent, "span", NULL, "standby", " (in standby)"); + child = pcmk__html_create(parent, PCMK__XE_SPAN, NULL, + PCMK_VALUE_STANDBY); + pcmk__xe_set_content(child, " (in standby)"); } // Maintenance mode if (node->details->maintenance) { - pcmk_create_html_node(parent, "span", NULL, "maint", - " (in maintenance mode)"); + child = pcmk__html_create(parent, PCMK__XE_SPAN, NULL, + PCMK__VALUE_MAINT); + pcmk__xe_set_content(child, " (in maintenance mode)"); } // Node health if (health < 0) { - pcmk_create_html_node(parent, "span", NULL, "health_red", - " (health is RED)"); + child = pcmk__html_create(parent, PCMK__XE_SPAN, NULL, + PCMK__VALUE_HEALTH_RED); + pcmk__xe_set_content(child, " (health is RED)"); + } else if (health == 0) { - pcmk_create_html_node(parent, "span", NULL, "health_yellow", - " (health is YELLOW)"); + child = pcmk__html_create(parent, PCMK__XE_SPAN, NULL, + PCMK__VALUE_HEALTH_YELLOW); + pcmk__xe_set_content(child, " (health is YELLOW)"); } // Feature set if (pcmk_is_set(show_opts, pcmk_show_feature_set)) { const char *feature_set = get_node_feature_set(node); if (feature_set != NULL) { - char *buf = crm_strdup_printf(", feature set %s", feature_set); - pcmk_create_html_node(parent, "span", NULL, NULL, buf); - free(buf); + child = pcmk__html_create(parent, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, ", feature set %s", feature_set); } } } @@ -1656,14 +1787,16 @@ node_html(pcmk__output_t *out, va_list args) { char *node_name = pe__node_display_name(node, pcmk_is_set(show_opts, pcmk_show_node_id)); if (full) { - xmlNodePtr item_node; + xmlNode *item_node = NULL; + xmlNode *child = NULL; if (pcmk_all_flags_set(show_opts, pcmk_show_brief | pcmk_show_rscs_by_node)) { GList *rscs = pe__filter_rsc_list(node->details->running_rsc, only_rsc); out->begin_list(out, NULL, NULL, "%s:", node_name); item_node = pcmk__output_xml_create_parent(out, "li", NULL); - pcmk_create_html_node(item_node, "span", NULL, NULL, "Status:"); + child = pcmk__html_create(item_node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, "Status:"); status_node(node, item_node, show_opts); if (rscs != NULL) { @@ -1682,7 +1815,8 @@ node_html(pcmk__output_t *out, va_list args) { out->begin_list(out, NULL, NULL, "%s:", node_name); item_node = pcmk__output_xml_create_parent(out, "li", NULL); - pcmk_create_html_node(item_node, "span", NULL, NULL, "Status:"); + child = pcmk__html_create(item_node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, "Status:"); status_node(node, item_node, show_opts); for (lpc2 = node->details->running_rsc; lpc2 != NULL; lpc2 = lpc2->next) { @@ -1690,7 +1824,7 @@ node_html(pcmk__output_t *out, va_list args) { PCMK__OUTPUT_LIST_HEADER(out, false, rc, "Resources"); show_opts |= pcmk_show_rsc_only; - out->message(out, crm_map_element_name(rsc->xml), show_opts, + out->message(out, pcmk__map_element_name(rsc->xml), show_opts, rsc, only_node, only_rsc); } @@ -1699,13 +1833,11 @@ node_html(pcmk__output_t *out, va_list args) { out->end_list(out); } else { - char *buf = crm_strdup_printf("%s:", node_name); - item_node = pcmk__output_create_xml_node(out, "li", NULL); - pcmk_create_html_node(item_node, "span", NULL, "bold", buf); + child = pcmk__html_create(item_node, PCMK__XE_SPAN, NULL, + PCMK__VALUE_BOLD); + pcmk__xe_set_content(child, "%s:", node_name); status_node(node, item_node, show_opts); - - free(buf); } } else { out->begin_list(out, NULL, NULL, "%s:", node_name); @@ -1741,7 +1873,7 @@ node_text_status(const pcmk_node_t *node) return "pending"; } else if (node->details->standby_onfail && node->details->online) { - return "standby (on-fail)"; + return "standby (" PCMK_META_ON_FAIL ")"; } else if (node->details->standby) { if (node->details->online) { @@ -1784,9 +1916,9 @@ node_text(pcmk__output_t *out, va_list args) { int health = pe__node_health(node); // Create a summary line with node type, name, and status - if (pe__is_guest_node(node)) { + if (pcmk__is_guest_or_bundle_node(node)) { g_string_append(str, "GuestNode"); - } else if (pe__is_remote_node(node)) { + } else if (pcmk__is_remote_node(node)) { g_string_append(str, "RemoteNode"); } else { g_string_append(str, "Node"); @@ -1833,8 +1965,8 @@ node_text(pcmk__output_t *out, va_list args) { pcmk_resource_t *rsc = (pcmk_resource_t *) gIter2->data; show_opts |= pcmk_show_rsc_only; - out->message(out, crm_map_element_name(rsc->xml), show_opts, - rsc, only_node, only_rsc); + out->message(out, pcmk__map_element_name(rsc->xml), + show_opts, rsc, only_node, only_rsc); } out->end_list(out); @@ -1855,6 +1987,54 @@ node_text(pcmk__output_t *out, va_list args) { return pcmk_rc_ok; } +/*! + * \internal + * \brief Convert an integer health value to a string representation + * + * \param[in] health Integer health value + * + * \retval \c PCMK_VALUE_RED if \p health is less than 0 + * \retval \c PCMK_VALUE_YELLOW if \p health is equal to 0 + * \retval \c PCMK_VALUE_GREEN if \p health is greater than 0 + */ +static const char * +health_text(int health) +{ + if (health < 0) { + return PCMK_VALUE_RED; + } else if (health == 0) { + return PCMK_VALUE_YELLOW; + } else { + return PCMK_VALUE_GREEN; + } +} + +/*! + * \internal + * \brief Convert a node type to a string representation + * + * \param[in] type Node type + * + * \retval \c PCMK_VALUE_MEMBER if \p node_type is \c pcmk_node_variant_cluster + * \retval \c PCMK_VALUE_REMOTE if \p node_type is \c pcmk_node_variant_remote + * \retval \c PCMK__VALUE_PING if \p node_type is \c node_ping + * \retval \c PCMK_VALUE_UNKNOWN otherwise + */ +static const char * +node_type_str(enum node_type type) +{ + switch (type) { + case pcmk_node_variant_cluster: + return PCMK_VALUE_MEMBER; + case pcmk_node_variant_remote: + return PCMK_VALUE_REMOTE; + case node_ping: + return PCMK__VALUE_PING; + default: + return PCMK_VALUE_UNKNOWN; + } +} + PCMK__OUTPUT_ARGS("node", "pcmk_node_t *", "uint32_t", "bool", "GList *", "GList *") static int @@ -1866,54 +2046,48 @@ node_xml(pcmk__output_t *out, va_list args) { GList *only_rsc = va_arg(args, GList *); if (full) { - const char *node_type = "unknown"; - char *length_s = pcmk__itoa(g_list_length(node->details->running_rsc)); - int health = pe__node_health(node); - const char *health_s = NULL; - const char *feature_set; - - switch (node->details->type) { - case pcmk_node_variant_cluster: - node_type = "member"; - break; - case pcmk_node_variant_remote: - node_type = "remote"; - break; - case node_ping: - node_type = "ping"; - break; - } - - if (health < 0) { - health_s = "red"; - } else if (health == 0) { - health_s = "yellow"; - } else { - health_s = "green"; - } - - feature_set = get_node_feature_set(node); - - pe__name_and_nvpairs_xml(out, true, "node", 15, - "name", node->details->uname, - "id", node->details->id, - "online", pcmk__btoa(node->details->online), - "standby", pcmk__btoa(node->details->standby), - "standby_onfail", pcmk__btoa(node->details->standby_onfail), - "maintenance", pcmk__btoa(node->details->maintenance), - "pending", pcmk__btoa(node->details->pending), - "unclean", pcmk__btoa(node->details->unclean), - "health", health_s, - "feature_set", feature_set, - "shutdown", pcmk__btoa(node->details->shutdown), - "expected_up", pcmk__btoa(node->details->expected_up), - "is_dc", pcmk__btoa(node->details->is_dc), - "resources_running", length_s, - "type", node_type); - - if (pe__is_guest_node(node)) { + const char *online = pcmk__btoa(node->details->online); + const char *standby = pcmk__btoa(node->details->standby); + const char *standby_onfail = pcmk__btoa(node->details->standby_onfail); + const char *maintenance = pcmk__btoa(node->details->maintenance); + const char *pending = pcmk__btoa(node->details->pending); + const char *unclean = pcmk__btoa(node->details->unclean); + const char *health = health_text(pe__node_health(node)); + const char *feature_set = get_node_feature_set(node); + const char *shutdown = pcmk__btoa(node->details->shutdown); + const char *expected_up = pcmk__btoa(node->details->expected_up); + const char *is_dc = pcmk__btoa(node->details->is_dc); + int length = g_list_length(node->details->running_rsc); + char *resources_running = pcmk__itoa(length); + const char *node_type = node_type_str(node->details->type); + + int rc = pcmk_rc_ok; + + rc = pe__name_and_nvpairs_xml(out, true, PCMK_XE_NODE, + PCMK_XA_NAME, node->details->uname, + PCMK_XA_ID, node->details->id, + PCMK_XA_ONLINE, online, + PCMK_XA_STANDBY, standby, + PCMK_XA_STANDBY_ONFAIL, standby_onfail, + PCMK_XA_MAINTENANCE, maintenance, + PCMK_XA_PENDING, pending, + PCMK_XA_UNCLEAN, unclean, + PCMK_XA_HEALTH, health, + PCMK_XA_FEATURE_SET, feature_set, + PCMK_XA_SHUTDOWN, shutdown, + PCMK_XA_EXPECTED_UP, expected_up, + PCMK_XA_IS_DC, is_dc, + PCMK_XA_RESOURCES_RUNNING, resources_running, + PCMK_XA_TYPE, node_type, + NULL); + + free(resources_running); + CRM_ASSERT(rc == pcmk_rc_ok); + + if (pcmk__is_guest_or_bundle_node(node)) { xmlNodePtr xml_node = pcmk__output_xml_peek_parent(out); - crm_xml_add(xml_node, "id_as_resource", node->details->remote_rsc->container->id); + crm_xml_add(xml_node, PCMK_XA_ID_AS_RESOURCE, + node->details->remote_rsc->container->id); } if (pcmk_is_set(show_opts, pcmk_show_rscs_by_node)) { @@ -1923,17 +2097,15 @@ node_xml(pcmk__output_t *out, va_list args) { pcmk_resource_t *rsc = (pcmk_resource_t *) lpc->data; show_opts |= pcmk_show_rsc_only; - out->message(out, crm_map_element_name(rsc->xml), show_opts, + out->message(out, pcmk__map_element_name(rsc->xml), show_opts, rsc, only_node, only_rsc); } } - free(length_s); - out->end_list(out); } else { - pcmk__output_xml_create_parent(out, "node", - "name", node->details->uname, + pcmk__output_xml_create_parent(out, PCMK_XE_NODE, + PCMK_XA_NAME, node->details->uname, NULL); } @@ -1979,25 +2151,28 @@ node_attribute_html(pcmk__output_t *out, va_list args) { int expected_score = va_arg(args, int); if (add_extra) { - int v; - char *s = crm_strdup_printf("%s: %s", name, value); + int v = 0; xmlNodePtr item_node = pcmk__output_create_xml_node(out, "li", NULL); + xmlNode *child = NULL; - if (value == NULL) { - v = 0; - } else { + if (value != NULL) { pcmk__scan_min_int(value, &v, INT_MIN); } - pcmk_create_html_node(item_node, "span", NULL, NULL, s); - free(s); + child = pcmk__html_create(item_node, PCMK__XE_SPAN, NULL, NULL); + pcmk__xe_set_content(child, "%s: %s", name, value); if (v <= 0) { - pcmk_create_html_node(item_node, "span", NULL, "bold", "(connectivity is lost)"); + child = pcmk__html_create(item_node, PCMK__XE_SPAN, NULL, + PCMK__VALUE_BOLD); + pcmk__xe_set_content(child, "(connectivity is lost)"); + } else if (v < expected_score) { - char *buf = crm_strdup_printf("(connectivity is degraded -- expected %d", expected_score); - pcmk_create_html_node(item_node, "span", NULL, "bold", buf); - free(buf); + child = pcmk__html_create(item_node, PCMK__XE_SPAN, NULL, + PCMK__VALUE_BOLD); + pcmk__xe_set_content(child, + "(connectivity is degraded -- expected %d)", + expected_score); } } else { out->list_item(out, NULL, "%s: %s", name, value); @@ -2006,7 +2181,7 @@ node_attribute_html(pcmk__output_t *out, va_list args) { return pcmk_rc_ok; } -PCMK__OUTPUT_ARGS("node-and-op", "pcmk_scheduler_t *", "xmlNodePtr") +PCMK__OUTPUT_ARGS("node-and-op", "pcmk_scheduler_t *", "xmlNode *") static int node_and_op(pcmk__output_t *out, va_list args) { pcmk_scheduler_t *scheduler = va_arg(args, pcmk_scheduler_t *); @@ -2016,18 +2191,19 @@ node_and_op(pcmk__output_t *out, va_list args) { gchar *node_str = NULL; char *last_change_str = NULL; - const char *op_rsc = crm_element_value(xml_op, "resource"); + const char *op_rsc = crm_element_value(xml_op, PCMK_XA_RESOURCE); int status; time_t last_change = 0; - pcmk__scan_min_int(crm_element_value(xml_op, XML_LRM_ATTR_OPSTATUS), - &status, PCMK_EXEC_UNKNOWN); + pcmk__scan_min_int(crm_element_value(xml_op, PCMK__XA_OP_STATUS), &status, + PCMK_EXEC_UNKNOWN); rsc = pe_find_resource(scheduler->resources, op_rsc); if (rsc) { - const pcmk_node_t *node = pe__current_node(rsc); - const char *target_role = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_TARGET_ROLE); + const pcmk_node_t *node = pcmk__current_node(rsc); + const char *target_role = g_hash_table_lookup(rsc->meta, + PCMK_META_TARGET_ROLE); uint32_t show_opts = pcmk_show_rsc_only | pcmk_show_pending; if (node == NULL) { @@ -2040,19 +2216,21 @@ node_and_op(pcmk__output_t *out, va_list args) { node_str = crm_strdup_printf("Unknown resource %s", op_rsc); } - if (crm_element_value_epoch(xml_op, XML_RSC_OP_LAST_CHANGE, + if (crm_element_value_epoch(xml_op, PCMK_XA_LAST_RC_CHANGE, &last_change) == pcmk_ok) { + const char *exec_time = crm_element_value(xml_op, PCMK_XA_EXEC_TIME); + last_change_str = crm_strdup_printf(", %s='%s', exec=%sms", - XML_RSC_OP_LAST_CHANGE, + PCMK_XA_LAST_RC_CHANGE, pcmk__trim(ctime(&last_change)), - crm_element_value(xml_op, XML_RSC_OP_T_EXEC)); + exec_time); } out->list_item(out, NULL, "%s: %s (node=%s, call=%s, rc=%s%s): %s", - node_str, pe__xe_history_key(xml_op), - crm_element_value(xml_op, XML_ATTR_UNAME), - crm_element_value(xml_op, XML_LRM_ATTR_CALLID), - crm_element_value(xml_op, XML_LRM_ATTR_RC), + node_str, pcmk__xe_history_key(xml_op), + crm_element_value(xml_op, PCMK_XA_UNAME), + crm_element_value(xml_op, PCMK__XA_CALL_ID), + crm_element_value(xml_op, PCMK__XA_RC_CODE), last_change_str ? last_change_str : "", pcmk_exec_status_str(status)); @@ -2061,50 +2239,63 @@ node_and_op(pcmk__output_t *out, va_list args) { return pcmk_rc_ok; } -PCMK__OUTPUT_ARGS("node-and-op", "pcmk_scheduler_t *", "xmlNodePtr") +PCMK__OUTPUT_ARGS("node-and-op", "pcmk_scheduler_t *", "xmlNode *") static int node_and_op_xml(pcmk__output_t *out, va_list args) { pcmk_scheduler_t *scheduler = va_arg(args, pcmk_scheduler_t *); xmlNodePtr xml_op = va_arg(args, xmlNodePtr); pcmk_resource_t *rsc = NULL; - const char *op_rsc = crm_element_value(xml_op, "resource"); + const char *uname = crm_element_value(xml_op, PCMK_XA_UNAME); + const char *call_id = crm_element_value(xml_op, PCMK__XA_CALL_ID); + const char *rc_s = crm_element_value(xml_op, PCMK__XA_RC_CODE); + const char *status_s = NULL; + const char *op_rsc = crm_element_value(xml_op, PCMK_XA_RESOURCE); int status; time_t last_change = 0; xmlNode *node = NULL; - pcmk__scan_min_int(crm_element_value(xml_op, XML_LRM_ATTR_OPSTATUS), + pcmk__scan_min_int(crm_element_value(xml_op, PCMK__XA_OP_STATUS), &status, PCMK_EXEC_UNKNOWN); - node = pcmk__output_create_xml_node(out, "operation", - "op", pe__xe_history_key(xml_op), - "node", crm_element_value(xml_op, XML_ATTR_UNAME), - "call", crm_element_value(xml_op, XML_LRM_ATTR_CALLID), - "rc", crm_element_value(xml_op, XML_LRM_ATTR_RC), - "status", pcmk_exec_status_str(status), + status_s = pcmk_exec_status_str(status); + + node = pcmk__output_create_xml_node(out, PCMK_XE_OPERATION, + PCMK_XA_OP, pcmk__xe_history_key(xml_op), + PCMK_XA_NODE, uname, + PCMK_XA_CALL, call_id, + PCMK_XA_RC, rc_s, + PCMK_XA_STATUS, status_s, NULL); rsc = pe_find_resource(scheduler->resources, op_rsc); if (rsc) { - const char *class = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS); - const char *kind = crm_element_value(rsc->xml, XML_ATTR_TYPE); - char *agent_tuple = NULL; - - agent_tuple = crm_strdup_printf("%s:%s:%s", class, - pcmk_is_set(pcmk_get_ra_caps(class), pcmk_ra_cap_provider) ? crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER) : "", - kind); - - pcmk__xe_set_props(node, "rsc", rsc_printable_id(rsc), - "agent", agent_tuple, + const char *class = crm_element_value(rsc->xml, PCMK_XA_CLASS); + const char *provider = crm_element_value(rsc->xml, PCMK_XA_PROVIDER); + const char *kind = crm_element_value(rsc->xml, PCMK_XA_TYPE); + bool has_provider = pcmk_is_set(pcmk_get_ra_caps(class), + pcmk_ra_cap_provider); + + char *agent_tuple = crm_strdup_printf("%s:%s:%s", + class, + (has_provider? provider : ""), + kind); + + pcmk__xe_set_props(node, + PCMK_XA_RSC, rsc_printable_id(rsc), + PCMK_XA_AGENT, agent_tuple, NULL); free(agent_tuple); } - if (crm_element_value_epoch(xml_op, XML_RSC_OP_LAST_CHANGE, + if (crm_element_value_epoch(xml_op, PCMK_XA_LAST_RC_CHANGE, &last_change) == pcmk_ok) { - pcmk__xe_set_props(node, XML_RSC_OP_LAST_CHANGE, - pcmk__trim(ctime(&last_change)), - XML_RSC_OP_T_EXEC, crm_element_value(xml_op, XML_RSC_OP_T_EXEC), + const char *last_rc_change = pcmk__trim(ctime(&last_change)); + const char *exec_time = crm_element_value(xml_op, PCMK_XA_EXEC_TIME); + + pcmk__xe_set_props(node, + PCMK_XA_LAST_RC_CHANGE, last_rc_change, + PCMK_XA_EXEC_TIME, exec_time, NULL); } @@ -2119,14 +2310,14 @@ node_attribute_xml(pcmk__output_t *out, va_list args) { bool add_extra = va_arg(args, int); int expected_score = va_arg(args, int); - xmlNodePtr node = pcmk__output_create_xml_node(out, "attribute", - "name", name, - "value", value, + xmlNodePtr node = pcmk__output_create_xml_node(out, PCMK_XE_ATTRIBUTE, + PCMK_XA_NAME, name, + PCMK_XA_VALUE, value, NULL); if (add_extra) { char *buf = pcmk__itoa(expected_score); - crm_xml_add(node, "expected", buf); + crm_xml_add(node, PCMK_XA_EXPECTED, buf); free(buf); } @@ -2181,7 +2372,7 @@ node_attribute_list(pcmk__output_t *out, va_list args) { int expected_score = 0; bool add_extra = false; - value = pe_node_attribute_raw(node, name); + value = pcmk__node_attr(node, name, NULL, pcmk__rsc_node_current); add_extra = add_extra_info(node, node->details->running_rsc, scheduler, name, &expected_score); @@ -2207,7 +2398,7 @@ node_capacity(pcmk__output_t *out, va_list args) const char *comment = va_arg(args, const char *); char *dump_text = crm_strdup_printf("%s: %s capacity:", - comment, pe__node_name(node)); + comment, pcmk__node_name(node)); g_hash_table_foreach(node->details->utilization, append_dump_text, &dump_text); out->list_item(out, NULL, "%s", dump_text); @@ -2221,11 +2412,12 @@ static int node_capacity_xml(pcmk__output_t *out, va_list args) { const pcmk_node_t *node = va_arg(args, pcmk_node_t *); + const char *uname = node->details->uname; const char *comment = va_arg(args, const char *); - xmlNodePtr xml_node = pcmk__output_create_xml_node(out, "capacity", - "node", node->details->uname, - "comment", comment, + xmlNodePtr xml_node = pcmk__output_create_xml_node(out, PCMK_XE_CAPACITY, + PCMK_XA_NODE, uname, + PCMK_XA_COMMENT, comment, NULL); g_hash_table_foreach(node->details->utilization, add_dump_node, xml_node); @@ -2233,7 +2425,7 @@ node_capacity_xml(pcmk__output_t *out, va_list args) } PCMK__OUTPUT_ARGS("node-history-list", "pcmk_scheduler_t *", "pcmk_node_t *", - "xmlNodePtr", "GList *", "GList *", "uint32_t", "uint32_t") + "xmlNode *", "GList *", "GList *", "uint32_t", "uint32_t") static int node_history_list(pcmk__output_t *out, va_list args) { pcmk_scheduler_t *scheduler = va_arg(args, pcmk_scheduler_t *); @@ -2248,13 +2440,15 @@ node_history_list(pcmk__output_t *out, va_list args) { xmlNode *rsc_entry = NULL; int rc = pcmk_rc_no_output; - lrm_rsc = find_xml_node(node_state, XML_CIB_TAG_LRM, FALSE); - lrm_rsc = find_xml_node(lrm_rsc, XML_LRM_TAG_RESOURCES, FALSE); + lrm_rsc = pcmk__xe_first_child(node_state, PCMK__XE_LRM, NULL, NULL); + lrm_rsc = pcmk__xe_first_child(lrm_rsc, PCMK__XE_LRM_RESOURCES, NULL, NULL); /* Print history of each of the node's resources */ - for (rsc_entry = first_named_child(lrm_rsc, XML_LRM_TAG_RESOURCE); - rsc_entry != NULL; rsc_entry = crm_next_same_xml(rsc_entry)) { - const char *rsc_id = crm_element_value(rsc_entry, XML_ATTR_ID); + for (rsc_entry = pcmk__xe_first_child(lrm_rsc, PCMK__XE_LRM_RESOURCE, NULL, + NULL); + rsc_entry != NULL; rsc_entry = pcmk__xe_next_same(rsc_entry)) { + + const char *rsc_id = crm_element_value(rsc_entry, PCMK_XA_ID); pcmk_resource_t *rsc = pe_find_resource(scheduler->resources, rsc_id); const pcmk_resource_t *parent = pe__const_top_resource(rsc, false); @@ -2266,7 +2460,7 @@ node_history_list(pcmk__output_t *out, va_list args) { * * For other resource types, is_filtered is okay. */ - if (parent->variant == pcmk_rsc_variant_group) { + if (pcmk__is_group(parent)) { if (!pcmk__str_in_list(rsc_printable_id(rsc), only_rsc, pcmk__str_star_matches) && !pcmk__str_in_list(rsc_printable_id(parent), only_rsc, @@ -2298,13 +2492,15 @@ node_history_list(pcmk__output_t *out, va_list args) { failcount, last_failure, false); } else { GList *op_list = get_operation_list(rsc_entry); - pcmk_resource_t *rsc = pe_find_resource(scheduler->resources, - crm_element_value(rsc_entry, XML_ATTR_ID)); + pcmk_resource_t *rsc = NULL; if (op_list == NULL) { continue; } + rsc = pe_find_resource(scheduler->resources, + crm_element_value(rsc_entry, PCMK_XA_ID)); + if (rc == pcmk_rc_no_output) { rc = pcmk_rc_ok; out->message(out, "node", node, show_opts, false, only_node, @@ -2389,10 +2585,10 @@ node_list_text(pcmk__output_t *out, va_list args) { } else if (node->details->online) { // Display online node in a list - if (pe__is_guest_node(node)) { + if (pcmk__is_guest_or_bundle_node(node)) { pcmk__add_word(&online_guest_nodes, 1024, node_name); - } else if (pe__is_remote_node(node)) { + } else if (pcmk__is_remote_node(node)) { pcmk__add_word(&online_remote_nodes, 1024, node_name); } else { @@ -2403,10 +2599,10 @@ node_list_text(pcmk__output_t *out, va_list args) { } else { // Display offline node in a list - if (pe__is_remote_node(node)) { + if (pcmk__is_remote_node(node)) { pcmk__add_word(&offline_remote_nodes, 1024, node_name); - } else if (pe__is_guest_node(node)) { + } else if (pcmk__is_guest_or_bundle_node(node)) { /* ignore offline guest nodes */ } else { @@ -2461,7 +2657,11 @@ node_list_xml(pcmk__output_t *out, va_list args) { uint32_t show_opts = va_arg(args, uint32_t); bool print_spacer G_GNUC_UNUSED = va_arg(args, int); - out->begin_list(out, NULL, NULL, "nodes"); + /* PCMK_XE_NODES acts as the list's element name for CLI tools that use + * pcmk__output_enable_list_element. Otherwise PCMK_XE_NODES is the + * value of the list's PCMK_XA_NAME attribute. + */ + out->begin_list(out, NULL, NULL, PCMK_XE_NODES); for (GList *gIter = nodes; gIter != NULL; gIter = gIter->next) { pcmk_node_t *node = (pcmk_node_t *) gIter->data; @@ -2490,16 +2690,19 @@ node_summary(pcmk__output_t *out, va_list args) { xmlNode *node_state = NULL; xmlNode *cib_status = pcmk_find_cib_element(scheduler->input, - XML_CIB_TAG_STATUS); + PCMK_XE_STATUS); int rc = pcmk_rc_no_output; if (xmlChildElementCount(cib_status) == 0) { return rc; } - for (node_state = first_named_child(cib_status, XML_CIB_TAG_STATE); - node_state != NULL; node_state = crm_next_same_xml(node_state)) { - pcmk_node_t *node = pe_find_node_id(scheduler->nodes, ID(node_state)); + for (node_state = pcmk__xe_first_child(cib_status, PCMK__XE_NODE_STATE, + NULL, NULL); + node_state != NULL; node_state = pcmk__xe_next_same(node_state)) { + + pcmk_node_t *node = pe_find_node_id(scheduler->nodes, + pcmk__xe_id(node_state)); if (!node || !node->details || !node->details->online) { continue; @@ -2551,20 +2754,20 @@ node_weight_xml(pcmk__output_t *out, va_list args) const char *uname = va_arg(args, const char *); const char *score = va_arg(args, const char *); - xmlNodePtr node = pcmk__output_create_xml_node(out, "node_weight", - "function", prefix, - "node", uname, - "score", score, + xmlNodePtr node = pcmk__output_create_xml_node(out, PCMK_XE_NODE_WEIGHT, + PCMK_XA_FUNCTION, prefix, + PCMK_XA_NODE, uname, + PCMK_XA_SCORE, score, NULL); if (rsc) { - crm_xml_add(node, "id", rsc->id); + crm_xml_add(node, PCMK_XA_ID, rsc->id); } return pcmk_rc_ok; } -PCMK__OUTPUT_ARGS("op-history", "xmlNodePtr", "const char *", "const char *", "int", "uint32_t") +PCMK__OUTPUT_ARGS("op-history", "xmlNode *", "const char *", "const char *", "int", "uint32_t") static int op_history_text(pcmk__output_t *out, va_list args) { xmlNodePtr xml_op = va_arg(args, xmlNodePtr); @@ -2582,7 +2785,7 @@ op_history_text(pcmk__output_t *out, va_list args) { return pcmk_rc_ok; } -PCMK__OUTPUT_ARGS("op-history", "xmlNodePtr", "const char *", "const char *", "int", "uint32_t") +PCMK__OUTPUT_ARGS("op-history", "xmlNode *", "const char *", "const char *", "int", "uint32_t") static int op_history_xml(pcmk__output_t *out, va_list args) { xmlNodePtr xml_op = va_arg(args, xmlNodePtr); @@ -2591,18 +2794,22 @@ op_history_xml(pcmk__output_t *out, va_list args) { int rc = va_arg(args, int); uint32_t show_opts = va_arg(args, uint32_t); + const char *call_id = crm_element_value(xml_op, PCMK__XA_CALL_ID); char *rc_s = pcmk__itoa(rc); - xmlNodePtr node = pcmk__output_create_xml_node(out, "operation_history", - "call", crm_element_value(xml_op, XML_LRM_ATTR_CALLID), - "task", task, - "rc", rc_s, - "rc_text", services_ocf_exitcode_str(rc), - NULL); + const char *rc_text = services_ocf_exitcode_str(rc); + xmlNodePtr node = NULL; + + node = pcmk__output_create_xml_node(out, PCMK_XE_OPERATION_HISTORY, + PCMK_XA_CALL, call_id, + PCMK_XA_TASK, task, + PCMK_XA_RC, rc_s, + PCMK_XA_RC_TEXT, rc_text, + NULL); free(rc_s); if (interval_ms_s && !pcmk__str_eq(interval_ms_s, "0", pcmk__str_casei)) { char *s = crm_strdup_printf("%sms", interval_ms_s); - crm_xml_add(node, "interval", s); + crm_xml_add(node, PCMK_XA_INTERVAL, s); free(s); } @@ -2610,23 +2817,23 @@ op_history_xml(pcmk__output_t *out, va_list args) { const char *value = NULL; time_t epoch = 0; - if ((crm_element_value_epoch(xml_op, XML_RSC_OP_LAST_CHANGE, + if ((crm_element_value_epoch(xml_op, PCMK_XA_LAST_RC_CHANGE, &epoch) == pcmk_ok) && (epoch > 0)) { char *s = pcmk__epoch2str(&epoch, 0); - crm_xml_add(node, XML_RSC_OP_LAST_CHANGE, s); + crm_xml_add(node, PCMK_XA_LAST_RC_CHANGE, s); free(s); } - value = crm_element_value(xml_op, XML_RSC_OP_T_EXEC); + value = crm_element_value(xml_op, PCMK_XA_EXEC_TIME); if (value) { char *s = crm_strdup_printf("%sms", value); - crm_xml_add(node, XML_RSC_OP_T_EXEC, s); + crm_xml_add(node, PCMK_XA_EXEC_TIME, s); free(s); } - value = crm_element_value(xml_op, XML_RSC_OP_T_QUEUE); + value = crm_element_value(xml_op, PCMK_XA_QUEUE_TIME); if (value) { char *s = crm_strdup_printf("%sms", value); - crm_xml_add(node, XML_RSC_OP_T_QUEUE, s); + crm_xml_add(node, PCMK_XA_QUEUE_TIME, s); free(s); } } @@ -2659,13 +2866,13 @@ promotion_score_xml(pcmk__output_t *out, va_list args) pcmk_node_t *chosen = va_arg(args, pcmk_node_t *); const char *score = va_arg(args, const char *); - xmlNodePtr node = pcmk__output_create_xml_node(out, "promotion_score", - "id", child_rsc->id, - "score", score, + xmlNodePtr node = pcmk__output_create_xml_node(out, PCMK_XE_PROMOTION_SCORE, + PCMK_XA_ID, child_rsc->id, + PCMK_XA_SCORE, score, NULL); if (chosen) { - crm_xml_add(node, "node", chosen->details->uname); + crm_xml_add(node, PCMK_XA_NODE, chosen->details->uname); } return pcmk_rc_ok; @@ -2675,29 +2882,22 @@ PCMK__OUTPUT_ARGS("resource-config", "const pcmk_resource_t *", "bool") static int resource_config(pcmk__output_t *out, va_list args) { const pcmk_resource_t *rsc = va_arg(args, const pcmk_resource_t *); + GString *xml_buf = g_string_sized_new(1024); bool raw = va_arg(args, int); - char *rsc_xml = formatted_xml_buf(rsc, raw); + formatted_xml_buf(rsc, xml_buf, raw); - out->output_xml(out, "xml", rsc_xml); + out->output_xml(out, PCMK_XE_XML, xml_buf->str); - free(rsc_xml); + g_string_free(xml_buf, TRUE); return pcmk_rc_ok; } PCMK__OUTPUT_ARGS("resource-config", "const pcmk_resource_t *", "bool") static int resource_config_text(pcmk__output_t *out, va_list args) { - const pcmk_resource_t *rsc = va_arg(args, const pcmk_resource_t *); - bool raw = va_arg(args, int); - - char *rsc_xml = formatted_xml_buf(rsc, raw); - pcmk__formatted_printf(out, "Resource XML:\n"); - out->output_xml(out, "xml", rsc_xml); - - free(rsc_xml); - return pcmk_rc_ok; + return resource_config(out, args); } PCMK__OUTPUT_ARGS("resource-history", "pcmk_resource_t *", "const char *", @@ -2734,31 +2934,33 @@ resource_history_xml(pcmk__output_t *out, va_list args) { time_t last_failure = va_arg(args, time_t); bool as_header = va_arg(args, int); - xmlNodePtr node = pcmk__output_xml_create_parent(out, "resource_history", - "id", rsc_id, + xmlNodePtr node = pcmk__output_xml_create_parent(out, + PCMK_XE_RESOURCE_HISTORY, + PCMK_XA_ID, rsc_id, NULL); if (rsc == NULL) { - pcmk__xe_set_bool_attr(node, "orphan", true); + pcmk__xe_set_bool_attr(node, PCMK_XA_ORPHAN, true); } else if (all || failcount || last_failure > 0) { char *migration_s = pcmk__itoa(rsc->migration_threshold); - pcmk__xe_set_props(node, "orphan", "false", - "migration-threshold", migration_s, + pcmk__xe_set_props(node, + PCMK_XA_ORPHAN, PCMK_VALUE_FALSE, + PCMK_META_MIGRATION_THRESHOLD, migration_s, NULL); free(migration_s); if (failcount > 0) { char *s = pcmk__itoa(failcount); - crm_xml_add(node, PCMK__FAIL_COUNT_PREFIX, s); + crm_xml_add(node, PCMK_XA_FAIL_COUNT, s); free(s); } if (last_failure > 0) { char *s = pcmk__epoch2str(&last_failure, 0); - crm_xml_add(node, PCMK__LAST_FAILURE_PREFIX, s); + crm_xml_add(node, PCMK_XA_LAST_FAILURE, s); free(s); } } @@ -2843,7 +3045,7 @@ resource_list(pcmk__output_t *out, va_list args) /* Skip primitives already counted in a brief summary */ } else if (pcmk_is_set(show_opts, pcmk_show_brief) - && (rsc->variant == pcmk_rsc_variant_primitive)) { + && pcmk__is_primitive(rsc)) { continue; /* Skip resources that aren't at least partially active, @@ -2863,7 +3065,7 @@ resource_list(pcmk__output_t *out, va_list args) } /* Print this resource */ - x = out->message(out, crm_map_element_name(rsc->xml), show_opts, rsc, + x = out->message(out, pcmk__map_element_name(rsc->xml), show_opts, rsc, only_node, only_rsc); if (x == pcmk_rc_ok) { rc = pcmk_rc_ok; @@ -2911,10 +3113,10 @@ resource_operation_list(pcmk__output_t *out, va_list args) /* Print each operation */ for (gIter = op_list; gIter != NULL; gIter = gIter->next) { xmlNode *xml_op = (xmlNode *) gIter->data; - const char *task = crm_element_value(xml_op, XML_LRM_ATTR_TASK); + const char *task = crm_element_value(xml_op, PCMK_XA_OPERATION); const char *interval_ms_s = crm_element_value(xml_op, - XML_LRM_ATTR_INTERVAL_MS); - const char *op_rc = crm_element_value(xml_op, XML_LRM_ATTR_RC); + PCMK_META_INTERVAL); + const char *op_rc = crm_element_value(xml_op, PCMK__XA_RC_CODE); int op_rc_i; pcmk__scan_min_int(op_rc, &op_rc_i, 0); @@ -2958,7 +3160,7 @@ resource_util(pcmk__output_t *out, va_list args) const char *fn = va_arg(args, const char *); char *dump_text = crm_strdup_printf("%s: %s utilization on %s:", - fn, rsc->id, pe__node_name(node)); + fn, rsc->id, pcmk__node_name(node)); g_hash_table_foreach(rsc->utilization, append_dump_text, &dump_text); out->list_item(out, NULL, "%s", dump_text); @@ -2974,95 +3176,169 @@ resource_util_xml(pcmk__output_t *out, va_list args) { pcmk_resource_t *rsc = va_arg(args, pcmk_resource_t *); pcmk_node_t *node = va_arg(args, pcmk_node_t *); + const char *uname = node->details->uname; const char *fn = va_arg(args, const char *); - xmlNodePtr xml_node = pcmk__output_create_xml_node(out, "utilization", - "resource", rsc->id, - "node", node->details->uname, - "function", fn, - NULL); + xmlNodePtr xml_node = NULL; + + xml_node = pcmk__output_create_xml_node(out, PCMK_XE_UTILIZATION, + PCMK_XA_RESOURCE, rsc->id, + PCMK_XA_NODE, uname, + PCMK_XA_FUNCTION, fn, + NULL); g_hash_table_foreach(rsc->utilization, add_dump_node, xml_node); return pcmk_rc_ok; } -PCMK__OUTPUT_ARGS("ticket", "pcmk_ticket_t *") +PCMK__OUTPUT_ARGS("ticket", "pcmk_ticket_t *", "bool", "bool") static int -ticket_html(pcmk__output_t *out, va_list args) { +ticket_default(pcmk__output_t *out, va_list args) { pcmk_ticket_t *ticket = va_arg(args, pcmk_ticket_t *); + bool raw = va_arg(args, int); + bool details = va_arg(args, int); - if (ticket->last_granted > -1) { - char *epoch_str = pcmk__epoch2str(&(ticket->last_granted), 0); + GString *detail_str = NULL; - out->list_item(out, NULL, "%s:\t%s%s %s=\"%s\"", ticket->id, - ticket->granted ? "granted" : "revoked", - ticket->standby ? " [standby]" : "", - "last-granted", pcmk__s(epoch_str, "")); - free(epoch_str); - } else { - out->list_item(out, NULL, "%s:\t%s%s", ticket->id, - ticket->granted ? "granted" : "revoked", - ticket->standby ? " [standby]" : ""); + if (raw) { + out->list_item(out, ticket->id, "%s", ticket->id); + return pcmk_rc_ok; } - return pcmk_rc_ok; -} + if (details && g_hash_table_size(ticket->state) > 0) { + GHashTableIter iter; + const char *name = NULL; + const char *value = NULL; + bool already_added = false; -PCMK__OUTPUT_ARGS("ticket", "pcmk_ticket_t *") -static int -ticket_text(pcmk__output_t *out, va_list args) { - pcmk_ticket_t *ticket = va_arg(args, pcmk_ticket_t *); + detail_str = g_string_sized_new(100); + pcmk__g_strcat(detail_str, "\t(", NULL); - if (ticket->last_granted > -1) { - char *epoch_str = pcmk__epoch2str(&(ticket->last_granted), 0); + g_hash_table_iter_init(&iter, ticket->state); + while (g_hash_table_iter_next(&iter, (void **) &name, (void **) &value)) { + if (already_added) { + g_string_append_printf(detail_str, ", %s=", name); + } else { + g_string_append_printf(detail_str, "%s=", name); + already_added = true; + } - out->list_item(out, ticket->id, "%s%s %s=\"%s\"", - ticket->granted ? "granted" : "revoked", - ticket->standby ? " [standby]" : "", - "last-granted", pcmk__s(epoch_str, "")); - free(epoch_str); + if (pcmk__str_any_of(name, PCMK_XA_LAST_GRANTED, "expires", NULL)) { + char *epoch_str = NULL; + long long time_ll; + + pcmk__scan_ll(value, &time_ll, 0); + epoch_str = pcmk__epoch2str((const time_t *) &time_ll, 0); + pcmk__g_strcat(detail_str, epoch_str, NULL); + free(epoch_str); + } else { + pcmk__g_strcat(detail_str, value, NULL); + } + } + + pcmk__g_strcat(detail_str, ")", NULL); + } + + if (ticket->last_granted > -1) { + /* Prior to the introduction of the details & raw arguments to this + * function, last-granted would always be added in this block. We need + * to preserve that behavior. At the same time, we also need to preserve + * the existing behavior from crm_ticket, which would include last-granted + * as part of the (...) detail string. + * + * Luckily we can check detail_str - if it's NULL, either there were no + * details, or we are preserving the previous behavior of this function. + * If it's not NULL, we are either preserving the previous behavior of + * crm_ticket or we were given details=true as an argument. + */ + if (detail_str == NULL) { + char *epoch_str = pcmk__epoch2str(&(ticket->last_granted), 0); + + out->list_item(out, NULL, "%s\t%s%s last-granted=\"%s\"", + ticket->id, + (ticket->granted? "granted" : "revoked"), + (ticket->standby? " [standby]" : ""), + pcmk__s(epoch_str, "")); + free(epoch_str); + } else { + out->list_item(out, NULL, "%s\t%s%s %s", + ticket->id, + (ticket->granted? "granted" : "revoked"), + (ticket->standby? " [standby]" : ""), + detail_str->str); + } } else { - out->list_item(out, ticket->id, "%s%s", + out->list_item(out, NULL, "%s\t%s%s%s", ticket->id, ticket->granted ? "granted" : "revoked", - ticket->standby ? " [standby]" : ""); + ticket->standby ? " [standby]" : "", + detail_str != NULL ? detail_str->str : ""); + } + + if (detail_str != NULL) { + g_string_free(detail_str, TRUE); } return pcmk_rc_ok; } -PCMK__OUTPUT_ARGS("ticket", "pcmk_ticket_t *") +PCMK__OUTPUT_ARGS("ticket", "pcmk_ticket_t *", "bool", "bool") static int ticket_xml(pcmk__output_t *out, va_list args) { pcmk_ticket_t *ticket = va_arg(args, pcmk_ticket_t *); + bool raw G_GNUC_UNUSED = va_arg(args, int); + bool details G_GNUC_UNUSED = va_arg(args, int); + + const char *status = NULL; + const char *standby = pcmk__btoa(ticket->standby); xmlNodePtr node = NULL; + GHashTableIter iter; + const char *name = NULL; + const char *value = NULL; - node = pcmk__output_create_xml_node(out, "ticket", - "id", ticket->id, - "status", ticket->granted ? "granted" : "revoked", - "standby", pcmk__btoa(ticket->standby), + status = ticket->granted? PCMK_VALUE_GRANTED : PCMK_VALUE_REVOKED; + + node = pcmk__output_create_xml_node(out, PCMK_XE_TICKET, + PCMK_XA_ID, ticket->id, + PCMK_XA_STATUS, status, + PCMK_XA_STANDBY, standby, NULL); if (ticket->last_granted > -1) { char *buf = pcmk__epoch2str(&ticket->last_granted, 0); - crm_xml_add(node, "last-granted", buf); + crm_xml_add(node, PCMK_XA_LAST_GRANTED, buf); free(buf); } + g_hash_table_iter_init(&iter, ticket->state); + while (g_hash_table_iter_next(&iter, (void **) &name, (void **) &value)) { + /* PCMK_XA_LAST_GRANTED and "expires" are already added by the check + * for ticket->last_granted above. + */ + if (pcmk__str_any_of(name, PCMK_XA_LAST_GRANTED, PCMK_XA_EXPIRES, + NULL)) { + continue; + } + + crm_xml_add(node, name, value); + } + return pcmk_rc_ok; } -PCMK__OUTPUT_ARGS("ticket-list", "pcmk_scheduler_t *", "bool") +PCMK__OUTPUT_ARGS("ticket-list", "GHashTable *", "bool", "bool", "bool") static int ticket_list(pcmk__output_t *out, va_list args) { - pcmk_scheduler_t *scheduler = va_arg(args, pcmk_scheduler_t *); + GHashTable *tickets = va_arg(args, GHashTable *); bool print_spacer = va_arg(args, int); + bool raw = va_arg(args, int); + bool details = va_arg(args, int); GHashTableIter iter; - gpointer key, value; + gpointer value; - if (g_hash_table_size(scheduler->tickets) == 0) { + if (g_hash_table_size(tickets) == 0) { return pcmk_rc_no_output; } @@ -3072,10 +3348,10 @@ ticket_list(pcmk__output_t *out, va_list args) { out->begin_list(out, NULL, NULL, "Tickets"); /* Print each ticket */ - g_hash_table_iter_init(&iter, scheduler->tickets); - while (g_hash_table_iter_next(&iter, &key, &value)) { + g_hash_table_iter_init(&iter, tickets); + while (g_hash_table_iter_next(&iter, NULL, &value)) { pcmk_ticket_t *ticket = (pcmk_ticket_t *) value; - out->message(out, "ticket", ticket); + out->message(out, "ticket", ticket, raw, details); } /* Close section */ @@ -3150,8 +3426,7 @@ static pcmk__message_entry_t fmt_functions[] = { { "resource-operation-list", "default", resource_operation_list }, { "resource-util", "default", resource_util }, { "resource-util", "xml", resource_util_xml }, - { "ticket", "default", ticket_text }, - { "ticket", "html", ticket_html }, + { "ticket", "default", ticket_default }, { "ticket", "xml", ticket_xml }, { "ticket-list", "default", ticket_list }, diff --git a/lib/pengine/pe_status_private.h b/lib/pengine/pe_status_private.h index bb0ee4e..309f0b7 100644 --- a/lib/pengine/pe_status_private.h +++ b/lib/pengine/pe_status_private.h @@ -114,7 +114,7 @@ G_GNUC_INTERNAL gboolean unpack_status(xmlNode *status, pcmk_scheduler_t *scheduler); G_GNUC_INTERNAL -op_digest_cache_t *pe__compare_fencing_digest(pcmk_resource_t *rsc, +pcmk__op_digest_t *pe__compare_fencing_digest(pcmk_resource_t *rsc, const char *agent, pcmk_node_t *node, pcmk_scheduler_t *scheduler); diff --git a/lib/pengine/remote.c b/lib/pengine/remote.c index 6b5058c..983ce80 100644 --- a/lib/pengine/remote.c +++ b/lib/pengine/remote.c @@ -1,5 +1,5 @@ /* - * Copyright 2013-2023 the Pacemaker project contributors + * Copyright 2013-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -8,48 +8,11 @@ */ #include <crm_internal.h> -#include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crm/common/scheduler_internal.h> #include <crm/pengine/internal.h> #include <glib.h> -bool -pe__resource_is_remote_conn(const pcmk_resource_t *rsc) -{ - return (rsc != NULL) && rsc->is_remote_node - && pe__is_remote_node(pe_find_node(rsc->cluster->nodes, rsc->id)); -} - -bool -pe__is_remote_node(const pcmk_node_t *node) -{ - return (node != NULL) && (node->details->type == pcmk_node_variant_remote) - && ((node->details->remote_rsc == NULL) - || (node->details->remote_rsc->container == NULL)); -} - -bool -pe__is_guest_node(const pcmk_node_t *node) -{ - return (node != NULL) && (node->details->type == pcmk_node_variant_remote) - && (node->details->remote_rsc != NULL) - && (node->details->remote_rsc->container != NULL); -} - -bool -pe__is_guest_or_remote_node(const pcmk_node_t *node) -{ - return (node != NULL) && (node->details->type == pcmk_node_variant_remote); -} - -bool -pe__is_bundle_node(const pcmk_node_t *node) -{ - return pe__is_guest_node(node) - && pe_rsc_is_bundled(node->details->remote_rsc); -} - /*! * \internal * \brief Check whether a resource creates a guest node @@ -89,17 +52,17 @@ xml_contains_remote_node(xmlNode *xml) return false; } - value = crm_element_value(xml, XML_ATTR_TYPE); + value = crm_element_value(xml, PCMK_XA_TYPE); if (!pcmk__str_eq(value, "remote", pcmk__str_casei)) { return false; } - value = crm_element_value(xml, XML_AGENT_ATTR_CLASS); + value = crm_element_value(xml, PCMK_XA_CLASS); if (!pcmk__str_eq(value, PCMK_RESOURCE_CLASS_OCF, pcmk__str_casei)) { return false; } - value = crm_element_value(xml, XML_AGENT_ATTR_PROVIDER); + value = crm_element_value(xml, PCMK_XA_PROVIDER); if (!pcmk__str_eq(value, "pacemaker", pcmk__str_casei)) { return false; } @@ -132,7 +95,7 @@ pe_foreach_guest_node(const pcmk_scheduler_t *scheduler, pcmk_resource_t *rsc = (pcmk_resource_t *) iter->data; if (rsc->is_remote_node && (rsc->container != NULL)) { - pcmk_node_t *guest_node = pe_find_node(scheduler->nodes, rsc->id); + pcmk_node_t *guest_node = pcmk_find_node(scheduler, rsc->id); if (guest_node) { (*helper)(guest_node, user_data); @@ -145,14 +108,16 @@ pe_foreach_guest_node(const pcmk_scheduler_t *scheduler, * \internal * \brief Create CIB XML for an implicit remote connection * - * \param[in,out] parent If not NULL, use as parent XML element - * \param[in] uname Name of Pacemaker Remote node - * \param[in] container If not NULL, use this as connection container - * \param[in] migrateable If not NULL, use as allow-migrate value - * \param[in] is_managed If not NULL, use as is-managed value - * \param[in] start_timeout If not NULL, use as remote connect timeout - * \param[in] server If not NULL, use as remote server value - * \param[in] port If not NULL, use as remote port value + * \param[in,out] parent If not \c NULL, use as parent XML element + * \param[in] uname Name of Pacemaker Remote node + * \param[in] container_id If not \c NULL, use this as connection container + * \param[in] migrateable If not \c NULL, use as remote + * \c PCMK_META_ALLOW_MIGRATE value + * \param[in] is_managed If not \c NULL, use as remote + * \c PCMK_META_IS_MANAGED value + * \param[in] start_timeout If not \c NULL, use as remote connect timeout + * \param[in] server If not \c NULL, use as \c PCMK_REMOTE_RA_ADDR + * \param[in] port If not \c NULL, use as \c PCMK_REMOTE_RA_PORT * * \return Newly created XML */ @@ -165,46 +130,45 @@ pe_create_remote_xml(xmlNode *parent, const char *uname, xmlNode *remote; xmlNode *xml_sub; - remote = create_xml_node(parent, XML_CIB_TAG_RESOURCE); + remote = pcmk__xe_create(parent, PCMK_XE_PRIMITIVE); // Add identity - crm_xml_add(remote, XML_ATTR_ID, uname); - crm_xml_add(remote, XML_AGENT_ATTR_CLASS, PCMK_RESOURCE_CLASS_OCF); - crm_xml_add(remote, XML_AGENT_ATTR_PROVIDER, "pacemaker"); - crm_xml_add(remote, XML_ATTR_TYPE, "remote"); + crm_xml_add(remote, PCMK_XA_ID, uname); + crm_xml_add(remote, PCMK_XA_CLASS, PCMK_RESOURCE_CLASS_OCF); + crm_xml_add(remote, PCMK_XA_PROVIDER, "pacemaker"); + crm_xml_add(remote, PCMK_XA_TYPE, "remote"); // Add meta-attributes - xml_sub = create_xml_node(remote, XML_TAG_META_SETS); - crm_xml_set_id(xml_sub, "%s-%s", uname, XML_TAG_META_SETS); + xml_sub = pcmk__xe_create(remote, PCMK_XE_META_ATTRIBUTES); + crm_xml_set_id(xml_sub, "%s-%s", uname, PCMK_XE_META_ATTRIBUTES); crm_create_nvpair_xml(xml_sub, NULL, - XML_RSC_ATTR_INTERNAL_RSC, XML_BOOLEAN_TRUE); + PCMK__META_INTERNAL_RSC, PCMK_VALUE_TRUE); if (container_id) { crm_create_nvpair_xml(xml_sub, NULL, - XML_RSC_ATTR_CONTAINER, container_id); + PCMK__META_CONTAINER, container_id); } if (migrateable) { crm_create_nvpair_xml(xml_sub, NULL, - XML_OP_ATTR_ALLOW_MIGRATE, migrateable); + PCMK_META_ALLOW_MIGRATE, migrateable); } if (is_managed) { - crm_create_nvpair_xml(xml_sub, NULL, XML_RSC_ATTR_MANAGED, is_managed); + crm_create_nvpair_xml(xml_sub, NULL, PCMK_META_IS_MANAGED, is_managed); } // Add instance attributes if (port || server) { - xml_sub = create_xml_node(remote, XML_TAG_ATTR_SETS); - crm_xml_set_id(xml_sub, "%s-%s", uname, XML_TAG_ATTR_SETS); + xml_sub = pcmk__xe_create(remote, PCMK_XE_INSTANCE_ATTRIBUTES); + crm_xml_set_id(xml_sub, "%s-%s", uname, PCMK_XE_INSTANCE_ATTRIBUTES); if (server) { - crm_create_nvpair_xml(xml_sub, NULL, XML_RSC_ATTR_REMOTE_RA_ADDR, - server); + crm_create_nvpair_xml(xml_sub, NULL, PCMK_REMOTE_RA_ADDR, server); } if (port) { - crm_create_nvpair_xml(xml_sub, NULL, "port", port); + crm_create_nvpair_xml(xml_sub, NULL, PCMK_REMOTE_RA_PORT, port); } } // Add operations - xml_sub = create_xml_node(remote, "operations"); + xml_sub = pcmk__xe_create(remote, PCMK_XE_OPERATIONS); crm_create_op_xml(xml_sub, uname, PCMK_ACTION_MONITOR, "30s", "30s"); if (start_timeout) { crm_create_op_xml(xml_sub, uname, PCMK_ACTION_START, "0", @@ -230,10 +194,10 @@ pe__add_param_check(const xmlNode *rsc_op, pcmk_resource_t *rsc, CRM_CHECK(scheduler && rsc_op && rsc && node, return); - check_op = calloc(1, sizeof(struct check_op)); - CRM_ASSERT(check_op != NULL); + check_op = pcmk__assert_alloc(1, sizeof(struct check_op)); - crm_trace("Deferring checks of %s until after allocation", ID(rsc_op)); + crm_trace("Deferring checks of %s until after allocation", + pcmk__xe_id(rsc_op)); check_op->rsc_op = rsc_op; check_op->rsc = rsc; check_op->node = node; diff --git a/lib/pengine/rules.c b/lib/pengine/rules.c index 50f9f64..540bc0d 100644 --- a/lib/pengine/rules.c +++ b/lib/pengine/rules.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2023 the Pacemaker project contributors + * Copyright 2004-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -8,324 +8,70 @@ */ #include <crm_internal.h> -#include <crm/crm.h> -#include <crm/msg_xml.h> -#include <crm/common/xml.h> -#include <crm/common/xml_internal.h> #include <glib.h> +#include <crm/crm.h> +#include <crm/common/xml.h> #include <crm/pengine/rules.h> -#include <crm/pengine/rules_internal.h> + +#include <crm/common/iso8601_internal.h> +#include <crm/common/nvpair_internal.h> +#include <crm/common/rules_internal.h> +#include <crm/common/xml_internal.h> #include <crm/pengine/internal.h> +#include <crm/pengine/rules_internal.h> #include <sys/types.h> #include <regex.h> -#include <ctype.h> CRM_TRACE_INIT_DATA(pe_rules); /*! - * \brief Evaluate any rules contained by given XML element - * - * \param[in,out] xml XML element to check for rules - * \param[in] node_hash Node attributes to use to evaluate expressions - * \param[in] now Time to use when evaluating expressions - * \param[out] next_change If not NULL, set to when evaluation will change - * - * \return TRUE if no rules, or any of rules present is in effect, else FALSE - */ -gboolean -pe_evaluate_rules(xmlNode *ruleset, GHashTable *node_hash, crm_time_t *now, - crm_time_t *next_change) -{ - pe_rule_eval_data_t rule_data = { - .node_hash = node_hash, - .role = pcmk_role_unknown, - .now = now, - .match_data = NULL, - .rsc_data = NULL, - .op_data = NULL - }; - - return pe_eval_rules(ruleset, &rule_data, next_change); -} - -gboolean -pe_test_rule(xmlNode *rule, GHashTable *node_hash, enum rsc_role_e role, - crm_time_t *now, crm_time_t *next_change, - pe_match_data_t *match_data) -{ - pe_rule_eval_data_t rule_data = { - .node_hash = node_hash, - .role = role, - .now = now, - .match_data = match_data, - .rsc_data = NULL, - .op_data = NULL - }; - - return pe_eval_expr(rule, &rule_data, next_change); -} - -/*! - * \brief Evaluate one rule subelement (pass/fail) - * - * A rule element may contain another rule, a node attribute expression, or a - * date expression. Given any one of those, evaluate it and return whether it - * passed. - * - * \param[in,out] expr Rule subelement XML - * \param[in] node_hash Node attributes to use when evaluating expression - * \param[in] role Resource role to use when evaluating expression - * \param[in] now Time to use when evaluating expression - * \param[out] next_change If not NULL, set to when evaluation will change - * \param[in] match_data If not NULL, resource back-references and params - * - * \return TRUE if expression is in effect under given conditions, else FALSE - */ -gboolean -pe_test_expression(xmlNode *expr, GHashTable *node_hash, enum rsc_role_e role, - crm_time_t *now, crm_time_t *next_change, - pe_match_data_t *match_data) -{ - pe_rule_eval_data_t rule_data = { - .node_hash = node_hash, - .role = role, - .now = now, - .match_data = match_data, - .rsc_data = NULL, - .op_data = NULL - }; - - return pe_eval_subexpr(expr, &rule_data, next_change); -} - -enum expression_type -find_expression_type(xmlNode * expr) -{ - const char *attr = NULL; - - attr = crm_element_value(expr, XML_EXPR_ATTR_ATTRIBUTE); - - if (pcmk__xe_is(expr, PCMK_XE_DATE_EXPRESSION)) { - return time_expr; - - } else if (pcmk__xe_is(expr, PCMK_XE_RSC_EXPRESSION)) { - return rsc_expr; - - } else if (pcmk__xe_is(expr, PCMK_XE_OP_EXPRESSION)) { - return op_expr; - - } else if (pcmk__xe_is(expr, XML_TAG_RULE)) { - return nested_rule; - - } else if (!pcmk__xe_is(expr, XML_TAG_EXPRESSION)) { - return not_expr; - - } else if (pcmk__str_any_of(attr, CRM_ATTR_UNAME, CRM_ATTR_KIND, CRM_ATTR_ID, NULL)) { - return loc_expr; - - } else if (pcmk__str_eq(attr, CRM_ATTR_ROLE, pcmk__str_none)) { - return role_expr; - } - - return attr_expr; -} - -/* As per the nethack rules: - * - * moon period = 29.53058 days ~= 30, year = 365.2422 days - * days moon phase advances on first day of year compared to preceding year - * = 365.2422 - 12*29.53058 ~= 11 - * years in Metonic cycle (time until same phases fall on the same days of - * the month) = 18.6 ~= 19 - * moon phase on first day of year (epact) ~= (11*(year%19) + 29) % 30 - * (29 as initial condition) - * current phase in days = first day phase + days elapsed in year - * 6 moons ~= 177 days - * 177 ~= 8 reported phases * 22 - * + 11/22 for rounding + * \internal + * \brief Map pe_rule_eval_data_t to pcmk_rule_input_t * - * 0-7, with 0: new, 4: full + * \param[out] new New data struct + * \param[in] old Old data struct */ - -static int -phase_of_the_moon(const crm_time_t *now) -{ - uint32_t epact, diy, goldn; - uint32_t y; - - crm_time_get_ordinal(now, &y, &diy); - - goldn = (y % 19) + 1; - epact = (11 * goldn + 18) % 30; - if ((epact == 25 && goldn > 11) || epact == 24) - epact++; - - return ((((((diy + epact) * 6) + 11) % 177) / 22) & 7); -} - -static int -check_one(const xmlNode *cron_spec, const char *xml_field, uint32_t time_field) -{ - int rc = pcmk_rc_undetermined; - const char *value = crm_element_value(cron_spec, xml_field); - long long low, high; - - if (value == NULL) { - /* Return pe_date_result_undetermined if the field is missing. */ - goto bail; - } - - if (pcmk__parse_ll_range(value, &low, &high) != pcmk_rc_ok) { - goto bail; - } else if (low == high) { - /* A single number was given, not a range. */ - if (time_field < low) { - rc = pcmk_rc_before_range; - } else if (time_field > high) { - rc = pcmk_rc_after_range; - } else { - rc = pcmk_rc_within_range; - } - } else if (low != -1 && high != -1) { - /* This is a range with both bounds. */ - if (time_field < low) { - rc = pcmk_rc_before_range; - } else if (time_field > high) { - rc = pcmk_rc_after_range; - } else { - rc = pcmk_rc_within_range; - } - } else if (low == -1) { - /* This is a range with no starting value. */ - rc = time_field <= high ? pcmk_rc_within_range : pcmk_rc_after_range; - } else if (high == -1) { - /* This is a range with no ending value. */ - rc = time_field >= low ? pcmk_rc_within_range : pcmk_rc_before_range; - } - -bail: - if (rc == pcmk_rc_within_range) { - crm_debug("Condition '%s' in %s: passed", value, xml_field); - } else { - crm_debug("Condition '%s' in %s: failed", value, xml_field); - } - - return rc; -} - -static gboolean -check_passes(int rc) { - /* _within_range is obvious. _undetermined is a pass because - * this is the return value if a field is not given. In this - * case, we just want to ignore it and check other fields to - * see if they place some restriction on what can pass. - */ - return rc == pcmk_rc_within_range || rc == pcmk_rc_undetermined; -} - -#define CHECK_ONE(spec, name, var) do { \ - int subpart_rc = check_one(spec, name, var); \ - if (check_passes(subpart_rc) == FALSE) { \ - return subpart_rc; \ - } \ -} while (0) - -int -pe_cron_range_satisfied(const crm_time_t *now, const xmlNode *cron_spec) -{ - uint32_t h, m, s, y, d, w; - - CRM_CHECK(now != NULL, return pcmk_rc_op_unsatisfied); - - crm_time_get_gregorian(now, &y, &m, &d); - CHECK_ONE(cron_spec, "years", y); - CHECK_ONE(cron_spec, "months", m); - CHECK_ONE(cron_spec, "monthdays", d); - - crm_time_get_timeofday(now, &h, &m, &s); - CHECK_ONE(cron_spec, "hours", h); - CHECK_ONE(cron_spec, "minutes", m); - CHECK_ONE(cron_spec, "seconds", s); - - crm_time_get_ordinal(now, &y, &d); - CHECK_ONE(cron_spec, "yeardays", d); - - crm_time_get_isoweek(now, &y, &w, &d); - CHECK_ONE(cron_spec, "weekyears", y); - CHECK_ONE(cron_spec, "weeks", w); - CHECK_ONE(cron_spec, "weekdays", d); - - CHECK_ONE(cron_spec, "moon", phase_of_the_moon(now)); - if (crm_element_value(cron_spec, "moon") != NULL) { - pcmk__config_warn("Support for 'moon' in date_spec elements " - "(such as %s) is deprecated and will be removed " - "in a future release of Pacemaker", ID(cron_spec)); - } - - /* If we get here, either no fields were specified (which is success), or all - * the fields that were specified had their conditions met (which is also a - * success). Thus, the result is success. - */ - return pcmk_rc_ok; -} - static void -update_field(crm_time_t *t, const xmlNode *xml, const char *attr, - void (*time_fn)(crm_time_t *, int)) +map_rule_input(pcmk_rule_input_t *new, const pe_rule_eval_data_t *old) { - long long value; - - if ((pcmk__scan_ll(crm_element_value(xml, attr), &value, 0LL) == pcmk_rc_ok) - && (value != 0LL) && (value >= INT_MIN) && (value <= INT_MAX)) { - time_fn(t, (int) value); + if (old == NULL) { + return; } -} - -static crm_time_t * -parse_xml_duration(const crm_time_t *start, const xmlNode *duration_spec) -{ - crm_time_t *end = pcmk_copy_time(start); - - update_field(end, duration_spec, "years", crm_time_add_years); - update_field(end, duration_spec, "months", crm_time_add_months); - update_field(end, duration_spec, "weeks", crm_time_add_weeks); - update_field(end, duration_spec, "days", crm_time_add_days); - update_field(end, duration_spec, "hours", crm_time_add_hours); - update_field(end, duration_spec, "minutes", crm_time_add_minutes); - update_field(end, duration_spec, "seconds", crm_time_add_seconds); - - return end; -} - -// 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) -{ - if ((next_change != NULL) && (t != NULL)) { - if (!crm_time_is_defined(next_change) - || (crm_time_compare(t, next_change) < 0)) { - crm_time_set(next_change, t); + new->now = old->now; + new->node_attrs = old->node_hash; + if (old->rsc_data != NULL) { + new->rsc_standard = old->rsc_data->standard; + new->rsc_provider = old->rsc_data->provider; + new->rsc_agent = old->rsc_data->agent; + } + if (old->match_data != NULL) { + new->rsc_params = old->match_data->params; + new->rsc_meta = old->match_data->meta; + if (old->match_data->re != NULL) { + new->rsc_id = old->match_data->re->string; + new->rsc_id_submatches = old->match_data->re->pmatch; + new->rsc_id_nmatches = old->match_data->re->nregs; } } + if (old->op_data != NULL) { + new->op_name = old->op_data->op_name; + new->op_interval_ms = old->op_data->interval; + } } -// Information about a block of nvpair elements -typedef struct sorted_set_s { - int score; // This block's score for sorting - const char *name; // This block's ID - const char *special_name; // ID that should sort first - xmlNode *attr_set; // This block - gboolean overwrite; // Whether existing values will be overwritten -} sorted_set_t; - static gint -sort_pairs(gconstpointer a, gconstpointer b) +sort_pairs(gconstpointer a, gconstpointer b, gpointer user_data) { - const sorted_set_t *pair_a = a; - const sorted_set_t *pair_b = b; + const xmlNode *pair_a = a; + const xmlNode *pair_b = b; + pcmk__nvpair_unpack_t *unpack_data = user_data; + + const char *score = NULL; + int score_a = 0; + int score_b = 0; if (a == NULL && b == NULL) { return 0; @@ -335,27 +81,35 @@ sort_pairs(gconstpointer a, gconstpointer b) return -1; } - if (pcmk__str_eq(pair_a->name, pair_a->special_name, pcmk__str_casei)) { + if (pcmk__str_eq(pcmk__xe_id(pair_a), unpack_data->first_id, + pcmk__str_none)) { return -1; - } else if (pcmk__str_eq(pair_b->name, pair_a->special_name, pcmk__str_casei)) { + } else if (pcmk__str_eq(pcmk__xe_id(pair_b), unpack_data->first_id, + pcmk__str_none)) { return 1; } + score = crm_element_value(pair_a, PCMK_XA_SCORE); + score_a = char2score(score); + + score = crm_element_value(pair_b, PCMK_XA_SCORE); + score_b = char2score(score); + /* If we're overwriting values, we want lowest score first, so the highest * score is processed last; if we're not overwriting values, we want highest * score first, so nothing else overwrites it. */ - if (pair_a->score < pair_b->score) { - return pair_a->overwrite? -1 : 1; - } else if (pair_a->score > pair_b->score) { - return pair_a->overwrite? 1 : -1; + if (score_a < score_b) { + return unpack_data->overwrite? -1 : 1; + } else if (score_a > score_b) { + return unpack_data->overwrite? 1 : -1; } return 0; } static void -populate_hash(xmlNode * nvpair_list, GHashTable * hash, gboolean overwrite, xmlNode * top) +populate_hash(xmlNode *nvpair_list, GHashTable *hash, bool overwrite) { const char *name = NULL; const char *value = NULL; @@ -363,24 +117,24 @@ populate_hash(xmlNode * nvpair_list, GHashTable * hash, gboolean overwrite, xmlN xmlNode *list = nvpair_list; xmlNode *an_attr = NULL; - if (pcmk__xe_is(list->children, XML_TAG_ATTRS)) { + if (pcmk__xe_is(list->children, PCMK__XE_ATTRIBUTES)) { list = list->children; } - for (an_attr = pcmk__xe_first_child(list); an_attr != NULL; - an_attr = pcmk__xe_next(an_attr)) { + for (an_attr = pcmk__xe_first_child(list, NULL, NULL, NULL); + an_attr != NULL; an_attr = pcmk__xe_next(an_attr)) { - if (pcmk__str_eq((const char *)an_attr->name, XML_CIB_TAG_NVPAIR, pcmk__str_none)) { - xmlNode *ref_nvpair = expand_idref(an_attr, top); + if (pcmk__xe_is(an_attr, PCMK_XE_NVPAIR)) { + xmlNode *ref_nvpair = expand_idref(an_attr, NULL); - name = crm_element_value(an_attr, XML_NVPAIR_ATTR_NAME); - if (name == NULL) { - name = crm_element_value(ref_nvpair, XML_NVPAIR_ATTR_NAME); + name = crm_element_value(an_attr, PCMK_XA_NAME); + if ((name == NULL) && (ref_nvpair != NULL)) { + name = crm_element_value(ref_nvpair, PCMK_XA_NAME); } - value = crm_element_value(an_attr, XML_NVPAIR_ATTR_VALUE); - if (value == NULL) { - value = crm_element_value(ref_nvpair, XML_NVPAIR_ATTR_VALUE); + value = crm_element_value(an_attr, PCMK_XA_VALUE); + if ((value == NULL) && (ref_nvpair != NULL)) { + value = crm_element_value(ref_nvpair, PCMK_XA_VALUE); } if (name == NULL || value == NULL) { @@ -390,6 +144,11 @@ populate_hash(xmlNode * nvpair_list, GHashTable * hash, gboolean overwrite, xmlN old_value = g_hash_table_lookup(hash, name); if (pcmk__str_eq(value, "#default", pcmk__str_casei)) { + // @COMPAT Deprecated since 2.1.8 + pcmk__config_warn("Support for setting meta-attributes (such " + "as %s) to the explicit value '#default' is " + "deprecated and will be removed in a future " + "release", name); if (old_value) { crm_trace("Letting %s default (removing explicit value \"%s\")", name, value); @@ -399,95 +158,69 @@ populate_hash(xmlNode * nvpair_list, GHashTable * hash, gboolean overwrite, xmlN } else if (old_value == NULL) { crm_trace("Setting %s=\"%s\"", name, value); - g_hash_table_insert(hash, strdup(name), strdup(value)); + pcmk__insert_dup(hash, name, value); } else if (overwrite) { crm_trace("Setting %s=\"%s\" (overwriting old value \"%s\")", name, value, old_value); - g_hash_table_replace(hash, strdup(name), strdup(value)); + pcmk__insert_dup(hash, name, value); } } } } -typedef struct unpack_data_s { - gboolean overwrite; - void *hash; - crm_time_t *next_change; - const pe_rule_eval_data_t *rule_data; - xmlNode *top; -} unpack_data_t; - static void unpack_attr_set(gpointer data, gpointer user_data) { - sorted_set_t *pair = data; - unpack_data_t *unpack_data = user_data; + xmlNode *pair = data; + pcmk__nvpair_unpack_t *unpack_data = user_data; - if (!pe_eval_rules(pair->attr_set, unpack_data->rule_data, - unpack_data->next_change)) { + if (pcmk__evaluate_rules(pair, &(unpack_data->rule_input), + unpack_data->next_change) != pcmk_rc_ok) { return; } - crm_trace("Adding attributes from %s (score %d) %s overwrite", - pair->name, pair->score, - (unpack_data->overwrite? "with" : "without")); - populate_hash(pair->attr_set, unpack_data->hash, unpack_data->overwrite, unpack_data->top); + crm_trace("Adding name/value pairs from %s %s overwrite", + pcmk__xe_id(pair), (unpack_data->overwrite? "with" : "without")); + populate_hash(pair, unpack_data->values, unpack_data->overwrite); } /*! * \internal * \brief Create a sorted list of nvpair blocks * - * \param[in,out] top XML document root (used to expand id-ref's) * \param[in] xml_obj XML element containing blocks of nvpair elements * \param[in] set_name If not NULL, only get blocks of this element - * \param[in] always_first If not NULL, sort block with this ID as first * - * \return List of sorted_set_t entries for nvpair blocks + * \return List of XML blocks of name/value pairs */ static GList * -make_pairs(xmlNode *top, const xmlNode *xml_obj, const char *set_name, - const char *always_first, gboolean overwrite) +make_pairs(const xmlNode *xml_obj, const char *set_name) { GList *unsorted = NULL; if (xml_obj == NULL) { return NULL; } - for (xmlNode *attr_set = pcmk__xe_first_child(xml_obj); attr_set != NULL; - attr_set = pcmk__xe_next(attr_set)) { + for (xmlNode *attr_set = pcmk__xe_first_child(xml_obj, NULL, NULL, NULL); + attr_set != NULL; attr_set = pcmk__xe_next(attr_set)) { - if (pcmk__str_eq(set_name, (const char *) attr_set->name, - pcmk__str_null_matches)) { - const char *score = NULL; - sorted_set_t *pair = NULL; - xmlNode *expanded_attr_set = expand_idref(attr_set, top); + if ((set_name == NULL) || pcmk__xe_is(attr_set, set_name)) { + xmlNode *expanded_attr_set = expand_idref(attr_set, NULL); if (expanded_attr_set == NULL) { - // Schema (if not "none") prevents this - continue; + continue; // Not possible with schema validation enabled } - - pair = calloc(1, sizeof(sorted_set_t)); - pair->name = ID(expanded_attr_set); - pair->special_name = always_first; - pair->attr_set = expanded_attr_set; - pair->overwrite = overwrite; - - score = crm_element_value(expanded_attr_set, XML_RULE_ATTR_SCORE); - pair->score = char2score(score); - - unsorted = g_list_prepend(unsorted, pair); + unsorted = g_list_prepend(unsorted, expanded_attr_set); } } - return g_list_sort(unsorted, sort_pairs); + return unsorted; } /*! * \brief Extract nvpair blocks contained by an XML element into a hash table * - * \param[in,out] top XML document root (used to expand id-ref's) + * \param[in,out] top Ignored * \param[in] xml_obj XML element containing blocks of nvpair elements * \param[in] set_name If not NULL, only use blocks of this element * \param[in] rule_data Matching parameters to use when unpacking @@ -502,26 +235,28 @@ pe_eval_nvpairs(xmlNode *top, const xmlNode *xml_obj, const char *set_name, const char *always_first, gboolean overwrite, crm_time_t *next_change) { - GList *pairs = make_pairs(top, xml_obj, set_name, always_first, overwrite); + GList *pairs = make_pairs(xml_obj, set_name); if (pairs) { - unpack_data_t data = { - .hash = hash, + pcmk__nvpair_unpack_t data = { + .values = hash, + .first_id = always_first, .overwrite = overwrite, .next_change = next_change, - .top = top, - .rule_data = rule_data }; + map_rule_input(&(data.rule_input), rule_data); + + pairs = g_list_sort_with_data(pairs, sort_pairs, &data); g_list_foreach(pairs, unpack_attr_set, &data); - g_list_free_full(pairs, free); + g_list_free(pairs); } } /*! * \brief Extract nvpair blocks contained by an XML element into a hash table * - * \param[in,out] top XML document root (used to expand id-ref's) + * \param[in,out] top Ignored * \param[in] xml_obj XML element containing blocks of nvpair elements * \param[in] set_name Element name to identify nvpair blocks * \param[in] node_hash Node attributes to use when evaluating rules @@ -539,709 +274,67 @@ pe_unpack_nvpairs(xmlNode *top, const xmlNode *xml_obj, const char *set_name, { pe_rule_eval_data_t rule_data = { .node_hash = node_hash, - .role = pcmk_role_unknown, .now = now, .match_data = NULL, .rsc_data = NULL, .op_data = NULL }; - pe_eval_nvpairs(top, xml_obj, set_name, &rule_data, hash, + pe_eval_nvpairs(NULL, xml_obj, set_name, &rule_data, hash, always_first, overwrite, next_change); } -/*! - * \brief Expand any regular expression submatches (%0-%9) in a string - * - * \param[in] string String possibly containing submatch variables - * \param[in] match_data If not NULL, regular expression matches - * - * \return Newly allocated string identical to \p string with submatches - * expanded, or NULL if there were no matches - */ -char * -pe_expand_re_matches(const char *string, const pe_re_match_data_t *match_data) -{ - size_t len = 0; - int i; - const char *p, *last_match_index; - char *p_dst, *result = NULL; - - if (pcmk__str_empty(string) || !match_data) { - return NULL; - } - - p = last_match_index = string; - - while (*p) { - if (*p == '%' && *(p + 1) && isdigit(*(p + 1))) { - i = *(p + 1) - '0'; - if (match_data->nregs >= i && match_data->pmatch[i].rm_so != -1 && - match_data->pmatch[i].rm_eo > match_data->pmatch[i].rm_so) { - len += p - last_match_index + (match_data->pmatch[i].rm_eo - match_data->pmatch[i].rm_so); - last_match_index = p + 2; - } - p++; - } - p++; - } - len += p - last_match_index + 1; - - /* FIXME: Excessive? */ - if (len - 1 <= 0) { - return NULL; - } - - p_dst = result = calloc(1, len); - p = string; - - while (*p) { - if (*p == '%' && *(p + 1) && isdigit(*(p + 1))) { - i = *(p + 1) - '0'; - if (match_data->nregs >= i && match_data->pmatch[i].rm_so != -1 && - match_data->pmatch[i].rm_eo > match_data->pmatch[i].rm_so) { - /* rm_eo can be equal to rm_so, but then there is nothing to do */ - int match_len = match_data->pmatch[i].rm_eo - match_data->pmatch[i].rm_so; - memcpy(p_dst, match_data->string + match_data->pmatch[i].rm_so, match_len); - p_dst += match_len; - } - p++; - } else { - *(p_dst) = *(p); - p_dst++; - } - p++; - } +// Deprecated functions kept only for backward API compatibility +// LCOV_EXCL_START - return result; -} +#include <crm/pengine/rules_compat.h> -/*! - * \brief Evaluate rules - * - * \param[in,out] ruleset XML possibly containing rule sub-elements - * \param[in] rule_data - * \param[out] next_change If not NULL, set to when evaluation will change - * - * \return TRUE if there are no rules or - */ gboolean pe_eval_rules(xmlNode *ruleset, const pe_rule_eval_data_t *rule_data, crm_time_t *next_change) { - // If there are no rules, pass by default - gboolean ruleset_default = TRUE; - - for (xmlNode *rule = first_named_child(ruleset, XML_TAG_RULE); - rule != NULL; rule = crm_next_same_xml(rule)) { - - ruleset_default = FALSE; - if (pe_eval_expr(rule, rule_data, next_change)) { - /* Only the deprecated "lifetime" element of location constraints - * may contain more than one rule at the top level -- the schema - * limits a block of nvpairs to a single top-level rule. So, this - * effectively means that a lifetime is active if any rule it - * contains is active. - */ - return TRUE; - } - } + pcmk_rule_input_t rule_input = { NULL, }; - return ruleset_default; + map_rule_input(&rule_input, rule_data); + return pcmk__evaluate_rules(ruleset, &rule_input, + next_change) == pcmk_rc_ok; } -/*! - * \brief Evaluate all of a rule's expressions - * - * \param[in,out] rule XML containing a rule definition or its id-ref - * \param[in] rule_data Matching parameters to check against rule - * \param[out] next_change If not NULL, set to when evaluation will change - * - * \return TRUE if \p rule_data passes \p rule, otherwise FALSE - */ gboolean -pe_eval_expr(xmlNode *rule, const pe_rule_eval_data_t *rule_data, - crm_time_t *next_change) -{ - xmlNode *expr = NULL; - gboolean test = TRUE; - gboolean empty = TRUE; - gboolean passed = TRUE; - gboolean do_and = TRUE; - const char *value = NULL; - - rule = expand_idref(rule, NULL); - value = crm_element_value(rule, XML_RULE_ATTR_BOOLEAN_OP); - if (pcmk__str_eq(value, "or", pcmk__str_casei)) { - do_and = FALSE; - passed = FALSE; - } - - crm_trace("Testing rule %s", ID(rule)); - for (expr = pcmk__xe_first_child(rule); expr != NULL; - expr = pcmk__xe_next(expr)) { - - test = pe_eval_subexpr(expr, rule_data, next_change); - empty = FALSE; - - if (test && do_and == FALSE) { - crm_trace("Expression %s/%s passed", ID(rule), ID(expr)); - return TRUE; - - } else if (test == FALSE && do_and) { - crm_trace("Expression %s/%s failed", ID(rule), ID(expr)); - return FALSE; - } - } - - if (empty) { - crm_err("Invalid Rule %s: rules must contain at least one expression", ID(rule)); - } - - crm_trace("Rule %s %s", ID(rule), passed ? "passed" : "failed"); - return passed; -} - -/*! - * \brief Evaluate a single rule expression, including any subexpressions - * - * \param[in,out] expr XML containing a rule expression - * \param[in] rule_data Matching parameters to check against expression - * \param[out] next_change If not NULL, set to when evaluation will change - * - * \return TRUE if \p rule_data passes \p expr, otherwise FALSE - */ -gboolean -pe_eval_subexpr(xmlNode *expr, const pe_rule_eval_data_t *rule_data, - crm_time_t *next_change) -{ - gboolean accept = FALSE; - const char *uname = NULL; - - switch (find_expression_type(expr)) { - case nested_rule: - accept = pe_eval_expr(expr, rule_data, next_change); - break; - case attr_expr: - case loc_expr: - /* these expressions can never succeed if there is - * no node to compare with - */ - if (rule_data->node_hash != NULL) { - accept = pe__eval_attr_expr(expr, rule_data); - } - break; - - case time_expr: - 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: - accept = pe__eval_role_expr(expr, rule_data); - break; - - case rsc_expr: - accept = pe__eval_rsc_expr(expr, rule_data); - break; - - case op_expr: - accept = pe__eval_op_expr(expr, rule_data); - break; - - default: - CRM_CHECK(FALSE /* bad type */ , return FALSE); - accept = FALSE; - } - if (rule_data->node_hash) { - uname = g_hash_table_lookup(rule_data->node_hash, CRM_ATTR_UNAME); - } - - crm_trace("Expression %s %s on %s", - ID(expr), accept ? "passed" : "failed", uname ? uname : "all nodes"); - return accept; -} - -/*! - * \internal - * \brief Compare two values in a rule's node attribute expression - * - * \param[in] l_val Value on left-hand side of comparison - * \param[in] r_val Value on right-hand side of comparison - * \param[in] type How to interpret the values (allowed values: - * \c "string", \c "integer", \c "number", - * \c "version", \c NULL) - * \param[in] op Type of comparison - * - * \return -1 if <tt>(l_val < r_val)</tt>, - * 0 if <tt>(l_val == r_val)</tt>, - * 1 if <tt>(l_val > r_val)</tt> - */ -static int -compare_attr_expr_vals(const char *l_val, const char *r_val, const char *type, - const char *op) -{ - int cmp = 0; - - if (l_val != NULL && r_val != NULL) { - if (type == NULL) { - if (pcmk__strcase_any_of(op, "lt", "lte", "gt", "gte", NULL)) { - if (pcmk__char_in_any_str('.', l_val, r_val, NULL)) { - type = "number"; - } else { - type = "integer"; - } - - } else { - type = "string"; - } - crm_trace("Defaulting to %s based comparison for '%s' op", type, op); - } - - if (pcmk__str_eq(type, "string", pcmk__str_casei)) { - cmp = strcasecmp(l_val, r_val); - - } else if (pcmk__str_eq(type, "integer", pcmk__str_casei)) { - long long l_val_num; - int rc1 = pcmk__scan_ll(l_val, &l_val_num, 0LL); - - long long r_val_num; - int rc2 = pcmk__scan_ll(r_val, &r_val_num, 0LL); - - if ((rc1 == pcmk_rc_ok) && (rc2 == pcmk_rc_ok)) { - if (l_val_num < r_val_num) { - cmp = -1; - } else if (l_val_num > r_val_num) { - cmp = 1; - } else { - cmp = 0; - } - - } else { - crm_debug("Integer parse error. Comparing %s and %s as strings", - l_val, r_val); - cmp = compare_attr_expr_vals(l_val, r_val, "string", op); - } - - } else if (pcmk__str_eq(type, "number", pcmk__str_casei)) { - double l_val_num; - double r_val_num; - - int rc1 = pcmk__scan_double(l_val, &l_val_num, NULL, NULL); - int rc2 = pcmk__scan_double(r_val, &r_val_num, NULL, NULL); - - if (rc1 == pcmk_rc_ok && rc2 == pcmk_rc_ok) { - if (l_val_num < r_val_num) { - cmp = -1; - } else if (l_val_num > r_val_num) { - cmp = 1; - } else { - cmp = 0; - } - - } else { - crm_debug("Floating-point parse error. Comparing %s and %s as " - "strings", l_val, r_val); - cmp = compare_attr_expr_vals(l_val, r_val, "string", op); - } - - } else if (pcmk__str_eq(type, "version", pcmk__str_casei)) { - cmp = compare_version(l_val, r_val); - - } - - } else if (l_val == NULL && r_val == NULL) { - cmp = 0; - } else if (r_val == NULL) { - cmp = 1; - } else { // l_val == NULL && r_val != NULL - cmp = -1; - } - - return cmp; -} - -/*! - * \internal - * \brief Check whether an attribute expression evaluates to \c true - * - * \param[in] l_val Value on left-hand side of comparison - * \param[in] r_val Value on right-hand side of comparison - * \param[in] type How to interpret the values (allowed values: - * \c "string", \c "integer", \c "number", - * \c "version", \c NULL) - * \param[in] op Type of comparison. - * - * \return \c true if expression evaluates to \c true, \c false - * otherwise - */ -static bool -accept_attr_expr(const char *l_val, const char *r_val, const char *type, - const char *op) -{ - int cmp; - - if (pcmk__str_eq(op, "defined", pcmk__str_casei)) { - return (l_val != NULL); - - } else if (pcmk__str_eq(op, "not_defined", pcmk__str_casei)) { - return (l_val == NULL); - - } - - cmp = compare_attr_expr_vals(l_val, r_val, type, op); - - if (pcmk__str_eq(op, "eq", pcmk__str_casei)) { - return (cmp == 0); - - } else if (pcmk__str_eq(op, "ne", pcmk__str_casei)) { - return (cmp != 0); - - } else if (l_val == NULL || r_val == NULL) { - // The comparison is meaningless from this point on - return false; - - } else if (pcmk__str_eq(op, "lt", pcmk__str_casei)) { - return (cmp < 0); - - } else if (pcmk__str_eq(op, "lte", pcmk__str_casei)) { - return (cmp <= 0); - - } else if (pcmk__str_eq(op, "gt", pcmk__str_casei)) { - return (cmp > 0); - - } else if (pcmk__str_eq(op, "gte", pcmk__str_casei)) { - return (cmp >= 0); - } - - return false; // Should never reach this point -} - -/*! - * \internal - * \brief Get correct value according to value-source - * - * \param[in] value value given in rule expression - * \param[in] value_source value-source given in rule expressions - * \param[in] match_data If not NULL, resource back-references and params - */ -static const char * -expand_value_source(const char *value, const char *value_source, - const pe_match_data_t *match_data) -{ - GHashTable *table = NULL; - - if (pcmk__str_empty(value)) { - return NULL; // value_source is irrelevant - - } else if (pcmk__str_eq(value_source, "param", pcmk__str_casei)) { - table = match_data->params; - - } else if (pcmk__str_eq(value_source, "meta", pcmk__str_casei)) { - table = match_data->meta; - - } else { // literal - return value; - } - - if (table == NULL) { - return NULL; - } - return (const char *) g_hash_table_lookup(table, value); -} - -/*! - * \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(const xmlNode *expr, const pe_rule_eval_data_t *rule_data) -{ - gboolean attr_allocated = FALSE; - const char *h_val = NULL; - - const char *op = NULL; - const char *type = NULL; - const char *attr = NULL; - const char *value = NULL; - const char *value_source = NULL; - - attr = crm_element_value(expr, XML_EXPR_ATTR_ATTRIBUTE); - op = crm_element_value(expr, XML_EXPR_ATTR_OPERATION); - value = crm_element_value(expr, XML_EXPR_ATTR_VALUE); - type = crm_element_value(expr, XML_EXPR_ATTR_TYPE); - value_source = crm_element_value(expr, XML_EXPR_ATTR_VALUE_SOURCE); - - if (attr == NULL) { - pe_err("Expression %s invalid: " XML_EXPR_ATTR_ATTRIBUTE - " not specified", pcmk__s(ID(expr), "without ID")); - return FALSE; - } else if (op == NULL) { - pe_err("Expression %s invalid: " XML_EXPR_ATTR_OPERATION - " not specified", pcmk__s(ID(expr), "without ID")); - } - - if (rule_data->match_data != NULL) { - // Expand any regular expression submatches (%0-%9) in attribute name - if (rule_data->match_data->re != NULL) { - char *resolved_attr = pe_expand_re_matches(attr, rule_data->match_data->re); - - if (resolved_attr != NULL) { - attr = (const char *) resolved_attr; - attr_allocated = TRUE; - } - } - - // Get value appropriate to value-source - value = expand_value_source(value, value_source, rule_data->match_data); - } - - if (rule_data->node_hash != NULL) { - h_val = (const char *)g_hash_table_lookup(rule_data->node_hash, attr); - } - - if (attr_allocated) { - free((char *)attr); - attr = NULL; - } - - 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(const xmlNode *expr, const pe_rule_eval_data_t *rule_data, - crm_time_t *next_change) -{ - crm_time_t *start = NULL; - crm_time_t *end = NULL; - const char *value = NULL; - const char *op = crm_element_value(expr, "operation"); - - xmlNode *duration_spec = NULL; - xmlNode *date_spec = NULL; - - // "undetermined" will also be returned for parsing errors - int rc = pcmk_rc_undetermined; - - crm_trace("Testing expression: %s", ID(expr)); - - duration_spec = first_named_child(expr, "duration"); - date_spec = first_named_child(expr, "date_spec"); - - value = crm_element_value(expr, "start"); - if (value != NULL) { - start = crm_time_new(value); - } - value = crm_element_value(expr, "end"); - if (value != NULL) { - end = crm_time_new(value); - } - - if (start != NULL && end == NULL && duration_spec != NULL) { - end = parse_xml_duration(start, duration_spec); - } - - if (pcmk__str_eq(op, "in_range", pcmk__str_null_matches | pcmk__str_casei)) { - if ((start == NULL) && (end == NULL)) { - // in_range requires at least one of start or end - } else if ((start != NULL) && (crm_time_compare(rule_data->now, start) < 0)) { - rc = pcmk_rc_before_range; - crm_time_set_if_earlier(next_change, start); - } else if ((end != NULL) && (crm_time_compare(rule_data->now, end) > 0)) { - rc = pcmk_rc_after_range; - } else { - rc = pcmk_rc_within_range; - if (end && next_change) { - // Evaluation doesn't change until second after end - crm_time_add_seconds(end, 1); - crm_time_set_if_earlier(next_change, end); - } - } - - } else if (pcmk__str_eq(op, "date_spec", pcmk__str_casei)) { - rc = pe_cron_range_satisfied(rule_data->now, date_spec); - // @TODO set next_change appropriately - - } else if (pcmk__str_eq(op, "gt", pcmk__str_casei)) { - if (start == NULL) { - // gt requires start - } else if (crm_time_compare(rule_data->now, start) > 0) { - rc = pcmk_rc_within_range; - } else { - rc = pcmk_rc_before_range; - - // Evaluation doesn't change until second after start - crm_time_add_seconds(start, 1); - crm_time_set_if_earlier(next_change, start); - } - - } else if (pcmk__str_eq(op, "lt", pcmk__str_casei)) { - if (end == NULL) { - // lt requires end - } else if (crm_time_compare(rule_data->now, end) < 0) { - rc = pcmk_rc_within_range; - crm_time_set_if_earlier(next_change, end); - } else { - rc = pcmk_rc_after_range; - } - } - - crm_time_free(start); - crm_time_free(end); - return rc; -} - -gboolean -pe__eval_op_expr(const xmlNode *expr, const pe_rule_eval_data_t *rule_data) +pe_evaluate_rules(xmlNode *ruleset, GHashTable *node_hash, crm_time_t *now, + crm_time_t *next_change) { - const char *name = crm_element_value(expr, XML_NVPAIR_ATTR_NAME); - const char *interval_s = crm_element_value(expr, XML_LRM_ATTR_INTERVAL); - guint interval; - - crm_trace("Testing op_defaults expression: %s", ID(expr)); - - if (rule_data->op_data == NULL) { - crm_trace("No operations data provided"); - return FALSE; - } - - interval = crm_parse_interval_spec(interval_s); - if (interval == 0 && errno != 0) { - crm_trace("Could not parse interval: %s", interval_s); - return FALSE; - } - - if (interval_s != NULL && interval != rule_data->op_data->interval) { - crm_trace("Interval doesn't match: %d != %d", interval, rule_data->op_data->interval); - return FALSE; - } - - if (!pcmk__str_eq(name, rule_data->op_data->op_name, pcmk__str_none)) { - crm_trace("Name doesn't match: %s != %s", name, rule_data->op_data->op_name); - return FALSE; - } + pcmk_rule_input_t rule_input = { + .node_attrs = node_hash, + .now = now, + }; - return TRUE; + return pcmk__evaluate_rules(ruleset, &rule_input, next_change); } -/*! - * \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(const xmlNode *expr, const pe_rule_eval_data_t *rule_data) +pe_test_rule(xmlNode *rule, GHashTable *node_hash, enum rsc_role_e role, + crm_time_t *now, crm_time_t *next_change, + pe_match_data_t *match_data) { - gboolean accept = FALSE; - const char *op = NULL; - const char *value = NULL; - - if (rule_data->role == pcmk_role_unknown) { - return accept; - } - - value = crm_element_value(expr, XML_EXPR_ATTR_VALUE); - op = crm_element_value(expr, XML_EXPR_ATTR_OPERATION); - - if (pcmk__str_eq(op, "defined", pcmk__str_casei)) { - if (rule_data->role > pcmk_role_started) { - accept = TRUE; - } - - } else if (pcmk__str_eq(op, "not_defined", pcmk__str_casei)) { - if ((rule_data->role > pcmk_role_unknown) - && (rule_data->role < pcmk_role_unpromoted)) { - accept = TRUE; - } - - } else if (pcmk__str_eq(op, "eq", pcmk__str_casei)) { - if (text2role(value) == rule_data->role) { - accept = TRUE; - } - - } else if (pcmk__str_eq(op, "ne", pcmk__str_casei)) { - // Test "ne" only with promotable clone roles - if ((rule_data->role > pcmk_role_unknown) - && (rule_data->role < pcmk_role_unpromoted)) { - accept = FALSE; + pcmk_rule_input_t rule_input = { + .node_attrs = node_hash, + .now = now, + }; - } else if (text2role(value) != rule_data->role) { - accept = TRUE; + if (match_data != NULL) { + rule_input.rsc_params = match_data->params; + rule_input.rsc_meta = match_data->meta; + if (match_data->re != NULL) { + rule_input.rsc_id = match_data->re->string; + rule_input.rsc_id_submatches = match_data->re->pmatch; + rule_input.rsc_id_nmatches = match_data->re->nregs; } } - return accept; + return pcmk_evaluate_rule(rule, &rule_input, next_change) == pcmk_rc_ok; } gboolean -pe__eval_rsc_expr(const xmlNode *expr, const pe_rule_eval_data_t *rule_data) -{ - const char *class = crm_element_value(expr, XML_AGENT_ATTR_CLASS); - const char *provider = crm_element_value(expr, XML_AGENT_ATTR_PROVIDER); - const char *type = crm_element_value(expr, XML_EXPR_ATTR_TYPE); - - crm_trace("Testing rsc_defaults expression: %s", ID(expr)); - - if (rule_data->rsc_data == NULL) { - crm_trace("No resource data provided"); - return FALSE; - } - - if (class != NULL && - !pcmk__str_eq(class, rule_data->rsc_data->standard, pcmk__str_none)) { - crm_trace("Class doesn't match: %s != %s", class, rule_data->rsc_data->standard); - return FALSE; - } - - if ((provider == NULL && rule_data->rsc_data->provider != NULL) || - (provider != NULL && rule_data->rsc_data->provider == NULL) || - !pcmk__str_eq(provider, rule_data->rsc_data->provider, pcmk__str_none)) { - crm_trace("Provider doesn't match: %s != %s", provider, rule_data->rsc_data->provider); - return FALSE; - } - - if (type != NULL && - !pcmk__str_eq(type, rule_data->rsc_data->agent, pcmk__str_none)) { - crm_trace("Agent doesn't match: %s != %s", type, rule_data->rsc_data->agent); - return FALSE; - } - - return TRUE; -} - -// Deprecated functions kept only for backward API compatibility -// LCOV_EXCL_START - -#include <crm/pengine/rules_compat.h> - -gboolean test_ruleset(xmlNode *ruleset, GHashTable *node_hash, crm_time_t *now) { return pe_evaluate_rules(ruleset, node_hash, now, NULL); @@ -1272,6 +365,29 @@ pe_test_rule_full(xmlNode *rule, GHashTable *node_hash, enum rsc_role_e role, } gboolean +pe_test_expression(xmlNode *expr, GHashTable *node_hash, enum rsc_role_e role, + crm_time_t *now, crm_time_t *next_change, + pe_match_data_t *match_data) +{ + pcmk_rule_input_t rule_input = { + .now = now, + .node_attrs = node_hash, + }; + + if (match_data != NULL) { + rule_input.rsc_params = match_data->params; + rule_input.rsc_meta = match_data->meta; + if (match_data->re != NULL) { + rule_input.rsc_id = match_data->re->string; + rule_input.rsc_id_submatches = match_data->re->pmatch; + rule_input.rsc_id_nmatches = match_data->re->nregs; + } + } + return pcmk__evaluate_condition(expr, &rule_input, + next_change) == pcmk_rc_ok; +} + +gboolean test_expression(xmlNode * expr, GHashTable * node_hash, enum rsc_role_e role, crm_time_t * now) { return pe_test_expression(expr, node_hash, role, now, NULL, NULL); @@ -1296,6 +412,27 @@ pe_test_expression_full(xmlNode *expr, GHashTable *node_hash, return pe_test_expression(expr, node_hash, role, now, NULL, match_data); } +gboolean +pe_eval_expr(xmlNode *rule, const pe_rule_eval_data_t *rule_data, + crm_time_t *next_change) +{ + pcmk_rule_input_t rule_input = { NULL, }; + + map_rule_input(&rule_input, rule_data); + return pcmk_evaluate_rule(rule, &rule_input, next_change) == pcmk_rc_ok; +} + +gboolean +pe_eval_subexpr(xmlNode *expr, const pe_rule_eval_data_t *rule_data, + crm_time_t *next_change) +{ + pcmk_rule_input_t rule_input = { NULL, }; + + map_rule_input(&rule_input, rule_data); + return pcmk__evaluate_condition(expr, &rule_input, + next_change) == pcmk_rc_ok; +} + void unpack_instance_attributes(xmlNode *top, xmlNode *xml_obj, const char *set_name, GHashTable *node_hash, GHashTable *hash, @@ -1304,16 +441,31 @@ unpack_instance_attributes(xmlNode *top, xmlNode *xml_obj, const char *set_name, { pe_rule_eval_data_t rule_data = { .node_hash = node_hash, - .role = pcmk_role_unknown, .now = now, .match_data = NULL, .rsc_data = NULL, .op_data = NULL }; - pe_eval_nvpairs(top, xml_obj, set_name, &rule_data, hash, always_first, + pe_eval_nvpairs(NULL, xml_obj, set_name, &rule_data, hash, always_first, overwrite, NULL); } +enum expression_type +find_expression_type(xmlNode *expr) +{ + return pcmk__condition_type(expr); +} + +char * +pe_expand_re_matches(const char *string, const pe_re_match_data_t *match_data) +{ + if (match_data == NULL) { + return NULL; + } + return pcmk__replace_submatches(string, match_data->string, + match_data->pmatch, match_data->nregs); +} + // LCOV_EXCL_STOP // End deprecated API diff --git a/lib/pengine/rules_alerts.c b/lib/pengine/rules_alerts.c index 9eed7ff..73351c7 100644 --- a/lib/pengine/rules_alerts.c +++ b/lib/pengine/rules_alerts.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2023 the Pacemaker project contributors + * Copyright 2015-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -9,7 +9,7 @@ #include <crm_internal.h> #include <crm/crm.h> -#include <crm/msg_xml.h> +#include <crm/common/xml.h> #include <crm/pengine/rules.h> #include <crm/common/alerts_internal.h> #include <crm/common/xml_internal.h> @@ -34,8 +34,8 @@ get_meta_attrs_from_cib(xmlNode *basenode, pcmk__alert_t *entry, const char *value = NULL; int rc = pcmk_rc_ok; - pe_unpack_nvpairs(basenode, basenode, XML_TAG_META_SETS, NULL, config_hash, - NULL, FALSE, now, NULL); + pe_unpack_nvpairs(basenode, basenode, PCMK_XE_META_ATTRIBUTES, NULL, + config_hash, NULL, FALSE, now, NULL); crm_time_free(now); value = g_hash_table_lookup(config_hash, PCMK_META_ENABLED); @@ -45,16 +45,20 @@ get_meta_attrs_from_cib(xmlNode *basenode, pcmk__alert_t *entry, goto done; } - value = g_hash_table_lookup(config_hash, XML_ALERT_ATTR_TIMEOUT); + value = g_hash_table_lookup(config_hash, PCMK_META_TIMEOUT); if (value) { - entry->timeout = crm_get_msec(value); + long long timeout_ms = crm_get_msec(value); + + entry->timeout = (int) QB_MIN(timeout_ms, INT_MAX); if (entry->timeout <= 0) { if (entry->timeout == 0) { crm_trace("Alert %s uses default timeout of %dmsec", entry->id, PCMK__ALERT_DEFAULT_TIMEOUT_MS); } else { - crm_warn("Alert %s has invalid timeout value '%s', using default %dmsec", - entry->id, (char*)value, PCMK__ALERT_DEFAULT_TIMEOUT_MS); + pcmk__config_warn("Alert %s has invalid timeout value '%s', " + "using default (%d ms)", + entry->id, value, + PCMK__ALERT_DEFAULT_TIMEOUT_MS); } entry->timeout = PCMK__ALERT_DEFAULT_TIMEOUT_MS; } else { @@ -65,7 +69,7 @@ get_meta_attrs_from_cib(xmlNode *basenode, pcmk__alert_t *entry, *max_timeout = entry->timeout; } } - value = g_hash_table_lookup(config_hash, XML_ALERT_ATTR_TSTAMP_FORMAT); + value = g_hash_table_lookup(config_hash, PCMK_META_TIMESTAMP_FORMAT); if (value) { /* hard to do any checks here as merely anything can * can be a valid time-format-string @@ -89,7 +93,8 @@ get_envvars_from_cib(xmlNode *basenode, pcmk__alert_t *entry) return; } - child = first_named_child(basenode, XML_TAG_ATTR_SETS); + child = pcmk__xe_first_child(basenode, PCMK_XE_INSTANCE_ATTRIBUTES, NULL, + NULL); if (child == NULL) { return; } @@ -98,16 +103,16 @@ get_envvars_from_cib(xmlNode *basenode, pcmk__alert_t *entry) entry->envvars = pcmk__strkey_table(free, free); } - for (child = first_named_child(child, XML_CIB_TAG_NVPAIR); child != NULL; - child = crm_next_same_xml(child)) { + for (child = pcmk__xe_first_child(child, PCMK_XE_NVPAIR, NULL, NULL); + child != NULL; child = pcmk__xe_next_same(child)) { - const char *name = crm_element_value(child, XML_NVPAIR_ATTR_NAME); - const char *value = crm_element_value(child, XML_NVPAIR_ATTR_VALUE); + const char *name = crm_element_value(child, PCMK_XA_NAME); + const char *value = crm_element_value(child, PCMK_XA_VALUE); if (value == NULL) { value = ""; } - g_hash_table_insert(entry->envvars, strdup(name), strdup(value)); + pcmk__insert_dup(entry->envvars, name, value); crm_trace("Alert %s: added environment variable %s='%s'", entry->id, name, value); } @@ -116,33 +121,34 @@ get_envvars_from_cib(xmlNode *basenode, pcmk__alert_t *entry) static void unpack_alert_filter(xmlNode *basenode, pcmk__alert_t *entry) { - xmlNode *select = first_named_child(basenode, XML_CIB_TAG_ALERT_SELECT); + xmlNode *select = pcmk__xe_first_child(basenode, PCMK_XE_SELECT, NULL, + NULL); xmlNode *event_type = NULL; uint32_t flags = pcmk__alert_none; - for (event_type = pcmk__xe_first_child(select); event_type != NULL; - event_type = pcmk__xe_next(event_type)) { + for (event_type = pcmk__xe_first_child(select, NULL, NULL, NULL); + event_type != NULL; event_type = pcmk__xe_next(event_type)) { - if (pcmk__xe_is(event_type, XML_CIB_TAG_ALERT_FENCING)) { + if (pcmk__xe_is(event_type, PCMK_XE_SELECT_FENCING)) { flags |= pcmk__alert_fencing; - } else if (pcmk__xe_is(event_type, XML_CIB_TAG_ALERT_NODES)) { + } else if (pcmk__xe_is(event_type, PCMK_XE_SELECT_NODES)) { flags |= pcmk__alert_node; - } else if (pcmk__xe_is(event_type, XML_CIB_TAG_ALERT_RESOURCES)) { + } else if (pcmk__xe_is(event_type, PCMK_XE_SELECT_RESOURCES)) { flags |= pcmk__alert_resource; - } else if (pcmk__xe_is(event_type, XML_CIB_TAG_ALERT_ATTRIBUTES)) { + } else if (pcmk__xe_is(event_type, PCMK_XE_SELECT_ATTRIBUTES)) { xmlNode *attr; const char *attr_name; int nattrs = 0; flags |= pcmk__alert_attribute; - for (attr = first_named_child(event_type, XML_CIB_TAG_ALERT_ATTR); - attr != NULL; - attr = crm_next_same_xml(attr)) { + for (attr = pcmk__xe_first_child(event_type, PCMK_XE_ATTRIBUTE, + NULL, NULL); + attr != NULL; attr = pcmk__xe_next_same(attr)) { - attr_name = crm_element_value(attr, XML_NVPAIR_ATTR_NAME); + attr_name = crm_element_value(attr, PCMK_XA_NAME); if (attr_name) { if (nattrs == 0) { g_strfreev(entry->select_attribute_name); @@ -216,17 +222,22 @@ pe_unpack_alerts(const xmlNode *alerts) return alert_list; } - for (alert = first_named_child(alerts, XML_CIB_TAG_ALERT); - alert != NULL; alert = crm_next_same_xml(alert)) { + for (alert = pcmk__xe_first_child(alerts, PCMK_XE_ALERT, NULL, NULL); + alert != NULL; alert = pcmk__xe_next_same(alert)) { xmlNode *recipient; int recipients = 0; - const char *alert_id = ID(alert); - const char *alert_path = crm_element_value(alert, XML_ALERT_ATTR_PATH); + const char *alert_id = pcmk__xe_id(alert); + const char *alert_path = crm_element_value(alert, PCMK_XA_PATH); /* The schema should enforce this, but to be safe ... */ - if ((alert_id == NULL) || (alert_path == NULL)) { - crm_warn("Ignoring invalid alert without id and path"); + if (alert_id == NULL) { + pcmk__config_warn("Ignoring invalid alert without " PCMK_XA_ID); + crm_log_xml_info(alert, "missing-id"); + continue; + } + if (alert_path == NULL) { + pcmk__config_warn("Ignoring alert %s: No " PCMK_XA_PATH, alert_id); continue; } @@ -247,14 +258,15 @@ pe_unpack_alerts(const xmlNode *alerts) entry->id, entry->path, entry->timeout, entry->tstamp_format, (entry->envvars? g_hash_table_size(entry->envvars) : 0)); - for (recipient = first_named_child(alert, XML_CIB_TAG_ALERT_RECIPIENT); - recipient != NULL; recipient = crm_next_same_xml(recipient)) { + for (recipient = pcmk__xe_first_child(alert, PCMK_XE_RECIPIENT, NULL, + NULL); + recipient != NULL; recipient = pcmk__xe_next_same(recipient)) { pcmk__alert_t *recipient_entry = pcmk__dup_alert(entry); recipients++; - recipient_entry->recipient = strdup(crm_element_value(recipient, - XML_ALERT_ATTR_REC_VALUE)); + recipient_entry->recipient = crm_element_value_copy(recipient, + PCMK_XA_VALUE); if (unpack_alert(recipient, recipient_entry, &max_timeout) != pcmk_rc_ok) { @@ -265,7 +277,8 @@ pe_unpack_alerts(const xmlNode *alerts) } alert_list = g_list_prepend(alert_list, recipient_entry); crm_debug("Alert %s has recipient %s with value %s and %d envvars", - entry->id, ID(recipient), recipient_entry->recipient, + entry->id, pcmk__xe_id(recipient), + recipient_entry->recipient, (recipient_entry->envvars? g_hash_table_size(recipient_entry->envvars) : 0)); } diff --git a/lib/pengine/status.c b/lib/pengine/status.c index e6ec237..36209da 100644 --- a/lib/pengine/status.c +++ b/lib/pengine/status.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2023 the Pacemaker project contributors + * Copyright 2004-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -12,8 +12,8 @@ #include <sys/param.h> #include <crm/crm.h> -#include <crm/msg_xml.h> #include <crm/common/xml.h> +#include <crm/common/cib_internal.h> #include <glib.h> @@ -56,6 +56,31 @@ pe_free_working_set(pcmk_scheduler_t *scheduler) } } +#define XPATH_DEPRECATED_RULES \ + "//" PCMK_XE_OP_DEFAULTS "//" PCMK_XE_EXPRESSION \ + "|//" PCMK_XE_OP "//" PCMK_XE_EXPRESSION + +/*! + * \internal + * \brief Log a warning for deprecated rule syntax in operations + * + * \param[in] scheduler Scheduler data + */ +static void +check_for_deprecated_rules(pcmk_scheduler_t *scheduler) +{ + // @COMPAT Drop this function when support for the syntax is dropped + xmlNode *deprecated = get_xpath_object(XPATH_DEPRECATED_RULES, + scheduler->input, LOG_NEVER); + + if (deprecated != NULL) { + pcmk__warn_once(pcmk__wo_op_attr_expr, + "Support for rules with node attribute expressions in " + PCMK_XE_OP " or " PCMK_XE_OP_DEFAULTS " is deprecated " + "and will be dropped in a future release"); + } +} + /* * Unpack everything * At the end you'll have: @@ -70,18 +95,27 @@ pe_free_working_set(pcmk_scheduler_t *scheduler) gboolean cluster_status(pcmk_scheduler_t * scheduler) { + const char *new_version = NULL; xmlNode *section = NULL; if ((scheduler == NULL) || (scheduler->input == NULL)) { return FALSE; } + new_version = crm_element_value(scheduler->input, PCMK_XA_CRM_FEATURE_SET); + + if (pcmk__check_feature_set(new_version) != pcmk_rc_ok) { + pcmk__config_err("Can't process CIB with feature set '%s' greater than our own '%s'", + new_version, CRM_FEATURE_SET); + return FALSE; + } + crm_trace("Beginning unpack"); if (scheduler->failed != NULL) { free_xml(scheduler->failed); } - scheduler->failed = create_xml_node(NULL, "failed-ops"); + scheduler->failed = pcmk__xe_create(NULL, "failed-ops"); if (scheduler->now == NULL) { scheduler->now = crm_time_new(NULL); @@ -89,47 +123,48 @@ cluster_status(pcmk_scheduler_t * scheduler) if (scheduler->dc_uuid == NULL) { scheduler->dc_uuid = crm_element_value_copy(scheduler->input, - XML_ATTR_DC_UUID); + PCMK_XA_DC_UUID); } - if (pcmk__xe_attr_is_true(scheduler->input, XML_ATTR_HAVE_QUORUM)) { - pe__set_working_set_flags(scheduler, pcmk_sched_quorate); + if (pcmk__xe_attr_is_true(scheduler->input, PCMK_XA_HAVE_QUORUM)) { + pcmk__set_scheduler_flags(scheduler, pcmk_sched_quorate); } else { - pe__clear_working_set_flags(scheduler, pcmk_sched_quorate); + pcmk__clear_scheduler_flags(scheduler, pcmk_sched_quorate); } - scheduler->op_defaults = get_xpath_object("//" XML_CIB_TAG_OPCONFIG, + scheduler->op_defaults = get_xpath_object("//" PCMK_XE_OP_DEFAULTS, scheduler->input, LOG_NEVER); - scheduler->rsc_defaults = get_xpath_object("//" XML_CIB_TAG_RSCCONFIG, + check_for_deprecated_rules(scheduler); + + scheduler->rsc_defaults = get_xpath_object("//" PCMK_XE_RSC_DEFAULTS, scheduler->input, LOG_NEVER); - section = get_xpath_object("//" XML_CIB_TAG_CRMCONFIG, scheduler->input, + section = get_xpath_object("//" PCMK_XE_CRM_CONFIG, scheduler->input, LOG_TRACE); unpack_config(section, scheduler); if (!pcmk_any_flags_set(scheduler->flags, pcmk_sched_location_only|pcmk_sched_quorate) && (scheduler->no_quorum_policy != pcmk_no_quorum_ignore)) { - crm_warn("Fencing and resource management disabled due to lack of quorum"); + pcmk__sched_warn("Fencing and resource management disabled " + "due to lack of quorum"); } - section = get_xpath_object("//" XML_CIB_TAG_NODES, scheduler->input, - LOG_TRACE); + section = get_xpath_object("//" PCMK_XE_NODES, scheduler->input, LOG_TRACE); unpack_nodes(section, scheduler); - section = get_xpath_object("//" XML_CIB_TAG_RESOURCES, scheduler->input, + section = get_xpath_object("//" PCMK_XE_RESOURCES, scheduler->input, LOG_TRACE); if (!pcmk_is_set(scheduler->flags, pcmk_sched_location_only)) { unpack_remote_nodes(section, scheduler); } unpack_resources(section, scheduler); - section = get_xpath_object("//" XML_CIB_TAG_TAGS, scheduler->input, - LOG_NEVER); + section = get_xpath_object("//" PCMK_XE_TAGS, scheduler->input, LOG_NEVER); unpack_tags(section, scheduler); if (!pcmk_is_set(scheduler->flags, pcmk_sched_location_only)) { - section = get_xpath_object("//"XML_CIB_TAG_STATUS, scheduler->input, + section = get_xpath_object("//" PCMK_XE_STATUS, scheduler->input, LOG_TRACE); unpack_status(section, scheduler); } @@ -144,7 +179,7 @@ cluster_status(pcmk_scheduler_t * scheduler) scheduler->blocked_resources); } - pe__set_working_set_flags(scheduler, pcmk_sched_have_status); + pcmk__set_scheduler_flags(scheduler, pcmk_sched_have_status); return TRUE; } @@ -207,8 +242,8 @@ pe_free_nodes(GList *nodes) /* This is called after pe_free_resources(), which means that we can't * use node->details->uname for Pacemaker Remote nodes. */ - crm_trace("Freeing node %s", (pe__is_guest_or_remote_node(node)? - "(guest or remote)" : pe__node_name(node))); + crm_trace("Freeing node %s", (pcmk__is_pacemaker_remote_node(node)? + "(guest or remote)" : pcmk__node_name(node))); if (node->details->attrs != NULL) { g_hash_table_destroy(node->details->attrs); @@ -235,12 +270,12 @@ pe__free_ordering(GList *constraints) GList *iterator = constraints; while (iterator != NULL) { - pe__ordering_t *order = iterator->data; + pcmk__action_relation_t *order = iterator->data; iterator = iterator->next; - free(order->lh_action_task); - free(order->rh_action_task); + free(order->task1); + free(order->task2); free(order); } if (constraints != NULL) { @@ -254,11 +289,11 @@ pe__free_location(GList *constraints) GList *iterator = constraints; while (iterator != NULL) { - pe__location_t *cons = iterator->data; + pcmk__location_t *cons = iterator->data; iterator = iterator->next; - g_list_free_full(cons->node_list_rh, free); + g_list_free_full(cons->nodes, free); free(cons->id); free(cons); } @@ -282,7 +317,7 @@ cleanup_calculations(pcmk_scheduler_t *scheduler) return; } - pe__clear_working_set_flags(scheduler, pcmk_sched_have_status); + pcmk__clear_scheduler_flags(scheduler, pcmk_sched_have_status); if (scheduler->config_hash != NULL) { g_hash_table_destroy(scheduler->config_hash); } @@ -378,12 +413,12 @@ set_working_set_defaults(pcmk_scheduler_t *scheduler) scheduler->flags = 0x0ULL; - pe__set_working_set_flags(scheduler, + pcmk__set_scheduler_flags(scheduler, pcmk_sched_symmetric_cluster |pcmk_sched_stop_removed_resources |pcmk_sched_cancel_removed_actions); - if (!strcmp(PCMK__CONCURRENT_FENCING_DEFAULT, "true")) { - pe__set_working_set_flags(scheduler, pcmk_sched_concurrent_fencing); + if (!strcmp(PCMK__CONCURRENT_FENCING_DEFAULT, PCMK_VALUE_TRUE)) { + pcmk__set_scheduler_flags(scheduler, pcmk_sched_concurrent_fencing); } } @@ -431,7 +466,7 @@ pe_find_node_any(const GList *nodes, const char *id, const char *uname) match = pe_find_node_id(nodes, id); } if ((match == NULL) && (uname != NULL)) { - match = pe_find_node(nodes, uname); + match = pcmk__find_node_in_list(nodes, uname); } return match; } @@ -461,6 +496,11 @@ pe_find_node_id(const GList *nodes, const char *id) return NULL; } +// Deprecated functions kept only for backward API compatibility +// LCOV_EXCL_START + +#include <crm/pengine/status_compat.h> + /*! * \brief Find a node by name in a list of nodes * @@ -472,12 +512,8 @@ pe_find_node_id(const GList *nodes, const char *id) pcmk_node_t * pe_find_node(const GList *nodes, const char *node_name) { - for (const GList *iter = nodes; iter != NULL; iter = iter->next) { - pcmk_node_t *node = (pcmk_node_t *) iter->data; - - if (pcmk__str_eq(node->details->uname, node_name, pcmk__str_casei)) { - return node; - } - } - return NULL; + return pcmk__find_node_in_list(nodes, node_name); } + +// LCOV_EXCL_STOP +// End deprecated API diff --git a/lib/pengine/tests/Makefile.am b/lib/pengine/tests/Makefile.am index 48ec5b4..52a0ff6 100644 --- a/lib/pengine/tests/Makefile.am +++ b/lib/pengine/tests/Makefile.am @@ -1,14 +1,14 @@ # -# Copyright 2020-2023 the Pacemaker project contributors +# Copyright 2020-2024 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. # +MAINTAINERCLEANFILES = Makefile.in -SUBDIRS = rules \ - native \ +SUBDIRS = native \ status \ unpack \ utils diff --git a/lib/pengine/tests/native/native_find_rsc_test.c b/lib/pengine/tests/native/native_find_rsc_test.c index b85ca24..ac1337d 100644 --- a/lib/pengine/tests/native/native_find_rsc_test.c +++ b/lib/pengine/tests/native/native_find_rsc_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 the Pacemaker project contributors + * Copyright 2022-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -30,7 +30,7 @@ setup(void **state) { crm_xml_init(); path = crm_strdup_printf("%s/crm_mon.xml", getenv("PCMK_CTS_CLI_DIR")); - input = filename2xml(path); + input = pcmk__xml_read(path); free(path); if (input == NULL) { @@ -43,16 +43,16 @@ setup(void **state) { return 1; } - pe__set_working_set_flags(scheduler, + pcmk__set_scheduler_flags(scheduler, pcmk_sched_no_counts|pcmk_sched_no_compat); scheduler->input = input; cluster_status(scheduler); /* Get references to the cluster nodes so we don't have to find them repeatedly. */ - cluster01 = pe_find_node(scheduler->nodes, "cluster01"); - cluster02 = pe_find_node(scheduler->nodes, "cluster02"); - httpd_bundle_0 = pe_find_node(scheduler->nodes, "httpd-bundle-0"); + cluster01 = pcmk_find_node(scheduler, "cluster01"); + cluster02 = pcmk_find_node(scheduler, "cluster02"); + httpd_bundle_0 = pcmk_find_node(scheduler, "httpd-bundle-0"); /* Get references to several resources we use frequently. */ for (GList *iter = scheduler->resources; iter != NULL; iter = iter->next) { @@ -539,7 +539,7 @@ bundle_rsc(void **state) { } static bool -bundle_first_replica(pe__bundle_replica_t *replica, void *user_data) +bundle_first_replica(pcmk__bundle_replica_t *replica, void *user_data) { pcmk_resource_t *ip_0 = replica->ip; pcmk_resource_t *child_0 = replica->child; diff --git a/lib/pengine/tests/native/pe_base_name_eq_test.c b/lib/pengine/tests/native/pe_base_name_eq_test.c index cb3c908..68112bb 100644 --- a/lib/pengine/tests/native/pe_base_name_eq_test.c +++ b/lib/pengine/tests/native/pe_base_name_eq_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 the Pacemaker project contributors + * Copyright 2022-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -29,7 +29,7 @@ setup(void **state) { crm_xml_init(); path = crm_strdup_printf("%s/crm_mon.xml", getenv("PCMK_CTS_CLI_DIR")); - input = filename2xml(path); + input = pcmk__xml_read(path); free(path); if (input == NULL) { @@ -42,7 +42,7 @@ setup(void **state) { return 1; } - pe__set_working_set_flags(scheduler, + pcmk__set_scheduler_flags(scheduler, pcmk_sched_no_counts|pcmk_sched_no_compat); scheduler->input = input; diff --git a/lib/pengine/tests/rules/Makefile.am b/lib/pengine/tests/rules/Makefile.am deleted file mode 100644 index 261ec16..0000000 --- a/lib/pengine/tests/rules/Makefile.am +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright 2020-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. -# - -include $(top_srcdir)/mk/tap.mk -include $(top_srcdir)/mk/unittest.mk - -LDADD += $(top_builddir)/lib/pengine/libpe_rules_test.la - -# Add "_test" to the end of all test program names to simplify .gitignore. -check_PROGRAMS = pe_cron_range_satisfied_test - -TESTS = $(check_PROGRAMS) diff --git a/lib/pengine/tests/rules/pe_cron_range_satisfied_test.c b/lib/pengine/tests/rules/pe_cron_range_satisfied_test.c deleted file mode 100644 index a8ba6cf..0000000 --- a/lib/pengine/tests/rules/pe_cron_range_satisfied_test.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2020-2022 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. - */ - -#include <crm_internal.h> - -#include <glib.h> - -#include <crm/msg_xml.h> -#include <crm/common/unittest_internal.h> -#include <crm/common/xml.h> -#include <crm/pengine/rules_internal.h> - -static void -run_one_test(const char *t, const char *x, int expected) { - crm_time_t *tm = crm_time_new(t); - xmlNodePtr xml = string2xml(x); - - assert_int_equal(pe_cron_range_satisfied(tm, xml), expected); - - crm_time_free(tm); - free_xml(xml); -} - -static void -no_time_given(void **state) { - assert_int_equal(pe_cron_range_satisfied(NULL, NULL), pcmk_rc_op_unsatisfied); -} - -static void -any_time_satisfies_empty_spec(void **state) { - crm_time_t *tm = crm_time_new(NULL); - - assert_int_equal(pe_cron_range_satisfied(tm, NULL), pcmk_rc_ok); - - crm_time_free(tm); -} - -static void -time_satisfies_year_spec(void **state) { - run_one_test("2020-01-01", - "<date_spec " XML_ATTR_ID "='spec' years='2020'/>", - pcmk_rc_ok); -} - -static void -time_after_year_spec(void **state) { - run_one_test("2020-01-01", - "<date_spec " XML_ATTR_ID "='spec' years='2019'/>", - pcmk_rc_after_range); -} - -static void -time_satisfies_year_range(void **state) { - run_one_test("2020-01-01", - "<date_spec " XML_ATTR_ID "='spec' years='2010-2030'/>", - pcmk_rc_ok); -} - -static void -time_before_year_range(void **state) { - run_one_test("2000-01-01", - "<date_spec " XML_ATTR_ID "='spec' years='2010-2030'/>", - pcmk_rc_before_range); -} - -static void -time_after_year_range(void **state) { - run_one_test("2020-01-01", - "<date_spec " XML_ATTR_ID "='spec' years='2010-2015'/>", - pcmk_rc_after_range); -} - -static void -range_without_start_year_passes(void **state) { - run_one_test("2010-01-01", - "<date_spec " XML_ATTR_ID "='spec' years='-2020'/>", - pcmk_rc_ok); -} - -static void -range_without_end_year_passes(void **state) { - run_one_test("2010-01-01", - "<date_spec " XML_ATTR_ID "='spec' years='2000-'/>", - pcmk_rc_ok); - run_one_test("2000-10-01", - "<date_spec " XML_ATTR_ID "='spec' years='2000-'/>", - pcmk_rc_ok); -} - -static void -yeardays_satisfies(void **state) { - run_one_test("2020-01-30", - "<date_spec " XML_ATTR_ID "='spec' yeardays='30'/>", - pcmk_rc_ok); -} - -static void -time_after_yeardays_spec(void **state) { - run_one_test("2020-02-15", - "<date_spec " XML_ATTR_ID "='spec' yeardays='40'/>", - pcmk_rc_after_range); -} - -static void -yeardays_feb_29_satisfies(void **state) { - run_one_test("2016-02-29", - "<date_spec " XML_ATTR_ID "='spec' yeardays='60'/>", - pcmk_rc_ok); -} - -static void -exact_ymd_satisfies(void **state) { - run_one_test("2001-12-31", - "<date_spec " XML_ATTR_ID "='spec' years='2001' months='12' " - "monthdays='31'/>", - pcmk_rc_ok); -} - -static void -range_in_month_satisfies(void **state) { - run_one_test("2001-06-10", - "<date_spec " XML_ATTR_ID "='spec' years='2001' months='6' " - "monthdays='1-10'/>", - pcmk_rc_ok); -} - -static void -exact_ymd_after_range(void **state) { - run_one_test("2001-12-31", - "<date_spec " XML_ATTR_ID "='spec' years='2001' months='12' " - "monthdays='30'/>", - pcmk_rc_after_range); -} - -static void -time_after_monthdays_range(void **state) { - run_one_test("2001-06-10", - "<date_spec " XML_ATTR_ID "='spec' years='2001' months='6' " - "monthdays='11-15'/>", - pcmk_rc_before_range); -} - -PCMK__UNIT_TEST(NULL, NULL, - cmocka_unit_test(no_time_given), - cmocka_unit_test(any_time_satisfies_empty_spec), - cmocka_unit_test(time_satisfies_year_spec), - cmocka_unit_test(time_after_year_spec), - cmocka_unit_test(time_satisfies_year_range), - cmocka_unit_test(time_before_year_range), - cmocka_unit_test(time_after_year_range), - cmocka_unit_test(range_without_start_year_passes), - cmocka_unit_test(range_without_end_year_passes), - cmocka_unit_test(yeardays_satisfies), - cmocka_unit_test(time_after_yeardays_spec), - cmocka_unit_test(yeardays_feb_29_satisfies), - cmocka_unit_test(exact_ymd_satisfies), - cmocka_unit_test(range_in_month_satisfies), - cmocka_unit_test(exact_ymd_after_range), - cmocka_unit_test(time_after_monthdays_range)) diff --git a/lib/pengine/tests/status/Makefile.am b/lib/pengine/tests/status/Makefile.am index c7ddb70..f91d150 100644 --- a/lib/pengine/tests/status/Makefile.am +++ b/lib/pengine/tests/status/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2022-2023 the Pacemaker project contributors +# Copyright 2022-2024 the Pacemaker project contributors # # The version control history for this file may have further details. # @@ -15,7 +15,6 @@ LDADD += $(top_builddir)/lib/pengine/libpe_status_test.la # Add "_test" to the end of all test program names to simplify .gitignore. check_PROGRAMS = pe_find_node_any_test \ pe_find_node_id_test \ - pe_find_node_test \ pe_new_working_set_test \ set_working_set_defaults_test diff --git a/lib/pengine/tests/status/pe_find_node_any_test.c b/lib/pengine/tests/status/pe_find_node_any_test.c index 5f5a27e..bbe046b 100644 --- a/lib/pengine/tests/status/pe_find_node_any_test.c +++ b/lib/pengine/tests/status/pe_find_node_any_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 the Pacemaker project contributors + * Copyright 2022-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -24,13 +24,13 @@ static void non_null_list(void **state) { GList *nodes = NULL; - pcmk_node_t *a = calloc(1, sizeof(pcmk_node_t)); - pcmk_node_t *b = calloc(1, sizeof(pcmk_node_t)); + pcmk_node_t *a = pcmk__assert_alloc(1, sizeof(pcmk_node_t)); + pcmk_node_t *b = pcmk__assert_alloc(1, sizeof(pcmk_node_t)); - a->details = calloc(1, sizeof(struct pe_node_shared_s)); + a->details = pcmk__assert_alloc(1, sizeof(struct pe_node_shared_s)); a->details->uname = "cluster1"; a->details->id = "id1"; - b->details = calloc(1, sizeof(struct pe_node_shared_s)); + b->details = pcmk__assert_alloc(1, sizeof(struct pe_node_shared_s)); b->details->uname = "cluster2"; b->details->id = "id2"; diff --git a/lib/pengine/tests/status/pe_find_node_id_test.c b/lib/pengine/tests/status/pe_find_node_id_test.c index c6b8773..694d760 100644 --- a/lib/pengine/tests/status/pe_find_node_id_test.c +++ b/lib/pengine/tests/status/pe_find_node_id_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 the Pacemaker project contributors + * Copyright 2022-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -22,12 +22,12 @@ static void non_null_list(void **state) { GList *nodes = NULL; - pcmk_node_t *a = calloc(1, sizeof(pcmk_node_t)); - pcmk_node_t *b = calloc(1, sizeof(pcmk_node_t)); + pcmk_node_t *a = pcmk__assert_alloc(1, sizeof(pcmk_node_t)); + pcmk_node_t *b = pcmk__assert_alloc(1, sizeof(pcmk_node_t)); - a->details = calloc(1, sizeof(struct pe_node_shared_s)); + a->details = pcmk__assert_alloc(1, sizeof(struct pe_node_shared_s)); a->details->id = "id1"; - b->details = calloc(1, sizeof(struct pe_node_shared_s)); + b->details = pcmk__assert_alloc(1, sizeof(struct pe_node_shared_s)); b->details->id = "id2"; nodes = g_list_append(nodes, a); diff --git a/lib/pengine/tests/status/pe_find_node_test.c b/lib/pengine/tests/status/pe_find_node_test.c deleted file mode 100644 index 305ddc9..0000000 --- a/lib/pengine/tests/status/pe_find_node_test.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2022-2023 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. - */ - -#include <crm_internal.h> - -#include <crm/common/unittest_internal.h> -#include <crm/pengine/internal.h> - -static void -empty_list(void **state) { - assert_null(pe_find_node(NULL, NULL)); - assert_null(pe_find_node(NULL, "cluster1")); -} - -static void -non_null_list(void **state) { - GList *nodes = NULL; - - pcmk_node_t *a = calloc(1, sizeof(pcmk_node_t)); - pcmk_node_t *b = calloc(1, sizeof(pcmk_node_t)); - - a->details = calloc(1, sizeof(struct pe_node_shared_s)); - a->details->uname = "cluster1"; - b->details = calloc(1, sizeof(struct pe_node_shared_s)); - b->details->uname = "cluster2"; - - nodes = g_list_append(nodes, a); - nodes = g_list_append(nodes, b); - - assert_ptr_equal(a, pe_find_node(nodes, "cluster1")); - assert_null(pe_find_node(nodes, "cluster10")); - assert_null(pe_find_node(nodes, "nodecluster1")); - assert_ptr_equal(b, pe_find_node(nodes, "CLUSTER2")); - assert_null(pe_find_node(nodes, "xyz")); - - free(a->details); - free(a); - free(b->details); - free(b); - g_list_free(nodes); -} - -PCMK__UNIT_TEST(NULL, NULL, - cmocka_unit_test(empty_list), - cmocka_unit_test(non_null_list)) diff --git a/lib/pengine/tests/status/set_working_set_defaults_test.c b/lib/pengine/tests/status/set_working_set_defaults_test.c index 7045a33..546cd8a 100644 --- a/lib/pengine/tests/status/set_working_set_defaults_test.c +++ b/lib/pengine/tests/status/set_working_set_defaults_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2023 the Pacemaker project contributors + * Copyright 2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -20,7 +20,8 @@ static void check_defaults(void **state) { uint32_t flags; - pcmk_scheduler_t *scheduler = calloc(1, sizeof(pcmk_scheduler_t)); + pcmk_scheduler_t *scheduler = pcmk__assert_alloc(1, + sizeof(pcmk_scheduler_t)); set_working_set_defaults(scheduler); @@ -28,7 +29,7 @@ check_defaults(void **state) { |pcmk_sched_stop_removed_resources |pcmk_sched_cancel_removed_actions; - if (!strcmp(PCMK__CONCURRENT_FENCING_DEFAULT, "true")) { + if (!strcmp(PCMK__CONCURRENT_FENCING_DEFAULT, PCMK_VALUE_TRUE)) { flags |= pcmk_sched_concurrent_fencing; } diff --git a/lib/pengine/unpack.c b/lib/pengine/unpack.c index 3429d56..de623d4 100644 --- a/lib/pengine/unpack.c +++ b/lib/pengine/unpack.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2023 the Pacemaker project contributors + * Copyright 2004-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -16,7 +16,6 @@ #include <crm/crm.h> #include <crm/services.h> -#include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crm/common/xml_internal.h> @@ -46,11 +45,13 @@ struct action_history { }; /* This uses pcmk__set_flags_as()/pcmk__clear_flags_as() directly rather than - * use pe__set_working_set_flags()/pe__clear_working_set_flags() so that the + * use pcmk__set_scheduler_flags()/pcmk__clear_scheduler_flags() so that the * flag is stringified more readably in log messages. */ #define set_config_flag(scheduler, option, flag) do { \ - const char *scf_value = pe_pref((scheduler)->config_hash, (option)); \ + GHashTable *config_hash = (scheduler)->config_hash; \ + const char *scf_value = pcmk__cluster_option(config_hash, (option)); \ + \ if (scf_value != NULL) { \ if (crm_is_true(scf_value)) { \ (scheduler)->flags = pcmk__set_flags_as(__func__, __LINE__, \ @@ -87,11 +88,11 @@ is_dangling_guest_node(pcmk_node_t *node) /* we are looking for a remote-node that was supposed to be mapped to a * container resource, but all traces of that container have disappeared * from both the config and the status section. */ - if (pe__is_guest_or_remote_node(node) && - node->details->remote_rsc && - node->details->remote_rsc->container == NULL && - pcmk_is_set(node->details->remote_rsc->flags, - pcmk_rsc_removed_filler)) { + if (pcmk__is_pacemaker_remote_node(node) + && (node->details->remote_rsc != NULL) + && (node->details->remote_rsc->container == NULL) + && pcmk_is_set(node->details->remote_rsc->flags, + pcmk_rsc_removed_filler)) { return TRUE; } @@ -104,7 +105,8 @@ is_dangling_guest_node(pcmk_node_t *node) * \param[in,out] scheduler Scheduler data * \param[in,out] node Node to fence * \param[in] reason Text description of why fencing is needed - * \param[in] priority_delay Whether to consider `priority-fencing-delay` + * \param[in] priority_delay Whether to consider + * \c PCMK_OPT_PRIORITY_FENCING_DELAY */ void pe_fence_node(pcmk_scheduler_t *scheduler, pcmk_node_t *node, @@ -113,7 +115,7 @@ pe_fence_node(pcmk_scheduler_t *scheduler, pcmk_node_t *node, CRM_CHECK(node, return); /* A guest node is fenced by marking its container as failed */ - if (pe__is_guest_node(node)) { + if (pcmk__is_guest_or_bundle_node(node)) { pcmk_resource_t *rsc = node->details->remote_rsc->container; if (!pcmk_is_set(rsc->flags, pcmk_rsc_failed)) { @@ -121,19 +123,19 @@ pe_fence_node(pcmk_scheduler_t *scheduler, pcmk_node_t *node, crm_notice("Not fencing guest node %s " "(otherwise would because %s): " "its guest resource %s is unmanaged", - pe__node_name(node), reason, rsc->id); + pcmk__node_name(node), reason, rsc->id); } else { - crm_warn("Guest node %s will be fenced " - "(by recovering its guest resource %s): %s", - pe__node_name(node), rsc->id, reason); + pcmk__sched_warn("Guest node %s will be fenced " + "(by recovering its guest resource %s): %s", + pcmk__node_name(node), rsc->id, reason); /* We don't mark the node as unclean because that would prevent the * node from running resources. We want to allow it to run resources * in this transition if the recovery succeeds. */ node->details->remote_requires_reset = TRUE; - pe__set_resource_flags(rsc, - pcmk_rsc_failed|pcmk_rsc_stop_if_failed); + pcmk__set_rsc_flags(rsc, + pcmk_rsc_failed|pcmk_rsc_stop_if_failed); } } @@ -141,39 +143,39 @@ pe_fence_node(pcmk_scheduler_t *scheduler, pcmk_node_t *node, crm_info("Cleaning up dangling connection for guest node %s: " "fencing was already done because %s, " "and guest resource no longer exists", - pe__node_name(node), reason); - pe__set_resource_flags(node->details->remote_rsc, - pcmk_rsc_failed|pcmk_rsc_stop_if_failed); + pcmk__node_name(node), reason); + pcmk__set_rsc_flags(node->details->remote_rsc, + pcmk_rsc_failed|pcmk_rsc_stop_if_failed); - } else if (pe__is_remote_node(node)) { + } else if (pcmk__is_remote_node(node)) { pcmk_resource_t *rsc = node->details->remote_rsc; if ((rsc != NULL) && !pcmk_is_set(rsc->flags, pcmk_rsc_managed)) { crm_notice("Not fencing remote node %s " "(otherwise would because %s): connection is unmanaged", - pe__node_name(node), reason); + pcmk__node_name(node), reason); } else if(node->details->remote_requires_reset == FALSE) { node->details->remote_requires_reset = TRUE; - crm_warn("Remote node %s %s: %s", - pe__node_name(node), - pe_can_fence(scheduler, node)? "will be fenced" : "is unclean", - reason); + pcmk__sched_warn("Remote node %s %s: %s", + pcmk__node_name(node), + pe_can_fence(scheduler, node)? "will be fenced" : "is unclean", + reason); } node->details->unclean = TRUE; - // No need to apply `priority-fencing-delay` for remote nodes + // No need to apply PCMK_OPT_PRIORITY_FENCING_DELAY for remote nodes pe_fence_op(node, NULL, TRUE, reason, FALSE, scheduler); } else if (node->details->unclean) { crm_trace("Cluster node %s %s because %s", - pe__node_name(node), + pcmk__node_name(node), pe_can_fence(scheduler, node)? "would also be fenced" : "also is unclean", reason); } else { - crm_warn("Cluster node %s %s: %s", - pe__node_name(node), - pe_can_fence(scheduler, node)? "will be fenced" : "is unclean", - reason); + pcmk__sched_warn("Cluster node %s %s: %s", + pcmk__node_name(node), + pe_can_fence(scheduler, node)? "will be fenced" : "is unclean", + reason); node->details->unclean = TRUE; pe_fence_op(node, NULL, TRUE, reason, priority_delay, scheduler); } @@ -182,17 +184,17 @@ pe_fence_node(pcmk_scheduler_t *scheduler, pcmk_node_t *node, // @TODO xpaths can't handle templates, rules, or id-refs // nvpair with provides or requires set to unfencing -#define XPATH_UNFENCING_NVPAIR XML_CIB_TAG_NVPAIR \ - "[(@" XML_NVPAIR_ATTR_NAME "='" PCMK_STONITH_PROVIDES "'" \ - "or @" XML_NVPAIR_ATTR_NAME "='" XML_RSC_ATTR_REQUIRES "') " \ - "and @" XML_NVPAIR_ATTR_VALUE "='" PCMK__VALUE_UNFENCING "']" +#define XPATH_UNFENCING_NVPAIR PCMK_XE_NVPAIR \ + "[(@" PCMK_XA_NAME "='" PCMK_STONITH_PROVIDES "'" \ + "or @" PCMK_XA_NAME "='" PCMK_META_REQUIRES "') " \ + "and @" PCMK_XA_VALUE "='" PCMK_VALUE_UNFENCING "']" // unfencing in rsc_defaults or any resource #define XPATH_ENABLE_UNFENCING \ - "/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_RESOURCES \ - "//" XML_TAG_META_SETS "/" XPATH_UNFENCING_NVPAIR \ - "|/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_RSCCONFIG \ - "/" XML_TAG_META_SETS "/" XPATH_UNFENCING_NVPAIR + "/" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION "/" PCMK_XE_RESOURCES \ + "//" PCMK_XE_META_ATTRIBUTES "/" XPATH_UNFENCING_NVPAIR \ + "|/" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION "/" PCMK_XE_RSC_DEFAULTS \ + "/" PCMK_XE_META_ATTRIBUTES "/" XPATH_UNFENCING_NVPAIR static void set_if_xpath(uint64_t flag, const char *xpath, pcmk_scheduler_t *scheduler) @@ -202,7 +204,7 @@ set_if_xpath(uint64_t flag, const char *xpath, pcmk_scheduler_t *scheduler) if (!pcmk_is_set(scheduler->flags, flag)) { result = xpath_search(scheduler->input, xpath); if (result && (numXpathResults(result) > 0)) { - pe__set_working_set_flags(scheduler, flag); + pcmk__set_scheduler_flags(scheduler, flag); } freeXpathObject(result); } @@ -212,11 +214,11 @@ gboolean unpack_config(xmlNode *config, pcmk_scheduler_t *scheduler) { const char *value = NULL; + guint interval_ms = 0U; GHashTable *config_hash = pcmk__strkey_table(free, free); pe_rule_eval_data_t rule_data = { .node_hash = NULL, - .role = pcmk_role_unknown, .now = scheduler->now, .match_data = NULL, .rsc_data = NULL, @@ -225,22 +227,24 @@ unpack_config(xmlNode *config, pcmk_scheduler_t *scheduler) scheduler->config_hash = config_hash; - pe__unpack_dataset_nvpairs(config, XML_CIB_TAG_PROPSET, &rule_data, config_hash, - CIB_OPTIONS_FIRST, FALSE, scheduler); + pe__unpack_dataset_nvpairs(config, PCMK_XE_CLUSTER_PROPERTY_SET, &rule_data, + config_hash, PCMK_VALUE_CIB_BOOTSTRAP_OPTIONS, + FALSE, scheduler); - verify_pe_options(scheduler->config_hash); + pcmk__validate_cluster_options(config_hash); - set_config_flag(scheduler, "enable-startup-probes", + set_config_flag(scheduler, PCMK_OPT_ENABLE_STARTUP_PROBES, pcmk_sched_probe_resources); if (!pcmk_is_set(scheduler->flags, pcmk_sched_probe_resources)) { crm_info("Startup probes: disabled (dangerous)"); } - value = pe_pref(scheduler->config_hash, XML_ATTR_HAVE_WATCHDOG); + value = pcmk__cluster_option(config_hash, PCMK_OPT_HAVE_WATCHDOG); if (value && crm_is_true(value)) { crm_info("Watchdog-based self-fencing will be performed via SBD if " - "fencing is required and stonith-watchdog-timeout is nonzero"); - pe__set_working_set_flags(scheduler, pcmk_sched_have_fencing); + "fencing is required and " PCMK_OPT_STONITH_WATCHDOG_TIMEOUT + " is nonzero"); + pcmk__set_scheduler_flags(scheduler, pcmk_sched_have_fencing); } /* Set certain flags via xpath here, so they can be used before the relevant @@ -249,28 +253,37 @@ unpack_config(xmlNode *config, pcmk_scheduler_t *scheduler) set_if_xpath(pcmk_sched_enable_unfencing, XPATH_ENABLE_UNFENCING, scheduler); - value = pe_pref(scheduler->config_hash, "stonith-timeout"); - scheduler->stonith_timeout = (int) crm_parse_interval_spec(value); + value = pcmk__cluster_option(config_hash, PCMK_OPT_STONITH_TIMEOUT); + pcmk_parse_interval_spec(value, &interval_ms); + + if (interval_ms >= INT_MAX) { + scheduler->stonith_timeout = INT_MAX; + } else { + scheduler->stonith_timeout = (int) interval_ms; + } crm_debug("STONITH timeout: %d", scheduler->stonith_timeout); - set_config_flag(scheduler, "stonith-enabled", pcmk_sched_fencing_enabled); + set_config_flag(scheduler, PCMK_OPT_STONITH_ENABLED, + pcmk_sched_fencing_enabled); if (pcmk_is_set(scheduler->flags, pcmk_sched_fencing_enabled)) { crm_debug("STONITH of failed nodes is enabled"); } else { crm_debug("STONITH of failed nodes is disabled"); } - scheduler->stonith_action = pe_pref(scheduler->config_hash, - "stonith-action"); - if (!strcmp(scheduler->stonith_action, "poweroff")) { - pe_warn_once(pcmk__wo_poweroff, - "Support for stonith-action of 'poweroff' is deprecated " - "and will be removed in a future release (use 'off' instead)"); + scheduler->stonith_action = pcmk__cluster_option(config_hash, + PCMK_OPT_STONITH_ACTION); + if (!strcmp(scheduler->stonith_action, PCMK__ACTION_POWEROFF)) { + pcmk__warn_once(pcmk__wo_poweroff, + "Support for " PCMK_OPT_STONITH_ACTION " of " + "'" PCMK__ACTION_POWEROFF "' is deprecated and will be " + "removed in a future release " + "(use '" PCMK_ACTION_OFF "' instead)"); scheduler->stonith_action = PCMK_ACTION_OFF; } crm_trace("STONITH will %s nodes", scheduler->stonith_action); - set_config_flag(scheduler, "concurrent-fencing", + set_config_flag(scheduler, PCMK_OPT_CONCURRENT_FENCING, pcmk_sched_concurrent_fencing); if (pcmk_is_set(scheduler->flags, pcmk_sched_concurrent_fencing)) { crm_debug("Concurrent fencing is enabled"); @@ -278,51 +291,52 @@ unpack_config(xmlNode *config, pcmk_scheduler_t *scheduler) crm_debug("Concurrent fencing is disabled"); } - value = pe_pref(scheduler->config_hash, - XML_CONFIG_ATTR_PRIORITY_FENCING_DELAY); + value = pcmk__cluster_option(config_hash, PCMK_OPT_PRIORITY_FENCING_DELAY); if (value) { - scheduler->priority_fencing_delay = crm_parse_interval_spec(value) - / 1000; + pcmk_parse_interval_spec(value, &interval_ms); + scheduler->priority_fencing_delay = (int) (interval_ms / 1000); crm_trace("Priority fencing delay is %ds", scheduler->priority_fencing_delay); } - set_config_flag(scheduler, "stop-all-resources", pcmk_sched_stop_all); + set_config_flag(scheduler, PCMK_OPT_STOP_ALL_RESOURCES, + pcmk_sched_stop_all); crm_debug("Stop all active resources: %s", - pcmk__btoa(pcmk_is_set(scheduler->flags, pcmk_sched_stop_all))); + pcmk__flag_text(scheduler->flags, pcmk_sched_stop_all)); - set_config_flag(scheduler, "symmetric-cluster", + set_config_flag(scheduler, PCMK_OPT_SYMMETRIC_CLUSTER, pcmk_sched_symmetric_cluster); if (pcmk_is_set(scheduler->flags, pcmk_sched_symmetric_cluster)) { crm_debug("Cluster is symmetric" " - resources can run anywhere by default"); } - value = pe_pref(scheduler->config_hash, "no-quorum-policy"); + value = pcmk__cluster_option(config_hash, PCMK_OPT_NO_QUORUM_POLICY); - if (pcmk__str_eq(value, "ignore", pcmk__str_casei)) { + if (pcmk__str_eq(value, PCMK_VALUE_IGNORE, pcmk__str_casei)) { scheduler->no_quorum_policy = pcmk_no_quorum_ignore; - } else if (pcmk__str_eq(value, "freeze", pcmk__str_casei)) { + } else if (pcmk__str_eq(value, PCMK_VALUE_FREEZE, pcmk__str_casei)) { scheduler->no_quorum_policy = pcmk_no_quorum_freeze; - } else if (pcmk__str_eq(value, "demote", pcmk__str_casei)) { + } else if (pcmk__str_eq(value, PCMK_VALUE_DEMOTE, pcmk__str_casei)) { scheduler->no_quorum_policy = pcmk_no_quorum_demote; - } else if (pcmk__str_eq(value, "suicide", pcmk__str_casei)) { + } else if (pcmk__str_eq(value, PCMK_VALUE_FENCE_LEGACY, pcmk__str_casei)) { if (pcmk_is_set(scheduler->flags, pcmk_sched_fencing_enabled)) { int do_panic = 0; - crm_element_value_int(scheduler->input, XML_ATTR_QUORUM_PANIC, + crm_element_value_int(scheduler->input, PCMK_XA_NO_QUORUM_PANIC, &do_panic); if (do_panic || pcmk_is_set(scheduler->flags, pcmk_sched_quorate)) { scheduler->no_quorum_policy = pcmk_no_quorum_fence; } else { - crm_notice("Resetting no-quorum-policy to 'stop': cluster has never had quorum"); + crm_notice("Resetting " PCMK_OPT_NO_QUORUM_POLICY + " to 'stop': cluster has never had quorum"); scheduler->no_quorum_policy = pcmk_no_quorum_stop; } } else { - pcmk__config_err("Resetting no-quorum-policy to 'stop' because " - "fencing is disabled"); + pcmk__config_err("Resetting " PCMK_OPT_NO_QUORUM_POLICY + " to 'stop' because fencing is disabled"); scheduler->no_quorum_policy = pcmk_no_quorum_stop; } @@ -349,7 +363,7 @@ unpack_config(xmlNode *config, pcmk_scheduler_t *scheduler) break; } - set_config_flag(scheduler, "stop-orphan-resources", + set_config_flag(scheduler, PCMK_OPT_STOP_ORPHAN_RESOURCES, pcmk_sched_stop_removed_resources); if (pcmk_is_set(scheduler->flags, pcmk_sched_stop_removed_resources)) { crm_trace("Orphan resources are stopped"); @@ -357,7 +371,7 @@ unpack_config(xmlNode *config, pcmk_scheduler_t *scheduler) crm_trace("Orphan resources are ignored"); } - set_config_flag(scheduler, "stop-orphan-actions", + set_config_flag(scheduler, PCMK_OPT_STOP_ORPHAN_ACTIONS, pcmk_sched_cancel_removed_actions); if (pcmk_is_set(scheduler->flags, pcmk_sched_cancel_removed_actions)) { crm_trace("Orphan resource actions are stopped"); @@ -365,27 +379,26 @@ unpack_config(xmlNode *config, pcmk_scheduler_t *scheduler) crm_trace("Orphan resource actions are ignored"); } - value = pe_pref(scheduler->config_hash, "remove-after-stop"); + value = pcmk__cluster_option(config_hash, PCMK__OPT_REMOVE_AFTER_STOP); if (value != NULL) { if (crm_is_true(value)) { - pe__set_working_set_flags(scheduler, pcmk_sched_remove_after_stop); -#ifndef PCMK__COMPAT_2_0 - pe_warn_once(pcmk__wo_remove_after, - "Support for the remove-after-stop cluster property is" - " deprecated and will be removed in a future release"); -#endif + pcmk__set_scheduler_flags(scheduler, pcmk_sched_remove_after_stop); + pcmk__warn_once(pcmk__wo_remove_after, + "Support for the " PCMK__OPT_REMOVE_AFTER_STOP + " cluster property is deprecated and will be " + "removed in a future release"); } else { - pe__clear_working_set_flags(scheduler, + pcmk__clear_scheduler_flags(scheduler, pcmk_sched_remove_after_stop); } } - set_config_flag(scheduler, "maintenance-mode", pcmk_sched_in_maintenance); + set_config_flag(scheduler, PCMK_OPT_MAINTENANCE_MODE, + pcmk_sched_in_maintenance); crm_trace("Maintenance mode: %s", - pcmk__btoa(pcmk_is_set(scheduler->flags, - pcmk_sched_in_maintenance))); + pcmk__flag_text(scheduler->flags, pcmk_sched_in_maintenance)); - set_config_flag(scheduler, "start-failure-is-fatal", + set_config_flag(scheduler, PCMK_OPT_START_FAILURE_IS_FATAL, pcmk_sched_start_failure_fatal); if (pcmk_is_set(scheduler->flags, pcmk_sched_start_failure_fatal)) { crm_trace("Start failures are always fatal"); @@ -394,26 +407,28 @@ unpack_config(xmlNode *config, pcmk_scheduler_t *scheduler) } if (pcmk_is_set(scheduler->flags, pcmk_sched_fencing_enabled)) { - set_config_flag(scheduler, "startup-fencing", + set_config_flag(scheduler, PCMK_OPT_STARTUP_FENCING, pcmk_sched_startup_fencing); } if (pcmk_is_set(scheduler->flags, pcmk_sched_startup_fencing)) { crm_trace("Unseen nodes will be fenced"); } else { - pe_warn_once(pcmk__wo_blind, "Blind faith: not fencing unseen nodes"); + pcmk__warn_once(pcmk__wo_blind, + "Blind faith: not fencing unseen nodes"); } pe__unpack_node_health_scores(scheduler); - scheduler->placement_strategy = pe_pref(scheduler->config_hash, - "placement-strategy"); + scheduler->placement_strategy = + pcmk__cluster_option(config_hash, PCMK_OPT_PLACEMENT_STRATEGY); crm_trace("Placement strategy: %s", scheduler->placement_strategy); - set_config_flag(scheduler, "shutdown-lock", pcmk_sched_shutdown_lock); + set_config_flag(scheduler, PCMK_OPT_SHUTDOWN_LOCK, + pcmk_sched_shutdown_lock); if (pcmk_is_set(scheduler->flags, pcmk_sched_shutdown_lock)) { - value = pe_pref(scheduler->config_hash, - XML_CONFIG_ATTR_SHUTDOWN_LOCK_LIMIT); - scheduler->shutdown_lock = crm_parse_interval_spec(value) / 1000; + value = pcmk__cluster_option(config_hash, PCMK_OPT_SHUTDOWN_LOCK_LIMIT); + pcmk_parse_interval_spec(value, &(scheduler->shutdown_lock)); + scheduler->shutdown_lock /= 1000; crm_trace("Resources will be locked to nodes that were cleanly " "shut down (locks expire after %s)", pcmk__readable_interval(scheduler->shutdown_lock)); @@ -422,9 +437,9 @@ unpack_config(xmlNode *config, pcmk_scheduler_t *scheduler) "shut down"); } - value = pe_pref(scheduler->config_hash, - XML_CONFIG_ATTR_NODE_PENDING_TIMEOUT); - scheduler->node_pending_timeout = crm_parse_interval_spec(value) / 1000; + value = pcmk__cluster_option(config_hash, PCMK_OPT_NODE_PENDING_TIMEOUT); + pcmk_parse_interval_spec(value, &(scheduler->node_pending_timeout)); + scheduler->node_pending_timeout /= 1000; if (scheduler->node_pending_timeout == 0) { crm_trace("Do not fence pending nodes"); } else { @@ -442,12 +457,13 @@ pe_create_node(const char *id, const char *uname, const char *type, { pcmk_node_t *new_node = NULL; - if (pe_find_node(scheduler->nodes, uname) != NULL) { + if (pcmk_find_node(scheduler, uname) != NULL) { pcmk__config_warn("More than one node entry has name '%s'", uname); } new_node = calloc(1, sizeof(pcmk_node_t)); if (new_node == NULL) { + pcmk__sched_err("Could not allocate memory for node %s", uname); return NULL; } @@ -456,6 +472,7 @@ pe_create_node(const char *id, const char *uname, const char *type, if (new_node->details == NULL) { free(new_node); + pcmk__sched_err("Could not allocate memory for node %s", uname); return NULL; } @@ -468,37 +485,37 @@ pe_create_node(const char *id, const char *uname, const char *type, new_node->details->running_rsc = NULL; new_node->details->data_set = scheduler; - if (pcmk__str_eq(type, "member", pcmk__str_null_matches | pcmk__str_casei)) { + if (pcmk__str_eq(type, PCMK_VALUE_MEMBER, + pcmk__str_null_matches|pcmk__str_casei)) { new_node->details->type = pcmk_node_variant_cluster; - } else if (pcmk__str_eq(type, "remote", pcmk__str_casei)) { + } else if (pcmk__str_eq(type, PCMK_VALUE_REMOTE, pcmk__str_casei)) { new_node->details->type = pcmk_node_variant_remote; - pe__set_working_set_flags(scheduler, pcmk_sched_have_remote_nodes); + pcmk__set_scheduler_flags(scheduler, pcmk_sched_have_remote_nodes); } else { /* @COMPAT 'ping' is the default for backward compatibility, but it * should be changed to 'member' at a compatibility break */ - if (!pcmk__str_eq(type, "ping", pcmk__str_casei)) { + if (!pcmk__str_eq(type, PCMK__VALUE_PING, pcmk__str_casei)) { pcmk__config_warn("Node %s has unrecognized type '%s', " - "assuming 'ping'", pcmk__s(uname, "without name"), - type); + "assuming '" PCMK__VALUE_PING "'", + pcmk__s(uname, "without name"), type); } - pe_warn_once(pcmk__wo_ping_node, - "Support for nodes of type 'ping' (such as %s) is " - "deprecated and will be removed in a future release", - pcmk__s(uname, "unnamed node")); + pcmk__warn_once(pcmk__wo_ping_node, + "Support for nodes of type '" PCMK__VALUE_PING "' " + "(such as %s) is deprecated and will be removed in a " + "future release", + pcmk__s(uname, "unnamed node")); new_node->details->type = node_ping; } new_node->details->attrs = pcmk__strkey_table(free, free); - if (pe__is_guest_or_remote_node(new_node)) { - g_hash_table_insert(new_node->details->attrs, strdup(CRM_ATTR_KIND), - strdup("remote")); + if (pcmk__is_pacemaker_remote_node(new_node)) { + pcmk__insert_dup(new_node->details->attrs, CRM_ATTR_KIND, "remote"); } else { - g_hash_table_insert(new_node->details->attrs, strdup(CRM_ATTR_KIND), - strdup("cluster")); + pcmk__insert_dup(new_node->details->attrs, CRM_ATTR_KIND, "cluster"); } new_node->details->utilization = pcmk__strkey_table(free, free); @@ -516,7 +533,7 @@ expand_remote_rsc_meta(xmlNode *xml_obj, xmlNode *parent, pcmk_scheduler_t *data xmlNode *attr_set = NULL; xmlNode *attr = NULL; - const char *container_id = ID(xml_obj); + const char *container_id = pcmk__xe_id(xml_obj); const char *remote_name = NULL; const char *remote_server = NULL; const char *remote_port = NULL; @@ -524,30 +541,39 @@ expand_remote_rsc_meta(xmlNode *xml_obj, xmlNode *parent, pcmk_scheduler_t *data const char *remote_allow_migrate=NULL; const char *is_managed = NULL; - for (attr_set = pcmk__xe_first_child(xml_obj); attr_set != NULL; - attr_set = pcmk__xe_next(attr_set)) { + for (attr_set = pcmk__xe_first_child(xml_obj, NULL, NULL, NULL); + attr_set != NULL; attr_set = pcmk__xe_next(attr_set)) { - if (!pcmk__str_eq((const char *)attr_set->name, XML_TAG_META_SETS, - pcmk__str_casei)) { + if (!pcmk__xe_is(attr_set, PCMK_XE_META_ATTRIBUTES)) { continue; } - for (attr = pcmk__xe_first_child(attr_set); attr != NULL; - attr = pcmk__xe_next(attr)) { - const char *value = crm_element_value(attr, XML_NVPAIR_ATTR_VALUE); - const char *name = crm_element_value(attr, XML_NVPAIR_ATTR_NAME); + for (attr = pcmk__xe_first_child(attr_set, NULL, NULL, NULL); + attr != NULL; attr = pcmk__xe_next(attr)) { + + const char *value = crm_element_value(attr, PCMK_XA_VALUE); + const char *name = crm_element_value(attr, PCMK_XA_NAME); + + if (name == NULL) { // Sanity + continue; + } - if (pcmk__str_eq(name, XML_RSC_ATTR_REMOTE_NODE, pcmk__str_casei)) { + if (strcmp(name, PCMK_META_REMOTE_NODE) == 0) { remote_name = value; - } else if (pcmk__str_eq(name, "remote-addr", pcmk__str_casei)) { + + } else if (strcmp(name, PCMK_META_REMOTE_ADDR) == 0) { remote_server = value; - } else if (pcmk__str_eq(name, "remote-port", pcmk__str_casei)) { + + } else if (strcmp(name, PCMK_META_REMOTE_PORT) == 0) { remote_port = value; - } else if (pcmk__str_eq(name, "remote-connect-timeout", pcmk__str_casei)) { + + } else if (strcmp(name, PCMK_META_REMOTE_CONNECT_TIMEOUT) == 0) { connect_timeout = value; - } else if (pcmk__str_eq(name, "remote-allow-migrate", pcmk__str_casei)) { - remote_allow_migrate=value; - } else if (pcmk__str_eq(name, XML_RSC_ATTR_MANAGED, pcmk__str_casei)) { + + } else if (strcmp(name, PCMK_META_REMOTE_ALLOW_MIGRATE) == 0) { + remote_allow_migrate = value; + + } else if (strcmp(name, PCMK_META_IS_MANAGED) == 0) { is_managed = value; } } @@ -603,20 +629,20 @@ unpack_nodes(xmlNode *xml_nodes, pcmk_scheduler_t *scheduler) const char *type = NULL; const char *score = NULL; - for (xml_obj = pcmk__xe_first_child(xml_nodes); xml_obj != NULL; - xml_obj = pcmk__xe_next(xml_obj)) { + for (xml_obj = pcmk__xe_first_child(xml_nodes, NULL, NULL, NULL); + xml_obj != NULL; xml_obj = pcmk__xe_next(xml_obj)) { - if (pcmk__str_eq((const char *)xml_obj->name, XML_CIB_TAG_NODE, pcmk__str_none)) { + if (pcmk__xe_is(xml_obj, PCMK_XE_NODE)) { new_node = NULL; - id = crm_element_value(xml_obj, XML_ATTR_ID); - uname = crm_element_value(xml_obj, XML_ATTR_UNAME); - type = crm_element_value(xml_obj, XML_ATTR_TYPE); - score = crm_element_value(xml_obj, XML_RULE_ATTR_SCORE); + id = crm_element_value(xml_obj, PCMK_XA_ID); + uname = crm_element_value(xml_obj, PCMK_XA_UNAME); + type = crm_element_value(xml_obj, PCMK_XA_TYPE); + score = crm_element_value(xml_obj, PCMK_XA_SCORE); crm_trace("Processing node %s/%s", uname, id); if (id == NULL) { - pcmk__config_err("Ignoring <" XML_CIB_TAG_NODE + pcmk__config_err("Ignoring <" PCMK_XE_NODE "> entry in configuration without id"); continue; } @@ -630,12 +656,13 @@ unpack_nodes(xmlNode *xml_nodes, pcmk_scheduler_t *scheduler) add_node_attrs(xml_obj, new_node, FALSE, scheduler); - crm_trace("Done with node %s", crm_element_value(xml_obj, XML_ATTR_UNAME)); + crm_trace("Done with node %s", + crm_element_value(xml_obj, PCMK_XA_UNAME)); } } if (scheduler->localhost - && (pe_find_node(scheduler->nodes, scheduler->localhost) == NULL)) { + && (pcmk_find_node(scheduler, scheduler->localhost) == NULL)) { crm_info("Creating a fake local node"); pe_create_node(scheduler->localhost, scheduler->localhost, NULL, 0, scheduler); @@ -654,18 +681,20 @@ setup_container(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler) return; } - container_id = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_CONTAINER); + container_id = g_hash_table_lookup(rsc->meta, PCMK__META_CONTAINER); if (container_id && !pcmk__str_eq(container_id, rsc->id, pcmk__str_casei)) { pcmk_resource_t *container = pe_find_resource(scheduler->resources, container_id); if (container) { rsc->container = container; - pe__set_resource_flags(container, pcmk_rsc_has_filler); + pcmk__set_rsc_flags(container, pcmk_rsc_has_filler); container->fillers = g_list_append(container->fillers, rsc); - pe_rsc_trace(rsc, "Resource %s's container is %s", rsc->id, container_id); + pcmk__rsc_trace(rsc, "Resource %s's container is %s", + rsc->id, container_id); } else { - pe_err("Resource %s: Unknown resource container (%s)", rsc->id, container_id); + pcmk__config_err("Resource %s: Unknown resource container (%s)", + rsc->id, container_id); } } } @@ -678,8 +707,8 @@ unpack_remote_nodes(xmlNode *xml_resources, pcmk_scheduler_t *scheduler) /* Create remote nodes and guest nodes from the resource configuration * before unpacking resources. */ - for (xml_obj = pcmk__xe_first_child(xml_resources); xml_obj != NULL; - xml_obj = pcmk__xe_next(xml_obj)) { + for (xml_obj = pcmk__xe_first_child(xml_resources, NULL, NULL, NULL); + xml_obj != NULL; xml_obj = pcmk__xe_next(xml_obj)) { const char *new_node_id = NULL; @@ -687,15 +716,16 @@ unpack_remote_nodes(xmlNode *xml_resources, pcmk_scheduler_t *scheduler) * primitives. */ if (xml_contains_remote_node(xml_obj)) { - new_node_id = ID(xml_obj); - /* The "pe_find_node" check is here to make sure we don't iterate over - * an expanded node that has already been added to the node list. */ + new_node_id = pcmk__xe_id(xml_obj); + /* The pcmk_find_node() check ensures we don't iterate over an + * expanded node that has already been added to the node list + */ if (new_node_id - && (pe_find_node(scheduler->nodes, new_node_id) == NULL)) { + && (pcmk_find_node(scheduler, new_node_id) == NULL)) { crm_trace("Found remote node %s defined by resource %s", - new_node_id, ID(xml_obj)); - pe_create_node(new_node_id, new_node_id, "remote", NULL, - scheduler); + new_node_id, pcmk__xe_id(xml_obj)); + pe_create_node(new_node_id, new_node_id, PCMK_VALUE_REMOTE, + NULL, scheduler); } continue; } @@ -703,7 +733,7 @@ unpack_remote_nodes(xmlNode *xml_resources, pcmk_scheduler_t *scheduler) /* Check for guest nodes, which are defined by special meta-attributes * of a primitive of any type (for example, VirtualDomain or Xen). */ - if (pcmk__str_eq((const char *)xml_obj->name, XML_CIB_TAG_RESOURCE, pcmk__str_none)) { + if (pcmk__xe_is(xml_obj, PCMK_XE_PRIMITIVE)) { /* This will add an ocf:pacemaker:remote primitive to the * configuration for the guest node's connection, to be unpacked * later. @@ -711,11 +741,11 @@ unpack_remote_nodes(xmlNode *xml_resources, pcmk_scheduler_t *scheduler) new_node_id = expand_remote_rsc_meta(xml_obj, xml_resources, scheduler); if (new_node_id - && (pe_find_node(scheduler->nodes, new_node_id) == NULL)) { + && (pcmk_find_node(scheduler, new_node_id) == NULL)) { crm_trace("Found guest node %s in resource %s", - new_node_id, ID(xml_obj)); - pe_create_node(new_node_id, new_node_id, "remote", NULL, - scheduler); + new_node_id, pcmk__xe_id(xml_obj)); + pe_create_node(new_node_id, new_node_id, PCMK_VALUE_REMOTE, + NULL, scheduler); } continue; } @@ -723,20 +753,21 @@ unpack_remote_nodes(xmlNode *xml_resources, pcmk_scheduler_t *scheduler) /* Check for guest nodes inside a group. Clones are currently not * supported as guest nodes. */ - if (pcmk__str_eq((const char *)xml_obj->name, XML_CIB_TAG_GROUP, pcmk__str_none)) { + if (pcmk__xe_is(xml_obj, PCMK_XE_GROUP)) { xmlNode *xml_obj2 = NULL; - for (xml_obj2 = pcmk__xe_first_child(xml_obj); xml_obj2 != NULL; - xml_obj2 = pcmk__xe_next(xml_obj2)) { + for (xml_obj2 = pcmk__xe_first_child(xml_obj, NULL, NULL, NULL); + xml_obj2 != NULL; xml_obj2 = pcmk__xe_next(xml_obj2)) { new_node_id = expand_remote_rsc_meta(xml_obj2, xml_resources, scheduler); if (new_node_id - && (pe_find_node(scheduler->nodes, new_node_id) == NULL)) { + && (pcmk_find_node(scheduler, new_node_id) == NULL)) { crm_trace("Found guest node %s in resource %s inside group %s", - new_node_id, ID(xml_obj2), ID(xml_obj)); - pe_create_node(new_node_id, new_node_id, "remote", NULL, - scheduler); + new_node_id, pcmk__xe_id(xml_obj2), + pcmk__xe_id(xml_obj)); + pe_create_node(new_node_id, new_node_id, PCMK_VALUE_REMOTE, + NULL, scheduler); } } } @@ -766,11 +797,11 @@ link_rsc2remotenode(pcmk_scheduler_t *scheduler, pcmk_resource_t *new_rsc) return; } - remote_node = pe_find_node(scheduler->nodes, new_rsc->id); + remote_node = pcmk_find_node(scheduler, new_rsc->id); CRM_CHECK(remote_node != NULL, return); - pe_rsc_trace(new_rsc, "Linking remote connection resource %s to %s", - new_rsc->id, pe__node_name(remote_node)); + pcmk__rsc_trace(new_rsc, "Linking remote connection resource %s to %s", + new_rsc->id, pcmk__node_name(remote_node)); remote_node->details->remote_rsc = new_rsc; if (new_rsc->container == NULL) { @@ -783,8 +814,8 @@ link_rsc2remotenode(pcmk_scheduler_t *scheduler, pcmk_resource_t *new_rsc) /* pe_create_node() marks the new node as "remote" or "cluster"; now * that we know the node is a guest node, update it correctly. */ - g_hash_table_replace(remote_node->details->attrs, strdup(CRM_ATTR_KIND), - strdup("container")); + pcmk__insert_dup(remote_node->details->attrs, + CRM_ATTR_KIND, "container"); } } @@ -820,11 +851,11 @@ unpack_resources(const xmlNode *xml_resources, pcmk_scheduler_t *scheduler) scheduler->template_rsc_sets = pcmk__strkey_table(free, destroy_tag); - for (xml_obj = pcmk__xe_first_child(xml_resources); xml_obj != NULL; - xml_obj = pcmk__xe_next(xml_obj)) { + for (xml_obj = pcmk__xe_first_child(xml_resources, NULL, NULL, NULL); + xml_obj != NULL; xml_obj = pcmk__xe_next(xml_obj)) { pcmk_resource_t *new_rsc = NULL; - const char *id = ID(xml_obj); + const char *id = pcmk__xe_id(xml_obj); if (pcmk__str_empty(id)) { pcmk__config_err("Ignoring <%s> resource without ID", @@ -832,23 +863,20 @@ unpack_resources(const xmlNode *xml_resources, pcmk_scheduler_t *scheduler) continue; } - if (pcmk__str_eq((const char *) xml_obj->name, XML_CIB_TAG_RSC_TEMPLATE, - pcmk__str_none)) { + if (pcmk__xe_is(xml_obj, PCMK_XE_TEMPLATE)) { if (g_hash_table_lookup_extended(scheduler->template_rsc_sets, id, NULL, NULL) == FALSE) { /* Record the template's ID for the knowledge of its existence anyway. */ - g_hash_table_insert(scheduler->template_rsc_sets, strdup(id), - NULL); + pcmk__insert_dup(scheduler->template_rsc_sets, id, NULL); } continue; } - crm_trace("Unpacking <%s " XML_ATTR_ID "='%s'>", - xml_obj->name, id); + crm_trace("Unpacking <%s " PCMK_XA_ID "='%s'>", xml_obj->name, id); if (pe__unpack_resource(xml_obj, &new_rsc, NULL, scheduler) == pcmk_rc_ok) { scheduler->resources = g_list_append(scheduler->resources, new_rsc); - pe_rsc_trace(new_rsc, "Added resource %s", new_rsc->id); + pcmk__rsc_trace(new_rsc, "Added resource %s", new_rsc->id); } else { pcmk__config_err("Ignoring <%s> resource '%s' " @@ -873,7 +901,8 @@ unpack_resources(const xmlNode *xml_resources, pcmk_scheduler_t *scheduler) && !pcmk_is_set(scheduler->flags, pcmk_sched_have_fencing)) { pcmk__config_err("Resource start-up disabled since no STONITH resources have been defined"); - pcmk__config_err("Either configure some or disable STONITH with the stonith-enabled option"); + pcmk__config_err("Either configure some or disable STONITH with the " + PCMK_OPT_STONITH_ENABLED " option"); pcmk__config_err("NOTE: Clusters with shared data need STONITH to ensure data integrity"); } @@ -887,33 +916,33 @@ unpack_tags(xmlNode *xml_tags, pcmk_scheduler_t *scheduler) scheduler->tags = pcmk__strkey_table(free, destroy_tag); - for (xml_tag = pcmk__xe_first_child(xml_tags); xml_tag != NULL; - xml_tag = pcmk__xe_next(xml_tag)) { + for (xml_tag = pcmk__xe_first_child(xml_tags, NULL, NULL, NULL); + xml_tag != NULL; xml_tag = pcmk__xe_next(xml_tag)) { xmlNode *xml_obj_ref = NULL; - const char *tag_id = ID(xml_tag); + const char *tag_id = pcmk__xe_id(xml_tag); - if (!pcmk__str_eq((const char *)xml_tag->name, XML_CIB_TAG_TAG, pcmk__str_none)) { + if (!pcmk__xe_is(xml_tag, PCMK_XE_TAG)) { continue; } if (tag_id == NULL) { - pcmk__config_err("Ignoring <%s> without " XML_ATTR_ID, + pcmk__config_err("Ignoring <%s> without " PCMK_XA_ID, (const char *) xml_tag->name); continue; } - for (xml_obj_ref = pcmk__xe_first_child(xml_tag); xml_obj_ref != NULL; - xml_obj_ref = pcmk__xe_next(xml_obj_ref)) { + for (xml_obj_ref = pcmk__xe_first_child(xml_tag, NULL, NULL, NULL); + xml_obj_ref != NULL; xml_obj_ref = pcmk__xe_next(xml_obj_ref)) { - const char *obj_ref = ID(xml_obj_ref); + const char *obj_ref = pcmk__xe_id(xml_obj_ref); - if (!pcmk__str_eq((const char *)xml_obj_ref->name, XML_CIB_TAG_OBJ_REF, pcmk__str_none)) { + if (!pcmk__xe_is(xml_obj_ref, PCMK_XE_OBJ_REF)) { continue; } if (obj_ref == NULL) { - pcmk__config_err("Ignoring <%s> for tag '%s' without " XML_ATTR_ID, + pcmk__config_err("Ignoring <%s> for tag '%s' without " PCMK_XA_ID, xml_obj_ref->name, tag_id); continue; } @@ -940,7 +969,7 @@ unpack_ticket_state(xmlNode *xml_ticket, pcmk_scheduler_t *scheduler) pcmk_ticket_t *ticket = NULL; - ticket_id = ID(xml_ticket); + ticket_id = pcmk__xe_id(xml_ticket); if (pcmk__str_empty(ticket_id)) { return FALSE; } @@ -959,13 +988,13 @@ unpack_ticket_state(xmlNode *xml_ticket, pcmk_scheduler_t *scheduler) const char *prop_name = (const char *)xIter->name; const char *prop_value = pcmk__xml_attr_value(xIter); - if (pcmk__str_eq(prop_name, XML_ATTR_ID, pcmk__str_none)) { + if (pcmk__str_eq(prop_name, PCMK_XA_ID, pcmk__str_none)) { continue; } - g_hash_table_replace(ticket->state, strdup(prop_name), strdup(prop_value)); + pcmk__insert_dup(ticket->state, prop_name, prop_value); } - granted = g_hash_table_lookup(ticket->state, "granted"); + granted = g_hash_table_lookup(ticket->state, PCMK__XA_GRANTED); if (granted && crm_is_true(granted)) { ticket->granted = TRUE; crm_info("We have ticket '%s'", ticket->id); @@ -974,7 +1003,7 @@ unpack_ticket_state(xmlNode *xml_ticket, pcmk_scheduler_t *scheduler) crm_info("We do not have ticket '%s'", ticket->id); } - last_granted = g_hash_table_lookup(ticket->state, "last-granted"); + last_granted = g_hash_table_lookup(ticket->state, PCMK_XA_LAST_GRANTED); if (last_granted) { long long last_granted_ll; @@ -982,7 +1011,7 @@ unpack_ticket_state(xmlNode *xml_ticket, pcmk_scheduler_t *scheduler) ticket->last_granted = (time_t) last_granted_ll; } - standby = g_hash_table_lookup(ticket->state, "standby"); + standby = g_hash_table_lookup(ticket->state, PCMK_XA_STANDBY); if (standby && crm_is_true(standby)) { ticket->standby = TRUE; if (ticket->granted) { @@ -1002,10 +1031,10 @@ unpack_tickets_state(xmlNode *xml_tickets, pcmk_scheduler_t *scheduler) { xmlNode *xml_obj = NULL; - for (xml_obj = pcmk__xe_first_child(xml_tickets); xml_obj != NULL; - xml_obj = pcmk__xe_next(xml_obj)) { + for (xml_obj = pcmk__xe_first_child(xml_tickets, NULL, NULL, NULL); + xml_obj != NULL; xml_obj = pcmk__xe_next(xml_obj)) { - if (!pcmk__str_eq((const char *)xml_obj->name, XML_CIB_TAG_TICKET_STATE, pcmk__str_none)) { + if (!pcmk__xe_is(xml_obj, PCMK__XE_TICKET_STATE)) { continue; } unpack_ticket_state(xml_obj, scheduler); @@ -1018,20 +1047,21 @@ static void unpack_handle_remote_attrs(pcmk_node_t *this_node, const xmlNode *state, pcmk_scheduler_t *scheduler) { - const char *resource_discovery_enabled = NULL; + const char *discovery = NULL; const xmlNode *attrs = NULL; pcmk_resource_t *rsc = NULL; - if (!pcmk__str_eq((const char *)state->name, XML_CIB_TAG_STATE, pcmk__str_none)) { + if (!pcmk__xe_is(state, PCMK__XE_NODE_STATE)) { return; } - if ((this_node == NULL) || !pe__is_guest_or_remote_node(this_node)) { + if ((this_node == NULL) || !pcmk__is_pacemaker_remote_node(this_node)) { return; } - crm_trace("Processing Pacemaker Remote node %s", pe__node_name(this_node)); + crm_trace("Processing Pacemaker Remote node %s", + pcmk__node_name(this_node)); - pcmk__scan_min_int(crm_element_value(state, XML_NODE_IS_MAINTENANCE), + pcmk__scan_min_int(crm_element_value(state, PCMK__XA_NODE_IN_MAINTENANCE), &(this_node->details->remote_maintenance), 0); rsc = this_node->details->remote_rsc; @@ -1039,33 +1069,45 @@ unpack_handle_remote_attrs(pcmk_node_t *this_node, const xmlNode *state, this_node->details->unclean = FALSE; this_node->details->unseen = FALSE; } - attrs = find_xml_node(state, XML_TAG_TRANSIENT_NODEATTRS, FALSE); + attrs = pcmk__xe_first_child(state, PCMK__XE_TRANSIENT_ATTRIBUTES, NULL, + NULL); add_node_attrs(attrs, this_node, TRUE, scheduler); if (pe__shutdown_requested(this_node)) { - crm_info("%s is shutting down", pe__node_name(this_node)); + crm_info("%s is shutting down", pcmk__node_name(this_node)); this_node->details->shutdown = TRUE; } - - if (crm_is_true(pe_node_attribute_raw(this_node, "standby"))) { - crm_info("%s is in standby mode", pe__node_name(this_node)); + + if (crm_is_true(pcmk__node_attr(this_node, PCMK_NODE_ATTR_STANDBY, NULL, + pcmk__rsc_node_current))) { + crm_info("%s is in standby mode", pcmk__node_name(this_node)); this_node->details->standby = TRUE; } - if (crm_is_true(pe_node_attribute_raw(this_node, "maintenance")) || - ((rsc != NULL) && !pcmk_is_set(rsc->flags, pcmk_rsc_managed))) { - crm_info("%s is in maintenance mode", pe__node_name(this_node)); + if (crm_is_true(pcmk__node_attr(this_node, PCMK_NODE_ATTR_MAINTENANCE, NULL, + pcmk__rsc_node_current)) + || ((rsc != NULL) && !pcmk_is_set(rsc->flags, pcmk_rsc_managed))) { + crm_info("%s is in maintenance mode", pcmk__node_name(this_node)); this_node->details->maintenance = TRUE; } - resource_discovery_enabled = pe_node_attribute_raw(this_node, XML_NODE_ATTR_RSC_DISCOVERY); - if (resource_discovery_enabled && !crm_is_true(resource_discovery_enabled)) { - if (pe__is_remote_node(this_node) + discovery = pcmk__node_attr(this_node, + PCMK__NODE_ATTR_RESOURCE_DISCOVERY_ENABLED, + NULL, pcmk__rsc_node_current); + if ((discovery != NULL) && !crm_is_true(discovery)) { + pcmk__warn_once(pcmk__wo_rdisc_enabled, + "Support for the " + PCMK__NODE_ATTR_RESOURCE_DISCOVERY_ENABLED + " node attribute is deprecated and will be removed" + " (and behave as 'true') in a future release."); + + if (pcmk__is_remote_node(this_node) && !pcmk_is_set(scheduler->flags, pcmk_sched_fencing_enabled)) { - crm_warn("Ignoring " XML_NODE_ATTR_RSC_DISCOVERY - " attribute on Pacemaker Remote node %s" - " because fencing is disabled", - pe__node_name(this_node)); + pcmk__config_warn("Ignoring " + PCMK__NODE_ATTR_RESOURCE_DISCOVERY_ENABLED + " attribute on Pacemaker Remote node %s" + " because fencing is disabled", + pcmk__node_name(this_node)); } else { /* This is either a remote node with fencing enabled, or a guest * node. We don't care whether fencing is enabled when fencing guest @@ -1073,7 +1115,7 @@ unpack_handle_remote_attrs(pcmk_node_t *this_node, const xmlNode *state, * resource. */ crm_info("%s has resource discovery disabled", - pe__node_name(this_node)); + pcmk__node_name(this_node)); this_node->details->rsc_discovery_enabled = FALSE; } } @@ -1092,26 +1134,33 @@ unpack_transient_attributes(const xmlNode *state, pcmk_node_t *node, pcmk_scheduler_t *scheduler) { const char *discovery = NULL; - const xmlNode *attrs = find_xml_node(state, XML_TAG_TRANSIENT_NODEATTRS, - FALSE); + const xmlNode *attrs = pcmk__xe_first_child(state, + PCMK__XE_TRANSIENT_ATTRIBUTES, + NULL, NULL); add_node_attrs(attrs, node, TRUE, scheduler); - if (crm_is_true(pe_node_attribute_raw(node, "standby"))) { - crm_info("%s is in standby mode", pe__node_name(node)); + if (crm_is_true(pcmk__node_attr(node, PCMK_NODE_ATTR_STANDBY, NULL, + pcmk__rsc_node_current))) { + crm_info("%s is in standby mode", pcmk__node_name(node)); node->details->standby = TRUE; } - if (crm_is_true(pe_node_attribute_raw(node, "maintenance"))) { - crm_info("%s is in maintenance mode", pe__node_name(node)); + if (crm_is_true(pcmk__node_attr(node, PCMK_NODE_ATTR_MAINTENANCE, NULL, + pcmk__rsc_node_current))) { + crm_info("%s is in maintenance mode", pcmk__node_name(node)); node->details->maintenance = TRUE; } - discovery = pe_node_attribute_raw(node, XML_NODE_ATTR_RSC_DISCOVERY); + discovery = pcmk__node_attr(node, + PCMK__NODE_ATTR_RESOURCE_DISCOVERY_ENABLED, + NULL, pcmk__rsc_node_current); if ((discovery != NULL) && !crm_is_true(discovery)) { - crm_warn("Ignoring " XML_NODE_ATTR_RSC_DISCOVERY - " attribute for %s because disabling resource discovery " - "is not allowed for cluster nodes", pe__node_name(node)); + pcmk__config_warn("Ignoring " + PCMK__NODE_ATTR_RESOURCE_DISCOVERY_ENABLED + " attribute for %s because disabling resource" + " discovery is not allowed for cluster nodes", + pcmk__node_name(node)); } } @@ -1120,9 +1169,9 @@ unpack_transient_attributes(const xmlNode *state, pcmk_node_t *node, * \brief Unpack a node state entry (first pass) * * Unpack one node state entry from status. This unpacks information from the - * node_state element itself and node attributes inside it, but not the - * resource history inside it. Multiple passes through the status are needed to - * fully unpack everything. + * \C PCMK__XE_NODE_STATE element itself and node attributes inside it, but not + * the resource history inside it. Multiple passes through the status are needed + * to fully unpack everything. * * \param[in] state CIB node state XML * \param[in,out] scheduler Scheduler data @@ -1134,40 +1183,41 @@ unpack_node_state(const xmlNode *state, pcmk_scheduler_t *scheduler) const char *uname = NULL; pcmk_node_t *this_node = NULL; - id = crm_element_value(state, XML_ATTR_ID); + id = crm_element_value(state, PCMK_XA_ID); if (id == NULL) { - crm_warn("Ignoring malformed " XML_CIB_TAG_STATE " entry without " - XML_ATTR_ID); + pcmk__config_err("Ignoring invalid " PCMK__XE_NODE_STATE " entry without " + PCMK_XA_ID); + crm_log_xml_info(state, "missing-id"); return; } - uname = crm_element_value(state, XML_ATTR_UNAME); + uname = crm_element_value(state, PCMK_XA_UNAME); if (uname == NULL) { /* If a joining peer makes the cluster acquire the quorum from corosync * meanwhile it has not joined CPG membership of pacemaker-controld yet, - * it's possible that the created node_state entry doesn't have an uname - * yet. We should recognize the node as `pending` and wait for it to - * join CPG. + * it's possible that the created PCMK__XE_NODE_STATE entry doesn't have + * a PCMK_XA_UNAME yet. We should recognize the node as `pending` and + * wait for it to join CPG. */ - crm_trace("Handling " XML_CIB_TAG_STATE " entry with id=\"%s\" without " - XML_ATTR_UNAME, id); + crm_trace("Handling " PCMK__XE_NODE_STATE " entry with id=\"%s\" " + "without " PCMK_XA_UNAME, + id); } this_node = pe_find_node_any(scheduler->nodes, id, uname); if (this_node == NULL) { - pcmk__config_warn("Ignoring recorded node state for id=\"%s\" (%s) " - "because it is no longer in the configuration", - id, pcmk__s(uname, "uname unknown")); + crm_notice("Ignoring recorded state for removed node with name %s and " + PCMK_XA_ID " %s", pcmk__s(uname, "unknown"), id); return; } - if (pe__is_guest_or_remote_node(this_node)) { + if (pcmk__is_pacemaker_remote_node(this_node)) { /* We can't determine the online status of Pacemaker Remote nodes until * after all resource history has been unpacked. In this first pass, we * do need to mark whether the node has been fenced, as this plays a * role during unpacking cluster node resource state. */ - pcmk__scan_min_int(crm_element_value(state, XML_NODE_IS_FENCED), + pcmk__scan_min_int(crm_element_value(state, PCMK__XA_NODE_FENCED), &(this_node->details->remote_was_fenced), 0); return; } @@ -1181,7 +1231,7 @@ unpack_node_state(const xmlNode *state, pcmk_scheduler_t *scheduler) this_node->details->unseen = FALSE; crm_trace("Determining online status of cluster node %s (id %s)", - pe__node_name(this_node), id); + pcmk__node_name(this_node), id); determine_online_status(state, this_node, scheduler); if (!pcmk_is_set(scheduler->flags, pcmk_sched_quorate) @@ -1219,18 +1269,20 @@ unpack_node_history(const xmlNode *status, bool fence, { int rc = pcmk_rc_ok; - // Loop through all node_state entries in CIB status - for (const xmlNode *state = first_named_child(status, XML_CIB_TAG_STATE); - state != NULL; state = crm_next_same_xml(state)) { + // Loop through all PCMK__XE_NODE_STATE entries in CIB status + for (const xmlNode *state = pcmk__xe_first_child(status, + PCMK__XE_NODE_STATE, NULL, + NULL); + state != NULL; state = pcmk__xe_next_same(state)) { - const char *id = ID(state); - const char *uname = crm_element_value(state, XML_ATTR_UNAME); + const char *id = pcmk__xe_id(state); + const char *uname = crm_element_value(state, PCMK_XA_UNAME); pcmk_node_t *this_node = NULL; if ((id == NULL) || (uname == NULL)) { // Warning already logged in first pass through status section crm_trace("Not unpacking resource history from malformed " - XML_CIB_TAG_STATE " without id and/or uname"); + PCMK__XE_NODE_STATE " without id and/or uname"); continue; } @@ -1251,7 +1303,7 @@ unpack_node_history(const xmlNode *status, bool fence, if (fence) { // We're processing all remaining nodes - } else if (pe__is_guest_node(this_node)) { + } else if (pcmk__is_guest_or_bundle_node(this_node)) { /* We can unpack a guest node's history only after we've unpacked * other resource history to the point that we know that the node's * connection and containing resource are both up. @@ -1266,7 +1318,7 @@ unpack_node_history(const xmlNode *status, bool fence, continue; } - } else if (pe__is_remote_node(this_node)) { + } else if (pcmk__is_remote_node(this_node)) { /* We can unpack a remote node's history only after we've unpacked * other resource history to the point that we know that the node's * connection is up, with the exception of when shutdown locks are @@ -1296,7 +1348,7 @@ unpack_node_history(const xmlNode *status, bool fence, continue; } - if (pe__is_guest_or_remote_node(this_node)) { + if (pcmk__is_pacemaker_remote_node(this_node)) { determine_remote_online_status(scheduler, this_node); unpack_handle_remote_attrs(this_node, state, scheduler); } @@ -1326,13 +1378,13 @@ unpack_status(xmlNode *status, pcmk_scheduler_t *scheduler) scheduler->tickets = pcmk__strkey_table(free, destroy_ticket); } - for (state = pcmk__xe_first_child(status); state != NULL; + for (state = pcmk__xe_first_child(status, NULL, NULL, NULL); state != NULL; state = pcmk__xe_next(state)) { - if (pcmk__str_eq((const char *)state->name, XML_CIB_TAG_TICKETS, pcmk__str_none)) { + if (pcmk__xe_is(state, PCMK_XE_TICKETS)) { unpack_tickets_state((xmlNode *) state, scheduler); - } else if (pcmk__str_eq((const char *)state->name, XML_CIB_TAG_STATE, pcmk__str_none)) { + } else if (pcmk__xe_is(state, PCMK__XE_NODE_STATE)) { unpack_node_state(state, scheduler); } } @@ -1353,7 +1405,7 @@ unpack_status(xmlNode *status, pcmk_scheduler_t *scheduler) if (scheduler->stop_needed != NULL) { for (GList *item = scheduler->stop_needed; item; item = item->next) { pcmk_resource_t *container = item->data; - pcmk_node_t *node = pe__current_node(container); + pcmk_node_t *node = pcmk__current_node(container); if (node) { stop_action(container, node, FALSE); @@ -1370,7 +1422,7 @@ unpack_status(xmlNode *status, pcmk_scheduler_t *scheduler) for (GList *gIter = scheduler->nodes; gIter != NULL; gIter = gIter->next) { pcmk_node_t *this_node = gIter->data; - if (!pe__is_guest_or_remote_node(this_node)) { + if (!pcmk__is_pacemaker_remote_node(this_node)) { continue; } if (this_node->details->shutdown @@ -1390,7 +1442,7 @@ unpack_status(xmlNode *status, pcmk_scheduler_t *scheduler) * \internal * \brief Unpack node's time when it became a member at the cluster layer * - * \param[in] node_state Node's node_state entry + * \param[in] node_state Node's \c PCMK__XE_NODE_STATE entry * \param[in,out] scheduler Scheduler data * * \return Epoch time when node became a cluster member @@ -1410,7 +1462,7 @@ unpack_node_member(const xmlNode *node_state, pcmk_scheduler_t *scheduler) /* If in_ccm=0, we'll return 0 here. If in_ccm=1, either the entry was * recorded as a boolean for a DC < 2.1.7, or the node is pending * shutdown and has left the CPG, in which case it was set to 1 to avoid - * fencing for node-pending-timeout. + * fencing for PCMK_OPT_NODE_PENDING_TIMEOUT. * * We return the effective time for in_ccm=1 because what's important to * avoid fencing is that effective time minus this value is less than @@ -1424,7 +1476,7 @@ unpack_node_member(const xmlNode *node_state, pcmk_scheduler_t *scheduler) if ((pcmk__scan_ll(member_time, &when_member, 0LL) != pcmk_rc_ok) || (when_member < 0LL)) { crm_warn("Unrecognized value '%s' for " PCMK__XA_IN_CCM - " in " XML_CIB_TAG_STATE " entry", member_time); + " in " PCMK__XE_NODE_STATE " entry", member_time); return -1LL; } return when_member; @@ -1435,7 +1487,7 @@ unpack_node_member(const xmlNode *node_state, pcmk_scheduler_t *scheduler) * \internal * \brief Unpack node's time when it became online in process group * - * \param[in] node_state Node's node_state entry + * \param[in] node_state Node's \c PCMK__XE_NODE_STATE entry * * \return Epoch time when node became online in process group (or 0 if not * online, or 1 for legacy online entries) @@ -1443,14 +1495,14 @@ unpack_node_member(const xmlNode *node_state, pcmk_scheduler_t *scheduler) static long long unpack_node_online(const xmlNode *node_state) { - const char *peer_time = crm_element_value(node_state, PCMK__XA_CRMD); + const char *peer_time = crm_element_value(node_state, PCMK_XA_CRMD); // @COMPAT Entries recorded for DCs < 2.1.7 have "online" or "offline" - if (pcmk__str_eq(peer_time, OFFLINESTATUS, + if (pcmk__str_eq(peer_time, PCMK_VALUE_OFFLINE, pcmk__str_casei|pcmk__str_null_matches)) { return 0LL; - } else if (pcmk__str_eq(peer_time, ONLINESTATUS, pcmk__str_casei)) { + } else if (pcmk__str_eq(peer_time, PCMK_VALUE_ONLINE, pcmk__str_casei)) { return 1LL; } else { @@ -1458,8 +1510,8 @@ unpack_node_online(const xmlNode *node_state) if ((pcmk__scan_ll(peer_time, &when_online, 0LL) != pcmk_rc_ok) || (when_online < 0)) { - crm_warn("Unrecognized value '%s' for " PCMK__XA_CRMD " in " - XML_CIB_TAG_STATE " entry, assuming offline", peer_time); + crm_warn("Unrecognized value '%s' for " PCMK_XA_CRMD " in " + PCMK__XE_NODE_STATE " entry, assuming offline", peer_time); return 0LL; } return when_online; @@ -1471,7 +1523,7 @@ unpack_node_online(const xmlNode *node_state) * \brief Unpack node attribute for user-requested fencing * * \param[in] node Node to check - * \param[in] node_state Node's node_state entry in CIB status + * \param[in] node_state Node's \c PCMK__XE_NODE_STATE entry in CIB status * * \return \c true if fencing has been requested for \p node, otherwise \c false */ @@ -1480,7 +1532,8 @@ unpack_node_terminate(const pcmk_node_t *node, const xmlNode *node_state) { long long value = 0LL; int value_i = 0; - const char *value_s = pe_node_attribute_raw(node, PCMK_NODE_ATTR_TERMINATE); + const char *value_s = pcmk__node_attr(node, PCMK_NODE_ATTR_TERMINATE, + NULL, pcmk__rsc_node_current); // Value may be boolean or an epoch time if (crm_str_to_boolean(value_s, &value_i) == 1) { @@ -1490,7 +1543,7 @@ unpack_node_terminate(const pcmk_node_t *node, const xmlNode *node_state) return (value > 0); } crm_warn("Ignoring unrecognized value '%s' for " PCMK_NODE_ATTR_TERMINATE - "node attribute for %s", value_s, pe__node_name(node)); + "node attribute for %s", value_s, pcmk__node_name(node)); return false; } @@ -1501,12 +1554,12 @@ determine_online_status_no_fencing(pcmk_scheduler_t *scheduler, { gboolean online = FALSE; const char *join = crm_element_value(node_state, PCMK__XA_JOIN); - const char *exp_state = crm_element_value(node_state, PCMK__XA_EXPECTED); + const char *exp_state = crm_element_value(node_state, PCMK_XA_EXPECTED); long long when_member = unpack_node_member(node_state, scheduler); long long when_online = unpack_node_online(node_state); if (when_member <= 0) { - crm_trace("Node %s is %sdown", pe__node_name(this_node), + crm_trace("Node %s is %sdown", pcmk__node_name(this_node), ((when_member < 0)? "presumed " : "")); } else if (when_online > 0) { @@ -1514,20 +1567,20 @@ determine_online_status_no_fencing(pcmk_scheduler_t *scheduler, online = TRUE; } else { crm_debug("Node %s is not ready to run resources: %s", - pe__node_name(this_node), join); + pcmk__node_name(this_node), join); } } else if (this_node->details->expected_up == FALSE) { crm_trace("Node %s controller is down: " "member@%lld online@%lld join=%s expected=%s", - pe__node_name(this_node), when_member, when_online, + pcmk__node_name(this_node), when_member, when_online, pcmk__s(join, "<null>"), pcmk__s(exp_state, "<null>")); } else { /* mark it unclean */ pe_fence_node(scheduler, this_node, "peer is unexpectedly down", FALSE); crm_info("Node %s member@%lld online@%lld join=%s expected=%s", - pe__node_name(this_node), when_member, when_online, + pcmk__node_name(this_node), when_member, when_online, pcmk__s(join, "<null>"), pcmk__s(exp_state, "<null>")); } return online; @@ -1543,7 +1596,7 @@ determine_online_status_no_fencing(pcmk_scheduler_t *scheduler, * \param[in] when_online Epoch time when node joined controller group * * \return true if node has been pending (on the way up) longer than - * node-pending-timeout, otherwise false + * \c PCMK_OPT_NODE_PENDING_TIMEOUT, otherwise false * \note This will also update the cluster's recheck time if appropriate. */ static inline bool @@ -1573,35 +1626,35 @@ determine_online_status_fencing(pcmk_scheduler_t *scheduler, { bool termination_requested = unpack_node_terminate(this_node, node_state); const char *join = crm_element_value(node_state, PCMK__XA_JOIN); - const char *exp_state = crm_element_value(node_state, PCMK__XA_EXPECTED); + const char *exp_state = crm_element_value(node_state, PCMK_XA_EXPECTED); long long when_member = unpack_node_member(node_state, scheduler); long long when_online = unpack_node_online(node_state); /* - PCMK__XA_JOIN ::= member|down|pending|banned - - PCMK__XA_EXPECTED ::= member|down + - PCMK_XA_EXPECTED ::= member|down @COMPAT with entries recorded for DCs < 2.1.7 - PCMK__XA_IN_CCM ::= true|false - - PCMK__XA_CRMD ::= online|offline + - PCMK_XA_CRMD ::= online|offline Since crm_feature_set 3.18.0 (pacemaker-2.1.7): - PCMK__XA_IN_CCM ::= <timestamp>|0 Since when node has been a cluster member. A value 0 of means the node is not a cluster member. - - PCMK__XA_CRMD ::= <timestamp>|0 + - PCMK_XA_CRMD ::= <timestamp>|0 Since when peer has been online in CPG. A value 0 means the peer is offline in CPG. */ crm_trace("Node %s member@%lld online@%lld join=%s expected=%s%s", - pe__node_name(this_node), when_member, when_online, + pcmk__node_name(this_node), when_member, when_online, pcmk__s(join, "<null>"), pcmk__s(exp_state, "<null>"), (termination_requested? " (termination requested)" : "")); if (this_node->details->shutdown) { - crm_debug("%s is shutting down", pe__node_name(this_node)); + crm_debug("%s is shutting down", pcmk__node_name(this_node)); /* Slightly different criteria since we can't shut down a dead peer */ return (when_online > 0); @@ -1620,7 +1673,7 @@ determine_online_status_fencing(pcmk_scheduler_t *scheduler, } else if (termination_requested) { if ((when_member <= 0) && (when_online <= 0) && pcmk__str_eq(join, CRMD_JOINSTATE_DOWN, pcmk__str_none)) { - crm_info("%s was fenced as requested", pe__node_name(this_node)); + crm_info("%s was fenced as requested", pcmk__node_name(this_node)); return false; } pe_fence_node(scheduler, this_node, "fencing was requested", false); @@ -1635,17 +1688,17 @@ determine_online_status_fencing(pcmk_scheduler_t *scheduler, } else if ((when_member > 0) || (when_online > 0)) { crm_info("- %s is not ready to run resources", - pe__node_name(this_node)); + pcmk__node_name(this_node)); this_node->details->standby = TRUE; this_node->details->pending = TRUE; } else { crm_trace("%s is down or still coming up", - pe__node_name(this_node)); + pcmk__node_name(this_node)); } } else if (when_member <= 0) { - // Consider `priority-fencing-delay` for lost nodes + // Consider PCMK_OPT_PRIORITY_FENCING_DELAY for lost nodes pe_fence_node(scheduler, this_node, "peer is no longer part of the cluster", TRUE); @@ -1656,11 +1709,12 @@ determine_online_status_fencing(pcmk_scheduler_t *scheduler, /* Everything is running at this point, now check join state */ } else if (pcmk__str_eq(join, CRMD_JOINSTATE_MEMBER, pcmk__str_none)) { - crm_info("%s is active", pe__node_name(this_node)); + crm_info("%s is active", pcmk__node_name(this_node)); } else if (pcmk__str_any_of(join, CRMD_JOINSTATE_PENDING, CRMD_JOINSTATE_DOWN, NULL)) { - crm_info("%s is not ready to run resources", pe__node_name(this_node)); + crm_info("%s is not ready to run resources", + pcmk__node_name(this_node)); this_node->details->standby = TRUE; this_node->details->pending = TRUE; @@ -1750,7 +1804,7 @@ determine_online_status(const xmlNode *node_state, pcmk_node_t *this_node, pcmk_scheduler_t *scheduler) { gboolean online = FALSE; - const char *exp_state = crm_element_value(node_state, PCMK__XA_EXPECTED); + const char *exp_state = crm_element_value(node_state, PCMK_XA_EXPECTED); CRM_CHECK(this_node != NULL, return); @@ -1786,30 +1840,30 @@ determine_online_status(const xmlNode *node_state, pcmk_node_t *this_node, } else { /* remove node from contention */ this_node->fixed = TRUE; // @COMPAT deprecated and unused - this_node->weight = -INFINITY; + this_node->weight = -PCMK_SCORE_INFINITY; } if (online && this_node->details->shutdown) { /* don't run resources here */ this_node->fixed = TRUE; // @COMPAT deprecated and unused - this_node->weight = -INFINITY; + this_node->weight = -PCMK_SCORE_INFINITY; } if (this_node->details->type == node_ping) { - crm_info("%s is not a Pacemaker node", pe__node_name(this_node)); + crm_info("%s is not a Pacemaker node", pcmk__node_name(this_node)); } else if (this_node->details->unclean) { - pe_proc_warn("%s is unclean", pe__node_name(this_node)); + pcmk__sched_warn("%s is unclean", pcmk__node_name(this_node)); } else if (this_node->details->online) { - crm_info("%s is %s", pe__node_name(this_node), + crm_info("%s is %s", pcmk__node_name(this_node), this_node->details->shutdown ? "shutting down" : this_node->details->pending ? "pending" : this_node->details->standby ? "standby" : this_node->details->maintenance ? "maintenance" : "online"); } else { - crm_trace("%s is offline", pe__node_name(this_node)); + crm_trace("%s is offline", pcmk__node_name(this_node)); } } @@ -1891,8 +1945,7 @@ clone_zero(const char *last_rsc_id) char *zero = NULL; CRM_ASSERT(end); - zero = calloc(base_name_len + 3, sizeof(char)); - CRM_ASSERT(zero); + zero = pcmk__assert_alloc(base_name_len + 3, sizeof(char)); memcpy(zero, last_rsc_id, base_name_len); zero[base_name_len] = ':'; zero[base_name_len + 1] = '0'; @@ -1904,10 +1957,10 @@ create_fake_resource(const char *rsc_id, const xmlNode *rsc_entry, pcmk_scheduler_t *scheduler) { pcmk_resource_t *rsc = NULL; - xmlNode *xml_rsc = create_xml_node(NULL, XML_CIB_TAG_RESOURCE); + xmlNode *xml_rsc = pcmk__xe_create(NULL, PCMK_XE_PRIMITIVE); - copy_in_properties(xml_rsc, rsc_entry); - crm_xml_add(xml_rsc, XML_ATTR_ID, rsc_id); + pcmk__xe_copy_attrs(xml_rsc, rsc_entry, pcmk__xaf_none); + crm_xml_add(xml_rsc, PCMK_XA_ID, rsc_id); crm_log_xml_debug(xml_rsc, "Orphan resource"); if (pe__unpack_resource(xml_rsc, &rsc, NULL, scheduler) != pcmk_rc_ok) { @@ -1918,9 +1971,10 @@ create_fake_resource(const char *rsc_id, const xmlNode *rsc_entry, pcmk_node_t *node; crm_debug("Detected orphaned remote node %s", rsc_id); - node = pe_find_node(scheduler->nodes, rsc_id); + node = pcmk_find_node(scheduler, rsc_id); if (node == NULL) { - node = pe_create_node(rsc_id, rsc_id, "remote", NULL, scheduler); + node = pe_create_node(rsc_id, rsc_id, PCMK_VALUE_REMOTE, NULL, + scheduler); } link_rsc2remotenode(scheduler, rsc); @@ -1930,12 +1984,12 @@ create_fake_resource(const char *rsc_id, const xmlNode *rsc_entry, } } - if (crm_element_value(rsc_entry, XML_RSC_ATTR_CONTAINER)) { + if (crm_element_value(rsc_entry, PCMK__META_CONTAINER)) { /* This orphaned rsc needs to be mapped to a container. */ crm_trace("Detected orphaned container filler %s", rsc_id); - pe__set_resource_flags(rsc, pcmk_rsc_removed_filler); + pcmk__set_rsc_flags(rsc, pcmk_rsc_removed_filler); } - pe__set_resource_flags(rsc, pcmk_rsc_removed); + pcmk__set_rsc_flags(rsc, pcmk_rsc_removed); scheduler->resources = g_list_append(scheduler->resources, rsc); return rsc; } @@ -1961,8 +2015,8 @@ create_anonymous_orphan(pcmk_resource_t *parent, const char *rsc_id, pcmk_resource_t *orphan = top->fns->find_rsc(top, rsc_id, NULL, pcmk_rsc_match_clone_only); - pe_rsc_debug(parent, "Created orphan %s for %s: %s on %s", - top->id, parent->id, rsc_id, pe__node_name(node)); + pcmk__rsc_debug(parent, "Created orphan %s for %s: %s on %s", + top->id, parent->id, rsc_id, pcmk__node_name(node)); return orphan; } @@ -1972,8 +2026,9 @@ create_anonymous_orphan(pcmk_resource_t *parent, const char *rsc_id, * * Return a child instance of the specified anonymous clone, in order of * preference: (1) the instance running on the specified node, if any; - * (2) an inactive instance (i.e. within the total of clone-max instances); - * (3) a newly created orphan (i.e. clone-max instances are already active). + * (2) an inactive instance (i.e. within the total of \c PCMK_META_CLONE_MAX + * instances); (3) a newly created orphan (that is, \c PCMK_META_CLONE_MAX + * instances are already active). * * \param[in,out] scheduler Scheduler data * \param[in] node Node on which to check for instance @@ -1989,13 +2044,11 @@ find_anonymous_clone(pcmk_scheduler_t *scheduler, const pcmk_node_t *node, pcmk_resource_t *inactive_instance = NULL; gboolean skip_inactive = FALSE; - CRM_ASSERT(parent != NULL); - CRM_ASSERT(pe_rsc_is_clone(parent)); - CRM_ASSERT(!pcmk_is_set(parent->flags, pcmk_rsc_unique)); + CRM_ASSERT(pcmk__is_anonymous_clone(parent)); // Check for active (or partially active, for cloned groups) instance - pe_rsc_trace(parent, "Looking for %s on %s in %s", - rsc_id, pe__node_name(node), parent->id); + pcmk__rsc_trace(parent, "Looking for %s on %s in %s", + rsc_id, pcmk__node_name(node), parent->id); for (rIter = parent->children; rsc == NULL && rIter; rIter = rIter->next) { GList *locations = NULL; pcmk_resource_t *child = rIter->data; @@ -2010,8 +2063,8 @@ find_anonymous_clone(pcmk_scheduler_t *scheduler, const pcmk_node_t *node, * (1) when child is a cloned group and we have already unpacked the * history of another member of the group on the same node; * (2) when we've already unpacked the history of another numbered - * instance on the same node (which can happen if globally-unique - * was flipped from true to false); and + * instance on the same node (which can happen if + * PCMK_META_GLOBALLY_UNIQUE was flipped from true to false); and * (3) when we re-run calculations on the same scheduler data as part of * a simulation. */ @@ -2023,7 +2076,7 @@ find_anonymous_clone(pcmk_scheduler_t *scheduler, const pcmk_node_t *node, */ CRM_LOG_ASSERT(locations->next == NULL); - if (((pcmk_node_t *) locations->data)->details == node->details) { + if (pcmk__same_node((pcmk_node_t *) locations->data, node)) { /* This child instance is active on the requested node, so check * for a corresponding configured resource. We use find_rsc() * instead of child because child may be a cloned group, and we @@ -2036,26 +2089,26 @@ find_anonymous_clone(pcmk_scheduler_t *scheduler, const pcmk_node_t *node, if (rsc) { /* If there are multiple instance history entries for an * anonymous clone in a single node's history (which can - * happen if globally-unique is switched from true to - * false), we want to consider the instances beyond the + * happen if PCMK_META_GLOBALLY_UNIQUE is switched from true + * to false), we want to consider the instances beyond the * first as orphans, even if there are inactive instance * numbers available. */ if (rsc->running_on) { crm_notice("Active (now-)anonymous clone %s has " "multiple (orphan) instance histories on %s", - parent->id, pe__node_name(node)); + parent->id, pcmk__node_name(node)); skip_inactive = TRUE; rsc = NULL; } else { - pe_rsc_trace(parent, "Resource %s, active", rsc->id); + pcmk__rsc_trace(parent, "Resource %s, active", rsc->id); } } } g_list_free(locations); } else { - pe_rsc_trace(parent, "Resource %s, skip inactive", child->id); + pcmk__rsc_trace(parent, "Resource %s, skip inactive", child->id); if (!skip_inactive && !inactive_instance && !pcmk_is_set(child->flags, pcmk_rsc_blocked)) { // Remember one inactive instance in case we don't find active @@ -2065,8 +2118,9 @@ find_anonymous_clone(pcmk_scheduler_t *scheduler, const pcmk_node_t *node, /* ... but don't use it if it was already associated with a * pending action on another node */ - if (inactive_instance && inactive_instance->pending_node - && (inactive_instance->pending_node->details != node->details)) { + if ((inactive_instance != NULL) && + (inactive_instance->pending_node != NULL) && + !pcmk__same_node(inactive_instance->pending_node, node)) { inactive_instance = NULL; } } @@ -2074,15 +2128,17 @@ find_anonymous_clone(pcmk_scheduler_t *scheduler, const pcmk_node_t *node, } if ((rsc == NULL) && !skip_inactive && (inactive_instance != NULL)) { - pe_rsc_trace(parent, "Resource %s, empty slot", inactive_instance->id); + pcmk__rsc_trace(parent, "Resource %s, empty slot", + inactive_instance->id); rsc = inactive_instance; } - /* If the resource has "requires" set to "quorum" or "nothing", and we don't - * have a clone instance for every node, we don't want to consume a valid - * instance number for unclean nodes. Such instances may appear to be active - * according to the history, but should be considered inactive, so we can - * start an instance elsewhere. Treat such instances as orphans. + /* If the resource has PCMK_META_REQUIRES set to PCMK_VALUE_QUORUM or + * PCMK_VALUE_NOTHING, and we don't have a clone instance for every node, we + * don't want to consume a valid instance number for unclean nodes. Such + * instances may appear to be active according to the history, but should be + * considered inactive, so we can start an instance elsewhere. Treat such + * instances as orphans. * * An exception is instances running on guest nodes -- since guest node * "fencing" is actually just a resource stop, requires shouldn't apply. @@ -2092,7 +2148,7 @@ find_anonymous_clone(pcmk_scheduler_t *scheduler, const pcmk_node_t *node, */ if ((rsc != NULL) && !pcmk_is_set(rsc->flags, pcmk_rsc_needs_fencing) && (!node->details->online || node->details->unclean) - && !pe__is_guest_node(node) + && !pcmk__is_guest_or_bundle_node(node) && !pe__is_universal_clone(parent, scheduler)) { rsc = NULL; @@ -2100,7 +2156,7 @@ find_anonymous_clone(pcmk_scheduler_t *scheduler, const pcmk_node_t *node, if (rsc == NULL) { rsc = create_anonymous_orphan(parent, rsc_id, node, scheduler); - pe_rsc_trace(parent, "Resource %s, orphan", rsc->id); + pcmk__rsc_trace(parent, "Resource %s, orphan", rsc->id); } return rsc; } @@ -2117,8 +2173,8 @@ unpack_find_resource(pcmk_scheduler_t *scheduler, const pcmk_node_t *node, if (rsc == NULL) { /* If we didn't find the resource by its name in the operation history, - * check it again as a clone instance. Even when clone-max=0, we create - * a single :0 orphan to match against here. + * check it again as a clone instance. Even when PCMK_META_CLONE_MAX=0, + * we create a single :0 orphan to match against here. */ char *clone0_id = clone_zero(rsc_id); pcmk_resource_t *clone0 = pe_find_resource(scheduler->resources, @@ -2143,9 +2199,9 @@ unpack_find_resource(pcmk_scheduler_t *scheduler, const pcmk_node_t *node, parent = uber_parent(rsc); } - if (pe_rsc_is_anon_clone(parent)) { + if (pcmk__is_anonymous_clone(parent)) { - if (pe_rsc_is_bundled(parent)) { + if (pcmk__is_bundled(parent)) { rsc = pe__find_bundle_replica(parent->parent, node); } else { char *base = clone_strip(rsc_id); @@ -2156,13 +2212,13 @@ unpack_find_resource(pcmk_scheduler_t *scheduler, const pcmk_node_t *node, } } - if (rsc && !pcmk__str_eq(rsc_id, rsc->id, pcmk__str_casei) - && !pcmk__str_eq(rsc_id, rsc->clone_name, pcmk__str_casei)) { + if (rsc && !pcmk__str_eq(rsc_id, rsc->id, pcmk__str_none) + && !pcmk__str_eq(rsc_id, rsc->clone_name, pcmk__str_none)) { pcmk__str_update(&rsc->clone_name, rsc_id); - pe_rsc_debug(rsc, "Internally renamed %s on %s to %s%s", - rsc_id, pe__node_name(node), rsc->id, - (pcmk_is_set(rsc->flags, pcmk_rsc_removed)? " (ORPHAN)" : "")); + pcmk__rsc_debug(rsc, "Internally renamed %s on %s to %s%s", + rsc_id, pcmk__node_name(node), rsc->id, + pcmk_is_set(rsc->flags, pcmk_rsc_removed)? " (ORPHAN)" : ""); } return rsc; } @@ -2172,22 +2228,23 @@ process_orphan_resource(const xmlNode *rsc_entry, const pcmk_node_t *node, pcmk_scheduler_t *scheduler) { pcmk_resource_t *rsc = NULL; - const char *rsc_id = crm_element_value(rsc_entry, XML_ATTR_ID); + const char *rsc_id = crm_element_value(rsc_entry, PCMK_XA_ID); - crm_debug("Detected orphan resource %s on %s", rsc_id, pe__node_name(node)); + crm_debug("Detected orphan resource %s on %s", + rsc_id, pcmk__node_name(node)); rsc = create_fake_resource(rsc_id, rsc_entry, scheduler); if (rsc == NULL) { return NULL; } if (!pcmk_is_set(scheduler->flags, pcmk_sched_stop_removed_resources)) { - pe__clear_resource_flags(rsc, pcmk_rsc_managed); + pcmk__clear_rsc_flags(rsc, pcmk_rsc_managed); } else { CRM_CHECK(rsc != NULL, return NULL); - pe_rsc_trace(rsc, "Added orphan %s", rsc->id); - resource_location(rsc, NULL, -INFINITY, "__orphan_do_not_run__", - scheduler); + pcmk__rsc_trace(rsc, "Added orphan %s", rsc->id); + resource_location(rsc, NULL, -PCMK_SCORE_INFINITY, + "__orphan_do_not_run__", scheduler); } return rsc; } @@ -2201,9 +2258,9 @@ process_rsc_state(pcmk_resource_t *rsc, pcmk_node_t *node, enum action_fail_response save_on_fail = pcmk_on_fail_ignore; CRM_ASSERT(rsc); - pe_rsc_trace(rsc, "Resource %s is %s on %s: on_fail=%s", - rsc->id, role2text(rsc->role), pe__node_name(node), - fail2text(on_fail)); + pcmk__rsc_trace(rsc, "Resource %s is %s on %s: on_fail=%s", + rsc->id, pcmk_role_text(rsc->role), pcmk__node_name(node), + pcmk_on_fail_text(on_fail)); /* process current state */ if (rsc->role != pcmk_role_unknown) { @@ -2213,11 +2270,11 @@ process_rsc_state(pcmk_resource_t *rsc, pcmk_node_t *node, if (g_hash_table_lookup(iter->known_on, node->details->id) == NULL) { pcmk_node_t *n = pe__copy_node(node); - pe_rsc_trace(rsc, "%s%s%s known on %s", - rsc->id, - ((rsc->clone_name == NULL)? "" : " also known as "), - ((rsc->clone_name == NULL)? "" : rsc->clone_name), - pe__node_name(n)); + pcmk__rsc_trace(rsc, "%s%s%s known on %s", + rsc->id, + ((rsc->clone_name == NULL)? "" : " also known as "), + ((rsc->clone_name == NULL)? "" : rsc->clone_name), + pcmk__node_name(n)); g_hash_table_insert(iter->known_on, (gpointer) n->details->id, n); } if (pcmk_is_set(iter->flags, pcmk_rsc_unique)) { @@ -2242,14 +2299,14 @@ process_rsc_state(pcmk_resource_t *rsc, pcmk_node_t *node, * operation history in the CIB will be cleared, freeing the affected * resource to run again once we are sure we know its state. */ - if (pe__is_guest_node(node)) { - pe__set_resource_flags(rsc, - pcmk_rsc_failed|pcmk_rsc_stop_if_failed); + if (pcmk__is_guest_or_bundle_node(node)) { + pcmk__set_rsc_flags(rsc, pcmk_rsc_failed|pcmk_rsc_stop_if_failed); should_fence = TRUE; } else if (pcmk_is_set(rsc->cluster->flags, pcmk_sched_fencing_enabled)) { - if (pe__is_remote_node(node) && node->details->remote_rsc + if (pcmk__is_remote_node(node) + && (node->details->remote_rsc != NULL) && !pcmk_is_set(node->details->remote_rsc->flags, pcmk_rsc_failed)) { @@ -2293,7 +2350,7 @@ process_rsc_state(pcmk_resource_t *rsc, pcmk_node_t *node, break; case pcmk_on_fail_demote: - pe__set_resource_flags(rsc, pcmk_rsc_failed); + pcmk__set_rsc_flags(rsc, pcmk_rsc_failed); demote_action(rsc, node, FALSE); break; @@ -2315,35 +2372,35 @@ process_rsc_state(pcmk_resource_t *rsc, pcmk_node_t *node, /* is_managed == FALSE will prevent any * actions being sent for the resource */ - pe__clear_resource_flags(rsc, pcmk_rsc_managed); - pe__set_resource_flags(rsc, pcmk_rsc_blocked); + pcmk__clear_rsc_flags(rsc, pcmk_rsc_managed); + pcmk__set_rsc_flags(rsc, pcmk_rsc_blocked); break; case pcmk_on_fail_ban: /* make sure it comes up somewhere else * or not at all */ - resource_location(rsc, node, -INFINITY, "__action_migration_auto__", - rsc->cluster); + resource_location(rsc, node, -PCMK_SCORE_INFINITY, + "__action_migration_auto__", rsc->cluster); break; case pcmk_on_fail_stop: - pe__set_next_role(rsc, pcmk_role_stopped, "on-fail=stop"); + pe__set_next_role(rsc, pcmk_role_stopped, + PCMK_META_ON_FAIL "=" PCMK_VALUE_STOP); break; case pcmk_on_fail_restart: if ((rsc->role != pcmk_role_stopped) && (rsc->role != pcmk_role_unknown)) { - pe__set_resource_flags(rsc, - pcmk_rsc_failed|pcmk_rsc_stop_if_failed); + pcmk__set_rsc_flags(rsc, + pcmk_rsc_failed|pcmk_rsc_stop_if_failed); stop_action(rsc, node, FALSE); } break; case pcmk_on_fail_restart_container: - pe__set_resource_flags(rsc, - pcmk_rsc_failed|pcmk_rsc_stop_if_failed); - if (rsc->container && pe_rsc_is_bundled(rsc)) { + pcmk__set_rsc_flags(rsc, pcmk_rsc_failed|pcmk_rsc_stop_if_failed); + if ((rsc->container != NULL) && pcmk__is_bundled(rsc)) { /* A bundle's remote connection can run on a different node than * the bundle's container. We don't necessarily know where the * container is running yet, so remember it and add a stop @@ -2360,17 +2417,14 @@ process_rsc_state(pcmk_resource_t *rsc, pcmk_node_t *node, break; case pcmk_on_fail_reset_remote: - pe__set_resource_flags(rsc, - pcmk_rsc_failed|pcmk_rsc_stop_if_failed); + pcmk__set_rsc_flags(rsc, pcmk_rsc_failed|pcmk_rsc_stop_if_failed); if (pcmk_is_set(rsc->cluster->flags, pcmk_sched_fencing_enabled)) { tmpnode = NULL; if (rsc->is_remote_node) { - tmpnode = pe_find_node(rsc->cluster->nodes, rsc->id); + tmpnode = pcmk_find_node(rsc->cluster, rsc->id); } - if (tmpnode && - pe__is_remote_node(tmpnode) && - tmpnode->details->remote_was_fenced == 0) { - + if (pcmk__is_remote_node(tmpnode) + && !(tmpnode->details->remote_was_fenced)) { /* The remote connection resource failed in a way that * should result in fencing the remote node. */ @@ -2397,7 +2451,7 @@ process_rsc_state(pcmk_resource_t *rsc, pcmk_node_t *node, * result in a fencing operation regardless if we're going to attempt to * reconnect to the remote-node in this transition or not. */ if (pcmk_is_set(rsc->flags, pcmk_rsc_failed) && rsc->is_remote_node) { - tmpnode = pe_find_node(rsc->cluster->nodes, rsc->id); + tmpnode = pcmk_find_node(rsc->cluster, rsc->id); if (tmpnode && tmpnode->details->unclean) { tmpnode->details->unseen = FALSE; } @@ -2407,13 +2461,13 @@ process_rsc_state(pcmk_resource_t *rsc, pcmk_node_t *node, && (rsc->role != pcmk_role_unknown)) { if (pcmk_is_set(rsc->flags, pcmk_rsc_removed)) { if (pcmk_is_set(rsc->flags, pcmk_rsc_managed)) { - pcmk__config_warn("Detected active orphan %s running on %s", - rsc->id, pe__node_name(node)); + crm_notice("Removed resource %s is active on %s and will be " + "stopped when possible", + rsc->id, pcmk__node_name(node)); } else { - pcmk__config_warn("Resource '%s' must be stopped manually on " - "%s because cluster is configured not to " - "stop active orphans", - rsc->id, pe__node_name(node)); + crm_notice("Removed resource %s must be stopped manually on %s " + "because " PCMK_OPT_STOP_ORPHAN_RESOURCES + " is set to false", rsc->id, pcmk__node_name(node)); } } @@ -2424,11 +2478,11 @@ process_rsc_state(pcmk_resource_t *rsc, pcmk_node_t *node, break; case pcmk_on_fail_demote: case pcmk_on_fail_block: - pe__set_resource_flags(rsc, pcmk_rsc_failed); + pcmk__set_rsc_flags(rsc, pcmk_rsc_failed); break; default: - pe__set_resource_flags(rsc, - pcmk_rsc_failed|pcmk_rsc_stop_if_failed); + pcmk__set_rsc_flags(rsc, + pcmk_rsc_failed|pcmk_rsc_stop_if_failed); break; } @@ -2436,7 +2490,8 @@ process_rsc_state(pcmk_resource_t *rsc, pcmk_node_t *node, /* Only do this for older status sections that included instance numbers * Otherwise stopped instances will appear as orphans */ - pe_rsc_trace(rsc, "Resetting clone_name %s for %s (stopped)", rsc->clone_name, rsc->id); + pcmk__rsc_trace(rsc, "Resetting clone_name %s for %s (stopped)", + rsc->clone_name, rsc->id); free(rsc->clone_name); rsc->clone_name = NULL; @@ -2448,7 +2503,7 @@ process_rsc_state(pcmk_resource_t *rsc, pcmk_node_t *node, for (; gIter != NULL; gIter = gIter->next) { pcmk_action_t *stop = (pcmk_action_t *) gIter->data; - pe__set_action_flags(stop, pcmk_action_optional); + pcmk__set_action_flags(stop, pcmk_action_optional); } g_list_free(possible_matches); @@ -2479,51 +2534,52 @@ process_recurring(pcmk_node_t *node, pcmk_resource_t *rsc, GList *gIter = sorted_op_list; CRM_ASSERT(rsc); - pe_rsc_trace(rsc, "%s: Start index %d, stop index = %d", rsc->id, start_index, stop_index); + pcmk__rsc_trace(rsc, "%s: Start index %d, stop index = %d", + rsc->id, start_index, stop_index); for (; gIter != NULL; gIter = gIter->next) { xmlNode *rsc_op = (xmlNode *) gIter->data; guint interval_ms = 0; char *key = NULL; - const char *id = ID(rsc_op); + const char *id = pcmk__xe_id(rsc_op); counter++; if (node->details->online == FALSE) { - pe_rsc_trace(rsc, "Skipping %s on %s: node is offline", - rsc->id, pe__node_name(node)); + pcmk__rsc_trace(rsc, "Skipping %s on %s: node is offline", + rsc->id, pcmk__node_name(node)); break; /* Need to check if there's a monitor for role="Stopped" */ } else if (start_index < stop_index && counter <= stop_index) { - pe_rsc_trace(rsc, "Skipping %s on %s: resource is not active", - id, pe__node_name(node)); + pcmk__rsc_trace(rsc, "Skipping %s on %s: resource is not active", + id, pcmk__node_name(node)); continue; } else if (counter < start_index) { - pe_rsc_trace(rsc, "Skipping %s on %s: old %d", - id, pe__node_name(node), counter); + pcmk__rsc_trace(rsc, "Skipping %s on %s: old %d", + id, pcmk__node_name(node), counter); continue; } - crm_element_value_ms(rsc_op, XML_LRM_ATTR_INTERVAL_MS, &interval_ms); + crm_element_value_ms(rsc_op, PCMK_META_INTERVAL, &interval_ms); if (interval_ms == 0) { - pe_rsc_trace(rsc, "Skipping %s on %s: non-recurring", - id, pe__node_name(node)); + pcmk__rsc_trace(rsc, "Skipping %s on %s: non-recurring", + id, pcmk__node_name(node)); continue; } - status = crm_element_value(rsc_op, XML_LRM_ATTR_OPSTATUS); + status = crm_element_value(rsc_op, PCMK__XA_OP_STATUS); if (pcmk__str_eq(status, "-1", pcmk__str_casei)) { - pe_rsc_trace(rsc, "Skipping %s on %s: status", - id, pe__node_name(node)); + pcmk__rsc_trace(rsc, "Skipping %s on %s: status", + id, pcmk__node_name(node)); continue; } - task = crm_element_value(rsc_op, XML_LRM_ATTR_TASK); + task = crm_element_value(rsc_op, PCMK_XA_OPERATION); /* create the action */ key = pcmk__op_key(rsc->id, task, interval_ms); - pe_rsc_trace(rsc, "Creating %s on %s", key, pe__node_name(node)); + pcmk__rsc_trace(rsc, "Creating %s on %s", key, pcmk__node_name(node)); custom_action(rsc, key, task, node, TRUE, scheduler); } } @@ -2546,8 +2602,8 @@ calculate_active_ops(const GList *sorted_op_list, int *start_index, counter++; - task = crm_element_value(rsc_op, XML_LRM_ATTR_TASK); - status = crm_element_value(rsc_op, XML_LRM_ATTR_OPSTATUS); + task = crm_element_value(rsc_op, PCMK_XA_OPERATION); + status = crm_element_value(rsc_op, PCMK__XA_OP_STATUS); if (pcmk__str_eq(task, PCMK_ACTION_STOP, pcmk__str_casei) && pcmk__str_eq(status, "0", pcmk__str_casei)) { @@ -2560,7 +2616,7 @@ calculate_active_ops(const GList *sorted_op_list, int *start_index, } else if ((implied_monitor_start <= *stop_index) && pcmk__str_eq(task, PCMK_ACTION_MONITOR, pcmk__str_casei)) { - const char *rc = crm_element_value(rsc_op, XML_LRM_ATTR_RC); + const char *rc = crm_element_value(rsc_op, PCMK__XA_RC_CODE); if (pcmk__strcase_any_of(rc, "0", "8", NULL)) { implied_monitor_start = counter; @@ -2587,14 +2643,14 @@ unpack_shutdown_lock(const xmlNode *rsc_entry, pcmk_resource_t *rsc, { time_t lock_time = 0; // When lock started (i.e. node shutdown time) - if ((crm_element_value_epoch(rsc_entry, XML_CONFIG_ATTR_SHUTDOWN_LOCK, + if ((crm_element_value_epoch(rsc_entry, PCMK_OPT_SHUTDOWN_LOCK, &lock_time) == pcmk_ok) && (lock_time != 0)) { if ((scheduler->shutdown_lock > 0) && (get_effective_time(scheduler) > (lock_time + scheduler->shutdown_lock))) { - pe_rsc_info(rsc, "Shutdown lock for %s on %s expired", - rsc->id, pe__node_name(node)); + pcmk__rsc_info(rsc, "Shutdown lock for %s on %s expired", + rsc->id, pcmk__node_name(node)); pe__clear_resource_history(rsc, node); } else { /* @COMPAT I don't like breaking const signatures, but @@ -2609,10 +2665,10 @@ unpack_shutdown_lock(const xmlNode *rsc_entry, pcmk_resource_t *rsc, /*! * \internal - * \brief Unpack one lrm_resource entry from a node's CIB status + * \brief Unpack one \c PCMK__XE_LRM_RESOURCE entry from a node's CIB status * * \param[in,out] node Node whose status is being unpacked - * \param[in] rsc_entry lrm_resource XML being unpacked + * \param[in] rsc_entry \c PCMK__XE_LRM_RESOURCE XML being unpacked * \param[in,out] scheduler Scheduler data * * \return Resource corresponding to the entry, or NULL if no operation history @@ -2626,7 +2682,7 @@ unpack_lrm_resource(pcmk_node_t *node, const xmlNode *lrm_resource, int start_index = -1; enum rsc_role_e req_role = pcmk_role_unknown; - const char *rsc_id = ID(lrm_resource); + const char *rsc_id = pcmk__xe_id(lrm_resource); pcmk_resource_t *rsc = NULL; GList *op_list = NULL; @@ -2639,16 +2695,20 @@ unpack_lrm_resource(pcmk_node_t *node, const xmlNode *lrm_resource, enum rsc_role_e saved_role = pcmk_role_unknown; if (rsc_id == NULL) { - crm_warn("Ignoring malformed " XML_LRM_TAG_RESOURCE - " entry without id"); + pcmk__config_err("Ignoring invalid " PCMK__XE_LRM_RESOURCE + " entry: No " PCMK_XA_ID); + crm_log_xml_info(lrm_resource, "missing-id"); return NULL; } - crm_trace("Unpacking " XML_LRM_TAG_RESOURCE " for %s on %s", - rsc_id, pe__node_name(node)); + crm_trace("Unpacking " PCMK__XE_LRM_RESOURCE " for %s on %s", + rsc_id, pcmk__node_name(node)); - // Build a list of individual lrm_rsc_op entries, so we can sort them - for (rsc_op = first_named_child(lrm_resource, XML_LRM_TAG_RSC_OP); - rsc_op != NULL; rsc_op = crm_next_same_xml(rsc_op)) { + /* Build a list of individual PCMK__XE_LRM_RSC_OP entries, so we can sort + * them + */ + for (rsc_op = pcmk__xe_first_child(lrm_resource, PCMK__XE_LRM_RSC_OP, NULL, + NULL); + rsc_op != NULL; rsc_op = pcmk__xe_next_same(rsc_op)) { op_list = g_list_prepend(op_list, rsc_op); } @@ -2702,12 +2762,14 @@ unpack_lrm_resource(pcmk_node_t *node, const xmlNode *lrm_resource, if ((rsc->next_role == pcmk_role_unknown) || (req_role < rsc->next_role)) { - pe__set_next_role(rsc, req_role, XML_RSC_ATTR_TARGET_ROLE); + pe__set_next_role(rsc, req_role, PCMK_META_TARGET_ROLE); } else if (req_role > rsc->next_role) { - pe_rsc_info(rsc, "%s: Not overwriting calculated next role %s" - " with requested next role %s", - rsc->id, role2text(rsc->next_role), role2text(req_role)); + pcmk__rsc_info(rsc, + "%s: Not overwriting calculated next role %s" + " with requested next role %s", + rsc->id, pcmk_role_text(rsc->next_role), + pcmk_role_text(req_role)); } } @@ -2722,7 +2784,8 @@ static void handle_orphaned_container_fillers(const xmlNode *lrm_rsc_list, pcmk_scheduler_t *scheduler) { - for (const xmlNode *rsc_entry = pcmk__xe_first_child(lrm_rsc_list); + for (const xmlNode *rsc_entry = pcmk__xe_first_child(lrm_rsc_list, NULL, + NULL, NULL); rsc_entry != NULL; rsc_entry = pcmk__xe_next(rsc_entry)) { pcmk_resource_t *rsc; @@ -2730,12 +2793,12 @@ handle_orphaned_container_fillers(const xmlNode *lrm_rsc_list, const char *rsc_id; const char *container_id; - if (!pcmk__str_eq((const char *)rsc_entry->name, XML_LRM_TAG_RESOURCE, pcmk__str_casei)) { + if (!pcmk__xe_is(rsc_entry, PCMK__XE_LRM_RESOURCE)) { continue; } - container_id = crm_element_value(rsc_entry, XML_RSC_ATTR_CONTAINER); - rsc_id = crm_element_value(rsc_entry, XML_ATTR_ID); + container_id = crm_element_value(rsc_entry, PCMK__META_CONTAINER); + rsc_id = crm_element_value(rsc_entry, PCMK_XA_ID); if (container_id == NULL || rsc_id == NULL) { continue; } @@ -2751,8 +2814,8 @@ handle_orphaned_container_fillers(const xmlNode *lrm_rsc_list, continue; } - pe_rsc_trace(rsc, "Mapped container of orphaned resource %s to %s", - rsc->id, container_id); + pcmk__rsc_trace(rsc, "Mapped container of orphaned resource %s to %s", + rsc->id, container_id); rsc->container = container; container->fillers = g_list_append(container->fillers, rsc); } @@ -2772,19 +2835,21 @@ unpack_node_lrm(pcmk_node_t *node, const xmlNode *xml, { bool found_orphaned_container_filler = false; - // Drill down to lrm_resources section - xml = find_xml_node(xml, XML_CIB_TAG_LRM, FALSE); + // Drill down to PCMK__XE_LRM_RESOURCES section + xml = pcmk__xe_first_child(xml, PCMK__XE_LRM, NULL, NULL); if (xml == NULL) { return; } - xml = find_xml_node(xml, XML_LRM_TAG_RESOURCES, FALSE); + xml = pcmk__xe_first_child(xml, PCMK__XE_LRM_RESOURCES, NULL, NULL); if (xml == NULL) { return; } - // Unpack each lrm_resource entry - for (const xmlNode *rsc_entry = first_named_child(xml, XML_LRM_TAG_RESOURCE); - rsc_entry != NULL; rsc_entry = crm_next_same_xml(rsc_entry)) { + // Unpack each PCMK__XE_LRM_RESOURCE entry + for (const xmlNode *rsc_entry = pcmk__xe_first_child(xml, + PCMK__XE_LRM_RESOURCE, + NULL, NULL); + rsc_entry != NULL; rsc_entry = pcmk__xe_next_same(rsc_entry)) { pcmk_resource_t *rsc = unpack_lrm_resource(node, rsc_entry, scheduler); @@ -2823,12 +2888,12 @@ set_node_score(gpointer key, gpointer value, gpointer user_data) node->weight = *score; } -#define XPATH_NODE_STATE "/" XML_TAG_CIB "/" XML_CIB_TAG_STATUS \ - "/" XML_CIB_TAG_STATE -#define SUB_XPATH_LRM_RESOURCE "/" XML_CIB_TAG_LRM \ - "/" XML_LRM_TAG_RESOURCES \ - "/" XML_LRM_TAG_RESOURCE -#define SUB_XPATH_LRM_RSC_OP "/" XML_LRM_TAG_RSC_OP +#define XPATH_NODE_STATE "/" PCMK_XE_CIB "/" PCMK_XE_STATUS \ + "/" PCMK__XE_NODE_STATE +#define SUB_XPATH_LRM_RESOURCE "/" PCMK__XE_LRM \ + "/" PCMK__XE_LRM_RESOURCES \ + "/" PCMK__XE_LRM_RESOURCE +#define SUB_XPATH_LRM_RSC_OP "/" PCMK__XE_LRM_RSC_OP static xmlNode * find_lrm_op(const char *resource, const char *op, const char *node, const char *source, @@ -2842,21 +2907,21 @@ find_lrm_op(const char *resource, const char *op, const char *node, const char * xpath = g_string_sized_new(256); pcmk__g_strcat(xpath, - XPATH_NODE_STATE "[@" XML_ATTR_UNAME "='", node, "']" - SUB_XPATH_LRM_RESOURCE "[@" XML_ATTR_ID "='", resource, "']" - SUB_XPATH_LRM_RSC_OP "[@" XML_LRM_ATTR_TASK "='", op, "'", + XPATH_NODE_STATE "[@" PCMK_XA_UNAME "='", node, "']" + SUB_XPATH_LRM_RESOURCE "[@" PCMK_XA_ID "='", resource, "']" + SUB_XPATH_LRM_RSC_OP "[@" PCMK_XA_OPERATION "='", op, "'", NULL); /* Need to check against transition_magic too? */ if ((source != NULL) && (strcmp(op, PCMK_ACTION_MIGRATE_TO) == 0)) { pcmk__g_strcat(xpath, - " and @" XML_LRM_ATTR_MIGRATE_TARGET "='", source, "']", + " and @" PCMK__META_MIGRATE_TARGET "='", source, "']", NULL); } else if ((source != NULL) && (strcmp(op, PCMK_ACTION_MIGRATE_FROM) == 0)) { pcmk__g_strcat(xpath, - " and @" XML_LRM_ATTR_MIGRATE_SOURCE "='", source, "']", + " and @" PCMK__META_MIGRATE_SOURCE "='", source, "']", NULL); } else { g_string_append_c(xpath, ']'); @@ -2870,8 +2935,8 @@ find_lrm_op(const char *resource, const char *op, const char *node, const char * int rc = PCMK_OCF_UNKNOWN_ERROR; int status = PCMK_EXEC_ERROR; - crm_element_value_int(xml, XML_LRM_ATTR_RC, &rc); - crm_element_value_int(xml, XML_LRM_ATTR_OPSTATUS, &status); + crm_element_value_int(xml, PCMK__XA_RC_CODE, &rc); + crm_element_value_int(xml, PCMK__XA_OP_STATUS, &status); if ((rc != target_rc) || (status != PCMK_EXEC_DONE)) { return NULL; } @@ -2890,8 +2955,8 @@ find_lrm_resource(const char *rsc_id, const char *node_name, xpath = g_string_sized_new(256); pcmk__g_strcat(xpath, - XPATH_NODE_STATE "[@" XML_ATTR_UNAME "='", node_name, "']" - SUB_XPATH_LRM_RESOURCE "[@" XML_ATTR_ID "='", rsc_id, "']", + XPATH_NODE_STATE "[@" PCMK_XA_UNAME "='", node_name, "']" + SUB_XPATH_LRM_RESOURCE "[@" PCMK_XA_ID "='", rsc_id, "']", NULL); xml = get_xpath_object((const char *) xpath->str, scheduler->input, @@ -2915,17 +2980,18 @@ unknown_on_node(pcmk_resource_t *rsc, const char *node_name) { bool result = false; xmlXPathObjectPtr search; - GString *xpath = g_string_sized_new(256); + char *xpath = NULL; - pcmk__g_strcat(xpath, - XPATH_NODE_STATE "[@" XML_ATTR_UNAME "='", node_name, "']" - SUB_XPATH_LRM_RESOURCE "[@" XML_ATTR_ID "='", rsc->id, "']" - SUB_XPATH_LRM_RSC_OP "[@" XML_LRM_ATTR_RC "!='193']", - NULL); - search = xpath_search(rsc->cluster->input, (const char *) xpath->str); + xpath = crm_strdup_printf(XPATH_NODE_STATE "[@" PCMK_XA_UNAME "='%s']" + SUB_XPATH_LRM_RESOURCE "[@" PCMK_XA_ID "='%s']" + SUB_XPATH_LRM_RSC_OP + "[@" PCMK__XA_RC_CODE "!='%d']", + node_name, rsc->id, PCMK_OCF_UNKNOWN); + + search = xpath_search(rsc->cluster->input, xpath); result = (numXpathResults(search) == 0); freeXpathObject(search); - g_string_free(xpath, TRUE); + free(xpath); return result; } @@ -2979,15 +3045,17 @@ non_monitor_after(const char *rsc_id, const char *node_name, return false; } - for (xmlNode *op = first_named_child(lrm_resource, XML_LRM_TAG_RSC_OP); - op != NULL; op = crm_next_same_xml(op)) { + for (xmlNode *op = pcmk__xe_first_child(lrm_resource, PCMK__XE_LRM_RSC_OP, + NULL, NULL); + op != NULL; op = pcmk__xe_next_same(op)) { + const char * task = NULL; if (op == xml_op) { continue; } - task = crm_element_value(op, XML_LRM_ATTR_TASK); + task = crm_element_value(op, PCMK_XA_OPERATION); if (pcmk__str_any_of(task, PCMK_ACTION_START, PCMK_ACTION_STOP, PCMK_ACTION_MIGRATE_TO, PCMK_ACTION_MIGRATE_FROM, @@ -3027,8 +3095,8 @@ newer_state_after_migrate(const char *rsc_id, const char *node_name, xml_op = migrate_from; } - source = crm_element_value(xml_op, XML_LRM_ATTR_MIGRATE_SOURCE); - target = crm_element_value(xml_op, XML_LRM_ATTR_MIGRATE_TARGET); + source = crm_element_value(xml_op, PCMK__META_MIGRATE_SOURCE); + target = crm_element_value(xml_op, PCMK__META_MIGRATE_TARGET); /* It's preferred to compare to the migrate event on the same node if * existing, since call ids are more reliable. @@ -3078,30 +3146,32 @@ get_migration_node_names(const xmlNode *entry, const pcmk_node_t *source_node, const pcmk_node_t *target_node, const char **source_name, const char **target_name) { - *source_name = crm_element_value(entry, XML_LRM_ATTR_MIGRATE_SOURCE); - *target_name = crm_element_value(entry, XML_LRM_ATTR_MIGRATE_TARGET); + *source_name = crm_element_value(entry, PCMK__META_MIGRATE_SOURCE); + *target_name = crm_element_value(entry, PCMK__META_MIGRATE_TARGET); if ((*source_name == NULL) || (*target_name == NULL)) { - crm_err("Ignoring resource history entry %s without " - XML_LRM_ATTR_MIGRATE_SOURCE " and " XML_LRM_ATTR_MIGRATE_TARGET, - ID(entry)); + pcmk__config_err("Ignoring resource history entry %s without " + PCMK__META_MIGRATE_SOURCE " and " + PCMK__META_MIGRATE_TARGET, pcmk__xe_id(entry)); return pcmk_rc_unpack_error; } if ((source_node != NULL) && !pcmk__str_eq(*source_name, source_node->details->uname, pcmk__str_casei|pcmk__str_null_matches)) { - crm_err("Ignoring resource history entry %s because " - XML_LRM_ATTR_MIGRATE_SOURCE "='%s' does not match %s", - ID(entry), *source_name, pe__node_name(source_node)); + pcmk__config_err("Ignoring resource history entry %s because " + PCMK__META_MIGRATE_SOURCE "='%s' does not match %s", + pcmk__xe_id(entry), *source_name, + pcmk__node_name(source_node)); return pcmk_rc_unpack_error; } if ((target_node != NULL) && !pcmk__str_eq(*target_name, target_node->details->uname, pcmk__str_casei|pcmk__str_null_matches)) { - crm_err("Ignoring resource history entry %s because " - XML_LRM_ATTR_MIGRATE_TARGET "='%s' does not match %s", - ID(entry), *target_name, pe__node_name(target_node)); + pcmk__config_err("Ignoring resource history entry %s because " + PCMK__META_MIGRATE_TARGET "='%s' does not match %s", + pcmk__xe_id(entry), *target_name, + pcmk__node_name(target_node)); return pcmk_rc_unpack_error; } @@ -3123,8 +3193,8 @@ get_migration_node_names(const xmlNode *entry, const pcmk_node_t *source_node, static void add_dangling_migration(pcmk_resource_t *rsc, const pcmk_node_t *node) { - pe_rsc_trace(rsc, "Dangling migration of %s requires stop on %s", - rsc->id, pe__node_name(node)); + pcmk__rsc_trace(rsc, "Dangling migration of %s requires stop on %s", + rsc->id, pcmk__node_name(node)); rsc->role = pcmk_role_stopped; rsc->dangling_migrations = g_list_prepend(rsc->dangling_migrations, (gpointer) node); @@ -3201,9 +3271,8 @@ unpack_migrate_to_success(struct action_history *history) */ return; } - crm_element_value_int(migrate_from, XML_LRM_ATTR_RC, &from_rc); - crm_element_value_int(migrate_from, XML_LRM_ATTR_OPSTATUS, - &from_status); + crm_element_value_int(migrate_from, PCMK__XA_RC_CODE, &from_rc); + crm_element_value_int(migrate_from, PCMK__XA_OP_STATUS, &from_status); } /* If the resource has newer state on both the source and target after the @@ -3230,7 +3299,7 @@ unpack_migrate_to_success(struct action_history *history) */ history->rsc->role = pcmk_role_started; - target_node = pe_find_node(history->rsc->cluster->nodes, target); + target_node = pcmk_find_node(history->rsc->cluster, target); active_on_target = !target_newer_state && (target_node != NULL) && target_node->details->online; @@ -3240,9 +3309,9 @@ unpack_migrate_to_success(struct action_history *history) TRUE); } else { // Mark resource as failed, require recovery, and prevent migration - pe__set_resource_flags(history->rsc, - pcmk_rsc_failed|pcmk_rsc_stop_if_failed); - pe__clear_resource_flags(history->rsc, pcmk_rsc_migratable); + pcmk__set_rsc_flags(history->rsc, + pcmk_rsc_failed|pcmk_rsc_stop_if_failed); + pcmk__clear_rsc_flags(history->rsc, pcmk_rsc_migratable); } return; } @@ -3259,8 +3328,8 @@ unpack_migrate_to_success(struct action_history *history) } if (active_on_target) { - pcmk_node_t *source_node = pe_find_node(history->rsc->cluster->nodes, - source); + pcmk_node_t *source_node = pcmk_find_node(history->rsc->cluster, + source); native_add_running(history->rsc, target_node, history->rsc->cluster, FALSE); @@ -3277,9 +3346,9 @@ unpack_migrate_to_success(struct action_history *history) } else if (!source_newer_op) { // Mark resource as failed, require recovery, and prevent migration - pe__set_resource_flags(history->rsc, - pcmk_rsc_failed|pcmk_rsc_stop_if_failed); - pe__clear_resource_flags(history->rsc, pcmk_rsc_migratable); + pcmk__set_rsc_flags(history->rsc, + pcmk_rsc_failed|pcmk_rsc_stop_if_failed); + pcmk__clear_rsc_flags(history->rsc, pcmk_rsc_migratable); } } @@ -3328,8 +3397,8 @@ unpack_migrate_to_failure(struct action_history *history) * active there. * (if it is up). */ - pcmk_node_t *target_node = pe_find_node(history->rsc->cluster->nodes, - target); + pcmk_node_t *target_node = pcmk_find_node(history->rsc->cluster, + target); if (target_node && target_node->details->online) { native_add_running(history->rsc, target_node, history->rsc->cluster, @@ -3394,8 +3463,8 @@ unpack_migrate_from_failure(struct action_history *history) /* The resource has no newer state on the source, so assume it's still * active there (if it is up). */ - pcmk_node_t *source_node = pe_find_node(history->rsc->cluster->nodes, - source); + pcmk_node_t *source_node = pcmk_find_node(history->rsc->cluster, + source); if (source_node && source_node->details->online) { native_add_running(history->rsc, source_node, history->rsc->cluster, @@ -3420,23 +3489,23 @@ record_failed_op(struct action_history *history) for (const xmlNode *xIter = history->rsc->cluster->failed->children; xIter != NULL; xIter = xIter->next) { - const char *key = pe__xe_history_key(xIter); - const char *uname = crm_element_value(xIter, XML_ATTR_UNAME); + const char *key = pcmk__xe_history_key(xIter); + const char *uname = crm_element_value(xIter, PCMK_XA_UNAME); if (pcmk__str_eq(history->key, key, pcmk__str_none) && pcmk__str_eq(uname, history->node->details->uname, pcmk__str_casei)) { crm_trace("Skipping duplicate entry %s on %s", - history->key, pe__node_name(history->node)); + history->key, pcmk__node_name(history->node)); return; } } crm_trace("Adding entry for %s on %s to failed action list", - history->key, pe__node_name(history->node)); - crm_xml_add(history->xml, XML_ATTR_UNAME, history->node->details->uname); - crm_xml_add(history->xml, XML_LRM_ATTR_RSCID, history->rsc->id); - add_node_copy(history->rsc->cluster->failed, history->xml); + history->key, pcmk__node_name(history->node)); + crm_xml_add(history->xml, PCMK_XA_UNAME, history->node->details->uname); + crm_xml_add(history->xml, PCMK__XA_RSC_ID, history->rsc->id); + pcmk__xml_copy(history->rsc->cluster->failed, history->xml); } static char * @@ -3445,22 +3514,20 @@ last_change_str(const xmlNode *xml_op) time_t when; char *result = NULL; - if (crm_element_value_epoch(xml_op, XML_RSC_OP_LAST_CHANGE, + if (crm_element_value_epoch(xml_op, PCMK_XA_LAST_RC_CHANGE, &when) == pcmk_ok) { char *when_s = pcmk__epoch2str(&when, 0); const char *p = strchr(when_s, ' '); // Skip day of week to make message shorter if ((p != NULL) && (*(++p) != '\0')) { - result = strdup(p); - CRM_ASSERT(result != NULL); + result = pcmk__str_copy(p); } free(when_s); } if (result == NULL) { - result = strdup("unknown time"); - CRM_ASSERT(result != NULL); + result = pcmk__str_copy("unknown_time"); } return result; @@ -3565,15 +3632,16 @@ cmp_on_fail(enum action_fail_response first, enum action_fail_response second) static void ban_from_all_nodes(pcmk_resource_t *rsc) { - int score = -INFINITY; + int score = -PCMK_SCORE_INFINITY; pcmk_resource_t *fail_rsc = rsc; if (fail_rsc->parent != NULL) { pcmk_resource_t *parent = uber_parent(fail_rsc); - if (pe_rsc_is_anon_clone(parent)) { - /* For anonymous clones, if an operation with on-fail=stop fails for - * any instance, the entire clone must stop. + if (pcmk__is_anonymous_clone(parent)) { + /* For anonymous clones, if an operation with + * PCMK_META_ON_FAIL=PCMK_VALUE_STOP fails for any instance, the + * entire clone must stop. */ fail_rsc = parent; } @@ -3608,7 +3676,7 @@ unpack_failure_handling(struct action_history *history, history->task, history->interval_ms, config); - const char *on_fail_str = g_hash_table_lookup(meta, XML_OP_ATTR_ON_FAIL); + const char *on_fail_str = g_hash_table_lookup(meta, PCMK_META_ON_FAIL); *on_fail = pcmk__parse_on_fail(history->rsc, history->task, history->interval_ms, on_fail_str); @@ -3649,17 +3717,17 @@ unpack_rsc_op_failure(struct action_history *history, (pcmk__str_empty(history->exit_reason)? "" : ": "), pcmk__s(history->exit_reason, ""), (is_probe? "probe" : history->task), history->rsc->id, - pe__node_name(history->node), last_change_s, + pcmk__node_name(history->node), last_change_s, history->exit_status, history->id); } else { - crm_warn("Unexpected result (%s%s%s) was recorded for " - "%s of %s on %s at %s " CRM_XS " exit-status=%d id=%s", - services_ocf_exitcode_str(history->exit_status), - (pcmk__str_empty(history->exit_reason)? "" : ": "), - pcmk__s(history->exit_reason, ""), - (is_probe? "probe" : history->task), history->rsc->id, - pe__node_name(history->node), last_change_s, - history->exit_status, history->id); + pcmk__sched_warn("Unexpected result (%s%s%s) was recorded for %s of " + "%s on %s at %s " CRM_XS " exit-status=%d id=%s", + services_ocf_exitcode_str(history->exit_status), + (pcmk__str_empty(history->exit_reason)? "" : ": "), + pcmk__s(history->exit_reason, ""), + (is_probe? "probe" : history->task), history->rsc->id, + pcmk__node_name(history->node), last_change_s, + history->exit_status, history->id); if (is_probe && (history->exit_status != PCMK_OCF_OK) && (history->exit_status != PCMK_OCF_NOT_RUNNING) @@ -3669,8 +3737,9 @@ unpack_rsc_op_failure(struct action_history *history, * didn't know resources will be probed even where they can't run. */ crm_notice("If it is not possible for %s to run on %s, see " - "the resource-discovery option for location constraints", - history->rsc->id, pe__node_name(history->node)); + "the " PCMK_XA_RESOURCE_DISCOVERY " option for location " + "constraints", + history->rsc->id, pcmk__node_name(history->node)); } record_failed_op(history); @@ -3679,14 +3748,14 @@ unpack_rsc_op_failure(struct action_history *history, free(last_change_s); if (cmp_on_fail(*on_fail, config_on_fail) < 0) { - pe_rsc_trace(history->rsc, "on-fail %s -> %s for %s", - fail2text(*on_fail), fail2text(config_on_fail), - history->key); + pcmk__rsc_trace(history->rsc, "on-fail %s -> %s for %s", + pcmk_on_fail_text(*on_fail), + pcmk_on_fail_text(config_on_fail), history->key); *on_fail = config_on_fail; } if (strcmp(history->task, PCMK_ACTION_STOP) == 0) { - resource_location(history->rsc, history->node, -INFINITY, + resource_location(history->rsc, history->node, -PCMK_SCORE_INFINITY, "__stop_fail__", history->rsc->cluster); } else if (strcmp(history->task, PCMK_ACTION_MIGRATE_TO) == 0) { @@ -3702,7 +3771,7 @@ unpack_rsc_op_failure(struct action_history *history, if (config_on_fail == pcmk_on_fail_block) { history->rsc->role = pcmk_role_promoted; pe__set_next_role(history->rsc, pcmk_role_stopped, - "demote with on-fail=block"); + "demote with " PCMK_META_ON_FAIL "=block"); } else if (history->exit_status == PCMK_OCF_NOT_RUNNING) { history->rsc->role = pcmk_role_stopped; @@ -3719,19 +3788,20 @@ unpack_rsc_op_failure(struct action_history *history, if (is_probe && (history->exit_status == PCMK_OCF_NOT_INSTALLED)) { /* leave stopped */ - pe_rsc_trace(history->rsc, "Leaving %s stopped", history->rsc->id); + pcmk__rsc_trace(history->rsc, "Leaving %s stopped", history->rsc->id); history->rsc->role = pcmk_role_stopped; } else if (history->rsc->role < pcmk_role_started) { - pe_rsc_trace(history->rsc, "Setting %s active", history->rsc->id); + pcmk__rsc_trace(history->rsc, "Setting %s active", history->rsc->id); set_active(history->rsc); } - pe_rsc_trace(history->rsc, - "Resource %s: role=%s, unclean=%s, on_fail=%s, fail_role=%s", - history->rsc->id, role2text(history->rsc->role), - pcmk__btoa(history->node->details->unclean), - fail2text(config_on_fail), role2text(fail_role)); + pcmk__rsc_trace(history->rsc, + "Resource %s: role=%s unclean=%s on_fail=%s fail_role=%s", + history->rsc->id, pcmk_role_text(history->rsc->role), + pcmk__btoa(history->node->details->unclean), + pcmk_on_fail_text(config_on_fail), + pcmk_role_text(fail_role)); if ((fail_role != pcmk_role_started) && (history->rsc->next_role < fail_role)) { @@ -3765,19 +3835,20 @@ block_if_unrecoverable(struct action_history *history) } last_change_s = last_change_str(history->xml); - pe_proc_err("No further recovery can be attempted for %s " - "because %s on %s failed (%s%s%s) at %s " - CRM_XS " rc=%d id=%s", - history->rsc->id, history->task, pe__node_name(history->node), - services_ocf_exitcode_str(history->exit_status), - (pcmk__str_empty(history->exit_reason)? "" : ": "), - pcmk__s(history->exit_reason, ""), - last_change_s, history->exit_status, history->id); + pcmk__sched_err("No further recovery can be attempted for %s " + "because %s on %s failed (%s%s%s) at %s " + CRM_XS " rc=%d id=%s", + history->rsc->id, history->task, + pcmk__node_name(history->node), + services_ocf_exitcode_str(history->exit_status), + (pcmk__str_empty(history->exit_reason)? "" : ": "), + pcmk__s(history->exit_reason, ""), + last_change_s, history->exit_status, history->id); free(last_change_s); - pe__clear_resource_flags(history->rsc, pcmk_rsc_managed); - pe__set_resource_flags(history->rsc, pcmk_rsc_blocked); + pcmk__clear_rsc_flags(history->rsc, pcmk_rsc_managed); + pcmk__set_rsc_flags(history->rsc, pcmk_rsc_blocked); } /*! @@ -3841,7 +3912,7 @@ remap_operation(struct action_history *history, } } - if (!pe_rsc_is_bundled(history->rsc) + if (!pcmk__is_bundled(history->rsc) && pcmk_xe_mask_probe_failure(history->xml) && ((history->execution_status != PCMK_EXEC_DONE) || (history->exit_status != PCMK_OCF_NOT_RUNNING))) { @@ -3887,24 +3958,24 @@ remap_operation(struct action_history *history, */ remap_because(history, &why, PCMK_EXEC_ERROR, "obsolete history format"); - crm_warn("Expected result not found for %s on %s " - "(corrupt or obsolete CIB?)", - history->key, pe__node_name(history->node)); + pcmk__config_warn("Expected result not found for %s on %s " + "(corrupt or obsolete CIB?)", + history->key, pcmk__node_name(history->node)); } else if (history->exit_status == history->expected_exit_status) { remap_because(history, &why, PCMK_EXEC_DONE, "expected result"); } else { remap_because(history, &why, PCMK_EXEC_ERROR, "unexpected result"); - pe_rsc_debug(history->rsc, - "%s on %s: expected %d (%s), got %d (%s%s%s)", - history->key, pe__node_name(history->node), - history->expected_exit_status, - services_ocf_exitcode_str(history->expected_exit_status), - history->exit_status, - services_ocf_exitcode_str(history->exit_status), - (pcmk__str_empty(history->exit_reason)? "" : ": "), - pcmk__s(history->exit_reason, "")); + pcmk__rsc_debug(history->rsc, + "%s on %s: expected %d (%s), got %d (%s%s%s)", + history->key, pcmk__node_name(history->node), + history->expected_exit_status, + services_ocf_exitcode_str(history->expected_exit_status), + history->exit_status, + services_ocf_exitcode_str(history->exit_status), + (pcmk__str_empty(history->exit_reason)? "" : ": "), + pcmk__s(history->exit_reason, "")); } switch (history->exit_status) { @@ -3914,9 +3985,10 @@ remap_operation(struct action_history *history, char *last_change_s = last_change_str(history->xml); remap_because(history, &why, PCMK_EXEC_DONE, "probe"); - pe_rsc_info(history->rsc, "Probe found %s active on %s at %s", - history->rsc->id, pe__node_name(history->node), - last_change_s); + pcmk__rsc_info(history->rsc, + "Probe found %s active on %s at %s", + history->rsc->id, pcmk__node_name(history->node), + last_change_s); free(last_change_s); } break; @@ -3944,10 +4016,10 @@ remap_operation(struct action_history *history, char *last_change_s = last_change_str(history->xml); remap_because(history, &why, PCMK_EXEC_DONE, "probe"); - pe_rsc_info(history->rsc, - "Probe found %s active and promoted on %s at %s", - history->rsc->id, pe__node_name(history->node), - last_change_s); + pcmk__rsc_info(history->rsc, + "Probe found %s active and promoted on %s at %s", + history->rsc->id, + pcmk__node_name(history->node), last_change_s); free(last_change_s); } if (!expired @@ -3970,7 +4042,7 @@ remap_operation(struct action_history *history, case PCMK_OCF_UNIMPLEMENT_FEATURE: { guint interval_ms = 0; - crm_element_value_ms(history->xml, XML_LRM_ATTR_INTERVAL_MS, + crm_element_value_ms(history->xml, PCMK_META_INTERVAL, &interval_ms); if (interval_ms == 0) { @@ -4002,7 +4074,7 @@ remap_operation(struct action_history *history, crm_info("Treating unknown exit status %d from %s of %s " "on %s at %s as failure", history->exit_status, task, history->rsc->id, - pe__node_name(history->node), last_change_s); + pcmk__node_name(history->node), last_change_s); remap_because(history, &why, PCMK_EXEC_ERROR, "unknown exit status"); free(last_change_s); @@ -4012,13 +4084,13 @@ remap_operation(struct action_history *history, remap_done: if (why != NULL) { - pe_rsc_trace(history->rsc, - "Remapped %s result from [%s: %s] to [%s: %s] " - "because of %s", - history->key, pcmk_exec_status_str(orig_exec_status), - crm_exit_str(orig_exit_status), - pcmk_exec_status_str(history->execution_status), - crm_exit_str(history->exit_status), why); + pcmk__rsc_trace(history->rsc, + "Remapped %s result from [%s: %s] to [%s: %s] " + "because of %s", + history->key, pcmk_exec_status_str(orig_exec_status), + crm_exit_str(orig_exit_status), + pcmk_exec_status_str(history->execution_status), + crm_exit_str(history->exit_status), why); } } @@ -4037,7 +4109,7 @@ should_clear_for_param_change(const xmlNode *xml_op, const char *task, rsc->cluster); } else { - op_digest_cache_t *digest_data = NULL; + pcmk__op_digest_t *digest_data = NULL; digest_data = rsc_action_digest_cmp(rsc, xml_op, node, rsc->cluster); @@ -4045,7 +4117,7 @@ should_clear_for_param_change(const xmlNode *xml_op, const char *task, case pcmk__digest_unknown: crm_trace("Resource %s history entry %s on %s" " has no digest to compare", - rsc->id, pe__xe_history_key(xml_op), + rsc->id, pcmk__xe_history_key(xml_op), node->details->id); break; case pcmk__digest_match: @@ -4063,7 +4135,7 @@ static void order_after_remote_fencing(pcmk_action_t *action, pcmk_resource_t *remote_conn, pcmk_scheduler_t *scheduler) { - pcmk_node_t *remote_node = pe_find_node(scheduler->nodes, remote_conn->id); + pcmk_node_t *remote_node = pcmk_find_node(scheduler, remote_conn->id); if (remote_node) { pcmk_action_t *fence = pe_fence_op(remote_node, NULL, TRUE, NULL, @@ -4102,7 +4174,7 @@ should_ignore_failure_timeout(const pcmk_resource_t *rsc, const char *task, && (interval_ms != 0) && pcmk__str_eq(task, PCMK_ACTION_MONITOR, pcmk__str_casei)) { - pcmk_node_t *remote_node = pe_find_node(rsc->cluster->nodes, rsc->id); + pcmk_node_t *remote_node = pcmk_find_node(rsc->cluster, rsc->id); if (remote_node && !remote_node->details->remote_was_fenced) { if (is_last_failure) { @@ -4143,18 +4215,20 @@ check_operation_expiry(struct action_history *history) const char *clear_reason = NULL; if (history->execution_status == PCMK_EXEC_NOT_INSTALLED) { - pe_rsc_trace(history->rsc, - "Resource history entry %s on %s is not expired: " - "Not Installed does not expire", - history->id, pe__node_name(history->node)); + pcmk__rsc_trace(history->rsc, + "Resource history entry %s on %s is not expired: " + "Not Installed does not expire", + history->id, pcmk__node_name(history->node)); return false; // "Not installed" must always be cleared manually } if ((history->rsc->failure_timeout > 0) - && (crm_element_value_epoch(history->xml, XML_RSC_OP_LAST_CHANGE, + && (crm_element_value_epoch(history->xml, PCMK_XA_LAST_RC_CHANGE, &last_run) == 0)) { - // Resource has a failure-timeout, and history entry has a timestamp + /* Resource has a PCMK_META_FAILURE_TIMEOUT and history entry has a + * timestamp + */ time_t now = get_effective_time(history->rsc->cluster); time_t last_failure = 0; @@ -4202,10 +4276,10 @@ check_operation_expiry(struct action_history *history) * fail count should be expired too), so this is really just a * failsafe. */ - pe_rsc_trace(history->rsc, - "Resource history entry %s on %s is not expired: " - "Unexpired fail count", - history->id, pe__node_name(history->node)); + pcmk__rsc_trace(history->rsc, + "Resource history entry %s on %s is not " + "expired: Unexpired fail count", + history->id, pcmk__node_name(history->node)); expired = false; } @@ -4259,10 +4333,10 @@ check_operation_expiry(struct action_history *history) case PCMK_OCF_DEGRADED: case PCMK_OCF_DEGRADED_PROMOTED: // Don't expire probes that return these values - pe_rsc_trace(history->rsc, - "Resource history entry %s on %s is not expired: " - "Probe result", - history->id, pe__node_name(history->node)); + pcmk__rsc_trace(history->rsc, + "Resource history entry %s on %s is not " + "expired: Probe result", + history->id, pcmk__node_name(history->node)); expired = false; break; } @@ -4275,7 +4349,7 @@ int pe__target_rc_from_xml(const xmlNode *xml_op) { int target_rc = 0; - const char *key = crm_element_value(xml_op, XML_ATTR_TRANSITION_KEY); + const char *key = crm_element_value(xml_op, PCMK__XA_TRANSITION_KEY); if (key == NULL) { return -1; @@ -4301,7 +4375,7 @@ update_resource_state(struct action_history *history, int exit_status, bool clear_past_failure = false; if ((exit_status == PCMK_OCF_NOT_INSTALLED) - || (!pe_rsc_is_bundled(history->rsc) + || (!pcmk__is_bundled(history->rsc) && pcmk_xe_mask_probe_failure(history->xml))) { history->rsc->role = pcmk_role_stopped; @@ -4311,7 +4385,7 @@ update_resource_state(struct action_history *history, int exit_status, } else if (pcmk__str_eq(history->task, PCMK_ACTION_MONITOR, pcmk__str_none)) { if ((last_failure != NULL) - && pcmk__str_eq(history->key, pe__xe_history_key(last_failure), + && pcmk__str_eq(history->key, pcmk__xe_history_key(last_failure), pcmk__str_none)) { clear_past_failure = true; } @@ -4335,7 +4409,9 @@ update_resource_state(struct action_history *history, int exit_status, } else if (pcmk__str_eq(history->task, PCMK_ACTION_DEMOTE, pcmk__str_none)) { if (*on_fail == pcmk_on_fail_demote) { - // Demote clears an error only if on-fail=demote + /* Demote clears an error only if + * PCMK_META_ON_FAIL=PCMK_VALUE_DEMOTE + */ clear_past_failure = true; } history->rsc->role = pcmk_role_unpromoted; @@ -4350,8 +4426,8 @@ update_resource_state(struct action_history *history, int exit_status, unpack_migrate_to_success(history); } else if (history->rsc->role < pcmk_role_started) { - pe_rsc_trace(history->rsc, "%s active on %s", - history->rsc->id, pe__node_name(history->node)); + pcmk__rsc_trace(history->rsc, "%s active on %s", + history->rsc->id, pcmk__node_name(history->node)); set_active(history->rsc); } @@ -4364,9 +4440,10 @@ update_resource_state(struct action_history *history, int exit_status, case pcmk_on_fail_ban: case pcmk_on_fail_standby_node: case pcmk_on_fail_fence_node: - pe_rsc_trace(history->rsc, - "%s (%s) is not cleared by a completed %s", - history->rsc->id, fail2text(*on_fail), history->task); + pcmk__rsc_trace(history->rsc, + "%s (%s) is not cleared by a completed %s", + history->rsc->id, pcmk_on_fail_text(*on_fail), + history->task); break; case pcmk_on_fail_block: @@ -4435,19 +4512,21 @@ can_affect_state(struct action_history *history) static int unpack_action_result(struct action_history *history) { - if ((crm_element_value_int(history->xml, XML_LRM_ATTR_OPSTATUS, + if ((crm_element_value_int(history->xml, PCMK__XA_OP_STATUS, &(history->execution_status)) < 0) || (history->execution_status < PCMK_EXEC_PENDING) || (history->execution_status > PCMK_EXEC_MAX) || (history->execution_status == PCMK_EXEC_CANCELLED)) { - crm_err("Ignoring resource history entry %s for %s on %s " - "with invalid " XML_LRM_ATTR_OPSTATUS " '%s'", - history->id, history->rsc->id, pe__node_name(history->node), - pcmk__s(crm_element_value(history->xml, XML_LRM_ATTR_OPSTATUS), - "")); + pcmk__config_err("Ignoring resource history entry %s for %s on %s " + "with invalid " PCMK__XA_OP_STATUS " '%s'", + history->id, history->rsc->id, + pcmk__node_name(history->node), + pcmk__s(crm_element_value(history->xml, + PCMK__XA_OP_STATUS), + "")); return pcmk_rc_unpack_error; } - if ((crm_element_value_int(history->xml, XML_LRM_ATTR_RC, + if ((crm_element_value_int(history->xml, PCMK__XA_RC_CODE, &(history->exit_status)) < 0) || (history->exit_status < 0) || (history->exit_status > CRM_EX_MAX)) { #if 0 @@ -4455,18 +4534,19 @@ unpack_action_result(struct action_history *history) * change behavior, it should be done at a major or minor series * release. */ - crm_err("Ignoring resource history entry %s for %s on %s " - "with invalid " XML_LRM_ATTR_RC " '%s'", - history->id, history->rsc->id, pe__node_name(history->node), - pcmk__s(crm_element_value(history->xml, XML_LRM_ATTR_RC), - "")); + pcmk__config_err("Ignoring resource history entry %s for %s on %s " + "with invalid " PCMK__XA_RC_CODE " '%s'", + history->id, history->rsc->id, + pcmk__node_name(history->node), + pcmk__s(crm_element_value(history->xml, + PCMK__XA_RC_CODE), + "")); return pcmk_rc_unpack_error; #else history->exit_status = CRM_EX_ERROR; #endif } - history->exit_reason = crm_element_value(history->xml, - XML_LRM_ATTR_EXIT_REASON); + history->exit_reason = crm_element_value(history->xml, PCMK_XA_EXIT_REASON); return pcmk_rc_ok; } @@ -4483,7 +4563,7 @@ unpack_action_result(struct action_history *history) static int process_expired_result(struct action_history *history, int orig_exit_status) { - if (!pe_rsc_is_bundled(history->rsc) + if (!pcmk__is_bundled(history->rsc) && pcmk_xe_mask_probe_failure(history->xml) && (orig_exit_status != history->expected_exit_status)) { @@ -4493,7 +4573,7 @@ process_expired_result(struct action_history *history, int orig_exit_status) crm_trace("Ignoring resource history entry %s for probe of %s on %s: " "Masked failure expired", history->id, history->rsc->id, - pe__node_name(history->node)); + pcmk__node_name(history->node)); return pcmk_rc_ok; } @@ -4505,7 +4585,7 @@ process_expired_result(struct action_history *history, int orig_exit_status) crm_notice("Ignoring resource history entry %s for %s of %s on %s: " "Expired failure", history->id, history->task, history->rsc->id, - pe__node_name(history->node)); + pcmk__node_name(history->node)); return pcmk_rc_ok; } @@ -4516,15 +4596,15 @@ process_expired_result(struct action_history *history, int orig_exit_status) * * @TODO We should skip this if there is a newer successful monitor. * Also, this causes rescheduling only if the history entry - * has an op-digest (which the expire-non-blocked-failure + * has a PCMK__XA_OP_DIGEST (which the expire-non-blocked-failure * scheduler regression test doesn't, but that may not be a * realistic scenario in production). */ crm_notice("Rescheduling %s-interval %s of %s on %s " "after failure expired", pcmk__readable_interval(history->interval_ms), history->task, - history->rsc->id, pe__node_name(history->node)); - crm_xml_add(history->xml, XML_LRM_ATTR_RESTART_DIGEST, + history->rsc->id, pcmk__node_name(history->node)); + crm_xml_add(history->xml, PCMK__XA_OP_RESTART_DIGEST, "calculated-failure-timeout"); return pcmk_rc_ok; } @@ -4554,14 +4634,14 @@ mask_probe_failure(struct action_history *history, int orig_exit_status, crm_notice("Treating probe result '%s' for %s on %s as 'not running'", services_ocf_exitcode_str(orig_exit_status), history->rsc->id, - pe__node_name(history->node)); + pcmk__node_name(history->node)); update_resource_state(history, history->expected_exit_status, last_failure, on_fail); - crm_xml_add(history->xml, XML_ATTR_UNAME, history->node->details->uname); + crm_xml_add(history->xml, PCMK_XA_UNAME, history->node->details->uname); record_failed_op(history); - resource_location(ban_rsc, history->node, -INFINITY, "masked-probe-failure", - history->rsc->cluster); + resource_location(ban_rsc, history->node, -PCMK_SCORE_INFINITY, + "masked-probe-failure", history->rsc->cluster); } /*! @@ -4573,7 +4653,8 @@ mask_probe_failure(struct action_history *history, int orig_exit_status, * \return true if \p last_failure is failure of pending action in \p history, * otherwise false * \note Both \p history and \p last_failure must come from the same - * lrm_resource block, as node and resource are assumed to be the same. + * \c PCMK__XE_LRM_RESOURCE block, as node and resource are assumed to be + * the same. */ static bool failure_is_newer(const struct action_history *history, @@ -4588,21 +4669,21 @@ failure_is_newer(const struct action_history *history, } if (!pcmk__str_eq(history->task, - crm_element_value(last_failure, XML_LRM_ATTR_TASK), + crm_element_value(last_failure, PCMK_XA_OPERATION), pcmk__str_none)) { return false; // last_failure is for different action } - if ((crm_element_value_ms(last_failure, XML_LRM_ATTR_INTERVAL_MS, + if ((crm_element_value_ms(last_failure, PCMK_META_INTERVAL, &failure_interval_ms) != pcmk_ok) || (history->interval_ms != failure_interval_ms)) { return false; // last_failure is for action with different interval } - if ((pcmk__scan_ll(crm_element_value(history->xml, XML_RSC_OP_LAST_CHANGE), + if ((pcmk__scan_ll(crm_element_value(history->xml, PCMK_XA_LAST_RC_CHANGE), &this_change, 0LL) != pcmk_rc_ok) || (pcmk__scan_ll(crm_element_value(last_failure, - XML_RSC_OP_LAST_CHANGE), + PCMK_XA_LAST_RC_CHANGE), &failure_change, 0LL) != pcmk_rc_ok) || (failure_change < this_change)) { return false; // Failure is not known to be newer @@ -4636,7 +4717,7 @@ process_pending_action(struct action_history *history, } if (strcmp(history->task, PCMK_ACTION_START) == 0) { - pe__set_resource_flags(history->rsc, pcmk_rsc_start_pending); + pcmk__set_rsc_flags(history->rsc, pcmk_rsc_start_pending); set_active(history->rsc); } else if (strcmp(history->task, PCMK_ACTION_PROMOTE) == 0) { @@ -4651,8 +4732,8 @@ process_pending_action(struct action_history *history, pcmk_node_t *target = NULL; migrate_target = crm_element_value(history->xml, - XML_LRM_ATTR_MIGRATE_TARGET); - target = pe_find_node(history->rsc->cluster->nodes, migrate_target); + PCMK__META_MIGRATE_TARGET); + target = pcmk_find_node(history->rsc->cluster, migrate_target); if (target != NULL) { stop_action(history->rsc, target, FALSE); } @@ -4700,27 +4781,28 @@ unpack_rsc_op(pcmk_resource_t *rsc, pcmk_node_t *node, xmlNode *xml_op, CRM_CHECK(rsc && node && xml_op, return); - history.id = ID(xml_op); + history.id = pcmk__xe_id(xml_op); if (history.id == NULL) { - crm_err("Ignoring resource history entry for %s on %s without ID", - rsc->id, pe__node_name(node)); + pcmk__config_err("Ignoring resource history entry for %s on %s " + "without ID", rsc->id, pcmk__node_name(node)); return; } // Task and interval - history.task = crm_element_value(xml_op, XML_LRM_ATTR_TASK); + history.task = crm_element_value(xml_op, PCMK_XA_OPERATION); if (history.task == NULL) { - crm_err("Ignoring resource history entry %s for %s on %s without " - XML_LRM_ATTR_TASK, history.id, rsc->id, pe__node_name(node)); + pcmk__config_err("Ignoring resource history entry %s for %s on %s " + "without " PCMK_XA_OPERATION, + history.id, rsc->id, pcmk__node_name(node)); return; } - crm_element_value_ms(xml_op, XML_LRM_ATTR_INTERVAL_MS, - &(history.interval_ms)); + crm_element_value_ms(xml_op, PCMK_META_INTERVAL, &(history.interval_ms)); if (!can_affect_state(&history)) { - pe_rsc_trace(rsc, - "Ignoring resource history entry %s for %s on %s " - "with irrelevant action '%s'", - history.id, rsc->id, pe__node_name(node), history.task); + pcmk__rsc_trace(rsc, + "Ignoring resource history entry %s for %s on %s " + "with irrelevant action '%s'", + history.id, rsc->id, pcmk__node_name(node), + history.task); return; } @@ -4729,19 +4811,20 @@ unpack_rsc_op(pcmk_resource_t *rsc, pcmk_node_t *node, xmlNode *xml_op, } history.expected_exit_status = pe__target_rc_from_xml(xml_op); - history.key = pe__xe_history_key(xml_op); - crm_element_value_int(xml_op, XML_LRM_ATTR_CALLID, &(history.call_id)); + history.key = pcmk__xe_history_key(xml_op); + crm_element_value_int(xml_op, PCMK__XA_CALL_ID, &(history.call_id)); - pe_rsc_trace(rsc, "Unpacking %s (%s call %d on %s): %s (%s)", - history.id, history.task, history.call_id, pe__node_name(node), - pcmk_exec_status_str(history.execution_status), - crm_exit_str(history.exit_status)); + pcmk__rsc_trace(rsc, "Unpacking %s (%s call %d on %s): %s (%s)", + history.id, history.task, history.call_id, + pcmk__node_name(node), + pcmk_exec_status_str(history.execution_status), + crm_exit_str(history.exit_status)); if (node->details->unclean) { - pe_rsc_trace(rsc, - "%s is running on %s, which is unclean (further action " - "depends on value of stop's on-fail attribute)", - rsc->id, pe__node_name(node)); + pcmk__rsc_trace(rsc, + "%s is running on %s, which is unclean (further action " + "depends on value of stop's on-fail attribute)", + rsc->id, pcmk__node_name(node)); } expired = check_operation_expiry(&history); @@ -4753,7 +4836,7 @@ unpack_rsc_op(pcmk_resource_t *rsc, pcmk_node_t *node, xmlNode *xml_op, goto done; } - if (!pe_rsc_is_bundled(rsc) && pcmk_xe_mask_probe_failure(xml_op)) { + if (!pcmk__is_bundled(rsc) && pcmk_xe_mask_probe_failure(xml_op)) { mask_probe_failure(&history, old_rc, *last_failure, on_fail); goto done; } @@ -4778,7 +4861,7 @@ unpack_rsc_op(pcmk_resource_t *rsc, pcmk_node_t *node, xmlNode *xml_op, crm_warn("Cannot ignore failed %s of %s on %s: " "Resource agent doesn't exist " CRM_XS " status=%d rc=%d id=%s", - history.task, rsc->id, pe__node_name(node), + history.task, rsc->id, pcmk__node_name(node), history.execution_status, history.exit_status, history.id); /* Also for printing it as "FAILED" by marking it as @@ -4786,14 +4869,14 @@ unpack_rsc_op(pcmk_resource_t *rsc, pcmk_node_t *node, xmlNode *xml_op, */ *on_fail = pcmk_on_fail_ban; } - resource_location(parent, node, -INFINITY, "hard-error", - rsc->cluster); + resource_location(parent, node, -PCMK_SCORE_INFINITY, + "hard-error", rsc->cluster); unpack_rsc_op_failure(&history, failure_strategy, fail_role, last_failure, on_fail); goto done; case PCMK_EXEC_NOT_CONNECTED: - if (pe__is_guest_or_remote_node(node) + if (pcmk__is_pacemaker_remote_node(node) && pcmk_is_set(node->details->remote_rsc->flags, pcmk_rsc_managed)) { /* We should never get into a situation where a managed remote @@ -4802,8 +4885,8 @@ unpack_rsc_op(pcmk_resource_t *rsc, pcmk_node_t *node, xmlNode *xml_op, * fail-safe in case a bug or unusual circumstances do lead to * that, ensure the remote connection is considered failed. */ - pe__set_resource_flags(node->details->remote_rsc, - pcmk_rsc_failed|pcmk_rsc_stop_if_failed); + pcmk__set_rsc_flags(node->details->remote_rsc, + pcmk_rsc_failed|pcmk_rsc_stop_if_failed); } break; // Not done, do error handling @@ -4830,14 +4913,14 @@ unpack_rsc_op(pcmk_resource_t *rsc, pcmk_node_t *node, xmlNode *xml_op, CRM_XS " %s", history.task, services_ocf_exitcode_str(history.exit_status), (pcmk__str_empty(history.exit_reason)? "" : ": "), - pcmk__s(history.exit_reason, ""), rsc->id, pe__node_name(node), - last_change_s, history.id); + pcmk__s(history.exit_reason, ""), rsc->id, + pcmk__node_name(node), last_change_s, history.id); free(last_change_s); update_resource_state(&history, history.expected_exit_status, *last_failure, on_fail); - crm_xml_add(xml_op, XML_ATTR_UNAME, node->details->uname); - pe__set_resource_flags(rsc, pcmk_rsc_ignore_failure); + crm_xml_add(xml_op, PCMK_XA_UNAME, node->details->uname); + pcmk__set_rsc_flags(rsc, pcmk_rsc_ignore_failure); record_failed_op(&history); @@ -4859,28 +4942,30 @@ unpack_rsc_op(pcmk_resource_t *rsc, pcmk_node_t *node, xmlNode *xml_op, do_crm_log(log_level, "Preventing %s from restarting on %s because " "of hard failure (%s%s%s) " CRM_XS " %s", - parent->id, pe__node_name(node), + parent->id, pcmk__node_name(node), services_ocf_exitcode_str(history.exit_status), (pcmk__str_empty(history.exit_reason)? "" : ": "), pcmk__s(history.exit_reason, ""), history.id); - resource_location(parent, node, -INFINITY, "hard-error", - rsc->cluster); + resource_location(parent, node, -PCMK_SCORE_INFINITY, + "hard-error", rsc->cluster); } else if (history.execution_status == PCMK_EXEC_ERROR_FATAL) { - crm_err("Preventing %s from restarting anywhere because " - "of fatal failure (%s%s%s) " CRM_XS " %s", - parent->id, services_ocf_exitcode_str(history.exit_status), - (pcmk__str_empty(history.exit_reason)? "" : ": "), - pcmk__s(history.exit_reason, ""), history.id); - resource_location(parent, NULL, -INFINITY, "fatal-error", - rsc->cluster); + pcmk__sched_err("Preventing %s from restarting anywhere because " + "of fatal failure (%s%s%s) " CRM_XS " %s", + parent->id, + services_ocf_exitcode_str(history.exit_status), + (pcmk__str_empty(history.exit_reason)? "" : ": "), + pcmk__s(history.exit_reason, ""), history.id); + resource_location(parent, NULL, -PCMK_SCORE_INFINITY, + "fatal-error", rsc->cluster); } } done: - pe_rsc_trace(rsc, "%s role on %s after %s is %s (next %s)", - rsc->id, pe__node_name(node), history.id, - role2text(rsc->role), role2text(rsc->next_role)); + pcmk__rsc_trace(rsc, "%s role on %s after %s is %s (next %s)", + rsc->id, pcmk__node_name(node), history.id, + pcmk_role_text(rsc->role), + pcmk_role_text(rsc->next_role)); } static void @@ -4891,55 +4976,54 @@ add_node_attrs(const xmlNode *xml_obj, pcmk_node_t *node, bool overwrite, pe_rule_eval_data_t rule_data = { .node_hash = NULL, - .role = pcmk_role_unknown, .now = scheduler->now, .match_data = NULL, .rsc_data = NULL, .op_data = NULL }; - g_hash_table_insert(node->details->attrs, - strdup(CRM_ATTR_UNAME), strdup(node->details->uname)); + pcmk__insert_dup(node->details->attrs, + CRM_ATTR_UNAME, node->details->uname); - g_hash_table_insert(node->details->attrs, strdup(CRM_ATTR_ID), - strdup(node->details->id)); + pcmk__insert_dup(node->details->attrs, CRM_ATTR_ID, node->details->id); if (pcmk__str_eq(node->details->id, scheduler->dc_uuid, pcmk__str_casei)) { scheduler->dc_node = node; node->details->is_dc = TRUE; - g_hash_table_insert(node->details->attrs, - strdup(CRM_ATTR_IS_DC), strdup(XML_BOOLEAN_TRUE)); + pcmk__insert_dup(node->details->attrs, + CRM_ATTR_IS_DC, PCMK_VALUE_TRUE); } else { - g_hash_table_insert(node->details->attrs, - strdup(CRM_ATTR_IS_DC), strdup(XML_BOOLEAN_FALSE)); + pcmk__insert_dup(node->details->attrs, + CRM_ATTR_IS_DC, PCMK_VALUE_FALSE); } - cluster_name = g_hash_table_lookup(scheduler->config_hash, "cluster-name"); + cluster_name = g_hash_table_lookup(scheduler->config_hash, + PCMK_OPT_CLUSTER_NAME); if (cluster_name) { - g_hash_table_insert(node->details->attrs, strdup(CRM_ATTR_CLUSTER_NAME), - strdup(cluster_name)); + pcmk__insert_dup(node->details->attrs, CRM_ATTR_CLUSTER_NAME, + cluster_name); } - pe__unpack_dataset_nvpairs(xml_obj, XML_TAG_ATTR_SETS, &rule_data, + pe__unpack_dataset_nvpairs(xml_obj, PCMK_XE_INSTANCE_ATTRIBUTES, &rule_data, node->details->attrs, NULL, overwrite, scheduler); - pe__unpack_dataset_nvpairs(xml_obj, XML_TAG_UTILIZATION, &rule_data, + pe__unpack_dataset_nvpairs(xml_obj, PCMK_XE_UTILIZATION, &rule_data, node->details->utilization, NULL, FALSE, scheduler); - if (pe_node_attribute_raw(node, CRM_ATTR_SITE_NAME) == NULL) { - const char *site_name = pe_node_attribute_raw(node, "site-name"); + if (pcmk__node_attr(node, CRM_ATTR_SITE_NAME, NULL, + pcmk__rsc_node_current) == NULL) { + const char *site_name = pcmk__node_attr(node, "site-name", NULL, + pcmk__rsc_node_current); if (site_name) { - g_hash_table_insert(node->details->attrs, - strdup(CRM_ATTR_SITE_NAME), - strdup(site_name)); + pcmk__insert_dup(node->details->attrs, + CRM_ATTR_SITE_NAME, site_name); } else if (cluster_name) { /* Default to cluster-name if unset */ - g_hash_table_insert(node->details->attrs, - strdup(CRM_ATTR_SITE_NAME), - strdup(cluster_name)); + pcmk__insert_dup(node->details->attrs, + CRM_ATTR_SITE_NAME, cluster_name); } } } @@ -4961,13 +5045,12 @@ extract_operations(const char *node, const char *rsc, xmlNode * rsc_entry, gbool op_list = NULL; sorted_op_list = NULL; - for (rsc_op = pcmk__xe_first_child(rsc_entry); + for (rsc_op = pcmk__xe_first_child(rsc_entry, NULL, NULL, NULL); rsc_op != NULL; rsc_op = pcmk__xe_next(rsc_op)) { - if (pcmk__str_eq((const char *)rsc_op->name, XML_LRM_TAG_RSC_OP, - pcmk__str_none)) { - crm_xml_add(rsc_op, "resource", rsc); - crm_xml_add(rsc_op, XML_ATTR_UNAME, node); + if (pcmk__xe_is(rsc_op, PCMK__XE_LRM_RSC_OP)) { + crm_xml_add(rsc_op, PCMK_XA_RESOURCE, rsc); + crm_xml_add(rsc_op, PCMK_XA_UNAME, node); op_list = g_list_prepend(op_list, rsc_op); } } @@ -4994,11 +5077,11 @@ extract_operations(const char *node, const char *rsc, xmlNode * rsc_entry, gbool counter++; if (start_index < stop_index) { - crm_trace("Skipping %s: not active", ID(rsc_entry)); + crm_trace("Skipping %s: not active", pcmk__xe_id(rsc_entry)); break; } else if (counter < start_index) { - crm_trace("Skipping %s: old", ID(rsc_op)); + crm_trace("Skipping %s: old", pcmk__xe_id(rsc_op)); continue; } op_list = g_list_append(op_list, rsc_op); @@ -5016,28 +5099,31 @@ find_operations(const char *rsc, const char *node, gboolean active_filter, GList *intermediate = NULL; xmlNode *tmp = NULL; - xmlNode *status = find_xml_node(scheduler->input, XML_CIB_TAG_STATUS, TRUE); + xmlNode *status = pcmk__xe_first_child(scheduler->input, PCMK_XE_STATUS, + NULL, NULL); pcmk_node_t *this_node = NULL; xmlNode *node_state = NULL; - for (node_state = pcmk__xe_first_child(status); node_state != NULL; - node_state = pcmk__xe_next(node_state)) { + CRM_CHECK(status != NULL, return NULL); - if (pcmk__str_eq((const char *)node_state->name, XML_CIB_TAG_STATE, pcmk__str_none)) { - const char *uname = crm_element_value(node_state, XML_ATTR_UNAME); + for (node_state = pcmk__xe_first_child(status, NULL, NULL, NULL); + node_state != NULL; node_state = pcmk__xe_next(node_state)) { + + if (pcmk__xe_is(node_state, PCMK__XE_NODE_STATE)) { + const char *uname = crm_element_value(node_state, PCMK_XA_UNAME); if (node != NULL && !pcmk__str_eq(uname, node, pcmk__str_casei)) { continue; } - this_node = pe_find_node(scheduler->nodes, uname); + this_node = pcmk_find_node(scheduler, uname); if(this_node == NULL) { CRM_LOG_ASSERT(this_node != NULL); continue; - } else if (pe__is_guest_or_remote_node(this_node)) { + } else if (pcmk__is_pacemaker_remote_node(this_node)) { determine_remote_online_status(scheduler, this_node); } else { @@ -5052,16 +5138,17 @@ find_operations(const char *rsc, const char *node, gboolean active_filter, */ xmlNode *lrm_rsc = NULL; - tmp = find_xml_node(node_state, XML_CIB_TAG_LRM, FALSE); - tmp = find_xml_node(tmp, XML_LRM_TAG_RESOURCES, FALSE); - - for (lrm_rsc = pcmk__xe_first_child(tmp); lrm_rsc != NULL; - lrm_rsc = pcmk__xe_next(lrm_rsc)) { + tmp = pcmk__xe_first_child(node_state, PCMK__XE_LRM, NULL, + NULL); + tmp = pcmk__xe_first_child(tmp, PCMK__XE_LRM_RESOURCES, NULL, + NULL); - if (pcmk__str_eq((const char *)lrm_rsc->name, - XML_LRM_TAG_RESOURCE, pcmk__str_none)) { + for (lrm_rsc = pcmk__xe_first_child(tmp, NULL, NULL, NULL); + lrm_rsc != NULL; lrm_rsc = pcmk__xe_next(lrm_rsc)) { - const char *rsc_id = crm_element_value(lrm_rsc, XML_ATTR_ID); + if (pcmk__xe_is(lrm_rsc, PCMK__XE_LRM_RESOURCE)) { + const char *rsc_id = crm_element_value(lrm_rsc, + PCMK_XA_ID); if (rsc != NULL && !pcmk__str_eq(rsc_id, rsc, pcmk__str_casei)) { continue; diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c index 4055d6d..d8d9c2e 100644 --- a/lib/pengine/utils.c +++ b/lib/pengine/utils.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2023 the Pacemaker project contributors + * Copyright 2004-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -13,7 +13,7 @@ #include <stdbool.h> #include <crm/crm.h> -#include <crm/msg_xml.h> +#include <crm/common/xml.h> #include <crm/pengine/rules.h> #include <crm/pengine/internal.h> @@ -35,7 +35,7 @@ gboolean ghash_free_str_str(gpointer key, gpointer value, gpointer user_data); bool pe_can_fence(const pcmk_scheduler_t *scheduler, const pcmk_node_t *node) { - if (pe__is_guest_node(node)) { + if (pcmk__is_guest_or_bundle_node(node)) { /* Guest nodes are fenced by stopping their container resource. We can * do that if the container's host is either online or fenceable. */ @@ -68,11 +68,11 @@ pe_can_fence(const pcmk_scheduler_t *scheduler, const pcmk_node_t *node) } else if(node->details->online) { crm_notice("We can fence %s without quorum because they're in our membership", - pe__node_name(node)); + pcmk__node_name(node)); return true; } - crm_trace("Cannot fence %s", pe__node_name(node)); + crm_trace("Cannot fence %s", pcmk__node_name(node)); return false; } @@ -92,8 +92,7 @@ pe__copy_node(const pcmk_node_t *this_node) CRM_ASSERT(this_node != NULL); - new_node = calloc(1, sizeof(pcmk_node_t)); - CRM_ASSERT(new_node != NULL); + new_node = pcmk__assert_alloc(1, sizeof(pcmk_node_t)); new_node->rsc_discover_mode = this_node->rsc_discover_mode; new_node->weight = this_node->weight; @@ -221,12 +220,12 @@ pe__log_node_weights(const char *file, const char *function, int line, "%s: %s allocation score on %s: %s", LOG_TRACE, line, 0, comment, rsc->id, - pe__node_name(node), + pcmk__node_name(node), pcmk_readable_score(node->weight)); } else { qb_log_from_external_source(function, file, "%s: %s = %s", LOG_TRACE, line, 0, - comment, pe__node_name(node), + comment, pcmk__node_name(node), pcmk_readable_score(node->weight)); } } @@ -350,10 +349,10 @@ resource_node_score(pcmk_resource_t *rsc, const pcmk_node_t *node, int score, g_hash_table_insert(rsc->allowed_nodes, (gpointer) match->details->id, match); } match->weight = pcmk__add_scores(match->weight, score); - pe_rsc_trace(rsc, - "Enabling %s preference (%s) for %s on %s (now %s)", - tag, pcmk_readable_score(score), rsc->id, pe__node_name(node), - pcmk_readable_score(match->weight)); + pcmk__rsc_trace(rsc, + "Enabling %s preference (%s) for %s on %s (now %s)", + tag, pcmk_readable_score(score), rsc->id, + pcmk__node_name(node), pcmk_readable_score(match->weight)); } void @@ -382,10 +381,10 @@ resource_location(pcmk_resource_t *rsc, const pcmk_node_t *node, int score, } } - if (node == NULL && score == -INFINITY) { + if ((node == NULL) && (score == -PCMK_SCORE_INFINITY)) { if (rsc->allocated_to) { crm_info("Deallocating %s from %s", - rsc->id, pe__node_name(rsc->allocated_to)); + rsc->id, pcmk__node_name(rsc->allocated_to)); free(rsc->allocated_to); rsc->allocated_to = NULL; } @@ -411,18 +410,26 @@ gboolean get_target_role(const pcmk_resource_t *rsc, enum rsc_role_e *role) { enum rsc_role_e local_role = pcmk_role_unknown; - const char *value = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_TARGET_ROLE); + const char *value = g_hash_table_lookup(rsc->meta, PCMK_META_TARGET_ROLE); CRM_CHECK(role != NULL, return FALSE); - if (pcmk__str_eq(value, "started", pcmk__str_null_matches | pcmk__str_casei) - || pcmk__str_eq("default", value, pcmk__str_casei)) { + if (pcmk__str_eq(value, PCMK_ROLE_STARTED, + pcmk__str_null_matches|pcmk__str_casei)) { + return FALSE; + } + if (pcmk__str_eq(PCMK_VALUE_DEFAULT, value, pcmk__str_casei)) { + // @COMPAT Deprecated since 2.1.8 + pcmk__config_warn("Support for setting " PCMK_META_TARGET_ROLE + " to the explicit value '" PCMK_VALUE_DEFAULT + "' is deprecated and will be removed in a " + "future release (just leave it unset)"); return FALSE; } - local_role = text2role(value); + local_role = pcmk_parse_role(value); if (local_role == pcmk_role_unknown) { - pcmk__config_err("Ignoring '" XML_RSC_ATTR_TARGET_ROLE "' for %s " + pcmk__config_err("Ignoring '" PCMK_META_TARGET_ROLE "' for %s " "because '%s' is not valid", rsc->id, value); return FALSE; @@ -435,7 +442,7 @@ get_target_role(const pcmk_resource_t *rsc, enum rsc_role_e *role) } } else { - pcmk__config_err("Ignoring '" XML_RSC_ATTR_TARGET_ROLE "' for %s " + pcmk__config_err("Ignoring '" PCMK_META_TARGET_ROLE "' for %s " "because '%s' only makes sense for promotable " "clones", rsc->id, value); return FALSE; @@ -478,14 +485,14 @@ order_actions(pcmk_action_t *lh_action, pcmk_action_t *rh_action, } } - wrapper = calloc(1, sizeof(pcmk__related_action_t)); + wrapper = pcmk__assert_alloc(1, sizeof(pcmk__related_action_t)); wrapper->action = rh_action; wrapper->type = flags; list = lh_action->actions_after; list = g_list_prepend(list, wrapper); lh_action->actions_after = list; - wrapper = calloc(1, sizeof(pcmk__related_action_t)); + wrapper = pcmk__assert_alloc(1, sizeof(pcmk__related_action_t)); wrapper->action = lh_action; wrapper->type = flags; list = rh_action->actions_before; @@ -524,7 +531,7 @@ ticket_new(const char *ticket_id, pcmk_scheduler_t *scheduler) ticket = calloc(1, sizeof(pcmk_ticket_t)); if (ticket == NULL) { - crm_err("Cannot allocate ticket '%s'", ticket_id); + pcmk__sched_err("Cannot allocate ticket '%s'", ticket_id); return NULL; } @@ -545,13 +552,16 @@ ticket_new(const char *ticket_id, pcmk_scheduler_t *scheduler) const char * rsc_printable_id(const pcmk_resource_t *rsc) { - return pcmk_is_set(rsc->flags, pcmk_rsc_unique)? rsc->id : ID(rsc->xml); + if (pcmk_is_set(rsc->flags, pcmk_rsc_unique)) { + return rsc->id; + } + return pcmk__xe_id(rsc->xml); } void pe__clear_resource_flags_recursive(pcmk_resource_t *rsc, uint64_t flags) { - pe__clear_resource_flags(rsc, flags); + pcmk__clear_rsc_flags(rsc, flags); for (GList *gIter = rsc->children; gIter != NULL; gIter = gIter->next) { pe__clear_resource_flags_recursive((pcmk_resource_t *) gIter->data, flags); @@ -570,7 +580,7 @@ pe__clear_resource_flags_on_all(pcmk_scheduler_t *scheduler, uint64_t flag) void pe__set_resource_flags_recursive(pcmk_resource_t *rsc, uint64_t flags) { - pe__set_resource_flags(rsc, flags); + pcmk__set_rsc_flags(rsc, flags); for (GList *gIter = rsc->children; gIter != NULL; gIter = gIter->next) { pe__set_resource_flags_recursive((pcmk_resource_t *) gIter->data, flags); @@ -626,6 +636,7 @@ add_tag_ref(GHashTable * tags, const char * tag_name, const char * obj_ref) if (tag == NULL) { tag = calloc(1, sizeof(pcmk_tag_t)); if (tag == NULL) { + pcmk__sched_err("Could not allocate memory for tag %s", tag_name); return FALSE; } tag->id = strdup(tag_name); @@ -665,7 +676,8 @@ add_tag_ref(GHashTable * tags, const char * tag_name, const char * obj_ref) bool pe__shutdown_requested(const pcmk_node_t *node) { - const char *shutdown = pe_node_attribute_raw(node, XML_CIB_ATTR_SHUTDOWN); + const char *shutdown = pcmk__node_attr(node, PCMK__NODE_ATTR_SHUTDOWN, NULL, + pcmk__rsc_node_current); return !pcmk__str_eq(shutdown, "0", pcmk__str_null_matches); } @@ -727,9 +739,10 @@ pe__resource_is_disabled(const pcmk_resource_t *rsc) const char *target_role = NULL; CRM_CHECK(rsc != NULL, return false); - target_role = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_TARGET_ROLE); + target_role = g_hash_table_lookup(rsc->meta, PCMK_META_TARGET_ROLE); if (target_role) { - enum rsc_role_e target_role_e = text2role(target_role); + // If invalid, we've already logged an error when unpacking + enum rsc_role_e target_role_e = pcmk_parse_role(target_role); if ((target_role_e == pcmk_role_stopped) || ((target_role_e == pcmk_role_unpromoted) @@ -754,7 +767,8 @@ bool pe__rsc_running_on_only(const pcmk_resource_t *rsc, const pcmk_node_t *node) { return (rsc != NULL) && pcmk__list_of_1(rsc->running_on) - && pe__same_node((const pcmk_node_t *) rsc->running_on->data, node); + && pcmk__same_node((const pcmk_node_t *) rsc->running_on->data, + node); } bool @@ -809,7 +823,7 @@ pe__build_node_name_list(pcmk_scheduler_t *scheduler, const char *s) */ nodes = g_list_prepend(nodes, strdup("*")); } else { - pcmk_node_t *node = pe_find_node(scheduler->nodes, s); + pcmk_node_t *node = pcmk_find_node(scheduler, s); if (node) { /* The given string was a valid uname for a node. Return a @@ -871,12 +885,14 @@ pe__failed_probe_for_rsc(const pcmk_resource_t *rsc, const char *name) const pcmk_resource_t *parent = pe__const_top_resource(rsc, false); const char *rsc_id = rsc->id; - if (parent->variant == pcmk_rsc_variant_clone) { + if (pcmk__is_clone(parent)) { rsc_id = pe__clone_child_id(parent); } - for (xmlNode *xml_op = pcmk__xml_first_child(rsc->cluster->failed); xml_op != NULL; - xml_op = pcmk__xml_next(xml_op)) { + for (xmlNode *xml_op = pcmk__xe_first_child(rsc->cluster->failed, NULL, + NULL, NULL); + xml_op != NULL; xml_op = pcmk__xe_next(xml_op)) { + const char *value = NULL; char *op_id = NULL; @@ -888,12 +904,12 @@ pe__failed_probe_for_rsc(const pcmk_resource_t *rsc, const char *name) /* This resource operation was not run on the given node. Note that if name is * NULL, this will always succeed. */ - value = crm_element_value(xml_op, XML_LRM_ATTR_TARGET); + value = crm_element_value(xml_op, PCMK__META_ON_NODE); if (value == NULL || !pcmk__str_eq(value, name, pcmk__str_casei|pcmk__str_null_matches)) { continue; } - if (!parse_op_key(pe__xe_history_key(xml_op), &op_id, NULL, NULL)) { + if (!parse_op_key(pcmk__xe_history_key(xml_op), &op_id, NULL, NULL)) { continue; // This history entry is missing an operation key } |