pacemaker  2.1.6-802a72226b
Scalable High-Availability cluster resource manager
st_actions.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2022 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/msg_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, "crm_feature_set", pcmk__str_casei)) {
100 
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 : ""));
105  }
106 }
107 
122 static GHashTable *
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)
126 {
127  GHashTable *arg_list = NULL;
128  const char *value = NULL;
129 
130  CRM_CHECK(action != NULL, return NULL);
131 
132  arg_list = pcmk__strkey_table(free, free);
133 
134  // Add action to arguments (using an alias if requested)
135  if (device_args) {
136  char buffer[512];
137 
138  snprintf(buffer, sizeof(buffer), "pcmk_%s_action", action);
139  value = g_hash_table_lookup(device_args, buffer);
140  if (value) {
141  crm_debug("Substituting '%s' for fence action %s targeting %s",
142  value, action, pcmk__s(target, "no node"));
143  action = value;
144  }
145  }
146  g_hash_table_insert(arg_list, strdup(STONITH_ATTR_ACTION_OP),
147  strdup(action));
148 
149  /* If this is a fencing operation against another node, add more standard
150  * arguments.
151  */
152  if ((target != NULL) && (device_args != NULL)) {
153  const char *param = NULL;
154 
155  /* Always pass the target's name, per
156  * https://github.com/ClusterLabs/fence-agents/blob/main/doc/FenceAgentAPI.md
157  */
158  g_hash_table_insert(arg_list, strdup("nodename"), strdup(target));
159 
160  // If the target's node ID was specified, pass it, too
161  if (target_nodeid != 0) {
162  char *nodeid = crm_strdup_printf("%" PRIu32, target_nodeid);
163 
164  // cts-fencing looks for this log message
165  crm_info("Passing '%s' as nodeid with fence action '%s' targeting %s",
166  nodeid, action, pcmk__s(target, "no node"));
167  g_hash_table_insert(arg_list, strdup("nodeid"), nodeid);
168  }
169 
170  // Check whether target must be specified in some other way
171  param = g_hash_table_lookup(device_args, PCMK_STONITH_HOST_ARGUMENT);
172  if (!pcmk__str_eq(agent, "fence_legacy", pcmk__str_none)
173  && !pcmk__str_eq(param, PCMK__VALUE_NONE, pcmk__str_casei)) {
174 
175  if (param == NULL) {
176  /* Use the caller's default for pcmk_host_argument, or "port" if
177  * none was given
178  */
179  param = (host_arg == NULL)? "port" : host_arg;
180  }
181  value = g_hash_table_lookup(device_args, param);
182 
183  if (pcmk__str_eq(value, "dynamic",
185  /* If the host argument was "dynamic" or not explicitly specified,
186  * add it with the target
187  */
188  const char *alias = NULL;
189 
190  if (port_map) {
191  alias = g_hash_table_lookup(port_map, target);
192  }
193  if (alias == NULL) {
194  alias = target;
195  }
196  crm_debug("Passing %s='%s' with fence action %s targeting %s",
197  param, alias, action, pcmk__s(target, "no node"));
198  g_hash_table_insert(arg_list, strdup(param), strdup(alias));
199  }
200  }
201  }
202 
203  if (device_args) {
204  g_hash_table_foreach(device_args, append_config_arg, arg_list);
205  }
206 
207  return arg_list;
208 }
209 
216 void
218 {
219  if (action) {
220  free(action->agent);
221  if (action->args) {
222  g_hash_table_destroy(action->args);
223  }
224  free(action->action);
225  if (action->svc_action) {
226  services_action_free(action->svc_action);
227  }
228  pcmk__reset_result(&(action->result));
229  free(action);
230  }
231 }
232 
243 {
244  return (action == NULL)? NULL : &(action->result);
245 }
246 
247 #define FAILURE_MAX_RETRIES 2
248 
265 stonith__action_create(const char *agent, const char *action_name,
266  const char *target, uint32_t target_nodeid,
267  int timeout_sec, GHashTable *device_args,
268  GHashTable *port_map, const char *host_arg)
269 {
270  stonith_action_t *action = calloc(1, sizeof(stonith_action_t));
271 
272  CRM_ASSERT(action != NULL);
273 
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;
281  action->max_retries = FAILURE_MAX_RETRIES;
282 
284  "Initialization bug in fencing library");
285 
286  if (device_args) {
287  char buffer[512];
288  const char *value = NULL;
289 
290  snprintf(buffer, sizeof(buffer), "pcmk_%s_retries", action_name);
291  value = g_hash_table_lookup(device_args, buffer);
292 
293  if (value) {
294  action->max_retries = atoi(value);
295  }
296  }
297 
298  return action;
299 }
300 
301 static gboolean
302 update_remaining_timeout(stonith_action_t * action)
303 {
304  int diff = time(NULL) - action->initial_start_time;
305 
306  if (action->tries >= action->max_retries) {
307  crm_info("Attempted to execute agent %s (%s) the maximum number of times (%d) allowed",
308  action->agent, action->action, action->max_retries);
309  action->remaining_timeout = 0;
310  } else if ((action->result.execution_status != PCMK_EXEC_TIMEOUT)
311  && (diff < (action->timeout * 0.7))) {
312  /* only set remaining timeout period if there is 30%
313  * or greater of the original timeout period left */
314  action->remaining_timeout = action->timeout - diff;
315  } else {
316  action->remaining_timeout = 0;
317  }
318  return action->remaining_timeout ? TRUE : FALSE;
319 }
320 
329 int
331 {
332  if (pcmk__result_ok(result)) {
333  return pcmk_rc_ok;
334  }
335 
336  switch (result->execution_status) {
337  case PCMK_EXEC_PENDING: return EINPROGRESS;
338  case PCMK_EXEC_CANCELLED: return ECANCELED;
339  case PCMK_EXEC_TIMEOUT: return ETIME;
340  case PCMK_EXEC_NOT_INSTALLED: return ENOENT;
341  case PCMK_EXEC_NOT_SUPPORTED: return EOPNOTSUPP;
342  case PCMK_EXEC_NOT_CONNECTED: return ENOTCONN;
343  case PCMK_EXEC_NO_FENCE_DEVICE: return ENODEV;
344  case PCMK_EXEC_NO_SECRETS: return EACCES;
345 
346  /* For the fencing API, PCMK_EXEC_INVALID is used with fencer API
347  * operations that don't involve executing an agent (for example,
348  * registering devices). This allows us to use the CRM_EX_* codes in the
349  * exit status for finer-grained responses.
350  */
351  case PCMK_EXEC_INVALID:
352  switch (result->exit_status) {
353  case CRM_EX_INVALID_PARAM: return EINVAL;
354  case CRM_EX_INSUFFICIENT_PRIV: return EACCES;
355  case CRM_EX_PROTOCOL: return EPROTO;
356 
357  /* CRM_EX_EXPIRED is used for orphaned fencing operations left
358  * over from a previous instance of the fencer. For API backward
359  * compatibility, this is mapped to the previously used code for
360  * this case, EHOSTUNREACH.
361  */
362  case CRM_EX_EXPIRED: return EHOSTUNREACH;
363  default: break;
364  }
365  break;
366 
367  default:
368  break;
369  }
370 
371  // Try to provide useful error code based on result's error output
372 
373  if (result->action_stderr == NULL) {
374  return ENODATA;
375 
376  } else if (strcasestr(result->action_stderr, "timed out")
377  || strcasestr(result->action_stderr, "timeout")) {
378  return ETIME;
379 
380  } else if (strcasestr(result->action_stderr, "unrecognised action")
381  || strcasestr(result->action_stderr, "unrecognized action")
382  || strcasestr(result->action_stderr, "unsupported action")) {
383  return EOPNOTSUPP;
384  }
385 
386  // Oh well, we tried
387  return pcmk_rc_error;
388 }
389 
403 int
405 {
406  if (rc >= 0) {
407  return PCMK_EXEC_DONE;
408  }
409  switch (-rc) {
410  case EACCES: return PCMK_EXEC_NO_SECRETS;
411  case ECANCELED: return PCMK_EXEC_CANCELLED;
412  case EHOSTUNREACH: return PCMK_EXEC_INVALID;
413  case EINPROGRESS: return PCMK_EXEC_PENDING;
414  case ENODEV: return PCMK_EXEC_NO_FENCE_DEVICE;
415  case ENOENT: return PCMK_EXEC_NOT_INSTALLED;
416  case ENOTCONN: return PCMK_EXEC_NOT_CONNECTED;
417  case EOPNOTSUPP: return PCMK_EXEC_NOT_SUPPORTED;
418  case EPROTO: return PCMK_EXEC_INVALID;
419  case EPROTONOSUPPORT: return PCMK_EXEC_NOT_SUPPORTED;
420  case ETIME: return PCMK_EXEC_TIMEOUT;
421  case ETIMEDOUT: return PCMK_EXEC_TIMEOUT;
422  default: return PCMK_EXEC_ERROR;
423  }
424 }
425 
433 void
435 {
436  int exit_status = CRM_EX_OK;
437  enum pcmk_exec_status execution_status = PCMK_EXEC_DONE;
438  const char *exit_reason = NULL;
439  const char *action_stdout = NULL;
440  int rc = pcmk_ok;
441 
442  CRM_CHECK(xml != NULL, return);
443 
444  if (result != NULL) {
445  exit_status = result->exit_status;
446  execution_status = result->execution_status;
447  exit_reason = result->exit_reason;
448  action_stdout = result->action_stdout;
450  }
451 
452  crm_xml_add_int(xml, XML_LRM_ATTR_OPSTATUS, (int) execution_status);
453  crm_xml_add_int(xml, XML_LRM_ATTR_RC, exit_status);
454  crm_xml_add(xml, XML_LRM_ATTR_EXIT_REASON, exit_reason);
455  crm_xml_add(xml, F_STONITH_OUTPUT, action_stdout);
456 
457  /* @COMPAT Peers in rolling upgrades, Pacemaker Remote nodes, and external
458  * code that use libstonithd <=2.1.2 don't check for the full result, and
459  * need a legacy return code instead.
460  */
461  crm_xml_add_int(xml, F_STONITH_RC, rc);
462 }
463 
472 xmlNode *
474 {
475  xmlNode *match = get_xpath_object("//@" XML_LRM_ATTR_RC, xml, LOG_NEVER);
476 
477  if (match == NULL) {
478  /* @COMPAT Peers <=2.1.2 in a rolling upgrade provide only a legacy
479  * return code, not a full result, so check for that.
480  */
481  match = get_xpath_object("//@" F_STONITH_RC, xml, LOG_ERR);
482  }
483  return match;
484 }
485 
493 void
495 {
496  int exit_status = CRM_EX_OK;
497  int execution_status = PCMK_EXEC_DONE;
498  const char *exit_reason = NULL;
499  char *action_stdout = NULL;
500 
501  CRM_CHECK((xml != NULL) && (result != NULL), return);
502 
503  exit_reason = crm_element_value(xml, XML_LRM_ATTR_EXIT_REASON);
504  action_stdout = crm_element_value_copy(xml, F_STONITH_OUTPUT);
505 
506  // A result must include an exit status and execution status
507  if ((crm_element_value_int(xml, XML_LRM_ATTR_RC, &exit_status) < 0)
509  &execution_status) < 0)) {
510  int rc = pcmk_ok;
511  exit_status = CRM_EX_ERROR;
512 
513  /* @COMPAT Peers <=2.1.2 in rolling upgrades provide only a legacy
514  * return code, not a full result, so check for that.
515  */
516  if (crm_element_value_int(xml, F_STONITH_RC, &rc) == 0) {
517  if ((rc == pcmk_ok) || (rc == -EINPROGRESS)) {
518  exit_status = CRM_EX_OK;
519  }
520  execution_status = stonith__legacy2status(rc);
521  exit_reason = pcmk_strerror(rc);
522 
523  } else {
524  execution_status = PCMK_EXEC_ERROR;
525  exit_reason = "Fencer reply contained neither a full result "
526  "nor a legacy return code (bug?)";
527  }
528  }
529  pcmk__set_result(result, exit_status, execution_status, exit_reason);
530  pcmk__set_result_output(result, action_stdout, NULL);
531 }
532 
533 static void
534 stonith_action_async_done(svc_action_t *svc_action)
535 {
536  stonith_action_t *action = (stonith_action_t *) svc_action->cb_data;
537 
538  set_result_from_svc_action(action, svc_action);
539  svc_action->params = NULL;
540  log_action(action, action->pid);
541 
542  if (!pcmk__result_ok(&(action->result))
543  && update_remaining_timeout(action)) {
544 
545  int rc = internal_stonith_action_execute(action);
546  if (rc == pcmk_ok) {
547  return;
548  }
549  }
550 
551  if (action->done_cb) {
552  action->done_cb(action->pid, &(action->result), action->userdata);
553  }
554 
555  action->svc_action = NULL; // don't remove our caller
557 }
558 
559 static void
560 stonith_action_async_forked(svc_action_t *svc_action)
561 {
562  stonith_action_t *action = (stonith_action_t *) svc_action->cb_data;
563 
564  action->pid = svc_action->pid;
565  action->svc_action = svc_action;
566 
567  if (action->fork_cb) {
568  (action->fork_cb) (svc_action->pid, action->userdata);
569  }
570 
572  NULL);
573 
574  crm_trace("Child process %d performing action '%s' successfully forked",
575  action->pid, action->action);
576 }
577 
578 static int
579 internal_stonith_action_execute(stonith_action_t * action)
580 {
581  int rc = -EPROTO;
582  int is_retry = 0;
583  svc_action_t *svc_action = NULL;
584  static int stonith_sequence = 0;
585  char *buffer = NULL;
586 
587  CRM_CHECK(action != NULL, return -EINVAL);
588 
589  if ((action->action == NULL) || (action->args == NULL)
590  || (action->agent == NULL)) {
592  PCMK_EXEC_ERROR_FATAL, "Bug in fencing library");
593  return -EINVAL;
594  }
595 
596  if (!action->tries) {
597  action->initial_start_time = time(NULL);
598  }
599  action->tries++;
600 
601  if (action->tries > 1) {
602  crm_info("Attempt %d to execute %s (%s). remaining timeout is %d",
603  action->tries, action->agent, action->action, action->remaining_timeout);
604  is_retry = 1;
605  }
606 
607  buffer = crm_strdup_printf(PCMK__FENCE_BINDIR "/%s",
608  basename(action->agent));
609  svc_action = services_action_create_generic(buffer, NULL);
610  free(buffer);
611 
612  if (svc_action->rc != PCMK_OCF_UNKNOWN) {
613  set_result_from_svc_action(action, svc_action);
614  services_action_free(svc_action);
615  return -E2BIG;
616  }
617 
618  svc_action->timeout = 1000 * action->remaining_timeout;
619  svc_action->standard = strdup(PCMK_RESOURCE_CLASS_STONITH);
620  svc_action->id = crm_strdup_printf("%s_%s_%dof%d", basename(action->agent),
621  action->action, action->tries,
622  action->max_retries);
623  svc_action->agent = strdup(action->agent);
624  svc_action->sequence = stonith_sequence++;
625  svc_action->params = action->args;
626  svc_action->cb_data = (void *) action;
627  svc_action->flags = pcmk__set_flags_as(__func__, __LINE__,
628  LOG_TRACE, "Action",
629  svc_action->id, svc_action->flags,
631  "SVC_ACTION_NON_BLOCKED");
632 
633  /* keep retries from executing out of control and free previous results */
634  if (is_retry) {
635  pcmk__reset_result(&(action->result));
636  sleep(1);
637  }
638 
639  if (action->async) {
640  // We never create a recurring action, so this should always return TRUE
642  &stonith_action_async_done,
643  &stonith_action_async_forked));
644  return pcmk_ok;
645 
646  } else if (services_action_sync(svc_action)) { // sync success
647  rc = pcmk_ok;
648 
649  } else { // sync failure
650  rc = -ECONNABORTED;
651  }
652 
653  set_result_from_svc_action(action, svc_action);
654  svc_action->params = NULL;
655  services_action_free(svc_action);
656  return rc;
657 }
658 
670 int
672  void (*done) (int pid,
674  void *user_data),
675  void (*fork_cb) (int pid, void *user_data))
676 {
677  if (!action) {
678  return -EINVAL;
679  }
680 
681  action->userdata = userdata;
682  action->done_cb = done;
683  action->fork_cb = fork_cb;
684  action->async = true;
685 
686  return internal_stonith_action_execute(action);
687 }
688 
697 int
699 {
700  int rc = pcmk_ok;
701 
702  CRM_CHECK(action != NULL, return -EINVAL);
703 
704  // Keep trying until success, max retries, or timeout
705  do {
706  rc = internal_stonith_action_execute(action);
707  } while ((rc != pcmk_ok) && update_remaining_timeout(action));
708 
709  return rc;
710 }
#define LOG_TRACE
Definition: logging.h:37
int rc
Exit status of action (set by library upon completion)
Definition: services.h:150
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:235
struct stonith_action_s stonith_action_t
Definition: internal.h:51
A dumping ground.
const char * pcmk_strerror(int rc)
Definition: results.c:148
No connection to executor.
Definition: results.h:323
#define ETIME
Definition: portability.h:150
void services_action_free(svc_action_t *op)
Definition: services.c:585
#define PCMK__FENCE_BINDIR
Definition: config.h:544
int pcmk_rc2legacy(int rc)
Definition: results.c:533
char * standard
Resource standard for resource actions, otherwise NULL.
Definition: services.h:133
void stonith__xe_get_result(const xmlNode *xml, pcmk__action_result_t *result)
Definition: st_actions.c:494
#define crm_log_output(level, prefix, output)
Definition: logging.h:109
char * id
Definition: services.h:121
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:398
void void pcmk__set_result_output(pcmk__action_result_t *result, char *out, char *err)
Definition: results.c:983
bool pcmk_stonith_param(const char *param)
Check whether a given stonith parameter is handled by Pacemaker.
Definition: agents.c:174
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:238
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:302
int stonith__legacy2status(int rc)
Definition: st_actions.c:404
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:867
Necessary CIB secrets are unavailable.
Definition: results.h:326
#define CRM_LOG_ASSERT(expr)
Definition: logging.h:219
#define PCMK__VALUE_NONE
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:265
int timeout
Action timeout (in milliseconds)
Definition: services.h:141
Action did not complete in time.
Definition: results.h:317
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute.
Definition: nvpair.c:532
#define LOG_NEVER
Definition: logging.h:47
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:214
Action was cancelled.
Definition: results.h:316
No fence device is configured for target.
Definition: results.h:325
const char * action
Definition: pcmk_fence.c:30
#define FAILURE_MAX_RETRIES
Definition: st_actions.c:247
enum svc_action_flags flags
Flag group of enum svc_action_flags.
Definition: services.h:171
Protocol violated.
Definition: results.h:263
char * services__grab_stderr(svc_action_t *action)
Definition: services.c:1411
uint32_t pid
Definition: cpg.c:46
#define crm_debug(fmt, args...)
Definition: logging.h:382
const char * services__exit_reason(const svc_action_t *action)
Definition: services.c:1376
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
Definition: nvpair.c:693
Used only to initialize variables.
Definition: results.h:313
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:496
gboolean services_action_sync(svc_action_t *op)
Definition: services.c:1020
GHashTable * params
Definition: services.h:148
#define crm_trace(fmt, args...)
Definition: logging.h:383
#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:117
#define F_STONITH_RC
Definition: internal.h:113
char * services__grab_stdout(svc_action_t *action)
Definition: services.c:1392
char * agent
Resource agent name for resource actions, otherwise NULL.
Definition: services.h:139
Action completed, result is known.
Definition: results.h:315
Success.
Definition: results.h:237
Execution failed, do not retry anywhere.
Definition: results.h:321
#define XML_LRM_ATTR_EXIT_REASON
Definition: msg_xml.h:333
int sequence
Definition: services.h:163
#define STONITH_ATTR_ACTION_OP
Definition: internal.h:165
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:671
#define F_STONITH_OUTPUT
Definition: internal.h:114
Requested item has expired.
Definition: results.h:278
Unspecified error.
Definition: results.h:168
const char * target
Definition: pcmk_fence.c:29
#define ENODATA
Definition: portability.h:145
#define PCMK_STONITH_HOST_ARGUMENT
Definition: agents.h:44
Agent does not implement requested action.
Definition: results.h:318
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
Definition: strings.c:611
pcmk__action_result_t result
Definition: pcmk_fence.c:35
Insufficient privileges.
Definition: results.h:243
pcmk__action_result_t * stonith__action_result(stonith_action_t *action)
Definition: st_actions.c:242
#define CRM_META
Definition: crm.h:78
int stonith__result2rc(const pcmk__action_result_t *result)
Definition: st_actions.c:330
#define CRM_ASSERT(expr)
Definition: results.h:42
int status
Execution status (enum pcmk_exec_status set by library)
Definition: services.h:158
Action is pending.
Definition: results.h:186
Fencing aka. STONITH.
#define XML_LRM_ATTR_OPSTATUS
Definition: msg_xml.h:325
Agent or dependency not available locally.
Definition: results.h:322
#define XML_LRM_ATTR_RC
Definition: msg_xml.h:326
#define pcmk_ok
Definition: results.h:68
Action is in progress.
Definition: results.h:314
int stonith__execute(stonith_action_t *action)
Definition: st_actions.c:698
xmlNode * stonith__find_xe_with_result(xmlNode *xml)
Definition: st_actions.c:473
void * cb_data
For caller&#39;s use (not used by library)
Definition: services.h:174
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:914
pcmk_exec_status
Execution status.
Definition: results.h:312
Parameter invalid (in local context)
Definition: results.h:241
Action cannot be attempted (e.g. shutdown)
Definition: results.h:324
void pcmk__reset_result(pcmk__action_result_t *result)
Definition: results.c:1003
unsigned int timeout
Definition: pcmk_fence.c:32
void stonith__destroy_action(stonith_action_t *action)
Definition: st_actions.c:217
Execution failed, may be retried.
Definition: results.h:319
#define crm_info(fmt, args...)
Definition: logging.h:380
void stonith__xe_set_result(xmlNode *xml, const pcmk__action_result_t *result)
Definition: st_actions.c:434