diff --git a/cts/cts-fencing.in b/cts/cts-fencing.in index 034304a974c..30fb39f2989 100644 --- a/cts/cts-fencing.in +++ b/cts/cts-fencing.in @@ -570,34 +570,6 @@ class FenceTests(Tests): test.add_log_pattern("Delaying 'off' action targeting node3 using true3", negative=True) - def build_nodeid_tests(self): - """Register tests that use a corosync node id.""" - our_uname = localname() - - # verify nodeid is supplied when nodeid is in the metadata parameters - test = self.new_test("supply_nodeid", - "Verify nodeid is given when fence agent has nodeid as parameter") - - test.add_cmd("stonith_admin", - args=f'--output-as=xml -R true1 -a fence_dummy -o mode=pass -o "pcmk_host_list={our_uname}"') - test.add_cmd("stonith_admin", args=f"--output-as=xml -F {our_uname} -t 3") - test.add_log_pattern(f"as nodeid with fence action 'off' targeting {our_uname}") - - # verify nodeid is _NOT_ supplied when nodeid is not in the metadata parameters - test = self.new_test("do_not_supply_nodeid", - "Verify nodeid is _NOT_ given when fence agent does not have nodeid as parameter") - - # use a host name that won't be in corosync.conf - test.add_cmd("stonith_admin", - args='--output-as=xml -R true1 -a fence_dummy_no_nodeid ' - f'-o mode=pass -o pcmk_host_list="regr-test {our_uname}"') - test.add_cmd("stonith_admin", args="--output-as=xml -F regr-test -t 3") - test.add_log_pattern("as nodeid with fence action 'off' targeting regr-test", - negative=True) - test.add_cmd("stonith_admin", args=f"--output-as=xml -F {our_uname} -t 3") - test.add_log_pattern("as nodeid with fence action 'off' targeting {our_uname}", - negative=True) - def build_unfence_tests(self): """Register tests that verify unfencing.""" our_uname = localname() @@ -917,7 +889,6 @@ def main(): tests.build_fence_no_merge_tests() tests.build_unfence_tests() tests.build_unfence_on_target_tests() - tests.build_nodeid_tests() tests.build_remap_tests() tests.build_query_tests() tests.build_metadata_tests() diff --git a/cts/support/fence_dummy.in b/cts/support/fence_dummy.in index 42c9a54eb9c..842fe47504f 100644 --- a/cts/support/fence_dummy.in +++ b/cts/support/fence_dummy.in @@ -1,7 +1,7 @@ #!@PYTHON@ """Dummy fence agent for testing.""" -__copyright__ = "Copyright 2012-2024 the Pacemaker project contributors" +__copyright__ = "Copyright 2012-2025 the Pacemaker project contributors" __license__ = "GNU General Public License version 2 or later (GPLv2+) WITHOUT ANY WARRANTY" import io @@ -159,14 +159,6 @@ ALL_OPT = { "shortdesc": "Ignored", "order": 4 }, - "nodeid": { - "getopt": "i:", - "longopt": "nodeid", - "help": "-i, --nodeid Corosync id of fence target (ignored)", - "required": "0", - "shortdesc": "Ignored", - "order": 4 - }, "uuid": { "getopt": "U:", "longopt": "uuid", @@ -446,8 +438,6 @@ def main(): no_reboot = True elif sys.argv[0].endswith("_no_on"): no_on = True - elif sys.argv[0].endswith("_no_nodeid"): - del ALL_OPT["nodeid"] device_opt = ALL_OPT.keys() diff --git a/daemons/fenced/fenced_cib.c b/daemons/fenced/fenced_cib.c index 887486d04e7..90c225569eb 100644 --- a/daemons/fenced/fenced_cib.c +++ b/daemons/fenced/fenced_cib.c @@ -194,6 +194,47 @@ update_stonith_watchdog_timeout_ms(xmlNode *cib) stonith_watchdog_timeout_ms = timeout_ms; } +/*! + * \internal + * \brief Mark a fence device dirty if its \c cib_registered flag is \c TRUE + * + * \param[in] key Ignored + * \param[in,out] value Fence device (fenced_device_t *) + * \param[in] user_data Ignored + * + * \note This function is suitable for use with \c g_hash_table_foreach(). + */ +static void +mark_dirty_if_cib_registered(gpointer key, gpointer value, gpointer user_data) +{ + fenced_device_t *device = value; + + if (device->cib_registered) { + device->dirty = TRUE; + } +} + +/*! + * \internal + * \brief Return the value of a fence device's \c dirty flag + * + * \param[in] key Ignored + * \param[in] value Fence device (fenced_device_t *) + * \param[in] user_data Ignored + * + * \return \c dirty flag of \p value + * + * \note This function is suitable for use with + * \c g_hash_table_foreach_remove(). + */ +static gboolean +device_is_dirty(gpointer key, gpointer value, gpointer user_data) +{ + fenced_device_t *device = value; + + return device->dirty; +} + /*! * \internal * \brief Update all STONITH device definitions based on current CIB @@ -201,20 +242,12 @@ update_stonith_watchdog_timeout_ms(xmlNode *cib) static void cib_devices_update(void) { - GHashTableIter iter; - stonith_device_t *device = NULL; - crm_info("Updating devices to version %s.%s.%s", 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)) { - if (device->cib_registered) { - device->dirty = TRUE; - } - } + fenced_foreach_device(mark_dirty_if_cib_registered, NULL); /* have list repopulated if cib has a watchdog-fencing-resource TODO: keep a cached list for queries happening while we are refreshing @@ -224,78 +257,78 @@ cib_devices_update(void) fenced_scheduler_run(local_cib); - g_hash_table_iter_init(&iter, device_list); - while (g_hash_table_iter_next(&iter, NULL, (void **)&device)) { - if (device->dirty) { - g_hash_table_iter_remove(&iter); - } - } + fenced_foreach_device_remove(device_is_dirty); } +#define PRIMITIVE_ID_XP_FRAGMENT "/" PCMK_XE_PRIMITIVE "[@" PCMK_XA_ID "='" + static void -update_cib_stonith_devices(const char *event, xmlNode * msg) +update_cib_stonith_devices(const xmlNode *patchset) { - int format = 1; - xmlNode *wrapper = pcmk__xe_first_child(msg, PCMK__XE_CIB_UPDATE_RESULT, - NULL, NULL); - xmlNode *patchset = pcmk__xe_first_child(wrapper, NULL, NULL, NULL); char *reason = NULL; - CRM_CHECK(patchset != NULL, return); - crm_element_value_int(patchset, PCMK_XA_FORMAT, &format); - - if (format != 2) { - crm_warn("Unknown patch format: %d", format); - return; - } - - for (xmlNode *change = pcmk__xe_first_child(patchset, NULL, NULL, NULL); + for (const xmlNode *change = pcmk__xe_first_child(patchset, NULL, NULL, + NULL); change != NULL; change = pcmk__xe_next(change, NULL)) { const char *op = crm_element_value(change, PCMK_XA_OPERATION); const char *xpath = crm_element_value(change, PCMK_XA_PATH); - const char *shortpath = NULL; + const char *primitive_xpath = NULL; if (pcmk__str_eq(op, PCMK_VALUE_MOVE, pcmk__str_null_matches) || (strstr(xpath, "/" PCMK_XE_STATUS) != NULL)) { continue; } - if (pcmk__str_eq(op, PCMK_VALUE_DELETE, pcmk__str_none) - && (strstr(xpath, "/" PCMK_XE_PRIMITIVE) != NULL)) { + primitive_xpath = strstr(xpath, PRIMITIVE_ID_XP_FRAGMENT); + if ((primitive_xpath != NULL) + && pcmk__str_eq(op, PCMK_VALUE_DELETE, pcmk__str_none)) { + const char *rsc_id = NULL; - char *search = NULL; - char *mutable = NULL; + const char *end_quote = NULL; - if ((strstr(xpath, PCMK_XE_INSTANCE_ATTRIBUTES) != NULL) - || (strstr(xpath, PCMK_XE_META_ATTRIBUTES) != NULL)) { + if ((strstr(primitive_xpath, PCMK_XE_INSTANCE_ATTRIBUTES) != NULL) + || (strstr(primitive_xpath, PCMK_XE_META_ATTRIBUTES) != NULL)) { reason = pcmk__str_copy("(meta) attribute deleted from " "resource"); break; } - mutable = pcmk__str_copy(xpath); - rsc_id = strstr(mutable, PCMK_XE_PRIMITIVE "[@" PCMK_XA_ID "=\'"); - if (rsc_id != NULL) { - rsc_id += strlen(PCMK_XE_PRIMITIVE "[@" PCMK_XA_ID "=\'"); - search = strchr(rsc_id, '\''); + + rsc_id = primitive_xpath + sizeof(PRIMITIVE_ID_XP_FRAGMENT) - 1; + end_quote = strchr(rsc_id, '\''); + + CRM_LOG_ASSERT(end_quote != NULL); + if (end_quote == NULL) { + crm_err("Bug: Malformed item in Pacemaker-generated patchset"); + continue; } - if (search != NULL) { - *search = 0; - stonith_device_remove(rsc_id, true); + + if (strchr(end_quote, '/') == NULL) { + /* The primitive element itself was deleted. If this was a + * fencing resource, it's faster to remove it directly than to + * run the scheduler and update all device registrations. + */ + char *copy = strndup(rsc_id, end_quote - rsc_id); + + pcmk__assert(copy != NULL); + stonith_device_remove(copy, true); + /* watchdog_device_update called afterwards to fall back to implicit definition if needed */ - } else { - crm_warn("Ignoring malformed CIB update (resource deletion)"); + + free(copy); + continue; } - free(mutable); - - } else if (strstr(xpath, "/" PCMK_XE_RESOURCES) - || strstr(xpath, "/" PCMK_XE_CONSTRAINTS) - || strstr(xpath, "/" PCMK_XE_RSC_DEFAULTS)) { - shortpath = strrchr(xpath, '/'); - pcmk__assert(shortpath != NULL); - reason = crm_strdup_printf("%s %s", op, shortpath+1); + } + + if (strstr(xpath, "/" PCMK_XE_RESOURCES) + || strstr(xpath, "/" PCMK_XE_CONSTRAINTS) + || strstr(xpath, "/" PCMK_XE_RSC_DEFAULTS)) { + + const char *shortpath = strrchr(xpath, '/'); + + reason = crm_strdup_printf("%s %s", op, shortpath + 1); break; } } @@ -313,8 +346,8 @@ static void watchdog_device_update(void) { if (stonith_watchdog_timeout_ms > 0) { - if (!g_hash_table_lookup(device_list, STONITH_WATCHDOG_ID) && - !stonith_watchdog_targets) { + if (!fenced_has_watchdog_device() + && (stonith_watchdog_targets == NULL)) { /* getting here watchdog-fencing enabled, no device there yet and reason isn't stonith_watchdog_targets preventing that */ @@ -325,15 +358,14 @@ watchdog_device_update(void) STONITH_WATCHDOG_ID, st_namespace_internal, STONITH_WATCHDOG_AGENT, - NULL, /* stonith_device_register will add our + NULL, /* fenced_device_register() will add our own name as PCMK_STONITH_HOST_LIST param so we can skip that here */ NULL); - rc = stonith_device_register(xml, TRUE); + rc = fenced_device_register(xml, true); pcmk__xml_free(xml); - if (rc != pcmk_ok) { - rc = pcmk_legacy2rc(rc); + if (rc != pcmk_rc_ok) { exit_code = CRM_EX_FATAL; crm_crit("Cannot register watchdog pseudo fence agent: %s", pcmk_rc_str(rc)); @@ -341,7 +373,7 @@ watchdog_device_update(void) } } - } else if (g_hash_table_lookup(device_list, STONITH_WATCHDOG_ID) != NULL) { + } else if (fenced_has_watchdog_device()) { /* be silent if no device - todo parameter to stonith_device_remove */ stonith_device_remove(STONITH_WATCHDOG_ID, true); } @@ -465,6 +497,7 @@ update_fencing_topology(const char *event, xmlNode *msg) static void update_cib_cache_cb(const char *event, xmlNode * msg) { + xmlNode *patchset = NULL; long long timeout_ms_saved = stonith_watchdog_timeout_ms; bool need_full_refresh = false; @@ -483,7 +516,6 @@ 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, PCMK__XA_CIB_RC, &rc); if (rc != pcmk_ok) { @@ -498,6 +530,11 @@ update_cib_cache_cb(const char *event, xmlNode * msg) switch (rc) { case pcmk_ok: case -pcmk_err_old_data: + /* @TODO Full refresh (with or without query) in case of + * -pcmk_err_old_data? It seems wrong to call + * stonith_device_remove() based on primitive deletion in an + * old diff. + */ break; case -pcmk_err_diff_resync: case -pcmk_err_diff_failed: @@ -532,7 +569,7 @@ update_cib_cache_cb(const char *event, xmlNode * msg) } else { // Partial refresh update_fencing_topology(event, msg); - update_cib_stonith_devices(event, msg); + update_cib_stonith_devices(patchset); } watchdog_device_update(); diff --git a/daemons/fenced/fenced_commands.c b/daemons/fenced/fenced_commands.c index 51666992bff..b31c52bf947 100644 --- a/daemons/fenced/fenced_commands.c +++ b/daemons/fenced/fenced_commands.c @@ -10,6 +10,7 @@ #include #include +#include // bool #include #include #include @@ -37,7 +38,8 @@ #include -GHashTable *device_list = NULL; +static GHashTable *device_table = NULL; + GHashTable *topology = NULL; static GList *cmd_list = NULL; @@ -76,14 +78,11 @@ static void search_devices_record_result(struct device_search_s *search, const c gboolean can_fence); static int get_agent_metadata(const char *agent, xmlNode **metadata); -static void read_action_metadata(stonith_device_t *device); +static void read_action_metadata(fenced_device_t *device); static enum fenced_target_by unpack_level_kind(const xmlNode *level); -typedef struct async_command_s { - +typedef struct { int id; - int pid; - int fd_stdout; uint32_t options; int default_timeout; /* seconds */ int timeout; /* seconds */ @@ -98,38 +97,79 @@ typedef struct async_command_s { char *remote_op_id; char *target; - uint32_t target_nodeid; char *action; char *device; + //! Head of device list (used only for freeing list with command object) GList *device_list; - GList *next_device_iter; // device_list entry for next device to execute + + //! Next item to process in \c device_list + GList *next_device_iter; void *internal_user_data; void (*done_cb) (int pid, const pcmk__action_result_t *result, void *user_data); - guint timer_sigterm; - guint timer_sigkill; - /*! If the operation timed out, this is the last signal - * we sent to the process to get it to terminate */ - int last_timeout_signo; - - stonith_device_t *active_on; - stonith_device_t *activating_on; + + fenced_device_t *active_on; + fenced_device_t *activating_on; } async_command_t; static xmlNode *construct_async_reply(const async_command_t *cmd, const pcmk__action_result_t *result); +/*! + * \internal + * \brief Check whether the fencer's device table contains a watchdog device + * + * \retval \c true If the device table contains a watchdog device + * \retval \c false Otherwise + */ +bool +fenced_has_watchdog_device(void) +{ + return (device_table != NULL) + && (g_hash_table_lookup(device_table, STONITH_WATCHDOG_ID) != NULL); +} + +/*! + * \internal + * \brief Call a function for each known fence device + * + * \param[in] fn Function to call for each device + * \param[in,out] user_data User data + */ +void +fenced_foreach_device(GHFunc fn, gpointer user_data) +{ + if (device_table != NULL) { + g_hash_table_foreach(device_table, fn, user_data); + } +} + +/*! + * \internal + * \brief Remove each known fence device matching a given predicate + * + * \param[in] fn Function that returns \c TRUE to remove a fence device or + * \c FALSE to keep it + */ +void +fenced_foreach_device_remove(GHRFunc fn) +{ + if (device_table != NULL) { + g_hash_table_foreach_remove(device_table, fn, NULL); + } +} + static gboolean -is_action_required(const char *action, const stonith_device_t *device) +is_action_required(const char *action, const fenced_device_t *device) { return (device != NULL) && device->automatic_unfencing && pcmk__str_eq(action, PCMK_ACTION_ON, pcmk__str_none); } static int -get_action_delay_max(const stonith_device_t *device, const char *action) +get_action_delay_max(const fenced_device_t *device, const char *action) { const char *value = NULL; guint delay_max = 0U; @@ -148,7 +188,7 @@ get_action_delay_max(const stonith_device_t *device, const char *action) } static int -get_action_delay_base(const stonith_device_t *device, const char *action, +get_action_delay_base(const fenced_device_t *device, const char *action, const char *target) { char *hash_value = NULL; @@ -214,7 +254,7 @@ get_action_delay_base(const stonith_device_t *device, const char *action, * the device is registered, whether by CIB change or API call. */ static int -get_action_timeout(const stonith_device_t *device, const char *action, +get_action_timeout(const fenced_device_t *device, const char *action, int default_timeout) { if (action && device && device->params) { @@ -250,13 +290,13 @@ get_action_timeout(const stonith_device_t *device, const char *action, * * \return Currently executing device for \p cmd if any, otherwise NULL */ -static stonith_device_t * +static fenced_device_t * cmd_device(const async_command_t *cmd) { - if ((cmd == NULL) || (cmd->device == NULL) || (device_list == NULL)) { + if ((cmd == NULL) || (cmd->device == NULL) || (device_table == NULL)) { return NULL; } - return g_hash_table_lookup(device_list, cmd->device); + return g_hash_table_lookup(device_table, cmd->device); } /*! @@ -272,8 +312,8 @@ fenced_device_reboot_action(const char *device_id) { const char *action = NULL; - if ((device_list != NULL) && (device_id != NULL)) { - stonith_device_t *device = g_hash_table_lookup(device_list, device_id); + if ((device_table != NULL) && (device_id != NULL)) { + fenced_device_t *device = g_hash_table_lookup(device_table, device_id); if ((device != NULL) && (device->params != NULL)) { action = g_hash_table_lookup(device->params, "pcmk_reboot_action"); @@ -293,8 +333,8 @@ fenced_device_reboot_action(const char *device_id) bool fenced_device_supports_on(const char *device_id) { - if ((device_list != NULL) && (device_id != NULL)) { - stonith_device_t *device = g_hash_table_lookup(device_list, device_id); + if ((device_table != NULL) && (device_id != NULL)) { + fenced_device_t *device = g_hash_table_lookup(device_table, device_id); if (device != NULL) { return pcmk_is_set(device->flags, st_device_supports_on); @@ -393,7 +433,7 @@ create_async_command(xmlNode *msg) } static int -get_action_limit(stonith_device_t * device) +get_action_limit(fenced_device_t *device) { const char *value = NULL; int action_limit = 1; @@ -408,7 +448,7 @@ get_action_limit(stonith_device_t * device) } static int -get_active_cmds(stonith_device_t * device) +get_active_cmds(fenced_device_t *device) { int counter = 0; GList *gIter = NULL; @@ -433,11 +473,14 @@ static void fork_cb(int pid, void *user_data) { async_command_t *cmd = (async_command_t *) user_data; - stonith_device_t * device = - /* in case of a retry we've done the move from - activating_on to active_on already + fenced_device_t *device = cmd->activating_on; + + if (device == NULL) { + /* In case of a retry, we've done the move from activating_on to + * active_on already */ - cmd->activating_on?cmd->activating_on:cmd->active_on; + device = cmd->active_on; + } pcmk__assert(device != NULL); crm_debug("Operation '%s' [%d]%s%s using %s now running with %ds timeout", @@ -450,7 +493,7 @@ fork_cb(int pid, void *user_data) static int get_agent_metadata_cb(gpointer data) { - stonith_device_t *device = data; + fenced_device_t *device = data; guint period_ms; switch (get_agent_metadata(device->agent, &device->agent_metadata)) { @@ -495,7 +538,7 @@ report_internal_result(async_command_t *cmd, int exit_status, } static gboolean -stonith_device_execute(stonith_device_t * device) +stonith_device_execute(fenced_device_t *device) { int exec_rc = 0; const char *action_str = NULL; @@ -596,8 +639,8 @@ stonith_device_execute(stonith_device_t * device) } action = stonith__action_create(device->agent, action_str, cmd->target, - cmd->target_nodeid, cmd->timeout, - device->params, device->aliases, host_arg); + cmd->timeout, device->params, + device->aliases, host_arg); /* for async exec, exec_rc is negative for early error exit otherwise handling of success/errors is done via callbacks */ @@ -630,7 +673,7 @@ static gboolean start_delay_helper(gpointer data) { async_command_t *cmd = data; - stonith_device_t *device = cmd_device(cmd); + fenced_device_t *device = cmd_device(cmd); cmd->delay_id = 0; if (device) { @@ -641,7 +684,7 @@ start_delay_helper(gpointer data) } static void -schedule_stonith_command(async_command_t * cmd, stonith_device_t * device) +schedule_stonith_command(async_command_t *cmd, fenced_device_t *device) { int delay_max = 0; int delay_base = 0; @@ -654,14 +697,6 @@ schedule_stonith_command(async_command_t * cmd, stonith_device_t * device) free(cmd->device); } - if (device->include_nodeid && (cmd->target != NULL)) { - pcmk__node_status_t *node = - pcmk__get_node(0, cmd->target, NULL, - pcmk__node_search_cluster_member); - - cmd->target_nodeid = node->cluster_layer_id; - } - cmd->device = pcmk__str_copy(device->id); cmd->timeout = get_action_timeout(device, cmd->action, cmd->default_timeout); @@ -724,7 +759,7 @@ static void free_device(gpointer data) { GList *gIter = NULL; - stonith_device_t *device = data; + fenced_device_t *device = data; g_hash_table_destroy(device->params); g_hash_table_destroy(device->aliases); @@ -757,19 +792,28 @@ free_device(gpointer data) free(device); } -void free_device_list(void) +/*! + * \internal + * \brief Initialize the table of known fence devices + */ +void +fenced_init_device_table(void) { - if (device_list != NULL) { - g_hash_table_destroy(device_list); - device_list = NULL; + if (device_table == NULL) { + device_table = pcmk__strkey_table(NULL, free_device); } } +/*! + * \internal + * \brief Free the table of known fence devices + */ void -init_device_list(void) +fenced_free_device_table(void) { - if (device_list == NULL) { - device_list = pcmk__strkey_table(NULL, free_device); + if (device_table != NULL) { + g_hash_table_destroy(device_table); + device_table = NULL; } } @@ -907,29 +951,8 @@ get_agent_metadata(const char *agent, xmlNode ** metadata) return pcmk_rc_ok; } -static gboolean -is_nodeid_required(xmlNode * xml) -{ - xmlXPathObject *xpath = NULL; - - if (!xml) { - return FALSE; - } - - xpath = pcmk__xpath_search(xml->doc, - "//" PCMK_XE_PARAMETER - "[@" PCMK_XA_NAME "='nodeid']"); - if (pcmk__xpath_num_results(xpath) == 0) { - xmlXPathFreeObject(xpath); - return FALSE; - } - - xmlXPathFreeObject(xpath); - return TRUE; -} - static void -read_action_metadata(stonith_device_t *device) +read_action_metadata(fenced_device_t *device) { xmlXPathObject *xpath = NULL; int max = 0; @@ -992,7 +1015,7 @@ read_action_metadata(stonith_device_t *device) } static const char * -target_list_type(stonith_device_t * dev) +target_list_type(fenced_device_t *dev) { const char *check_type = NULL; @@ -1016,16 +1039,16 @@ target_list_type(stonith_device_t * dev) return check_type; } -static stonith_device_t * -build_device_from_xml(xmlNode *dev) +static fenced_device_t * +build_device_from_xml(const xmlNode *dev) { const char *value; - stonith_device_t *device = NULL; + fenced_device_t *device = NULL; char *agent = crm_element_value_copy(dev, PCMK_XA_AGENT); CRM_CHECK(agent != NULL, return device); - device = pcmk__assert_alloc(1, sizeof(stonith_device_t)); + device = pcmk__assert_alloc(1, sizeof(fenced_device_t)); device->id = crm_element_value_copy(dev, PCMK_XA_ID); device->agent = agent; @@ -1071,11 +1094,6 @@ build_device_from_xml(xmlNode *dev) break; } - value = g_hash_table_lookup(device->params, "nodeid"); - if (!value) { - device->include_nodeid = is_nodeid_required(device->agent_metadata); - } - value = crm_element_value(dev, PCMK__XA_RSC_PROVIDES); if (pcmk__str_eq(value, PCMK_VALUE_UNFENCING, pcmk__str_casei)) { device->automatic_unfencing = TRUE; @@ -1092,17 +1110,13 @@ build_device_from_xml(xmlNode *dev) } device->work = mainloop_add_trigger(G_PRIORITY_HIGH, stonith_device_dispatch, device); - /* TODO: Hook up priority */ return device; } static void -schedule_internal_command(const char *origin, - stonith_device_t * device, - const char *action, - const char *target, - int timeout, +schedule_internal_command(const char *origin, fenced_device_t *device, + const char *action, const char *target, int timeout, void *internal_user_data, void (*done_cb) (int pid, const pcmk__action_result_t *result, @@ -1141,7 +1155,7 @@ status_search_cb(int pid, const pcmk__action_result_t *result, void *user_data) { async_command_t *cmd = user_data; struct device_search_s *search = cmd->internal_user_data; - stonith_device_t *dev = cmd_device(cmd); + fenced_device_t *dev = cmd_device(cmd); gboolean can = FALSE; free_async_command(cmd); @@ -1191,7 +1205,7 @@ dynamic_list_search_cb(int pid, const pcmk__action_result_t *result, { async_command_t *cmd = user_data; struct device_search_s *search = cmd->internal_user_data; - stonith_device_t *dev = cmd_device(cmd); + fenced_device_t *dev = cmd_device(cmd); gboolean can_fence = FALSE; free_async_command(cmd); @@ -1298,12 +1312,12 @@ device_params_diff(GHashTable *first, GHashTable *second) { /*! * \internal - * \brief Checks to see if an identical device already exists in the device_list + * \brief Checks to see if an identical device already exists in the table */ -static stonith_device_t * -device_has_duplicate(const stonith_device_t *device) +static fenced_device_t * +device_has_duplicate(const fenced_device_t *device) { - stonith_device_t *dup = g_hash_table_lookup(device_list, device->id); + fenced_device_t *dup = g_hash_table_lookup(device_table, device->id); if (!dup) { crm_trace("No match for %s", device->id); @@ -1325,97 +1339,98 @@ device_has_duplicate(const stonith_device_t *device) } int -stonith_device_register(xmlNode *dev, gboolean from_cib) +fenced_device_register(const xmlNode *dev, bool from_cib) { - stonith_device_t *dup = NULL; - stonith_device_t *device = build_device_from_xml(dev); - guint ndevices = 0; - int rv = pcmk_ok; + const char *local_node_name = fenced_get_local_node(); + fenced_device_t *dup = NULL; + fenced_device_t *device = build_device_from_xml(dev); + int rc = pcmk_rc_ok; - CRM_CHECK(device != NULL, return -ENOMEM); + CRM_CHECK(device != NULL, return ENOMEM); /* do we have a watchdog-device? */ - if (pcmk__str_eq(device->id, STONITH_WATCHDOG_ID, pcmk__str_none) || - pcmk__str_any_of(device->agent, STONITH_WATCHDOG_AGENT, - STONITH_WATCHDOG_AGENT_INTERNAL, NULL)) do { + if (pcmk__str_eq(device->id, STONITH_WATCHDOG_ID, pcmk__str_none) + || pcmk__str_any_of(device->agent, STONITH_WATCHDOG_AGENT, + STONITH_WATCHDOG_AGENT_INTERNAL, NULL)) { + if (stonith_watchdog_timeout_ms <= 0) { crm_err("Ignoring watchdog fence device without " - PCMK_OPT_STONITH_WATCHDOG_TIMEOUT " set."); - rv = -ENODEV; - /* fall through to cleanup & return */ - } else if (!pcmk__str_any_of(device->agent, STONITH_WATCHDOG_AGENT, - STONITH_WATCHDOG_AGENT_INTERNAL, NULL)) { - crm_err("Ignoring watchdog fence device with unknown " - "agent '%s' unequal '" STONITH_WATCHDOG_AGENT "'.", - device->agent?device->agent:""); - rv = -ENODEV; - /* fall through to cleanup & return */ - } else if (!pcmk__str_eq(device->id, STONITH_WATCHDOG_ID, - pcmk__str_none)) { - crm_err("Ignoring watchdog fence device " - "named %s !='"STONITH_WATCHDOG_ID"'.", - device->id?device->id:""); - rv = -ENODEV; - /* fall through to cleanup & return */ - } else { - const char *local_node_name = fenced_get_local_node(); + PCMK_OPT_STONITH_WATCHDOG_TIMEOUT " set"); + rc = ENODEV; + goto done; + } + if (!pcmk__str_any_of(device->agent, STONITH_WATCHDOG_AGENT, + STONITH_WATCHDOG_AGENT_INTERNAL, NULL)) { + crm_err("Ignoring watchdog fence device with unknown agent '%s' " + "rather than '" STONITH_WATCHDOG_AGENT "'", + pcmk__s(device->agent, "")); + rc = ENODEV; + goto done; + } + if (!pcmk__str_eq(device->id, STONITH_WATCHDOG_ID, pcmk__str_none)) { + crm_err("Ignoring watchdog fence device named '%s' rather than " + "'" STONITH_WATCHDOG_ID "'", + pcmk__s(device->id, "")); + rc = ENODEV; + goto done; + } - if (pcmk__str_eq(device->agent, STONITH_WATCHDOG_AGENT, - pcmk__str_none)) { - /* this either has an empty list or the targets - configured for watchdog-fencing - */ - g_list_free_full(stonith_watchdog_targets, free); - stonith_watchdog_targets = device->targets; - device->targets = NULL; - } - if (node_does_watchdog_fencing(local_node_name)) { - g_list_free_full(device->targets, free); - device->targets = stonith__parse_targets(local_node_name); - pcmk__insert_dup(device->params, - PCMK_STONITH_HOST_LIST, local_node_name); - /* proceed as with any other stonith-device */ - break; - } + if (pcmk__str_eq(device->agent, STONITH_WATCHDOG_AGENT, + pcmk__str_none)) { + /* This has either an empty list or the targets configured for + * watchdog fencing + */ + g_list_free_full(stonith_watchdog_targets, free); + stonith_watchdog_targets = device->targets; + device->targets = NULL; + } - crm_debug("Skip registration of watchdog fence device on node not in host-list."); - /* cleanup and fall through to more cleanup and return */ + if (!node_does_watchdog_fencing(local_node_name)) { + crm_debug("Skip registration of watchdog fence device on node not " + "in host list"); device->targets = NULL; stonith_device_remove(device->id, from_cib); + goto done; } - free_device(device); - return rv; - } while (0); + + // Proceed as with any other fencing device + g_list_free_full(device->targets, free); + device->targets = stonith__parse_targets(local_node_name); + pcmk__insert_dup(device->params, PCMK_STONITH_HOST_LIST, + local_node_name); + } dup = device_has_duplicate(device); - if (dup) { - ndevices = g_hash_table_size(device_list); + if (dup != NULL) { + guint ndevices = g_hash_table_size(device_table); + crm_debug("Device '%s' already in device list (%d active device%s)", device->id, ndevices, pcmk__plural_s(ndevices)); free_device(device); device = dup; - dup = g_hash_table_lookup(device_list, device->id); - dup->dirty = FALSE; + device->dirty = FALSE; } else { - stonith_device_t *old = g_hash_table_lookup(device_list, device->id); - - if (from_cib && old && old->api_registered) { - /* If the cib is writing over an entry that is shared with a stonith client, - * copy any pending ops that currently exist on the old entry to the new one. - * Otherwise the pending ops will be reported as failures + guint ndevices = 0; + fenced_device_t *old = g_hash_table_lookup(device_table, device->id); + + if (from_cib && (old != NULL) && old->api_registered) { + /* If the CIB is writing over an entry that is shared with a stonith + * client, copy any pending ops that currently exist on the old + * entry to the new one. Otherwise the pending ops will be reported + * as failures. */ crm_info("Overwriting existing entry for %s from CIB", device->id); device->pending_ops = old->pending_ops; device->api_registered = TRUE; old->pending_ops = NULL; - if (device->pending_ops) { + if (device->pending_ops != NULL) { mainloop_set_trigger(device->work); } } - g_hash_table_replace(device_list, device->id, device); + g_hash_table_replace(device_table, device->id, device); - ndevices = g_hash_table_size(device_list); + ndevices = g_hash_table_size(device_table); crm_notice("Added '%s' to device list (%d active device%s)", device->id, ndevices, pcmk__plural_s(ndevices)); } @@ -1426,19 +1441,23 @@ stonith_device_register(xmlNode *dev, gboolean from_cib) device->api_registered = TRUE; } - return pcmk_ok; +done: + if (rc != pcmk_rc_ok) { + free_device(device); + } + return rc; } void stonith_device_remove(const char *id, bool from_cib) { - stonith_device_t *device = g_hash_table_lookup(device_list, id); + fenced_device_t *device = g_hash_table_lookup(device_table, id); guint ndevices = 0; - if (!device) { - ndevices = g_hash_table_size(device_list); - crm_info("Device '%s' not found (%d active device%s)", - id, ndevices, pcmk__plural_s(ndevices)); + if (device == NULL) { + ndevices = g_hash_table_size(device_table); + crm_info("Device '%s' not found (%u active device%s)", id, ndevices, + pcmk__plural_s(ndevices)); return; } @@ -1450,16 +1469,16 @@ stonith_device_remove(const char *id, bool from_cib) } if (!device->cib_registered && !device->api_registered) { - g_hash_table_remove(device_list, id); - ndevices = g_hash_table_size(device_list); - crm_info("Removed '%s' from device list (%d active device%s)", + g_hash_table_remove(device_table, id); + ndevices = g_hash_table_size(device_table); + crm_info("Removed '%s' from device list (%u active device%s)", id, ndevices, pcmk__plural_s(ndevices)); } else { - crm_trace("Not removing '%s' from device list (%d active) because " - "still registered via:%s%s", - id, g_hash_table_size(device_list), - (device->cib_registered? " cib" : ""), - (device->api_registered? " api" : "")); + // Exactly one is true at this point + crm_trace("Not removing '%s' from device list (%u active) because " + "still registered via %s", + id, g_hash_table_size(device_table), + (device->cib_registered? "CIB" : "API")); } } @@ -1905,7 +1924,7 @@ execute_agent_action(xmlNode *msg, pcmk__action_result_t *result) 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; + fenced_device_t *device = NULL; if ((id == NULL) || (action == NULL)) { crm_info("Malformed API action request: device %s, action %s", @@ -1936,7 +1955,7 @@ execute_agent_action(xmlNode *msg, pcmk__action_result_t *result) } } - device = g_hash_table_lookup(device_list, id); + device = g_hash_table_lookup(device_table, id); if (device == NULL) { crm_info("Ignoring API '%s' action request because device %s not found", action, id); @@ -1971,7 +1990,7 @@ search_devices_record_result(struct device_search_s *search, const char *device, search->replies_received++; if (can_fence && device) { if (search->support_action_only != st_device_supports_none) { - stonith_device_t *dev = g_hash_table_lookup(device_list, device); + fenced_device_t *dev = g_hash_table_lookup(device_table, device); if (dev && !pcmk_is_set(dev->flags, search->support_action_only)) { return; } @@ -2008,7 +2027,7 @@ search_devices_record_result(struct device_search_s *search, const char *device, * \return TRUE if local host is allowed to execute action, FALSE otherwise */ static gboolean -localhost_is_eligible(const stonith_device_t *device, const char *action, +localhost_is_eligible(const fenced_device_t *device, const char *action, const char *target, gboolean allow_self) { gboolean localhost_is_target = pcmk__str_eq(target, fenced_get_local_node(), @@ -2045,7 +2064,7 @@ localhost_is_eligible(const stonith_device_t *device, const char *action, * might be remapped to, otherwise false */ static bool -localhost_is_eligible_with_remap(const stonith_device_t *device, +localhost_is_eligible_with_remap(const fenced_device_t *device, const char *action, const char *target, gboolean allow_self) { @@ -2081,13 +2100,13 @@ localhost_is_eligible_with_remap(const stonith_device_t *device, * otherwise \c false */ static inline bool -can_use_target_cache(const stonith_device_t *dev) +can_use_target_cache(const fenced_device_t *dev) { return (dev->targets != NULL) && (time(NULL) < (dev->targets_age + 60)); } static void -can_fence_host_with_device(stonith_device_t *dev, +can_fence_host_with_device(fenced_device_t *dev, struct device_search_s *search) { gboolean can = FALSE; @@ -2201,7 +2220,7 @@ can_fence_host_with_device(stonith_device_t *dev, static void search_devices(gpointer key, gpointer value, gpointer user_data) { - stonith_device_t *dev = value; + fenced_device_t *dev = value; struct device_search_s *search = user_data; can_fence_host_with_device(dev, search); @@ -2215,7 +2234,7 @@ get_capable_devices(const char *host, const char *action, int timeout, uint32_t support_action_only) { struct device_search_s *search; - guint ndevices = g_hash_table_size(device_list); + guint ndevices = g_hash_table_size(device_table); if (ndevices == 0) { callback(NULL, user_data); @@ -2241,7 +2260,7 @@ get_capable_devices(const char *host, const char *action, int timeout, ndevices, pcmk__plural_s(ndevices), (search->action? search->action : "unknown action"), (search->host? search->host : "any node")); - g_hash_table_foreach(device_list, search_devices, search); + fenced_foreach_device(search_devices, search); } struct st_query_data { @@ -2264,7 +2283,7 @@ struct st_query_data { */ static void add_action_specific_attributes(xmlNode *xml, const char *action, - const stonith_device_t *device, + const fenced_device_t *device, const char *target) { int action_specific_timeout; @@ -2324,7 +2343,7 @@ add_action_specific_attributes(xmlNode *xml, const char *action, * \param[in] allow_self Whether self-fencing is allowed */ static void -add_disallowed(xmlNode *xml, const char *action, const stonith_device_t *device, +add_disallowed(xmlNode *xml, const char *action, const fenced_device_t *device, const char *target, gboolean allow_self) { if (!localhost_is_eligible(device, action, target, allow_self)) { @@ -2346,7 +2365,7 @@ add_disallowed(xmlNode *xml, const char *action, const stonith_device_t *device, */ static void add_action_reply(xmlNode *xml, const char *action, - const stonith_device_t *device, const char *target, + const fenced_device_t *device, const char *target, gboolean allow_self) { xmlNode *child = pcmk__xe_create(xml, PCMK__XE_ST_DEVICE_ACTION); @@ -2408,7 +2427,7 @@ stonith_query_capable_device_cb(GList * devices, void *user_data) 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); + fenced_device_t *device = g_hash_table_lookup(device_table, lpc->data); const char *action = query->action; xmlNode *dev = NULL; @@ -2640,7 +2659,7 @@ send_async_reply(const async_command_t *cmd, const pcmk__action_result_t *result static void cancel_stonith_command(async_command_t * cmd) { - stonith_device_t *device = cmd_device(cmd); + fenced_device_t *device = cmd_device(cmd); if (device) { crm_trace("Cancel scheduled '%s' action using %s", @@ -2722,12 +2741,12 @@ reply_to_duplicates(async_command_t *cmd, const pcmk__action_result_t *result, * * \return Next device required for action if any, otherwise NULL */ -static stonith_device_t * +static fenced_device_t * next_required_device(async_command_t *cmd) { for (GList *iter = cmd->next_device_iter; iter != NULL; iter = iter->next) { - stonith_device_t *next_device = g_hash_table_lookup(device_list, - iter->data); + fenced_device_t *next_device = g_hash_table_lookup(device_table, + iter->data); if (is_action_required(cmd->action, next_device)) { /* This is only called for successful actions, so it's OK to skip @@ -2745,8 +2764,8 @@ st_child_done(int pid, const pcmk__action_result_t *result, void *user_data) { async_command_t *cmd = user_data; - stonith_device_t *device = NULL; - stonith_device_t *next_device = NULL; + fenced_device_t *device = NULL; + fenced_device_t *next_device = NULL; CRM_CHECK(cmd != NULL, return); @@ -2773,7 +2792,7 @@ st_child_done(int pid, const pcmk__action_result_t *result, void *user_data) && !is_action_required(cmd->action, device)) { /* if this device didn't work out, see if there are any others we can try. * if the failed device was 'required', we can't pick another device. */ - next_device = g_hash_table_lookup(device_list, + next_device = g_hash_table_lookup(device_table, cmd->next_device_iter->data); cmd->next_device_iter = cmd->next_device_iter->next; } @@ -2791,34 +2810,18 @@ st_child_done(int pid, const pcmk__action_result_t *result, void *user_data) } } -static gint -sort_device_priority(gconstpointer a, gconstpointer b) -{ - const stonith_device_t *dev_a = a; - const stonith_device_t *dev_b = b; - - if (dev_a->priority > dev_b->priority) { - return -1; - } else if (dev_a->priority < dev_b->priority) { - return 1; - } - return 0; -} - static void stonith_fence_get_devices_cb(GList * devices, void *user_data) { async_command_t *cmd = user_data; - stonith_device_t *device = NULL; + fenced_device_t *device = NULL; guint ndevices = g_list_length(devices); crm_info("Found %d matching device%s for target '%s'", ndevices, pcmk__plural_s(ndevices), cmd->target); if (devices != NULL) { - /* Order based on priority */ - devices = g_list_sort(devices, sort_device_priority); - device = g_hash_table_lookup(device_list, devices->data); + device = g_hash_table_lookup(device_table, devices->data); } if (device == NULL) { // No device found @@ -2832,7 +2835,11 @@ stonith_fence_get_devices_cb(GList * devices, void *user_data) free_async_command(cmd); g_list_free_full(devices, free); - } else { // Device found, schedule it for fencing + } else { + /* Device found. Schedule a fencing command for it. + * + * Assign devices to device_list so that it will be freed with cmd. + */ cmd->device_list = devices; cmd->next_device_iter = devices->next; schedule_stonith_command(cmd, device); @@ -2850,7 +2857,7 @@ static void fence_locally(xmlNode *msg, pcmk__action_result_t *result) { const char *device_id = NULL; - stonith_device_t *device = NULL; + fenced_device_t *device = NULL; async_command_t *cmd = NULL; xmlNode *dev = NULL; @@ -2868,7 +2875,7 @@ fence_locally(xmlNode *msg, pcmk__action_result_t *result) device_id = crm_element_value(dev, PCMK__XA_ST_DEVICE_ID); if (device_id != NULL) { - device = g_hash_table_lookup(device_list, device_id); + device = g_hash_table_lookup(device_table, device_id); if (device == NULL) { crm_err("Requested device '%s' is not available", device_id); pcmk__format_result(result, CRM_EX_ERROR, PCMK_EXEC_NO_FENCE_DEVICE, @@ -3403,8 +3410,9 @@ handle_device_add_request(pcmk__request_t *request) "//" PCMK__XE_ST_DEVICE_ID, LOG_ERR); if (is_privileged(request->ipc_client, op)) { - int rc = stonith_device_register(dev, FALSE); + int rc = fenced_device_register(dev, false); + rc = pcmk_rc2legacy(rc); pcmk__set_result(&request->result, ((rc == pcmk_ok)? CRM_EX_OK : CRM_EX_ERROR), stonith__legacy2status(rc), diff --git a/daemons/fenced/fenced_scheduler.c b/daemons/fenced/fenced_scheduler.c index 46d74320fcc..a67fef5c3ab 100644 --- a/daemons/fenced/fenced_scheduler.c +++ b/daemons/fenced/fenced_scheduler.c @@ -226,7 +226,7 @@ register_if_fencing_device(gpointer data, gpointer user_data) xml = create_device_registration_xml(rsc_id, st_namespace_any, agent, params, rsc_provides); stonith_key_value_freeall(params, 1, 1); - pcmk__assert(stonith_device_register(xml, TRUE) == pcmk_ok); + pcmk__assert(fenced_device_register(xml, true) == pcmk_rc_ok); pcmk__xml_free(xml); } diff --git a/daemons/fenced/pacemaker-fenced.c b/daemons/fenced/pacemaker-fenced.c index 32a3f2bf562..cb862b22845 100644 --- a/daemons/fenced/pacemaker-fenced.c +++ b/daemons/fenced/pacemaker-fenced.c @@ -1,5 +1,5 @@ /* - * Copyright 2009-2024 the Pacemaker project contributors + * Copyright 2009-2025 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -437,7 +437,7 @@ stonith_cleanup(void) pcmk__client_cleanup(); free_stonith_remote_op_list(); free_topology_list(); - free_device_list(); + fenced_free_device_table(); free_metadata_cache(); fenced_unregister_handlers(); } @@ -634,7 +634,7 @@ main(int argc, char **argv) setup_cib(); } - init_device_list(); + fenced_init_device_table(); init_topology_list(); pcmk__serve_fenced_ipc(&ipcs, &ipc_callbacks); diff --git a/daemons/fenced/pacemaker-fenced.h b/daemons/fenced/pacemaker-fenced.h index 04aadedc39e..c1590438cc1 100644 --- a/daemons/fenced/pacemaker-fenced.h +++ b/daemons/fenced/pacemaker-fenced.h @@ -1,5 +1,5 @@ /* - * Copyright 2009-2024 the Pacemaker project contributors + * Copyright 2009-2025 the Pacemaker project contributors * * This source code is licensed under the GNU General Public License version 2 * or later (GPLv2+) WITHOUT ANY WARRANTY. @@ -26,7 +26,7 @@ */ gboolean stonith_check_fence_tolerance(int tolerance, const char *target, const char *action); -typedef struct stonith_device_s { +typedef struct { char *id; char *agent; char *namespace; @@ -35,14 +35,9 @@ typedef struct stonith_device_s { GString *on_target_actions; GList *targets; time_t targets_age; - gboolean has_attr_map; - - // Whether target's nodeid should be passed as a parameter to the agent - gboolean include_nodeid; /* whether the cluster should automatically unfence nodes with the device */ gboolean automatic_unfencing; - guint priority; uint32_t flags; // Group of enum st_device_flags @@ -60,7 +55,7 @@ typedef struct stonith_device_s { gboolean cib_registered; gboolean api_registered; gboolean dirty; -} stonith_device_t; +} fenced_device_t; /* These values are used to index certain arrays by "phase". Usually an * operation has only one "phase", so phase is always zero. However, some @@ -220,8 +215,12 @@ typedef struct stonith_topology_s { void stonith_shutdown(int nsig); -void init_device_list(void); -void free_device_list(void); +void fenced_init_device_table(void); +void fenced_free_device_table(void); +bool fenced_has_watchdog_device(void); +void fenced_foreach_device(GHFunc fn, gpointer user_data); +void fenced_foreach_device_remove(GHRFunc fn); + void init_topology_list(void); void free_topology_list(void); void free_stonith_remote_op_list(void); @@ -234,7 +233,7 @@ uint64_t get_stonith_flag(const char *name); void stonith_command(pcmk__client_t *client, uint32_t id, uint32_t flags, xmlNode *op_request, const char *remote_peer); -int stonith_device_register(xmlNode *msg, gboolean from_cib); +int fenced_device_register(const xmlNode *dev, bool from_cib); void stonith_device_remove(const char *id, bool from_cib); @@ -326,7 +325,6 @@ fenced_support_flag(const char *action) return st_device_supports_none; } -extern GHashTable *device_list; extern GHashTable *topology; extern long long stonith_watchdog_timeout_ms; extern GList *stonith_watchdog_targets; diff --git a/doc/sphinx/Pacemaker_Explained/fencing.rst b/doc/sphinx/Pacemaker_Explained/fencing.rst index 915f69fd0b9..dce479e3c61 100644 --- a/doc/sphinx/Pacemaker_Explained/fencing.rst +++ b/doc/sphinx/Pacemaker_Explained/fencing.rst @@ -179,17 +179,6 @@ fencing resource (*not* meta-attributes, even though they are interpreted by Pacemaker rather than the fence agent). These are also listed in the man page for ``pacemaker-fenced``. -.. Not_Yet_Implemented: - - +----------------------+---------+--------------------+----------------------------------------+ - | priority | integer | 0 | .. index:: | - | | | | single: priority | - | | | | | - | | | | The priority of the fence device. | - | | | | Devices are tried in order of highest | - | | | | priority to lowest. | - +----------------------+---------+--------------------+----------------------------------------+ - .. list-table:: **Additional Properties of Fencing Resources** :class: longtable :widths: 2 1 2 4 diff --git a/include/crm/fencing/internal.h b/include/crm/fencing/internal.h index d46dab7ab9a..46159936457 100644 --- a/include/crm/fencing/internal.h +++ b/include/crm/fencing/internal.h @@ -1,5 +1,5 @@ /* - * Copyright 2011-2024 the Pacemaker project contributors + * Copyright 2011-2025 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -58,7 +58,6 @@ typedef struct stonith_action_s stonith_action_t; stonith_action_t *stonith__action_create(const char *agent, const char *action_name, const char *target, - uint32_t target_nodeid, int timeout_sec, GHashTable *device_args, GHashTable *port_map, diff --git a/lib/fencing/st_actions.c b/lib/fencing/st_actions.c index d085ff8ab30..5da7acf026d 100644 --- a/lib/fencing/st_actions.c +++ b/lib/fencing/st_actions.c @@ -113,7 +113,6 @@ append_config_arg(gpointer key, gpointer value, gpointer user_data) * \param[in] agent Fencing agent name * \param[in] action Name of fencing action * \param[in] target Name of target node for fencing action - * \param[in] target_nodeid Node ID of target node for fencing action * \param[in] device_args Fence device parameters * \param[in] port_map Target node-to-port mapping for fence device * \param[in] host_arg Argument name for passing target @@ -122,8 +121,7 @@ append_config_arg(gpointer key, gpointer value, gpointer user_data) */ static GHashTable * make_args(const char *agent, const char *action, const char *target, - uint32_t target_nodeid, GHashTable *device_args, - GHashTable *port_map, const char *host_arg) + GHashTable *device_args, GHashTable *port_map, const char *host_arg) { GHashTable *arg_list = NULL; const char *value = NULL; @@ -159,16 +157,6 @@ make_args(const char *agent, const char *action, const char *target, */ pcmk__insert_dup(arg_list, "nodename", target); - // If the target's node ID was specified, pass it, too - if (target_nodeid != 0) { - char *nodeid = crm_strdup_printf("%" PRIu32, target_nodeid); - - // cts-fencing looks for this log message - crm_info("Passing '%s' as nodeid with fence action '%s' targeting %s", - nodeid, action, pcmk__s(target, "no node")); - g_hash_table_insert(arg_list, strdup("nodeid"), nodeid); - } - // Check whether target should be specified as some other argument param = g_hash_table_lookup(device_args, PCMK_STONITH_HOST_ARGUMENT); if (param == NULL) { @@ -253,7 +241,6 @@ stonith__action_result(stonith_action_t *action) * \param[in] agent Fence agent to use * \param[in] action_name Fencing action to be executed * \param[in] target Name of target of fencing action (if known) - * \param[in] target_nodeid Node ID of target of fencing action (if known) * \param[in] timeout_sec Timeout to be used when executing action * \param[in] device_args Parameters to pass to fence agent * \param[in] port_map Mapping of target names to device ports @@ -263,14 +250,14 @@ stonith__action_result(stonith_action_t *action) */ stonith_action_t * stonith__action_create(const char *agent, const char *action_name, - const char *target, uint32_t target_nodeid, - int timeout_sec, GHashTable *device_args, - GHashTable *port_map, const char *host_arg) + const char *target, int timeout_sec, + GHashTable *device_args, GHashTable *port_map, + const char *host_arg) { stonith_action_t *action = pcmk__assert_alloc(1, sizeof(stonith_action_t)); - action->args = make_args(agent, action_name, target, target_nodeid, - device_args, port_map, host_arg); + action->args = make_args(agent, action_name, target, device_args, port_map, + host_arg); crm_debug("Preparing '%s' action targeting %s using agent %s", action_name, pcmk__s(target, "no node"), agent); action->agent = strdup(agent); diff --git a/lib/fencing/st_client.c b/lib/fencing/st_client.c index a2c541c366b..52d348d27d2 100644 --- a/lib/fencing/st_client.c +++ b/lib/fencing/st_client.c @@ -2504,8 +2504,8 @@ stonith__metadata_async(const char *agent, int timeout_sec, int rc = pcmk_ok; action = stonith__action_create(agent, PCMK_ACTION_METADATA, - NULL, 0, timeout_sec, NULL, - NULL, NULL); + NULL, timeout_sec, NULL, NULL, + NULL); rc = stonith__execute_async(action, user_data, callback, NULL); if (rc != pcmk_ok) { diff --git a/lib/fencing/st_rhcs.c b/lib/fencing/st_rhcs.c index 6d0c6f94476..d091ea1153a 100644 --- a/lib/fencing/st_rhcs.c +++ b/lib/fencing/st_rhcs.c @@ -129,8 +129,8 @@ stonith__rhcs_get_metadata(const char *agent, int timeout_sec, xmlXPathObject *xpathObj = NULL; stonith_action_t *action = stonith__action_create(agent, PCMK_ACTION_METADATA, - NULL, 0, timeout_sec, - NULL, NULL, NULL); + NULL, timeout_sec, NULL, + NULL, NULL); int rc = stonith__execute(action); pcmk__action_result_t *result = stonith__action_result(action); @@ -306,7 +306,7 @@ stonith__rhcs_validate(stonith_t *st, int call_options, const char *target, host_arg = NULL; } - action = stonith__action_create(agent, PCMK_ACTION_VALIDATE_ALL, target, 0, + action = stonith__action_create(agent, PCMK_ACTION_VALIDATE_ALL, target, remaining_timeout, params, NULL, host_arg); rc = stonith__execute(action);