18 #include <sys/types.h> 29 struct stonith_action_s {
39 void (*fork_cb) (
int pid,
void *user_data);
44 time_t initial_start_time;
46 int remaining_timeout;
79 if (
action->result.action_stderr != NULL) {
89 append_config_arg(gpointer key, gpointer value, gpointer user_data)
101 crm_trace(
"Passing %s=%s with fence action",
102 (
const char *) key, (
const char *) (value? value :
""));
122 make_args(
const char *agent,
const char *
action,
const char *
target,
123 uint32_t target_nodeid, GHashTable *device_args,
124 GHashTable *port_map,
const char *host_arg)
126 GHashTable *arg_list = NULL;
127 const char *value = NULL;
137 snprintf(buffer,
sizeof(buffer),
"pcmk_%s_action",
action);
138 value = g_hash_table_lookup(device_args, buffer);
140 crm_debug(
"Substituting '%s' for fence action %s targeting %s",
150 if ((
target != NULL) && (device_args != NULL)) {
151 const char *param = NULL;
159 if (target_nodeid != 0) {
163 crm_info(
"Passing '%s' as nodeid with fence action '%s' targeting %s",
165 g_hash_table_insert(arg_list, strdup(
"nodeid"), nodeid);
177 param = (host_arg == NULL)?
"port" : host_arg;
179 value = g_hash_table_lookup(device_args, param);
181 if (pcmk__str_eq(value,
"dynamic",
186 const char *alias = NULL;
189 alias = g_hash_table_lookup(port_map,
target);
194 crm_debug(
"Passing %s='%s' with fence action %s targeting %s",
202 g_hash_table_foreach(device_args, append_config_arg, arg_list);
220 g_hash_table_destroy(
action->args);
245 #define FAILURE_MAX_RETRIES 2 264 const char *
target, uint32_t target_nodeid,
265 int timeout_sec, GHashTable *device_args,
266 GHashTable *port_map,
const char *host_arg)
270 action->args = make_args(agent, action_name,
target, target_nodeid,
271 device_args, port_map, host_arg);
272 crm_debug(
"Preparing '%s' action targeting %s using agent %s",
273 action_name, pcmk__s(
target,
"no node"), agent);
274 action->agent = strdup(agent);
275 action->action = strdup(action_name);
276 action->timeout =
action->remaining_timeout = timeout_sec;
280 "Initialization bug in fencing library");
284 const char *value = NULL;
286 snprintf(buffer,
sizeof(buffer),
"pcmk_%s_retries", action_name);
287 value = g_hash_table_lookup(device_args, buffer);
290 action->max_retries = atoi(value);
300 int diff = time(NULL) -
action->initial_start_time;
303 crm_info(
"Attempted to execute agent %s (%s) the maximum number of times (%d) allowed",
305 action->remaining_timeout = 0;
307 && (diff < (
action->timeout * 0.7))) {
312 action->remaining_timeout = 0;
314 return action->remaining_timeout ? TRUE : FALSE;
328 if (pcmk__result_ok(
result)) {
434 const char *exit_reason = NULL;
435 const char *action_stdout = NULL;
494 const char *exit_reason = NULL;
495 char *action_stdout = NULL;
505 &execution_status) < 0)) {
513 if ((rc ==
pcmk_ok) || (rc == -EINPROGRESS)) {
521 exit_reason =
"Fencer reply contained neither a full result " 522 "nor a legacy return code (bug?)";
534 set_result_from_svc_action(
action, svc_action);
535 svc_action->
params = NULL;
538 if (!pcmk__result_ok(&(
action->result))
539 && update_remaining_timeout(
action)) {
541 int rc = internal_stonith_action_execute(
action);
551 action->svc_action = NULL;
561 action->svc_action = svc_action;
570 crm_trace(
"Child process %d performing action '%s' successfully forked",
580 static int stonith_sequence = 0;
586 || (
action->agent == NULL)) {
593 action->initial_start_time = time(NULL);
598 crm_info(
"Attempt %d to execute %s (%s). remaining timeout is %d",
609 set_result_from_svc_action(
action, svc_action);
620 svc_action->
sequence = stonith_sequence++;
623 svc_action->
flags = pcmk__set_flags_as(__func__, __LINE__,
625 svc_action->
id, svc_action->
flags,
627 "SVC_ACTION_NON_BLOCKED");
638 &stonith_action_async_done,
639 &stonith_action_async_forked));
649 set_result_from_svc_action(
action, svc_action);
650 svc_action->
params = NULL;
668 void (*done) (
int pid,
671 void (*fork_cb) (
int pid,
void *user_data))
677 action->userdata = userdata;
679 action->fork_cb = fork_cb;
682 return internal_stonith_action_execute(
action);
702 rc = internal_stonith_action_execute(
action);
703 }
while ((rc !=
pcmk_ok) && update_remaining_timeout(
action));
int rc
Exit status of action (set by library upon completion)
#define CRM_CHECK(expr, failure_action)
struct stonith_action_s stonith_action_t
const char * pcmk_strerror(int rc)
No connection to executor.
void services_action_free(svc_action_t *op)
#define PCMK__FENCE_BINDIR
int pcmk_rc2legacy(int rc)
char * standard
Resource standard for resource actions, otherwise NULL.
void stonith__xe_get_result(const xmlNode *xml, pcmk__action_result_t *result)
#define PCMK__XA_ST_OUTPUT
#define crm_log_output(level, prefix, output)
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
void void pcmk__set_result_output(pcmk__action_result_t *result, char *out, char *err)
bool pcmk_stonith_param(const char *param)
Check whether a given stonith parameter is handled by Pacemaker.
#define PCMK_XA_EXIT_REASON
enum pcmk_exec_status execution_status
svc_action_t * services_action_create_generic(const char *exec, const char *args[])
Request execution of an arbitrary command.
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
int stonith__legacy2status(int rc)
gboolean services_action_async_fork_notify(svc_action_t *op, void(*action_callback)(svc_action_t *), void(*action_fork_callback)(svc_action_t *))
Run an action asynchronously, with callback after process is forked.
Necessary CIB secrets are unavailable.
#define CRM_LOG_ASSERT(expr)
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)
int timeout
Action timeout (in milliseconds)
Action did not complete in time.
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute.
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
No fence device is configured for target.
#define FAILURE_MAX_RETRIES
enum svc_action_flags flags
Flag group of enum svc_action_flags.
char * services__grab_stderr(svc_action_t *action)
#define crm_debug(fmt, args...)
const char * services__exit_reason(const svc_action_t *action)
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
Used only to initialize variables.
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
gboolean services_action_sync(svc_action_t *op)
#define crm_trace(fmt, args...)
#define PCMK_RESOURCE_CLASS_STONITH
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
Object for executing external actions.
char * services__grab_stdout(svc_action_t *action)
char * agent
Resource agent name for resource actions, otherwise NULL.
Wrappers for and extensions to libxml2.
Action completed, result is known.
Execution failed, do not retry anywhere.
#define STONITH_ATTR_ACTION_OP
int stonith__execute_async(stonith_action_t *action, void *userdata, void(*done)(int pid, const pcmk__action_result_t *result, void *user_data), void(*fork_cb)(int pid, void *user_data))
Requested item has expired.
#define PCMK_XA_CRM_FEATURE_SET
#define PCMK_STONITH_HOST_ARGUMENT
Agent does not implement requested action.
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
pcmk__action_result_t result
pcmk__action_result_t * stonith__action_result(stonith_action_t *action)
int stonith__result2rc(const pcmk__action_result_t *result)
int status
Execution status (enum pcmk_exec_status set by library)
#define PCMK__XA_OP_STATUS
Agent or dependency not available locally.
int stonith__execute(stonith_action_t *action)
xmlNode * stonith__find_xe_with_result(xmlNode *xml)
void * cb_data
For caller's use (not used by library)
void pcmk__set_result(pcmk__action_result_t *result, int exit_status, enum pcmk_exec_status exec_status, const char *exit_reason)
pcmk_exec_status
Execution status.
Parameter invalid (in local context)
Action cannot be attempted (e.g. shutdown)
#define pcmk__assert_alloc(nmemb, size)
void pcmk__reset_result(pcmk__action_result_t *result)
void stonith__destroy_action(stonith_action_t *action)
Execution failed, may be retried.
#define crm_info(fmt, args...)
void pcmk__insert_dup(GHashTable *table, const char *name, const char *value)
void stonith__xe_set_result(xmlNode *xml, const pcmk__action_result_t *result)