pacemaker  2.1.8-3980678f03
Scalable High-Availability cluster resource manager
st_actions.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2024 the Pacemaker project contributors
3  *
4  * The version control history for this file may have further details.
5  *
6  * This source code is licensed under the GNU Lesser General Public License
7  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8  */
9 
10 #include <crm_internal.h>
11 
12 #include <stdbool.h>
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <libgen.h>
17 #include <inttypes.h>
18 #include <sys/types.h>
19 #include <glib.h>
20 
21 #include <crm/crm.h>
22 #include <crm/stonith-ng.h>
23 #include <crm/fencing/internal.h>
24 #include <crm/common/xml.h>
25 #include <crm/services_internal.h>
26 
27 #include "fencing_private.h"
28 
29 struct stonith_action_s {
31  char *agent;
32  char *action;
33  GHashTable *args;
34  int timeout;
35  bool async;
36  void *userdata;
37  void (*done_cb) (int pid, const pcmk__action_result_t *result,
38  void *user_data);
39  void (*fork_cb) (int pid, void *user_data);
40 
41  svc_action_t *svc_action;
42 
44  time_t initial_start_time;
45  int tries;
46  int remaining_timeout;
47  int max_retries;
48 
49  int pid;
51 };
52 
53 static int internal_stonith_action_execute(stonith_action_t *action);
54 static void log_action(stonith_action_t *action, pid_t pid);
55 
63 static void
64 set_result_from_svc_action(stonith_action_t *action, svc_action_t *svc_action)
65 {
66  pcmk__set_result(&(action->result), svc_action->rc, svc_action->status,
67  services__exit_reason(svc_action));
69  services__grab_stdout(svc_action),
70  services__grab_stderr(svc_action));
71 }
72 
73 static void
74 log_action(stonith_action_t *action, pid_t pid)
75 {
76  /* The services library has already logged the output at info or debug
77  * level, so just raise to warning for stderr.
78  */
79  if (action->result.action_stderr != NULL) {
80  /* Logging the whole string confuses syslog when the string is xml */
81  char *prefix = crm_strdup_printf("%s[%d] stderr:", action->agent, pid);
82 
83  crm_log_output(LOG_WARNING, prefix, action->result.action_stderr);
84  free(prefix);
85  }
86 }
87 
88 static void
89 append_config_arg(gpointer key, gpointer value, gpointer user_data)
90 {
91  /* The fencer will filter "action" out when it registers the device,
92  * but ignore it here in case any external API users don't.
93  *
94  * Also filter out parameters handled directly by Pacemaker.
95  */
96  if (!pcmk__str_eq(key, STONITH_ATTR_ACTION_OP, pcmk__str_casei)
97  && !pcmk_stonith_param(key)
98  && (strstr(key, CRM_META) == NULL)
99  && !pcmk__str_eq(key, PCMK_XA_CRM_FEATURE_SET, pcmk__str_none)) {
100 
101  crm_trace("Passing %s=%s with fence action",
102  (const char *) key, (const char *) (value? value : ""));
103  pcmk__insert_dup((GHashTable *) user_data, key, pcmk__s(value, ""));
104  }
105 }
106 
121 static GHashTable *
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)
125 {
126  GHashTable *arg_list = NULL;
127  const char *value = NULL;
128 
129  CRM_CHECK(action != NULL, return NULL);
130 
131  arg_list = pcmk__strkey_table(free, free);
132 
133  // Add action to arguments (using an alias if requested)
134  if (device_args) {
135  char buffer[512];
136 
137  snprintf(buffer, sizeof(buffer), "pcmk_%s_action", action);
138  value = g_hash_table_lookup(device_args, buffer);
139  if (value) {
140  crm_debug("Substituting '%s' for fence action %s targeting %s",
141  value, action, pcmk__s(target, "no node"));
142  action = value;
143  }
144  }
146 
147  /* If this is a fencing operation against another node, add more standard
148  * arguments.
149  */
150  if ((target != NULL) && (device_args != NULL)) {
151  const char *param = NULL;
152 
153  /* Always pass the target's name, per
154  * https://github.com/ClusterLabs/fence-agents/blob/main/doc/FenceAgentAPI.md
155  */
156  pcmk__insert_dup(arg_list, "nodename", target);
157 
158  // If the target's node ID was specified, pass it, too
159  if (target_nodeid != 0) {
160  char *nodeid = crm_strdup_printf("%" PRIu32, target_nodeid);
161 
162  // cts-fencing looks for this log message
163  crm_info("Passing '%s' as nodeid with fence action '%s' targeting %s",
164  nodeid, action, pcmk__s(target, "no node"));
165  g_hash_table_insert(arg_list, strdup("nodeid"), nodeid);
166  }
167 
168  // Check whether target must be specified in some other way
169  param = g_hash_table_lookup(device_args, PCMK_STONITH_HOST_ARGUMENT);
170  if (!pcmk__str_eq(agent, "fence_legacy", pcmk__str_none)
171  && !pcmk__str_eq(param, PCMK_VALUE_NONE, pcmk__str_casei)) {
172 
173  if (param == NULL) {
174  /* Use the caller's default for pcmk_host_argument, or "port" if
175  * none was given
176  */
177  param = (host_arg == NULL)? "port" : host_arg;
178  }
179  value = g_hash_table_lookup(device_args, param);
180 
181  if (pcmk__str_eq(value, "dynamic",
183  /* If the host argument was "dynamic" or not explicitly specified,
184  * add it with the target
185  */
186  const char *alias = NULL;
187 
188  if (port_map) {
189  alias = g_hash_table_lookup(port_map, target);
190  }
191  if (alias == NULL) {
192  alias = target;
193  }
194  crm_debug("Passing %s='%s' with fence action %s targeting %s",
195  param, alias, action, pcmk__s(target, "no node"));
196  pcmk__insert_dup(arg_list, param, alias);
197  }
198  }
199  }
200 
201  if (device_args) {
202  g_hash_table_foreach(device_args, append_config_arg, arg_list);
203  }
204 
205  return arg_list;
206 }
207 
214 void
216 {
217  if (action) {
218  free(action->agent);
219  if (action->args) {
220  g_hash_table_destroy(action->args);
221  }
222  free(action->action);
223  if (action->svc_action) {
224  services_action_free(action->svc_action);
225  }
226  pcmk__reset_result(&(action->result));
227  free(action);
228  }
229 }
230 
241 {
242  return (action == NULL)? NULL : &(action->result);
243 }
244 
245 #define FAILURE_MAX_RETRIES 2
246 
263 stonith__action_create(const char *agent, const char *action_name,
264  const char *target, uint32_t target_nodeid,
265  int timeout_sec, GHashTable *device_args,
266  GHashTable *port_map, const char *host_arg)
267 {
269 
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;
277  action->max_retries = FAILURE_MAX_RETRIES;
278 
280  "Initialization bug in fencing library");
281 
282  if (device_args) {
283  char buffer[512];
284  const char *value = NULL;
285 
286  snprintf(buffer, sizeof(buffer), "pcmk_%s_retries", action_name);
287  value = g_hash_table_lookup(device_args, buffer);
288 
289  if (value) {
290  action->max_retries = atoi(value);
291  }
292  }
293 
294  return action;
295 }
296 
297 static gboolean
298 update_remaining_timeout(stonith_action_t * action)
299 {
300  int diff = time(NULL) - action->initial_start_time;
301 
302  if (action->tries >= action->max_retries) {
303  crm_info("Attempted to execute agent %s (%s) the maximum number of times (%d) allowed",
304  action->agent, action->action, action->max_retries);
305  action->remaining_timeout = 0;
306  } else if ((action->result.execution_status != PCMK_EXEC_TIMEOUT)
307  && (diff < (action->timeout * 0.7))) {
308  /* only set remaining timeout period if there is 30%
309  * or greater of the original timeout period left */
310  action->remaining_timeout = action->timeout - diff;
311  } else {
312  action->remaining_timeout = 0;
313  }
314  return action->remaining_timeout ? TRUE : FALSE;
315 }
316 
325 int
327 {
328  if (pcmk__result_ok(result)) {
329  return pcmk_rc_ok;
330  }
331 
332  switch (result->execution_status) {
333  case PCMK_EXEC_PENDING: return EINPROGRESS;
334  case PCMK_EXEC_CANCELLED: return ECANCELED;
335  case PCMK_EXEC_TIMEOUT: return ETIME;
336  case PCMK_EXEC_NOT_INSTALLED: return ENOENT;
337  case PCMK_EXEC_NOT_SUPPORTED: return EOPNOTSUPP;
338  case PCMK_EXEC_NOT_CONNECTED: return ENOTCONN;
339  case PCMK_EXEC_NO_FENCE_DEVICE: return ENODEV;
340  case PCMK_EXEC_NO_SECRETS: return EACCES;
341 
342  /* For the fencing API, PCMK_EXEC_INVALID is used with fencer API
343  * operations that don't involve executing an agent (for example,
344  * registering devices). This allows us to use the CRM_EX_* codes in the
345  * exit status for finer-grained responses.
346  */
347  case PCMK_EXEC_INVALID:
348  switch (result->exit_status) {
349  case CRM_EX_INVALID_PARAM: return EINVAL;
350  case CRM_EX_INSUFFICIENT_PRIV: return EACCES;
351  case CRM_EX_PROTOCOL: return EPROTO;
352 
353  /* CRM_EX_EXPIRED is used for orphaned fencing operations left
354  * over from a previous instance of the fencer. For API backward
355  * compatibility, this is mapped to the previously used code for
356  * this case, EHOSTUNREACH.
357  */
358  case CRM_EX_EXPIRED: return EHOSTUNREACH;
359  default: break;
360  }
361  break;
362 
363  default:
364  break;
365  }
366 
367  // Try to provide useful error code based on result's error output
368 
369  if (result->action_stderr == NULL) {
370  return ENODATA;
371 
372  } else if (strcasestr(result->action_stderr, "timed out")
373  || strcasestr(result->action_stderr, "timeout")) {
374  return ETIME;
375 
376  } else if (strcasestr(result->action_stderr, "unrecognised action")
377  || strcasestr(result->action_stderr, "unrecognized action")
378  || strcasestr(result->action_stderr, "unsupported action")) {
379  return EOPNOTSUPP;
380  }
381 
382  // Oh well, we tried
383  return pcmk_rc_error;
384 }
385 
399 int
401 {
402  if (rc >= 0) {
403  return PCMK_EXEC_DONE;
404  }
405  switch (-rc) {
406  case EACCES: return PCMK_EXEC_NO_SECRETS;
407  case ECANCELED: return PCMK_EXEC_CANCELLED;
408  case EHOSTUNREACH: return PCMK_EXEC_INVALID;
409  case EINPROGRESS: return PCMK_EXEC_PENDING;
410  case ENODEV: return PCMK_EXEC_NO_FENCE_DEVICE;
411  case ENOENT: return PCMK_EXEC_NOT_INSTALLED;
412  case ENOTCONN: return PCMK_EXEC_NOT_CONNECTED;
413  case EOPNOTSUPP: return PCMK_EXEC_NOT_SUPPORTED;
414  case EPROTO: return PCMK_EXEC_INVALID;
415  case EPROTONOSUPPORT: return PCMK_EXEC_NOT_SUPPORTED;
416  case ETIME: return PCMK_EXEC_TIMEOUT;
417  case ETIMEDOUT: return PCMK_EXEC_TIMEOUT;
418  default: return PCMK_EXEC_ERROR;
419  }
420 }
421 
429 void
431 {
432  int exit_status = CRM_EX_OK;
433  enum pcmk_exec_status execution_status = PCMK_EXEC_DONE;
434  const char *exit_reason = NULL;
435  const char *action_stdout = NULL;
436  int rc = pcmk_ok;
437 
438  CRM_CHECK(xml != NULL, return);
439 
440  if (result != NULL) {
441  exit_status = result->exit_status;
442  execution_status = result->execution_status;
443  exit_reason = result->exit_reason;
444  action_stdout = result->action_stdout;
446  }
447 
448  crm_xml_add_int(xml, PCMK__XA_OP_STATUS, (int) execution_status);
449  crm_xml_add_int(xml, PCMK__XA_RC_CODE, exit_status);
450  crm_xml_add(xml, PCMK_XA_EXIT_REASON, exit_reason);
451  crm_xml_add(xml, PCMK__XA_ST_OUTPUT, action_stdout);
452 
453  /* @COMPAT Peers in rolling upgrades, Pacemaker Remote nodes, and external
454  * code that use libstonithd <=2.1.2 don't check for the full result, and
455  * need a legacy return code instead.
456  */
458 }
459 
468 xmlNode *
470 {
471  xmlNode *match = get_xpath_object("//@" PCMK__XA_RC_CODE, xml, LOG_NEVER);
472 
473  if (match == NULL) {
474  /* @COMPAT Peers <=2.1.2 in a rolling upgrade provide only a legacy
475  * return code, not a full result, so check for that.
476  */
477  match = get_xpath_object("//@" PCMK__XA_ST_RC, xml, LOG_ERR);
478  }
479  return match;
480 }
481 
489 void
491 {
492  int exit_status = CRM_EX_OK;
493  int execution_status = PCMK_EXEC_DONE;
494  const char *exit_reason = NULL;
495  char *action_stdout = NULL;
496 
497  CRM_CHECK((xml != NULL) && (result != NULL), return);
498 
499  exit_reason = crm_element_value(xml, PCMK_XA_EXIT_REASON);
500  action_stdout = crm_element_value_copy(xml, PCMK__XA_ST_OUTPUT);
501 
502  // A result must include an exit status and execution status
503  if ((crm_element_value_int(xml, PCMK__XA_RC_CODE, &exit_status) < 0)
505  &execution_status) < 0)) {
506  int rc = pcmk_ok;
507  exit_status = CRM_EX_ERROR;
508 
509  /* @COMPAT Peers <=2.1.2 in rolling upgrades provide only a legacy
510  * return code, not a full result, so check for that.
511  */
512  if (crm_element_value_int(xml, PCMK__XA_ST_RC, &rc) == 0) {
513  if ((rc == pcmk_ok) || (rc == -EINPROGRESS)) {
514  exit_status = CRM_EX_OK;
515  }
516  execution_status = stonith__legacy2status(rc);
517  exit_reason = pcmk_strerror(rc);
518 
519  } else {
520  execution_status = PCMK_EXEC_ERROR;
521  exit_reason = "Fencer reply contained neither a full result "
522  "nor a legacy return code (bug?)";
523  }
524  }
525  pcmk__set_result(result, exit_status, execution_status, exit_reason);
526  pcmk__set_result_output(result, action_stdout, NULL);
527 }
528 
529 static void
530 stonith_action_async_done(svc_action_t *svc_action)
531 {
532  stonith_action_t *action = (stonith_action_t *) svc_action->cb_data;
533 
534  set_result_from_svc_action(action, svc_action);
535  svc_action->params = NULL;
536  log_action(action, action->pid);
537 
538  if (!pcmk__result_ok(&(action->result))
539  && update_remaining_timeout(action)) {
540 
541  int rc = internal_stonith_action_execute(action);
542  if (rc == pcmk_ok) {
543  return;
544  }
545  }
546 
547  if (action->done_cb) {
548  action->done_cb(action->pid, &(action->result), action->userdata);
549  }
550 
551  action->svc_action = NULL; // don't remove our caller
553 }
554 
555 static void
556 stonith_action_async_forked(svc_action_t *svc_action)
557 {
558  stonith_action_t *action = (stonith_action_t *) svc_action->cb_data;
559 
560  action->pid = svc_action->pid;
561  action->svc_action = svc_action;
562 
563  if (action->fork_cb) {
564  (action->fork_cb) (svc_action->pid, action->userdata);
565  }
566 
568  NULL);
569 
570  crm_trace("Child process %d performing action '%s' successfully forked",
571  action->pid, action->action);
572 }
573 
574 static int
575 internal_stonith_action_execute(stonith_action_t * action)
576 {
577  int rc = -EPROTO;
578  int is_retry = 0;
579  svc_action_t *svc_action = NULL;
580  static int stonith_sequence = 0;
581  char *buffer = NULL;
582 
583  CRM_CHECK(action != NULL, return -EINVAL);
584 
585  if ((action->action == NULL) || (action->args == NULL)
586  || (action->agent == NULL)) {
588  PCMK_EXEC_ERROR_FATAL, "Bug in fencing library");
589  return -EINVAL;
590  }
591 
592  if (!action->tries) {
593  action->initial_start_time = time(NULL);
594  }
595  action->tries++;
596 
597  if (action->tries > 1) {
598  crm_info("Attempt %d to execute %s (%s). remaining timeout is %d",
599  action->tries, action->agent, action->action, action->remaining_timeout);
600  is_retry = 1;
601  }
602 
603  buffer = crm_strdup_printf(PCMK__FENCE_BINDIR "/%s",
604  basename(action->agent));
605  svc_action = services_action_create_generic(buffer, NULL);
606  free(buffer);
607 
608  if (svc_action->rc != PCMK_OCF_UNKNOWN) {
609  set_result_from_svc_action(action, svc_action);
610  services_action_free(svc_action);
611  return -E2BIG;
612  }
613 
614  svc_action->timeout = 1000 * action->remaining_timeout;
615  svc_action->standard = strdup(PCMK_RESOURCE_CLASS_STONITH);
616  svc_action->id = crm_strdup_printf("%s_%s_%dof%d", basename(action->agent),
617  action->action, action->tries,
618  action->max_retries);
619  svc_action->agent = strdup(action->agent);
620  svc_action->sequence = stonith_sequence++;
621  svc_action->params = action->args;
622  svc_action->cb_data = (void *) action;
623  svc_action->flags = pcmk__set_flags_as(__func__, __LINE__,
624  LOG_TRACE, "Action",
625  svc_action->id, svc_action->flags,
627  "SVC_ACTION_NON_BLOCKED");
628 
629  /* keep retries from executing out of control and free previous results */
630  if (is_retry) {
631  pcmk__reset_result(&(action->result));
632  sleep(1);
633  }
634 
635  if (action->async) {
636  // We never create a recurring action, so this should always return TRUE
638  &stonith_action_async_done,
639  &stonith_action_async_forked));
640  return pcmk_ok;
641 
642  } else if (services_action_sync(svc_action)) { // sync success
643  rc = pcmk_ok;
644 
645  } else { // sync failure
646  rc = -ECONNABORTED;
647  }
648 
649  set_result_from_svc_action(action, svc_action);
650  svc_action->params = NULL;
651  services_action_free(svc_action);
652  return rc;
653 }
654 
666 int
668  void (*done) (int pid,
670  void *user_data),
671  void (*fork_cb) (int pid, void *user_data))
672 {
673  if (!action) {
674  return -EINVAL;
675  }
676 
677  action->userdata = userdata;
678  action->done_cb = done;
679  action->fork_cb = fork_cb;
680  action->async = true;
681 
682  return internal_stonith_action_execute(action);
683 }
684 
693 int
695 {
696  int rc = pcmk_ok;
697 
698  CRM_CHECK(action != NULL, return -EINVAL);
699 
700  // Keep trying until success, max retries, or timeout
701  do {
702  rc = internal_stonith_action_execute(action);
703  } while ((rc != pcmk_ok) && update_remaining_timeout(action));
704 
705  return rc;
706 }
#define LOG_TRACE
Definition: logging.h:38
int rc
Exit status of action (set by library upon completion)
Definition: services.h:155
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:245
struct stonith_action_s stonith_action_t
Definition: internal.h:51
A dumping ground.
const char * pcmk_strerror(int rc)
Definition: results.c:149
No connection to executor.
Definition: results.h:341
#define ETIME
Definition: portability.h:111
void services_action_free(svc_action_t *op)
Definition: services.c:583
#define PCMK__FENCE_BINDIR
Definition: config.h:559
int pcmk_rc2legacy(int rc)
Definition: results.c:546
char * standard
Resource standard for resource actions, otherwise NULL.
Definition: services.h:138
#define PCMK__XA_RC_CODE
void stonith__xe_get_result(const xmlNode *xml, pcmk__action_result_t *result)
Definition: st_actions.c:490
#define PCMK__XA_ST_OUTPUT
#define crm_log_output(level, prefix, output)
Definition: logging.h:115
char * id
Definition: services.h:126
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
Definition: nvpair.c:348
void void pcmk__set_result_output(pcmk__action_result_t *result, char *out, char *err)
Definition: results.c:1045
bool pcmk_stonith_param(const char *param)
Check whether a given stonith parameter is handled by Pacemaker.
Definition: agents.c:175
#define PCMK_XA_EXIT_REASON
Definition: xml_names.h:269
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.
Definition: services.c:356
Unspecified error.
Definition: results.h:256
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
Definition: nvpair.c:301
int stonith__legacy2status(int rc)
Definition: st_actions.c:400
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.
Definition: services.c:865
Necessary CIB secrets are unavailable.
Definition: results.h:344
#define CRM_LOG_ASSERT(expr)
Definition: logging.h:228
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)
Definition: st_actions.c:263
int timeout
Action timeout (in milliseconds)
Definition: services.h:146
Action did not complete in time.
Definition: results.h:335
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute.
Definition: nvpair.c:482
#define LOG_NEVER
Definition: logging.h:48
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:189
Action was cancelled.
Definition: results.h:334
No fence device is configured for target.
Definition: results.h:343
const char * action
Definition: pcmk_fence.c:30
#define FAILURE_MAX_RETRIES
Definition: st_actions.c:245
enum svc_action_flags flags
Flag group of enum svc_action_flags.
Definition: services.h:176
Protocol violated.
Definition: results.h:281
char * services__grab_stderr(svc_action_t *action)
Definition: services.c:1409
uint32_t pid
Definition: cpg.c:49
#define crm_debug(fmt, args...)
Definition: logging.h:402
const char * services__exit_reason(const svc_action_t *action)
Definition: services.c:1374
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
Definition: nvpair.c:674
Used only to initialize variables.
Definition: results.h:331
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:446
gboolean services_action_sync(svc_action_t *op)
Definition: services.c:1018
#define PCMK_VALUE_NONE
Definition: options.h:178
GHashTable * params
Definition: services.h:153
#define crm_trace(fmt, args...)
Definition: logging.h:404
#define PCMK_RESOURCE_CLASS_STONITH
Definition: agents.h:31
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
Object for executing external actions.
Definition: services.h:122
char * services__grab_stdout(svc_action_t *action)
Definition: services.c:1390
char * agent
Resource agent name for resource actions, otherwise NULL.
Definition: services.h:144
Wrappers for and extensions to libxml2.
Action completed, result is known.
Definition: results.h:333
Success.
Definition: results.h:255
Execution failed, do not retry anywhere.
Definition: results.h:339
int sequence
Definition: services.h:168
#define STONITH_ATTR_ACTION_OP
Definition: internal.h:110
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))
Definition: st_actions.c:667
Requested item has expired.
Definition: results.h:296
Unspecified error.
Definition: results.h:181
const char * target
Definition: pcmk_fence.c:29
#define PCMK_XA_CRM_FEATURE_SET
Definition: xml_names.h:249
#define ENODATA
Definition: portability.h:106
#define PCMK_STONITH_HOST_ARGUMENT
Definition: agents.h:44
Agent does not implement requested action.
Definition: results.h:336
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
Definition: strings.c:683
pcmk__action_result_t result
Definition: pcmk_fence.c:35
Insufficient privileges.
Definition: results.h:261
pcmk__action_result_t * stonith__action_result(stonith_action_t *action)
Definition: st_actions.c:240
#define CRM_META
Definition: crm.h:81
int stonith__result2rc(const pcmk__action_result_t *result)
Definition: st_actions.c:326
int status
Execution status (enum pcmk_exec_status set by library)
Definition: services.h:163
Action is pending.
Definition: results.h:203
Fencing aka. STONITH.
#define PCMK__XA_OP_STATUS
Agent or dependency not available locally.
Definition: results.h:340
#define pcmk_ok
Definition: results.h:69
Action is in progress.
Definition: results.h:332
int stonith__execute(stonith_action_t *action)
Definition: st_actions.c:694
xmlNode * stonith__find_xe_with_result(xmlNode *xml)
Definition: st_actions.c:469
void * cb_data
For caller&#39;s use (not used by library)
Definition: services.h:179
void pcmk__set_result(pcmk__action_result_t *result, int exit_status, enum pcmk_exec_status exec_status, const char *exit_reason)
Definition: results.c:976
pcmk_exec_status
Execution status.
Definition: results.h:330
Parameter invalid (in local context)
Definition: results.h:259
Action cannot be attempted (e.g. shutdown)
Definition: results.h:342
#define PCMK__XA_ST_RC
#define pcmk__assert_alloc(nmemb, size)
Definition: internal.h:297
void pcmk__reset_result(pcmk__action_result_t *result)
Definition: results.c:1065
unsigned int timeout
Definition: pcmk_fence.c:32
void stonith__destroy_action(stonith_action_t *action)
Definition: st_actions.c:215
Execution failed, may be retried.
Definition: results.h:337
#define crm_info(fmt, args...)
Definition: logging.h:399
void pcmk__insert_dup(GHashTable *table, const char *name, const char *value)
Definition: strings.c:701
void stonith__xe_set_result(xmlNode *xml, const pcmk__action_result_t *result)
Definition: st_actions.c:430