17 #include <sys/types.h> 28 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 :
""));
103 g_hash_table_insert((GHashTable *) user_data,
104 strdup(key), strdup(value? value :
""));
109 make_args(
const char *agent,
const char *
action,
const char *victim,
110 uint32_t victim_nodeid, GHashTable * device_args,
111 GHashTable * port_map,
const char *host_arg)
113 GHashTable *arg_list = NULL;
114 const char *value = NULL;
124 snprintf(buffer,
sizeof(buffer),
"pcmk_%s_action",
action);
125 value = g_hash_table_lookup(device_args, buffer);
127 crm_debug(
"Substituting '%s' for fence action %s targeting %s",
138 if (victim && device_args) {
139 const char *param = NULL;
144 g_hash_table_insert(arg_list, strdup(
"nodename"), strdup(victim));
151 crm_info(
"Passing '%s' as nodeid with fence action '%s' targeting %s",
153 g_hash_table_insert(arg_list, strdup(
"nodeid"), nodeid);
165 param = (host_arg == NULL)?
"port" : host_arg;
167 value = g_hash_table_lookup(device_args, param);
169 if (pcmk__str_eq(value,
"dynamic",
174 const char *alias = NULL;
177 alias = g_hash_table_lookup(port_map, victim);
182 crm_debug(
"Passing %s='%s' with fence action %s targeting %s",
183 param, alias,
action, victim);
184 g_hash_table_insert(arg_list, strdup(param), strdup(alias));
190 g_hash_table_foreach(device_args, append_config_arg, arg_list);
208 g_hash_table_destroy(
action->args);
234 #define FAILURE_MAX_RETRIES 2 239 uint32_t victim_nodeid,
240 int timeout, GHashTable * device_args,
241 GHashTable * port_map,
const char *host_arg)
248 action->args = make_args(agent, _action, victim, victim_nodeid,
249 device_args, port_map, host_arg);
250 crm_debug(
"Preparing '%s' action for %s using agent %s",
251 _action, (victim? victim :
"no target"), agent);
252 action->agent = strdup(agent);
253 action->action = strdup(_action);
259 "Initialization bug in fencing library");
263 const char *value = NULL;
265 snprintf(buffer,
sizeof(buffer),
"pcmk_%s_retries", _action);
266 value = g_hash_table_lookup(device_args, buffer);
269 action->max_retries = atoi(value);
279 int diff = time(NULL) -
action->initial_start_time;
282 crm_info(
"Attempted to execute agent %s (%s) the maximum number of times (%d) allowed",
284 action->remaining_timeout = 0;
286 && (diff < (
action->timeout * 0.7))) {
291 action->remaining_timeout = 0;
293 return action->remaining_timeout ? TRUE : FALSE;
307 if (pcmk__result_ok(
result)) {
413 const char *exit_reason = NULL;
414 const char *action_stdout = NULL;
473 const char *exit_reason = NULL;
474 char *action_stdout = NULL;
484 &execution_status) < 0)) {
492 if ((rc ==
pcmk_ok) || (rc == -EINPROGRESS)) {
500 exit_reason =
"Fencer reply contained neither a full result " 501 "nor a legacy return code (bug?)";
513 set_result_from_svc_action(
action, svc_action);
514 svc_action->
params = NULL;
517 if (!pcmk__result_ok(&(
action->result))
518 && update_remaining_timeout(
action)) {
520 int rc = internal_stonith_action_execute(
action);
530 action->svc_action = NULL;
540 action->svc_action = svc_action;
549 crm_trace(
"Child process %d performing action '%s' successfully forked",
559 static int stonith_sequence = 0;
565 || (
action->agent == NULL)) {
572 action->initial_start_time = time(NULL);
577 crm_info(
"Attempt %d to execute %s (%s). remaining timeout is %d",
588 set_result_from_svc_action(
action, svc_action);
598 svc_action->
sequence = stonith_sequence++;
601 svc_action->
flags = pcmk__set_flags_as(__func__, __LINE__,
603 svc_action->
id, svc_action->
flags,
605 "SVC_ACTION_NON_BLOCKED");
616 &stonith_action_async_done,
617 &stonith_action_async_forked));
627 set_result_from_svc_action(
action, svc_action);
628 svc_action->
params = NULL;
647 void (*done) (
int pid,
650 void (*fork_cb) (
int pid,
void *user_data))
656 action->userdata = userdata;
658 action->fork_cb = fork_cb;
661 return internal_stonith_action_execute(
action);
681 rc = internal_stonith_action_execute(
action);
682 }
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
void stonith__xe_get_result(xmlNode *xml, pcmk__action_result_t *result)
int pcmk_rc2legacy(int rc)
stonith_action_t * stonith_action_create(const char *agent, const char *_action, const char *victim, uint32_t victim_nodeid, int timeout, GHashTable *device_args, GHashTable *port_map, const char *host_arg)
char * standard
Resource standard for resource actions, otherwise NULL.
#define crm_log_output(level, prefix, output)
const char * services__exit_reason(svc_action_t *action)
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.
enum pcmk_exec_status execution_status
svc_action_t * services_action_create_generic(const char *exec, const char *args[])
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)
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...)
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...)
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.
void pcmk__str_update(char **str, const char *value)
Action completed, result is known.
Execution failed, do not retry anywhere.
#define XML_LRM_ATTR_EXIT_REASON
#define STONITH_ATTR_ACTION_OP
Requested item has expired.
int stonith_action_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))
#define PCMK_RESOURCE_CLASS_STONITH
#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 XML_LRM_ATTR_OPSTATUS
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)
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 stonith__xe_set_result(xmlNode *xml, const pcmk__action_result_t *result)