summaryrefslogtreecommitdiffstats
path: root/lib/cib
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lib/cib/Makefile.am2
-rw-r--r--lib/cib/cib_attrs.c255
-rw-r--r--lib/cib/cib_client.c35
-rw-r--r--lib/cib/cib_file.c90
-rw-r--r--lib/cib/cib_native.c45
-rw-r--r--lib/cib/cib_ops.c350
-rw-r--r--lib/cib/cib_remote.c50
-rw-r--r--lib/cib/cib_utils.c383
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