diff options
Diffstat (limited to 'lib/cib')
-rw-r--r-- | lib/cib/Makefile.am | 2 | ||||
-rw-r--r-- | lib/cib/cib_attrs.c | 255 | ||||
-rw-r--r-- | lib/cib/cib_client.c | 35 | ||||
-rw-r--r-- | lib/cib/cib_file.c | 90 | ||||
-rw-r--r-- | lib/cib/cib_native.c | 45 | ||||
-rw-r--r-- | lib/cib/cib_ops.c | 350 | ||||
-rw-r--r-- | lib/cib/cib_remote.c | 50 | ||||
-rw-r--r-- | lib/cib/cib_utils.c | 383 |
8 files changed, 566 insertions, 644 deletions
diff --git a/lib/cib/Makefile.am b/lib/cib/Makefile.am index a74c4b1..b23c332 100644 --- a/lib/cib/Makefile.am +++ b/lib/cib/Makefile.am @@ -20,7 +20,7 @@ libcib_la_SOURCES += cib_ops.c libcib_la_SOURCES += cib_remote.c libcib_la_SOURCES += cib_utils.c -libcib_la_LDFLAGS = -version-info 32:0:5 +libcib_la_LDFLAGS = -version-info 33:0:6 libcib_la_CPPFLAGS = -I$(top_srcdir) $(AM_CPPFLAGS) libcib_la_CFLAGS = $(CFLAGS_HARDENED_LIB) diff --git a/lib/cib/cib_attrs.c b/lib/cib/cib_attrs.c index 11629b8..2014a0a 100644 --- a/lib/cib/cib_attrs.c +++ b/lib/cib/cib_attrs.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. * @@ -22,7 +22,6 @@ #include <fcntl.h> #include <libgen.h> -#include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crm/common/xml_internal.h> #include <crm/common/output_internal.h> @@ -66,22 +65,23 @@ find_attr(cib_t *cib, const char *section, const char *node_uuid, if (attr_set_type) { set_type = attr_set_type; } else { - set_type = XML_TAG_ATTR_SETS; + set_type = PCMK_XE_INSTANCE_ATTRIBUTES; } - if (pcmk__str_eq(section, XML_CIB_TAG_CRMCONFIG, pcmk__str_casei)) { + if (pcmk__str_eq(section, PCMK_XE_CRM_CONFIG, pcmk__str_casei)) { node_uuid = NULL; - set_type = XML_CIB_TAG_PROPSET; + set_type = PCMK_XE_CLUSTER_PROPERTY_SET; - } else if (pcmk__strcase_any_of(section, XML_CIB_TAG_OPCONFIG, XML_CIB_TAG_RSCCONFIG, + } else if (pcmk__strcase_any_of(section, + PCMK_XE_OP_DEFAULTS, PCMK_XE_RSC_DEFAULTS, NULL)) { node_uuid = NULL; - set_type = XML_TAG_META_SETS; + set_type = PCMK_XE_META_ATTRIBUTES; - } else if (pcmk__str_eq(section, XML_CIB_TAG_TICKETS, pcmk__str_casei)) { + } else if (pcmk__str_eq(section, PCMK_XE_TICKETS, pcmk__str_casei)) { node_uuid = NULL; - section = XML_CIB_TAG_STATUS; - node_type = XML_CIB_TAG_TICKETS; + section = PCMK_XE_STATUS; + node_type = PCMK_XE_TICKETS; } else if (node_uuid == NULL) { return EINVAL; @@ -96,51 +96,51 @@ find_attr(cib_t *cib, const char *section, const char *node_uuid, xpath = g_string_sized_new(1024); g_string_append(xpath, xpath_base); - if (pcmk__str_eq(node_type, XML_CIB_TAG_TICKETS, pcmk__str_casei)) { + if (pcmk__str_eq(node_type, PCMK_XE_TICKETS, pcmk__str_casei)) { pcmk__g_strcat(xpath, "//", node_type, NULL); } else if (node_uuid) { - const char *node_type = XML_CIB_TAG_NODE; + const char *node_type = PCMK_XE_NODE; - if (pcmk__str_eq(section, XML_CIB_TAG_STATUS, pcmk__str_casei)) { - node_type = XML_CIB_TAG_STATE; - set_type = XML_TAG_TRANSIENT_NODEATTRS; + if (pcmk__str_eq(section, PCMK_XE_STATUS, pcmk__str_casei)) { + node_type = PCMK__XE_NODE_STATE; + set_type = PCMK__XE_TRANSIENT_ATTRIBUTES; } pcmk__g_strcat(xpath, - "//", node_type, "[@" XML_ATTR_ID "='", node_uuid, "']", + "//", node_type, "[@" PCMK_XA_ID "='", node_uuid, "']", NULL); } pcmk__g_strcat(xpath, "//", set_type, NULL); if (set_name) { - pcmk__g_strcat(xpath, "[@" XML_ATTR_ID "='", set_name, "']", NULL); + pcmk__g_strcat(xpath, "[@" PCMK_XA_ID "='", set_name, "']", NULL); } g_string_append(xpath, "//nvpair"); if (attr_id && attr_name) { pcmk__g_strcat(xpath, - "[@" XML_ATTR_ID "='", attr_id, "' " - "and @" XML_ATTR_NAME "='", attr_name, "']", NULL); + "[@" PCMK_XA_ID "='", attr_id, "' " + "and @" PCMK_XA_NAME "='", attr_name, "']", NULL); } else if (attr_id) { - pcmk__g_strcat(xpath, "[@" XML_ATTR_ID "='", attr_id, "']", NULL); + pcmk__g_strcat(xpath, "[@" PCMK_XA_ID "='", attr_id, "']", NULL); } else if (attr_name) { - pcmk__g_strcat(xpath, "[@" XML_ATTR_NAME "='", attr_name, "']", NULL); + pcmk__g_strcat(xpath, "[@" PCMK_XA_NAME "='", attr_name, "']", NULL); } rc = cib_internal_op(cib, PCMK__CIB_REQUEST_QUERY, NULL, (const char *) xpath->str, NULL, &xml_search, cib_sync_call|cib_scope_local|cib_xpath, user_name); - if (rc < 0) { - rc = pcmk_legacy2rc(rc); + rc = pcmk_legacy2rc(rc); + + if (rc != pcmk_rc_ok) { crm_trace("Query failed for attribute %s (section=%s, node=%s, set=%s, xpath=%s): %s", attr_name, section, pcmk__s(node_uuid, "<null>"), pcmk__s(set_name, "<null>"), (const char *) xpath->str, pcmk_rc_str(rc)); } else { - rc = pcmk_rc_ok; crm_log_xml_debug(xml_search, "Match"); } @@ -153,16 +153,8 @@ static int handle_multiples(pcmk__output_t *out, xmlNode *search, const char *attr_name) { if ((search != NULL) && (search->children != NULL)) { - xmlNode *child = NULL; - - out->info(out, "Multiple attributes match name=%s", attr_name); - for (child = pcmk__xml_first_child(search); child != NULL; - child = pcmk__xml_next(child)) { - out->info(out, " Value: %s \t(id=%s)", - crm_element_value(child, XML_NVPAIR_ATTR_VALUE), ID(child)); - } + pcmk__warn_multiple_name_matches(out, search, attr_name); return ENOTUNIQ; - } else { return pcmk_rc_ok; } @@ -195,7 +187,7 @@ cib__update_node_attr(pcmk__output_t *out, cib_t *cib, int call_options, const c free_xml(xml_search); return ENOTUNIQ; } else { - pcmk__str_update(&local_attr_id, crm_element_value(xml_search, XML_ATTR_ID)); + local_attr_id = crm_element_value_copy(xml_search, PCMK_XA_ID); attr_id = local_attr_id; free_xml(xml_search); goto do_modify; @@ -211,38 +203,38 @@ cib__update_node_attr(pcmk__output_t *out, cib_t *cib, int call_options, const c } else { free_xml(xml_search); crm_trace("%s does not exist, create it", attr_name); - if (pcmk__str_eq(section, XML_CIB_TAG_TICKETS, pcmk__str_casei)) { + if (pcmk__str_eq(section, PCMK_XE_TICKETS, pcmk__str_casei)) { node_uuid = NULL; - section = XML_CIB_TAG_STATUS; - node_type = XML_CIB_TAG_TICKETS; + section = PCMK_XE_STATUS; + node_type = PCMK_XE_TICKETS; - xml_top = create_xml_node(xml_obj, XML_CIB_TAG_STATUS); - xml_obj = create_xml_node(xml_top, XML_CIB_TAG_TICKETS); + xml_top = pcmk__xe_create(xml_obj, PCMK_XE_STATUS); + xml_obj = pcmk__xe_create(xml_top, PCMK_XE_TICKETS); - } else if (pcmk__str_eq(section, XML_CIB_TAG_NODES, pcmk__str_casei)) { + } else if (pcmk__str_eq(section, PCMK_XE_NODES, pcmk__str_casei)) { if (node_uuid == NULL) { return EINVAL; } - if (pcmk__str_eq(node_type, "remote", pcmk__str_casei)) { - xml_top = create_xml_node(xml_obj, XML_CIB_TAG_NODES); - xml_obj = create_xml_node(xml_top, XML_CIB_TAG_NODE); - crm_xml_add(xml_obj, XML_ATTR_TYPE, "remote"); - crm_xml_add(xml_obj, XML_ATTR_ID, node_uuid); - crm_xml_add(xml_obj, XML_ATTR_UNAME, node_uuid); + if (pcmk__str_eq(node_type, PCMK_VALUE_REMOTE, pcmk__str_casei)) { + xml_top = pcmk__xe_create(xml_obj, PCMK_XE_NODES); + xml_obj = pcmk__xe_create(xml_top, PCMK_XE_NODE); + crm_xml_add(xml_obj, PCMK_XA_TYPE, PCMK_VALUE_REMOTE); + crm_xml_add(xml_obj, PCMK_XA_ID, node_uuid); + crm_xml_add(xml_obj, PCMK_XA_UNAME, node_uuid); } else { - tag = XML_CIB_TAG_NODE; + tag = PCMK_XE_NODE; } - } else if (pcmk__str_eq(section, XML_CIB_TAG_STATUS, pcmk__str_casei)) { - tag = XML_TAG_TRANSIENT_NODEATTRS; + } else if (pcmk__str_eq(section, PCMK_XE_STATUS, pcmk__str_casei)) { + tag = PCMK__XE_TRANSIENT_ATTRIBUTES; if (node_uuid == NULL) { return EINVAL; } - xml_top = create_xml_node(xml_obj, XML_CIB_TAG_STATE); - crm_xml_add(xml_top, XML_ATTR_ID, node_uuid); + xml_top = pcmk__xe_create(xml_obj, PCMK__XE_NODE_STATE); + crm_xml_add(xml_top, PCMK_XA_ID, node_uuid); xml_obj = xml_top; } else { @@ -251,12 +243,14 @@ cib__update_node_attr(pcmk__output_t *out, cib_t *cib, int call_options, const c } if (set_name == NULL) { - if (pcmk__str_eq(section, XML_CIB_TAG_CRMCONFIG, pcmk__str_casei)) { - local_set_name = strdup(CIB_OPTIONS_FIRST); + if (pcmk__str_eq(section, PCMK_XE_CRM_CONFIG, pcmk__str_casei)) { + local_set_name = + pcmk__str_copy(PCMK_VALUE_CIB_BOOTSTRAP_OPTIONS); - } else if (pcmk__str_eq(node_type, XML_CIB_TAG_TICKETS, pcmk__str_casei)) { + } else if (pcmk__str_eq(node_type, PCMK_XE_TICKETS, + pcmk__str_casei)) { local_set_name = crm_strdup_printf("%s-%s", section, - XML_CIB_TAG_TICKETS); + PCMK_XE_TICKETS); } else if (node_uuid) { local_set_name = crm_strdup_printf("%s-%s", section, node_uuid); @@ -285,27 +279,30 @@ cib__update_node_attr(pcmk__output_t *out, cib_t *cib, int call_options, const c crm_trace("Creating %s/%s", section, tag); if (tag != NULL) { - xml_obj = create_xml_node(xml_obj, tag); - crm_xml_add(xml_obj, XML_ATTR_ID, node_uuid); + xml_obj = pcmk__xe_create(xml_obj, tag); + crm_xml_add(xml_obj, PCMK_XA_ID, node_uuid); if (xml_top == NULL) { xml_top = xml_obj; } } - if (node_uuid == NULL && !pcmk__str_eq(node_type, XML_CIB_TAG_TICKETS, pcmk__str_casei)) { - if (pcmk__str_eq(section, XML_CIB_TAG_CRMCONFIG, pcmk__str_casei)) { - xml_obj = create_xml_node(xml_obj, XML_CIB_TAG_PROPSET); + if ((node_uuid == NULL) + && !pcmk__str_eq(node_type, PCMK_XE_TICKETS, pcmk__str_casei)) { + + if (pcmk__str_eq(section, PCMK_XE_CRM_CONFIG, pcmk__str_casei)) { + xml_obj = pcmk__xe_create(xml_obj, + PCMK_XE_CLUSTER_PROPERTY_SET); } else { - xml_obj = create_xml_node(xml_obj, XML_TAG_META_SETS); + xml_obj = pcmk__xe_create(xml_obj, PCMK_XE_META_ATTRIBUTES); } } else if (set_type) { - xml_obj = create_xml_node(xml_obj, set_type); + xml_obj = pcmk__xe_create(xml_obj, set_type); } else { - xml_obj = create_xml_node(xml_obj, XML_TAG_ATTR_SETS); + xml_obj = pcmk__xe_create(xml_obj, PCMK_XE_INSTANCE_ATTRIBUTES); } - crm_xml_add(xml_obj, XML_ATTR_ID, set_name); + crm_xml_add(xml_obj, PCMK_XA_ID, set_name); if (xml_top == NULL) { xml_top = xml_obj; @@ -321,15 +318,20 @@ cib__update_node_attr(pcmk__output_t *out, cib_t *cib, int call_options, const c crm_log_xml_trace(xml_top, "update_attr"); rc = cib_internal_op(cib, PCMK__CIB_REQUEST_MODIFY, NULL, section, xml_top, NULL, call_options, user_name); - if (rc < 0) { + + if (!pcmk_is_set(call_options, cib_sync_call) && (cib->variant != cib_file) + && (rc >= 0)) { + // For async call, positive rc is the call ID (file always synchronous) + rc = pcmk_rc_ok; + } else { rc = pcmk_legacy2rc(rc); + } + if (rc != pcmk_rc_ok) { out->err(out, "Error setting %s=%s (section=%s, set=%s): %s", attr_name, attr_value, section, pcmk__s(set_name, "<null>"), pcmk_rc_str(rc)); crm_log_xml_info(xml_top, "Update"); - } else { - rc = pcmk_rc_ok; } free(local_set_name); @@ -387,7 +389,7 @@ cib__delete_node_attr(pcmk__output_t *out, cib_t *cib, int options, const char * free_xml(xml_search); return rc; } else { - pcmk__str_update(&local_attr_id, crm_element_value(xml_search, XML_ATTR_ID)); + local_attr_id = crm_element_value_copy(xml_search, PCMK_XA_ID); attr_id = local_attr_id; free_xml(xml_search); } @@ -397,16 +399,21 @@ cib__delete_node_attr(pcmk__output_t *out, cib_t *cib, int options, const char * rc = cib_internal_op(cib, PCMK__CIB_REQUEST_DELETE, NULL, section, xml_obj, NULL, options, user_name); - if (rc < 0) { - rc = pcmk_legacy2rc(rc); - } else { + + if (!pcmk_is_set(options, cib_sync_call) && (cib->variant != cib_file) + && (rc >= 0)) { + // For async call, positive rc is the call ID (file always synchronous) rc = pcmk_rc_ok; + } else { + rc = pcmk_legacy2rc(rc); + } + + if (rc == pcmk_rc_ok) { out->info(out, "Deleted %s %s: id=%s%s%s%s%s", section, node_uuid ? "attribute" : "option", local_attr_id, set_name ? " set=" : "", set_name ? set_name : "", attr_name ? " name=" : "", attr_name ? attr_name : ""); } - free(local_attr_id); free_xml(xml_obj); return rc; @@ -487,7 +494,8 @@ read_attr_delegate(cib_t *cib, const char *section, const char *node_uuid, if (rc == pcmk_rc_ok) { if (result->children == NULL) { - pcmk__str_update(attr_value, crm_element_value(result, XML_NVPAIR_ATTR_VALUE)); + pcmk__str_update(attr_value, + crm_element_value(result, PCMK_XA_VALUE)); } else { rc = ENOTUNIQ; } @@ -535,7 +543,6 @@ static int get_uuid_from_result(const xmlNode *result, char **uuid, int *is_remote) { int rc = -ENXIO; - const char *tag; const char *parsed_uuid = NULL; int parsed_is_remote = FALSE; @@ -544,41 +551,42 @@ get_uuid_from_result(const xmlNode *result, char **uuid, int *is_remote) } /* If there are multiple results, the first is sufficient */ - tag = (const char *) (result->name); - if (pcmk__str_eq(tag, "xpath-query", pcmk__str_casei)) { - result = pcmk__xml_first_child(result); + if (pcmk__xe_is(result, PCMK__XE_XPATH_QUERY)) { + result = pcmk__xe_first_child(result, NULL, NULL, NULL); CRM_CHECK(result != NULL, return rc); - tag = (const char *) (result->name); } - if (pcmk__str_eq(tag, XML_CIB_TAG_NODE, pcmk__str_casei)) { - /* Result is <node> tag from <nodes> section */ + if (pcmk__xe_is(result, PCMK_XE_NODE)) { + // Result is PCMK_XE_NODE element from PCMK_XE_NODES section - if (pcmk__str_eq(crm_element_value(result, XML_ATTR_TYPE), "remote", pcmk__str_casei)) { - parsed_uuid = crm_element_value(result, XML_ATTR_UNAME); + if (pcmk__str_eq(crm_element_value(result, PCMK_XA_TYPE), + PCMK_VALUE_REMOTE, pcmk__str_casei)) { + parsed_uuid = crm_element_value(result, PCMK_XA_UNAME); parsed_is_remote = TRUE; } else { - parsed_uuid = ID(result); + parsed_uuid = pcmk__xe_id(result); parsed_is_remote = FALSE; } - } else if (pcmk__str_eq(tag, XML_CIB_TAG_RESOURCE, pcmk__str_casei)) { + } else if (pcmk__xe_is(result, PCMK_XE_PRIMITIVE)) { /* Result is <primitive> for ocf:pacemaker:remote resource */ - parsed_uuid = ID(result); + parsed_uuid = pcmk__xe_id(result); parsed_is_remote = TRUE; - } else if (pcmk__str_eq(tag, XML_CIB_TAG_NVPAIR, pcmk__str_casei)) { - /* Result is remote-node parameter of <primitive> for guest node */ + } else if (pcmk__xe_is(result, PCMK_XE_NVPAIR)) { + /* Result is PCMK_META_REMOTE_NODE parameter of <primitive> for guest + * node + */ - parsed_uuid = crm_element_value(result, XML_NVPAIR_ATTR_VALUE); + parsed_uuid = crm_element_value(result, PCMK_XA_VALUE); parsed_is_remote = TRUE; - } else if (pcmk__str_eq(tag, XML_CIB_TAG_STATE, pcmk__str_casei)) { - /* Result is <node_state> tag from <status> section */ + } else if (pcmk__xe_is(result, PCMK__XE_NODE_STATE)) { + // Result is PCMK__XE_NODE_STATE element from PCMK_XE_STATUS section - parsed_uuid = crm_element_value(result, XML_ATTR_UNAME); - if (pcmk__xe_attr_is_true(result, XML_NODE_IS_REMOTE)) { + parsed_uuid = crm_element_value(result, PCMK_XA_UNAME); + if (pcmk__xe_attr_is_true(result, PCMK_XA_REMOTE_NODE)) { parsed_is_remote = TRUE; } } @@ -605,16 +613,16 @@ get_uuid_from_result(const xmlNode *result, char **uuid, int *is_remote) #define XPATH_UPPER_TRANS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" #define XPATH_LOWER_TRANS "abcdefghijklmnopqrstuvwxyz" #define XPATH_NODE \ - "/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_NODES \ - "/" XML_CIB_TAG_NODE "[translate(@" XML_ATTR_UNAME ",'" XPATH_UPPER_TRANS "','" XPATH_LOWER_TRANS "') ='%s']" \ - "|/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_RESOURCES \ - "/" XML_CIB_TAG_RESOURCE \ + "/" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION "/" PCMK_XE_NODES \ + "/" PCMK_XE_NODE "[translate(@" PCMK_XA_UNAME ",'" XPATH_UPPER_TRANS "','" XPATH_LOWER_TRANS "') ='%s']" \ + "|/" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION "/" PCMK_XE_RESOURCES \ + "/" PCMK_XE_PRIMITIVE \ "[@class='ocf'][@provider='pacemaker'][@type='remote'][translate(@id,'" XPATH_UPPER_TRANS "','" XPATH_LOWER_TRANS "') ='%s']" \ - "|/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_RESOURCES \ - "/" XML_CIB_TAG_RESOURCE "/" XML_TAG_META_SETS "/" XML_CIB_TAG_NVPAIR \ - "[@name='" XML_RSC_ATTR_REMOTE_NODE "'][translate(@value,'" XPATH_UPPER_TRANS "','" XPATH_LOWER_TRANS "') ='%s']" \ - "|/" XML_TAG_CIB "/" XML_CIB_TAG_STATUS "/" XML_CIB_TAG_STATE \ - "[@" XML_NODE_IS_REMOTE "='true'][translate(@" XML_ATTR_ID ",'" XPATH_UPPER_TRANS "','" XPATH_LOWER_TRANS "') ='%s']" + "|/" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION "/" PCMK_XE_RESOURCES \ + "/" PCMK_XE_PRIMITIVE "/" PCMK_XE_META_ATTRIBUTES "/" PCMK_XE_NVPAIR \ + "[@name='" PCMK_META_REMOTE_NODE "'][translate(@value,'" XPATH_UPPER_TRANS "','" XPATH_LOWER_TRANS "') ='%s']" \ + "|/" PCMK_XE_CIB "/" PCMK_XE_STATUS "/" PCMK__XE_NODE_STATE \ + "[@" PCMK_XA_REMOTE_NODE "='true'][translate(@" PCMK_XA_ID ",'" XPATH_UPPER_TRANS "','" XPATH_LOWER_TRANS "') ='%s']" int query_node_uuid(cib_t * the_cib, const char *uname, char **uuid, int *is_remote_node) @@ -657,6 +665,11 @@ query_node_uuid(cib_t * the_cib, const char *uname, char **uuid, int *is_remote_ return rc; } +// Deprecated functions kept only for backward API compatibility +// LCOV_EXCL_START + +#include <crm/cib/util_compat.h> + int query_node_uname(cib_t * the_cib, const char *uuid, char **uname) { @@ -669,33 +682,31 @@ query_node_uname(cib_t * the_cib, const char *uuid, char **uname) CRM_ASSERT(uname != NULL); CRM_ASSERT(uuid != NULL); - rc = the_cib->cmds->query(the_cib, XML_CIB_TAG_NODES, &fragment, + rc = the_cib->cmds->query(the_cib, PCMK_XE_NODES, &fragment, cib_sync_call | cib_scope_local); if (rc != pcmk_ok) { return rc; } xml_obj = fragment; - CRM_CHECK(pcmk__xe_is(xml_obj, XML_CIB_TAG_NODES), return -ENOMSG); + CRM_CHECK(pcmk__xe_is(xml_obj, PCMK_XE_NODES), return -ENOMSG); crm_log_xml_trace(xml_obj, "Result section"); rc = -ENXIO; *uname = NULL; - for (a_child = pcmk__xml_first_child(xml_obj); a_child != NULL; - a_child = pcmk__xml_next(a_child)) { - - if (pcmk__str_eq((const char *)a_child->name, XML_CIB_TAG_NODE, - pcmk__str_none)) { - child_name = ID(a_child); - if (pcmk__str_eq(uuid, child_name, pcmk__str_casei)) { - child_name = crm_element_value(a_child, XML_ATTR_UNAME); - if (child_name != NULL) { - *uname = strdup(child_name); - rc = pcmk_ok; - } - break; + for (a_child = pcmk__xe_first_child(xml_obj, PCMK_XE_NODE, NULL, NULL); + a_child != NULL; a_child = pcmk__xe_next_same(a_child)) { + + child_name = pcmk__xe_id(a_child); + + if (pcmk__str_eq(uuid, child_name, pcmk__str_casei)) { + child_name = crm_element_value(a_child, PCMK_XA_UNAME); + if (child_name != NULL) { + *uname = strdup(child_name); + rc = pcmk_ok; } + break; } } @@ -712,18 +723,22 @@ set_standby(cib_t * the_cib, const char *uuid, const char *scope, const char *st CRM_CHECK(uuid != NULL, return -EINVAL); CRM_CHECK(standby_value != NULL, return -EINVAL); - if (pcmk__strcase_any_of(scope, "reboot", XML_CIB_TAG_STATUS, NULL)) { - scope = XML_CIB_TAG_STATUS; + if (pcmk__strcase_any_of(scope, "reboot", PCMK_XE_STATUS, NULL)) { + scope = PCMK_XE_STATUS; attr_id = crm_strdup_printf("transient-standby-%.256s", uuid); } else { - scope = XML_CIB_TAG_NODES; + scope = PCMK_XE_NODES; attr_id = crm_strdup_printf("standby-%.256s", uuid); } rc = update_attr_delegate(the_cib, cib_sync_call, scope, uuid, NULL, NULL, - attr_id, "standby", standby_value, TRUE, NULL, NULL); + attr_id, PCMK_NODE_ATTR_STANDBY, standby_value, + TRUE, NULL, NULL); free(attr_id); return rc; } + +// LCOV_EXCL_STOP +// End deprecated API diff --git a/lib/cib/cib_client.c b/lib/cib/cib_client.c index 32e1f83..c980429 100644 --- a/lib/cib/cib_client.c +++ b/lib/cib/cib_client.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. * @@ -22,7 +22,6 @@ #include <crm/crm.h> #include <crm/cib/internal.h> -#include <crm/msg_xml.h> #include <crm/common/xml.h> static GHashTable *cib_op_callback_table = NULL; @@ -89,7 +88,7 @@ cib_client_add_notify_callback(cib_t * cib, const char *event, crm_trace("Adding callback for %s events (%d)", event, g_list_length(cib->notify_list)); - new_client = calloc(1, sizeof(cib_notify_client_t)); + new_client = pcmk__assert_alloc(1, sizeof(cib_notify_client_t)); new_client->event = event; new_client->callback = callback; @@ -147,7 +146,7 @@ cib_client_del_notify_callback(cib_t *cib, const char *event, crm_debug("Removing callback for %s events", event); - new_client = calloc(1, sizeof(cib_notify_client_t)); + new_client = pcmk__assert_alloc(1, sizeof(cib_notify_client_t)); new_client->event = event; new_client->callback = callback; @@ -209,7 +208,7 @@ cib_client_register_callback_full(cib_t *cib, int call_id, int timeout, return FALSE; } - blob = calloc(1, sizeof(cib_callback_client_t)); + blob = pcmk__assert_alloc(1, sizeof(cib_callback_client_t)); blob->id = callback_name; blob->only_success = only_success; blob->user_data = user_data; @@ -217,9 +216,9 @@ cib_client_register_callback_full(cib_t *cib, int call_id, int timeout, blob->free_func = free_func; if (timeout > 0) { - struct timer_rec_s *async_timer = NULL; + struct timer_rec_s *async_timer = + pcmk__assert_alloc(1, sizeof(struct timer_rec_s)); - async_timer = calloc(1, sizeof(struct timer_rec_s)); blob->timer = async_timer; async_timer->cib = cib; @@ -401,10 +400,7 @@ cib_client_init_transaction(cib_t *cib) } if (rc == pcmk_rc_ok) { - cib->transaction = create_xml_node(NULL, T_CIB_TRANSACTION); - if (cib->transaction == NULL) { - rc = ENOMEM; - } + cib->transaction = pcmk__xe_create(NULL, PCMK__XE_CIB_TRANSACTION); } if (rc != pcmk_rc_ok) { @@ -451,6 +447,21 @@ cib_client_end_transaction(cib_t *cib, bool commit, int call_options) return rc; } +static int +cib_client_fetch_schemas(cib_t *cib, xmlNode **output_data, const char *after_ver, + int call_options) +{ + xmlNode *data = pcmk__xe_create(NULL, PCMK__XA_SCHEMA); + int rc = pcmk_ok; + + crm_xml_add(data, PCMK_XA_VERSION, after_ver); + + rc = cib_internal_op(cib, PCMK__CIB_REQUEST_SCHEMAS, NULL, NULL, data, + output_data, call_options, NULL); + free_xml(data); + return rc; +} + static void cib_client_set_user(cib_t *cib, const char *user) { @@ -736,6 +747,8 @@ cib_new_variant(void) new_cib->cmds->set_user = cib_client_set_user; + new_cib->cmds->fetch_schemas = cib_client_fetch_schemas; + return new_cib; } diff --git a/lib/cib/cib_file.c b/lib/cib/cib_file.c index a279823..24bd029 100644 --- a/lib/cib/cib_file.c +++ b/lib/cib/cib_file.c @@ -1,6 +1,6 @@ /* * Original copyright 2004 International Business Machines - * Later changes copyright 2008-2023 the Pacemaker project contributors + * Later changes copyright 2008-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -24,7 +24,6 @@ #include <crm/crm.h> #include <crm/cib/internal.h> -#include <crm/msg_xml.h> #include <crm/common/ipc.h> #include <crm/common/xml.h> #include <crm/common/xml_internal.h> @@ -219,9 +218,11 @@ cib_file_process_request(cib_t *cib, xmlNode *request, xmlNode **output) int call_id = 0; int call_options = cib_none; - const char *op = crm_element_value(request, F_CIB_OPERATION); - const char *section = crm_element_value(request, F_CIB_SECTION); - xmlNode *data = get_message_xml(request, F_CIB_CALLDATA); + const char *op = crm_element_value(request, PCMK__XA_CIB_OP); + const char *section = crm_element_value(request, PCMK__XA_CIB_SECTION); + xmlNode *wrapper = pcmk__xe_first_child(request, PCMK__XE_CIB_CALLDATA, + NULL, NULL); + xmlNode *data = pcmk__xe_first_child(wrapper, NULL, NULL, NULL); bool changed = false; bool read_only = false; @@ -234,18 +235,18 @@ cib_file_process_request(cib_t *cib, xmlNode *request, xmlNode **output) cib__get_operation(op, &operation); op_function = file_get_op_function(operation); - crm_element_value_int(request, F_CIB_CALLID, &call_id); - crm_element_value_int(request, F_CIB_CALLOPTS, &call_options); + crm_element_value_int(request, PCMK__XA_CIB_CALLID, &call_id); + crm_element_value_int(request, PCMK__XA_CIB_CALLOPT, &call_options); read_only = !pcmk_is_set(operation->flags, cib__op_attr_modifies); // Mirror the logic in prepare_input() in pacemaker-based - if ((section != NULL) && pcmk__xe_is(data, XML_TAG_CIB)) { + if ((section != NULL) && pcmk__xe_is(data, PCMK_XE_CIB)) { data = pcmk_find_cib_element(data, section); } - rc = cib_perform_op(op, call_options, op_function, read_only, section, + rc = cib_perform_op(cib, op, call_options, op_function, read_only, section, request, data, true, &changed, &private->cib_xml, &result_cib, &cib_diff, output); @@ -257,7 +258,8 @@ cib_file_process_request(cib_t *cib, xmlNode *request, xmlNode **output) } if (rc == -pcmk_err_schema_validation) { - validate_xml_verbose(result_cib); + // Show validation errors to stderr + pcmk__validate_xml(result_cib, NULL, NULL, NULL); } else if ((rc == pcmk_ok) && !read_only) { pcmk__log_xml_patchset(LOG_DEBUG, cib_diff); @@ -327,8 +329,8 @@ cib_file_perform_op_delegate(cib_t *cib, const char *op, const char *host, if (rc != pcmk_ok) { return rc; } - crm_xml_add(request, XML_ACL_TAG_USER, user_name); - crm_xml_add(request, F_CIB_CLIENTID, private->id); + crm_xml_add(request, PCMK_XE_ACL_TARGET, user_name); + crm_xml_add(request, PCMK__XA_CIB_CLIENTID, private->id); if (pcmk_is_set(call_options, cib_transaction)) { rc = cib__extend_transaction(cib, request); @@ -339,7 +341,7 @@ cib_file_perform_op_delegate(cib_t *cib, const char *op, const char *host, if ((output_data != NULL) && (output != NULL)) { if (output->doc == private->cib_xml->doc) { - *output_data = copy_xml(output); + *output_data = pcmk__xml_copy(NULL, output); } else { *output_data = output; } @@ -383,21 +385,21 @@ load_file_cib(const char *filename, xmlNode **output) } /* Parse XML from file */ - root = filename2xml(filename); + root = pcmk__xml_read(filename); if (root == NULL) { return -pcmk_err_schema_validation; } /* Add a status section if not already present */ - if (find_xml_node(root, XML_CIB_TAG_STATUS, FALSE) == NULL) { - create_xml_node(root, XML_CIB_TAG_STATUS); + if (pcmk__xe_first_child(root, PCMK_XE_STATUS, NULL, NULL) == NULL) { + pcmk__xe_create(root, PCMK_XE_STATUS); } /* Validate XML against its specified schema */ - if (validate_xml(root, NULL, TRUE) == FALSE) { - const char *schema = crm_element_value(root, XML_ATTR_VALIDATION); + if (!pcmk__configured_schema_validates(root)) { + const char *schema = crm_element_value(root, PCMK_XA_VALIDATE_WITH); - crm_err("CIB does not validate against %s", schema); + crm_err("CIB does not validate against %s, or that schema is unknown", schema); free_xml(root); return -pcmk_err_schema_validation; } @@ -437,8 +439,8 @@ cib_file_signon(cib_t *cib, const char *name, enum cib_conn_type type) * \internal * \brief Write out the in-memory CIB to a live CIB file * - * param[in] cib_root Root of XML tree to write - * param[in,out] path Full path to file to write + * \param[in] cib_root Root of XML tree to write + * \param[in,out] path Full path to file to write * * \return 0 on success, -1 on failure */ @@ -547,10 +549,10 @@ cib_file_signoff(cib_t *cib) /* Otherwise, it's a simple write */ } else { - gboolean do_bzip = pcmk__ends_with_ext(private->filename, ".bz2"); + bool compress = pcmk__ends_with_ext(private->filename, ".bz2"); - if (write_xml_file(private->cib_xml, private->filename, - do_bzip) <= 0) { + if (pcmk__xml_write_file(private->cib_xml, private->filename, + compress, NULL) != pcmk_rc_ok) { rc = pcmk_err_generic; } } @@ -764,7 +766,7 @@ cib_file_read_and_verify(const char *filename, const char *sigfile, xmlNode **ro } /* Parse XML */ - local_root = filename2xml(filename); + local_root = pcmk__xml_read(filename); if (local_root == NULL) { crm_warn("Cluster configuration file %s is corrupt (unparseable as XML)", filename); return -pcmk_err_cib_corrupt; @@ -876,8 +878,8 @@ cib_file_backup(const char *cib_dirname, const char *cib_filename) * \internal * \brief Prepare CIB XML to be written to disk * - * Set num_updates to 0, set cib-last-written to the current timestamp, - * and strip out the status section. + * Set \c PCMK_XA_NUM_UPDATES to 0, set \c PCMK_XA_CIB_LAST_WRITTEN to the + * current timestamp, and strip out the status section. * * \param[in,out] root Root of CIB XML tree * @@ -889,16 +891,14 @@ cib_file_prepare_xml(xmlNode *root) xmlNode *cib_status_root = NULL; /* Always write out with num_updates=0 and current last-written timestamp */ - crm_xml_add(root, XML_ATTR_NUMUPDATES, "0"); + crm_xml_add(root, PCMK_XA_NUM_UPDATES, "0"); pcmk__xe_add_last_written(root); /* Delete status section before writing to file, because * we discard it on startup anyway, and users get confused by it */ - cib_status_root = find_xml_node(root, XML_CIB_TAG_STATUS, TRUE); - CRM_LOG_ASSERT(cib_status_root != NULL); - if (cib_status_root != NULL) { - free_xml(cib_status_root); - } + cib_status_root = pcmk__xe_first_child(root, PCMK_XE_STATUS, NULL, NULL); + CRM_CHECK(cib_status_root != NULL, return); + free_xml(cib_status_root); } /*! @@ -923,9 +923,8 @@ cib_file_write_with_digest(xmlNode *cib_root, const char *cib_dirname, char *digest = NULL; /* Detect CIB version for diagnostic purposes */ - const char *epoch = crm_element_value(cib_root, XML_ATTR_GENERATION); - const char *admin_epoch = crm_element_value(cib_root, - XML_ATTR_GENERATION_ADMIN); + const char *epoch = crm_element_value(cib_root, PCMK_XA_EPOCH); + const char *admin_epoch = crm_element_value(cib_root, PCMK_XA_ADMIN_EPOCH); /* Determine full CIB and signature pathnames */ char *cib_path = crm_strdup_printf("%s/%s", cib_dirname, cib_filename); @@ -935,9 +934,6 @@ cib_file_write_with_digest(xmlNode *cib_root, const char *cib_dirname, char *tmp_cib = crm_strdup_printf("%s/cib.XXXXXX", cib_dirname); char *tmp_digest = crm_strdup_printf("%s/cib.XXXXXX", cib_dirname); - CRM_ASSERT((cib_path != NULL) && (digest_path != NULL) - && (tmp_cib != NULL) && (tmp_digest != NULL)); - /* Ensure the admin didn't modify the existing CIB underneath us */ crm_trace("Reading cluster configuration file %s", cib_path); rc = cib_file_read_and_verify(cib_path, NULL, NULL); @@ -982,7 +978,7 @@ cib_file_write_with_digest(xmlNode *cib_root, const char *cib_dirname, } /* Write out the CIB */ - if (write_xml_fd(cib_root, tmp_cib, fd, FALSE) <= 0) { + if (pcmk__xml_write_fd(cib_root, tmp_cib, fd, false, NULL) != pcmk_rc_ok) { crm_err("Changes couldn't be written to %s", tmp_cib); exit_rc = pcmk_err_cib_save; goto cleanup; @@ -1063,11 +1059,13 @@ cib_file_process_transaction_requests(cib_t *cib, xmlNode *transaction) { cib_file_opaque_t *private = cib->variant_opaque; - for (xmlNode *request = first_named_child(transaction, T_CIB_COMMAND); - request != NULL; request = crm_next_same_xml(request)) { + for (xmlNode *request = pcmk__xe_first_child(transaction, + PCMK__XE_CIB_COMMAND, NULL, + NULL); + request != NULL; request = pcmk__xe_next_same(request)) { xmlNode *output = NULL; - const char *op = crm_element_value(request, F_CIB_OPERATION); + const char *op = crm_element_value(request, PCMK__XA_CIB_OP); int rc = cib_file_process_request(cib, request, &output); @@ -1111,7 +1109,7 @@ cib_file_commit_transaction(cib_t *cib, xmlNode *transaction, cib_file_opaque_t *private = cib->variant_opaque; xmlNode *saved_cib = private->cib_xml; - CRM_CHECK(pcmk__xe_is(transaction, T_CIB_TRANSACTION), + CRM_CHECK(pcmk__xe_is(transaction, PCMK__XE_CIB_TRANSACTION), return pcmk_rc_no_transaction); /* *result_cib should be a copy of private->cib_xml (created by @@ -1122,7 +1120,7 @@ cib_file_commit_transaction(cib_t *cib, xmlNode *transaction, * * cib_perform_op() will infer changes for the commit request at the end. */ CRM_CHECK((*result_cib != NULL) && (*result_cib != private->cib_xml), - *result_cib = copy_xml(private->cib_xml)); + *result_cib = pcmk__xml_copy(NULL, private->cib_xml)); crm_trace("Committing transaction for CIB file client (%s) on file '%s' to " "working CIB", @@ -1158,7 +1156,7 @@ cib_file_process_commit_transaction(const char *op, int options, xmlNode **result_cib, xmlNode **answer) { int rc = pcmk_rc_ok; - const char *client_id = crm_element_value(req, F_CIB_CLIENTID); + const char *client_id = crm_element_value(req, PCMK__XA_CIB_CLIENTID); cib_t *cib = NULL; CRM_CHECK(client_id != NULL, return -EINVAL); diff --git a/lib/cib/cib_native.c b/lib/cib/cib_native.c index c5e8b9e..b014223 100644 --- a/lib/cib/cib_native.c +++ b/lib/cib/cib_native.c @@ -1,6 +1,6 @@ /* * Copyright 2004 International Business Machines - * Later changes copyright 2004-2023 the Pacemaker project contributors + * Later changes copyright 2004-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -27,8 +27,8 @@ #include <crm/crm.h> #include <crm/cib/internal.h> -#include <crm/msg_xml.h> #include <crm/common/mainloop.h> +#include <crm/common/xml.h> typedef struct cib_native_opaque_s { char *token; @@ -94,26 +94,28 @@ cib_native_perform_op_delegate(cib_t *cib, const char *op, const char *host, if (!(call_options & cib_sync_call)) { crm_trace("Async call, returning %d", cib->call_id); - CRM_CHECK(cib->call_id != 0, return -ENOMSG); - free_xml(op_reply); - return cib->call_id; + CRM_CHECK(cib->call_id != 0, + rc = -ENOMSG; goto done); + rc = cib->call_id; + goto done; } rc = pcmk_ok; - crm_element_value_int(op_reply, F_CIB_CALLID, &reply_id); + crm_element_value_int(op_reply, PCMK__XA_CIB_CALLID, &reply_id); if (reply_id == cib->call_id) { - xmlNode *tmp = get_message_xml(op_reply, F_CIB_CALLDATA); + xmlNode *wrapper = pcmk__xe_first_child(op_reply, PCMK__XE_CIB_CALLDATA, + NULL, NULL); + xmlNode *tmp = pcmk__xe_first_child(wrapper, NULL, NULL, NULL); crm_trace("Synchronous reply %d received", reply_id); - if (crm_element_value_int(op_reply, F_CIB_RC, &rc) != 0) { + if (crm_element_value_int(op_reply, PCMK__XA_CIB_RC, &rc) != 0) { rc = -EPROTO; } if (output_data == NULL || (call_options & cib_discard_reply)) { crm_trace("Discarding reply"); - - } else if (tmp != NULL) { - *output_data = copy_xml(tmp); + } else { + *output_data = pcmk__xml_copy(NULL, tmp); } } else if (reply_id <= 0) { @@ -188,7 +190,7 @@ cib_native_dispatch_internal(const char *buffer, ssize_t length, return 0; } - msg = string2xml(buffer); + msg = pcmk__xml_parse(buffer); if (msg == NULL) { crm_warn("Received a NULL message from the CIB manager"); @@ -196,14 +198,14 @@ cib_native_dispatch_internal(const char *buffer, ssize_t length, } /* do callbacks */ - type = crm_element_value(msg, F_TYPE); + type = crm_element_value(msg, PCMK__XA_T); crm_trace("Activating %s callbacks...", type); crm_log_xml_explicit(msg, "cib-reply"); - if (pcmk__str_eq(type, T_CIB, pcmk__str_casei)) { + if (pcmk__str_eq(type, PCMK__VALUE_CIB, pcmk__str_none)) { cib_native_callback(cib, msg, 0, 0); - } else if (pcmk__str_eq(type, T_CIB_NOTIFY, pcmk__str_casei)) { + } else if (pcmk__str_eq(type, PCMK__VALUE_CIB_NOTIFY, pcmk__str_none)) { g_list_foreach(cib->notify_list, cib_native_notify, msg); } else { @@ -332,7 +334,7 @@ cib_native_signon_raw(cib_t *cib, const char *name, enum cib_conn_type type, if (crm_ipc_send(native->ipc, hello, crm_ipc_client_response, -1, &reply) > 0) { - const char *msg_type = crm_element_value(reply, F_CIB_OPERATION); + const char *msg_type = crm_element_value(reply, PCMK__XA_CIB_OP); crm_log_xml_trace(reply, "reg-reply"); @@ -343,7 +345,8 @@ cib_native_signon_raw(cib_t *cib, const char *name, enum cib_conn_type type, rc = -EPROTO; } else { - native->token = crm_element_value_copy(reply, F_CIB_CLIENTID); + native->token = crm_element_value_copy(reply, + PCMK__XA_CIB_CLIENTID); if (native->token == NULL) { rc = -EPROTO; } @@ -399,13 +402,13 @@ static int cib_native_register_notification(cib_t *cib, const char *callback, int enabled) { int rc = pcmk_ok; - xmlNode *notify_msg = create_xml_node(NULL, "cib-callback"); + xmlNode *notify_msg = pcmk__xe_create(NULL, PCMK__XE_CIB_CALLBACK); cib_native_opaque_t *native = cib->variant_opaque; if (cib->state != cib_disconnected) { - crm_xml_add(notify_msg, F_CIB_OPERATION, T_CIB_NOTIFY); - crm_xml_add(notify_msg, F_CIB_NOTIFY_TYPE, callback); - crm_xml_add_int(notify_msg, F_CIB_NOTIFY_ACTIVATE, enabled); + crm_xml_add(notify_msg, PCMK__XA_CIB_OP, PCMK__VALUE_CIB_NOTIFY); + crm_xml_add(notify_msg, PCMK__XA_CIB_NOTIFY_TYPE, callback); + crm_xml_add_int(notify_msg, PCMK__XA_CIB_NOTIFY_ACTIVATE, enabled); rc = crm_ipc_send(native->ipc, notify_msg, crm_ipc_client_response, 1000 * cib->call_timeout, NULL); if (rc <= 0) { diff --git a/lib/cib/cib_ops.c b/lib/cib/cib_ops.c index c324304..fd42317 100644 --- a/lib/cib/cib_ops.c +++ b/lib/cib/cib_ops.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. * @@ -24,7 +24,6 @@ #include <crm/crm.h> #include <crm/cib/internal.h> -#include <crm/msg_xml.h> #include <crm/common/xml.h> #include <crm/common/xml_internal.h> @@ -127,6 +126,9 @@ static const cib__operation_t cib_ops[] = { |cib__op_attr_writes_through |cib__op_attr_transaction }, + { + PCMK__CIB_REQUEST_SCHEMAS, cib__op_schemas, cib__op_attr_local + } }; /*! @@ -180,7 +182,7 @@ cib_process_query(const char *op, int options, const char *section, xmlNode * re CRM_CHECK(*answer == NULL, free_xml(*answer)); *answer = NULL; - if (pcmk__str_eq(XML_CIB_TAG_SECTION_ALL, section, pcmk__str_casei)) { + if (pcmk__str_eq(PCMK__XE_ALL, section, pcmk__str_casei)) { section = NULL; } @@ -190,10 +192,10 @@ cib_process_query(const char *op, int options, const char *section, xmlNode * re result = -ENXIO; } else if (options & cib_no_children) { - xmlNode *shallow = create_xml_node(*answer, + xmlNode *shallow = pcmk__xe_create(*answer, (const char *) obj_root->name); - copy_in_properties(shallow, obj_root); + pcmk__xe_copy_attrs(shallow, obj_root, pcmk__xaf_none); *answer = shallow; } else { @@ -222,8 +224,7 @@ update_counter(xmlNode *xml_obj, const char *field, bool reset) int_value = atoi(old_value); new_value = pcmk__itoa(++int_value); } else { - new_value = strdup("1"); - CRM_ASSERT(new_value != NULL); + new_value = pcmk__str_copy("1"); } crm_trace("Update %s from %s to %s", @@ -248,8 +249,8 @@ cib_process_erase(const char *op, int options, const char *section, xmlNode * re free_xml(*result_cib); } *result_cib = createEmptyCib(0); - copy_in_properties(*result_cib, existing_cib); - update_counter(*result_cib, XML_ATTR_GENERATION_ADMIN, false); + pcmk__xe_copy_attrs(*result_cib, existing_cib, pcmk__xaf_none); + update_counter(*result_cib, PCMK_XA_ADMIN_EPOCH, false); *answer = NULL; return result; @@ -261,29 +262,23 @@ cib_process_upgrade(const char *op, int options, const char *section, xmlNode * xmlNode ** answer) { int rc = 0; - int new_version = 0; - int current_version = 0; - int max_version = 0; - const char *max = crm_element_value(req, F_CIB_SCHEMA_MAX); - const char *value = crm_element_value(existing_cib, XML_ATTR_VALIDATION); + const char *max_schema = crm_element_value(req, PCMK__XA_CIB_SCHEMA_MAX); + const char *original_schema = NULL; + const char *new_schema = NULL; *answer = NULL; - crm_trace("Processing \"%s\" event with max=%s", op, max); - - if (value != NULL) { - current_version = get_schema_version(value); - } - - if (max) { - max_version = get_schema_version(max); - } - - rc = update_validation(result_cib, &new_version, max_version, TRUE, - !(options & cib_verbose)); - if (new_version > current_version) { - update_counter(*result_cib, XML_ATTR_GENERATION_ADMIN, false); - update_counter(*result_cib, XML_ATTR_GENERATION, true); - update_counter(*result_cib, XML_ATTR_NUMUPDATES, true); + crm_trace("Processing \"%s\" event with max=%s", op, max_schema); + + original_schema = crm_element_value(existing_cib, PCMK_XA_VALIDATE_WITH); + rc = pcmk__update_schema(result_cib, max_schema, true, + !pcmk_is_set(options, cib_verbose)); + rc = pcmk_rc2legacy(rc); + new_schema = crm_element_value(*result_cib, PCMK_XA_VALIDATE_WITH); + + if (pcmk__cmp_schemas_by_name(new_schema, original_schema) > 0) { + update_counter(*result_cib, PCMK_XA_ADMIN_EPOCH, false); + update_counter(*result_cib, PCMK_XA_EPOCH, true); + update_counter(*result_cib, PCMK_XA_NUM_UPDATES, true); return pcmk_ok; } @@ -297,10 +292,10 @@ cib_process_bump(const char *op, int options, const char *section, xmlNode * req int result = pcmk_ok; crm_trace("Processing %s for epoch='%s'", op, - pcmk__s(crm_element_value(existing_cib, XML_ATTR_GENERATION), "")); + pcmk__s(crm_element_value(existing_cib, PCMK_XA_EPOCH), "")); *answer = NULL; - update_counter(*result_cib, XML_ATTR_GENERATION, false); + update_counter(*result_cib, PCMK_XA_EPOCH, false); return result; } @@ -326,14 +321,14 @@ cib_process_replace(const char *op, int options, const char *section, xmlNode * return -EINVAL; } - if (pcmk__str_eq(XML_CIB_TAG_SECTION_ALL, section, pcmk__str_casei)) { + if (pcmk__str_eq(PCMK__XE_ALL, section, pcmk__str_casei)) { section = NULL; } else if (pcmk__xe_is(input, section)) { section = NULL; } - if (pcmk__xe_is(input, XML_TAG_CIB)) { + if (pcmk__xe_is(input, PCMK_XE_CIB)) { int updates = 0; int epoch = 0; int admin_epoch = 0; @@ -343,11 +338,12 @@ cib_process_replace(const char *op, int options, const char *section, xmlNode * int replace_admin_epoch = 0; const char *reason = NULL; - const char *peer = crm_element_value(req, F_ORIG); - const char *digest = crm_element_value(req, XML_ATTR_DIGEST); + const char *peer = crm_element_value(req, PCMK__XA_SRC); + const char *digest = crm_element_value(req, PCMK__XA_DIGEST); if (digest) { - const char *version = crm_element_value(req, XML_ATTR_CRM_VERSION); + const char *version = crm_element_value(req, + PCMK_XA_CRM_FEATURE_SET); char *digest_verify = calculate_xml_versioned_digest(input, FALSE, TRUE, version ? version : CRM_FEATURE_SET); @@ -370,19 +366,19 @@ cib_process_replace(const char *op, int options, const char *section, xmlNode * cib_version_details(input, &replace_admin_epoch, &replace_epoch, &replace_updates); if (replace_admin_epoch < admin_epoch) { - reason = XML_ATTR_GENERATION_ADMIN; + reason = PCMK_XA_ADMIN_EPOCH; } else if (replace_admin_epoch > admin_epoch) { /* no more checks */ } else if (replace_epoch < epoch) { - reason = XML_ATTR_GENERATION; + reason = PCMK_XA_EPOCH; } else if (replace_epoch > epoch) { /* no more checks */ } else if (replace_updates < updates) { - reason = XML_ATTR_NUMUPDATES; + reason = PCMK_XA_NUM_UPDATES; } if (reason != NULL) { @@ -400,23 +396,35 @@ cib_process_replace(const char *op, int options, const char *section, xmlNode * if (*result_cib != existing_cib) { free_xml(*result_cib); } - *result_cib = copy_xml(input); + *result_cib = pcmk__xml_copy(NULL, input); } else { xmlNode *obj_root = NULL; - gboolean ok = TRUE; obj_root = pcmk_find_cib_element(*result_cib, section); - ok = replace_xml_child(NULL, obj_root, input, FALSE); - if (ok == FALSE) { + result = pcmk__xe_replace_match(obj_root, input); + result = pcmk_rc2legacy(result); + if (result != pcmk_ok) { crm_trace("No matching object to replace"); - result = -ENXIO; } } return result; } +static int +delete_child(xmlNode *child, void *userdata) +{ + xmlNode *obj_root = userdata; + + if (pcmk__xe_delete_match(obj_root, child) != pcmk_rc_ok) { + crm_trace("No matching object to delete: %s=%s", + child->name, pcmk__xe_id(child)); + } + + return pcmk_rc_ok; +} + int cib_process_delete(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer) @@ -437,16 +445,9 @@ cib_process_delete(const char *op, int options, const char *section, xmlNode * r obj_root = pcmk_find_cib_element(*result_cib, section); if (pcmk__xe_is(input, section)) { - xmlNode *child = NULL; - for (child = pcmk__xml_first_child(input); child; - child = pcmk__xml_next(child)) { - if (replace_xml_child(NULL, obj_root, child, TRUE) == FALSE) { - crm_trace("No matching object to delete: %s=%s", child->name, ID(child)); - } - } - - } else if (replace_xml_child(NULL, obj_root, input, TRUE) == FALSE) { - crm_trace("No matching object to delete: %s=%s", input->name, ID(input)); + pcmk__xe_foreach_child(input, NULL, delete_child, obj_root); + } else { + delete_child(input, obj_root); } return pcmk_ok; @@ -457,6 +458,7 @@ cib_process_modify(const char *op, int options, const char *section, xmlNode * r xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer) { xmlNode *obj_root = NULL; + uint32_t flags = pcmk__xaf_none; crm_trace("Processing \"%s\" event", op); @@ -479,7 +481,7 @@ cib_process_modify(const char *op, int options, const char *section, xmlNode * r return -EINVAL; } - tmp_section = create_xml_node(NULL, section); + tmp_section = pcmk__xe_create(NULL, section); cib_process_xpath(PCMK__CIB_REQUEST_CREATE, 0, path, NULL, tmp_section, NULL, result_cib, answer); free_xml(tmp_section); @@ -489,9 +491,13 @@ cib_process_modify(const char *op, int options, const char *section, xmlNode * r CRM_CHECK(obj_root != NULL, return -EINVAL); - if (update_xml_child(obj_root, input) == FALSE) { + if (pcmk_is_set(options, cib_score_update)) { + flags |= pcmk__xaf_score_update; + } + + if (pcmk__xe_update_match(obj_root, input, flags) != pcmk_rc_ok) { if (options & cib_can_create) { - add_node_copy(obj_root, input); + pcmk__xml_copy(obj_root, input); } else { return -ENXIO; } @@ -522,123 +528,10 @@ cib_process_modify(const char *op, int options, const char *section, xmlNode * r } static int -update_cib_object(xmlNode * parent, xmlNode * update) -{ - int result = pcmk_ok; - xmlNode *target = NULL; - xmlNode *a_child = NULL; - const char *replace = NULL; - const char *object_id = NULL; - const char *object_name = NULL; - - CRM_CHECK(update != NULL, return -EINVAL); - CRM_CHECK(parent != NULL, return -EINVAL); - - object_name = (const char *) update->name; - CRM_CHECK(object_name != NULL, return -EINVAL); - - object_id = ID(update); - crm_trace("Processing update for <%s%s%s%s>", object_name, - ((object_id == NULL)? "" : " " XML_ATTR_ID "='"), - pcmk__s(object_id, ""), - ((object_id == NULL)? "" : "'")); - - if (object_id == NULL) { - /* placeholder object */ - target = find_xml_node(parent, object_name, FALSE); - - } else { - target = pcmk__xe_match(parent, object_name, XML_ATTR_ID, object_id); - } - - if (target == NULL) { - target = create_xml_node(parent, object_name); - } - - crm_trace("Found node <%s%s%s%s> to update", object_name, - ((object_id == NULL)? "" : " " XML_ATTR_ID "='"), - pcmk__s(object_id, ""), - ((object_id == NULL)? "" : "'")); - - // @COMPAT: XML_CIB_ATTR_REPLACE is unused internally. Remove at break. - replace = crm_element_value(update, XML_CIB_ATTR_REPLACE); - if (replace != NULL) { - int last = 0; - int len = strlen(replace); - - for (int lpc = 0; lpc <= len; ++lpc) { - if (replace[lpc] == ',' || replace[lpc] == 0) { - if (last != lpc) { - char *replace_item = strndup(replace + last, lpc - last); - xmlNode *remove = find_xml_node(target, replace_item, - FALSE); - - if (remove != NULL) { - crm_trace("Replacing node <%s> in <%s>", - replace_item, target->name); - free_xml(remove); - } - free(replace_item); - } - last = lpc + 1; - } - } - xml_remove_prop(update, XML_CIB_ATTR_REPLACE); - xml_remove_prop(target, XML_CIB_ATTR_REPLACE); - } - - copy_in_properties(target, update); - - if (xml_acl_denied(target)) { - crm_notice("Cannot update <%s " XML_ATTR_ID "=%s>", - pcmk__s(object_name, "<null>"), - pcmk__s(object_id, "<null>")); - return -EACCES; - } - - crm_trace("Processing children of <%s%s%s%s>", object_name, - ((object_id == NULL)? "" : " " XML_ATTR_ID "='"), - pcmk__s(object_id, ""), - ((object_id == NULL)? "" : "'")); - - for (a_child = pcmk__xml_first_child(update); a_child != NULL; - a_child = pcmk__xml_next(a_child)) { - int tmp_result = 0; - - crm_trace("Updating child <%s%s%s%s>", a_child->name, - ((ID(a_child) == NULL)? "" : " " XML_ATTR_ID "='"), - pcmk__s(ID(a_child), ""), ((ID(a_child) == NULL)? "" : "'")); - - tmp_result = update_cib_object(target, a_child); - - /* only the first error is likely to be interesting */ - if (tmp_result != pcmk_ok) { - crm_err("Error updating child <%s%s%s%s>", - a_child->name, - ((ID(a_child) == NULL)? "" : " " XML_ATTR_ID "='"), - pcmk__s(ID(a_child), ""), - ((ID(a_child) == NULL)? "" : "'")); - - if (result == pcmk_ok) { - result = tmp_result; - } - } - } - - crm_trace("Finished handling update for <%s%s%s%s>", object_name, - ((object_id == NULL)? "" : " " XML_ATTR_ID "='"), - pcmk__s(object_id, ""), - ((object_id == NULL)? "" : "'")); - - return result; -} - -static int add_cib_object(xmlNode * parent, xmlNode * new_obj) { const char *object_name = NULL; const char *object_id = NULL; - xmlNode *equiv_node = NULL; if ((parent == NULL) || (new_obj == NULL)) { return -EINVAL; @@ -649,24 +542,33 @@ add_cib_object(xmlNode * parent, xmlNode * new_obj) return -EINVAL; } - object_id = ID(new_obj); - - crm_trace("Processing creation of <%s%s%s%s>", object_name, - ((object_id == NULL)? "" : " " XML_ATTR_ID "='"), - pcmk__s(object_id, ""), - ((object_id == NULL)? "" : "'")); + object_id = pcmk__xe_id(new_obj); + if (pcmk__xe_first_child(parent, object_name, + ((object_id != NULL)? PCMK_XA_ID : NULL), + object_id)) { + return -EEXIST; + } - if (object_id == NULL) { - equiv_node = find_xml_node(parent, object_name, FALSE); + if (object_id != NULL) { + crm_trace("Processing creation of <%s " PCMK_XA_ID "='%s'>", + object_name, object_id); } else { - equiv_node = pcmk__xe_match(parent, object_name, XML_ATTR_ID, - object_id); - } - if (equiv_node != NULL) { - return -EEXIST; + crm_trace("Processing creation of <%s>", object_name); } - return update_cib_object(parent, new_obj); + /* @COMPAT PCMK__XA_REPLACE is deprecated since 2.1.6. Due to a legacy use + * case, PCMK__XA_REPLACE has special meaning and should not be included in + * the newly created object until we can break behavioral backward + * compatibility. + * + * At a compatibility break, drop this and drop the definition of + * PCMK__XA_REPLACE. Treat it like any other attribute. + */ + pcmk__xml_tree_foreach(new_obj, pcmk__xe_remove_attr_cb, + (void *) PCMK__XA_REPLACE); + + pcmk__xml_copy(parent, new_obj); + return pcmk_ok; } static bool @@ -681,14 +583,13 @@ update_results(xmlNode *failed, xmlNode *target, const char *operation, error_msg = pcmk_strerror(return_code); was_error = true; - xml_node = create_xml_node(failed, XML_FAIL_TAG_CIB); - add_node_copy(xml_node, target); + xml_node = pcmk__xe_create(failed, PCMK__XE_FAILED_UPDATE); + pcmk__xml_copy(xml_node, target); - crm_xml_add(xml_node, XML_FAILCIB_ATTR_ID, ID(target)); - crm_xml_add(xml_node, XML_FAILCIB_ATTR_OBJTYPE, - (const char *) target->name); - crm_xml_add(xml_node, XML_FAILCIB_ATTR_OP, operation); - crm_xml_add(xml_node, XML_FAILCIB_ATTR_REASON, error_msg); + crm_xml_add(xml_node, PCMK_XA_ID, pcmk__xe_id(target)); + crm_xml_add(xml_node, PCMK_XA_OBJECT_TYPE, (const char *) target->name); + crm_xml_add(xml_node, PCMK_XA_OPERATION, operation); + crm_xml_add(xml_node, PCMK_XA_REASON, error_msg); crm_warn("Action %s failed: %s (cde=%d)", operation, error_msg, return_code); @@ -707,13 +608,13 @@ cib_process_create(const char *op, int options, const char *section, xmlNode * r crm_trace("Processing %s for %s section", op, pcmk__s(section, "unspecified")); - if (pcmk__str_eq(XML_CIB_TAG_SECTION_ALL, section, pcmk__str_casei)) { + if (pcmk__str_eq(PCMK__XE_ALL, section, pcmk__str_casei)) { section = NULL; - } else if (pcmk__str_eq(XML_TAG_CIB, section, pcmk__str_casei)) { + } else if (pcmk__str_eq(section, PCMK_XE_CIB, pcmk__str_casei)) { section = NULL; - } else if (pcmk__xe_is(input, XML_TAG_CIB)) { + } else if (pcmk__xe_is(input, PCMK_XE_CIB)) { section = NULL; } @@ -729,7 +630,8 @@ cib_process_create(const char *op, int options, const char *section, xmlNode * r answer); } - failed = create_xml_node(NULL, XML_TAG_FAILED); + // @COMPAT Deprecated since 2.1.8 + failed = pcmk__xe_create(NULL, PCMK__XE_FAILED); update_section = pcmk_find_cib_element(*result_cib, section); if (pcmk__xe_is(input, section)) { @@ -770,7 +672,7 @@ cib_process_diff(const char *op, int options, const char *section, xmlNode * req const char *originator = NULL; if (req != NULL) { - originator = crm_element_value(req, F_ORIG); + originator = crm_element_value(req, PCMK__XA_SRC); } crm_trace("Processing \"%s\" event from %s%s", @@ -780,7 +682,7 @@ cib_process_diff(const char *op, int options, const char *section, xmlNode * req if (*result_cib != existing_cib) { free_xml(*result_cib); } - *result_cib = copy_xml(existing_cib); + *result_cib = pcmk__xml_copy(NULL, existing_cib); return xml_apply_patchset(*result_cib, input, TRUE); } @@ -797,7 +699,7 @@ cib__config_changed_v1(xmlNode *last, xmlNode *next, xmlNode **diff) CRM_ASSERT(diff != NULL); if (*diff == NULL && last != NULL && next != NULL) { - *diff = diff_xml_object(last, next, FALSE); + *diff = pcmk__diff_v1_xml_object(last, next, false); } if (*diff == NULL) { @@ -807,7 +709,7 @@ cib__config_changed_v1(xmlNode *last, xmlNode *next, xmlNode **diff) crm_element_value_int(*diff, PCMK_XA_FORMAT, &format); CRM_LOG_ASSERT(format == 1); - xpathObj = xpath_search(*diff, "//" XML_CIB_TAG_CONFIGURATION); + xpathObj = xpath_search(*diff, "//" PCMK_XE_CONFIGURATION); if (numXpathResults(xpathObj) > 0) { config_changes = true; goto done; @@ -815,38 +717,38 @@ cib__config_changed_v1(xmlNode *last, xmlNode *next, xmlNode **diff) freeXpathObject(xpathObj); /* - * Do not check XML_TAG_DIFF_ADDED "//" XML_TAG_CIB + * Do not check PCMK__XE_DIFF_ADDED "//" PCMK_XE_CIB * This always contains every field and would produce a false positive * every time if the checked value existed */ - xpathObj = xpath_search(*diff, "//" XML_TAG_DIFF_REMOVED "//" XML_TAG_CIB); + xpathObj = xpath_search(*diff, "//" PCMK__XE_DIFF_REMOVED "//" PCMK_XE_CIB); max = numXpathResults(xpathObj); for (lpc = 0; lpc < max; lpc++) { xmlNode *top = getXpathResult(xpathObj, lpc); - if (crm_element_value(top, XML_ATTR_GENERATION) != NULL) { + if (crm_element_value(top, PCMK_XA_EPOCH) != NULL) { config_changes = true; goto done; } - if (crm_element_value(top, XML_ATTR_GENERATION_ADMIN) != NULL) { + if (crm_element_value(top, PCMK_XA_ADMIN_EPOCH) != NULL) { config_changes = true; goto done; } - if (crm_element_value(top, XML_ATTR_VALIDATION) != NULL) { + if (crm_element_value(top, PCMK_XA_VALIDATE_WITH) != NULL) { config_changes = true; goto done; } - if (crm_element_value(top, XML_ATTR_CRM_VERSION) != NULL) { + if (crm_element_value(top, PCMK_XA_CRM_FEATURE_SET) != NULL) { config_changes = true; goto done; } - if (crm_element_value(top, "remote-clear-port") != NULL) { + if (crm_element_value(top, PCMK_XA_REMOTE_CLEAR_PORT) != NULL) { config_changes = true; goto done; } - if (crm_element_value(top, "remote-tls-port") != NULL) { + if (crm_element_value(top, PCMK_XA_REMOTE_TLS_PORT) != NULL) { config_changes = true; goto done; } @@ -889,7 +791,7 @@ cib_process_xpath(const char *op, int options, const char *section, } else if (is_query) { if (max > 1) { - *answer = create_xml_node(NULL, "xpath-query"); + *answer = pcmk__xe_create(NULL, PCMK__XE_XPATH_QUERY); } } @@ -924,23 +826,29 @@ cib_process_xpath(const char *op, int options, const char *section, } } else if (pcmk__str_eq(op, PCMK__CIB_REQUEST_MODIFY, pcmk__str_none)) { - if (update_xml_child(match, input) == FALSE) { + uint32_t flags = pcmk__xaf_none; + + if (pcmk_is_set(options, cib_score_update)) { + flags |= pcmk__xaf_score_update; + } + + if (pcmk__xe_update_match(match, input, flags) != pcmk_rc_ok) { rc = -ENXIO; } else if ((options & cib_multiple) == 0) { break; } } else if (pcmk__str_eq(op, PCMK__CIB_REQUEST_CREATE, pcmk__str_none)) { - add_node_copy(match, input); + pcmk__xml_copy(match, input); break; } else if (pcmk__str_eq(op, PCMK__CIB_REQUEST_QUERY, pcmk__str_none)) { if (options & cib_no_children) { - xmlNode *shallow = create_xml_node(*answer, + xmlNode *shallow = pcmk__xe_create(*answer, (const char *) match->name); - copy_in_properties(shallow, match); + pcmk__xe_copy_attrs(shallow, match, pcmk__xaf_none); if (*answer == NULL) { *answer = shallow; @@ -951,11 +859,11 @@ cib_process_xpath(const char *op, int options, const char *section, xmlNode *parent = match; while (parent && parent->type == XML_ELEMENT_NODE) { - const char *id = crm_element_value(parent, XML_ATTR_ID); + const char *id = crm_element_value(parent, PCMK_XA_ID); char *new_path = NULL; if (id) { - new_path = crm_strdup_printf("/%s[@" XML_ATTR_ID "='%s']" + new_path = crm_strdup_printf("/%s[@" PCMK_XA_ID "='%s']" "%s", parent->name, id, pcmk__s(path, "")); @@ -970,14 +878,14 @@ cib_process_xpath(const char *op, int options, const char *section, crm_trace("Got: %s", path); if (*answer == NULL) { - *answer = create_xml_node(NULL, "xpath-query"); + *answer = pcmk__xe_create(NULL, PCMK__XE_XPATH_QUERY); } - parent = create_xml_node(*answer, "xpath-query-path"); - crm_xml_add(parent, XML_ATTR_ID, path); + parent = pcmk__xe_create(*answer, PCMK__XE_XPATH_QUERY_PATH); + crm_xml_add(parent, PCMK_XA_ID, path); free(path); } else if (*answer) { - add_node_copy(*answer, match); + pcmk__xml_copy(*answer, match); } else { *answer = match; @@ -988,9 +896,7 @@ cib_process_xpath(const char *op, int options, const char *section, xmlNode *parent = match->parent; free_xml(match); - if (input != NULL) { - add_node_copy(parent, input); - } + pcmk__xml_copy(parent, input); if ((options & cib_multiple) == 0) { break; diff --git a/lib/cib/cib_remote.c b/lib/cib/cib_remote.c index 77479d7..fa558a5 100644 --- a/lib/cib/cib_remote.c +++ b/lib/cib/cib_remote.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2023 the Pacemaker project contributors + * Copyright 2008-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -22,9 +22,9 @@ #include <crm/crm.h> #include <crm/cib/internal.h> -#include <crm/msg_xml.h> #include <crm/common/ipc_internal.h> #include <crm/common/mainloop.h> +#include <crm/common/xml.h> #include <crm/common/remote_internal.h> #include <crm/common/output_internal.h> @@ -126,7 +126,7 @@ cib_remote_perform_op(cib_t *cib, const char *op, const char *host, break; } - crm_element_value_int(op_reply, F_CIB_CALLID, &reply_id); + crm_element_value_int(op_reply, PCMK__XA_CIB_CALLID, &reply_id); if (reply_id == msg_id) { break; @@ -167,7 +167,7 @@ cib_remote_perform_op(cib_t *cib, const char *op, const char *host, crm_trace("Synchronous reply received"); /* Start processing the reply... */ - if (crm_element_value_int(op_reply, F_CIB_RC, &rc) != 0) { + if (crm_element_value_int(op_reply, PCMK__XA_CIB_RC, &rc) != 0) { rc = -EPROTO; } @@ -189,12 +189,14 @@ cib_remote_perform_op(cib_t *cib, const char *op, const char *host, /* do nothing more */ } else if (!(call_options & cib_discard_reply)) { - xmlNode *tmp = get_message_xml(op_reply, F_CIB_CALLDATA); + xmlNode *wrapper = pcmk__xe_first_child(op_reply, PCMK__XE_CIB_CALLDATA, + NULL, NULL); + xmlNode *tmp = pcmk__xe_first_child(wrapper, NULL, NULL, NULL); if (tmp == NULL) { crm_trace("No output in reply to \"%s\" command %d", op, cib->call_id - 1); } else { - *output_data = copy_xml(tmp); + *output_data = pcmk__xml_copy(NULL, tmp); } } @@ -218,14 +220,14 @@ cib_remote_callback_dispatch(gpointer user_data) msg = pcmk__remote_message_xml(&private->callback); while (msg) { - const char *type = crm_element_value(msg, F_TYPE); + const char *type = crm_element_value(msg, PCMK__XA_T); crm_trace("Activating %s callbacks...", type); - if (pcmk__str_eq(type, T_CIB, pcmk__str_casei)) { + if (pcmk__str_eq(type, PCMK__VALUE_CIB, pcmk__str_none)) { cib_native_callback(cib, msg, 0, 0); - } else if (pcmk__str_eq(type, T_CIB_NOTIFY, pcmk__str_casei)) { + } else if (pcmk__str_eq(type, PCMK__VALUE_CIB_NOTIFY, pcmk__str_none)) { g_list_foreach(cib->notify_list, cib_native_notify, msg); } else { @@ -380,11 +382,11 @@ cib_tls_signon(cib_t *cib, pcmk__remote_t *connection, gboolean event_channel) } /* login to server */ - login = create_xml_node(NULL, T_CIB_COMMAND); - crm_xml_add(login, "op", "authenticate"); - crm_xml_add(login, "user", private->user); - crm_xml_add(login, "password", private->passwd); - crm_xml_add(login, "hidden", "password"); + login = pcmk__xe_create(NULL, PCMK__XE_CIB_COMMAND); + crm_xml_add(login, PCMK_XA_OP, "authenticate"); + crm_xml_add(login, PCMK_XA_USER, private->user); + crm_xml_add(login, PCMK__XA_PASSWORD, private->passwd); + crm_xml_add(login, PCMK__XA_HIDDEN, PCMK__VALUE_PASSWORD); pcmk__remote_send_xml(connection, login); free_xml(login); @@ -402,8 +404,9 @@ cib_tls_signon(cib_t *cib, pcmk__remote_t *connection, gboolean event_channel) } else { /* grab the token */ - const char *msg_type = crm_element_value(answer, F_CIB_OPERATION); - const char *tmp_ticket = crm_element_value(answer, F_CIB_CLIENTID); + const char *msg_type = crm_element_value(answer, PCMK__XA_CIB_OP); + const char *tmp_ticket = crm_element_value(answer, + PCMK__XA_CIB_CLIENTID); if (!pcmk__str_eq(msg_type, CRM_OP_REGISTER, pcmk__str_casei)) { crm_err("Invalid registration message: %s", msg_type); @@ -538,12 +541,12 @@ cib_remote_inputfd(cib_t * cib) static int cib_remote_register_notification(cib_t * cib, const char *callback, int enabled) { - xmlNode *notify_msg = create_xml_node(NULL, T_CIB_COMMAND); + xmlNode *notify_msg = pcmk__xe_create(NULL, PCMK__XE_CIB_COMMAND); cib_remote_opaque_t *private = cib->variant_opaque; - crm_xml_add(notify_msg, F_CIB_OPERATION, T_CIB_NOTIFY); - crm_xml_add(notify_msg, F_CIB_NOTIFY_TYPE, callback); - crm_xml_add_int(notify_msg, F_CIB_NOTIFY_ACTIVATE, enabled); + crm_xml_add(notify_msg, PCMK__XA_CIB_OP, PCMK__VALUE_CIB_NOTIFY); + crm_xml_add(notify_msg, PCMK__XA_CIB_NOTIFY_TYPE, callback); + crm_xml_add_int(notify_msg, PCMK__XA_CIB_NOTIFY_ACTIVATE, enabled); pcmk__remote_send_xml(&private->callback, notify_msg); free_xml(notify_msg); return pcmk_ok; @@ -610,10 +613,9 @@ cib_remote_new(const char *server, const char *user, const char *passwd, int por cib->variant = cib_remote; cib->variant_opaque = private; - pcmk__str_update(&private->server, server); - pcmk__str_update(&private->user, user); - pcmk__str_update(&private->passwd, passwd); - + private->server = pcmk__str_copy(server); + private->user = pcmk__str_copy(user); + private->passwd = pcmk__str_copy(passwd); private->port = port; private->encrypted = encrypted; diff --git a/lib/cib/cib_utils.c b/lib/cib/cib_utils.c index 0082eef..7ef3789 100644 --- a/lib/cib/cib_utils.c +++ b/lib/cib/cib_utils.c @@ -1,6 +1,6 @@ /* * Original copyright 2004 International Business Machines - * Later changes copyright 2008-2023 the Pacemaker project contributors + * Later changes copyright 2008-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -19,27 +19,11 @@ #include <crm/crm.h> #include <crm/cib/internal.h> -#include <crm/msg_xml.h> #include <crm/common/cib_internal.h> #include <crm/common/xml.h> #include <crm/common/xml_internal.h> #include <crm/pengine/rules.h> -xmlNode * -cib_get_generation(cib_t * cib) -{ - xmlNode *the_cib = NULL; - xmlNode *generation = create_xml_node(NULL, XML_CIB_TAG_GENERATION_TUPPLE); - - cib->cmds->query(cib, NULL, &the_cib, cib_scope_local | cib_sync_call); - if (the_cib != NULL) { - copy_in_properties(generation, the_cib); - free_xml(the_cib); - } - - return generation; -} - gboolean cib_version_details(xmlNode * cib, int *admin_epoch, int *epoch, int *updates) { @@ -51,9 +35,9 @@ cib_version_details(xmlNode * cib, int *admin_epoch, int *epoch, int *updates) return FALSE; } else { - crm_element_value_int(cib, XML_ATTR_GENERATION, epoch); - crm_element_value_int(cib, XML_ATTR_NUMUPDATES, updates); - crm_element_value_int(cib, XML_ATTR_GENERATION_ADMIN, admin_epoch); + crm_element_value_int(cib, PCMK_XA_EPOCH, epoch); + crm_element_value_int(cib, PCMK_XA_NUM_UPDATES, updates); + crm_element_value_int(cib, PCMK_XA_ADMIN_EPOCH, admin_epoch); } return TRUE; } @@ -91,6 +75,7 @@ int cib__get_notify_patchset(const xmlNode *msg, const xmlNode **patchset) { int rc = pcmk_err_generic; + xmlNode *wrapper = NULL; CRM_ASSERT(patchset != NULL); *patchset = NULL; @@ -100,14 +85,17 @@ cib__get_notify_patchset(const xmlNode *msg, const xmlNode **patchset) return ENOMSG; } - if ((crm_element_value_int(msg, F_CIB_RC, &rc) != 0) || (rc != pcmk_ok)) { + if ((crm_element_value_int(msg, PCMK__XA_CIB_RC, &rc) != 0) + || (rc != pcmk_ok)) { + crm_warn("Ignore failed CIB update: %s " CRM_XS " rc=%d", pcmk_strerror(rc), rc); crm_log_xml_debug(msg, "failed"); return pcmk_legacy2rc(rc); } - *patchset = get_message_xml(msg, F_CIB_UPDATE_RESULT); + wrapper = pcmk__xe_first_child(msg, PCMK__XE_CIB_UPDATE_RESULT, NULL, NULL); + *patchset = pcmk__xe_first_child(wrapper, NULL, NULL, NULL); if (*patchset == NULL) { crm_err("CIB diff notification received with no patchset"); @@ -116,7 +104,7 @@ cib__get_notify_patchset(const xmlNode *msg, const xmlNode **patchset) return pcmk_rc_ok; } -#define XPATH_DIFF_V1 "//" F_CIB_UPDATE_RESULT "//" XML_TAG_DIFF_ADDED +#define XPATH_DIFF_V1 "//" PCMK__XE_CIB_UPDATE_RESULT "//" PCMK__XE_DIFF_ADDED /*! * \internal @@ -124,7 +112,7 @@ cib__get_notify_patchset(const xmlNode *msg, const xmlNode **patchset) * * \param[in] patchset CIB XML patchset * \param[in] element XML tag of CIB element to check (\c NULL is equivalent - * to \c XML_TAG_CIB) + * to \c PCMK_XE_CIB) * * \return \c true if \p element was modified, or \c false otherwise */ @@ -132,7 +120,7 @@ static bool element_in_patchset_v1(const xmlNode *patchset, const char *element) { char *xpath = crm_strdup_printf(XPATH_DIFF_V1 "//%s", - pcmk__s(element, XML_TAG_CIB)); + pcmk__s(element, PCMK_XE_CIB)); xmlXPathObject *xpath_obj = xpath_search(patchset, xpath); free(xpath); @@ -150,7 +138,7 @@ element_in_patchset_v1(const xmlNode *patchset, const char *element) * * \param[in] patchset CIB XML patchset * \param[in] element XML tag of CIB element to check (\c NULL is equivalent - * to \c XML_TAG_CIB). Supported values include any CIB + * to \c PCMK_XE_CIB). Supported values include any CIB * element supported by \c pcmk__cib_abs_xpath_for(). * * \return \c true if \p element was modified, or \c false otherwise @@ -168,11 +156,12 @@ element_in_patchset_v2(const xmlNode *patchset, const char *element) // Matches if and only if element_xpath is part of a changed path element_regex = crm_strdup_printf("^%s(/|$)", element_xpath); - for (const xmlNode *change = first_named_child(patchset, XML_DIFF_CHANGE); - change != NULL; change = crm_next_same_xml(change)) { + for (const xmlNode *change = pcmk__xe_first_child(patchset, PCMK_XE_CHANGE, + NULL, NULL); + change != NULL; change = pcmk__xe_next_same(change)) { - const char *op = crm_element_value(change, F_CIB_OPERATION); - const char *diff_xpath = crm_element_value(change, XML_DIFF_PATH); + const char *op = crm_element_value(change, PCMK__XA_CIB_OP); + const char *diff_xpath = crm_element_value(change, PCMK_XA_PATH); if (pcmk__str_eq(diff_xpath, element_regex, pcmk__str_regex)) { // Change to an existing element @@ -180,9 +169,10 @@ element_in_patchset_v2(const xmlNode *patchset, const char *element) break; } - if (pcmk__str_eq(op, "create", pcmk__str_none) + if (pcmk__str_eq(op, PCMK_VALUE_CREATE, pcmk__str_none) && pcmk__str_eq(diff_xpath, parent_xpath, pcmk__str_none) - && pcmk__xe_is(pcmk__xml_first_child(change), element)) { + && pcmk__xe_is(pcmk__xe_first_child(change, NULL, NULL, NULL), + element)) { // Newly added element rc = true; @@ -200,7 +190,7 @@ element_in_patchset_v2(const xmlNode *patchset, const char *element) * * \param[in] patchset CIB XML patchset * \param[in] element XML tag of CIB element to check (\c NULL is equivalent - * to \c XML_TAG_CIB). Supported values include any CIB + * to \c PCMK_XE_CIB). Supported values include any CIB * element supported by \c pcmk__cib_abs_xpath_for(). * * \return \c true if \p element was modified, or \c false otherwise @@ -229,7 +219,7 @@ cib__element_in_patchset(const xmlNode *patchset, const char *element) /*! * \brief Create XML for a new (empty) CIB * - * \param[in] cib_epoch What to use as "epoch" CIB property + * \param[in] cib_epoch What to use as \c PCMK_XA_EPOCH CIB attribute * * \return Newly created XML for empty CIB * \note It is the caller's responsibility to free the result with free_xml(). @@ -239,32 +229,32 @@ createEmptyCib(int cib_epoch) { xmlNode *cib_root = NULL, *config = NULL; - cib_root = create_xml_node(NULL, XML_TAG_CIB); - crm_xml_add(cib_root, XML_ATTR_CRM_VERSION, CRM_FEATURE_SET); - crm_xml_add(cib_root, XML_ATTR_VALIDATION, xml_latest_schema()); + cib_root = pcmk__xe_create(NULL, PCMK_XE_CIB); + crm_xml_add(cib_root, PCMK_XA_CRM_FEATURE_SET, CRM_FEATURE_SET); + crm_xml_add(cib_root, PCMK_XA_VALIDATE_WITH, pcmk__highest_schema_name()); - crm_xml_add_int(cib_root, XML_ATTR_GENERATION, cib_epoch); - crm_xml_add_int(cib_root, XML_ATTR_NUMUPDATES, 0); - crm_xml_add_int(cib_root, XML_ATTR_GENERATION_ADMIN, 0); + crm_xml_add_int(cib_root, PCMK_XA_EPOCH, cib_epoch); + crm_xml_add_int(cib_root, PCMK_XA_NUM_UPDATES, 0); + crm_xml_add_int(cib_root, PCMK_XA_ADMIN_EPOCH, 0); - config = create_xml_node(cib_root, XML_CIB_TAG_CONFIGURATION); - create_xml_node(cib_root, XML_CIB_TAG_STATUS); + config = pcmk__xe_create(cib_root, PCMK_XE_CONFIGURATION); + pcmk__xe_create(cib_root, PCMK_XE_STATUS); - create_xml_node(config, XML_CIB_TAG_CRMCONFIG); - create_xml_node(config, XML_CIB_TAG_NODES); - create_xml_node(config, XML_CIB_TAG_RESOURCES); - create_xml_node(config, XML_CIB_TAG_CONSTRAINTS); + pcmk__xe_create(config, PCMK_XE_CRM_CONFIG); + pcmk__xe_create(config, PCMK_XE_NODES); + pcmk__xe_create(config, PCMK_XE_RESOURCES); + pcmk__xe_create(config, PCMK_XE_CONSTRAINTS); #if PCMK__RESOURCE_STICKINESS_DEFAULT != 0 { - xmlNode *rsc_defaults = create_xml_node(config, XML_CIB_TAG_RSCCONFIG); - xmlNode *meta = create_xml_node(rsc_defaults, XML_TAG_META_SETS); - xmlNode *nvpair = create_xml_node(meta, XML_CIB_TAG_NVPAIR); - - crm_xml_add(meta, XML_ATTR_ID, "build-resource-defaults"); - crm_xml_add(nvpair, XML_ATTR_ID, "build-" XML_RSC_ATTR_STICKINESS); - crm_xml_add(nvpair, XML_NVPAIR_ATTR_NAME, XML_RSC_ATTR_STICKINESS); - crm_xml_add_int(nvpair, XML_NVPAIR_ATTR_VALUE, + xmlNode *rsc_defaults = pcmk__xe_create(config, PCMK_XE_RSC_DEFAULTS); + xmlNode *meta = pcmk__xe_create(rsc_defaults, PCMK_XE_META_ATTRIBUTES); + xmlNode *nvpair = pcmk__xe_create(meta, PCMK_XE_NVPAIR); + + crm_xml_add(meta, PCMK_XA_ID, "build-resource-defaults"); + crm_xml_add(nvpair, PCMK_XA_ID, "build-" PCMK_META_RESOURCE_STICKINESS); + crm_xml_add(nvpair, PCMK_XA_NAME, PCMK_META_RESOURCE_STICKINESS); + crm_xml_add_int(nvpair, PCMK_XA_VALUE, PCMK__RESOURCE_STICKINESS_DEFAULT); } #endif @@ -281,7 +271,7 @@ cib_acl_enabled(xmlNode *xml, const char *user) GHashTable *options = pcmk__strkey_table(free, free); cib_read_config(options, xml); - value = cib_pref(options, "enable-acl"); + value = pcmk__cluster_option(options, PCMK_OPT_ENABLE_ACL); rc = crm_is_true(value); g_hash_table_destroy(options); } @@ -324,7 +314,7 @@ should_copy_cib(const char *op, const char *section, int call_options) return false; } - if (pcmk__str_eq(section, XML_CIB_TAG_STATUS, pcmk__str_none)) { + if (pcmk__str_eq(section, PCMK_XE_STATUS, pcmk__str_none)) { /* Copying large CIBs accounts for a huge percentage of our CIB usage, * and this avoids some of it. * @@ -339,11 +329,10 @@ should_copy_cib(const char *op, const char *section, int call_options) } int -cib_perform_op(const char *op, int call_options, cib__op_fn_t fn, bool is_query, - const char *section, xmlNode *req, xmlNode *input, - bool manage_counters, bool *config_changed, - xmlNode **current_cib, xmlNode **result_cib, xmlNode **diff, - xmlNode **output) +cib_perform_op(cib_t *cib, const char *op, int call_options, cib__op_fn_t fn, + bool is_query, const char *section, xmlNode *req, xmlNode *input, + bool manage_counters, bool *config_changed, xmlNode **current_cib, + xmlNode **result_cib, xmlNode **diff, xmlNode **output) { int rc = pcmk_ok; bool check_schema = true; @@ -353,8 +342,7 @@ cib_perform_op(const char *op, int call_options, cib__op_fn_t fn, bool is_query, xmlNode *patchset_cib = NULL; xmlNode *local_diff = NULL; - const char *new_version = NULL; - const char *user = crm_element_value(req, F_CIB_USER); + const char *user = crm_element_value(req, PCMK__XA_CIB_USER); bool with_digest = false; crm_trace("Begin %s%s%s op", @@ -406,11 +394,11 @@ cib_perform_op(const char *op, int call_options, cib__op_fn_t fn, bool is_query, } else if(cib_filtered && (*output)->doc == cib_filtered->doc) { /* We're about to free the document of which *output is a part */ - *output = copy_xml(*output); + *output = pcmk__xml_copy(NULL, *output); } else if ((*output)->doc == (*current_cib)->doc) { /* Give them a copy they can free */ - *output = copy_xml(*output); + *output = pcmk__xml_copy(NULL, *output); } free_xml(cib_filtered); @@ -425,8 +413,8 @@ cib_perform_op(const char *op, int call_options, cib__op_fn_t fn, bool is_query, scratch = *current_cib; // Make a copy of the top-level element to store version details - top = create_xml_node(NULL, (const char *) scratch->name); - copy_in_properties(top, scratch); + top = pcmk__xe_create(NULL, (const char *) scratch->name); + pcmk__xe_copy_attrs(top, scratch, pcmk__xaf_none); patchset_cib = top; xml_track_changes(scratch, user, NULL, cib_acl_enabled(scratch, user)); @@ -438,7 +426,7 @@ cib_perform_op(const char *op, int call_options, cib__op_fn_t fn, bool is_query, *current_cib = scratch; } else { - scratch = copy_xml(*current_cib); + scratch = pcmk__xml_copy(NULL, *current_cib); patchset_cib = *current_cib; xml_track_changes(scratch, user, NULL, cib_acl_enabled(scratch, user)); @@ -469,13 +457,18 @@ cib_perform_op(const char *op, int call_options, cib__op_fn_t fn, bool is_query, goto done; } - if (scratch) { - new_version = crm_element_value(scratch, XML_ATTR_CRM_VERSION); - - if (new_version && compare_version(new_version, CRM_FEATURE_SET) > 0) { - crm_err("Discarding update with feature set '%s' greater than our own '%s'", - new_version, CRM_FEATURE_SET); - rc = -EPROTONOSUPPORT; + /* If the CIB is from a file, we don't need to check that the feature set is + * supported. All we care about in that case is the schema version, which + * is checked elsewhere. + */ + if (scratch && (cib == NULL || cib->variant != cib_file)) { + const char *new_version = crm_element_value(scratch, PCMK_XA_CRM_FEATURE_SET); + + rc = pcmk__check_feature_set(new_version); + if (rc != pcmk_rc_ok) { + pcmk__config_err("Discarding update with feature set '%s' greater than our own '%s'", + new_version, CRM_FEATURE_SET); + rc = pcmk_rc2legacy(rc); goto done; } } @@ -484,22 +477,22 @@ cib_perform_op(const char *op, int call_options, cib__op_fn_t fn, bool is_query, int old = 0; int new = 0; - crm_element_value_int(scratch, XML_ATTR_GENERATION_ADMIN, &new); - crm_element_value_int(patchset_cib, XML_ATTR_GENERATION_ADMIN, &old); + crm_element_value_int(scratch, PCMK_XA_ADMIN_EPOCH, &new); + crm_element_value_int(patchset_cib, PCMK_XA_ADMIN_EPOCH, &old); if (old > new) { crm_err("%s went backwards: %d -> %d (Opts: %#x)", - XML_ATTR_GENERATION_ADMIN, old, new, call_options); + PCMK_XA_ADMIN_EPOCH, old, new, call_options); crm_log_xml_warn(req, "Bad Op"); crm_log_xml_warn(input, "Bad Data"); rc = -pcmk_err_old_data; } else if (old == new) { - crm_element_value_int(scratch, XML_ATTR_GENERATION, &new); - crm_element_value_int(patchset_cib, XML_ATTR_GENERATION, &old); + crm_element_value_int(scratch, PCMK_XA_EPOCH, &new); + crm_element_value_int(patchset_cib, PCMK_XA_EPOCH, &old); if (old > new) { crm_err("%s went backwards: %d -> %d (Opts: %#x)", - XML_ATTR_GENERATION, old, new, call_options); + PCMK_XA_EPOCH, old, new, call_options); crm_log_xml_warn(req, "Bad Op"); crm_log_xml_warn(input, "Bad Data"); rc = -pcmk_err_old_data; @@ -509,10 +502,10 @@ cib_perform_op(const char *op, int call_options, cib__op_fn_t fn, bool is_query, crm_trace("Massaging CIB contents"); pcmk__strip_xml_text(scratch); - fix_plus_plus_recursive(scratch); if (!make_copy) { - /* At this point, patchset_cib is just the "cib" tag and its properties. + /* At this point, patchset_cib is just the PCMK_XE_CIB tag and its + * properties. * * The v1 format would barf on this, but we know the v2 patch * format only needs it for the top-level version fields @@ -549,7 +542,7 @@ cib_perform_op(const char *op, int call_options, cib__op_fn_t fn, bool is_query, // Validate the calculated patch set int test_rc = pcmk_ok; int format = 1; - xmlNode *cib_copy = copy_xml(patchset_cib); + xmlNode *cib_copy = pcmk__xml_copy(NULL, patchset_cib); crm_element_value_int(local_diff, PCMK_XA_FORMAT, &format); test_rc = xml_apply_patchset(cib_copy, local_diff, @@ -571,7 +564,7 @@ cib_perform_op(const char *op, int call_options, cib__op_fn_t fn, bool is_query, ); } - if (pcmk__str_eq(section, XML_CIB_TAG_STATUS, pcmk__str_casei)) { + if (pcmk__str_eq(section, PCMK_XE_STATUS, pcmk__str_casei)) { /* Throttle the amount of costly validation we perform due to status updates * a) we don't really care whats in the status section * b) we don't validate any of its contents at the moment anyway @@ -583,59 +576,53 @@ cib_perform_op(const char *op, int call_options, cib__op_fn_t fn, bool is_query, * Exceptions, anything in: static filter_t filter[] = { - { 0, XML_ATTR_ORIGIN }, - { 0, XML_CIB_ATTR_WRITTEN }, - { 0, XML_ATTR_UPDATE_ORIG }, - { 0, XML_ATTR_UPDATE_CLIENT }, - { 0, XML_ATTR_UPDATE_USER }, + { 0, PCMK_XA_CRM_DEBUG_ORIGIN }, + { 0, PCMK_XA_CIB_LAST_WRITTEN }, + { 0, PCMK_XA_UPDATE_ORIGIN }, + { 0, PCMK_XA_UPDATE_CLIENT }, + { 0, PCMK_XA_UPDATE_USER }, }; */ if (*config_changed && !pcmk_is_set(call_options, cib_no_mtime)) { - const char *schema = crm_element_value(scratch, XML_ATTR_VALIDATION); + const char *schema = crm_element_value(scratch, PCMK_XA_VALIDATE_WITH); pcmk__xe_add_last_written(scratch); - if (schema) { - static int minimum_schema = 0; - int current_schema = get_schema_version(schema); + pcmk__warn_if_schema_deprecated(schema); - if (minimum_schema == 0) { - minimum_schema = get_schema_version("pacemaker-1.2"); + /* Make values of origin, client, and user in scratch match + * the ones in req (if the schema allows the attributes) + */ + if (pcmk__cmp_schemas_by_name(schema, "pacemaker-1.2") >= 0) { + const char *origin = crm_element_value(req, PCMK__XA_SRC); + const char *client = crm_element_value(req, + PCMK__XA_CIB_CLIENTNAME); + + if (origin != NULL) { + crm_xml_add(scratch, PCMK_XA_UPDATE_ORIGIN, origin); + } else { + pcmk__xe_remove_attr(scratch, PCMK_XA_UPDATE_ORIGIN); } - /* Does the CIB support the "update-*" attributes... */ - if (current_schema >= minimum_schema) { - /* Ensure values of origin, client, and user in scratch match - * the values in req - */ - const char *origin = crm_element_value(req, F_ORIG); - const char *client = crm_element_value(req, F_CIB_CLIENTNAME); - - if (origin != NULL) { - crm_xml_add(scratch, XML_ATTR_UPDATE_ORIG, origin); - } else { - xml_remove_prop(scratch, XML_ATTR_UPDATE_ORIG); - } - - if (client != NULL) { - crm_xml_add(scratch, XML_ATTR_UPDATE_CLIENT, user); - } else { - xml_remove_prop(scratch, XML_ATTR_UPDATE_CLIENT); - } + if (client != NULL) { + crm_xml_add(scratch, PCMK_XA_UPDATE_CLIENT, user); + } else { + pcmk__xe_remove_attr(scratch, PCMK_XA_UPDATE_CLIENT); + } - if (user != NULL) { - crm_xml_add(scratch, XML_ATTR_UPDATE_USER, user); - } else { - xml_remove_prop(scratch, XML_ATTR_UPDATE_USER); - } + if (user != NULL) { + crm_xml_add(scratch, PCMK_XA_UPDATE_USER, user); + } else { + pcmk__xe_remove_attr(scratch, PCMK_XA_UPDATE_USER); } } } crm_trace("Perform validation: %s", pcmk__btoa(check_schema)); - if ((rc == pcmk_ok) && check_schema && !validate_xml(scratch, NULL, true)) { + if ((rc == pcmk_ok) && check_schema + && !pcmk__configured_schema_validates(scratch)) { const char *current_schema = crm_element_value(scratch, - XML_ATTR_VALIDATION); + PCMK_XA_VALIDATE_WITH); crm_warn("Updated CIB does not validate against %s schema", pcmk__s(current_schema, "unspecified")); @@ -677,30 +664,28 @@ cib__create_op(cib_t *cib, const char *op, const char *host, { CRM_CHECK((cib != NULL) && (op_msg != NULL), return -EPROTO); - *op_msg = create_xml_node(NULL, T_CIB_COMMAND); - if (*op_msg == NULL) { - return -EPROTO; - } + *op_msg = pcmk__xe_create(NULL, PCMK__XE_CIB_COMMAND); cib->call_id++; if (cib->call_id < 1) { cib->call_id = 1; } - crm_xml_add(*op_msg, F_XML_TAGNAME, T_CIB_COMMAND); - crm_xml_add(*op_msg, F_TYPE, T_CIB); - crm_xml_add(*op_msg, F_CIB_OPERATION, op); - crm_xml_add(*op_msg, F_CIB_HOST, host); - crm_xml_add(*op_msg, F_CIB_SECTION, section); - crm_xml_add(*op_msg, F_CIB_USER, user_name); - crm_xml_add(*op_msg, F_CIB_CLIENTNAME, client_name); - crm_xml_add_int(*op_msg, F_CIB_CALLID, cib->call_id); + crm_xml_add(*op_msg, PCMK__XA_T, PCMK__VALUE_CIB); + crm_xml_add(*op_msg, PCMK__XA_CIB_OP, op); + crm_xml_add(*op_msg, PCMK__XA_CIB_HOST, host); + crm_xml_add(*op_msg, PCMK__XA_CIB_SECTION, section); + crm_xml_add(*op_msg, PCMK__XA_CIB_USER, user_name); + crm_xml_add(*op_msg, PCMK__XA_CIB_CLIENTNAME, client_name); + crm_xml_add_int(*op_msg, PCMK__XA_CIB_CALLID, cib->call_id); crm_trace("Sending call options: %.8lx, %d", (long)call_options, call_options); - crm_xml_add_int(*op_msg, F_CIB_CALLOPTS, call_options); + crm_xml_add_int(*op_msg, PCMK__XA_CIB_CALLOPT, call_options); if (data != NULL) { - add_message_xml(*op_msg, F_CIB_CALLDATA, data); + xmlNode *wrapper = pcmk__xe_create(*op_msg, PCMK__XE_CIB_CALLDATA); + + pcmk__xml_copy(wrapper, data); } if (pcmk_is_set(call_options, cib_inhibit_bcast)) { @@ -721,8 +706,8 @@ cib__create_op(cib_t *cib, const char *op, const char *host, static int validate_transaction_request(const xmlNode *request) { - const char *op = crm_element_value(request, F_CIB_OPERATION); - const char *host = crm_element_value(request, F_CIB_HOST); + const char *op = crm_element_value(request, PCMK__XA_CIB_OP); + const char *host = crm_element_value(request, PCMK__XA_CIB_HOST); const cib__operation_t *operation = NULL; int rc = cib__get_operation(op, &operation); @@ -768,10 +753,10 @@ cib__extend_transaction(cib_t *cib, xmlNode *request) } if (rc == pcmk_rc_ok) { - add_node_copy(cib->transaction, request); + pcmk__xml_copy(cib->transaction, request); } else { - const char *op = crm_element_value(request, F_CIB_OPERATION); + const char *op = crm_element_value(request, PCMK__XA_CIB_OP); const char *client_id = NULL; cib->cmds->client_id(cib, NULL, &client_id); @@ -789,9 +774,12 @@ cib_native_callback(cib_t * cib, xmlNode * msg, int call_id, int rc) cib_callback_client_t *blob = NULL; if (msg != NULL) { - crm_element_value_int(msg, F_CIB_RC, &rc); - crm_element_value_int(msg, F_CIB_CALLID, &call_id); - output = get_message_xml(msg, F_CIB_CALLDATA); + xmlNode *wrapper = NULL; + + crm_element_value_int(msg, PCMK__XA_CIB_RC, &rc); + crm_element_value_int(msg, PCMK__XA_CIB_CALLID, &call_id); + wrapper = pcmk__xe_first_child(msg, PCMK__XE_CIB_CALLDATA, NULL, NULL); + output = pcmk__xe_first_child(wrapper, NULL, NULL, NULL); } blob = cib__lookup_id(call_id); @@ -843,7 +831,7 @@ cib_native_notify(gpointer data, gpointer user_data) return; } - event = crm_element_value(msg, F_SUBTYPE); + event = crm_element_value(msg, PCMK__XA_SUBT); if (entry == NULL) { crm_warn("Skipping callback - NULL callback client"); @@ -863,55 +851,6 @@ cib_native_notify(gpointer data, gpointer user_data) crm_trace("Callback invoked..."); } -static pcmk__cluster_option_t cib_opts[] = { - /* name, legacy name, type, allowed values, - * default value, validator, - * short description, - * long description - */ - { - "enable-acl", NULL, "boolean", NULL, - "false", pcmk__valid_boolean, - N_("Enable Access Control Lists (ACLs) for the CIB"), - NULL - }, - { - "cluster-ipc-limit", NULL, "integer", NULL, - "500", pcmk__valid_positive_number, - N_("Maximum IPC message backlog before disconnecting a cluster daemon"), - N_("Raise this if log has \"Evicting client\" messages for cluster daemon" - " PIDs (a good value is the number of resources in the cluster" - " multiplied by the number of nodes).") - }, -}; - -void -cib_metadata(void) -{ - const char *desc_short = "Cluster Information Base manager options"; - const char *desc_long = "Cluster options used by Pacemaker's Cluster " - "Information Base manager"; - - gchar *s = pcmk__format_option_metadata("pacemaker-based", desc_short, - desc_long, cib_opts, - PCMK__NELEM(cib_opts)); - printf("%s", s); - g_free(s); -} - -static void -verify_cib_options(GHashTable *options) -{ - pcmk__validate_cluster_options(options, cib_opts, PCMK__NELEM(cib_opts)); -} - -const char * -cib_pref(GHashTable * options, const char *name) -{ - return pcmk__cluster_option(options, cib_opts, PCMK__NELEM(cib_opts), - name); -} - gboolean cib_read_config(GHashTable * options, xmlNode * current_cib) { @@ -926,13 +865,14 @@ cib_read_config(GHashTable * options, xmlNode * current_cib) g_hash_table_remove_all(options); - config = pcmk_find_cib_element(current_cib, XML_CIB_TAG_CRMCONFIG); + config = pcmk_find_cib_element(current_cib, PCMK_XE_CRM_CONFIG); if (config) { - pe_unpack_nvpairs(current_cib, config, XML_CIB_TAG_PROPSET, NULL, - options, CIB_OPTIONS_FIRST, TRUE, now, NULL); + pe_unpack_nvpairs(current_cib, config, PCMK_XE_CLUSTER_PROPERTY_SET, + NULL, options, PCMK_VALUE_CIB_BOOTSTRAP_OPTIONS, TRUE, + now, NULL); } - verify_cib_options(options); + pcmk__validate_cluster_options(options); crm_time_free(now); @@ -973,14 +913,17 @@ cib_apply_patch_event(xmlNode *event, xmlNode *input, xmlNode **output, { int rc = pcmk_err_generic; + xmlNode *wrapper = NULL; xmlNode *diff = NULL; CRM_ASSERT(event); CRM_ASSERT(input); CRM_ASSERT(output); - crm_element_value_int(event, F_CIB_RC, &rc); - diff = get_message_xml(event, F_CIB_UPDATE_RESULT); + crm_element_value_int(event, PCMK__XA_CIB_RC, &rc); + wrapper = pcmk__xe_first_child(event, PCMK__XE_CIB_UPDATE_RESULT, NULL, + NULL); + diff = pcmk__xe_first_child(wrapper, NULL, NULL, NULL); if (rc < pcmk_ok || diff == NULL) { return rc; @@ -1092,6 +1035,21 @@ cib__clean_up_connection(cib_t **cib) #include <crm/cib/util_compat.h> +xmlNode * +cib_get_generation(cib_t * cib) +{ + xmlNode *the_cib = NULL; + xmlNode *generation = pcmk__xe_create(NULL, PCMK__XE_GENERATION_TUPLE); + + cib->cmds->query(cib, NULL, &the_cib, cib_scope_local | cib_sync_call); + if (the_cib != NULL) { + pcmk__xe_copy_attrs(generation, the_cib, pcmk__xaf_none); + free_xml(the_cib); + } + + return generation; +} + const char * get_object_path(const char *object_type) { @@ -1110,5 +1068,32 @@ get_object_root(const char *object_type, xmlNode *the_root) return pcmk_find_cib_element(the_root, object_type); } +const char * +cib_pref(GHashTable * options, const char *name) +{ + return pcmk__cluster_option(options, name); +} + +void +cib_metadata(void) +{ + pcmk__output_t *out = NULL; + int rc = pcmk__output_new(&out, "text", NULL, NULL); + + if (rc != pcmk_rc_ok) { + crm_err("Unable to output metadata: %s", pcmk_rc_str(rc)); + return; + } + + pcmk__daemon_metadata(out, "pacemaker-based", + "Cluster Information Base manager options", + "Cluster options used by Pacemaker's Cluster " + "Information Base manager", + pcmk__opt_based); + + out->finish(out, CRM_EX_OK, true, NULL); + pcmk__output_free(out); +} + // LCOV_EXCL_STOP // End deprecated API |