diff options
Diffstat (limited to 'lib/fencing')
-rw-r--r-- | lib/fencing/Makefile.am | 2 | ||||
-rw-r--r-- | lib/fencing/st_actions.c | 46 | ||||
-rw-r--r-- | lib/fencing/st_client.c | 277 | ||||
-rw-r--r-- | lib/fencing/st_lha.c | 115 | ||||
-rw-r--r-- | lib/fencing/st_output.c | 66 | ||||
-rw-r--r-- | lib/fencing/st_rhcs.c | 65 |
6 files changed, 301 insertions, 270 deletions
diff --git a/lib/fencing/Makefile.am b/lib/fencing/Makefile.am index 5302035..116b2f4 100644 --- a/lib/fencing/Makefile.am +++ b/lib/fencing/Makefile.am @@ -14,7 +14,7 @@ noinst_HEADERS = fencing_private.h lib_LTLIBRARIES = libstonithd.la -libstonithd_la_LDFLAGS = -version-info 34:4:8 +libstonithd_la_LDFLAGS = -version-info 34:5:8 libstonithd_la_CFLAGS = $(CFLAGS_HARDENED_LIB) libstonithd_la_LDFLAGS += $(LDFLAGS_HARDENED_LIB) diff --git a/lib/fencing/st_actions.c b/lib/fencing/st_actions.c index b81015e..6b4d1e7 100644 --- a/lib/fencing/st_actions.c +++ b/lib/fencing/st_actions.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2022 the Pacemaker project contributors + * Copyright 2004-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -21,7 +21,7 @@ #include <crm/crm.h> #include <crm/stonith-ng.h> #include <crm/fencing/internal.h> -#include <crm/msg_xml.h> +#include <crm/common/xml.h> #include <crm/services_internal.h> #include "fencing_private.h" @@ -96,12 +96,11 @@ append_config_arg(gpointer key, gpointer value, gpointer user_data) if (!pcmk__str_eq(key, STONITH_ATTR_ACTION_OP, pcmk__str_casei) && !pcmk_stonith_param(key) && (strstr(key, CRM_META) == NULL) - && !pcmk__str_eq(key, "crm_feature_set", pcmk__str_casei)) { + && !pcmk__str_eq(key, PCMK_XA_CRM_FEATURE_SET, pcmk__str_none)) { crm_trace("Passing %s=%s with fence action", (const char *) key, (const char *) (value? value : "")); - g_hash_table_insert((GHashTable *) user_data, - strdup(key), strdup(value? value : "")); + pcmk__insert_dup((GHashTable *) user_data, key, pcmk__s(value, "")); } } @@ -143,8 +142,7 @@ make_args(const char *agent, const char *action, const char *target, action = value; } } - g_hash_table_insert(arg_list, strdup(STONITH_ATTR_ACTION_OP), - strdup(action)); + pcmk__insert_dup(arg_list, STONITH_ATTR_ACTION_OP, action); /* If this is a fencing operation against another node, add more standard * arguments. @@ -155,7 +153,7 @@ make_args(const char *agent, const char *action, const char *target, /* Always pass the target's name, per * https://github.com/ClusterLabs/fence-agents/blob/main/doc/FenceAgentAPI.md */ - g_hash_table_insert(arg_list, strdup("nodename"), strdup(target)); + pcmk__insert_dup(arg_list, "nodename", target); // If the target's node ID was specified, pass it, too if (target_nodeid != 0) { @@ -170,7 +168,7 @@ make_args(const char *agent, const char *action, const char *target, // Check whether target must be specified in some other way param = g_hash_table_lookup(device_args, PCMK_STONITH_HOST_ARGUMENT); if (!pcmk__str_eq(agent, "fence_legacy", pcmk__str_none) - && !pcmk__str_eq(param, PCMK__VALUE_NONE, pcmk__str_casei)) { + && !pcmk__str_eq(param, PCMK_VALUE_NONE, pcmk__str_casei)) { if (param == NULL) { /* Use the caller's default for pcmk_host_argument, or "port" if @@ -195,7 +193,7 @@ make_args(const char *agent, const char *action, const char *target, } crm_debug("Passing %s='%s' with fence action %s targeting %s", param, alias, action, pcmk__s(target, "no node")); - g_hash_table_insert(arg_list, strdup(param), strdup(alias)); + pcmk__insert_dup(arg_list, param, alias); } } } @@ -267,9 +265,7 @@ stonith__action_create(const char *agent, const char *action_name, int timeout_sec, GHashTable *device_args, GHashTable *port_map, const char *host_arg) { - stonith_action_t *action = calloc(1, sizeof(stonith_action_t)); - - CRM_ASSERT(action != NULL); + stonith_action_t *action = pcmk__assert_alloc(1, sizeof(stonith_action_t)); action->args = make_args(agent, action_name, target, target_nodeid, device_args, port_map, host_arg); @@ -449,16 +445,16 @@ stonith__xe_set_result(xmlNode *xml, const pcmk__action_result_t *result) rc = pcmk_rc2legacy(stonith__result2rc(result)); } - crm_xml_add_int(xml, XML_LRM_ATTR_OPSTATUS, (int) execution_status); - crm_xml_add_int(xml, XML_LRM_ATTR_RC, exit_status); - crm_xml_add(xml, XML_LRM_ATTR_EXIT_REASON, exit_reason); - crm_xml_add(xml, F_STONITH_OUTPUT, action_stdout); + crm_xml_add_int(xml, PCMK__XA_OP_STATUS, (int) execution_status); + crm_xml_add_int(xml, PCMK__XA_RC_CODE, exit_status); + crm_xml_add(xml, PCMK_XA_EXIT_REASON, exit_reason); + crm_xml_add(xml, PCMK__XA_ST_OUTPUT, action_stdout); /* @COMPAT Peers in rolling upgrades, Pacemaker Remote nodes, and external * code that use libstonithd <=2.1.2 don't check for the full result, and * need a legacy return code instead. */ - crm_xml_add_int(xml, F_STONITH_RC, rc); + crm_xml_add_int(xml, PCMK__XA_ST_RC, rc); } /*! @@ -472,13 +468,13 @@ stonith__xe_set_result(xmlNode *xml, const pcmk__action_result_t *result) xmlNode * stonith__find_xe_with_result(xmlNode *xml) { - xmlNode *match = get_xpath_object("//@" XML_LRM_ATTR_RC, xml, LOG_NEVER); + xmlNode *match = get_xpath_object("//@" PCMK__XA_RC_CODE, xml, LOG_NEVER); if (match == NULL) { /* @COMPAT Peers <=2.1.2 in a rolling upgrade provide only a legacy * return code, not a full result, so check for that. */ - match = get_xpath_object("//@" F_STONITH_RC, xml, LOG_ERR); + match = get_xpath_object("//@" PCMK__XA_ST_RC, xml, LOG_ERR); } return match; } @@ -500,12 +496,12 @@ stonith__xe_get_result(const xmlNode *xml, pcmk__action_result_t *result) CRM_CHECK((xml != NULL) && (result != NULL), return); - exit_reason = crm_element_value(xml, XML_LRM_ATTR_EXIT_REASON); - action_stdout = crm_element_value_copy(xml, F_STONITH_OUTPUT); + exit_reason = crm_element_value(xml, PCMK_XA_EXIT_REASON); + action_stdout = crm_element_value_copy(xml, PCMK__XA_ST_OUTPUT); // A result must include an exit status and execution status - if ((crm_element_value_int(xml, XML_LRM_ATTR_RC, &exit_status) < 0) - || (crm_element_value_int(xml, XML_LRM_ATTR_OPSTATUS, + if ((crm_element_value_int(xml, PCMK__XA_RC_CODE, &exit_status) < 0) + || (crm_element_value_int(xml, PCMK__XA_OP_STATUS, &execution_status) < 0)) { int rc = pcmk_ok; exit_status = CRM_EX_ERROR; @@ -513,7 +509,7 @@ stonith__xe_get_result(const xmlNode *xml, pcmk__action_result_t *result) /* @COMPAT Peers <=2.1.2 in rolling upgrades provide only a legacy * return code, not a full result, so check for that. */ - if (crm_element_value_int(xml, F_STONITH_RC, &rc) == 0) { + if (crm_element_value_int(xml, PCMK__XA_ST_RC, &rc) == 0) { if ((rc == pcmk_ok) || (rc == -EINPROGRESS)) { exit_status = CRM_EX_OK; } diff --git a/lib/fencing/st_client.c b/lib/fencing/st_client.c index 1d32cc1..27ea86b 100644 --- a/lib/fencing/st_client.c +++ b/lib/fencing/st_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. * @@ -21,7 +21,7 @@ #include <crm/crm.h> #include <crm/stonith-ng.h> #include <crm/fencing/internal.h> -#include <crm/msg_xml.h> +#include <crm/common/xml.h> #include <crm/common/mainloop.h> @@ -274,7 +274,7 @@ stonith_connection_destroy(gpointer user_data) crm_trace("Sending destroyed notification"); blob.stonith = stonith; - blob.xml = create_xml_node(NULL, "notify"); + blob.xml = pcmk__xe_create(NULL, PCMK__XE_NOTIFY); native = stonith->st_private; native->ipc = NULL; @@ -282,8 +282,8 @@ stonith_connection_destroy(gpointer user_data) free(native->token); native->token = NULL; stonith->state = stonith_disconnected; - crm_xml_add(blob.xml, F_TYPE, T_STONITH_NOTIFY); - crm_xml_add(blob.xml, F_SUBTYPE, T_STONITH_NOTIFY_DISCONNECT); + crm_xml_add(blob.xml, PCMK__XA_T, PCMK__VALUE_ST_NOTIFY); + crm_xml_add(blob.xml, PCMK__XA_SUBT, PCMK__VALUE_ST_NOTIFY_DISCONNECT); foreach_notify_entry(native, stonith_send_notification, &blob); free_xml(blob.xml); @@ -295,8 +295,8 @@ create_device_registration_xml(const char *id, enum stonith_namespace namespace, const stonith_key_value_t *params, const char *rsc_provides) { - xmlNode *data = create_xml_node(NULL, F_STONITH_DEVICE); - xmlNode *args = create_xml_node(data, XML_TAG_ATTRS); + xmlNode *data = pcmk__xe_create(NULL, PCMK__XE_ST_DEVICE_ID); + xmlNode *args = pcmk__xe_create(data, PCMK__XE_ATTRIBUTES); #if HAVE_STONITH_STONITH_H if (namespace == st_namespace_any) { @@ -308,14 +308,15 @@ create_device_registration_xml(const char *id, enum stonith_namespace namespace, } #endif - crm_xml_add(data, XML_ATTR_ID, id); - crm_xml_add(data, F_STONITH_ORIGIN, __func__); - crm_xml_add(data, "agent", agent); + crm_xml_add(data, PCMK_XA_ID, id); + crm_xml_add(data, PCMK__XA_ST_ORIGIN, __func__); + crm_xml_add(data, PCMK_XA_AGENT, agent); if ((namespace != st_namespace_any) && (namespace != st_namespace_invalid)) { - crm_xml_add(data, "namespace", stonith_namespace2text(namespace)); + crm_xml_add(data, PCMK__XA_NAMESPACE, + stonith_namespace2text(namespace)); } if (rsc_provides) { - crm_xml_add(data, "rsc_provides", rsc_provides); + crm_xml_add(data, PCMK__XA_RSC_PROVIDES, rsc_provides); } for (; params; params = params->next) { @@ -327,14 +328,15 @@ create_device_registration_xml(const char *id, enum stonith_namespace namespace, static int stonith_api_register_device(stonith_t *st, int call_options, - const char *id, const char *namespace, + const char *id, const char *namespace_s, const char *agent, const stonith_key_value_t *params) { int rc = 0; xmlNode *data = NULL; - data = create_device_registration_xml(id, stonith_text2namespace(namespace), + data = create_device_registration_xml(id, + stonith_text2namespace(namespace_s), agent, params, NULL); rc = stonith_send_command(st, STONITH_OP_DEVICE_ADD, data, NULL, call_options, 0); @@ -349,9 +351,9 @@ stonith_api_remove_device(stonith_t * st, int call_options, const char *name) int rc = 0; xmlNode *data = NULL; - data = create_xml_node(NULL, F_STONITH_DEVICE); - crm_xml_add(data, F_STONITH_ORIGIN, __func__); - crm_xml_add(data, XML_ATTR_ID, name); + data = pcmk__xe_create(NULL, PCMK__XE_ST_DEVICE_ID); + crm_xml_add(data, PCMK__XA_ST_ORIGIN, __func__); + crm_xml_add(data, PCMK_XA_ID, name); rc = stonith_send_command(st, STONITH_OP_DEVICE_DEL, data, NULL, call_options, 0); free_xml(data); @@ -368,21 +370,21 @@ stonith_api_remove_level_full(stonith_t *st, int options, CRM_CHECK(node || pattern || (attr && value), return -EINVAL); - data = create_xml_node(NULL, XML_TAG_FENCING_LEVEL); - crm_xml_add(data, F_STONITH_ORIGIN, __func__); + data = pcmk__xe_create(NULL, PCMK_XE_FENCING_LEVEL); + crm_xml_add(data, PCMK__XA_ST_ORIGIN, __func__); if (node) { - crm_xml_add(data, XML_ATTR_STONITH_TARGET, node); + crm_xml_add(data, PCMK_XA_TARGET, node); } else if (pattern) { - crm_xml_add(data, XML_ATTR_STONITH_TARGET_PATTERN, pattern); + crm_xml_add(data, PCMK_XA_TARGET_PATTERN, pattern); } else { - crm_xml_add(data, XML_ATTR_STONITH_TARGET_ATTRIBUTE, attr); - crm_xml_add(data, XML_ATTR_STONITH_TARGET_VALUE, value); + crm_xml_add(data, PCMK_XA_TARGET_ATTRIBUTE, attr); + crm_xml_add(data, PCMK_XA_TARGET_VALUE, value); } - crm_xml_add_int(data, XML_ATTR_STONITH_INDEX, level); + crm_xml_add_int(data, PCMK_XA_INDEX, level); rc = stonith_send_command(st, STONITH_OP_LEVEL_DEL, data, NULL, options, 0); free_xml(data); @@ -421,22 +423,21 @@ create_level_registration_xml(const char *node, const char *pattern, CRM_CHECK(node || pattern || (attr && value), return NULL); - data = create_xml_node(NULL, XML_TAG_FENCING_LEVEL); - CRM_CHECK(data, return NULL); + data = pcmk__xe_create(NULL, PCMK_XE_FENCING_LEVEL); - crm_xml_add(data, F_STONITH_ORIGIN, __func__); - crm_xml_add_int(data, XML_ATTR_ID, level); - crm_xml_add_int(data, XML_ATTR_STONITH_INDEX, level); + crm_xml_add(data, PCMK__XA_ST_ORIGIN, __func__); + crm_xml_add_int(data, PCMK_XA_ID, level); + crm_xml_add_int(data, PCMK_XA_INDEX, level); if (node) { - crm_xml_add(data, XML_ATTR_STONITH_TARGET, node); + crm_xml_add(data, PCMK_XA_TARGET, node); } else if (pattern) { - crm_xml_add(data, XML_ATTR_STONITH_TARGET_PATTERN, pattern); + crm_xml_add(data, PCMK_XA_TARGET_PATTERN, pattern); } else { - crm_xml_add(data, XML_ATTR_STONITH_TARGET_ATTRIBUTE, attr); - crm_xml_add(data, XML_ATTR_STONITH_TARGET_VALUE, value); + crm_xml_add(data, PCMK_XA_TARGET_ATTRIBUTE, attr); + crm_xml_add(data, PCMK_XA_TARGET_VALUE, value); } for (; device_list; device_list = device_list->next) { @@ -444,7 +445,7 @@ create_level_registration_xml(const char *node, const char *pattern, } if (list != NULL) { - crm_xml_add(data, XML_ATTR_STONITH_DEVICES, (const char *) list->str); + crm_xml_add(data, PCMK_XA_DEVICES, (const char *) list->str); g_string_free(list, TRUE); } return data; @@ -476,11 +477,12 @@ stonith_api_register_level(stonith_t * st, int options, const char *node, int le } static int -stonith_api_device_list(stonith_t * stonith, int call_options, const char *namespace, - stonith_key_value_t ** devices, int timeout) +stonith_api_device_list(stonith_t *stonith, int call_options, + const char *namespace_s, stonith_key_value_t **devices, + int timeout) { int count = 0; - enum stonith_namespace ns = stonith_text2namespace(namespace); + enum stonith_namespace ns = stonith_text2namespace(namespace_s); if (devices == NULL) { crm_err("Parameter error: stonith_api_device_list"); @@ -505,14 +507,14 @@ stonith_api_device_list(stonith_t * stonith, int call_options, const char *names // See stonith_api_operations_t:metadata() documentation static int stonith_api_device_metadata(stonith_t *stonith, int call_options, - const char *agent, const char *namespace, + const char *agent, const char *namespace_s, char **output, int timeout_sec) { /* By executing meta-data directly, we can get it from stonith_admin when * the cluster is not running, which is important for higher-level tools. */ - enum stonith_namespace ns = stonith_get_namespace(agent, namespace); + enum stonith_namespace ns = stonith_get_namespace(agent, namespace_s); if (timeout_sec <= 0) { timeout_sec = PCMK_DEFAULT_METADATA_TIMEOUT_MS; @@ -550,10 +552,10 @@ stonith_api_query(stonith_t * stonith, int call_options, const char *target, CRM_CHECK(devices != NULL, return -EINVAL); - data = create_xml_node(NULL, F_STONITH_DEVICE); - crm_xml_add(data, F_STONITH_ORIGIN, __func__); - crm_xml_add(data, F_STONITH_TARGET, target); - crm_xml_add(data, F_STONITH_ACTION, PCMK_ACTION_OFF); + data = pcmk__xe_create(NULL, PCMK__XE_ST_DEVICE_ID); + crm_xml_add(data, PCMK__XA_ST_ORIGIN, __func__); + crm_xml_add(data, PCMK__XA_ST_TARGET, target); + crm_xml_add(data, PCMK__XA_ST_DEVICE_ACTION, PCMK_ACTION_OFF); rc = stonith_send_command(stonith, STONITH_OP_QUERY, data, &output, call_options, timeout); if (rc < 0) { @@ -573,7 +575,9 @@ stonith_api_query(stonith_t * stonith, int call_options, const char *target, crm_info("%s[%d] = %s", "//@agent", lpc, match_path); free(match_path); - *devices = stonith_key_value_add(*devices, NULL, crm_element_value(match, XML_ATTR_ID)); + *devices = stonith_key_value_add(*devices, NULL, + crm_element_value(match, + PCMK_XA_ID)); } } @@ -605,11 +609,11 @@ stonith_api_call(stonith_t *stonith, int call_options, const char *id, int rc = 0; xmlNode *data = NULL; - data = create_xml_node(NULL, F_STONITH_DEVICE); - crm_xml_add(data, F_STONITH_ORIGIN, __func__); - crm_xml_add(data, F_STONITH_DEVICE, id); - crm_xml_add(data, F_STONITH_ACTION, action); - crm_xml_add(data, F_STONITH_TARGET, target); + data = pcmk__xe_create(NULL, PCMK__XE_ST_DEVICE_ID); + crm_xml_add(data, PCMK__XA_ST_ORIGIN, __func__); + crm_xml_add(data, PCMK__XA_ST_DEVICE_ID, id); + crm_xml_add(data, PCMK__XA_ST_DEVICE_ACTION, action); + crm_xml_add(data, PCMK__XA_ST_TARGET, target); rc = stonith_send_command(stonith, STONITH_OP_EXEC, data, output, call_options, timeout_sec); @@ -631,7 +635,7 @@ stonith_api_list(stonith_t * stonith, int call_options, const char *id, char **l if (output && list_info) { const char *list_str; - list_str = crm_element_value(output, F_STONITH_OUTPUT); + list_str = crm_element_value(output, PCMK__XA_ST_OUTPUT); if (list_str) { *list_info = strdup(list_str); @@ -667,12 +671,12 @@ stonith_api_fence_with_delay(stonith_t * stonith, int call_options, const char * int rc = 0; xmlNode *data = NULL; - data = create_xml_node(NULL, __func__); - crm_xml_add(data, F_STONITH_TARGET, node); - crm_xml_add(data, F_STONITH_ACTION, action); - crm_xml_add_int(data, F_STONITH_TIMEOUT, timeout); - crm_xml_add_int(data, F_STONITH_TOLERANCE, tolerance); - crm_xml_add_int(data, F_STONITH_DELAY, delay); + data = pcmk__xe_create(NULL, __func__); + crm_xml_add(data, PCMK__XA_ST_TARGET, node); + crm_xml_add(data, PCMK__XA_ST_DEVICE_ACTION, action); + crm_xml_add_int(data, PCMK__XA_ST_TIMEOUT, timeout); + crm_xml_add_int(data, PCMK__XA_ST_TOLERANCE, tolerance); + crm_xml_add_int(data, PCMK__XA_ST_DELAY, delay); rc = stonith_send_command(stonith, STONITH_OP_FENCE, data, NULL, call_options, timeout); free_xml(data); @@ -708,8 +712,8 @@ stonith_api_history(stonith_t * stonith, int call_options, const char *node, *history = NULL; if (node) { - data = create_xml_node(NULL, __func__); - crm_xml_add(data, F_STONITH_TARGET, node); + data = pcmk__xe_create(NULL, __func__); + crm_xml_add(data, PCMK__XA_ST_TARGET, node); } stonith__set_call_options(call_options, node, st_opt_sync_call); @@ -719,28 +723,27 @@ stonith_api_history(stonith_t * stonith, int call_options, const char *node, if (rc == 0) { xmlNode *op = NULL; - xmlNode *reply = get_xpath_object("//" F_STONITH_HISTORY_LIST, output, + xmlNode *reply = get_xpath_object("//" PCMK__XE_ST_HISTORY, output, LOG_NEVER); - for (op = pcmk__xml_first_child(reply); op != NULL; - op = pcmk__xml_next(op)) { + for (op = pcmk__xe_first_child(reply, NULL, NULL, NULL); op != NULL; + op = pcmk__xe_next(op)) { stonith_history_t *kvp; long long completed; long long completed_nsec = 0L; - kvp = calloc(1, sizeof(stonith_history_t)); - kvp->target = crm_element_value_copy(op, F_STONITH_TARGET); - kvp->action = crm_element_value_copy(op, F_STONITH_ACTION); - kvp->origin = crm_element_value_copy(op, F_STONITH_ORIGIN); - kvp->delegate = crm_element_value_copy(op, F_STONITH_DELEGATE); - kvp->client = crm_element_value_copy(op, F_STONITH_CLIENTNAME); - crm_element_value_ll(op, F_STONITH_DATE, &completed); + kvp = pcmk__assert_alloc(1, sizeof(stonith_history_t)); + kvp->target = crm_element_value_copy(op, PCMK__XA_ST_TARGET); + kvp->action = crm_element_value_copy(op, PCMK__XA_ST_DEVICE_ACTION); + kvp->origin = crm_element_value_copy(op, PCMK__XA_ST_ORIGIN); + kvp->delegate = crm_element_value_copy(op, PCMK__XA_ST_DELEGATE); + kvp->client = crm_element_value_copy(op, PCMK__XA_ST_CLIENTNAME); + crm_element_value_ll(op, PCMK__XA_ST_DATE, &completed); kvp->completed = (time_t) completed; - crm_element_value_ll(op, F_STONITH_DATE_NSEC, &completed_nsec); + crm_element_value_ll(op, PCMK__XA_ST_DATE_NSEC, &completed_nsec); kvp->completed_nsec = completed_nsec; - crm_element_value_int(op, F_STONITH_STATE, &kvp->state); - kvp->exit_reason = crm_element_value_copy(op, - XML_LRM_ATTR_EXIT_REASON); + crm_element_value_int(op, PCMK__XA_ST_STATE, &kvp->state); + kvp->exit_reason = crm_element_value_copy(op, PCMK_XA_EXIT_REASON); if (last) { last->next = kvp; @@ -805,22 +808,21 @@ stonithlib_GCompareFunc(gconstpointer a, gconstpointer b) xmlNode * stonith_create_op(int call_id, const char *token, const char *op, xmlNode * data, int call_options) { - xmlNode *op_msg = create_xml_node(NULL, "stonith_command"); + xmlNode *op_msg = NULL; - CRM_CHECK(op_msg != NULL, return NULL); CRM_CHECK(token != NULL, return NULL); - crm_xml_add(op_msg, F_XML_TAGNAME, "stonith_command"); - - crm_xml_add(op_msg, F_TYPE, T_STONITH_NG); - crm_xml_add(op_msg, F_STONITH_CALLBACK_TOKEN, token); - crm_xml_add(op_msg, F_STONITH_OPERATION, op); - crm_xml_add_int(op_msg, F_STONITH_CALLID, call_id); + op_msg = pcmk__xe_create(NULL, PCMK__XE_STONITH_COMMAND); + crm_xml_add(op_msg, PCMK__XA_T, PCMK__VALUE_STONITH_NG); + crm_xml_add(op_msg, PCMK__XA_ST_OP, op); + crm_xml_add_int(op_msg, PCMK__XA_ST_CALLID, call_id); crm_trace("Sending call options: %.8lx, %d", (long)call_options, call_options); - crm_xml_add_int(op_msg, F_STONITH_CALLOPTS, call_options); + crm_xml_add_int(op_msg, PCMK__XA_ST_CALLOPT, call_options); if (data != NULL) { - add_message_xml(op_msg, F_STONITH_CALLDATA, data); + xmlNode *wrapper = pcmk__xe_create(op_msg, PCMK__XE_ST_CALLDATA); + + pcmk__xml_copy(wrapper, data); } return op_msg; @@ -943,7 +945,7 @@ invoke_registered_callbacks(stonith_t *stonith, const xmlNode *msg, int call_id) } else { // We have the fencer reply - if ((crm_element_value_int(msg, F_STONITH_CALLID, &call_id) != 0) + if ((crm_element_value_int(msg, PCMK__XA_ST_CALLID, &call_id) != 0) || (call_id <= 0)) { crm_log_xml_warn(msg, "Bad fencer reply"); } @@ -1008,7 +1010,7 @@ set_callback_timeout(stonith_callback_client_t * callback, stonith_t * stonith, } if (!async_timer) { - async_timer = calloc(1, sizeof(struct timer_rec_s)); + async_timer = pcmk__assert_alloc(1, sizeof(struct timer_rec_s)); callback->timer = async_timer; } @@ -1053,27 +1055,29 @@ stonith_dispatch_internal(const char *buffer, ssize_t length, gpointer userdata) private = st->st_private; blob.stonith = st; - blob.xml = string2xml(buffer); + blob.xml = pcmk__xml_parse(buffer); if (blob.xml == NULL) { crm_warn("Received malformed message from fencer: %s", buffer); return 0; } /* do callbacks */ - type = crm_element_value(blob.xml, F_TYPE); + type = crm_element_value(blob.xml, PCMK__XA_T); crm_trace("Activating %s callbacks...", type); - if (pcmk__str_eq(type, T_STONITH_NG, pcmk__str_none)) { + if (pcmk__str_eq(type, PCMK__VALUE_STONITH_NG, pcmk__str_none)) { invoke_registered_callbacks(st, blob.xml, 0); - } else if (pcmk__str_eq(type, T_STONITH_NOTIFY, pcmk__str_none)) { + } else if (pcmk__str_eq(type, PCMK__VALUE_ST_NOTIFY, pcmk__str_none)) { foreach_notify_entry(private, stonith_send_notification, &blob); - } else if (pcmk__str_eq(type, T_STONITH_TIMEOUT_VALUE, pcmk__str_none)) { + + } else if (pcmk__str_eq(type, PCMK__VALUE_ST_ASYNC_TIMEOUT_VALUE, + pcmk__str_none)) { int call_id = 0; int timeout = 0; - crm_element_value_int(blob.xml, F_STONITH_TIMEOUT, &timeout); - crm_element_value_int(blob.xml, F_STONITH_CALLID, &call_id); + crm_element_value_int(blob.xml, PCMK__XA_ST_TIMEOUT, &timeout); + crm_element_value_int(blob.xml, PCMK__XA_ST_CALLID, &call_id); update_callback_timeout(call_id, timeout, st); } else { @@ -1136,11 +1140,11 @@ stonith_api_signon(stonith_t * stonith, const char *name, int *stonith_fd) rc = -ENOTCONN; } else { xmlNode *reply = NULL; - xmlNode *hello = create_xml_node(NULL, "stonith_command"); + xmlNode *hello = pcmk__xe_create(NULL, PCMK__XE_STONITH_COMMAND); - crm_xml_add(hello, F_TYPE, T_STONITH_NG); - crm_xml_add(hello, F_STONITH_OPERATION, CRM_OP_REGISTER); - crm_xml_add(hello, F_STONITH_CLIENTNAME, name); + crm_xml_add(hello, PCMK__XA_T, PCMK__VALUE_STONITH_NG); + crm_xml_add(hello, PCMK__XA_ST_OP, CRM_OP_REGISTER); + crm_xml_add(hello, PCMK__XA_ST_CLIENTNAME, name); rc = crm_ipc_send(native->ipc, hello, crm_ipc_client_response, -1, &reply); if (rc < 0) { @@ -1153,9 +1157,9 @@ stonith_api_signon(stonith_t * stonith, const char *name, int *stonith_fd) rc = -EPROTO; } else { - const char *msg_type = crm_element_value(reply, F_STONITH_OPERATION); + const char *msg_type = crm_element_value(reply, PCMK__XA_ST_OP); - native->token = crm_element_value_copy(reply, F_STONITH_CLIENTID); + native->token = crm_element_value_copy(reply, PCMK__XA_ST_CLIENTID); if (!pcmk__str_eq(msg_type, CRM_OP_REGISTER, pcmk__str_none)) { crm_debug("Couldn't register with the fencer: invalid reply type '%s'", (msg_type? msg_type : "(missing)")); @@ -1190,16 +1194,16 @@ static int stonith_set_notification(stonith_t * stonith, const char *callback, int enabled) { int rc = pcmk_ok; - xmlNode *notify_msg = create_xml_node(NULL, __func__); + xmlNode *notify_msg = pcmk__xe_create(NULL, __func__); stonith_private_t *native = stonith->st_private; if (stonith->state != stonith_disconnected) { - crm_xml_add(notify_msg, F_STONITH_OPERATION, T_STONITH_NOTIFY); + crm_xml_add(notify_msg, PCMK__XA_ST_OP, STONITH_OP_NOTIFY); if (enabled) { - crm_xml_add(notify_msg, F_STONITH_NOTIFY_ACTIVATE, callback); + crm_xml_add(notify_msg, PCMK__XA_ST_NOTIFY_ACTIVATE, callback); } else { - crm_xml_add(notify_msg, F_STONITH_NOTIFY_DEACTIVATE, callback); + crm_xml_add(notify_msg, PCMK__XA_ST_NOTIFY_DEACTIVATE, callback); } rc = crm_ipc_send(native->ipc, notify_msg, crm_ipc_client_response, -1, NULL); @@ -1226,7 +1230,7 @@ stonith_api_add_notification(stonith_t * stonith, const char *event, private = stonith->st_private; crm_trace("Adding callback for %s events (%d)", event, g_list_length(private->notify_list)); - new_client = calloc(1, sizeof(stonith_notify_client_t)); + new_client = pcmk__assert_alloc(1, sizeof(stonith_notify_client_t)); new_client->event = event; new_client->notify = callback; @@ -1275,7 +1279,7 @@ stonith_api_del_notification(stonith_t * stonith, const char *event) crm_debug("Removing callback for %s events", event); - new_client = calloc(1, sizeof(stonith_notify_client_t)); + new_client = pcmk__assert_alloc(1, sizeof(stonith_notify_client_t)); new_client->event = event; new_client->notify = NULL; @@ -1333,7 +1337,7 @@ stonith_api_add_callback(stonith_t * stonith, int call_id, int timeout, int opti return FALSE; } - blob = calloc(1, sizeof(stonith_callback_client_t)); + blob = pcmk__assert_alloc(1, sizeof(stonith_callback_client_t)); blob->id = callback_name; blob->only_success = (options & st_opt_report_only_success) ? TRUE : FALSE; blob->user_data = user_data; @@ -1410,27 +1414,24 @@ get_event_data_xml(xmlNode *msg, const char *ntype) static stonith_event_t * xml_to_event(xmlNode *msg) { - stonith_event_t *event = calloc(1, sizeof(stonith_event_t)); + stonith_event_t *event = pcmk__assert_alloc(1, sizeof(stonith_event_t)); struct event_private *event_private = NULL; - CRM_ASSERT(event != NULL); - - event->opaque = calloc(1, sizeof(struct event_private)); - CRM_ASSERT(event->opaque != NULL); + event->opaque = pcmk__assert_alloc(1, sizeof(struct event_private)); event_private = (struct event_private *) event->opaque; crm_log_xml_trace(msg, "stonith_notify"); // All notification types have the operation result and notification subtype stonith__xe_get_result(msg, &event_private->result); - event->operation = crm_element_value_copy(msg, F_STONITH_OPERATION); + event->operation = crm_element_value_copy(msg, PCMK__XA_ST_OP); // @COMPAT The API originally provided the result as a legacy return code event->result = pcmk_rc2legacy(stonith__result2rc(&event_private->result)); // Some notification subtypes have additional information - if (pcmk__str_eq(event->operation, T_STONITH_NOTIFY_FENCE, + if (pcmk__str_eq(event->operation, PCMK__VALUE_ST_NOTIFY_FENCE, pcmk__str_none)) { xmlNode *data = get_event_data_xml(msg, event->operation); @@ -1438,13 +1439,16 @@ xml_to_event(xmlNode *msg) crm_err("No data for %s event", event->operation); crm_log_xml_notice(msg, "BadEvent"); } else { - event->origin = crm_element_value_copy(data, F_STONITH_ORIGIN); - event->action = crm_element_value_copy(data, F_STONITH_ACTION); - event->target = crm_element_value_copy(data, F_STONITH_TARGET); - event->executioner = crm_element_value_copy(data, F_STONITH_DELEGATE); - event->id = crm_element_value_copy(data, F_STONITH_REMOTE_OP_ID); - event->client_origin = crm_element_value_copy(data, F_STONITH_CLIENTNAME); - event->device = crm_element_value_copy(data, F_STONITH_DEVICE); + event->origin = crm_element_value_copy(data, PCMK__XA_ST_ORIGIN); + event->action = crm_element_value_copy(data, + PCMK__XA_ST_DEVICE_ACTION); + event->target = crm_element_value_copy(data, PCMK__XA_ST_TARGET); + event->executioner = crm_element_value_copy(data, + PCMK__XA_ST_DELEGATE); + event->id = crm_element_value_copy(data, PCMK__XA_ST_REMOTE_OP); + event->client_origin = + crm_element_value_copy(data, PCMK__XA_ST_CLIENTNAME); + event->device = crm_element_value_copy(data, PCMK__XA_ST_DEVICE_ID); } } else if (pcmk__str_any_of(event->operation, @@ -1457,7 +1461,7 @@ xml_to_event(xmlNode *msg) crm_err("No data for %s event", event->operation); crm_log_xml_notice(msg, "BadEvent"); } else { - event->device = crm_element_value_copy(data, F_STONITH_DEVICE); + event->device = crm_element_value_copy(data, PCMK__XA_ST_DEVICE_ID); } } @@ -1497,7 +1501,7 @@ stonith_send_notification(gpointer data, gpointer user_data) return; } - event = crm_element_value(blob->xml, F_SUBTYPE); + event = crm_element_value(blob->xml, PCMK__XA_SUBT); if (entry == NULL) { crm_warn("Skipping callback - NULL callback client"); @@ -1575,14 +1579,14 @@ stonith_send_command(stonith_t * stonith, const char *op, xmlNode * data, xmlNod return -EINVAL; } - crm_xml_add_int(op_msg, F_STONITH_TIMEOUT, timeout); + crm_xml_add_int(op_msg, PCMK__XA_ST_TIMEOUT, timeout); crm_trace("Sending %s message to fencer with timeout %ds", op, timeout); if (data) { - const char *delay_s = crm_element_value(data, F_STONITH_DELAY); + const char *delay_s = crm_element_value(data, PCMK__XA_ST_DELAY); if (delay_s) { - crm_xml_add(op_msg, F_STONITH_DELAY, delay_s); + crm_xml_add(op_msg, PCMK__XA_ST_DELAY, delay_s); } } @@ -1612,7 +1616,7 @@ stonith_send_command(stonith_t * stonith, const char *op, xmlNode * data, xmlNod return stonith->call_id; } - crm_element_value_int(op_reply, F_STONITH_CALLID, &reply_id); + crm_element_value_int(op_reply, PCMK__XA_ST_CALLID, &reply_id); if (reply_id == stonith->call_id) { pcmk__action_result_t result = PCMK__UNKNOWN_RESULT; @@ -1754,8 +1758,7 @@ stonith_api_validate(stonith_t *st, int call_options, const char *rsc_id, host_arg = params->value; } if (!pcmk_stonith_param(params->key)) { - g_hash_table_insert(params_table, strdup(params->key), - strdup(params->value)); + pcmk__insert_dup(params_table, params->key, params->value); } } @@ -1928,9 +1931,9 @@ stonith_key_value_add(stonith_key_value_t * head, const char *key, const char *v { stonith_key_value_t *p, *end; - p = calloc(1, sizeof(stonith_key_value_t)); - pcmk__str_update(&p->key, key); - pcmk__str_update(&p->value, value); + p = pcmk__assert_alloc(1, sizeof(stonith_key_value_t)); + p->key = pcmk__str_copy(key); + p->value = pcmk__str_copy(value); end = head; while (end && end->next) { @@ -2157,8 +2160,7 @@ parse_list_line(const char *line, int len, GList **output) continue; } - entry = calloc(i - entry_start + 1, sizeof(char)); - CRM_ASSERT(entry != NULL); + entry = pcmk__assert_alloc(i - entry_start + 1, sizeof(char)); /* Read entry, stopping at first separator * @@ -2406,7 +2408,7 @@ stonith__device_parameter_flags(uint32_t *device_flags, const char *device_name, CRM_CHECK((device_flags != NULL) && (metadata != NULL), return); - xpath = xpath_search(metadata, "//parameter"); + xpath = xpath_search(metadata, "//" PCMK_XE_PARAMETER); max = numXpathResults(xpath); if (max <= 0) { @@ -2423,7 +2425,7 @@ stonith__device_parameter_flags(uint32_t *device_flags, const char *device_name, continue; } - parameter = crm_element_value(match, "name"); + parameter = crm_element_value(match, PCMK_XA_NAME); if (pcmk__str_eq(parameter, "plug", pcmk__str_casei)) { stonith__set_device_flags(*device_flags, device_name, @@ -2470,8 +2472,9 @@ stonith__metadata_async(const char *agent, int timeout_sec, stonith_action_t *action = NULL; int rc = pcmk_ok; - action = stonith__action_create(agent, "metadata", NULL, 0, - timeout_sec, NULL, NULL, NULL); + action = stonith__action_create(agent, PCMK_ACTION_METADATA, + NULL, 0, timeout_sec, NULL, + NULL, NULL); rc = stonith__execute_async(action, user_data, callback, NULL); if (rc != pcmk_ok) { @@ -2665,7 +2668,7 @@ stonith__event_description(const stonith_event_t *event) status = crm_exit_str(CRM_EX_OK); } - if (pcmk__str_eq(event->operation, T_STONITH_NOTIFY_HISTORY, + if (pcmk__str_eq(event->operation, PCMK__VALUE_ST_NOTIFY_HISTORY, pcmk__str_none)) { return crm_strdup_printf("Fencing history may have changed"); @@ -2688,7 +2691,7 @@ stonith__event_description(const stonith_event_t *event) device); } - // event->operation should be T_STONITH_NOTIFY_FENCE at this point + // event->operation should be PCMK__VALUE_ST_NOTIFY_FENCE at this point return crm_strdup_printf("Operation %s of %s by %s for %s@%s: %s%s%s%s (ref=%s)", action, target, executioner, origin, origin_node, diff --git a/lib/fencing/st_lha.c b/lib/fencing/st_lha.c index fd26217..a379c10 100644 --- a/lib/fencing/st_lha.c +++ b/lib/fencing/st_lha.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. * @@ -19,7 +19,6 @@ #include <crm/crm.h> #include <crm/stonith-ng.h> #include <crm/fencing/internal.h> -#include <crm/msg_xml.h> #include <crm/common/xml.h> #include <stonith/stonith.h> @@ -30,25 +29,35 @@ static void *lha_agents_lib = NULL; +// @TODO Use XML string constants and maybe a real XML object static const char META_TEMPLATE[] = - "<?xml version=\"1.0\"?>\n" - "<!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n" - "<resource-agent name=\"%s\">\n" - " <version>1.0</version>\n" - " <longdesc lang=\"en\">\n" + "<?xml " PCMK_XA_VERSION "=\"1.0\"?>\n" + "<" PCMK_XE_RESOURCE_AGENT " " PCMK_XA_NAME "=\"%s\">\n" + " <" PCMK_XE_VERSION ">1.1</" PCMK_XE_VERSION ">\n" + " <" PCMK_XE_LONGDESC " " PCMK_XA_LANG "=\"" PCMK__VALUE_EN "\">\n" + "%s\n" + " </" PCMK_XE_LONGDESC ">\n" + " <" PCMK_XE_SHORTDESC " " PCMK_XA_LANG "=\"" PCMK__VALUE_EN "\">" + "%s" + "</" PCMK_XE_SHORTDESC ">\n" "%s\n" - " </longdesc>\n" - " <shortdesc lang=\"en\">%s</shortdesc>\n" - "%s\n" - " <actions>\n" - " <action name=\"start\" timeout=\"%s\" />\n" - " <action name=\"stop\" timeout=\"15\" />\n" - " <action name=\"status\" timeout=\"%s\" />\n" - " <action name=\"monitor\" timeout=\"%s\" interval=\"3600\"/>\n" - " <action name=\"meta-data\" timeout=\"15\" />\n" - " </actions>\n" - " <special tag=\"heartbeat\">\n" - " <version>2.0</version>\n" " </special>\n" "</resource-agent>\n"; + " <" PCMK_XE_ACTIONS ">\n" + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "=\"" PCMK_ACTION_START "\"" + " " PCMK_META_TIMEOUT "=\"%s\" />\n" + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "=\"" PCMK_ACTION_STOP "\"" + " " PCMK_META_TIMEOUT "=\"15s\" />\n" + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "=\"" PCMK_ACTION_STATUS "\"" + " " PCMK_META_TIMEOUT "=\"%s\" />\n" + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "=\"" PCMK_ACTION_MONITOR "\"" + " " PCMK_META_TIMEOUT "=\"%s\"" + " " PCMK_META_INTERVAL "=\"3600s\" />\n" + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "=\"" PCMK_ACTION_META_DATA "\"" + " " PCMK_META_TIMEOUT "=\"15s\" />\n" + " </" PCMK_XE_ACTIONS ">\n" + " <" PCMK_XE_SPECIAL " " PCMK_XA_TAG "=\"heartbeat\">\n" + " <" PCMK_XE_VERSION ">2.0</" PCMK_XE_VERSION ">\n" + " </" PCMK_XE_SPECIAL ">\n" + "</" PCMK_XE_RESOURCE_AGENT ">\n"; static void * find_library_function(void **handle, const char *lib, const char *fn) @@ -194,60 +203,66 @@ stonith__lha_metadata(const char *agent, int timeout, char **output) } if (lha_agents_lib && st_new_fn && st_del_fn && st_info_fn && st_log_fn) { - char *xml_meta_longdesc = NULL; - char *xml_meta_shortdesc = NULL; - - char *meta_param = NULL; - char *meta_longdesc = NULL; - char *meta_shortdesc = NULL; + const char *meta_longdesc = NULL; + const char *meta_shortdesc = NULL; + const char *meta_param = NULL; const char *timeout_str = NULL; - stonith_obj = (*st_new_fn) (agent); - if (stonith_obj) { - (*st_log_fn) (stonith_obj, (PILLogFun) & stonith_plugin); - pcmk__str_update(&meta_longdesc, - (*st_info_fn) (stonith_obj, ST_DEVICEDESCR)); + gchar *meta_longdesc_esc = NULL; + gchar *meta_shortdesc_esc = NULL; + + stonith_obj = st_new_fn(agent); + if (stonith_obj != NULL) { + st_log_fn(stonith_obj, (PILLogFun) &stonith_plugin); + + meta_longdesc = st_info_fn(stonith_obj, ST_DEVICEDESCR); if (meta_longdesc == NULL) { crm_warn("no long description in %s's metadata.", agent); - meta_longdesc = strdup(no_parameter_info); + meta_longdesc = no_parameter_info; } - pcmk__str_update(&meta_shortdesc, - (*st_info_fn) (stonith_obj, ST_DEVICEID)); + meta_shortdesc = st_info_fn(stonith_obj, ST_DEVICEID); if (meta_shortdesc == NULL) { crm_warn("no short description in %s's metadata.", agent); - meta_shortdesc = strdup(no_parameter_info); + meta_shortdesc = no_parameter_info; } - pcmk__str_update(&meta_param, - (*st_info_fn) (stonith_obj, ST_CONF_XML)); + meta_param = st_info_fn(stonith_obj, ST_CONF_XML); if (meta_param == NULL) { crm_warn("no list of parameters in %s's metadata.", agent); - meta_param = strdup(no_parameter_info); + meta_param = no_parameter_info; } - (*st_del_fn) (stonith_obj); + + st_del_fn(stonith_obj); + } else { errno = EINVAL; crm_perror(LOG_ERR, "Agent %s not found", agent); return -EINVAL; } - xml_meta_longdesc = - (char *)xmlEncodeEntitiesReentrant(NULL, (const unsigned char *)meta_longdesc); - xml_meta_shortdesc = - (char *)xmlEncodeEntitiesReentrant(NULL, (const unsigned char *)meta_shortdesc); + if (pcmk__xml_needs_escape(meta_longdesc, pcmk__xml_escape_text)) { + meta_longdesc_esc = pcmk__xml_escape(meta_longdesc, + pcmk__xml_escape_text); + meta_longdesc = meta_longdesc_esc; + } + if (pcmk__xml_needs_escape(meta_shortdesc, pcmk__xml_escape_text)) { + meta_shortdesc_esc = pcmk__xml_escape(meta_shortdesc, + pcmk__xml_escape_text); + meta_shortdesc = meta_shortdesc_esc; + } + /* @TODO This needs a string that's parsable by crm_get_msec(). In + * general, pcmk__readable_interval() doesn't provide that. It works + * here because PCMK_DEFAULT_ACTION_TIMEOUT_MS is 20000 -> "20s". + */ timeout_str = pcmk__readable_interval(PCMK_DEFAULT_ACTION_TIMEOUT_MS); - buffer = crm_strdup_printf(META_TEMPLATE, agent, xml_meta_longdesc, - xml_meta_shortdesc, meta_param, + buffer = crm_strdup_printf(META_TEMPLATE, agent, meta_longdesc, + meta_shortdesc, meta_param, timeout_str, timeout_str, timeout_str); - xmlFree(xml_meta_longdesc); - xmlFree(xml_meta_shortdesc); - - free(meta_shortdesc); - free(meta_longdesc); - free(meta_param); + g_free(meta_longdesc_esc); + g_free(meta_shortdesc_esc); } if (output) { *output = buffer; diff --git a/lib/fencing/st_output.c b/lib/fencing/st_output.c index a0ce8e7..786f9d5 100644 --- a/lib/fencing/st_output.c +++ b/lib/fencing/st_output.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 the Pacemaker project contributors + * Copyright 2019-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -12,7 +12,6 @@ #include <stdint.h> #include <crm/stonith-ng.h> -#include <crm/msg_xml.h> #include <crm/common/iso8601.h> #include <crm/common/util.h> #include <crm/common/xml.h> @@ -132,13 +131,14 @@ stonith__history_description(const stonith_history_t *history, if (((history->state == st_failed) || (history->state == st_done)) && (history->delegate != NULL)) { - pcmk__g_strcat(str, "delegate=", history->delegate, ", ", NULL); + pcmk__g_strcat(str, PCMK_XA_DELEGATE "=", history->delegate, ", ", + NULL); } // Add information about originator pcmk__g_strcat(str, - "client=", history->client, ", origin=", history->origin, - NULL); + PCMK_XA_CLIENT "=", history->client, ", " + PCMK_XA_ORIGIN "=", history->origin, NULL); // For completed actions, add completion time if (completed_time_s != NULL) { @@ -293,8 +293,8 @@ full_history_xml(pcmk__output_t *out, va_list args) } else { char *rc_s = pcmk__itoa(history_rc); - pcmk__output_create_xml_node(out, "fence_history", - "status", rc_s, + pcmk__output_create_xml_node(out, PCMK_XE_FENCE_HISTORY, + PCMK_XA_STATUS, rc_s, NULL); free(rc_s); @@ -312,7 +312,7 @@ last_fenced_html(pcmk__output_t *out, va_list args) { if (when) { char *buf = crm_strdup_printf("Node %s last fenced at: %s", target, ctime(&when)); - pcmk__output_create_html_node(out, "div", NULL, NULL, buf); + pcmk__output_create_html_node(out, PCMK__XE_DIV, NULL, NULL, buf); free(buf); return pcmk_rc_ok; } else { @@ -344,9 +344,9 @@ last_fenced_xml(pcmk__output_t *out, va_list args) { if (when) { char *buf = timespec_string(when, 0, false); - pcmk__output_create_xml_node(out, "last-fenced", - "target", target, - "when", buf, + pcmk__output_create_xml_node(out, PCMK_XE_LAST_FENCED, + PCMK_XA_TARGET, target, + PCMK_XA_WHEN, buf, NULL); free(buf); @@ -456,28 +456,32 @@ stonith_event_xml(pcmk__output_t *out, va_list args) const char *succeeded G_GNUC_UNUSED = va_arg(args, const char *); uint32_t show_opts G_GNUC_UNUSED = va_arg(args, uint32_t); - xmlNodePtr node = pcmk__output_create_xml_node(out, "fence_event", - "action", event->action, - "target", event->target, - "client", event->client, - "origin", event->origin, - NULL); + xmlNodePtr node = NULL; + + node = pcmk__output_create_xml_node(out, PCMK_XE_FENCE_EVENT, + PCMK_XA_ACTION, event->action, + PCMK_XA_TARGET, event->target, + PCMK_XA_CLIENT, event->client, + PCMK_XA_ORIGIN, event->origin, + NULL); switch (event->state) { case st_failed: - pcmk__xe_set_props(node, "status", "failed", - XML_LRM_ATTR_EXIT_REASON, event->exit_reason, + pcmk__xe_set_props(node, + PCMK_XA_STATUS, PCMK_VALUE_FAILED, + PCMK_XA_EXIT_REASON, event->exit_reason, NULL); break; case st_done: - crm_xml_add(node, "status", "success"); + crm_xml_add(node, PCMK_XA_STATUS, PCMK_VALUE_SUCCESS); break; default: { char *state = pcmk__itoa(event->state); - pcmk__xe_set_props(node, "status", "pending", - "extended-status", state, + pcmk__xe_set_props(node, + PCMK_XA_STATUS, PCMK_VALUE_PENDING, + PCMK_XA_EXTENDED_STATUS, state, NULL); free(state); break; @@ -485,14 +489,14 @@ stonith_event_xml(pcmk__output_t *out, va_list args) } if (event->delegate != NULL) { - crm_xml_add(node, "delegate", event->delegate); + crm_xml_add(node, PCMK_XA_DELEGATE, event->delegate); } if ((event->state == st_failed) || (event->state == st_done)) { char *time_s = timespec_string(event->completed, event->completed_nsec, true); - crm_xml_add(node, "completed", time_s); + crm_xml_add(node, PCMK_XA_COMPLETED, time_s); free(time_s); } @@ -512,12 +516,12 @@ validate_agent_html(pcmk__output_t *out, va_list args) { if (device) { char *buf = crm_strdup_printf("Validation of %s on %s %s", agent, device, rc ? "failed" : "succeeded"); - pcmk__output_create_html_node(out, "div", NULL, NULL, buf); + pcmk__output_create_html_node(out, PCMK__XE_DIV, NULL, NULL, buf); free(buf); } else { char *buf = crm_strdup_printf("Validation of %s %s", agent, rc ? "failed" : "succeeded"); - pcmk__output_create_html_node(out, "div", NULL, NULL, buf); + pcmk__output_create_html_node(out, PCMK__XE_DIV, NULL, NULL, buf); free(buf); } @@ -557,12 +561,14 @@ validate_agent_xml(pcmk__output_t *out, va_list args) { const char *error_output = va_arg(args, const char *); int rc = va_arg(args, int); - xmlNodePtr node = pcmk__output_create_xml_node( - out, "validate", "agent", agent, "valid", pcmk__btoa(rc == pcmk_ok), - NULL); + const char *valid = pcmk__btoa(rc == pcmk_ok); + xmlNodePtr node = pcmk__output_create_xml_node(out, PCMK_XE_VALIDATE, + PCMK_XA_AGENT, agent, + PCMK_XA_VALID, valid, + NULL); if (device != NULL) { - crm_xml_add(node, "device", device); + crm_xml_add(node, PCMK_XA_DEVICE, device); } pcmk__output_xml_push_parent(out, node); diff --git a/lib/fencing/st_rhcs.c b/lib/fencing/st_rhcs.c index 854d333..d104fe8 100644 --- a/lib/fencing/st_rhcs.c +++ b/lib/fencing/st_rhcs.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2023 the Pacemaker project contributors + * Copyright 2004-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -16,6 +16,7 @@ #include <dirent.h> #include <crm/crm.h> +#include <crm/common/xml.h> #include <crm/stonith-ng.h> #include <crm/fencing/internal.h> @@ -98,7 +99,8 @@ stonith_rhcs_parameter_not_required(xmlNode *metadata, const char *parameter) CRM_CHECK(metadata != NULL, return); CRM_CHECK(parameter != NULL, return); - xpath = crm_strdup_printf("//parameter[@name='%s']", parameter); + xpath = crm_strdup_printf("//" PCMK_XE_PARAMETER "[@" PCMK_XA_NAME "='%s']", + parameter); /* Fudge metadata so that the parameter isn't required in config * Pacemaker handles and adds it */ xpathObj = xpath_search(metadata, xpath); @@ -125,9 +127,10 @@ stonith__rhcs_get_metadata(const char *agent, int timeout_sec, xmlNode *xml = NULL; xmlNode *actions = NULL; xmlXPathObject *xpathObj = NULL; - stonith_action_t *action = stonith__action_create(agent, "metadata", NULL, - 0, timeout_sec, NULL, - NULL, NULL); + stonith_action_t *action = stonith__action_create(agent, + PCMK_ACTION_METADATA, + NULL, 0, timeout_sec, + NULL, NULL, NULL); int rc = stonith__execute(action); pcmk__action_result_t *result = stonith__action_result(action); @@ -162,7 +165,7 @@ stonith__rhcs_get_metadata(const char *agent, int timeout_sec, return -ENODATA; } - xml = string2xml(result->action_stdout); + xml = pcmk__xml_parse(result->action_stdout); stonith__destroy_action(action); if (xml == NULL) { @@ -170,27 +173,29 @@ stonith__rhcs_get_metadata(const char *agent, int timeout_sec, return -pcmk_err_schema_validation; } - xpathObj = xpath_search(xml, "//actions"); + xpathObj = xpath_search(xml, "//" PCMK_XE_ACTIONS); if (numXpathResults(xpathObj) > 0) { actions = getXpathResult(xpathObj, 0); } freeXpathObject(xpathObj); // Add start and stop (implemented by pacemaker, not agent) to meta-data - xpathObj = xpath_search(xml, "//action[@name='stop']"); + xpathObj = xpath_search(xml, + "//" PCMK_XE_ACTION + "[@" PCMK_XA_NAME "='" PCMK_ACTION_STOP "']"); if (numXpathResults(xpathObj) <= 0) { xmlNode *tmp = NULL; const char *timeout_str = NULL; timeout_str = pcmk__readable_interval(PCMK_DEFAULT_ACTION_TIMEOUT_MS); - tmp = create_xml_node(actions, "action"); - crm_xml_add(tmp, "name", PCMK_ACTION_STOP); - crm_xml_add(tmp, "timeout", timeout_str); + tmp = pcmk__xe_create(actions, PCMK_XE_ACTION); + crm_xml_add(tmp, PCMK_XA_NAME, PCMK_ACTION_STOP); + crm_xml_add(tmp, PCMK_META_TIMEOUT, timeout_str); - tmp = create_xml_node(actions, "action"); - crm_xml_add(tmp, "name", PCMK_ACTION_START); - crm_xml_add(tmp, "timeout", timeout_str); + tmp = pcmk__xe_create(actions, PCMK_XE_ACTION); + crm_xml_add(tmp, PCMK_XA_NAME, PCMK_ACTION_START); + crm_xml_add(tmp, PCMK_META_TIMEOUT, timeout_str); } freeXpathObject(xpathObj); @@ -219,27 +224,33 @@ stonith__rhcs_get_metadata(const char *agent, int timeout_sec, int stonith__rhcs_metadata(const char *agent, int timeout_sec, char **output) { - char *buffer = NULL; + GString *buffer = NULL; xmlNode *xml = NULL; int rc = stonith__rhcs_get_metadata(agent, timeout_sec, &xml); if (rc != pcmk_ok) { - free_xml(xml); - return rc; + goto done; } - buffer = dump_xml_formatted_with_text(xml); - free_xml(xml); - if (buffer == NULL) { - return -pcmk_err_schema_validation; + buffer = g_string_sized_new(1024); + pcmk__xml_string(xml, pcmk__xml_fmt_pretty|pcmk__xml_fmt_text, buffer, 0); + + if (pcmk__str_empty(buffer->str)) { + rc = -pcmk_err_schema_validation; + goto done; } - if (output) { - *output = buffer; - } else { - free(buffer); + + if (output != NULL) { + pcmk__str_update(output, buffer->str); } - return pcmk_ok; + +done: + if (buffer != NULL) { + g_string_free(buffer, TRUE); + } + free_xml(xml); + return rc; } bool @@ -291,7 +302,7 @@ stonith__rhcs_validate(stonith_t *st, int call_options, const char *target, return -ETIME; } - } else if (pcmk__str_eq(host_arg, PCMK__VALUE_NONE, pcmk__str_casei)) { + } else if (pcmk__str_eq(host_arg, PCMK_VALUE_NONE, pcmk__str_casei)) { host_arg = NULL; } |