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 :
""));
103 g_hash_table_insert((GHashTable *) user_data,
104 strdup(key), strdup(value? value :
""));
123 make_args(
const char *agent,
const char *
action,
const char *
target,
124 uint32_t target_nodeid, GHashTable *device_args,
125 GHashTable *port_map,
const char *host_arg)
127 GHashTable *arg_list = NULL;
128 const char *value = NULL;
138 snprintf(buffer,
sizeof(buffer),
"pcmk_%s_action",
action);
139 value = g_hash_table_lookup(device_args, buffer);
141 crm_debug(
"Substituting '%s' for fence action %s targeting %s",
152 if ((
target != NULL) && (device_args != NULL)) {
153 const char *param = NULL;
158 g_hash_table_insert(arg_list, strdup(
"nodename"), strdup(
target));
161 if (target_nodeid != 0) {
165 crm_info(
"Passing '%s' as nodeid with fence action '%s' targeting %s",
167 g_hash_table_insert(arg_list, strdup(
"nodeid"), nodeid);
179 param = (host_arg == NULL)?
"port" : host_arg;
181 value = g_hash_table_lookup(device_args, param);
183 if (pcmk__str_eq(value,
"dynamic",
188 const char *alias = NULL;
191 alias = g_hash_table_lookup(port_map,
target);
196 crm_debug(
"Passing %s='%s' with fence action %s targeting %s",
198 g_hash_table_insert(arg_list, strdup(param), strdup(alias));
204 g_hash_table_foreach(device_args, append_config_arg, arg_list);
222 g_hash_table_destroy(
action->args);
247 #define FAILURE_MAX_RETRIES 2 266 const char *
target, uint32_t target_nodeid,
267 int timeout_sec, GHashTable *device_args,
268 GHashTable *port_map,
const char *host_arg)
274 action->args = make_args(agent, action_name,
target, target_nodeid,
275 device_args, port_map, host_arg);
276 crm_debug(
"Preparing '%s' action targeting %s using agent %s",
277 action_name, pcmk__s(
target,
"no node"), agent);
278 action->agent = strdup(agent);
279 action->action = strdup(action_name);
280 action->timeout =
action->remaining_timeout = timeout_sec;
284 "Initialization bug in fencing library");
288 const char *value = NULL;
290 snprintf(buffer,
sizeof(buffer),
"pcmk_%s_retries", action_name);
291 value = g_hash_table_lookup(device_args, buffer);
294 action->max_retries = atoi(value);
304 int diff = time(NULL) -
action->initial_start_time;
307 crm_info(
"Attempted to execute agent %s (%s) the maximum number of times (%d) allowed",
309 action->remaining_timeout = 0;
311 && (diff < (
action->timeout * 0.7))) {
316 action->remaining_timeout = 0;
318 return action->remaining_timeout ? TRUE : FALSE;
332 if (pcmk__result_ok(
result)) {
438 const char *exit_reason = NULL;
439 const char *action_stdout = NULL;
498 const char *exit_reason = NULL;
499 char *action_stdout = NULL;
509 &execution_status) < 0)) {
517 if ((rc ==
pcmk_ok) || (rc == -EINPROGRESS)) {
525 exit_reason =
"Fencer reply contained neither a full result " 526 "nor a legacy return code (bug?)";
538 set_result_from_svc_action(
action, svc_action);
539 svc_action->
params = NULL;
542 if (!pcmk__result_ok(&(
action->result))
543 && update_remaining_timeout(
action)) {
545 int rc = internal_stonith_action_execute(
action);
555 action->svc_action = NULL;
565 action->svc_action = svc_action;
574 crm_trace(
"Child process %d performing action '%s' successfully forked",
584 static int stonith_sequence = 0;
590 || (
action->agent == NULL)) {
597 action->initial_start_time = time(NULL);
602 crm_info(
"Attempt %d to execute %s (%s). remaining timeout is %d",
613 set_result_from_svc_action(
action, svc_action);
624 svc_action->
sequence = stonith_sequence++;
627 svc_action->
flags = pcmk__set_flags_as(__func__, __LINE__,
629 svc_action->
id, svc_action->
flags,
631 "SVC_ACTION_NON_BLOCKED");
642 &stonith_action_async_done,
643 &stonith_action_async_forked));
653 set_result_from_svc_action(
action, svc_action);
654 svc_action->
params = NULL;
672 void (*done) (
int pid,
675 void (*fork_cb) (
int pid,
void *user_data))
681 action->userdata = userdata;
683 action->fork_cb = fork_cb;
686 return internal_stonith_action_execute(
action);
706 rc = internal_stonith_action_execute(
action);
707 }
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 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.
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.
Action completed, result is known.
Execution failed, do not retry anywhere.
#define XML_LRM_ATTR_EXIT_REASON
#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_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)