summaryrefslogtreecommitdiffstats
path: root/daemons/fenced
diff options
context:
space:
mode:
Diffstat (limited to 'daemons/fenced')
-rw-r--r--daemons/fenced/cts-fence-helper.c15
-rw-r--r--daemons/fenced/fenced_cib.c219
-rw-r--r--daemons/fenced/fenced_commands.c579
-rw-r--r--daemons/fenced/fenced_history.c242
-rw-r--r--daemons/fenced/fenced_remote.c459
-rw-r--r--daemons/fenced/fenced_scheduler.c15
-rw-r--r--daemons/fenced/pacemaker-fenced.c392
-rw-r--r--daemons/fenced/pacemaker-fenced.h14
8 files changed, 950 insertions, 985 deletions
diff --git a/daemons/fenced/cts-fence-helper.c b/daemons/fenced/cts-fence-helper.c
index 07bd500..edde8ca 100644
--- a/daemons/fenced/cts-fence-helper.c
+++ b/daemons/fenced/cts-fence-helper.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2023 the Pacemaker project contributors
+ * Copyright 2009-2024 the Pacemaker project contributors
*
* This source code is licensed under the GNU General Public License version 2
* or later (GPLv2+) WITHOUT ANY WARRANTY.
@@ -20,7 +20,6 @@
#include <fcntl.h>
#include <crm/crm.h>
-#include <crm/msg_xml.h>
#include <crm/common/ipc.h>
#include <crm/cluster/internal.h>
@@ -164,8 +163,10 @@ passive_test(void)
stonith_api_delete(st);
crm_exit(CRM_EX_DISCONNECT);
}
- st->cmds->register_notification(st, T_STONITH_NOTIFY_DISCONNECT, st_callback);
- st->cmds->register_notification(st, T_STONITH_NOTIFY_FENCE, st_callback);
+ st->cmds->register_notification(st, PCMK__VALUE_ST_NOTIFY_DISCONNECT,
+ st_callback);
+ st->cmds->register_notification(st, PCMK__VALUE_ST_NOTIFY_FENCE,
+ st_callback);
st->cmds->register_notification(st, STONITH_OP_DEVICE_ADD, st_callback);
st->cmds->register_notification(st, STONITH_OP_DEVICE_DEL, st_callback);
st->cmds->register_callback(st, 0, 120, st_opt_timeout_updates, NULL, "st_global_callback",
@@ -325,8 +326,10 @@ sanity_tests(void)
stonith_api_delete(st);
crm_exit(CRM_EX_DISCONNECT);
}
- st->cmds->register_notification(st, T_STONITH_NOTIFY_DISCONNECT, st_callback);
- st->cmds->register_notification(st, T_STONITH_NOTIFY_FENCE, st_callback);
+ st->cmds->register_notification(st, PCMK__VALUE_ST_NOTIFY_DISCONNECT,
+ st_callback);
+ st->cmds->register_notification(st, PCMK__VALUE_ST_NOTIFY_FENCE,
+ st_callback);
st->cmds->register_notification(st, STONITH_OP_DEVICE_ADD, st_callback);
st->cmds->register_notification(st, STONITH_OP_DEVICE_DEL, st_callback);
st->cmds->register_callback(st, 0, 120, st_opt_timeout_updates, NULL, "st_global_callback",
diff --git a/daemons/fenced/fenced_cib.c b/daemons/fenced/fenced_cib.c
index e11bf68..6bf0e6f 100644
--- a/daemons/fenced/fenced_cib.c
+++ b/daemons/fenced/fenced_cib.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2023 the Pacemaker project contributors
+ * Copyright 2009-2024 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -15,7 +15,6 @@
#include <libxml/xpath.h>
#include <crm/crm.h>
-#include <crm/msg_xml.h>
#include <crm/common/xml.h>
#include <crm/cluster/internal.h>
@@ -55,11 +54,12 @@ node_has_attr(const char *node, const char *name, const char *value)
*/
xpath = g_string_sized_new(256);
pcmk__g_strcat(xpath,
- "//" XML_CIB_TAG_NODES "/" XML_CIB_TAG_NODE
- "[@" XML_ATTR_UNAME "='", node, "']/" XML_TAG_ATTR_SETS
- "/" XML_CIB_TAG_NVPAIR
- "[@" XML_NVPAIR_ATTR_NAME "='", name, "' "
- "and @" XML_NVPAIR_ATTR_VALUE "='", value, "']", NULL);
+ "//" PCMK_XE_NODES "/" PCMK_XE_NODE
+ "[@" PCMK_XA_UNAME "='", node, "']"
+ "/" PCMK_XE_INSTANCE_ATTRIBUTES
+ "/" PCMK_XE_NVPAIR
+ "[@" PCMK_XA_NAME "='", name, "' "
+ "and @" PCMK_XA_VALUE "='", value, "']", NULL);
match = get_xpath_object((const char *) xpath->str, local_cib, LOG_NEVER);
@@ -76,7 +76,7 @@ add_topology_level(xmlNode *match)
CRM_CHECK(match != NULL, return);
fenced_register_level(match, &desc, &result);
- fenced_send_level_notification(STONITH_OP_LEVEL_ADD, &result, desc);
+ fenced_send_config_notification(STONITH_OP_LEVEL_ADD, &result, desc);
pcmk__reset_result(&result);
free(desc);
}
@@ -86,14 +86,14 @@ topology_remove_helper(const char *node, int level)
{
char *desc = NULL;
pcmk__action_result_t result = PCMK__UNKNOWN_RESULT;
- xmlNode *data = create_xml_node(NULL, XML_TAG_FENCING_LEVEL);
+ xmlNode *data = pcmk__xe_create(NULL, PCMK_XE_FENCING_LEVEL);
- crm_xml_add(data, F_STONITH_ORIGIN, __func__);
- crm_xml_add_int(data, XML_ATTR_STONITH_INDEX, level);
- crm_xml_add(data, XML_ATTR_STONITH_TARGET, node);
+ crm_xml_add(data, PCMK__XA_ST_ORIGIN, __func__);
+ crm_xml_add_int(data, PCMK_XA_INDEX, level);
+ crm_xml_add(data, PCMK_XA_TARGET, node);
fenced_unregister_level(data, &desc, &result);
- fenced_send_level_notification(STONITH_OP_LEVEL_DEL, &result, desc);
+ fenced_send_config_notification(STONITH_OP_LEVEL_DEL, &result, desc);
pcmk__reset_result(&result);
free_xml(data);
free(desc);
@@ -108,7 +108,7 @@ remove_topology_level(xmlNode *match)
CRM_CHECK(match != NULL, return);
key = stonith_level_key(match, fenced_target_by_unknown);
- crm_element_value_int(match, XML_ATTR_STONITH_INDEX, &index);
+ crm_element_value_int(match, PCMK_XA_INDEX, &index);
topology_remove_helper(key, index);
free(key);
}
@@ -149,7 +149,7 @@ void
fencing_topology_init(void)
{
xmlXPathObjectPtr xpathObj = NULL;
- const char *xpath = "//" XML_TAG_FENCING_LEVEL;
+ const char *xpath = "//" PCMK_XE_FENCING_LEVEL;
crm_trace("Full topology refresh");
free_topology_list();
@@ -174,37 +174,41 @@ remove_cib_device(xmlXPathObjectPtr xpathObj)
CRM_LOG_ASSERT(match != NULL);
if(match != NULL) {
- standard = crm_element_value(match, XML_AGENT_ATTR_CLASS);
+ standard = crm_element_value(match, PCMK_XA_CLASS);
}
if (!pcmk__str_eq(standard, PCMK_RESOURCE_CLASS_STONITH, pcmk__str_casei)) {
continue;
}
- rsc_id = crm_element_value(match, XML_ATTR_ID);
+ rsc_id = crm_element_value(match, PCMK_XA_ID);
stonith_device_remove(rsc_id, true);
}
}
+#define XPATH_WATCHDOG_TIMEOUT "//" PCMK_XE_NVPAIR \
+ "[@" PCMK_XA_NAME "='" \
+ PCMK_OPT_STONITH_WATCHDOG_TIMEOUT "']"
+
static void
update_stonith_watchdog_timeout_ms(xmlNode *cib)
{
- long timeout_ms = 0;
+ long long timeout_ms = 0;
xmlNode *stonith_watchdog_xml = NULL;
const char *value = NULL;
- stonith_watchdog_xml = get_xpath_object("//nvpair[@name='stonith-watchdog-timeout']",
- cib, LOG_NEVER);
+ stonith_watchdog_xml = get_xpath_object(XPATH_WATCHDOG_TIMEOUT, cib,
+ LOG_NEVER);
if (stonith_watchdog_xml) {
- value = crm_element_value(stonith_watchdog_xml, XML_NVPAIR_ATTR_VALUE);
+ value = crm_element_value(stonith_watchdog_xml, PCMK_XA_VALUE);
}
if (value) {
timeout_ms = crm_get_msec(value);
}
if (timeout_ms < 0) {
- timeout_ms = pcmk__auto_watchdog_timeout();
+ timeout_ms = pcmk__auto_stonith_watchdog_timeout();
}
stonith_watchdog_timeout_ms = timeout_ms;
@@ -221,9 +225,9 @@ cib_devices_update(void)
stonith_device_t *device = NULL;
crm_info("Updating devices to version %s.%s.%s",
- crm_element_value(local_cib, XML_ATTR_GENERATION_ADMIN),
- crm_element_value(local_cib, XML_ATTR_GENERATION),
- crm_element_value(local_cib, XML_ATTR_NUMUPDATES));
+ crm_element_value(local_cib, PCMK_XA_ADMIN_EPOCH),
+ crm_element_value(local_cib, PCMK_XA_EPOCH),
+ crm_element_value(local_cib, PCMK_XA_NUM_UPDATES));
g_hash_table_iter_init(&iter, device_list);
while (g_hash_table_iter_next(&iter, NULL, (void **)&device)) {
@@ -256,7 +260,9 @@ update_cib_stonith_devices_v1(const char *event, xmlNode * msg)
xmlXPathObjectPtr xpath_obj = NULL;
/* process new constraints */
- xpath_obj = xpath_search(msg, "//" F_CIB_UPDATE_RESULT "//" XML_CONS_TAG_RSC_LOCATION);
+ xpath_obj = xpath_search(msg,
+ "//" PCMK__XE_CIB_UPDATE_RESULT
+ "//" PCMK_XE_RSC_LOCATION);
if (numXpathResults(xpath_obj) > 0) {
int max = numXpathResults(xpath_obj), lpc = 0;
@@ -273,14 +279,20 @@ update_cib_stonith_devices_v1(const char *event, xmlNode * msg)
freeXpathObject(xpath_obj);
/* process deletions */
- xpath_obj = xpath_search(msg, "//" F_CIB_UPDATE_RESULT "//" XML_TAG_DIFF_REMOVED "//" XML_CIB_TAG_RESOURCE);
+ xpath_obj = xpath_search(msg,
+ "//" PCMK__XE_CIB_UPDATE_RESULT
+ "//" PCMK__XE_DIFF_REMOVED
+ "//" PCMK_XE_PRIMITIVE);
if (numXpathResults(xpath_obj) > 0) {
remove_cib_device(xpath_obj);
}
freeXpathObject(xpath_obj);
/* process additions */
- xpath_obj = xpath_search(msg, "//" F_CIB_UPDATE_RESULT "//" XML_TAG_DIFF_ADDED "//" XML_CIB_TAG_RESOURCE);
+ xpath_obj = xpath_search(msg,
+ "//" PCMK__XE_CIB_UPDATE_RESULT
+ "//" PCMK__XE_DIFF_ADDED
+ "//" PCMK_XE_PRIMITIVE);
if (numXpathResults(xpath_obj) > 0) {
int max = numXpathResults(xpath_obj), lpc = 0;
@@ -289,8 +301,8 @@ update_cib_stonith_devices_v1(const char *event, xmlNode * msg)
const char *standard = NULL;
xmlNode *match = getXpathResult(xpath_obj, lpc);
- rsc_id = crm_element_value(match, XML_ATTR_ID);
- standard = crm_element_value(match, XML_AGENT_ATTR_CLASS);
+ rsc_id = crm_element_value(match, PCMK_XA_ID);
+ standard = crm_element_value(match, PCMK_XA_CLASS);
if (!pcmk__str_eq(standard, PCMK_RESOURCE_CLASS_STONITH, pcmk__str_casei)) {
continue;
@@ -314,35 +326,39 @@ update_cib_stonith_devices_v2(const char *event, xmlNode * msg)
{
xmlNode *change = NULL;
char *reason = NULL;
- bool needs_update = FALSE;
- xmlNode *patchset = get_message_xml(msg, F_CIB_UPDATE_RESULT);
+ xmlNode *wrapper = pcmk__xe_first_child(msg, PCMK__XE_CIB_UPDATE_RESULT,
+ NULL, NULL);
+ xmlNode *patchset = pcmk__xe_first_child(wrapper, NULL, NULL, NULL);
+
+ for (change = pcmk__xe_first_child(patchset, NULL, NULL, NULL);
+ change != NULL; change = pcmk__xe_next(change)) {
- for (change = pcmk__xml_first_child(patchset); change != NULL;
- change = pcmk__xml_next(change)) {
- const char *op = crm_element_value(change, XML_DIFF_OP);
- const char *xpath = crm_element_value(change, XML_DIFF_PATH);
+ const char *op = crm_element_value(change, PCMK_XA_OPERATION);
+ const char *xpath = crm_element_value(change, PCMK_XA_PATH);
const char *shortpath = NULL;
- if ((op == NULL) ||
- (strcmp(op, "move") == 0) ||
- strstr(xpath, "/"XML_CIB_TAG_STATUS)) {
+ if (pcmk__str_eq(op, PCMK_VALUE_MOVE, pcmk__str_null_matches)
+ || (strstr(xpath, "/" PCMK_XE_STATUS) != NULL)) {
continue;
- } else if (pcmk__str_eq(op, "delete", pcmk__str_casei) && strstr(xpath, "/"XML_CIB_TAG_RESOURCE)) {
+ }
+
+ if (pcmk__str_eq(op, PCMK_VALUE_DELETE, pcmk__str_none)
+ && (strstr(xpath, "/" PCMK_XE_PRIMITIVE) != NULL)) {
const char *rsc_id = NULL;
char *search = NULL;
char *mutable = NULL;
- if (strstr(xpath, XML_TAG_ATTR_SETS) ||
- strstr(xpath, XML_TAG_META_SETS)) {
- needs_update = TRUE;
- pcmk__str_update(&reason,
- "(meta) attribute deleted from resource");
+ if ((strstr(xpath, PCMK_XE_INSTANCE_ATTRIBUTES) != NULL)
+ || (strstr(xpath, PCMK_XE_META_ATTRIBUTES) != NULL)) {
+
+ reason = pcmk__str_copy("(meta) attribute deleted from "
+ "resource");
break;
}
- pcmk__str_update(&mutable, xpath);
- rsc_id = strstr(mutable, "primitive[@" XML_ATTR_ID "=\'");
+ mutable = pcmk__str_copy(xpath);
+ rsc_id = strstr(mutable, PCMK_XE_PRIMITIVE "[@" PCMK_XA_ID "=\'");
if (rsc_id != NULL) {
- rsc_id += strlen("primitive[@" XML_ATTR_ID "=\'");
+ rsc_id += strlen(PCMK_XE_PRIMITIVE "[@" PCMK_XA_ID "=\'");
search = strchr(rsc_id, '\'');
}
if (search != NULL) {
@@ -355,30 +371,31 @@ update_cib_stonith_devices_v2(const char *event, xmlNode * msg)
}
free(mutable);
- } else if (strstr(xpath, "/"XML_CIB_TAG_RESOURCES) ||
- strstr(xpath, "/"XML_CIB_TAG_CONSTRAINTS) ||
- strstr(xpath, "/"XML_CIB_TAG_RSCCONFIG)) {
+ } else if (strstr(xpath, "/" PCMK_XE_RESOURCES)
+ || strstr(xpath, "/" PCMK_XE_CONSTRAINTS)
+ || strstr(xpath, "/" PCMK_XE_RSC_DEFAULTS)) {
shortpath = strrchr(xpath, '/'); CRM_ASSERT(shortpath);
reason = crm_strdup_printf("%s %s", op, shortpath+1);
- needs_update = TRUE;
break;
}
}
- if(needs_update) {
+ if (reason != NULL) {
crm_info("Updating device list from CIB: %s", reason);
cib_devices_update();
+ free(reason);
} else {
crm_trace("No updates for device list found in CIB");
}
- free(reason);
}
static void
update_cib_stonith_devices(const char *event, xmlNode * msg)
{
int format = 1;
- xmlNode *patchset = get_message_xml(msg, F_CIB_UPDATE_RESULT);
+ xmlNode *wrapper = pcmk__xe_first_child(msg, PCMK__XE_CIB_UPDATE_RESULT,
+ NULL, NULL);
+ xmlNode *patchset = pcmk__xe_first_child(wrapper, NULL, NULL, NULL);
CRM_ASSERT(patchset);
crm_element_value_int(patchset, PCMK_XA_FORMAT, &format);
@@ -465,17 +482,19 @@ remove_fencing_topology(xmlXPathObjectPtr xpathObj)
xmlNode *match = getXpathResult(xpathObj, lpc);
CRM_LOG_ASSERT(match != NULL);
- if (match && crm_element_value(match, XML_DIFF_MARKER)) {
+ if (match && crm_element_value(match, PCMK__XA_CRM_DIFF_MARKER)) {
/* Deletion */
int index = 0;
char *target = stonith_level_key(match, fenced_target_by_unknown);
- crm_element_value_int(match, XML_ATTR_STONITH_INDEX, &index);
+ crm_element_value_int(match, PCMK_XA_INDEX, &index);
if (target == NULL) {
- crm_err("Invalid fencing target in element %s", ID(match));
+ crm_err("Invalid fencing target in element %s",
+ pcmk__xe_id(match));
} else if (index <= 0) {
- crm_err("Invalid level for %s in element %s", target, ID(match));
+ crm_err("Invalid level for %s in element %s",
+ target, pcmk__xe_id(match));
} else {
topology_remove_helper(target, index);
@@ -491,21 +510,27 @@ update_fencing_topology(const char *event, xmlNode * msg)
int format = 1;
const char *xpath;
xmlXPathObjectPtr xpathObj = NULL;
- xmlNode *patchset = get_message_xml(msg, F_CIB_UPDATE_RESULT);
+ xmlNode *wrapper = pcmk__xe_first_child(msg, PCMK__XE_CIB_UPDATE_RESULT,
+ NULL, NULL);
+ xmlNode *patchset = pcmk__xe_first_child(wrapper, NULL, NULL, NULL);
CRM_ASSERT(patchset);
crm_element_value_int(patchset, PCMK_XA_FORMAT, &format);
if(format == 1) {
/* Process deletions (only) */
- xpath = "//" F_CIB_UPDATE_RESULT "//" XML_TAG_DIFF_REMOVED "//" XML_TAG_FENCING_LEVEL;
+ xpath = "//" PCMK__XE_CIB_UPDATE_RESULT
+ "//" PCMK__XE_DIFF_REMOVED
+ "//" PCMK_XE_FENCING_LEVEL;
xpathObj = xpath_search(msg, xpath);
remove_fencing_topology(xpathObj);
freeXpathObject(xpathObj);
/* Process additions and changes */
- xpath = "//" F_CIB_UPDATE_RESULT "//" XML_TAG_DIFF_ADDED "//" XML_TAG_FENCING_LEVEL;
+ xpath = "//" PCMK__XE_CIB_UPDATE_RESULT
+ "//" PCMK__XE_DIFF_ADDED
+ "//" PCMK_XE_FENCING_LEVEL;
xpathObj = xpath_search(msg, xpath);
register_fencing_topology(xpathObj);
@@ -518,33 +543,36 @@ update_fencing_topology(const char *event, xmlNode * msg)
xml_patch_versions(patchset, add, del);
- for (change = pcmk__xml_first_child(patchset); change != NULL;
- change = pcmk__xml_next(change)) {
- const char *op = crm_element_value(change, XML_DIFF_OP);
- const char *xpath = crm_element_value(change, XML_DIFF_PATH);
+ for (change = pcmk__xe_first_child(patchset, NULL, NULL, NULL);
+ change != NULL; change = pcmk__xe_next(change)) {
+
+ const char *op = crm_element_value(change, PCMK_XA_OPERATION);
+ const char *xpath = crm_element_value(change, PCMK_XA_PATH);
if(op == NULL) {
continue;
- } else if(strstr(xpath, "/" XML_TAG_FENCING_LEVEL) != NULL) {
+ } else if(strstr(xpath, "/" PCMK_XE_FENCING_LEVEL) != NULL) {
/* Change to a specific entry */
crm_trace("Handling %s operation %d.%d.%d for %s", op, add[0], add[1], add[2], xpath);
- if(strcmp(op, "move") == 0) {
+ if (strcmp(op, PCMK_VALUE_MOVE) == 0) {
continue;
- } else if(strcmp(op, "create") == 0) {
+ } else if (strcmp(op, PCMK_VALUE_CREATE) == 0) {
add_topology_level(change->children);
- } else if(strcmp(op, "modify") == 0) {
- xmlNode *match = first_named_child(change, XML_DIFF_RESULT);
+ } else if (strcmp(op, PCMK_VALUE_MODIFY) == 0) {
+ xmlNode *match = pcmk__xe_first_child(change,
+ PCMK_XE_CHANGE_RESULT,
+ NULL, NULL);
if(match) {
remove_topology_level(match->children);
add_topology_level(match->children);
}
- } else if(strcmp(op, "delete") == 0) {
+ } else if (strcmp(op, PCMK_VALUE_DELETE) == 0) {
/* Nuclear option, all we have is the path and an id... not enough to remove a specific entry */
crm_info("Re-initializing fencing topology after %s operation %d.%d.%d for %s",
op, add[0], add[1], add[2], xpath);
@@ -552,20 +580,23 @@ update_fencing_topology(const char *event, xmlNode * msg)
return;
}
- } else if (strstr(xpath, "/" XML_TAG_FENCING_TOPOLOGY) != NULL) {
+ } else if (strstr(xpath, "/" PCMK_XE_FENCING_TOPOLOGY) != NULL) {
/* Change to the topology in general */
crm_info("Re-initializing fencing topology after top-level %s operation %d.%d.%d for %s",
op, add[0], add[1], add[2], xpath);
fencing_topology_init();
return;
- } else if (strstr(xpath, "/" XML_CIB_TAG_CONFIGURATION)) {
+ } else if (strstr(xpath, "/" PCMK_XE_CONFIGURATION)) {
/* Changes to the whole config section, possibly including the topology as a whild */
- if(first_named_child(change, XML_TAG_FENCING_TOPOLOGY) == NULL) {
+ if (pcmk__xe_first_child(change, PCMK_XE_FENCING_TOPOLOGY, NULL,
+ NULL) == NULL) {
crm_trace("Nothing for us in %s operation %d.%d.%d for %s.",
op, add[0], add[1], add[2], xpath);
- } else if(strcmp(op, "delete") == 0 || strcmp(op, "create") == 0) {
+ } else if (pcmk__str_any_of(op,
+ PCMK_VALUE_DELETE,
+ PCMK_VALUE_CREATE, NULL)) {
crm_info("Re-initializing fencing topology after top-level %s operation %d.%d.%d for %s.",
op, add[0], add[1], add[2], xpath);
fencing_topology_init();
@@ -586,7 +617,7 @@ update_fencing_topology(const char *event, xmlNode * msg)
static void
update_cib_cache_cb(const char *event, xmlNode * msg)
{
- long timeout_ms_saved = stonith_watchdog_timeout_ms;
+ long long timeout_ms_saved = stonith_watchdog_timeout_ms;
bool need_full_refresh = false;
if(!have_cib_devices) {
@@ -603,14 +634,18 @@ update_cib_cache_cb(const char *event, xmlNode * msg)
*/
if (local_cib != NULL) {
int rc = pcmk_ok;
+ xmlNode *wrapper = NULL;
xmlNode *patchset = NULL;
- crm_element_value_int(msg, F_CIB_RC, &rc);
+ crm_element_value_int(msg, PCMK__XA_CIB_RC, &rc);
if (rc != pcmk_ok) {
return;
}
- 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);
+
rc = xml_apply_patchset(local_cib, patchset, TRUE);
switch (rc) {
case pcmk_ok:
@@ -660,7 +695,7 @@ init_cib_cache_cb(xmlNode * msg, int call_id, int rc, xmlNode * output, void *us
{
crm_info("Updating device list from CIB");
have_cib_devices = TRUE;
- local_cib = copy_xml(output);
+ local_cib = pcmk__xml_copy(NULL, output);
pcmk__refresh_node_caches_from_cib(local_cib);
update_stonith_watchdog_timeout_ms(local_cib);
@@ -693,7 +728,7 @@ void
fenced_cib_cleanup(void)
{
if (cib_api != NULL) {
- cib_api->cmds->del_notify_callback(cib_api, T_CIB_DIFF_NOTIFY,
+ cib_api->cmds->del_notify_callback(cib_api, PCMK__VALUE_CIB_DIFF_NOTIFY,
update_cib_cache_cb);
cib__clean_up_connection(&cib_api);
}
@@ -719,16 +754,20 @@ setup_cib(void)
if (rc != pcmk_ok) {
crm_err("Could not connect to the CIB manager: %s (%d)", pcmk_strerror(rc), rc);
+ return;
+ }
- } else if (pcmk_ok !=
- cib_api->cmds->add_notify_callback(cib_api, T_CIB_DIFF_NOTIFY, update_cib_cache_cb)) {
+ rc = cib_api->cmds->add_notify_callback(cib_api,
+ PCMK__VALUE_CIB_DIFF_NOTIFY,
+ update_cib_cache_cb);
+ if (rc != pcmk_ok) {
crm_err("Could not set CIB notification callback");
-
- } else {
- rc = cib_api->cmds->query(cib_api, NULL, NULL, cib_scope_local);
- cib_api->cmds->register_callback(cib_api, rc, 120, FALSE, NULL, "init_cib_cache_cb",
- init_cib_cache_cb);
- cib_api->cmds->set_connection_dnotify(cib_api, cib_connection_destroy);
- crm_info("Watching for fencing topology changes");
+ return;
}
+
+ rc = cib_api->cmds->query(cib_api, NULL, NULL, cib_scope_local);
+ cib_api->cmds->register_callback(cib_api, rc, 120, FALSE, NULL,
+ "init_cib_cache_cb", init_cib_cache_cb);
+ cib_api->cmds->set_connection_dnotify(cib_api, cib_connection_destroy);
+ crm_info("Watching for fencing topology changes");
}
diff --git a/daemons/fenced/fenced_commands.c b/daemons/fenced/fenced_commands.c
index 7a62ed6..223a701 100644
--- a/daemons/fenced/fenced_commands.c
+++ b/daemons/fenced/fenced_commands.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2023 the Pacemaker project contributors
+ * Copyright 2009-2024 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -23,7 +23,6 @@
#include <ctype.h>
#include <crm/crm.h>
-#include <crm/msg_xml.h>
#include <crm/common/ipc.h>
#include <crm/common/ipc_internal.h>
#include <crm/cluster/internal.h>
@@ -129,7 +128,7 @@ static int
get_action_delay_max(const stonith_device_t *device, const char *action)
{
const char *value = NULL;
- int delay_max = 0;
+ guint delay_max = 0U;
if (!pcmk__is_fencing_action(action)) {
return 0;
@@ -137,10 +136,11 @@ get_action_delay_max(const stonith_device_t *device, const char *action)
value = g_hash_table_lookup(device->params, PCMK_STONITH_DELAY_MAX);
if (value) {
- delay_max = crm_parse_interval_spec(value) / 1000;
+ pcmk_parse_interval_spec(value, &delay_max);
+ delay_max /= 1000;
}
- return delay_max;
+ return (int) delay_max;
}
static int
@@ -148,7 +148,7 @@ get_action_delay_base(const stonith_device_t *device, const char *action,
const char *target)
{
char *hash_value = NULL;
- int delay_base = 0;
+ guint delay_base = 0U;
if (!pcmk__is_fencing_action(action)) {
return 0;
@@ -157,11 +157,9 @@ get_action_delay_base(const stonith_device_t *device, const char *action,
hash_value = g_hash_table_lookup(device->params, PCMK_STONITH_DELAY_BASE);
if (hash_value) {
- char *value = strdup(hash_value);
+ char *value = pcmk__str_copy(hash_value);
char *valptr = value;
- CRM_ASSERT(value != NULL);
-
if (target != NULL) {
for (char *val = strtok(value, "; \t"); val != NULL; val = strtok(NULL, "; \t")) {
char *mapval = strchr(val, ':');
@@ -181,13 +179,14 @@ get_action_delay_base(const stonith_device_t *device, const char *action,
}
if (strchr(value, ':') == 0) {
- delay_base = crm_parse_interval_spec(value) / 1000;
+ pcmk_parse_interval_spec(value, &delay_base);
+ delay_base /= 1000;
}
free(valptr);
}
- return delay_base;
+ return (int) delay_base;
}
/*!
@@ -232,7 +231,8 @@ get_action_timeout(const stonith_device_t *device, const char *action,
snprintf(buffer, sizeof(buffer), "pcmk_%s_timeout", action);
value = g_hash_table_lookup(device->params, buffer);
if (value) {
- return atoi(value);
+ long long timeout_ms = crm_get_msec(value);
+ return (int) QB_MIN(timeout_ms / 1000, INT_MAX);
}
}
return default_timeout;
@@ -345,34 +345,33 @@ create_async_command(xmlNode *msg)
return NULL;
}
- op = get_xpath_object("//@" F_STONITH_ACTION, msg, LOG_ERR);
+ op = get_xpath_object("//@" PCMK__XE_ST_DEVICE_ACTION, msg, LOG_ERR);
if (op == NULL) {
return NULL;
}
- cmd = calloc(1, sizeof(async_command_t));
- CRM_ASSERT(cmd != NULL);
+ cmd = pcmk__assert_alloc(1, sizeof(async_command_t));
// All messages must include these
- cmd->action = crm_element_value_copy(op, F_STONITH_ACTION);
- cmd->op = crm_element_value_copy(msg, F_STONITH_OPERATION);
- cmd->client = crm_element_value_copy(msg, F_STONITH_CLIENTID);
+ cmd->action = crm_element_value_copy(op, PCMK__XA_ST_DEVICE_ACTION);
+ cmd->op = crm_element_value_copy(msg, PCMK__XA_ST_OP);
+ cmd->client = crm_element_value_copy(msg, PCMK__XA_ST_CLIENTID);
if ((cmd->action == NULL) || (cmd->op == NULL) || (cmd->client == NULL)) {
free_async_command(cmd);
return NULL;
}
- crm_element_value_int(msg, F_STONITH_CALLID, &(cmd->id));
- crm_element_value_int(msg, F_STONITH_CALLOPTS, &(cmd->options));
- crm_element_value_int(msg, F_STONITH_DELAY, &(cmd->start_delay));
- crm_element_value_int(msg, F_STONITH_TIMEOUT, &(cmd->default_timeout));
+ crm_element_value_int(msg, PCMK__XA_ST_CALLID, &(cmd->id));
+ crm_element_value_int(msg, PCMK__XA_ST_CALLOPT, &(cmd->options));
+ crm_element_value_int(msg, PCMK__XA_ST_DELAY, &(cmd->start_delay));
+ crm_element_value_int(msg, PCMK__XA_ST_TIMEOUT, &(cmd->default_timeout));
cmd->timeout = cmd->default_timeout;
- cmd->origin = crm_element_value_copy(msg, F_ORIG);
- cmd->remote_op_id = crm_element_value_copy(msg, F_STONITH_REMOTE_OP_ID);
- cmd->client_name = crm_element_value_copy(msg, F_STONITH_CLIENTNAME);
- cmd->target = crm_element_value_copy(op, F_STONITH_TARGET);
- cmd->device = crm_element_value_copy(op, F_STONITH_DEVICE);
+ cmd->origin = crm_element_value_copy(msg, PCMK__XA_SRC);
+ cmd->remote_op_id = crm_element_value_copy(msg, PCMK__XA_ST_REMOTE_OP);
+ cmd->client_name = crm_element_value_copy(msg, PCMK__XA_ST_CLIENTNAME);
+ cmd->target = crm_element_value_copy(op, PCMK__XA_ST_TARGET);
+ cmd->device = crm_element_value_copy(op, PCMK__XA_ST_DEVICE_ID);
cmd->done_cb = st_child_done;
@@ -645,12 +644,13 @@ schedule_stonith_command(async_command_t * cmd, stonith_device_t * device)
}
if (device->include_nodeid && (cmd->target != NULL)) {
- crm_node_t *node = crm_get_peer(0, cmd->target);
+ crm_node_t *node = pcmk__get_node(0, cmd->target, NULL,
+ pcmk__node_search_cluster_member);
cmd->target_nodeid = node->id;
}
- cmd->device = strdup(device->id);
+ cmd->device = pcmk__str_copy(device->id);
cmd->timeout = get_action_timeout(device, cmd->action, cmd->default_timeout);
if (cmd->remote_op_id) {
@@ -785,7 +785,7 @@ build_port_aliases(const char *hostmap, GList ** targets)
case ':':
if (lpc > last) {
free(name);
- name = calloc(1, 1 + lpc - last);
+ name = pcmk__assert_alloc(1, 1 + lpc - last);
memcpy(name, hostmap + last, lpc - last);
}
last = lpc + 1;
@@ -801,7 +801,7 @@ build_port_aliases(const char *hostmap, GList ** targets)
char *value = NULL;
int k = 0;
- value = calloc(1, 1 + lpc - last);
+ value = pcmk__assert_alloc(1, 1 + lpc - last);
memcpy(value, hostmap + last, lpc - last);
for (int i = 0; value[i] != '\0'; i++) {
@@ -814,7 +814,7 @@ build_port_aliases(const char *hostmap, GList ** targets)
crm_debug("Adding alias '%s'='%s'", name, value);
g_hash_table_replace(aliases, name, value);
if (targets) {
- *targets = g_list_append(*targets, strdup(value));
+ *targets = g_list_append(*targets, pcmk__str_copy(value));
}
value = NULL;
name = NULL;
@@ -888,10 +888,10 @@ get_agent_metadata(const char *agent, xmlNode ** metadata)
crm_err("Could not retrieve metadata for fencing agent %s", agent);
return EAGAIN;
}
- g_hash_table_replace(metadata_cache, strdup(agent), buffer);
+ g_hash_table_replace(metadata_cache, pcmk__str_copy(agent), buffer);
}
- *metadata = string2xml(buffer);
+ *metadata = pcmk__xml_parse(buffer);
return pcmk_rc_ok;
}
@@ -908,7 +908,8 @@ is_nodeid_required(xmlNode * xml)
return FALSE;
}
- xpath = xpath_search(xml, "//parameter[@name='nodeid']");
+ xpath = xpath_search(xml,
+ "//" PCMK_XE_PARAMETER "[@" PCMK_XA_NAME "='nodeid']");
if (numXpathResults(xpath) <= 0) {
freeXpathObject(xpath);
return FALSE;
@@ -944,7 +945,7 @@ read_action_metadata(stonith_device_t *device)
CRM_LOG_ASSERT(match != NULL);
if(match == NULL) { continue; };
- action = crm_element_value(match, "name");
+ action = crm_element_value(match, PCMK_XA_NAME);
if (pcmk__str_eq(action, PCMK_ACTION_LIST, pcmk__str_none)) {
stonith__set_device_flags(device->flags, device->id,
@@ -956,16 +957,23 @@ read_action_metadata(stonith_device_t *device)
stonith__set_device_flags(device->flags, device->id,
st_device_supports_reboot);
} else if (pcmk__str_eq(action, PCMK_ACTION_ON, pcmk__str_none)) {
- /* "automatic" means the cluster will unfence node when it joins */
- /* "required" is a deprecated synonym for "automatic" */
- if (pcmk__xe_attr_is_true(match, "automatic") || pcmk__xe_attr_is_true(match, "required")) {
+ /* PCMK_XA_AUTOMATIC means the cluster will unfence a node when it
+ * joins.
+ *
+ * @COMPAT PCMK__XA_REQUIRED is a deprecated synonym for
+ * PCMK_XA_AUTOMATIC.
+ */
+ if (pcmk__xe_attr_is_true(match, PCMK_XA_AUTOMATIC)
+ || pcmk__xe_attr_is_true(match, PCMK__XA_REQUIRED)) {
device->automatic_unfencing = TRUE;
}
stonith__set_device_flags(device->flags, device->id,
st_device_supports_on);
}
- if ((action != NULL) && pcmk__xe_attr_is_true(match, "on_target")) {
+ if ((action != NULL)
+ && pcmk__xe_attr_is_true(match, PCMK_XA_ON_TARGET)) {
+
pcmk__add_word(&(device->on_target_actions), 64, action);
}
}
@@ -993,7 +1001,7 @@ map_action(GHashTable *params, const char *action, const char *value)
} else {
crm_warn("Mapping %s='%s' to %s='%s'",
STONITH_ATTR_ACTION_OP, value, key, value);
- g_hash_table_insert(params, key, strdup(value));
+ g_hash_table_insert(params, key, pcmk__str_copy(value));
}
}
@@ -1023,7 +1031,8 @@ xml2device_params(const char *name, const xmlNode *dev)
crm_warn("Ignoring empty '%s' parameter", STONITH_ATTR_ACTION_OP);
} else if (strcmp(value, PCMK_ACTION_REBOOT) == 0) {
- crm_warn("Ignoring %s='reboot' (see stonith-action cluster property instead)",
+ crm_warn("Ignoring %s='reboot' (see " PCMK_OPT_STONITH_ACTION
+ " cluster property instead)",
STONITH_ATTR_ACTION_OP);
} else if (strcmp(value, PCMK_ACTION_OFF) == 0) {
@@ -1050,15 +1059,15 @@ target_list_type(stonith_device_t * dev)
if (check_type == NULL) {
if (g_hash_table_lookup(dev->params, PCMK_STONITH_HOST_LIST)) {
- check_type = "static-list";
+ check_type = PCMK_VALUE_STATIC_LIST;
} else if (g_hash_table_lookup(dev->params, PCMK_STONITH_HOST_MAP)) {
- check_type = "static-list";
+ check_type = PCMK_VALUE_STATIC_LIST;
} else if (pcmk_is_set(dev->flags, st_device_supports_list)) {
- check_type = "dynamic-list";
+ check_type = PCMK_VALUE_DYNAMIC_LIST;
} else if (pcmk_is_set(dev->flags, st_device_supports_status)) {
- check_type = "status";
+ check_type = PCMK_VALUE_STATUS;
} else {
- check_type = PCMK__VALUE_NONE;
+ check_type = PCMK_VALUE_NONE;
}
}
@@ -1070,17 +1079,15 @@ build_device_from_xml(xmlNode *dev)
{
const char *value;
stonith_device_t *device = NULL;
- char *agent = crm_element_value_copy(dev, "agent");
+ char *agent = crm_element_value_copy(dev, PCMK_XA_AGENT);
CRM_CHECK(agent != NULL, return device);
- device = calloc(1, sizeof(stonith_device_t));
-
- CRM_CHECK(device != NULL, {free(agent); return device;});
+ device = pcmk__assert_alloc(1, sizeof(stonith_device_t));
- device->id = crm_element_value_copy(dev, XML_ATTR_ID);
+ device->id = crm_element_value_copy(dev, PCMK_XA_ID);
device->agent = agent;
- device->namespace = crm_element_value_copy(dev, "namespace");
+ device->namespace = crm_element_value_copy(dev, PCMK__XA_NAMESPACE);
device->params = xml2device_params(device->id, dev);
value = g_hash_table_lookup(device->params, PCMK_STONITH_HOST_LIST);
@@ -1092,8 +1099,10 @@ build_device_from_xml(xmlNode *dev)
device->aliases = build_port_aliases(value, &(device->targets));
value = target_list_type(device);
- if (!pcmk__str_eq(value, "static-list", pcmk__str_casei) && device->targets) {
- /* Other than "static-list", dev-> targets is unnecessary. */
+ if (!pcmk__str_eq(value, PCMK_VALUE_STATIC_LIST, pcmk__str_casei)
+ && (device->targets != NULL)) {
+
+ // device->targets is necessary only with PCMK_VALUE_STATIC_LIST
g_list_free_full(device->targets, free);
device->targets = NULL;
}
@@ -1125,8 +1134,8 @@ build_device_from_xml(xmlNode *dev)
device->include_nodeid = is_nodeid_required(device->agent_metadata);
}
- value = crm_element_value(dev, "rsc_provides");
- if (pcmk__str_eq(value, PCMK__VALUE_UNFENCING, pcmk__str_casei)) {
+ value = crm_element_value(dev, PCMK__XA_RSC_PROVIDES);
+ if (pcmk__str_eq(value, PCMK_VALUE_UNFENCING, pcmk__str_casei)) {
device->automatic_unfencing = TRUE;
}
@@ -1159,17 +1168,17 @@ schedule_internal_command(const char *origin,
{
async_command_t *cmd = NULL;
- cmd = calloc(1, sizeof(async_command_t));
+ cmd = pcmk__assert_alloc(1, sizeof(async_command_t));
cmd->id = -1;
cmd->default_timeout = timeout ? timeout : 60;
cmd->timeout = cmd->default_timeout;
- cmd->action = strdup(action);
- pcmk__str_update(&cmd->target, target);
- cmd->device = strdup(device->id);
- cmd->origin = strdup(origin);
- cmd->client = strdup(crm_system_name);
- cmd->client_name = strdup(crm_system_name);
+ cmd->action = pcmk__str_copy(action);
+ cmd->target = pcmk__str_copy(target);
+ cmd->device = pcmk__str_copy(device->id);
+ cmd->origin = pcmk__str_copy(origin);
+ cmd->client = pcmk__str_copy(crm_system_name);
+ cmd->client_name = pcmk__str_copy(crm_system_name);
cmd->internal_user_data = internal_user_data;
cmd->done_cb = done_cb; /* cmd, not internal_user_data, is passed to 'done_cb' as the userdata */
@@ -1292,13 +1301,13 @@ dynamic_list_search_cb(int pid, const pcmk__action_result_t *result,
((result->exit_reason == NULL)? "" : ")"));
}
- /* Fall back to pcmk_host_check="status" if the user didn't explicitly
- * specify "dynamic-list".
+ /* Fall back to pcmk_host_check=PCMK_VALUE_STATUS if the user didn't
+ * explicitly specify PCMK_VALUE_DYNAMIC_LIST
*/
if (g_hash_table_lookup(dev->params, PCMK_STONITH_HOST_CHECK) == NULL) {
crm_notice("Switching to pcmk_host_check='status' for %s", dev->id);
- g_hash_table_replace(dev->params, strdup(PCMK_STONITH_HOST_CHECK),
- strdup("status"));
+ pcmk__insert_dup(dev->params, PCMK_STONITH_HOST_CHECK,
+ PCMK_VALUE_STATUS);
}
}
@@ -1330,7 +1339,7 @@ device_params_diff(GHashTable *first, GHashTable *second) {
if(strstr(key, "CRM_meta") == key) {
continue;
- } else if(strcmp(key, "crm_feature_set") == 0) {
+ } else if (strcmp(key, PCMK_XA_CRM_FEATURE_SET) == 0) {
continue;
} else {
char *other_value = g_hash_table_lookup(second, key);
@@ -1389,7 +1398,7 @@ stonith_device_register(xmlNode *dev, gboolean from_cib)
STONITH_WATCHDOG_AGENT_INTERNAL, NULL)) do {
if (stonith_watchdog_timeout_ms <= 0) {
crm_err("Ignoring watchdog fence device without "
- "stonith-watchdog-timeout set.");
+ PCMK_OPT_STONITH_WATCHDOG_TIMEOUT " set.");
rv = -ENODEV;
/* fall through to cleanup & return */
} else if (!pcmk__str_any_of(device->agent, STONITH_WATCHDOG_AGENT,
@@ -1419,9 +1428,8 @@ stonith_device_register(xmlNode *dev, gboolean from_cib)
if (node_does_watchdog_fencing(stonith_our_uname)) {
g_list_free_full(device->targets, free);
device->targets = stonith__parse_targets(stonith_our_uname);
- g_hash_table_replace(device->params,
- strdup(PCMK_STONITH_HOST_LIST),
- strdup(stonith_our_uname));
+ pcmk__insert_dup(device->params,
+ PCMK_STONITH_HOST_LIST, stonith_our_uname);
/* proceed as with any other stonith-device */
break;
}
@@ -1578,18 +1586,18 @@ stonith_level_key(const xmlNode *level, enum fenced_target_by mode)
}
switch (mode) {
case fenced_target_by_name:
- return crm_element_value_copy(level, XML_ATTR_STONITH_TARGET);
+ return crm_element_value_copy(level, PCMK_XA_TARGET);
case fenced_target_by_pattern:
- return crm_element_value_copy(level, XML_ATTR_STONITH_TARGET_PATTERN);
+ return crm_element_value_copy(level, PCMK_XA_TARGET_PATTERN);
case fenced_target_by_attribute:
return crm_strdup_printf("%s=%s",
- crm_element_value(level, XML_ATTR_STONITH_TARGET_ATTRIBUTE),
- crm_element_value(level, XML_ATTR_STONITH_TARGET_VALUE));
+ crm_element_value(level, PCMK_XA_TARGET_ATTRIBUTE),
+ crm_element_value(level, PCMK_XA_TARGET_VALUE));
default:
- return crm_strdup_printf("unknown-%s", ID(level));
+ return crm_strdup_printf("unknown-%s", pcmk__xe_id(level));
}
}
@@ -1604,15 +1612,15 @@ stonith_level_key(const xmlNode *level, enum fenced_target_by mode)
static enum fenced_target_by
unpack_level_kind(const xmlNode *level)
{
- if (crm_element_value(level, XML_ATTR_STONITH_TARGET) != NULL) {
+ if (crm_element_value(level, PCMK_XA_TARGET) != NULL) {
return fenced_target_by_name;
}
- if (crm_element_value(level, XML_ATTR_STONITH_TARGET_PATTERN) != NULL) {
+ if (crm_element_value(level, PCMK_XA_TARGET_PATTERN) != NULL) {
return fenced_target_by_pattern;
}
if (!stand_alone /* if standalone, there's no attribute manager */
- && (crm_element_value(level, XML_ATTR_STONITH_TARGET_ATTRIBUTE) != NULL)
- && (crm_element_value(level, XML_ATTR_STONITH_TARGET_VALUE) != NULL)) {
+ && (crm_element_value(level, PCMK_XA_TARGET_ATTRIBUTE) != NULL)
+ && (crm_element_value(level, PCMK_XA_TARGET_VALUE) != NULL)) {
return fenced_target_by_attribute;
}
return fenced_target_by_unknown;
@@ -1670,8 +1678,8 @@ unpack_level_request(xmlNode *xml, enum fenced_target_by *mode, char **target,
* search by xpath, because it might give multiple hits if the XML is the
* CIB.
*/
- if ((xml != NULL) && !pcmk__xe_is(xml, XML_TAG_FENCING_LEVEL)) {
- xml = get_xpath_object("//" XML_TAG_FENCING_LEVEL, xml, LOG_WARNING);
+ if ((xml != NULL) && !pcmk__xe_is(xml, PCMK_XE_FENCING_LEVEL)) {
+ xml = get_xpath_object("//" PCMK_XE_FENCING_LEVEL, xml, LOG_WARNING);
}
if (xml == NULL) {
@@ -1681,7 +1689,7 @@ unpack_level_request(xmlNode *xml, enum fenced_target_by *mode, char **target,
} else {
local_mode = unpack_level_kind(xml);
local_target = stonith_level_key(xml, local_mode);
- crm_element_value_int(xml, XML_ATTR_STONITH_INDEX, &local_id);
+ crm_element_value_int(xml, PCMK_XA_INDEX, &local_id);
if (desc != NULL) {
*desc = crm_strdup_printf("%s[%d]", local_target, local_id);
}
@@ -1737,7 +1745,7 @@ fenced_register_level(xmlNode *msg, char **desc, pcmk__action_result_t *result)
}
// Ensure an ID was given (even the client API adds an ID)
- if (pcmk__str_empty(ID(level))) {
+ if (pcmk__str_empty(pcmk__xe_id(level))) {
crm_warn("Ignoring registration for topology level without ID");
free(target);
crm_log_xml_trace(level, "Bad level");
@@ -1749,12 +1757,12 @@ fenced_register_level(xmlNode *msg, char **desc, pcmk__action_result_t *result)
// Ensure a valid target was specified
if (mode == fenced_target_by_unknown) {
crm_warn("Ignoring registration for topology level '%s' "
- "without valid target", ID(level));
+ "without valid target", pcmk__xe_id(level));
free(target);
crm_log_xml_trace(level, "Bad level");
pcmk__format_result(result, CRM_EX_INVALID_PARAM, PCMK_EXEC_INVALID,
"Invalid target for topology level '%s'",
- ID(level));
+ pcmk__xe_id(level));
return;
}
@@ -1766,28 +1774,24 @@ fenced_register_level(xmlNode *msg, char **desc, pcmk__action_result_t *result)
crm_log_xml_trace(level, "Bad level");
pcmk__format_result(result, CRM_EX_INVALID_PARAM, PCMK_EXEC_INVALID,
"Invalid level number '%s' for topology level '%s'",
- pcmk__s(crm_element_value(level,
- XML_ATTR_STONITH_INDEX),
+ pcmk__s(crm_element_value(level, PCMK_XA_INDEX),
""),
- ID(level));
+ pcmk__xe_id(level));
return;
}
/* Find or create topology table entry */
tp = g_hash_table_lookup(topology, target);
if (tp == NULL) {
- tp = calloc(1, sizeof(stonith_topology_t));
- if (tp == NULL) {
- pcmk__set_result(result, CRM_EX_ERROR, PCMK_EXEC_ERROR,
- strerror(ENOMEM));
- free(target);
- return;
- }
+ tp = pcmk__assert_alloc(1, sizeof(stonith_topology_t));
+
tp->kind = mode;
tp->target = target;
- tp->target_value = crm_element_value_copy(level, XML_ATTR_STONITH_TARGET_VALUE);
- tp->target_pattern = crm_element_value_copy(level, XML_ATTR_STONITH_TARGET_PATTERN);
- tp->target_attribute = crm_element_value_copy(level, XML_ATTR_STONITH_TARGET_ATTRIBUTE);
+ tp->target_value = crm_element_value_copy(level, PCMK_XA_TARGET_VALUE);
+ tp->target_pattern = crm_element_value_copy(level,
+ PCMK_XA_TARGET_PATTERN);
+ tp->target_attribute = crm_element_value_copy(level,
+ PCMK_XA_TARGET_ATTRIBUTE);
g_hash_table_replace(topology, tp->target, tp);
crm_trace("Added %s (%d) to the topology (%d active entries)",
@@ -1801,12 +1805,12 @@ fenced_register_level(xmlNode *msg, char **desc, pcmk__action_result_t *result)
tp->target, id);
}
- devices = parse_device_list(crm_element_value(level, XML_ATTR_STONITH_DEVICES));
+ devices = parse_device_list(crm_element_value(level, PCMK_XA_DEVICES));
for (dIter = devices; dIter; dIter = dIter->next) {
const char *device = dIter->value;
crm_trace("Adding device '%s' for %s[%d]", device, tp->target, id);
- tp->levels[id] = g_list_append(tp->levels[id], strdup(device));
+ tp->levels[id] = g_list_append(tp->levels[id], pcmk__str_copy(device));
}
stonith_key_value_freeall(devices, 1, 1);
@@ -1857,12 +1861,11 @@ fenced_unregister_level(xmlNode *msg, char **desc,
crm_log_xml_trace(level, "Bad level");
pcmk__format_result(result, CRM_EX_INVALID_PARAM, PCMK_EXEC_INVALID,
"Invalid level number '%s' for topology level %s",
- pcmk__s(crm_element_value(level,
- XML_ATTR_STONITH_INDEX),
+ pcmk__s(crm_element_value(level, PCMK_XA_INDEX),
"<null>"),
// Client API doesn't add ID to unregistration XML
- pcmk__s(ID(level), ""));
+ pcmk__s(pcmk__xe_id(level), ""));
return;
}
@@ -1906,26 +1909,29 @@ list_to_string(GList *list, const char *delim, gboolean terminate_with_delim)
char *rv;
GList *gIter;
+ char *pos = NULL;
+ const char *lead_delim = "";
+
for (gIter = list; gIter != NULL; gIter = gIter->next) {
const char *value = (const char *) gIter->data;
alloc_size += strlen(value);
}
- rv = calloc(alloc_size, sizeof(char));
- if (rv) {
- char *pos = rv;
- const char *lead_delim = "";
- for (gIter = list; gIter != NULL; gIter = gIter->next) {
- const char *value = (const char *) gIter->data;
+ rv = pcmk__assert_alloc(alloc_size, sizeof(char));
+ pos = rv;
- pos = &pos[sprintf(pos, "%s%s", lead_delim, value)];
- lead_delim = delim;
- }
- if (max && terminate_with_delim) {
- sprintf(pos, "%s", delim);
- }
+ for (gIter = list; gIter != NULL; gIter = gIter->next) {
+ const char *value = (const char *) gIter->data;
+
+ pos = &pos[sprintf(pos, "%s%s", lead_delim, value)];
+ lead_delim = delim;
+ }
+
+ if (max && terminate_with_delim) {
+ sprintf(pos, "%s", delim);
}
+
return rv;
}
@@ -1947,10 +1953,11 @@ list_to_string(GList *list, const char *delim, gboolean terminate_with_delim)
static void
execute_agent_action(xmlNode *msg, pcmk__action_result_t *result)
{
- xmlNode *dev = get_xpath_object("//" F_STONITH_DEVICE, msg, LOG_ERR);
- xmlNode *op = get_xpath_object("//@" F_STONITH_ACTION, msg, LOG_ERR);
- const char *id = crm_element_value(dev, F_STONITH_DEVICE);
- const char *action = crm_element_value(op, F_STONITH_ACTION);
+ xmlNode *dev = get_xpath_object("//" PCMK__XE_ST_DEVICE_ID, msg, LOG_ERR);
+ xmlNode *op = get_xpath_object("//@" PCMK__XE_ST_DEVICE_ACTION, msg,
+ LOG_ERR);
+ const char *id = crm_element_value(dev, PCMK__XA_ST_DEVICE_ID);
+ const char *action = crm_element_value(op, PCMK__XA_ST_DEVICE_ACTION);
async_command_t *cmd = NULL;
stonith_device_t *device = NULL;
@@ -2023,7 +2030,8 @@ search_devices_record_result(struct device_search_s *search, const char *device,
return;
}
}
- search->capable = g_list_append(search->capable, strdup(device));
+ search->capable = g_list_append(search->capable,
+ pcmk__str_copy(device));
}
if (search->replies_needed == search->replies_received) {
@@ -2158,10 +2166,12 @@ can_fence_host_with_device(stonith_device_t *dev,
// Check eligibility as specified by pcmk_host_check
check_type = target_list_type(dev);
alias = g_hash_table_lookup(dev->aliases, target);
- if (pcmk__str_eq(check_type, PCMK__VALUE_NONE, pcmk__str_casei)) {
+ if (pcmk__str_eq(check_type, PCMK_VALUE_NONE, pcmk__str_casei)) {
can = TRUE;
- } else if (pcmk__str_eq(check_type, "static-list", pcmk__str_casei)) {
+ } else if (pcmk__str_eq(check_type, PCMK_VALUE_STATIC_LIST,
+ pcmk__str_casei)) {
+
if (pcmk__str_in_list(target, dev->targets, pcmk__str_casei)) {
can = TRUE;
} else if (g_hash_table_lookup(dev->params, PCMK_STONITH_HOST_MAP)
@@ -2169,7 +2179,8 @@ can_fence_host_with_device(stonith_device_t *dev,
can = TRUE;
}
- } else if (pcmk__str_eq(check_type, "dynamic-list", pcmk__str_casei)) {
+ } else if (pcmk__str_eq(check_type, PCMK_VALUE_DYNAMIC_LIST,
+ pcmk__str_casei)) {
time_t now = time(NULL);
if (dev->targets == NULL || dev->targets_age + 60 < now) {
@@ -2177,8 +2188,10 @@ can_fence_host_with_device(stonith_device_t *dev,
search->per_device_timeout);
if (device_timeout > search->per_device_timeout) {
- crm_notice("Since the pcmk_list_timeout(%ds) parameter of %s is larger than stonith-timeout(%ds), timeout may occur",
- device_timeout, dev_id, search->per_device_timeout);
+ crm_notice("Since the pcmk_list_timeout (%ds) parameter of %s "
+ "is larger than " PCMK_OPT_STONITH_TIMEOUT
+ " (%ds), timeout may occur",
+ device_timeout, dev_id, search->per_device_timeout);
}
crm_trace("Running '%s' to check whether %s is eligible to fence %s (%s)",
@@ -2196,12 +2209,14 @@ can_fence_host_with_device(stonith_device_t *dev,
can = TRUE;
}
- } else if (pcmk__str_eq(check_type, "status", pcmk__str_casei)) {
+ } else if (pcmk__str_eq(check_type, PCMK_VALUE_STATUS, pcmk__str_casei)) {
int device_timeout = get_action_timeout(dev, check_type, search->per_device_timeout);
if (device_timeout > search->per_device_timeout) {
- crm_notice("Since the pcmk_status_timeout(%ds) parameter of %s is larger than stonith-timeout(%ds), timeout may occur",
- device_timeout, dev_id, search->per_device_timeout);
+ crm_notice("Since the pcmk_status_timeout (%ds) parameter of %s is "
+ "larger than " PCMK_OPT_STONITH_TIMEOUT " (%ds), "
+ "timeout may occur",
+ device_timeout, dev_id, search->per_device_timeout);
}
crm_trace("Running '%s' to check whether %s is eligible to fence %s (%s)",
@@ -2246,16 +2261,10 @@ get_capable_devices(const char *host, const char *action, int timeout, bool suic
return;
}
- search = calloc(1, sizeof(struct device_search_s));
- if (!search) {
- crm_crit("Cannot search for capable fence devices: %s",
- strerror(ENOMEM));
- callback(NULL, user_data);
- return;
- }
+ search = pcmk__assert_alloc(1, sizeof(struct device_search_s));
- pcmk__str_update(&search->host, host);
- pcmk__str_update(&search->action, action);
+ search->host = pcmk__str_copy(host);
+ search->action = pcmk__str_copy(action);
search->per_device_timeout = timeout;
search->allow_suicide = suicide;
search->callback = callback;
@@ -2303,28 +2312,31 @@ add_action_specific_attributes(xmlNode *xml, const char *action,
CRM_CHECK(xml && action && device, return);
+ // PCMK__XA_ST_REQUIRED is currently used only for unfencing
if (is_action_required(action, device)) {
crm_trace("Action '%s' is required using %s", action, device->id);
- crm_xml_add_int(xml, F_STONITH_DEVICE_REQUIRED, 1);
+ crm_xml_add_int(xml, PCMK__XA_ST_REQUIRED, 1);
}
+ // pcmk_<action>_timeout if configured
action_specific_timeout = get_action_timeout(device, action, 0);
if (action_specific_timeout) {
- crm_trace("Action '%s' has timeout %dms using %s",
+ crm_trace("Action '%s' has timeout %ds using %s",
action, action_specific_timeout, device->id);
- crm_xml_add_int(xml, F_STONITH_ACTION_TIMEOUT, action_specific_timeout);
+ crm_xml_add_int(xml, PCMK__XA_ST_ACTION_TIMEOUT,
+ action_specific_timeout);
}
delay_max = get_action_delay_max(device, action);
if (delay_max > 0) {
crm_trace("Action '%s' has maximum random delay %ds using %s",
action, delay_max, device->id);
- crm_xml_add_int(xml, F_STONITH_DELAY_MAX, delay_max);
+ crm_xml_add_int(xml, PCMK__XA_ST_DELAY_MAX, delay_max);
}
delay_base = get_action_delay_base(device, action, target);
if (delay_base > 0) {
- crm_xml_add_int(xml, F_STONITH_DELAY_BASE, delay_base);
+ crm_xml_add_int(xml, PCMK__XA_ST_DELAY_BASE, delay_base);
}
if ((delay_max > 0) && (delay_base == 0)) {
@@ -2357,7 +2369,7 @@ add_disallowed(xmlNode *xml, const char *action, const stonith_device_t *device,
if (!localhost_is_eligible(device, action, target, allow_suicide)) {
crm_trace("Action '%s' using %s is disallowed for local host",
action, device->id);
- pcmk__xe_set_bool_attr(xml, F_STONITH_ACTION_DISALLOWED, true);
+ pcmk__xe_set_bool_attr(xml, PCMK__XA_ST_ACTION_DISALLOWED, true);
}
}
@@ -2376,9 +2388,9 @@ add_action_reply(xmlNode *xml, const char *action,
const stonith_device_t *device, const char *target,
gboolean allow_suicide)
{
- xmlNode *child = create_xml_node(xml, F_STONITH_ACTION);
+ xmlNode *child = pcmk__xe_create(xml, PCMK__XE_ST_DEVICE_ACTION);
- crm_xml_add(child, XML_ATTR_ID, action);
+ crm_xml_add(child, PCMK_XA_ID, action);
add_action_specific_attributes(child, action, device, target);
add_disallowed(child, action, device, target, allow_suicide);
}
@@ -2402,8 +2414,11 @@ stonith_send_reply(const xmlNode *reply, int call_options,
if (remote_peer == NULL) {
do_local_reply(reply, client, call_options);
} else {
- send_cluster_message(crm_get_peer(0, remote_peer), crm_msg_stonith_ng,
- reply, FALSE);
+ const crm_node_t *node =
+ pcmk__get_node(0, remote_peer, NULL,
+ pcmk__node_search_cluster_member);
+
+ pcmk__cluster_send_message(node, crm_msg_stonith_ng, reply);
}
}
@@ -2412,7 +2427,7 @@ stonith_query_capable_device_cb(GList * devices, void *user_data)
{
struct st_query_data *query = user_data;
int available_devices = 0;
- xmlNode *dev = NULL;
+ xmlNode *wrapper = NULL;
xmlNode *list = NULL;
GList *lpc = NULL;
pcmk__client_t *client = NULL;
@@ -2426,12 +2441,15 @@ stonith_query_capable_device_cb(GList * devices, void *user_data)
}
}
- /* Pack the results into XML */
- list = create_xml_node(NULL, __func__);
- crm_xml_add(list, F_STONITH_TARGET, query->target);
+ // Pack the results into XML
+ wrapper = pcmk__xe_create(query->reply, PCMK__XE_ST_CALLDATA);
+ list = pcmk__xe_create(wrapper, __func__);
+ crm_xml_add(list, PCMK__XA_ST_TARGET, query->target);
+
for (lpc = devices; lpc != NULL; lpc = lpc->next) {
stonith_device_t *device = g_hash_table_lookup(device_list, lpc->data);
const char *action = query->action;
+ xmlNode *dev = NULL;
if (!device) {
/* It is possible the device got unregistered while
@@ -2441,12 +2459,15 @@ stonith_query_capable_device_cb(GList * devices, void *user_data)
available_devices++;
- dev = create_xml_node(list, F_STONITH_DEVICE);
- crm_xml_add(dev, XML_ATTR_ID, device->id);
- crm_xml_add(dev, "namespace", device->namespace);
- crm_xml_add(dev, "agent", device->agent);
- crm_xml_add_int(dev, F_STONITH_DEVICE_VERIFIED, device->verified);
- crm_xml_add_int(dev, F_STONITH_DEVICE_SUPPORT_FLAGS, device->flags);
+ dev = pcmk__xe_create(list, PCMK__XE_ST_DEVICE_ID);
+ crm_xml_add(dev, PCMK_XA_ID, device->id);
+ crm_xml_add(dev, PCMK__XA_NAMESPACE, device->namespace);
+ crm_xml_add(dev, PCMK_XA_AGENT, device->agent);
+
+ // Has had successful monitor, list, or status on this node
+ crm_xml_add_int(dev, PCMK__XA_ST_MONITOR_VERIFIED, device->verified);
+
+ crm_xml_add_int(dev, PCMK__XA_ST_DEVICE_SUPPORT_FLAGS, device->flags);
/* If the originating fencer wants to reboot the node, and we have a
* capable device that doesn't support "reboot", remap to "off" instead.
@@ -2482,13 +2503,13 @@ stonith_query_capable_device_cb(GList * devices, void *user_data)
/* A query without a target wants device parameters */
if (query->target == NULL) {
- xmlNode *attrs = create_xml_node(dev, XML_TAG_ATTRS);
+ xmlNode *attrs = pcmk__xe_create(dev, PCMK__XE_ATTRIBUTES);
g_hash_table_foreach(device->params, hash2field, attrs);
}
}
- crm_xml_add_int(list, F_STONITH_AVAILABLE_DEVICES, available_devices);
+ crm_xml_add_int(list, PCMK__XA_ST_AVAILABLE_DEVICES, available_devices);
if (query->target) {
crm_debug("Found %d matching device%s for target '%s'",
available_devices, pcmk__plural_s(available_devices),
@@ -2498,10 +2519,7 @@ stonith_query_capable_device_cb(GList * devices, void *user_data)
available_devices, pcmk__plural_s(available_devices));
}
- if (list != NULL) {
- crm_log_xml_trace(list, "Add query results");
- add_message_xml(query->reply, F_STONITH_CALLDATA, list);
- }
+ crm_log_xml_trace(list, "query-result");
stonith_send_reply(query->reply, query->call_options, query->remote_peer,
client);
@@ -2513,7 +2531,6 @@ done:
free(query->target);
free(query->action);
free(query);
- free_xml(list);
g_list_free_full(devices, free);
}
@@ -2542,14 +2559,16 @@ log_async_result(const async_command_t *cmd,
if (pcmk__result_ok(result)) {
log_level = (cmd->target == NULL)? LOG_DEBUG : LOG_NOTICE;
if ((result->action_stdout != NULL)
- && !pcmk__str_eq(cmd->action, "metadata", pcmk__str_none)) {
+ && !pcmk__str_eq(cmd->action, PCMK_ACTION_METADATA,
+ pcmk__str_none)) {
output_log_level = LOG_DEBUG;
}
next = NULL;
} else {
log_level = (cmd->target == NULL)? LOG_NOTICE : LOG_ERR;
if ((result->action_stdout != NULL)
- && !pcmk__str_eq(cmd->action, "metadata", pcmk__str_none)) {
+ && !pcmk__str_eq(cmd->action, PCMK_ACTION_METADATA,
+ pcmk__str_none)) {
output_log_level = LOG_WARNING;
}
}
@@ -2633,7 +2652,7 @@ send_async_reply(const async_command_t *cmd, const pcmk__action_result_t *result
reply = construct_async_reply(cmd, result);
if (merged) {
- pcmk__xe_set_bool_attr(reply, F_STONITH_MERGED, true);
+ pcmk__xe_set_bool_attr(reply, PCMK__XA_ST_OP_MERGED, true);
}
if (!stand_alone && pcmk__is_fencing_action(cmd->action)
@@ -2643,9 +2662,9 @@ send_async_reply(const async_command_t *cmd, const pcmk__action_result_t *result
*/
crm_trace("Broadcast '%s' result for %s (target was also originator)",
cmd->action, cmd->target);
- crm_xml_add(reply, F_SUBTYPE, "broadcast");
- crm_xml_add(reply, F_STONITH_OPERATION, T_STONITH_NOTIFY);
- send_cluster_message(NULL, crm_msg_stonith_ng, reply, FALSE);
+ crm_xml_add(reply, PCMK__XA_SUBT, PCMK__VALUE_BROADCAST);
+ crm_xml_add(reply, PCMK__XA_ST_OP, STONITH_OP_NOTIFY);
+ pcmk__cluster_send_message(NULL, crm_msg_stonith_ng, reply);
} else {
// Reply only to the originator
stonith_send_reply(reply, cmd->options, cmd->origin, client);
@@ -2656,18 +2675,19 @@ send_async_reply(const async_command_t *cmd, const pcmk__action_result_t *result
if (stand_alone) {
/* Do notification with a clean data object */
- xmlNode *notify_data = create_xml_node(NULL, T_STONITH_NOTIFY_FENCE);
+ xmlNode *notify_data = pcmk__xe_create(NULL, PCMK__XE_ST_NOTIFY_FENCE);
stonith__xe_set_result(notify_data, result);
- crm_xml_add(notify_data, F_STONITH_TARGET, cmd->target);
- crm_xml_add(notify_data, F_STONITH_OPERATION, cmd->op);
- crm_xml_add(notify_data, F_STONITH_DELEGATE, "localhost");
- crm_xml_add(notify_data, F_STONITH_DEVICE, cmd->device);
- crm_xml_add(notify_data, F_STONITH_REMOTE_OP_ID, cmd->remote_op_id);
- crm_xml_add(notify_data, F_STONITH_ORIGIN, cmd->client);
+ crm_xml_add(notify_data, PCMK__XA_ST_TARGET, cmd->target);
+ crm_xml_add(notify_data, PCMK__XA_ST_OP, cmd->op);
+ crm_xml_add(notify_data, PCMK__XA_ST_DELEGATE, "localhost");
+ crm_xml_add(notify_data, PCMK__XA_ST_DEVICE_ID, cmd->device);
+ crm_xml_add(notify_data, PCMK__XA_ST_REMOTE_OP, cmd->remote_op_id);
+ crm_xml_add(notify_data, PCMK__XA_ST_ORIGIN, cmd->client);
- fenced_send_notification(T_STONITH_NOTIFY_FENCE, result, notify_data);
- fenced_send_notification(T_STONITH_NOTIFY_HISTORY, NULL, NULL);
+ fenced_send_notification(PCMK__VALUE_ST_NOTIFY_FENCE, result,
+ notify_data);
+ fenced_send_notification(PCMK__VALUE_ST_NOTIFY_HISTORY, NULL, NULL);
}
}
@@ -2890,7 +2910,7 @@ fence_locally(xmlNode *msg, pcmk__action_result_t *result)
CRM_CHECK((msg != NULL) && (result != NULL), return);
- dev = get_xpath_object("//@" F_STONITH_TARGET, msg, LOG_ERR);
+ dev = get_xpath_object("//@" PCMK__XA_ST_TARGET, msg, LOG_ERR);
cmd = create_async_command(msg);
if (cmd == NULL) {
@@ -2899,7 +2919,7 @@ fence_locally(xmlNode *msg, pcmk__action_result_t *result)
return;
}
- device_id = crm_element_value(dev, F_STONITH_DEVICE);
+ device_id = crm_element_value(dev, PCMK__XA_ST_DEVICE_ID);
if (device_id != NULL) {
device = g_hash_table_lookup(device_list, device_id);
if (device == NULL) {
@@ -2911,14 +2931,16 @@ fence_locally(xmlNode *msg, pcmk__action_result_t *result)
schedule_stonith_command(cmd, device);
} else {
- const char *host = crm_element_value(dev, F_STONITH_TARGET);
+ const char *host = crm_element_value(dev, PCMK__XA_ST_TARGET);
if (pcmk_is_set(cmd->options, st_opt_cs_nodeid)) {
int nodeid = 0;
crm_node_t *node = NULL;
pcmk__scan_min_int(host, &nodeid, 0);
- node = pcmk__search_known_node_cache(nodeid, NULL, CRM_GET_PEER_ANY);
+ node = pcmk__search_node_caches(nodeid, NULL,
+ pcmk__node_search_any
+ |pcmk__node_search_cluster_cib);
if (node != NULL) {
host = node->uname;
}
@@ -2953,10 +2975,10 @@ fenced_construct_reply(const xmlNode *request, xmlNode *data,
{
xmlNode *reply = NULL;
- reply = create_xml_node(NULL, T_STONITH_REPLY);
+ reply = pcmk__xe_create(NULL, PCMK__XE_ST_REPLY);
- crm_xml_add(reply, "st_origin", __func__);
- crm_xml_add(reply, F_TYPE, T_STONITH_NG);
+ crm_xml_add(reply, PCMK__XA_ST_ORIGIN, __func__);
+ crm_xml_add(reply, PCMK__XA_T, PCMK__VALUE_STONITH_NG);
stonith__xe_set_result(reply, result);
if (request == NULL) {
@@ -2976,12 +2998,12 @@ fenced_construct_reply(const xmlNode *request, xmlNode *data,
// Attributes to copy from request to reply
const char *names[] = {
- F_STONITH_OPERATION,
- F_STONITH_CALLID,
- F_STONITH_CLIENTID,
- F_STONITH_CLIENTNAME,
- F_STONITH_REMOTE_OP_ID,
- F_STONITH_CALLOPTS
+ PCMK__XA_ST_OP,
+ PCMK__XA_ST_CALLID,
+ PCMK__XA_ST_CLIENTID,
+ PCMK__XA_ST_CLIENTNAME,
+ PCMK__XA_ST_REMOTE_OP,
+ PCMK__XA_ST_CALLOPT,
};
for (int lpc = 0; lpc < PCMK__NELEM(names); lpc++) {
@@ -2990,7 +3012,9 @@ fenced_construct_reply(const xmlNode *request, xmlNode *data,
crm_xml_add(reply, name, value);
}
if (data != NULL) {
- add_message_xml(reply, F_STONITH_CALLDATA, data);
+ xmlNode *wrapper = pcmk__xe_create(reply, PCMK__XE_ST_CALLDATA);
+
+ pcmk__xml_copy(wrapper, data);
}
}
return reply;
@@ -3007,20 +3031,20 @@ static xmlNode *
construct_async_reply(const async_command_t *cmd,
const pcmk__action_result_t *result)
{
- xmlNode *reply = create_xml_node(NULL, T_STONITH_REPLY);
-
- crm_xml_add(reply, "st_origin", __func__);
- crm_xml_add(reply, F_TYPE, T_STONITH_NG);
- crm_xml_add(reply, F_STONITH_OPERATION, cmd->op);
- crm_xml_add(reply, F_STONITH_DEVICE, cmd->device);
- crm_xml_add(reply, F_STONITH_REMOTE_OP_ID, cmd->remote_op_id);
- crm_xml_add(reply, F_STONITH_CLIENTID, cmd->client);
- crm_xml_add(reply, F_STONITH_CLIENTNAME, cmd->client_name);
- crm_xml_add(reply, F_STONITH_TARGET, cmd->target);
- crm_xml_add(reply, F_STONITH_ACTION, cmd->op);
- crm_xml_add(reply, F_STONITH_ORIGIN, cmd->origin);
- crm_xml_add_int(reply, F_STONITH_CALLID, cmd->id);
- crm_xml_add_int(reply, F_STONITH_CALLOPTS, cmd->options);
+ xmlNode *reply = pcmk__xe_create(NULL, PCMK__XE_ST_REPLY);
+
+ crm_xml_add(reply, PCMK__XA_ST_ORIGIN, __func__);
+ crm_xml_add(reply, PCMK__XA_T, PCMK__VALUE_STONITH_NG);
+ crm_xml_add(reply, PCMK__XA_ST_OP, cmd->op);
+ crm_xml_add(reply, PCMK__XA_ST_DEVICE_ID, cmd->device);
+ crm_xml_add(reply, PCMK__XA_ST_REMOTE_OP, cmd->remote_op_id);
+ crm_xml_add(reply, PCMK__XA_ST_CLIENTID, cmd->client);
+ crm_xml_add(reply, PCMK__XA_ST_CLIENTNAME, cmd->client_name);
+ crm_xml_add(reply, PCMK__XA_ST_TARGET, cmd->target);
+ crm_xml_add(reply, PCMK__XA_ST_DEVICE_ACTION, cmd->op);
+ crm_xml_add(reply, PCMK__XA_ST_ORIGIN, cmd->origin);
+ crm_xml_add_int(reply, PCMK__XA_ST_CALLID, cmd->id);
+ crm_xml_add_int(reply, PCMK__XA_ST_CALLOPT, cmd->options);
stonith__xe_set_result(reply, result);
return reply;
@@ -3081,7 +3105,8 @@ check_alternate_host(const char *target)
static void
remove_relay_op(xmlNode * request)
{
- xmlNode *dev = get_xpath_object("//@" F_STONITH_ACTION, request, LOG_TRACE);
+ xmlNode *dev = get_xpath_object("//@" PCMK__XE_ST_DEVICE_ACTION, request,
+ LOG_TRACE);
const char *relay_op_id = NULL;
const char *op_id = NULL;
const char *client_name = NULL;
@@ -3089,12 +3114,12 @@ remove_relay_op(xmlNode * request)
remote_fencing_op_t *relay_op = NULL;
if (dev) {
- target = crm_element_value(dev, F_STONITH_TARGET);
+ target = crm_element_value(dev, PCMK__XA_ST_TARGET);
}
- relay_op_id = crm_element_value(request, F_STONITH_REMOTE_OP_ID_RELAY);
- op_id = crm_element_value(request, F_STONITH_REMOTE_OP_ID);
- client_name = crm_element_value(request, F_STONITH_CLIENTNAME);
+ relay_op_id = crm_element_value(request, PCMK__XA_ST_REMOTE_OP_RELAY);
+ op_id = crm_element_value(request, PCMK__XA_ST_REMOTE_OP);
+ client_name = crm_element_value(request, PCMK__XA_ST_CLIENTNAME);
/* Delete RELAY operation. */
if (relay_op_id && target && pcmk__str_eq(target, stonith_our_uname, pcmk__str_casei)) {
@@ -3162,11 +3187,11 @@ is_privileged(const pcmk__client_t *c, const char *op)
static xmlNode *
handle_register_request(pcmk__request_t *request)
{
- xmlNode *reply = create_xml_node(NULL, "reply");
+ xmlNode *reply = pcmk__xe_create(NULL, "reply");
CRM_ASSERT(request->ipc_client != NULL);
- crm_xml_add(reply, F_STONITH_OPERATION, CRM_OP_REGISTER);
- crm_xml_add(reply, F_STONITH_CLIENTID, request->ipc_client->id);
+ crm_xml_add(reply, PCMK__XA_ST_OP, CRM_OP_REGISTER);
+ crm_xml_add(reply, PCMK__XA_ST_CLIENTID, request->ipc_client->id);
pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
pcmk__set_request_flags(request, pcmk__request_reuse_options);
return reply;
@@ -3187,11 +3212,12 @@ handle_agent_request(pcmk__request_t *request)
static xmlNode *
handle_update_timeout_request(pcmk__request_t *request)
{
- const char *call_id = crm_element_value(request->xml, F_STONITH_CALLID);
- const char *client_id = crm_element_value(request->xml, F_STONITH_CLIENTID);
+ const char *call_id = crm_element_value(request->xml, PCMK__XA_ST_CALLID);
+ const char *client_id = crm_element_value(request->xml,
+ PCMK__XA_ST_CLIENTID);
int op_timeout = 0;
- crm_element_value_int(request->xml, F_STONITH_TIMEOUT, &op_timeout);
+ crm_element_value_int(request->xml, PCMK__XA_ST_TIMEOUT, &op_timeout);
do_stonith_async_timeout_update(client_id, call_id, op_timeout);
pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
return NULL;
@@ -3205,7 +3231,8 @@ handle_query_request(pcmk__request_t *request)
xmlNode *dev = NULL;
const char *action = NULL;
const char *target = NULL;
- const char *client_id = crm_element_value(request->xml, F_STONITH_CLIENTID);
+ const char *client_id = crm_element_value(request->xml,
+ PCMK__XA_ST_CLIENTID);
struct st_query_data *query = NULL;
if (request->peer != NULL) {
@@ -3218,51 +3245,51 @@ handle_query_request(pcmk__request_t *request)
pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
- dev = get_xpath_object("//@" F_STONITH_ACTION, request->xml, LOG_NEVER);
+ dev = get_xpath_object("//@" PCMK__XE_ST_DEVICE_ACTION, request->xml,
+ LOG_NEVER);
if (dev != NULL) {
- const char *device = crm_element_value(dev, F_STONITH_DEVICE);
+ const char *device = crm_element_value(dev, PCMK__XA_ST_DEVICE_ID);
if (pcmk__str_eq(device, "manual_ack", pcmk__str_casei)) {
return NULL; // No query or reply necessary
}
- target = crm_element_value(dev, F_STONITH_TARGET);
- action = crm_element_value(dev, F_STONITH_ACTION);
+ target = crm_element_value(dev, PCMK__XA_ST_TARGET);
+ action = crm_element_value(dev, PCMK__XA_ST_DEVICE_ACTION);
}
crm_log_xml_trace(request->xml, "Query");
- query = calloc(1, sizeof(struct st_query_data));
- CRM_ASSERT(query != NULL);
+ query = pcmk__assert_alloc(1, sizeof(struct st_query_data));
query->reply = fenced_construct_reply(request->xml, NULL, &request->result);
- pcmk__str_update(&query->remote_peer, request->peer);
- pcmk__str_update(&query->client_id, client_id);
- pcmk__str_update(&query->target, target);
- pcmk__str_update(&query->action, action);
+ query->remote_peer = pcmk__str_copy(request->peer);
+ query->client_id = pcmk__str_copy(client_id);
+ query->target = pcmk__str_copy(target);
+ query->action = pcmk__str_copy(action);
query->call_options = request->call_options;
- crm_element_value_int(request->xml, F_STONITH_TIMEOUT, &timeout);
+ crm_element_value_int(request->xml, PCMK__XA_ST_TIMEOUT, &timeout);
get_capable_devices(target, action, timeout,
pcmk_is_set(query->call_options, st_opt_allow_suicide),
query, stonith_query_capable_device_cb, st_device_supports_none);
return NULL;
}
-// T_STONITH_NOTIFY
+// STONITH_OP_NOTIFY
static xmlNode *
handle_notify_request(pcmk__request_t *request)
{
const char *flag_name = NULL;
CRM_ASSERT(request->ipc_client != NULL);
- flag_name = crm_element_value(request->xml, F_STONITH_NOTIFY_ACTIVATE);
+ flag_name = crm_element_value(request->xml, PCMK__XA_ST_NOTIFY_ACTIVATE);
if (flag_name != NULL) {
crm_debug("Enabling %s callbacks for client %s",
flag_name, pcmk__request_origin(request));
pcmk__set_client_flags(request->ipc_client, get_stonith_flag(flag_name));
}
- flag_name = crm_element_value(request->xml, F_STONITH_NOTIFY_DEACTIVATE);
+ flag_name = crm_element_value(request->xml, PCMK__XA_ST_NOTIFY_DEACTIVATE);
if (flag_name != NULL) {
crm_debug("Disabling %s callbacks for client %s",
flag_name, pcmk__request_origin(request));
@@ -3273,22 +3300,23 @@ handle_notify_request(pcmk__request_t *request)
pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
pcmk__set_request_flags(request, pcmk__request_reuse_options);
- return pcmk__ipc_create_ack(request->ipc_flags, "ack", NULL, CRM_EX_OK);
+ return pcmk__ipc_create_ack(request->ipc_flags, PCMK__XE_ACK, NULL,
+ CRM_EX_OK);
}
// STONITH_OP_RELAY
static xmlNode *
handle_relay_request(pcmk__request_t *request)
{
- xmlNode *dev = get_xpath_object("//@" F_STONITH_TARGET, request->xml,
+ xmlNode *dev = get_xpath_object("//@" PCMK__XA_ST_TARGET, request->xml,
LOG_TRACE);
crm_notice("Received forwarded fencing request from "
"%s %s to fence (%s) peer %s",
pcmk__request_origin_type(request),
pcmk__request_origin(request),
- crm_element_value(dev, F_STONITH_ACTION),
- crm_element_value(dev, F_STONITH_TARGET));
+ crm_element_value(dev, PCMK__XA_ST_DEVICE_ACTION),
+ crm_element_value(dev, PCMK__XA_ST_TARGET));
if (initiate_remote_stonith_op(NULL, request->xml, FALSE) == NULL) {
fenced_set_protocol_error(&request->result);
@@ -3324,11 +3352,11 @@ handle_fence_request(pcmk__request_t *request)
} else {
const char *alternate_host = NULL;
- xmlNode *dev = get_xpath_object("//@" F_STONITH_TARGET, request->xml,
+ xmlNode *dev = get_xpath_object("//@" PCMK__XA_ST_TARGET, request->xml,
LOG_TRACE);
- const char *target = crm_element_value(dev, F_STONITH_TARGET);
- const char *action = crm_element_value(dev, F_STONITH_ACTION);
- const char *device = crm_element_value(dev, F_STONITH_DEVICE);
+ const char *target = crm_element_value(dev, PCMK__XA_ST_TARGET);
+ const char *action = crm_element_value(dev, PCMK__XA_ST_DEVICE_ACTION);
+ const char *device = crm_element_value(dev, PCMK__XA_ST_DEVICE_ID);
if (request->ipc_client != NULL) {
int tolerance = 0;
@@ -3336,7 +3364,7 @@ handle_fence_request(pcmk__request_t *request)
crm_notice("Client %s wants to fence (%s) %s using %s",
pcmk__request_origin(request), action,
target, (device? device : "any device"));
- crm_element_value_int(dev, F_STONITH_TOLERANCE, &tolerance);
+ crm_element_value_int(dev, PCMK__XA_ST_TOLERANCE, &tolerance);
if (stonith_check_fence_tolerance(tolerance, target, action)) {
pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE,
NULL);
@@ -3354,9 +3382,12 @@ handle_fence_request(pcmk__request_t *request)
if (alternate_host != NULL) {
const char *client_id = NULL;
remote_fencing_op_t *op = NULL;
+ crm_node_t *node = pcmk__get_node(0, alternate_host, NULL,
+ pcmk__node_search_cluster_member);
if (request->ipc_client->id == 0) {
- client_id = crm_element_value(request->xml, F_STONITH_CLIENTID);
+ client_id = crm_element_value(request->xml,
+ PCMK__XA_ST_CLIENTID);
} else {
client_id = request->ipc_client->id;
}
@@ -3367,12 +3398,11 @@ handle_fence_request(pcmk__request_t *request)
*/
op = create_remote_stonith_op(client_id, request->xml, FALSE);
- crm_xml_add(request->xml, F_STONITH_OPERATION, STONITH_OP_RELAY);
- crm_xml_add(request->xml, F_STONITH_CLIENTID,
+ crm_xml_add(request->xml, PCMK__XA_ST_OP, STONITH_OP_RELAY);
+ crm_xml_add(request->xml, PCMK__XA_ST_CLIENTID,
request->ipc_client->id);
- crm_xml_add(request->xml, F_STONITH_REMOTE_OP_ID, op->id);
- send_cluster_message(crm_get_peer(0, alternate_host),
- crm_msg_stonith_ng, request->xml, FALSE);
+ crm_xml_add(request->xml, PCMK__XA_ST_REMOTE_OP, op->id);
+ pcmk__cluster_send_message(node, crm_msg_stonith_ng, request->xml);
pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_PENDING,
NULL);
@@ -3416,8 +3446,8 @@ handle_history_request(pcmk__request_t *request)
static xmlNode *
handle_device_add_request(pcmk__request_t *request)
{
- const char *op = crm_element_value(request->xml, F_STONITH_OPERATION);
- xmlNode *dev = get_xpath_object("//" F_STONITH_DEVICE, request->xml,
+ const char *op = crm_element_value(request->xml, PCMK__XA_ST_OP);
+ xmlNode *dev = get_xpath_object("//" PCMK__XE_ST_DEVICE_ID, request->xml,
LOG_ERR);
if (is_privileged(request->ipc_client, op)) {
@@ -3432,8 +3462,8 @@ handle_device_add_request(pcmk__request_t *request)
PCMK_EXEC_INVALID,
"Unprivileged users must register device via CIB");
}
- fenced_send_device_notification(op, &request->result,
- (dev == NULL)? NULL : ID(dev));
+ fenced_send_config_notification(op, &request->result,
+ (dev == NULL)? NULL : pcmk__xe_id(dev));
return fenced_construct_reply(request->xml, NULL, &request->result);
}
@@ -3441,10 +3471,10 @@ handle_device_add_request(pcmk__request_t *request)
static xmlNode *
handle_device_delete_request(pcmk__request_t *request)
{
- xmlNode *dev = get_xpath_object("//" F_STONITH_DEVICE, request->xml,
+ xmlNode *dev = get_xpath_object("//" PCMK__XE_ST_DEVICE_ID, request->xml,
LOG_ERR);
- const char *device_id = crm_element_value(dev, XML_ATTR_ID);
- const char *op = crm_element_value(request->xml, F_STONITH_OPERATION);
+ const char *device_id = crm_element_value(dev, PCMK_XA_ID);
+ const char *op = crm_element_value(request->xml, PCMK__XA_ST_OP);
if (is_privileged(request->ipc_client, op)) {
stonith_device_remove(device_id, false);
@@ -3454,7 +3484,7 @@ handle_device_delete_request(pcmk__request_t *request)
PCMK_EXEC_INVALID,
"Unprivileged users must delete device via CIB");
}
- fenced_send_device_notification(op, &request->result, device_id);
+ fenced_send_config_notification(op, &request->result, device_id);
return fenced_construct_reply(request->xml, NULL, &request->result);
}
@@ -3463,7 +3493,7 @@ static xmlNode *
handle_level_add_request(pcmk__request_t *request)
{
char *desc = NULL;
- const char *op = crm_element_value(request->xml, F_STONITH_OPERATION);
+ const char *op = crm_element_value(request->xml, PCMK__XA_ST_OP);
if (is_privileged(request->ipc_client, op)) {
fenced_register_level(request->xml, &desc, &request->result);
@@ -3473,7 +3503,7 @@ handle_level_add_request(pcmk__request_t *request)
PCMK_EXEC_INVALID,
"Unprivileged users must add level via CIB");
}
- fenced_send_level_notification(op, &request->result, desc);
+ fenced_send_config_notification(op, &request->result, desc);
free(desc);
return fenced_construct_reply(request->xml, NULL, &request->result);
}
@@ -3483,7 +3513,7 @@ static xmlNode *
handle_level_delete_request(pcmk__request_t *request)
{
char *desc = NULL;
- const char *op = crm_element_value(request->xml, F_STONITH_OPERATION);
+ const char *op = crm_element_value(request->xml, PCMK__XA_ST_OP);
if (is_privileged(request->ipc_client, op)) {
fenced_unregister_level(request->xml, &desc, &request->result);
@@ -3493,7 +3523,7 @@ handle_level_delete_request(pcmk__request_t *request)
PCMK_EXEC_INVALID,
"Unprivileged users must delete level via CIB");
}
- fenced_send_level_notification(op, &request->result, desc);
+ fenced_send_config_notification(op, &request->result, desc);
free(desc);
return fenced_construct_reply(request->xml, NULL, &request->result);
}
@@ -3505,9 +3535,9 @@ handle_cache_request(pcmk__request_t *request)
int node_id = 0;
const char *name = NULL;
- crm_element_value_int(request->xml, XML_ATTR_ID, &node_id);
- name = crm_element_value(request->xml, XML_ATTR_UNAME);
- reap_crm_member(node_id, name);
+ crm_element_value_int(request->xml, PCMK_XA_ID, &node_id);
+ name = crm_element_value(request->xml, PCMK_XA_UNAME);
+ pcmk__cluster_forget_cluster_node(node_id, name);
pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
return NULL;
}
@@ -3531,7 +3561,7 @@ fenced_register_handlers(void)
{ STONITH_OP_EXEC, handle_agent_request },
{ STONITH_OP_TIMEOUT_UPDATE, handle_update_timeout_request },
{ STONITH_OP_QUERY, handle_query_request },
- { T_STONITH_NOTIFY, handle_notify_request },
+ { STONITH_OP_NOTIFY, handle_notify_request },
{ STONITH_OP_RELAY, handle_relay_request },
{ STONITH_OP_FENCE, handle_fence_request },
{ STONITH_OP_FENCE_HISTORY, handle_history_request },
@@ -3596,12 +3626,15 @@ static void
handle_reply(pcmk__client_t *client, xmlNode *request, const char *remote_peer)
{
// Copy, because request might be freed before we want to log this
- char *op = crm_element_value_copy(request, F_STONITH_OPERATION);
+ char *op = crm_element_value_copy(request, PCMK__XA_ST_OP);
if (pcmk__str_eq(op, STONITH_OP_QUERY, pcmk__str_none)) {
process_remote_stonith_query(request);
- } else if (pcmk__str_any_of(op, T_STONITH_NOTIFY, STONITH_OP_FENCE, NULL)) {
+
+ } else if (pcmk__str_any_of(op, STONITH_OP_NOTIFY, STONITH_OP_FENCE,
+ NULL)) {
fenced_process_fencing_reply(request);
+
} else {
crm_err("Ignoring unknown %s reply from %s %s",
pcmk__s(op, "untyped"), ((client == NULL)? "peer" : "client"),
@@ -3635,13 +3668,13 @@ stonith_command(pcmk__client_t *client, uint32_t id, uint32_t flags,
CRM_CHECK(message != NULL, return);
- if (get_xpath_object("//" T_STONITH_REPLY, message, LOG_NEVER) != NULL) {
+ if (get_xpath_object("//" PCMK__XE_ST_REPLY, message, LOG_NEVER) != NULL) {
is_reply = true;
}
- crm_element_value_int(message, F_STONITH_CALLOPTS, &call_options);
+ crm_element_value_int(message, PCMK__XA_ST_CALLOPT, &call_options);
crm_debug("Processing %ssynchronous %s %s %u from %s %s",
pcmk_is_set(call_options, st_opt_sync_call)? "" : "a",
- crm_element_value(message, F_STONITH_OPERATION),
+ crm_element_value(message, PCMK__XA_ST_OP),
(is_reply? "reply" : "request"), id,
((client == NULL)? "peer" : "client"),
((client == NULL)? remote_peer : pcmk__client_name(client)));
@@ -3663,7 +3696,7 @@ stonith_command(pcmk__client_t *client, uint32_t id, uint32_t flags,
.result = PCMK__UNKNOWN_RESULT,
};
- request.op = crm_element_value_copy(request.xml, F_STONITH_OPERATION);
+ request.op = crm_element_value_copy(request.xml, PCMK__XA_ST_OP);
CRM_CHECK(request.op != NULL, return);
if (pcmk_is_set(request.call_options, st_opt_sync_call)) {
diff --git a/daemons/fenced/fenced_history.c b/daemons/fenced/fenced_history.c
index a766477..5fcdb1f 100644
--- a/daemons/fenced/fenced_history.c
+++ b/daemons/fenced/fenced_history.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2022 the Pacemaker project contributors
+ * Copyright 2009-2024 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -14,7 +14,6 @@
#include <stdlib.h>
#include <crm/crm.h>
-#include <crm/msg_xml.h>
#include <crm/common/ipc.h>
#include <crm/common/ipc_internal.h>
#include <crm/cluster/internal.h>
@@ -42,23 +41,22 @@ stonith_send_broadcast_history(xmlNode *history,
int callopts,
const char *target)
{
- xmlNode *bcast = create_xml_node(NULL, "stonith_command");
- xmlNode *data = create_xml_node(NULL, __func__);
-
- if (target) {
- crm_xml_add(data, F_STONITH_TARGET, target);
- }
- crm_xml_add(bcast, F_TYPE, T_STONITH_NG);
- crm_xml_add(bcast, F_SUBTYPE, "broadcast");
- crm_xml_add(bcast, F_STONITH_OPERATION, STONITH_OP_FENCE_HISTORY);
- crm_xml_add_int(bcast, F_STONITH_CALLOPTS, callopts);
- if (history) {
- add_node_copy(data, history);
+ xmlNode *bcast = pcmk__xe_create(NULL, PCMK__XE_STONITH_COMMAND);
+ xmlNode *wrapper = pcmk__xe_create(bcast, PCMK__XE_ST_CALLDATA);
+ xmlNode *call_data = pcmk__xe_create(wrapper, __func__);
+
+ crm_xml_add(bcast, PCMK__XA_T, PCMK__VALUE_STONITH_NG);
+ crm_xml_add(bcast, PCMK__XA_SUBT, PCMK__VALUE_BROADCAST);
+ crm_xml_add(bcast, PCMK__XA_ST_OP, STONITH_OP_FENCE_HISTORY);
+ crm_xml_add_int(bcast, PCMK__XA_ST_CALLOPT, callopts);
+
+ pcmk__xml_copy(call_data, history);
+ if (target != NULL) {
+ crm_xml_add(call_data, PCMK__XA_ST_TARGET, target);
}
- add_message_xml(bcast, F_STONITH_CALLDATA, data);
- send_cluster_message(NULL, crm_msg_stonith_ng, bcast, FALSE);
- free_xml(data);
+ pcmk__cluster_send_message(NULL, crm_msg_stonith_ng, bcast);
+
free_xml(bcast);
}
@@ -100,7 +98,7 @@ stonith_fence_history_cleanup(const char *target,
g_hash_table_foreach_remove(stonith_remote_op_list,
stonith_remove_history_entry,
(gpointer) target);
- fenced_send_notification(T_STONITH_NOTIFY_HISTORY, NULL, NULL);
+ fenced_send_notification(PCMK__VALUE_ST_NOTIFY_HISTORY, NULL, NULL);
}
}
@@ -133,34 +131,68 @@ stonith_fence_history_cleanup(const char *target,
* situations where it would be handy to have it probably.
*/
-
-static int
-op_time_sort(const void *a_voidp, const void *b_voidp)
+/*!
+ * \internal
+ * \brief Compare two remote fencing operations by status and completion time
+ *
+ * A pending operation is ordered before a completed operation. If both
+ * operations have completed, then the more recently completed operation is
+ * ordered first. Two pending operations are considered equal.
+ *
+ * \param[in] a First \c remote_fencing_op_t to compare
+ * \param[in] b Second \c remote_fencing_op_t to compare
+ *
+ * \return Standard comparison result (a negative integer if \p a is lesser,
+ * 0 if the values are equal, and a positive integer if \p a is greater)
+ */
+static gint
+cmp_op_by_completion(gconstpointer a, gconstpointer b)
{
- const remote_fencing_op_t **a = (const remote_fencing_op_t **) a_voidp;
- const remote_fencing_op_t **b = (const remote_fencing_op_t **) b_voidp;
- gboolean a_pending = ((*a)->state != st_failed) && ((*a)->state != st_done);
- gboolean b_pending = ((*b)->state != st_failed) && ((*b)->state != st_done);
+ const remote_fencing_op_t *op1 = a;
+ const remote_fencing_op_t *op2 = b;
+ bool op1_pending = stonith__op_state_pending(op1->state);
+ bool op2_pending = stonith__op_state_pending(op2->state);
- if (a_pending && b_pending) {
+ if (op1_pending && op2_pending) {
return 0;
- } else if (a_pending) {
+ }
+ if (op1_pending) {
return -1;
- } else if (b_pending) {
+ }
+ if (op2_pending) {
return 1;
- } else if ((*b)->completed == (*a)->completed) {
- if ((*b)->completed_nsec > (*a)->completed_nsec) {
- return 1;
- } else if ((*b)->completed_nsec == (*a)->completed_nsec) {
- return 0;
- }
- } else if ((*b)->completed > (*a)->completed) {
+ }
+ if (op1->completed > op2->completed) {
+ return -1;
+ }
+ if (op1->completed < op2->completed) {
return 1;
}
-
- return -1;
+ if (op1->completed_nsec > op2->completed_nsec) {
+ return -1;
+ }
+ if (op1->completed_nsec < op2->completed_nsec) {
+ return 1;
+ }
+ return 0;
}
+/*!
+ * \internal
+ * \brief Remove a completed operation from \c stonith_remote_op_list
+ *
+ * \param[in] data \c remote_fencing_op_t to remove
+ * \param[in] user_data Ignored
+ */
+static void
+remove_completed_remote_op(gpointer data, gpointer user_data)
+{
+ const remote_fencing_op_t *op = data;
+
+ if (!stonith__op_state_pending(op->state)) {
+ g_hash_table_remove(stonith_remote_op_list, op->id);
+ }
+}
/*!
* \internal
@@ -170,43 +202,24 @@ op_time_sort(const void *a_voidp, const void *b_voidp)
void
stonith_fence_history_trim(void)
{
- guint num_ops;
-
- if (!stonith_remote_op_list) {
+ if (stonith_remote_op_list == NULL) {
return;
}
- num_ops = g_hash_table_size(stonith_remote_op_list);
- if (num_ops > MAX_STONITH_HISTORY) {
- remote_fencing_op_t *ops[num_ops];
- remote_fencing_op_t *op = NULL;
- GHashTableIter iter;
- int i;
- crm_trace("Fencing History growing beyond limit of %d so purge "
- "half of failed/successful attempts", MAX_STONITH_HISTORY);
+ if (g_hash_table_size(stonith_remote_op_list) > MAX_STONITH_HISTORY) {
+ GList *ops = g_hash_table_get_values(stonith_remote_op_list);
- /* write all ops into an array */
- i = 0;
- g_hash_table_iter_init(&iter, stonith_remote_op_list);
- while (g_hash_table_iter_next(&iter, NULL, (void **)&op)) {
- ops[i++] = op;
- }
- /* run quicksort over the array so that we get pending ops
- * first and then sorted most recent to oldest
- */
- qsort(ops, num_ops, sizeof(remote_fencing_op_t *), op_time_sort);
- /* purgest oldest half of the history entries */
- for (i = MAX_STONITH_HISTORY / 2; i < num_ops; i++) {
- /* keep pending ops even if they shouldn't fill more than
- * half of our buffer
- */
- if ((ops[i]->state == st_failed) || (ops[i]->state == st_done)) {
- g_hash_table_remove(stonith_remote_op_list, ops[i]->id);
- }
- }
- /* we've just purged valid data from the list so there is no need
- * to create a notification - if displayed it can stay
- */
+ crm_trace("More than %d entries in fencing history, purging oldest "
+ "completed operations", MAX_STONITH_HISTORY);
+
+ ops = g_list_sort(ops, cmp_op_by_completion);
+
+ // Always keep pending ops regardless of number of entries
+ g_list_foreach(g_list_nth(ops, MAX_STONITH_HISTORY / 2),
+ remove_completed_remote_op, NULL);
+
+ // No need for a notification after purging old data
+ g_list_free(ops);
}
}
@@ -228,10 +241,11 @@ stonith_xml_history_to_list(const xmlNode *history)
CRM_LOG_ASSERT(rv != NULL);
- for (xml_op = pcmk__xml_first_child(history); xml_op != NULL;
- xml_op = pcmk__xml_next(xml_op)) {
+ for (xml_op = pcmk__xe_first_child(history, NULL, NULL, NULL);
+ xml_op != NULL; xml_op = pcmk__xe_next(xml_op)) {
+
remote_fencing_op_t *op = NULL;
- char *id = crm_element_value_copy(xml_op, F_STONITH_REMOTE_OP_ID);
+ char *id = crm_element_value_copy(xml_op, PCMK__XA_ST_REMOTE_OP);
int state;
int exit_status = CRM_EX_OK;
int execution_status = PCMK_EXEC_DONE;
@@ -245,35 +259,37 @@ stonith_xml_history_to_list(const xmlNode *history)
crm_trace("Attaching op %s to hashtable", id);
- op = calloc(1, sizeof(remote_fencing_op_t));
+ op = pcmk__assert_alloc(1, sizeof(remote_fencing_op_t));
op->id = id;
- op->target = crm_element_value_copy(xml_op, F_STONITH_TARGET);
- op->action = crm_element_value_copy(xml_op, F_STONITH_ACTION);
- op->originator = crm_element_value_copy(xml_op, F_STONITH_ORIGIN);
- op->delegate = crm_element_value_copy(xml_op, F_STONITH_DELEGATE);
- op->client_name = crm_element_value_copy(xml_op, F_STONITH_CLIENTNAME);
- crm_element_value_ll(xml_op, F_STONITH_DATE, &completed);
+ op->target = crm_element_value_copy(xml_op, PCMK__XA_ST_TARGET);
+ op->action = crm_element_value_copy(xml_op, PCMK__XA_ST_DEVICE_ACTION);
+ op->originator = crm_element_value_copy(xml_op, PCMK__XA_ST_ORIGIN);
+ op->delegate = crm_element_value_copy(xml_op, PCMK__XA_ST_DELEGATE);
+ op->client_name = crm_element_value_copy(xml_op,
+ PCMK__XA_ST_CLIENTNAME);
+ crm_element_value_ll(xml_op, PCMK__XA_ST_DATE, &completed);
op->completed = (time_t) completed;
- crm_element_value_ll(xml_op, F_STONITH_DATE_NSEC, &completed_nsec);
+ crm_element_value_ll(xml_op, PCMK__XA_ST_DATE_NSEC, &completed_nsec);
op->completed_nsec = completed_nsec;
- crm_element_value_int(xml_op, F_STONITH_STATE, &state);
+ crm_element_value_int(xml_op, PCMK__XA_ST_STATE, &state);
op->state = (enum op_state) state;
/* @COMPAT We can't use stonith__xe_get_result() here because
* fencers <2.1.3 didn't include results, leading it to assume an error
* status. Instead, set an unknown status in that case.
*/
- if ((crm_element_value_int(xml_op, XML_LRM_ATTR_RC, &exit_status) < 0)
- || (crm_element_value_int(xml_op, XML_LRM_ATTR_OPSTATUS,
+ if ((crm_element_value_int(xml_op, PCMK__XA_RC_CODE, &exit_status) < 0)
+ || (crm_element_value_int(xml_op, PCMK__XA_OP_STATUS,
&execution_status) < 0)) {
exit_status = CRM_EX_INDETERMINATE;
execution_status = PCMK_EXEC_UNKNOWN;
}
pcmk__set_result(&op->result, exit_status, execution_status,
- crm_element_value(xml_op, XML_LRM_ATTR_EXIT_REASON));
+ crm_element_value(xml_op, PCMK_XA_EXIT_REASON));
pcmk__set_result_output(&op->result,
- crm_element_value_copy(xml_op, F_STONITH_OUTPUT),
+ crm_element_value_copy(xml_op,
+ PCMK__XA_ST_OUTPUT),
NULL);
@@ -309,7 +325,7 @@ stonith_local_history_diff_and_merge(GHashTable *remote_history,
if (stonith_remote_op_list) {
char *id = NULL;
- history = create_xml_node(NULL, F_STONITH_HISTORY_LIST);
+ history = pcmk__xe_create(NULL, PCMK__XE_ST_HISTORY);
g_hash_table_iter_init(&iter, stonith_remote_op_list);
while (g_hash_table_iter_next(&iter, (void **)&id, (void **)&op)) {
@@ -361,18 +377,19 @@ stonith_local_history_diff_and_merge(GHashTable *remote_history,
cnt++;
crm_trace("Attaching op %s", op->id);
- entry = create_xml_node(history, STONITH_OP_EXEC);
+ entry = pcmk__xe_create(history, STONITH_OP_EXEC);
if (add_id) {
- crm_xml_add(entry, F_STONITH_REMOTE_OP_ID, op->id);
+ crm_xml_add(entry, PCMK__XA_ST_REMOTE_OP, op->id);
}
- crm_xml_add(entry, F_STONITH_TARGET, op->target);
- crm_xml_add(entry, F_STONITH_ACTION, op->action);
- crm_xml_add(entry, F_STONITH_ORIGIN, op->originator);
- crm_xml_add(entry, F_STONITH_DELEGATE, op->delegate);
- crm_xml_add(entry, F_STONITH_CLIENTNAME, op->client_name);
- crm_xml_add_ll(entry, F_STONITH_DATE, op->completed);
- crm_xml_add_ll(entry, F_STONITH_DATE_NSEC, op->completed_nsec);
- crm_xml_add_int(entry, F_STONITH_STATE, op->state);
+ crm_xml_add(entry, PCMK__XA_ST_TARGET, op->target);
+ crm_xml_add(entry, PCMK__XA_ST_DEVICE_ACTION, op->action);
+ crm_xml_add(entry, PCMK__XA_ST_ORIGIN, op->originator);
+ crm_xml_add(entry, PCMK__XA_ST_DELEGATE, op->delegate);
+ crm_xml_add(entry, PCMK__XA_ST_CLIENTNAME, op->client_name);
+ crm_xml_add_ll(entry, PCMK__XA_ST_DATE, op->completed);
+ crm_xml_add_ll(entry, PCMK__XA_ST_DATE_NSEC,
+ op->completed_nsec);
+ crm_xml_add_int(entry, PCMK__XA_ST_STATE, op->state);
stonith__xe_set_result(entry, &op->result);
}
}
@@ -418,7 +435,7 @@ stonith_local_history_diff_and_merge(GHashTable *remote_history,
if (updated) {
stonith_fence_history_trim();
- fenced_send_notification(T_STONITH_NOTIFY_HISTORY, NULL, NULL);
+ fenced_send_notification(PCMK__VALUE_ST_NOTIFY_HISTORY, NULL, NULL);
}
if (cnt == 0) {
@@ -459,17 +476,19 @@ stonith_fence_history(xmlNode *msg, xmlNode **output,
const char *remote_peer, int options)
{
const char *target = NULL;
- xmlNode *dev = get_xpath_object("//@" F_STONITH_TARGET, msg, LOG_NEVER);
+ xmlNode *dev = get_xpath_object("//@" PCMK__XA_ST_TARGET, msg, LOG_NEVER);
xmlNode *out_history = NULL;
if (dev) {
- target = crm_element_value(dev, F_STONITH_TARGET);
+ target = crm_element_value(dev, PCMK__XA_ST_TARGET);
if (target && (options & st_opt_cs_nodeid)) {
int nodeid;
crm_node_t *node;
pcmk__scan_min_int(target, &nodeid, 0);
- node = pcmk__search_known_node_cache(nodeid, NULL, CRM_GET_PEER_ANY);
+ node = pcmk__search_node_caches(nodeid, NULL,
+ pcmk__node_search_any
+ |pcmk__node_search_cluster_cib);
if (node) {
target = node->uname;
}
@@ -477,18 +496,20 @@ stonith_fence_history(xmlNode *msg, xmlNode **output,
}
if (options & st_opt_cleanup) {
+ const char *call_id = crm_element_value(msg, PCMK__XA_ST_CALLID);
+
crm_trace("Cleaning up operations on %s in %p", target,
stonith_remote_op_list);
+ stonith_fence_history_cleanup(target, (call_id != NULL));
- stonith_fence_history_cleanup(target,
- crm_element_value(msg, F_STONITH_CALLID) != NULL);
} else if (options & st_opt_broadcast) {
/* there is no clear sign atm for when a history sync
is done so send a notification for anything
that smells like history-sync
*/
- fenced_send_notification(T_STONITH_NOTIFY_HISTORY_SYNCED, NULL, NULL);
- if (crm_element_value(msg, F_STONITH_CALLID)) {
+ fenced_send_notification(PCMK__VALUE_ST_NOTIFY_HISTORY_SYNCED, NULL,
+ NULL);
+ if (crm_element_value(msg, PCMK__XA_ST_CALLID) != NULL) {
/* this is coming from the stonith-API
*
* craft a broadcast with node's history
@@ -502,8 +523,8 @@ stonith_fence_history(xmlNode *msg, xmlNode **output,
NULL);
} else if (remote_peer &&
!pcmk__str_eq(remote_peer, stonith_our_uname, pcmk__str_casei)) {
- xmlNode *history = get_xpath_object("//" F_STONITH_HISTORY_LIST,
- msg, LOG_NEVER);
+ xmlNode *history = get_xpath_object("//" PCMK__XE_ST_HISTORY, msg,
+ LOG_NEVER);
/* either a broadcast created directly upon stonith-API request
* or a diff as response to such a thing
@@ -514,7 +535,9 @@ stonith_fence_history(xmlNode *msg, xmlNode **output,
* otherwise broadcast what we have on top
* marking as differential and merge in afterwards
*/
- if (!history || !pcmk__xe_attr_is_true(history, F_STONITH_DIFFERENTIAL)) {
+ if (!history
+ || !pcmk__xe_attr_is_true(history, PCMK__XA_ST_DIFFERENTIAL)) {
+
GHashTable *received_history = NULL;
if (history != NULL) {
@@ -524,7 +547,8 @@ stonith_fence_history(xmlNode *msg, xmlNode **output,
stonith_local_history_diff_and_merge(received_history, TRUE, NULL);
if (out_history) {
crm_trace("Broadcasting history-diff to peers");
- pcmk__xe_set_bool_attr(out_history, F_STONITH_DIFFERENTIAL, true);
+ pcmk__xe_set_bool_attr(out_history,
+ PCMK__XA_ST_DIFFERENTIAL, true);
stonith_send_broadcast_history(out_history,
st_opt_broadcast | st_opt_discard_reply,
NULL);
diff --git a/daemons/fenced/fenced_remote.c b/daemons/fenced/fenced_remote.c
index 843b3d4..f87eeb6 100644
--- a/daemons/fenced/fenced_remote.c
+++ b/daemons/fenced/fenced_remote.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2023 the Pacemaker project contributors
+ * Copyright 2009-2024 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -24,7 +24,6 @@
#include <regex.h>
#include <crm/crm.h>
-#include <crm/msg_xml.h>
#include <crm/common/ipc.h>
#include <crm/common/ipc_internal.h>
#include <crm/cluster/internal.h>
@@ -370,24 +369,25 @@ undo_op_remap(remote_fencing_op_t *op)
* \internal
* \brief Create notification data XML for a fencing operation result
*
- * \param[in] op Fencer operation that completed
+ * \param[in,out] parent Parent XML element for newly created element
+ * \param[in] op Fencer operation that completed
*
* \return Newly created XML to add as notification data
* \note The caller is responsible for freeing the result.
*/
static xmlNode *
-fencing_result2xml(const remote_fencing_op_t *op)
+fencing_result2xml(xmlNode *parent, const remote_fencing_op_t *op)
{
- xmlNode *notify_data = create_xml_node(NULL, T_STONITH_NOTIFY_FENCE);
+ xmlNode *notify_data = pcmk__xe_create(parent, PCMK__XE_ST_NOTIFY_FENCE);
- crm_xml_add_int(notify_data, "state", op->state);
- crm_xml_add(notify_data, F_STONITH_TARGET, op->target);
- crm_xml_add(notify_data, F_STONITH_ACTION, op->action);
- crm_xml_add(notify_data, F_STONITH_DELEGATE, op->delegate);
- crm_xml_add(notify_data, F_STONITH_REMOTE_OP_ID, op->id);
- crm_xml_add(notify_data, F_STONITH_ORIGIN, op->originator);
- crm_xml_add(notify_data, F_STONITH_CLIENTID, op->client_id);
- crm_xml_add(notify_data, F_STONITH_CLIENTNAME, op->client_name);
+ crm_xml_add_int(notify_data, PCMK_XA_STATE, op->state);
+ crm_xml_add(notify_data, PCMK__XA_ST_TARGET, op->target);
+ crm_xml_add(notify_data, PCMK__XA_ST_DEVICE_ACTION, op->action);
+ crm_xml_add(notify_data, PCMK__XA_ST_DELEGATE, op->delegate);
+ crm_xml_add(notify_data, PCMK__XA_ST_REMOTE_OP, op->id);
+ crm_xml_add(notify_data, PCMK__XA_ST_ORIGIN, op->originator);
+ crm_xml_add(notify_data, PCMK__XA_ST_CLIENTID, op->client_id);
+ crm_xml_add(notify_data, PCMK__XA_ST_CLIENTNAME, op->client_name);
return notify_data;
}
@@ -403,25 +403,26 @@ void
fenced_broadcast_op_result(const remote_fencing_op_t *op, bool op_merged)
{
static int count = 0;
- xmlNode *bcast = create_xml_node(NULL, T_STONITH_REPLY);
- xmlNode *notify_data = fencing_result2xml(op);
+ xmlNode *bcast = pcmk__xe_create(NULL, PCMK__XE_ST_REPLY);
+ xmlNode *wrapper = NULL;
+ xmlNode *notify_data = NULL;
count++;
crm_trace("Broadcasting result to peers");
- crm_xml_add(bcast, F_TYPE, T_STONITH_NOTIFY);
- crm_xml_add(bcast, F_SUBTYPE, "broadcast");
- crm_xml_add(bcast, F_STONITH_OPERATION, T_STONITH_NOTIFY);
- crm_xml_add_int(bcast, "count", count);
+ crm_xml_add(bcast, PCMK__XA_T, PCMK__VALUE_ST_NOTIFY);
+ crm_xml_add(bcast, PCMK__XA_SUBT, PCMK__VALUE_BROADCAST);
+ crm_xml_add(bcast, PCMK__XA_ST_OP, STONITH_OP_NOTIFY);
+ crm_xml_add_int(bcast, PCMK_XA_COUNT, count);
if (op_merged) {
- pcmk__xe_set_bool_attr(bcast, F_STONITH_MERGED, true);
+ pcmk__xe_set_bool_attr(bcast, PCMK__XA_ST_OP_MERGED, true);
}
+ wrapper = pcmk__xe_create(bcast, PCMK__XE_ST_CALLDATA);
+ notify_data = fencing_result2xml(wrapper, op);
stonith__xe_set_result(notify_data, &op->result);
- add_message_xml(bcast, F_STONITH_CALLDATA, notify_data);
- send_cluster_message(NULL, crm_msg_stonith_ng, bcast, FALSE);
- free_xml(notify_data);
+ pcmk__cluster_send_message(NULL, crm_msg_stonith_ng, bcast);
free_xml(bcast);
return;
@@ -447,12 +448,12 @@ handle_local_reply_and_notify(remote_fencing_op_t *op, xmlNode *data)
}
/* Do notification with a clean data object */
- crm_xml_add_int(data, "state", op->state);
- crm_xml_add(data, F_STONITH_TARGET, op->target);
- crm_xml_add(data, F_STONITH_OPERATION, op->action);
+ crm_xml_add_int(data, PCMK_XA_STATE, op->state);
+ crm_xml_add(data, PCMK__XA_ST_TARGET, op->target);
+ crm_xml_add(data, PCMK__XA_ST_OP, op->action);
reply = fenced_construct_reply(op->request, data, &op->result);
- crm_xml_add(reply, F_STONITH_DELEGATE, op->delegate);
+ crm_xml_add(reply, PCMK__XA_ST_DELEGATE, op->delegate);
/* Send fencing OP reply to local client that initiated fencing */
client = pcmk__find_client_by_id(op->client_id);
@@ -463,10 +464,11 @@ handle_local_reply_and_notify(remote_fencing_op_t *op, xmlNode *data)
}
/* bcast to all local clients that the fencing operation happend */
- notify_data = fencing_result2xml(op);
- fenced_send_notification(T_STONITH_NOTIFY_FENCE, &op->result, notify_data);
+ notify_data = fencing_result2xml(NULL, op);
+ fenced_send_notification(PCMK__VALUE_ST_NOTIFY_FENCE, &op->result,
+ notify_data);
free_xml(notify_data);
- fenced_send_notification(T_STONITH_NOTIFY_HISTORY, NULL, NULL);
+ fenced_send_notification(PCMK__VALUE_ST_NOTIFY_HISTORY, NULL, NULL);
/* mark this op as having notify's already sent */
op->notify_sent = TRUE;
@@ -509,12 +511,13 @@ finalize_op_duplicates(remote_fencing_op_t *op, xmlNode *data)
static char *
delegate_from_xml(xmlNode *xml)
{
- xmlNode *match = get_xpath_object("//@" F_STONITH_DELEGATE, xml, LOG_NEVER);
+ xmlNode *match = get_xpath_object("//@" PCMK__XA_ST_DELEGATE, xml,
+ LOG_NEVER);
if (match == NULL) {
- return crm_element_value_copy(xml, F_ORIG);
+ return crm_element_value_copy(xml, PCMK__XA_SRC);
} else {
- return crm_element_value_copy(match, F_STONITH_DELEGATE);
+ return crm_element_value_copy(match, PCMK__XA_ST_DELEGATE);
}
}
@@ -564,7 +567,7 @@ finalize_op(remote_fencing_op_t *op, xmlNode *data, bool dup)
undo_op_remap(op);
if (data == NULL) {
- data = create_xml_node(NULL, "remote-op");
+ data = pcmk__xe_create(NULL, "remote-op");
local_data = data;
} else if (op->delegate == NULL) {
@@ -584,15 +587,15 @@ finalize_op(remote_fencing_op_t *op, xmlNode *data, bool dup)
}
}
- if (dup || (crm_element_value(data, F_STONITH_MERGED) != NULL)) {
+ if (dup || (crm_element_value(data, PCMK__XA_ST_OP_MERGED) != NULL)) {
op_merged = true;
}
/* Tell everyone the operation is done, we will continue
* with doing the local notifications once we receive
* the broadcast back. */
- subt = crm_element_value(data, F_SUBTYPE);
- if (!dup && !pcmk__str_eq(subt, "broadcast", pcmk__str_casei)) {
+ subt = crm_element_value(data, PCMK__XA_SUBT);
+ if (!dup && !pcmk__str_eq(subt, PCMK__VALUE_BROADCAST, pcmk__str_none)) {
/* Defer notification until the bcast message arrives */
fenced_broadcast_op_result(op, op_merged);
free_xml(local_data);
@@ -800,7 +803,8 @@ add_required_device(remote_fencing_op_t *op, const char *device)
sort_strings);
if (!match) {
- op->automatic_list = g_list_prepend(op->automatic_list, strdup(device));
+ op->automatic_list = g_list_prepend(op->automatic_list,
+ pcmk__str_copy(device));
}
}
@@ -833,7 +837,10 @@ set_op_device_list(remote_fencing_op_t * op, GList *devices)
op->devices_list = NULL;
}
for (lpc = devices; lpc != NULL; lpc = lpc->next) {
- op->devices_list = g_list_append(op->devices_list, strdup(lpc->data));
+ const char *device = lpc->data;
+
+ op->devices_list = g_list_append(op->devices_list,
+ pcmk__str_copy(device));
}
op->devices = op->devices_list;
}
@@ -1001,6 +1008,7 @@ merge_duplicates(remote_fencing_op_t *op)
g_hash_table_iter_init(&iter, stonith_remote_op_list);
while (g_hash_table_iter_next(&iter, NULL, (void **)&other)) {
const char *other_action = op_requested_action(other);
+ crm_node_t *node = NULL;
if (!strcmp(op->id, other->id)) {
continue; // Don't compare against self
@@ -1030,7 +1038,11 @@ merge_duplicates(remote_fencing_op_t *op)
op->id, other->id, other->target);
continue;
}
- if (!fencing_peer_active(crm_get_peer(0, other->originator))) {
+
+ node = pcmk__get_node(0, other->originator, NULL,
+ pcmk__node_search_cluster_member);
+
+ if (!fencing_peer_active(node)) {
crm_notice("Failing action '%s' targeting %s originating from "
"client %s@%s: Originator is dead " CRM_XS " id=%.8s",
other->action, other->target, other->client_name,
@@ -1042,8 +1054,8 @@ merge_duplicates(remote_fencing_op_t *op)
}
if ((other->total_timeout > 0)
&& (now > (other->total_timeout + other->created))) {
- crm_trace("%.8s not duplicate of %.8s: old (%ld vs. %ld + %d)",
- op->id, other->id, now, other->created,
+ crm_trace("%.8s not duplicate of %.8s: old (%lld vs. %lld + %ds)",
+ op->id, other->id, (long long)now, (long long)other->created,
other->total_timeout);
continue;
}
@@ -1055,7 +1067,7 @@ merge_duplicates(remote_fencing_op_t *op)
if (other->total_timeout == 0) {
other->total_timeout = op->total_timeout =
TIMEOUT_MULTIPLY_FACTOR * get_op_total_timeout(op, NULL);
- crm_trace("Best guess as to timeout used for %.8s: %d",
+ crm_trace("Best guess as to timeout used for %.8s: %ds",
other->id, other->total_timeout);
}
crm_notice("Merging fencing action '%s' targeting %s originating from "
@@ -1097,12 +1109,12 @@ int
fenced_handle_manual_confirmation(const pcmk__client_t *client, xmlNode *msg)
{
remote_fencing_op_t *op = NULL;
- xmlNode *dev = get_xpath_object("//@" F_STONITH_TARGET, msg, LOG_ERR);
+ xmlNode *dev = get_xpath_object("//@" PCMK__XA_ST_TARGET, msg, LOG_ERR);
CRM_CHECK(dev != NULL, return EPROTO);
crm_notice("Received manual confirmation that %s has been fenced",
- pcmk__s(crm_element_value(dev, F_STONITH_TARGET),
+ pcmk__s(crm_element_value(dev, PCMK__XA_ST_TARGET),
"unknown target"));
op = initiate_remote_stonith_op(client, msg, TRUE);
if (op == NULL) {
@@ -1110,7 +1122,7 @@ fenced_handle_manual_confirmation(const pcmk__client_t *client, xmlNode *msg)
}
op->state = st_done;
set_fencing_completed(op);
- op->delegate = strdup("a human");
+ op->delegate = pcmk__str_copy("a human");
// For the fencer's purposes, the fencing operation is done
pcmk__set_result(&op->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
@@ -1137,7 +1149,8 @@ void *
create_remote_stonith_op(const char *client, xmlNode *request, gboolean peer)
{
remote_fencing_op_t *op = NULL;
- xmlNode *dev = get_xpath_object("//@" F_STONITH_TARGET, request, LOG_NEVER);
+ xmlNode *dev = get_xpath_object("//@" PCMK__XA_ST_TARGET, request,
+ LOG_NEVER);
int call_options = 0;
const char *operation = NULL;
@@ -1146,7 +1159,7 @@ create_remote_stonith_op(const char *client, xmlNode *request, gboolean peer)
/* If this operation is owned by another node, check to make
* sure we haven't already created this operation. */
if (peer && dev) {
- const char *op_id = crm_element_value(dev, F_STONITH_REMOTE_OP_ID);
+ const char *op_id = crm_element_value(dev, PCMK__XA_ST_REMOTE_OP);
CRM_CHECK(op_id != NULL, return NULL);
@@ -1158,15 +1171,14 @@ create_remote_stonith_op(const char *client, xmlNode *request, gboolean peer)
}
}
- op = calloc(1, sizeof(remote_fencing_op_t));
- CRM_ASSERT(op != NULL);
+ op = pcmk__assert_alloc(1, sizeof(remote_fencing_op_t));
- crm_element_value_int(request, F_STONITH_TIMEOUT, &(op->base_timeout));
+ crm_element_value_int(request, PCMK__XA_ST_TIMEOUT, &(op->base_timeout));
// Value -1 means disable any static/random fencing delays
- crm_element_value_int(request, F_STONITH_DELAY, &(op->client_delay));
+ crm_element_value_int(request, PCMK__XA_ST_DELAY, &(op->client_delay));
if (peer && dev) {
- op->id = crm_element_value_copy(dev, F_STONITH_REMOTE_OP_ID);
+ op->id = crm_element_value_copy(dev, PCMK__XA_ST_REMOTE_OP);
} else {
op->id = crm_generate_uuid();
}
@@ -1175,41 +1187,49 @@ create_remote_stonith_op(const char *client, xmlNode *request, gboolean peer)
op->state = st_query;
op->replies_expected = fencing_active_peers();
- op->action = crm_element_value_copy(dev, F_STONITH_ACTION);
- op->originator = crm_element_value_copy(dev, F_STONITH_ORIGIN);
- op->delegate = crm_element_value_copy(dev, F_STONITH_DELEGATE); /* May not be set */
- op->created = time(NULL);
+ op->action = crm_element_value_copy(dev, PCMK__XA_ST_DEVICE_ACTION);
+ /* The node initiating the stonith operation. If an operation is relayed,
+ * this is the last node the operation lands on. When in standalone mode,
+ * origin is the ID of the client that originated the operation.
+ *
+ * Or may be the name of the function that created the operation.
+ */
+ op->originator = crm_element_value_copy(dev, PCMK__XA_ST_ORIGIN);
if (op->originator == NULL) {
/* Local or relayed request */
- op->originator = strdup(stonith_our_uname);
+ op->originator = pcmk__str_copy(stonith_our_uname);
}
- CRM_LOG_ASSERT(client != NULL);
- if (client) {
- op->client_id = strdup(client);
- }
+ // Delegate may not be set
+ op->delegate = crm_element_value_copy(dev, PCMK__XA_ST_DELEGATE);
+ op->created = time(NULL);
+ CRM_LOG_ASSERT(client != NULL);
+ op->client_id = pcmk__str_copy(client);
/* For a RELAY operation, set fenced on the client. */
- operation = crm_element_value(request, F_STONITH_OPERATION);
+ operation = crm_element_value(request, PCMK__XA_ST_OP);
if (pcmk__str_eq(operation, STONITH_OP_RELAY, pcmk__str_none)) {
op->client_name = crm_strdup_printf("%s.%lu", crm_system_name,
(unsigned long) getpid());
} else {
- op->client_name = crm_element_value_copy(request, F_STONITH_CLIENTNAME);
+ op->client_name = crm_element_value_copy(request,
+ PCMK__XA_ST_CLIENTNAME);
}
- op->target = crm_element_value_copy(dev, F_STONITH_TARGET);
- op->request = copy_xml(request); /* TODO: Figure out how to avoid this */
- crm_element_value_int(request, F_STONITH_CALLOPTS, &call_options);
+ op->target = crm_element_value_copy(dev, PCMK__XA_ST_TARGET);
+
+ // @TODO Figure out how to avoid copying XML here
+ op->request = pcmk__xml_copy(NULL, request);
+ crm_element_value_int(request, PCMK__XA_ST_CALLOPT, &call_options);
op->call_options = call_options;
- crm_element_value_int(request, F_STONITH_CALLID, &(op->client_callid));
+ crm_element_value_int(request, PCMK__XA_ST_CALLID, &(op->client_callid));
crm_trace("%s new fencing op %s ('%s' targeting %s for client %s, "
- "base timeout %d, %u %s expected)",
+ "base timeout %ds, %u %s expected)",
(peer && dev)? "Recorded" : "Generated", op->id, op->action,
op->target, op->client_name, op->base_timeout,
op->replies_expected,
@@ -1220,14 +1240,15 @@ create_remote_stonith_op(const char *client, xmlNode *request, gboolean peer)
crm_node_t *node;
pcmk__scan_min_int(op->target, &nodeid, 0);
- node = pcmk__search_known_node_cache(nodeid, NULL, CRM_GET_PEER_ANY);
+ node = pcmk__search_node_caches(nodeid, NULL,
+ pcmk__node_search_any
+ |pcmk__node_search_cluster_cib);
/* Ensure the conversion only happens once */
stonith__clear_call_options(op->call_options, op->id, st_opt_cs_nodeid);
if (node && node->uname) {
- free(op->target);
- op->target = strdup(node->uname);
+ pcmk__str_update(&(op->target), node->uname);
} else {
crm_warn("Could not expand nodeid '%s' into a host name", op->target);
@@ -1239,7 +1260,7 @@ create_remote_stonith_op(const char *client, xmlNode *request, gboolean peer)
if (op->state != st_duplicate) {
/* kick history readers */
- fenced_send_notification(T_STONITH_NOTIFY_HISTORY, NULL, NULL);
+ fenced_send_notification(PCMK__VALUE_ST_NOTIFY_HISTORY, NULL, NULL);
}
/* safe to trim as long as that doesn't touch pending ops */
@@ -1272,7 +1293,7 @@ initiate_remote_stonith_op(const pcmk__client_t *client, xmlNode *request,
if (client) {
client_id = client->id;
} else {
- client_id = crm_element_value(request, F_STONITH_CLIENTID);
+ client_id = crm_element_value(request, PCMK__XA_ST_CLIENTID);
}
CRM_LOG_ASSERT(client_id != NULL);
@@ -1305,7 +1326,7 @@ initiate_remote_stonith_op(const pcmk__client_t *client, xmlNode *request,
default:
crm_notice("Requesting peer fencing (%s) targeting %s "
- CRM_XS " id=%.8s state=%s base_timeout=%d",
+ CRM_XS " id=%.8s state=%s base_timeout=%ds",
op->action, op->target, op->id,
stonith_op_state_str(op->state), op->base_timeout);
}
@@ -1313,24 +1334,24 @@ initiate_remote_stonith_op(const pcmk__client_t *client, xmlNode *request,
query = stonith_create_op(op->client_callid, op->id, STONITH_OP_QUERY,
NULL, op->call_options);
- crm_xml_add(query, F_STONITH_REMOTE_OP_ID, op->id);
- crm_xml_add(query, F_STONITH_TARGET, op->target);
- crm_xml_add(query, F_STONITH_ACTION, op_requested_action(op));
- crm_xml_add(query, F_STONITH_ORIGIN, op->originator);
- crm_xml_add(query, F_STONITH_CLIENTID, op->client_id);
- crm_xml_add(query, F_STONITH_CLIENTNAME, op->client_name);
- crm_xml_add_int(query, F_STONITH_TIMEOUT, op->base_timeout);
+ crm_xml_add(query, PCMK__XA_ST_REMOTE_OP, op->id);
+ crm_xml_add(query, PCMK__XA_ST_TARGET, op->target);
+ crm_xml_add(query, PCMK__XA_ST_DEVICE_ACTION, op_requested_action(op));
+ crm_xml_add(query, PCMK__XA_ST_ORIGIN, op->originator);
+ crm_xml_add(query, PCMK__XA_ST_CLIENTID, op->client_id);
+ crm_xml_add(query, PCMK__XA_ST_CLIENTNAME, op->client_name);
+ crm_xml_add_int(query, PCMK__XA_ST_TIMEOUT, op->base_timeout);
/* In case of RELAY operation, RELAY information is added to the query to delete the original operation of RELAY. */
- operation = crm_element_value(request, F_STONITH_OPERATION);
+ operation = crm_element_value(request, PCMK__XA_ST_OP);
if (pcmk__str_eq(operation, STONITH_OP_RELAY, pcmk__str_none)) {
- relay_op_id = crm_element_value(request, F_STONITH_REMOTE_OP_ID);
+ relay_op_id = crm_element_value(request, PCMK__XA_ST_REMOTE_OP);
if (relay_op_id) {
- crm_xml_add(query, F_STONITH_REMOTE_OP_ID_RELAY, relay_op_id);
+ crm_xml_add(query, PCMK__XA_ST_REMOTE_OP_RELAY, relay_op_id);
}
}
- send_cluster_message(NULL, crm_msg_stonith_ng, query, FALSE);
+ pcmk__cluster_send_message(NULL, crm_msg_stonith_ng, query);
free_xml(query);
query_timeout = op->base_timeout * TIMEOUT_MULTIPLY_FACTOR;
@@ -1348,6 +1369,16 @@ enum find_best_peer_options {
FIND_PEER_VERIFIED_ONLY = 0x0004,
};
+static bool
+is_watchdog_fencing(const remote_fencing_op_t *op, const char *device)
+{
+ return (stonith_watchdog_timeout_ms > 0
+ // Only an explicit mismatch is considered not a watchdog fencing.
+ && pcmk__str_eq(device, STONITH_WATCHDOG_ID, pcmk__str_null_matches)
+ && pcmk__is_fencing_action(op->action)
+ && node_does_watchdog_fencing(op->target));
+}
+
static peer_device_info_t *
find_best_peer(const char *device, remote_fencing_op_t * op, enum find_best_peer_options options)
{
@@ -1443,10 +1474,10 @@ stonith_choose_peer(remote_fencing_op_t * op)
&& pcmk_is_set(op->call_options, st_opt_topology)
&& (advance_topology_level(op, false) == pcmk_rc_ok));
- if ((stonith_watchdog_timeout_ms > 0)
- && pcmk__is_fencing_action(op->action)
- && pcmk__str_eq(device, STONITH_WATCHDOG_ID, pcmk__str_none)
- && node_does_watchdog_fencing(op->target)) {
+ /* With a simple watchdog fencing configuration without a topology,
+ * "device" is NULL here. Consider it should be done with watchdog fencing.
+ */
+ if (is_watchdog_fencing(op, device)) {
crm_info("Couldn't contact watchdog-fencing target-node (%s)",
op->target);
/* check_watchdog_fencing_and_wait will log additional info */
@@ -1458,32 +1489,69 @@ stonith_choose_peer(remote_fencing_op_t * op)
}
static int
+valid_fencing_timeout(int specified_timeout, bool action_specific,
+ const remote_fencing_op_t *op, const char *device)
+{
+ int timeout = specified_timeout;
+
+ if (!is_watchdog_fencing(op, device)) {
+ return timeout;
+ }
+
+ timeout = (int) QB_MIN(QB_MAX(specified_timeout,
+ stonith_watchdog_timeout_ms / 1000), INT_MAX);
+
+ if (timeout > specified_timeout) {
+ if (action_specific) {
+ crm_warn("pcmk_%s_timeout %ds for %s is too short (must be >= "
+ PCMK_OPT_STONITH_WATCHDOG_TIMEOUT " %ds), using %ds "
+ "instead",
+ op->action, specified_timeout, device? device : "watchdog",
+ timeout, timeout);
+
+ } else {
+ crm_warn("Fencing timeout %ds is too short (must be >= "
+ PCMK_OPT_STONITH_WATCHDOG_TIMEOUT " %ds), using %ds "
+ "instead",
+ specified_timeout, timeout, timeout);
+ }
+ }
+
+ return timeout;
+}
+
+static int
get_device_timeout(const remote_fencing_op_t *op,
const peer_device_info_t *peer, const char *device,
bool with_delay)
{
+ int timeout = op->base_timeout;
device_properties_t *props;
- int delay = 0;
+
+ timeout = valid_fencing_timeout(op->base_timeout, false, op, device);
if (!peer || !device) {
- return op->base_timeout;
+ return timeout;
}
props = g_hash_table_lookup(peer->devices, device);
if (!props) {
- return op->base_timeout;
+ return timeout;
+ }
+
+ if (props->custom_action_timeout[op->phase]) {
+ timeout = valid_fencing_timeout(props->custom_action_timeout[op->phase],
+ true, op, device);
}
// op->client_delay < 0 means disable any static/random fencing delays
if (with_delay && (op->client_delay >= 0)) {
// delay_base is eventually limited by delay_max
- delay = (props->delay_max[op->phase] > 0 ?
- props->delay_max[op->phase] : props->delay_base[op->phase]);
+ timeout += (props->delay_max[op->phase] > 0 ?
+ props->delay_max[op->phase] : props->delay_base[op->phase]);
}
- return (props->custom_action_timeout[op->phase]?
- props->custom_action_timeout[op->phase] : op->base_timeout)
- + delay;
+ return timeout;
}
struct timeout_data {
@@ -1532,7 +1600,7 @@ static int
get_op_total_timeout(const remote_fencing_op_t *op,
const peer_device_info_t *chosen_peer)
{
- int total_timeout = 0;
+ long long total_timeout = 0;
stonith_topology_t *tp = find_topology_for_host(op->target);
if (pcmk_is_set(op->call_options, st_opt_topology) && tp) {
@@ -1558,17 +1626,7 @@ get_op_total_timeout(const remote_fencing_op_t *op,
continue;
}
for (device_list = tp->levels[i]; device_list; device_list = device_list->next) {
- /* in case of watchdog-device we add the timeout to the budget
- regardless of if we got a reply or not
- */
- if ((stonith_watchdog_timeout_ms > 0)
- && pcmk__is_fencing_action(op->action)
- && pcmk__str_eq(device_list->data, STONITH_WATCHDOG_ID,
- pcmk__str_none)
- && node_does_watchdog_fencing(op->target)) {
- total_timeout += stonith_watchdog_timeout_ms / 1000;
- continue;
- }
+ bool found = false;
for (iter = op->query_results; iter != NULL; iter = iter->next) {
const peer_device_info_t *peer = iter->data;
@@ -1586,9 +1644,17 @@ get_op_total_timeout(const remote_fencing_op_t *op,
total_timeout += get_device_timeout(op, peer,
device_list->data,
true);
+ found = true;
break;
}
} /* End Loop3: match device with peer that owns device, find device's timeout period */
+
+ /* in case of watchdog-device we add the timeout to the budget
+ if didn't get a reply
+ */
+ if (!found && is_watchdog_fencing(op, device_list->data)) {
+ total_timeout += stonith_watchdog_timeout_ms / 1000;
+ }
} /* End Loop2: iterate through devices at a specific level */
} /*End Loop1: iterate through fencing levels */
@@ -1612,15 +1678,23 @@ get_op_total_timeout(const remote_fencing_op_t *op,
} else if (chosen_peer) {
total_timeout = get_peer_timeout(op, chosen_peer);
+
} else {
+ total_timeout = valid_fencing_timeout(op->base_timeout, false, op,
+ NULL);
+ }
+
+ if (total_timeout <= 0) {
total_timeout = op->base_timeout;
}
/* Take any requested fencing delay into account to prevent it from eating
* up the total timeout.
*/
- return ((total_timeout ? total_timeout : op->base_timeout)
- + ((op->client_delay > 0)? op->client_delay : 0));
+ if (op->client_delay > 0) {
+ total_timeout += op->client_delay;
+ }
+ return (int) QB_MIN(total_timeout, INT_MAX);
}
static void
@@ -1643,9 +1717,9 @@ report_timeout_period(remote_fencing_op_t * op, int op_timeout)
}
crm_trace("Reporting timeout for %s (id=%.8s)", op->client_name, op->id);
- client_node = crm_element_value(op->request, F_STONITH_CLIENTNODE);
- call_id = crm_element_value(op->request, F_STONITH_CALLID);
- client_id = crm_element_value(op->request, F_STONITH_CLIENTID);
+ client_node = crm_element_value(op->request, PCMK__XA_ST_CLIENTNODE);
+ call_id = crm_element_value(op->request, PCMK__XA_ST_CALLID);
+ client_id = crm_element_value(op->request, PCMK__XA_ST_CLIENTID);
if (!client_node || !call_id || !client_id) {
return;
}
@@ -1658,12 +1732,14 @@ report_timeout_period(remote_fencing_op_t * op, int op_timeout)
/* The client is connected to another node, relay this update to them */
update = stonith_create_op(op->client_callid, op->id, STONITH_OP_TIMEOUT_UPDATE, NULL, 0);
- crm_xml_add(update, F_STONITH_REMOTE_OP_ID, op->id);
- crm_xml_add(update, F_STONITH_CLIENTID, client_id);
- crm_xml_add(update, F_STONITH_CALLID, call_id);
- crm_xml_add_int(update, F_STONITH_TIMEOUT, op_timeout);
+ crm_xml_add(update, PCMK__XA_ST_REMOTE_OP, op->id);
+ crm_xml_add(update, PCMK__XA_ST_CLIENTID, client_id);
+ crm_xml_add(update, PCMK__XA_ST_CALLID, call_id);
+ crm_xml_add_int(update, PCMK__XA_ST_TIMEOUT, op_timeout);
- send_cluster_message(crm_get_peer(0, client_node), crm_msg_stonith_ng, update, FALSE);
+ pcmk__cluster_send_message(pcmk__get_node(0, client_node, NULL,
+ pcmk__node_search_cluster_member),
+ crm_msg_stonith_ng, update);
free_xml(update);
@@ -1742,17 +1818,18 @@ static gboolean
check_watchdog_fencing_and_wait(remote_fencing_op_t * op)
{
if (node_does_watchdog_fencing(op->target)) {
+ guint timeout_ms = QB_MIN(stonith_watchdog_timeout_ms, UINT_MAX);
- crm_notice("Waiting %lds for %s to self-fence (%s) for "
+ crm_notice("Waiting %s for %s to self-fence (%s) for "
"client %s " CRM_XS " id=%.8s",
- (stonith_watchdog_timeout_ms / 1000),
- op->target, op->action, op->client_name, op->id);
+ pcmk__readable_interval(timeout_ms), op->target, op->action,
+ op->client_name, op->id);
if (op->op_timer_one) {
g_source_remove(op->op_timer_one);
}
- op->op_timer_one = g_timeout_add(stonith_watchdog_timeout_ms,
- remote_op_watchdog_done, op);
+ op->op_timer_one = g_timeout_add(timeout_ms, remote_op_watchdog_done,
+ op);
return TRUE;
} else {
crm_debug("Skipping fallback to watchdog-fencing as %s is "
@@ -1819,7 +1896,7 @@ request_peer_fencing(remote_fencing_op_t *op, peer_device_info_t *peer)
op->total_timeout = TIMEOUT_MULTIPLY_FACTOR * get_op_total_timeout(op, peer);
op->op_timer_total = g_timeout_add(1000 * op->total_timeout, remote_op_timeout, op);
report_timeout_period(op, op->total_timeout);
- crm_info("Total timeout set to %d for peer's fencing targeting %s for %s"
+ crm_info("Total timeout set to %ds for peer's fencing targeting %s for %s"
CRM_XS "id=%.8s",
op->total_timeout, op->target, op->client_name, op->id);
}
@@ -1846,6 +1923,9 @@ request_peer_fencing(remote_fencing_op_t *op, peer_device_info_t *peer)
if (peer) {
int timeout_one = 0;
xmlNode *remote_op = stonith_create_op(op->client_callid, op->id, STONITH_OP_FENCE, NULL, 0);
+ const crm_node_t *peer_node =
+ pcmk__get_node(0, peer->host, NULL,
+ pcmk__node_search_cluster_member);
if (op->client_delay > 0) {
/* Take requested fencing delay into account to prevent it from
@@ -1854,15 +1934,15 @@ request_peer_fencing(remote_fencing_op_t *op, peer_device_info_t *peer)
timeout_one = TIMEOUT_MULTIPLY_FACTOR * op->client_delay;
}
- crm_xml_add(remote_op, F_STONITH_REMOTE_OP_ID, op->id);
- crm_xml_add(remote_op, F_STONITH_TARGET, op->target);
- crm_xml_add(remote_op, F_STONITH_ACTION, op->action);
- crm_xml_add(remote_op, F_STONITH_ORIGIN, op->originator);
- crm_xml_add(remote_op, F_STONITH_CLIENTID, op->client_id);
- crm_xml_add(remote_op, F_STONITH_CLIENTNAME, op->client_name);
- crm_xml_add_int(remote_op, F_STONITH_TIMEOUT, timeout);
- crm_xml_add_int(remote_op, F_STONITH_CALLOPTS, op->call_options);
- crm_xml_add_int(remote_op, F_STONITH_DELAY, op->client_delay);
+ crm_xml_add(remote_op, PCMK__XA_ST_REMOTE_OP, op->id);
+ crm_xml_add(remote_op, PCMK__XA_ST_TARGET, op->target);
+ crm_xml_add(remote_op, PCMK__XA_ST_DEVICE_ACTION, op->action);
+ crm_xml_add(remote_op, PCMK__XA_ST_ORIGIN, op->originator);
+ crm_xml_add(remote_op, PCMK__XA_ST_CLIENTID, op->client_id);
+ crm_xml_add(remote_op, PCMK__XA_ST_CLIENTNAME, op->client_name);
+ crm_xml_add_int(remote_op, PCMK__XA_ST_TIMEOUT, timeout);
+ crm_xml_add_int(remote_op, PCMK__XA_ST_CALLOPT, op->call_options);
+ crm_xml_add_int(remote_op, PCMK__XA_ST_DELAY, op->client_delay);
if (device) {
timeout_one += TIMEOUT_MULTIPLY_FACTOR *
@@ -1871,14 +1951,15 @@ request_peer_fencing(remote_fencing_op_t *op, peer_device_info_t *peer)
"using %s " CRM_XS " for client %s (%ds)",
peer->host, op->action, op->target, device,
op->client_name, timeout_one);
- crm_xml_add(remote_op, F_STONITH_DEVICE, device);
+ crm_xml_add(remote_op, PCMK__XA_ST_DEVICE_ID, device);
} else {
timeout_one += TIMEOUT_MULTIPLY_FACTOR * get_peer_timeout(op, peer);
crm_notice("Requesting that %s perform '%s' action targeting %s "
- CRM_XS " for client %s (%ds, %lds)",
+ CRM_XS " for client %s (%ds, %s)",
peer->host, op->action, op->target, op->client_name,
- timeout_one, stonith_watchdog_timeout_ms);
+ timeout_one,
+ pcmk__readable_interval(stonith_watchdog_timeout_ms));
}
op->state = st_exec;
@@ -1887,11 +1968,8 @@ request_peer_fencing(remote_fencing_op_t *op, peer_device_info_t *peer)
op->op_timer_one = 0;
}
- if (!((stonith_watchdog_timeout_ms > 0)
- && (pcmk__str_eq(device, STONITH_WATCHDOG_ID, pcmk__str_none)
- || (pcmk__str_eq(peer->host, op->target, pcmk__str_casei)
- && pcmk__is_fencing_action(op->action)))
- && check_watchdog_fencing_and_wait(op))) {
+ if (!is_watchdog_fencing(op, device)
+ || !check_watchdog_fencing_and_wait(op)) {
/* Some thoughts about self-fencing cases reaching this point:
- Actually check in check_watchdog_fencing_and_wait
@@ -1907,8 +1985,8 @@ request_peer_fencing(remote_fencing_op_t *op, peer_device_info_t *peer)
enabled for a node but the watchdog-fencing-device isn't
explicitly chosen for suicide. Local pe-execution in sbd
may detect the node as unclean and lead to timely suicide.
- Otherwise the selection of stonith-watchdog-timeout at
- least is questionable.
+ Otherwise the selection of PCMK_OPT_STONITH_WATCHDOG_TIMEOUT
+ at least is questionable.
*/
/* coming here we're not waiting for watchdog timeout -
@@ -1916,7 +1994,7 @@ request_peer_fencing(remote_fencing_op_t *op, peer_device_info_t *peer)
op->op_timer_one = g_timeout_add((1000 * timeout_one), remote_op_timeout_one, op);
}
- send_cluster_message(crm_get_peer(0, peer->host), crm_msg_stonith_ng, remote_op, FALSE);
+ pcmk__cluster_send_message(peer_node, crm_msg_stonith_ng, remote_op);
peer->tried = TRUE;
free_xml(remote_op);
return;
@@ -1948,11 +2026,15 @@ request_peer_fencing(remote_fencing_op_t *op, peer_device_info_t *peer)
* but we have all the expected replies, then no devices
* are available to execute the fencing operation. */
- if(stonith_watchdog_timeout_ms > 0 && pcmk__str_eq(device,
- STONITH_WATCHDOG_ID, pcmk__str_null_matches)) {
- if (check_watchdog_fencing_and_wait(op)) {
- return;
- }
+ if (is_watchdog_fencing(op, device)
+ && check_watchdog_fencing_and_wait(op)) {
+ /* Consider a watchdog fencing targeting an offline node executing
+ * once it starts waiting for the target to self-fence. So that when
+ * the query timer pops, remote_op_query_timeout() considers the
+ * fencing already in progress.
+ */
+ op->state = st_exec;
+ return;
}
if (op->state == st_query) {
@@ -2078,24 +2160,25 @@ parse_action_specific(const xmlNode *xml, const char *peer, const char *device,
enum st_remap_phase phase, device_properties_t *props)
{
props->custom_action_timeout[phase] = 0;
- crm_element_value_int(xml, F_STONITH_ACTION_TIMEOUT,
+ crm_element_value_int(xml, PCMK__XA_ST_ACTION_TIMEOUT,
&props->custom_action_timeout[phase]);
if (props->custom_action_timeout[phase]) {
- crm_trace("Peer %s with device %s returned %s action timeout %d",
+ crm_trace("Peer %s with device %s returned %s action timeout %ds",
peer, device, action, props->custom_action_timeout[phase]);
}
props->delay_max[phase] = 0;
- crm_element_value_int(xml, F_STONITH_DELAY_MAX, &props->delay_max[phase]);
+ crm_element_value_int(xml, PCMK__XA_ST_DELAY_MAX, &props->delay_max[phase]);
if (props->delay_max[phase]) {
- crm_trace("Peer %s with device %s returned maximum of random delay %d for %s",
+ crm_trace("Peer %s with device %s returned maximum of random delay %ds for %s",
peer, device, props->delay_max[phase], action);
}
props->delay_base[phase] = 0;
- crm_element_value_int(xml, F_STONITH_DELAY_BASE, &props->delay_base[phase]);
+ crm_element_value_int(xml, PCMK__XA_ST_DELAY_BASE,
+ &props->delay_base[phase]);
if (props->delay_base[phase]) {
- crm_trace("Peer %s with device %s returned base delay %d for %s",
+ crm_trace("Peer %s with device %s returned base delay %ds for %s",
peer, device, props->delay_base[phase], action);
}
@@ -2103,7 +2186,7 @@ parse_action_specific(const xmlNode *xml, const char *peer, const char *device,
if (pcmk__str_eq(action, PCMK_ACTION_ON, pcmk__str_none)) {
int required = 0;
- crm_element_value_int(xml, F_STONITH_DEVICE_REQUIRED, &required);
+ crm_element_value_int(xml, PCMK__XA_ST_REQUIRED, &required);
if (required) {
crm_trace("Peer %s requires device %s to execute for action %s",
peer, device, action);
@@ -2114,7 +2197,7 @@ parse_action_specific(const xmlNode *xml, const char *peer, const char *device,
/* If a reboot is remapped to off+on, it's possible that a node is allowed
* to perform one action but not another.
*/
- if (pcmk__xe_attr_is_true(xml, F_STONITH_ACTION_DISALLOWED)) {
+ if (pcmk__xe_attr_is_true(xml, PCMK__XA_ST_ACTION_DISALLOWED)) {
props->disallowed[phase] = TRUE;
crm_trace("Peer %s is disallowed from executing %s for device %s",
peer, action, device);
@@ -2136,37 +2219,39 @@ add_device_properties(const xmlNode *xml, remote_fencing_op_t *op,
{
xmlNode *child;
int verified = 0;
- device_properties_t *props = calloc(1, sizeof(device_properties_t));
+ device_properties_t *props =
+ pcmk__assert_alloc(1, sizeof(device_properties_t));
int flags = st_device_supports_on; /* Old nodes that don't set the flag assume they support the on action */
/* Add a new entry to this peer's devices list */
- CRM_ASSERT(props != NULL);
- g_hash_table_insert(peer->devices, strdup(device), props);
+ g_hash_table_insert(peer->devices, pcmk__str_copy(device), props);
/* Peers with verified (monitored) access will be preferred */
- crm_element_value_int(xml, F_STONITH_DEVICE_VERIFIED, &verified);
+ crm_element_value_int(xml, PCMK__XA_ST_MONITOR_VERIFIED, &verified);
if (verified) {
crm_trace("Peer %s has confirmed a verified device %s",
peer->host, device);
props->verified = TRUE;
}
- crm_element_value_int(xml, F_STONITH_DEVICE_SUPPORT_FLAGS, &flags);
+ crm_element_value_int(xml, PCMK__XA_ST_DEVICE_SUPPORT_FLAGS, &flags);
props->device_support_flags = flags;
/* Parse action-specific device properties */
parse_action_specific(xml, peer->host, device, op_requested_action(op),
op, st_phase_requested, props);
- for (child = pcmk__xml_first_child(xml); child != NULL;
- child = pcmk__xml_next(child)) {
+ for (child = pcmk__xe_first_child(xml, NULL, NULL, NULL); child != NULL;
+ child = pcmk__xe_next(child)) {
/* Replies for "reboot" operations will include the action-specific
* values for "off" and "on" in child elements, just in case the reboot
* winds up getting remapped.
*/
- if (pcmk__str_eq(ID(child), PCMK_ACTION_OFF, pcmk__str_none)) {
+ if (pcmk__str_eq(pcmk__xe_id(child), PCMK_ACTION_OFF, pcmk__str_none)) {
parse_action_specific(child, peer->host, device, PCMK_ACTION_OFF,
op, st_phase_off, props);
- } else if (pcmk__str_eq(ID(child), PCMK_ACTION_ON, pcmk__str_none)) {
+
+ } else if (pcmk__str_eq(pcmk__xe_id(child), PCMK_ACTION_ON,
+ pcmk__str_none)) {
parse_action_specific(child, peer->host, device, PCMK_ACTION_ON,
op, st_phase_on, props);
}
@@ -2188,19 +2273,17 @@ static peer_device_info_t *
add_result(remote_fencing_op_t *op, const char *host, int ndevices,
const xmlNode *xml)
{
- peer_device_info_t *peer = calloc(1, sizeof(peer_device_info_t));
+ peer_device_info_t *peer = pcmk__assert_alloc(1,
+ sizeof(peer_device_info_t));
xmlNode *child;
- // cppcheck seems not to understand the abort logic in CRM_CHECK
- // cppcheck-suppress memleak
- CRM_CHECK(peer != NULL, return NULL);
- peer->host = strdup(host);
+ peer->host = pcmk__str_copy(host);
peer->devices = pcmk__strkey_table(free, free);
/* Each child element describes one capable device available to the peer */
- for (child = pcmk__xml_first_child(xml); child != NULL;
- child = pcmk__xml_next(child)) {
- const char *device = ID(child);
+ for (child = pcmk__xe_first_child(xml, NULL, NULL, NULL); child != NULL;
+ child = pcmk__xe_next(child)) {
+ const char *device = pcmk__xe_id(child);
if (device) {
add_device_properties(child, op, peer, device);
@@ -2241,16 +2324,16 @@ process_remote_stonith_query(xmlNode *msg)
remote_fencing_op_t *op = NULL;
peer_device_info_t *peer = NULL;
uint32_t replies_expected;
- xmlNode *dev = get_xpath_object("//@" F_STONITH_REMOTE_OP_ID, msg, LOG_ERR);
+ xmlNode *dev = get_xpath_object("//@" PCMK__XA_ST_REMOTE_OP, msg, LOG_ERR);
CRM_CHECK(dev != NULL, return -EPROTO);
- id = crm_element_value(dev, F_STONITH_REMOTE_OP_ID);
+ id = crm_element_value(dev, PCMK__XA_ST_REMOTE_OP);
CRM_CHECK(id != NULL, return -EPROTO);
- dev = get_xpath_object("//@" F_STONITH_AVAILABLE_DEVICES, msg, LOG_ERR);
+ dev = get_xpath_object("//@" PCMK__XA_ST_AVAILABLE_DEVICES, msg, LOG_ERR);
CRM_CHECK(dev != NULL, return -EPROTO);
- crm_element_value_int(dev, F_STONITH_AVAILABLE_DEVICES, &ndevices);
+ crm_element_value_int(dev, PCMK__XA_ST_AVAILABLE_DEVICES, &ndevices);
op = g_hash_table_lookup(stonith_remote_op_list, id);
if (op == NULL) {
@@ -2266,7 +2349,7 @@ process_remote_stonith_query(xmlNode *msg)
if ((++op->replies >= replies_expected) && (op->state == st_query)) {
have_all_replies = TRUE;
}
- host = crm_element_value(msg, F_ORIG);
+ host = crm_element_value(msg, PCMK__XA_SRC);
host_is_target = pcmk__str_eq(host, op->target, pcmk__str_casei);
crm_info("Query result %d of %d from %s for %s/%s (%d device%s) %s",
@@ -2339,12 +2422,12 @@ fenced_process_fencing_reply(xmlNode *msg)
const char *id = NULL;
const char *device = NULL;
remote_fencing_op_t *op = NULL;
- xmlNode *dev = get_xpath_object("//@" F_STONITH_REMOTE_OP_ID, msg, LOG_ERR);
+ xmlNode *dev = get_xpath_object("//@" PCMK__XA_ST_REMOTE_OP, msg, LOG_ERR);
pcmk__action_result_t result = PCMK__UNKNOWN_RESULT;
CRM_CHECK(dev != NULL, return);
- id = crm_element_value(dev, F_STONITH_REMOTE_OP_ID);
+ id = crm_element_value(dev, PCMK__XA_ST_REMOTE_OP);
CRM_CHECK(id != NULL, return);
dev = stonith__find_xe_with_result(msg);
@@ -2352,7 +2435,7 @@ fenced_process_fencing_reply(xmlNode *msg)
stonith__xe_get_result(dev, &result);
- device = crm_element_value(dev, F_STONITH_DEVICE);
+ device = crm_element_value(dev, PCMK__XA_ST_DEVICE_ID);
if (stonith_remote_op_list) {
op = g_hash_table_lookup(stonith_remote_op_list, id);
@@ -2360,7 +2443,7 @@ fenced_process_fencing_reply(xmlNode *msg)
if ((op == NULL) && pcmk__result_ok(&result)) {
/* Record successful fencing operations */
- const char *client_id = crm_element_value(dev, F_STONITH_CLIENTID);
+ const char *client_id = crm_element_value(dev, PCMK__XA_ST_CLIENTID);
op = create_remote_stonith_op(client_id, dev, TRUE);
}
@@ -2383,7 +2466,9 @@ fenced_process_fencing_reply(xmlNode *msg)
return;
}
- if (pcmk__str_eq(crm_element_value(msg, F_SUBTYPE), "broadcast", pcmk__str_casei)) {
+ if (pcmk__str_eq(crm_element_value(msg, PCMK__XA_SUBT),
+ PCMK__VALUE_BROADCAST, pcmk__str_none)) {
+
if (pcmk__result_ok(&op->result)) {
op->state = st_done;
} else {
@@ -2412,7 +2497,7 @@ fenced_process_fencing_reply(xmlNode *msg)
return;
}
- device = crm_element_value(msg, F_STONITH_DEVICE);
+ device = crm_element_value(msg, PCMK__XA_ST_DEVICE_ID);
if ((op->phase == 2) && !pcmk__result_ok(&op->result)) {
/* A remapped "on" failed, but the node was already turned off
diff --git a/daemons/fenced/fenced_scheduler.c b/daemons/fenced/fenced_scheduler.c
index 27d990f..69e16fa 100644
--- a/daemons/fenced/fenced_scheduler.c
+++ b/daemons/fenced/fenced_scheduler.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2023 the Pacemaker project contributors
+ * Copyright 2009-2024 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -124,14 +124,14 @@ register_if_fencing_device(gpointer data, gpointer user_data)
if (rsc->children != NULL) {
for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
register_if_fencing_device(iter->data, NULL);
- if (pe_rsc_is_clone(rsc)) {
+ if (pcmk__is_clone(rsc)) {
return; // Only one instance needs to be checked for clones
}
}
return;
}
- rclass = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS);
+ rclass = crm_element_value(rsc->xml, PCMK_XA_CLASS);
if (!pcmk__str_eq(rclass, PCMK_RESOURCE_CLASS_STONITH, pcmk__str_casei)) {
return; // Not a fencing device
}
@@ -163,8 +163,7 @@ register_if_fencing_device(gpointer data, gpointer user_data)
}
// If device is in a group, check whether local node is allowed for group
- if ((rsc->parent != NULL)
- && (rsc->parent->variant == pcmk_rsc_variant_group)) {
+ if (pcmk__is_group(rsc->parent)) {
pcmk_node_t *group_node = local_node_allowed_for(rsc->parent);
if ((group_node != NULL) && (group_node->weight < 0)) {
@@ -177,8 +176,12 @@ register_if_fencing_device(gpointer data, gpointer user_data)
crm_debug("Reloading configuration of fencing device %s", rsc->id);
- agent = crm_element_value(rsc->xml, XML_EXPR_ATTR_TYPE);
+ agent = crm_element_value(rsc->xml, PCMK_XA_TYPE);
+ /* @COMPAT Support for node attribute expressions in rules for resource
+ * meta-attributes is deprecated. When we can break behavioral backward
+ * compatibility, replace node with NULL here.
+ */
get_meta_attributes(rsc->meta, rsc, node, scheduler);
rsc_provides = g_hash_table_lookup(rsc->meta, PCMK_STONITH_PROVIDES);
diff --git a/daemons/fenced/pacemaker-fenced.c b/daemons/fenced/pacemaker-fenced.c
index 7c69fb8..5ba97b5 100644
--- a/daemons/fenced/pacemaker-fenced.c
+++ b/daemons/fenced/pacemaker-fenced.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2023 the Pacemaker project contributors
+ * Copyright 2009-2024 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -22,7 +22,6 @@
#include <inttypes.h> // PRIu32, PRIx32
#include <crm/crm.h>
-#include <crm/msg_xml.h>
#include <crm/common/cmdline_internal.h>
#include <crm/common/ipc.h>
#include <crm/common/ipc_internal.h>
@@ -42,7 +41,7 @@
#define SUMMARY "daemon for executing fencing devices in a Pacemaker cluster"
char *stonith_our_uname = NULL;
-long stonith_watchdog_timeout_ms = 0;
+long long stonith_watchdog_timeout_ms = 0;
GList *stonith_watchdog_targets = NULL;
static GMainLoop *mainloop = NULL;
@@ -75,11 +74,11 @@ st_ipc_accept(qb_ipcs_connection_t * c, uid_t uid, gid_t gid)
if (stonith_shutdown_flag) {
crm_info("Ignoring new client [%d] during shutdown",
pcmk__client_pid(c));
- return -EPERM;
+ return -ECONNREFUSED;
}
if (pcmk__new_client(c, uid, gid) == NULL) {
- return -EIO;
+ return -ENOMEM;
}
return 0;
}
@@ -102,34 +101,31 @@ st_ipc_dispatch(qb_ipcs_connection_t * qbc, void *data, size_t size)
request = pcmk__client_data2xml(c, data, &id, &flags);
if (request == NULL) {
- pcmk__ipc_send_ack(c, id, flags, "nack", NULL, CRM_EX_PROTOCOL);
+ pcmk__ipc_send_ack(c, id, flags, PCMK__XE_NACK, NULL, CRM_EX_PROTOCOL);
return 0;
}
- op = crm_element_value(request, F_CRM_TASK);
+ op = crm_element_value(request, PCMK__XA_CRM_TASK);
if(pcmk__str_eq(op, CRM_OP_RM_NODE_CACHE, pcmk__str_casei)) {
- crm_xml_add(request, F_TYPE, T_STONITH_NG);
- crm_xml_add(request, F_STONITH_OPERATION, op);
- crm_xml_add(request, F_STONITH_CLIENTID, c->id);
- crm_xml_add(request, F_STONITH_CLIENTNAME, pcmk__client_name(c));
- crm_xml_add(request, F_STONITH_CLIENTNODE, stonith_our_uname);
+ crm_xml_add(request, PCMK__XA_T, PCMK__VALUE_STONITH_NG);
+ crm_xml_add(request, PCMK__XA_ST_OP, op);
+ crm_xml_add(request, PCMK__XA_ST_CLIENTID, c->id);
+ crm_xml_add(request, PCMK__XA_ST_CLIENTNAME, pcmk__client_name(c));
+ crm_xml_add(request, PCMK__XA_ST_CLIENTNODE, stonith_our_uname);
- send_cluster_message(NULL, crm_msg_stonith_ng, request, FALSE);
+ pcmk__cluster_send_message(NULL, crm_msg_stonith_ng, request);
free_xml(request);
return 0;
}
if (c->name == NULL) {
- const char *value = crm_element_value(request, F_STONITH_CLIENTNAME);
+ const char *value = crm_element_value(request, PCMK__XA_ST_CLIENTNAME);
- if (value == NULL) {
- value = "unknown";
- }
- c->name = crm_strdup_printf("%s.%u", value, c->pid);
+ c->name = crm_strdup_printf("%s.%u", pcmk__s(value, "unknown"), c->pid);
}
- crm_element_value_int(request, F_STONITH_CALLOPTS, &call_options);
+ crm_element_value_int(request, PCMK__XA_ST_CALLOPT, &call_options);
crm_trace("Flags %#08" PRIx32 "/%#08x for command %" PRIu32
" from client %s", flags, call_options, id, pcmk__client_name(c));
@@ -139,9 +135,9 @@ st_ipc_dispatch(qb_ipcs_connection_t * qbc, void *data, size_t size)
c->request_id = id; /* Reply only to the last one */
}
- crm_xml_add(request, F_STONITH_CLIENTID, c->id);
- crm_xml_add(request, F_STONITH_CLIENTNAME, pcmk__client_name(c));
- crm_xml_add(request, F_STONITH_CLIENTNODE, stonith_our_uname);
+ crm_xml_add(request, PCMK__XA_ST_CLIENTID, c->id);
+ crm_xml_add(request, PCMK__XA_ST_CLIENTNAME, pcmk__client_name(c));
+ crm_xml_add(request, PCMK__XA_ST_CLIENTNODE, stonith_our_uname);
crm_log_xml_trace(request, "ipc-received");
stonith_command(c, id, flags, request, NULL);
@@ -177,10 +173,10 @@ st_ipc_destroy(qb_ipcs_connection_t * c)
static void
stonith_peer_callback(xmlNode * msg, void *private_data)
{
- const char *remote_peer = crm_element_value(msg, F_ORIG);
- const char *op = crm_element_value(msg, F_STONITH_OPERATION);
+ const char *remote_peer = crm_element_value(msg, PCMK__XA_SRC);
+ const char *op = crm_element_value(msg, PCMK__XA_ST_OP);
- if (pcmk__str_eq(op, "poke", pcmk__str_none)) {
+ if (pcmk__str_eq(op, STONITH_OP_POKE, pcmk__str_none)) {
return;
}
@@ -197,20 +193,19 @@ stonith_peer_ais_callback(cpg_handle_t handle,
uint32_t kind = 0;
xmlNode *xml = NULL;
const char *from = NULL;
- char *data = pcmk_message_common_cs(handle, nodeid, pid, msg, &kind, &from);
+ char *data = pcmk__cpg_message_data(handle, nodeid, pid, msg, &kind, &from);
if(data == NULL) {
return;
}
if (kind == crm_class_cluster) {
- xml = string2xml(data);
+ xml = pcmk__xml_parse(data);
if (xml == NULL) {
crm_err("Invalid XML: '%.120s'", data);
free(data);
return;
}
- crm_xml_add(xml, F_ORIG, from);
- /* crm_xml_add_int(xml, F_SEQ, wrapper->id); */
+ crm_xml_add(xml, PCMK__XA_SRC, from);
stonith_peer_callback(xml, NULL);
}
@@ -257,7 +252,7 @@ do_local_reply(const xmlNode *notify_src, pcmk__client_t *client,
uint64_t
get_stonith_flag(const char *name)
{
- if (pcmk__str_eq(name, T_STONITH_NOTIFY_FENCE, pcmk__str_casei)) {
+ if (pcmk__str_eq(name, PCMK__VALUE_ST_NOTIFY_FENCE, pcmk__str_none)) {
return st_callback_notify_fence;
} else if (pcmk__str_eq(name, STONITH_OP_DEVICE_ADD, pcmk__str_casei)) {
@@ -266,10 +261,12 @@ get_stonith_flag(const char *name)
} else if (pcmk__str_eq(name, STONITH_OP_DEVICE_DEL, pcmk__str_casei)) {
return st_callback_device_del;
- } else if (pcmk__str_eq(name, T_STONITH_NOTIFY_HISTORY, pcmk__str_casei)) {
+ } else if (pcmk__str_eq(name, PCMK__VALUE_ST_NOTIFY_HISTORY,
+ pcmk__str_none)) {
return st_callback_notify_history;
- } else if (pcmk__str_eq(name, T_STONITH_NOTIFY_HISTORY_SYNCED, pcmk__str_casei)) {
+ } else if (pcmk__str_eq(name, PCMK__VALUE_ST_NOTIFY_HISTORY_SYNCED,
+ pcmk__str_none)) {
return st_callback_notify_history_synced;
}
@@ -287,7 +284,7 @@ stonith_notify_client(gpointer key, gpointer value, gpointer user_data)
CRM_CHECK(client != NULL, return);
CRM_CHECK(update_msg != NULL, return);
- type = crm_element_value(update_msg, F_SUBTYPE);
+ type = crm_element_value(update_msg, PCMK__XA_SUBT);
CRM_CHECK(type != NULL, crm_log_xml_err(update_msg, "notify"); return);
if (client->ipcs == NULL) {
@@ -325,10 +322,10 @@ do_stonith_async_timeout_update(const char *client_id, const char *call_id, int
return;
}
- notify_data = create_xml_node(NULL, T_STONITH_TIMEOUT_VALUE);
- crm_xml_add(notify_data, F_TYPE, T_STONITH_TIMEOUT_VALUE);
- crm_xml_add(notify_data, F_STONITH_CALLID, call_id);
- crm_xml_add_int(notify_data, F_STONITH_TIMEOUT, timeout);
+ notify_data = pcmk__xe_create(NULL, PCMK__XE_ST_ASYNC_TIMEOUT_VALUE);
+ crm_xml_add(notify_data, PCMK__XA_T, PCMK__VALUE_ST_ASYNC_TIMEOUT_VALUE);
+ crm_xml_add(notify_data, PCMK__XA_ST_CALLID, call_id);
+ crm_xml_add_int(notify_data, PCMK__XA_ST_TIMEOUT, timeout);
crm_trace("timeout update is %d for client %s and call id %s", timeout, client_id, call_id);
@@ -352,17 +349,19 @@ fenced_send_notification(const char *type, const pcmk__action_result_t *result,
xmlNode *data)
{
/* TODO: Standardize the contents of data */
- xmlNode *update_msg = create_xml_node(NULL, "notify");
+ xmlNode *update_msg = pcmk__xe_create(NULL, PCMK__XE_NOTIFY);
CRM_LOG_ASSERT(type != NULL);
- crm_xml_add(update_msg, F_TYPE, T_STONITH_NOTIFY);
- crm_xml_add(update_msg, F_SUBTYPE, type);
- crm_xml_add(update_msg, F_STONITH_OPERATION, type);
+ crm_xml_add(update_msg, PCMK__XA_T, PCMK__VALUE_ST_NOTIFY);
+ crm_xml_add(update_msg, PCMK__XA_SUBT, type);
+ crm_xml_add(update_msg, PCMK__XA_ST_OP, type);
stonith__xe_set_result(update_msg, result);
if (data != NULL) {
- add_message_xml(update_msg, F_STONITH_CALLDATA, data);
+ xmlNode *wrapper = pcmk__xe_create(update_msg, PCMK__XE_ST_CALLDATA);
+
+ pcmk__xml_copy(wrapper, data);
}
crm_trace("Notifying clients");
@@ -375,60 +374,25 @@ fenced_send_notification(const char *type, const pcmk__action_result_t *result,
* \internal
* \brief Send notifications for a configuration change to subscribed clients
*
- * \param[in] op Notification type (STONITH_OP_DEVICE_ADD,
- * STONITH_OP_DEVICE_DEL, STONITH_OP_LEVEL_ADD, or
- * STONITH_OP_LEVEL_DEL)
- * \param[in] result Operation result
- * \param[in] desc Description of what changed
- * \param[in] active Current number of devices or topologies in use
- */
-static void
-send_config_notification(const char *op, const pcmk__action_result_t *result,
- const char *desc, int active)
-{
- xmlNode *notify_data = create_xml_node(NULL, op);
-
- CRM_CHECK(notify_data != NULL, return);
-
- crm_xml_add(notify_data, F_STONITH_DEVICE, desc);
- crm_xml_add_int(notify_data, F_STONITH_ACTIVE, active);
-
- fenced_send_notification(op, result, notify_data);
- free_xml(notify_data);
-}
-
-/*!
- * \internal
- * \brief Send notifications for a device change to subscribed clients
- *
- * \param[in] op Notification type (STONITH_OP_DEVICE_ADD or
- * STONITH_OP_DEVICE_DEL)
+ * \param[in] op Notification type (\c STONITH_OP_DEVICE_ADD,
+ * \c STONITH_OP_DEVICE_DEL, \c STONITH_OP_LEVEL_ADD, or
+ * \c STONITH_OP_LEVEL_DEL)
* \param[in] result Operation result
- * \param[in] desc ID of device that changed
+ * \param[in] desc Description of what changed (either device ID or string
+ * representation of level
+ * (<tt><target>[<level_index>]</tt>))
*/
void
-fenced_send_device_notification(const char *op,
+fenced_send_config_notification(const char *op,
const pcmk__action_result_t *result,
const char *desc)
{
- send_config_notification(op, result, desc, g_hash_table_size(device_list));
-}
+ xmlNode *notify_data = pcmk__xe_create(NULL, op);
-/*!
- * \internal
- * \brief Send notifications for a topology level change to subscribed clients
- *
- * \param[in] op Notification type (STONITH_OP_LEVEL_ADD or
- * STONITH_OP_LEVEL_DEL)
- * \param[in] result Operation result
- * \param[in] desc String representation of level (<target>[<level_index>])
- */
-void
-fenced_send_level_notification(const char *op,
- const pcmk__action_result_t *result,
- const char *desc)
-{
- send_config_notification(op, result, desc, g_hash_table_size(topology));
+ crm_xml_add(notify_data, PCMK__XA_ST_DEVICE_ID, desc);
+
+ fenced_send_notification(op, result, notify_data);
+ free_xml(notify_data);
}
/*!
@@ -466,7 +430,7 @@ stonith_cleanup(void)
qb_ipcs_destroy(ipcs);
}
- crm_peer_destroy();
+ pcmk__cluster_destroy_node_caches();
pcmk__client_cleanup();
free_stonith_remote_op_list();
free_topology_list();
@@ -512,221 +476,34 @@ st_peer_update_callback(enum crm_status_type type, crm_node_t * node, const void
* This is a hack until we can send to a nodeid and/or we fix node name lookups
* These messages are ignored in stonith_peer_callback()
*/
- xmlNode *query = create_xml_node(NULL, "stonith_command");
+ xmlNode *query = pcmk__xe_create(NULL, PCMK__XE_STONITH_COMMAND);
- crm_xml_add(query, F_XML_TAGNAME, "stonith_command");
- crm_xml_add(query, F_TYPE, T_STONITH_NG);
- crm_xml_add(query, F_STONITH_OPERATION, "poke");
+ crm_xml_add(query, PCMK__XA_T, PCMK__VALUE_STONITH_NG);
+ crm_xml_add(query, PCMK__XA_ST_OP, STONITH_OP_POKE);
crm_debug("Broadcasting our uname because of node %u", node->id);
- send_cluster_message(NULL, crm_msg_stonith_ng, query, FALSE);
+ pcmk__cluster_send_message(NULL, crm_msg_stonith_ng, query);
free_xml(query);
}
}
-static pcmk__cluster_option_t fencer_options[] = {
- /* name, old name, type, allowed values,
- * default value, validator,
- * short description,
- * long description
- */
- {
- PCMK_STONITH_HOST_ARGUMENT, NULL, "string", NULL, "port", NULL,
- N_("Advanced use only: An alternate parameter to supply instead of 'port'"),
- N_("some devices do not support the "
- "standard 'port' parameter or may provide additional ones. Use "
- "this to specify an alternate, device-specific, parameter "
- "that should indicate the machine to be fenced. A value of "
- "none can be used to tell the cluster not to supply any "
- "additional parameters.")
- },
- {
- PCMK_STONITH_HOST_MAP,NULL, "string", NULL, "", NULL,
- N_("A mapping of host names to ports numbers for devices that do not support host names."),
- N_("Eg. node1:1;node2:2,3 would tell the cluster to use port 1 for node1 and ports 2 and 3 for node2")
- },
- {
- PCMK_STONITH_HOST_LIST,NULL, "string", NULL, "", NULL,
- N_("Eg. node1,node2,node3"),
- N_("A list of machines controlled by "
- "this device (Optional unless pcmk_host_list=static-list)")
- },
- {
- PCMK_STONITH_HOST_CHECK,NULL, "string", NULL, "dynamic-list", NULL,
- N_("How to determine which machines are controlled by the device."),
- N_("Allowed values: dynamic-list "
- "(query the device via the 'list' command), static-list "
- "(check the pcmk_host_list attribute), status "
- "(query the device via the 'status' command), "
- "none (assume every device can fence every "
- "machine)")
- },
- {
- PCMK_STONITH_DELAY_MAX,NULL, "time", NULL, "0s", NULL,
- N_("Enable a base delay for fencing actions and specify base delay value."),
- N_("Enable a delay of no more than the "
- "time specified before executing fencing actions. Pacemaker "
- "derives the overall delay by taking the value of "
- "pcmk_delay_base and adding a random delay value such "
- "that the sum is kept below this maximum.")
- },
- {
- PCMK_STONITH_DELAY_BASE,NULL, "string", NULL, "0s", NULL,
- N_("Enable a base delay for "
- "fencing actions and specify base delay value."),
- N_("This enables a static delay for "
- "fencing actions, which can help avoid \"death matches\" where "
- "two nodes try to fence each other at the same time. If "
- "pcmk_delay_max is also used, a random delay will be "
- "added such that the total delay is kept below that value."
- "This can be set to a single time value to apply to any node "
- "targeted by this device (useful if a separate device is "
- "configured for each target), or to a node map (for example, "
- "\"node1:1s;node2:5\") to set a different value per target.")
- },
- {
- PCMK_STONITH_ACTION_LIMIT,NULL, "integer", NULL, "1", NULL,
- N_("The maximum number of actions can be performed in parallel on this device"),
- N_("Cluster property concurrent-fencing=true needs to be configured first."
- "Then use this to specify the maximum number of actions can be performed in parallel on this device. -1 is unlimited.")
- },
- {
- "pcmk_reboot_action", NULL, "string", NULL,
- PCMK_ACTION_REBOOT, NULL,
- N_("Advanced use only: An alternate command to run instead of 'reboot'"),
- N_("Some devices do not support the standard commands or may provide additional ones.\n"
- "Use this to specify an alternate, device-specific, command that implements the \'reboot\' action.")
- },
- {
- "pcmk_reboot_timeout",NULL, "time", NULL, "60s", NULL,
- N_("Advanced use only: Specify an alternate timeout to use for reboot actions instead of stonith-timeout"),
- N_("Some devices need much more/less time to complete than normal."
- "Use this to specify an alternate, device-specific, timeout for \'reboot\' actions.")
- },
- {
- "pcmk_reboot_retries",NULL, "integer", NULL, "2", NULL,
- N_("Advanced use only: The maximum number of times to retry the 'reboot' command within the timeout period"),
- N_("Some devices do not support multiple connections."
- " Operations may 'fail' if the device is busy with another task so Pacemaker will automatically retry the operation, if there is time remaining."
- " Use this option to alter the number of times Pacemaker retries \'reboot\' actions before giving up.")
- },
- {
- "pcmk_off_action", NULL, "string", NULL,
- PCMK_ACTION_OFF, NULL,
- N_("Advanced use only: An alternate command to run instead of \'off\'"),
- N_("Some devices do not support the standard commands or may provide additional ones."
- "Use this to specify an alternate, device-specific, command that implements the \'off\' action.")
- },
- {
- "pcmk_off_timeout",NULL, "time", NULL, "60s", NULL,
- N_("Advanced use only: Specify an alternate timeout to use for off actions instead of stonith-timeout"),
- N_("Some devices need much more/less time to complete than normal."
- "Use this to specify an alternate, device-specific, timeout for \'off\' actions.")
- },
- {
- "pcmk_off_retries",NULL, "integer", NULL, "2", NULL,
- N_("Advanced use only: The maximum number of times to retry the 'off' command within the timeout period"),
- N_("Some devices do not support multiple connections."
- " Operations may 'fail' if the device is busy with another task so Pacemaker will automatically retry the operation, if there is time remaining."
- " Use this option to alter the number of times Pacemaker retries \'off\' actions before giving up.")
- },
- {
- "pcmk_on_action", NULL, "string", NULL,
- PCMK_ACTION_ON, NULL,
- N_("Advanced use only: An alternate command to run instead of 'on'"),
- N_("Some devices do not support the standard commands or may provide additional ones."
- "Use this to specify an alternate, device-specific, command that implements the \'on\' action.")
- },
- {
- "pcmk_on_timeout",NULL, "time", NULL, "60s", NULL,
- N_("Advanced use only: Specify an alternate timeout to use for on actions instead of stonith-timeout"),
- N_("Some devices need much more/less time to complete than normal."
- "Use this to specify an alternate, device-specific, timeout for \'on\' actions.")
- },
- {
- "pcmk_on_retries",NULL, "integer", NULL, "2", NULL,
- N_("Advanced use only: The maximum number of times to retry the 'on' command within the timeout period"),
- N_("Some devices do not support multiple connections."
- " Operations may 'fail' if the device is busy with another task so Pacemaker will automatically retry the operation, if there is time remaining."
- " Use this option to alter the number of times Pacemaker retries \'on\' actions before giving up.")
- },
- {
- "pcmk_list_action",NULL, "string", NULL,
- PCMK_ACTION_LIST, NULL,
- N_("Advanced use only: An alternate command to run instead of \'list\'"),
- N_("Some devices do not support the standard commands or may provide additional ones."
- "Use this to specify an alternate, device-specific, command that implements the \'list\' action.")
- },
- {
- "pcmk_list_timeout",NULL, "time", NULL, "60s", NULL,
- N_("Advanced use only: Specify an alternate timeout to use for list actions instead of stonith-timeout"),
- N_("Some devices need much more/less time to complete than normal."
- "Use this to specify an alternate, device-specific, timeout for \'list\' actions.")
- },
- {
- "pcmk_list_retries",NULL, "integer", NULL, "2", NULL,
- N_("Advanced use only: The maximum number of times to retry the \'list\' command within the timeout period"),
- N_("Some devices do not support multiple connections."
- " Operations may 'fail' if the device is busy with another task so Pacemaker will automatically retry the operation, if there is time remaining."
- " Use this option to alter the number of times Pacemaker retries \'list\' actions before giving up.")
- },
- {
- "pcmk_monitor_action", NULL, "string", NULL,
- PCMK_ACTION_MONITOR, NULL,
- N_("Advanced use only: An alternate command to run instead of \'monitor\'"),
- N_("Some devices do not support the standard commands or may provide additional ones."
- "Use this to specify an alternate, device-specific, command that implements the \'monitor\' action.")
- },
- {
- "pcmk_monitor_timeout",NULL, "time", NULL, "60s", NULL,
- N_("Advanced use only: Specify an alternate timeout to use for monitor actions instead of stonith-timeout"),
- N_("Some devices need much more/less time to complete than normal.\n"
- "Use this to specify an alternate, device-specific, timeout for \'monitor\' actions.")
- },
- {
- "pcmk_monitor_retries",NULL, "integer", NULL, "2", NULL,
- N_("Advanced use only: The maximum number of times to retry the \'monitor\' command within the timeout period"),
- N_("Some devices do not support multiple connections."
- " Operations may 'fail' if the device is busy with another task so Pacemaker will automatically retry the operation, if there is time remaining."
- " Use this option to alter the number of times Pacemaker retries \'monitor\' actions before giving up.")
- },
- {
- "pcmk_status_action", NULL, "string", NULL,
- PCMK_ACTION_STATUS, NULL,
- N_("Advanced use only: An alternate command to run instead of \'status\'"),
- N_("Some devices do not support the standard commands or may provide additional ones."
- "Use this to specify an alternate, device-specific, command that implements the \'status\' action.")
- },
- {
- "pcmk_status_timeout",NULL, "time", NULL, "60s", NULL,
- N_("Advanced use only: Specify an alternate timeout to use for status actions instead of stonith-timeout"),
- N_("Some devices need much more/less time to complete than normal."
- "Use this to specify an alternate, device-specific, timeout for \'status\' actions.")
- },
- {
- "pcmk_status_retries",NULL, "integer", NULL, "2", NULL,
- N_("Advanced use only: The maximum number of times to retry the \'status\' command within the timeout period"),
- N_("Some devices do not support multiple connections."
- " Operations may 'fail' if the device is busy with another task so Pacemaker will automatically retry the operation, if there is time remaining."
- " Use this option to alter the number of times Pacemaker retries \'status\' actions before giving up.")
- },
-};
-
-void
+/* @COMPAT Deprecated since 2.1.8. Use pcmk_list_fence_attrs() or
+ * crm_resource --list-options=fencing instead of querying daemon metadata.
+ */
+static int
fencer_metadata(void)
{
+ const char *name = "pacemaker-fenced";
const char *desc_short = N_("Instance attributes available for all "
- "\"stonith\"-class resources");
- const char *desc_long = N_("Instance attributes available for all \"stonith\"-"
- "class resources and used by Pacemaker's fence "
- "daemon, formerly known as stonithd");
-
- gchar *s = pcmk__format_option_metadata("pacemaker-fenced", desc_short,
- desc_long, fencer_options,
- PCMK__NELEM(fencer_options));
- printf("%s", s);
- g_free(s);
+ "\"stonith\"-class resources");
+ const char *desc_long = N_("Instance attributes available for all "
+ "\"stonith\"-class resources and used by "
+ "Pacemaker's fence daemon, formerly known as "
+ "stonithd");
+
+ return pcmk__daemon_metadata(out, name, desc_short, desc_long,
+ pcmk__opt_fencing);
}
static GOptionEntry entries[] = {
@@ -747,8 +524,7 @@ build_arg_context(pcmk__common_args_t *args, GOptionGroup **group)
{
GOptionContext *context = NULL;
- context = pcmk__build_arg_context(args, "text (default), xml", group,
- "[metadata]");
+ context = pcmk__build_arg_context(args, "text (default), xml", group, NULL);
pcmk__add_main_args(context, entries);
return context;
}
@@ -757,7 +533,7 @@ int
main(int argc, char **argv)
{
int rc = pcmk_rc_ok;
- crm_cluster_t *cluster = NULL;
+ pcmk_cluster_t *cluster = NULL;
crm_ipc_t *old_instance = NULL;
GError *error = NULL;
@@ -791,7 +567,13 @@ main(int argc, char **argv)
if ((g_strv_length(processed_args) >= 2)
&& pcmk__str_eq(processed_args[1], "metadata", pcmk__str_none)) {
- fencer_metadata();
+
+ rc = fencer_metadata();
+ if (rc != pcmk_rc_ok) {
+ exit_code = CRM_EX_FATAL;
+ g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
+ "Unable to display metadata: %s", pcmk_rc_str(rc));
+ }
goto done;
}
@@ -826,7 +608,7 @@ main(int argc, char **argv)
mainloop_add_signal(SIGTERM, stonith_shutdown);
- crm_peer_init();
+ pcmk__cluster_init_node_caches();
rc = fenced_scheduler_init();
if (rc != pcmk_rc_ok) {
@@ -840,16 +622,16 @@ main(int argc, char **argv)
if (!stand_alone) {
#if SUPPORT_COROSYNC
- if (is_corosync_cluster()) {
- cluster->destroy = stonith_peer_cs_destroy;
- cluster->cpg.cpg_deliver_fn = stonith_peer_ais_callback;
- cluster->cpg.cpg_confchg_fn = pcmk_cpg_membership;
+ if (pcmk_get_cluster_layer() == pcmk_cluster_layer_corosync) {
+ pcmk_cluster_set_destroy_fn(cluster, stonith_peer_cs_destroy);
+ pcmk_cpg_set_deliver_fn(cluster, stonith_peer_ais_callback);
+ pcmk_cpg_set_confchg_fn(cluster, pcmk__cpg_confchg_cb);
}
#endif // SUPPORT_COROSYNC
- crm_set_status_callback(&st_peer_update_callback);
+ pcmk__cluster_set_status_callback(&st_peer_update_callback);
- if (crm_cluster_connect(cluster) == FALSE) {
+ if (pcmk_cluster_connect(cluster) != pcmk_rc_ok) {
exit_code = CRM_EX_FATAL;
crm_crit("Cannot sign in to the cluster... terminating");
goto done;
diff --git a/daemons/fenced/pacemaker-fenced.h b/daemons/fenced/pacemaker-fenced.h
index 220978a..2d8047c 100644
--- a/daemons/fenced/pacemaker-fenced.h
+++ b/daemons/fenced/pacemaker-fenced.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2023 the Pacemaker project contributors
+ * Copyright 2009-2024 the Pacemaker project contributors
*
* This source code is licensed under the GNU General Public License version 2
* or later (GPLv2+) WITHOUT ANY WARRANTY.
@@ -111,8 +111,8 @@ typedef struct remote_fencing_op_s {
/*!
* Fencing delay (in seconds) requested by API client (used by controller to
- * implement priority-fencing-delay). A value of -1 means disable all
- * configured delays.
+ * implement \c PCMK_OPT_PRIORITY_FENCING_DELAY). A value of -1 means
+ * disable all configured delays.
*/
int client_delay;
@@ -253,12 +253,9 @@ void
void fenced_send_notification(const char *type,
const pcmk__action_result_t *result,
xmlNode *data);
-void fenced_send_device_notification(const char *op,
+void fenced_send_config_notification(const char *op,
const pcmk__action_result_t *result,
const char *desc);
-void fenced_send_level_notification(const char *op,
- const pcmk__action_result_t *result,
- const char *desc);
remote_fencing_op_t *initiate_remote_stonith_op(const pcmk__client_t *client,
xmlNode *request,
@@ -281,7 +278,6 @@ void set_fencing_completed(remote_fencing_op_t * op);
int fenced_handle_manual_confirmation(const pcmk__client_t *client,
xmlNode *msg);
-void fencer_metadata(void);
const char *fenced_device_reboot_action(const char *device_id);
bool fenced_device_supports_on(const char *device_id);
@@ -327,7 +323,7 @@ extern char *stonith_our_uname;
extern gboolean stand_alone;
extern GHashTable *device_list;
extern GHashTable *topology;
-extern long stonith_watchdog_timeout_ms;
+extern long long stonith_watchdog_timeout_ms;
extern GList *stonith_watchdog_targets;
extern GHashTable *stonith_remote_op_list;
extern crm_exit_t exit_code;