pacemaker  2.1.4-dc6eb4362
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 <stdlib.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <libgen.h>
16 #include <inttypes.h>
17 #include <sys/types.h>
18 #include <glib.h>
19 
20 #include <crm/crm.h>
21 #include <crm/stonith-ng.h>
22 #include <crm/fencing/internal.h>
23 #include <crm/msg_xml.h>
24 #include <crm/services_internal.h>
25 
26 #include "fencing_private.h"
27 
28 struct stonith_action_s {
30  char *agent;
31  char *action;
32  char *victim;
33  GHashTable *args;
34  int timeout;
35  int 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 
108 static GHashTable *
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)
112 {
113  GHashTable *arg_list = NULL;
114  const char *value = NULL;
115 
116  CRM_CHECK(action != NULL, return NULL);
117 
118  arg_list = pcmk__strkey_table(free, free);
119 
120  // Add action to arguments (using an alias if requested)
121  if (device_args) {
122  char buffer[512];
123 
124  snprintf(buffer, sizeof(buffer), "pcmk_%s_action", action);
125  value = g_hash_table_lookup(device_args, buffer);
126  if (value) {
127  crm_debug("Substituting '%s' for fence action %s targeting %s",
128  value, action, victim);
129  action = value;
130  }
131  }
132  g_hash_table_insert(arg_list, strdup(STONITH_ATTR_ACTION_OP),
133  strdup(action));
134 
135  /* If this is a fencing operation against another node, add more standard
136  * arguments.
137  */
138  if (victim && device_args) {
139  const char *param = NULL;
140 
141  /* Always pass the target's name, per
142  * https://github.com/ClusterLabs/fence-agents/blob/master/doc/FenceAgentAPI.md
143  */
144  g_hash_table_insert(arg_list, strdup("nodename"), strdup(victim));
145 
146  // If the target's node ID was specified, pass it, too
147  if (victim_nodeid) {
148  char *nodeid = crm_strdup_printf("%" PRIu32, victim_nodeid);
149 
150  // cts-fencing looks for this log message
151  crm_info("Passing '%s' as nodeid with fence action '%s' targeting %s",
152  nodeid, action, victim);
153  g_hash_table_insert(arg_list, strdup("nodeid"), nodeid);
154  }
155 
156  // Check whether target must be specified in some other way
157  param = g_hash_table_lookup(device_args, PCMK_STONITH_HOST_ARGUMENT);
158  if (!pcmk__str_eq(agent, "fence_legacy", pcmk__str_none)
159  && !pcmk__str_eq(param, PCMK__VALUE_NONE, pcmk__str_casei)) {
160 
161  if (param == NULL) {
162  /* Use the caller's default for pcmk_host_argument, or "port" if
163  * none was given
164  */
165  param = (host_arg == NULL)? "port" : host_arg;
166  }
167  value = g_hash_table_lookup(device_args, param);
168 
169  if (pcmk__str_eq(value, "dynamic",
171  /* If the host argument was "dynamic" or not explicitly specified,
172  * add it with the target
173  */
174  const char *alias = NULL;
175 
176  if (port_map) {
177  alias = g_hash_table_lookup(port_map, victim);
178  }
179  if (alias == NULL) {
180  alias = victim;
181  }
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));
185  }
186  }
187  }
188 
189  if (device_args) {
190  g_hash_table_foreach(device_args, append_config_arg, arg_list);
191  }
192 
193  return arg_list;
194 }
195 
202 void
204 {
205  if (action) {
206  free(action->agent);
207  if (action->args) {
208  g_hash_table_destroy(action->args);
209  }
210  free(action->action);
211  free(action->victim);
212  if (action->svc_action) {
213  services_action_free(action->svc_action);
214  }
215  pcmk__reset_result(&(action->result));
216  free(action);
217  }
218 }
219 
230 {
231  return (action == NULL)? NULL : &(action->result);
232 }
233 
234 #define FAILURE_MAX_RETRIES 2
236 stonith_action_create(const char *agent,
237  const char *_action,
238  const char *victim,
239  uint32_t victim_nodeid,
240  int timeout, GHashTable * device_args,
241  GHashTable * port_map, const char *host_arg)
242 {
244 
245  action = calloc(1, sizeof(stonith_action_t));
246  CRM_ASSERT(action != NULL);
247 
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);
254  pcmk__str_update(&action->victim, victim);
255  action->timeout = action->remaining_timeout = timeout;
256  action->max_retries = FAILURE_MAX_RETRIES;
257 
259  "Initialization bug in fencing library");
260 
261  if (device_args) {
262  char buffer[512];
263  const char *value = NULL;
264 
265  snprintf(buffer, sizeof(buffer), "pcmk_%s_retries", _action);
266  value = g_hash_table_lookup(device_args, buffer);
267 
268  if (value) {
269  action->max_retries = atoi(value);
270  }
271  }
272 
273  return action;
274 }
275 
276 static gboolean
277 update_remaining_timeout(stonith_action_t * action)
278 {
279  int diff = time(NULL) - action->initial_start_time;
280 
281  if (action->tries >= action->max_retries) {
282  crm_info("Attempted to execute agent %s (%s) the maximum number of times (%d) allowed",
283  action->agent, action->action, action->max_retries);
284  action->remaining_timeout = 0;
285  } else if ((action->result.execution_status != PCMK_EXEC_TIMEOUT)
286  && (diff < (action->timeout * 0.7))) {
287  /* only set remaining timeout period if there is 30%
288  * or greater of the original timeout period left */
289  action->remaining_timeout = action->timeout - diff;
290  } else {
291  action->remaining_timeout = 0;
292  }
293  return action->remaining_timeout ? TRUE : FALSE;
294 }
295 
304 int
306 {
307  if (pcmk__result_ok(result)) {
308  return pcmk_rc_ok;
309  }
310 
311  switch (result->execution_status) {
312  case PCMK_EXEC_PENDING: return EINPROGRESS;
313  case PCMK_EXEC_CANCELLED: return ECANCELED;
314  case PCMK_EXEC_TIMEOUT: return ETIME;
315  case PCMK_EXEC_NOT_INSTALLED: return ENOENT;
316  case PCMK_EXEC_NOT_SUPPORTED: return EOPNOTSUPP;
317  case PCMK_EXEC_NOT_CONNECTED: return ENOTCONN;
318  case PCMK_EXEC_NO_FENCE_DEVICE: return ENODEV;
319  case PCMK_EXEC_NO_SECRETS: return EACCES;
320 
321  /* For the fencing API, PCMK_EXEC_INVALID is used with fencer API
322  * operations that don't involve executing an agent (for example,
323  * registering devices). This allows us to use the CRM_EX_* codes in the
324  * exit status for finer-grained responses.
325  */
326  case PCMK_EXEC_INVALID:
327  switch (result->exit_status) {
328  case CRM_EX_INVALID_PARAM: return EINVAL;
329  case CRM_EX_INSUFFICIENT_PRIV: return EACCES;
330  case CRM_EX_PROTOCOL: return EPROTO;
331 
332  /* CRM_EX_EXPIRED is used for orphaned fencing operations left
333  * over from a previous instance of the fencer. For API backward
334  * compatibility, this is mapped to the previously used code for
335  * this case, EHOSTUNREACH.
336  */
337  case CRM_EX_EXPIRED: return EHOSTUNREACH;
338  default: break;
339  }
340  break;
341 
342  default:
343  break;
344  }
345 
346  // Try to provide useful error code based on result's error output
347 
348  if (result->action_stderr == NULL) {
349  return ENODATA;
350 
351  } else if (strcasestr(result->action_stderr, "timed out")
352  || strcasestr(result->action_stderr, "timeout")) {
353  return ETIME;
354 
355  } else if (strcasestr(result->action_stderr, "unrecognised action")
356  || strcasestr(result->action_stderr, "unrecognized action")
357  || strcasestr(result->action_stderr, "unsupported action")) {
358  return EOPNOTSUPP;
359  }
360 
361  // Oh well, we tried
362  return pcmk_rc_error;
363 }
364 
378 int
380 {
381  if (rc >= 0) {
382  return PCMK_EXEC_DONE;
383  }
384  switch (-rc) {
385  case EACCES: return PCMK_EXEC_NO_SECRETS;
386  case ECANCELED: return PCMK_EXEC_CANCELLED;
387  case EHOSTUNREACH: return PCMK_EXEC_INVALID;
388  case EINPROGRESS: return PCMK_EXEC_PENDING;
389  case ENODEV: return PCMK_EXEC_NO_FENCE_DEVICE;
390  case ENOENT: return PCMK_EXEC_NOT_INSTALLED;
391  case ENOTCONN: return PCMK_EXEC_NOT_CONNECTED;
392  case EOPNOTSUPP: return PCMK_EXEC_NOT_SUPPORTED;
393  case EPROTO: return PCMK_EXEC_INVALID;
394  case EPROTONOSUPPORT: return PCMK_EXEC_NOT_SUPPORTED;
395  case ETIME: return PCMK_EXEC_TIMEOUT;
396  case ETIMEDOUT: return PCMK_EXEC_TIMEOUT;
397  default: return PCMK_EXEC_ERROR;
398  }
399 }
400 
408 void
410 {
411  int exit_status = CRM_EX_OK;
412  enum pcmk_exec_status execution_status = PCMK_EXEC_DONE;
413  const char *exit_reason = NULL;
414  const char *action_stdout = NULL;
415  int rc = pcmk_ok;
416 
417  CRM_CHECK(xml != NULL, return);
418 
419  if (result != NULL) {
420  exit_status = result->exit_status;
421  execution_status = result->execution_status;
422  exit_reason = result->exit_reason;
423  action_stdout = result->action_stdout;
425  }
426 
427  crm_xml_add_int(xml, XML_LRM_ATTR_OPSTATUS, (int) execution_status);
428  crm_xml_add_int(xml, XML_LRM_ATTR_RC, exit_status);
429  crm_xml_add(xml, XML_LRM_ATTR_EXIT_REASON, exit_reason);
430  crm_xml_add(xml, F_STONITH_OUTPUT, action_stdout);
431 
432  /* @COMPAT Peers in rolling upgrades, Pacemaker Remote nodes, and external
433  * code that use libstonithd <=2.1.2 don't check for the full result, and
434  * need a legacy return code instead.
435  */
436  crm_xml_add_int(xml, F_STONITH_RC, rc);
437 }
438 
447 xmlNode *
449 {
450  xmlNode *match = get_xpath_object("//@" XML_LRM_ATTR_RC, xml, LOG_NEVER);
451 
452  if (match == NULL) {
453  /* @COMPAT Peers <=2.1.2 in a rolling upgrade provide only a legacy
454  * return code, not a full result, so check for that.
455  */
456  match = get_xpath_object("//@" F_STONITH_RC, xml, LOG_ERR);
457  }
458  return match;
459 }
460 
468 void
470 {
471  int exit_status = CRM_EX_OK;
472  int execution_status = PCMK_EXEC_DONE;
473  const char *exit_reason = NULL;
474  char *action_stdout = NULL;
475 
476  CRM_CHECK((xml != NULL) && (result != NULL), return);
477 
478  exit_reason = crm_element_value(xml, XML_LRM_ATTR_EXIT_REASON);
479  action_stdout = crm_element_value_copy(xml, F_STONITH_OUTPUT);
480 
481  // A result must include an exit status and execution status
482  if ((crm_element_value_int(xml, XML_LRM_ATTR_RC, &exit_status) < 0)
484  &execution_status) < 0)) {
485  int rc = pcmk_ok;
486  exit_status = CRM_EX_ERROR;
487 
488  /* @COMPAT Peers <=2.1.2 in rolling upgrades provide only a legacy
489  * return code, not a full result, so check for that.
490  */
491  if (crm_element_value_int(xml, F_STONITH_RC, &rc) == 0) {
492  if ((rc == pcmk_ok) || (rc == -EINPROGRESS)) {
493  exit_status = CRM_EX_OK;
494  }
495  execution_status = stonith__legacy2status(rc);
496  exit_reason = pcmk_strerror(rc);
497 
498  } else {
499  execution_status = PCMK_EXEC_ERROR;
500  exit_reason = "Fencer reply contained neither a full result "
501  "nor a legacy return code (bug?)";
502  }
503  }
504  pcmk__set_result(result, exit_status, execution_status, exit_reason);
505  pcmk__set_result_output(result, action_stdout, NULL);
506 }
507 
508 static void
509 stonith_action_async_done(svc_action_t *svc_action)
510 {
511  stonith_action_t *action = (stonith_action_t *) svc_action->cb_data;
512 
513  set_result_from_svc_action(action, svc_action);
514  svc_action->params = NULL;
515  log_action(action, action->pid);
516 
517  if (!pcmk__result_ok(&(action->result))
518  && update_remaining_timeout(action)) {
519 
520  int rc = internal_stonith_action_execute(action);
521  if (rc == pcmk_ok) {
522  return;
523  }
524  }
525 
526  if (action->done_cb) {
527  action->done_cb(action->pid, &(action->result), action->userdata);
528  }
529 
530  action->svc_action = NULL; // don't remove our caller
532 }
533 
534 static void
535 stonith_action_async_forked(svc_action_t *svc_action)
536 {
537  stonith_action_t *action = (stonith_action_t *) svc_action->cb_data;
538 
539  action->pid = svc_action->pid;
540  action->svc_action = svc_action;
541 
542  if (action->fork_cb) {
543  (action->fork_cb) (svc_action->pid, action->userdata);
544  }
545 
547  NULL);
548 
549  crm_trace("Child process %d performing action '%s' successfully forked",
550  action->pid, action->action);
551 }
552 
553 static int
554 internal_stonith_action_execute(stonith_action_t * action)
555 {
556  int rc = -EPROTO;
557  int is_retry = 0;
558  svc_action_t *svc_action = NULL;
559  static int stonith_sequence = 0;
560  char *buffer = NULL;
561 
562  CRM_CHECK(action != NULL, return -EINVAL);
563 
564  if ((action->action == NULL) || (action->args == NULL)
565  || (action->agent == NULL)) {
567  PCMK_EXEC_ERROR_FATAL, "Bug in fencing library");
568  return -EINVAL;
569  }
570 
571  if (!action->tries) {
572  action->initial_start_time = time(NULL);
573  }
574  action->tries++;
575 
576  if (action->tries > 1) {
577  crm_info("Attempt %d to execute %s (%s). remaining timeout is %d",
578  action->tries, action->agent, action->action, action->remaining_timeout);
579  is_retry = 1;
580  }
581 
582  buffer = crm_strdup_printf(PCMK__FENCE_BINDIR "/%s",
583  basename(action->agent));
584  svc_action = services_action_create_generic(buffer, NULL);
585  free(buffer);
586 
587  if (svc_action->rc != PCMK_OCF_UNKNOWN) {
588  set_result_from_svc_action(action, svc_action);
589  services_action_free(svc_action);
590  return -E2BIG;
591  }
592 
593  svc_action->timeout = 1000 * action->remaining_timeout;
594  svc_action->standard = strdup(PCMK_RESOURCE_CLASS_STONITH);
595  svc_action->id = crm_strdup_printf("%s_%s_%d", basename(action->agent),
596  action->action, action->tries);
597  svc_action->agent = strdup(action->agent);
598  svc_action->sequence = stonith_sequence++;
599  svc_action->params = action->args;
600  svc_action->cb_data = (void *) action;
601  svc_action->flags = pcmk__set_flags_as(__func__, __LINE__,
602  LOG_TRACE, "Action",
603  svc_action->id, svc_action->flags,
605  "SVC_ACTION_NON_BLOCKED");
606 
607  /* keep retries from executing out of control and free previous results */
608  if (is_retry) {
609  pcmk__reset_result(&(action->result));
610  sleep(1);
611  }
612 
613  if (action->async) {
614  // We never create a recurring action, so this should always return TRUE
616  &stonith_action_async_done,
617  &stonith_action_async_forked));
618  return pcmk_ok;
619 
620  } else if (services_action_sync(svc_action)) { // sync success
621  rc = pcmk_ok;
622 
623  } else { // sync failure
624  rc = -ECONNABORTED;
625  }
626 
627  set_result_from_svc_action(action, svc_action);
628  svc_action->params = NULL;
629  services_action_free(svc_action);
630  return rc;
631 }
632 
644 int
646  void *userdata,
647  void (*done) (int pid,
649  void *user_data),
650  void (*fork_cb) (int pid, void *user_data))
651 {
652  if (!action) {
653  return -EINVAL;
654  }
655 
656  action->userdata = userdata;
657  action->done_cb = done;
658  action->fork_cb = fork_cb;
659  action->async = 1;
660 
661  return internal_stonith_action_execute(action);
662 }
663 
672 int
674 {
675  int rc = pcmk_ok;
676 
677  CRM_CHECK(action != NULL, return -EINVAL);
678 
679  // Keep trying until success, max retries, or timeout
680  do {
681  rc = internal_stonith_action_execute(action);
682  } while ((rc != pcmk_ok) && update_remaining_timeout(action));
683 
684  return rc;
685 }
#define LOG_TRACE
Definition: logging.h:37
int rc
Exit status of action (set by library upon completion)
Definition: services.h:154
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:226
struct stonith_action_s stonith_action_t
Definition: internal.h:50
A dumping ground.
const char * pcmk_strerror(int rc)
Definition: results.c:58
No connection to executor.
Definition: results.h:316
#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:540
void stonith__xe_get_result(xmlNode *xml, pcmk__action_result_t *result)
Definition: st_actions.c:469
int pcmk_rc2legacy(int rc)
Definition: results.c:415
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)
Definition: st_actions.c:236
char * standard
Resource standard for resource actions, otherwise NULL.
Definition: services.h:137
#define crm_log_output(level, prefix, output)
Definition: logging.h:125
char * id
Definition: services.h:125
const char * services__exit_reason(svc_action_t *action)
Definition: services.c:1376
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:431
void void pcmk__set_result_output(pcmk__action_result_t *result, char *out, char *err)
Definition: results.c:883
bool pcmk_stonith_param(const char *param)
Check whether a given stonith parameter is handled by Pacemaker.
Definition: agents.c:170
enum pcmk_exec_status execution_status
svc_action_t * services_action_create_generic(const char *exec, const char *args[])
Definition: services.c:356
Unspecified error.
Definition: results.h:240
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:323
int stonith__legacy2status(int rc)
Definition: st_actions.c:379
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:319
#define CRM_LOG_ASSERT(expr)
Definition: logging.h:210
#define PCMK__VALUE_NONE
int timeout
Action timeout (in milliseconds)
Definition: services.h:145
Action did not complete in time.
Definition: results.h:310
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute.
Definition: nvpair.c:565
#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:309
No fence device is configured for target.
Definition: results.h:318
const char * action
Definition: pcmk_fence.c:29
#define FAILURE_MAX_RETRIES
Definition: st_actions.c:234
enum svc_action_flags flags
Flag group of enum svc_action_flags.
Definition: services.h:175
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:363
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
Definition: nvpair.c:726
Used only to initialize variables.
Definition: results.h:306
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:529
gboolean services_action_sync(svc_action_t *op)
Definition: services.c:1020
GHashTable * params
Definition: services.h:152
#define crm_trace(fmt, args...)
Definition: logging.h:364
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
Object for executing external actions.
Definition: services.h:121
#define F_STONITH_RC
Definition: internal.h:107
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:143
void pcmk__str_update(char **str, const char *value)
Definition: strings.c:1188
Action completed, result is known.
Definition: results.h:308
Success.
Definition: results.h:239
Execution failed, do not retry anywhere.
Definition: results.h:314
#define XML_LRM_ATTR_EXIT_REASON
Definition: msg_xml.h:321
int sequence
Definition: services.h:167
#define STONITH_ATTR_ACTION_OP
Definition: internal.h:158
#define F_STONITH_OUTPUT
Definition: internal.h:108
Requested item has expired.
Definition: results.h:278
Unspecified error.
Definition: results.h:163
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))
Definition: st_actions.c:645
#define PCMK_RESOURCE_CLASS_STONITH
Definition: services.h:45
#define ENODATA
Definition: portability.h:145
#define PCMK_STONITH_HOST_ARGUMENT
Definition: agents.h:32
Agent does not implement requested action.
Definition: results.h:311
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:34
Insufficient privileges.
Definition: results.h:245
pcmk__action_result_t * stonith__action_result(stonith_action_t *action)
Definition: st_actions.c:229
#define CRM_META
Definition: crm.h:78
int stonith__result2rc(const pcmk__action_result_t *result)
Definition: st_actions.c:305
#define CRM_ASSERT(expr)
Definition: results.h:42
int status
Execution status (enum pcmk_exec_status set by library)
Definition: services.h:162
Action is pending.
Definition: results.h:188
Fencing aka. STONITH.
#define XML_LRM_ATTR_OPSTATUS
Definition: msg_xml.h:313
Agent or dependency not available locally.
Definition: results.h:315
#define XML_LRM_ATTR_RC
Definition: msg_xml.h:314
#define pcmk_ok
Definition: results.h:68
Action is in progress.
Definition: results.h:307
int stonith__execute(stonith_action_t *action)
Definition: st_actions.c:673
xmlNode * stonith__find_xe_with_result(xmlNode *xml)
Definition: st_actions.c:448
void * cb_data
For caller&#39;s use (not used by library)
Definition: services.h:178
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:814
pcmk_exec_status
Execution status.
Definition: results.h:305
Parameter invalid (in local context)
Definition: results.h:243
Action cannot be attempted (e.g. shutdown)
Definition: results.h:317
void pcmk__reset_result(pcmk__action_result_t *result)
Definition: results.c:903
unsigned int timeout
Definition: pcmk_fence.c:31
void stonith__destroy_action(stonith_action_t *action)
Definition: st_actions.c:203
Execution failed, may be retried.
Definition: results.h:312
#define crm_info(fmt, args...)
Definition: logging.h:361
void stonith__xe_set_result(xmlNode *xml, const pcmk__action_result_t *result)
Definition: st_actions.c:409