pacemaker  3.0.0-d8340737c4
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  /* Filter out parameters handled directly by Pacemaker.
92  *
93  * STONITH_ATTR_ACTION_OP is added elsewhere and should never be part of the
94  * fencing resource's parameter list. We should ignore its value if it is
95  * configured there.
96  */
97  if (!pcmk__str_eq(key, STONITH_ATTR_ACTION_OP, pcmk__str_casei)
98  && !pcmk_stonith_param(key)
99  && (strstr(key, CRM_META) == NULL)
100  && !pcmk__str_eq(key, PCMK_XA_CRM_FEATURE_SET, pcmk__str_none)) {
101 
102  crm_trace("Passing %s=%s with fence action",
103  (const char *) key, (const char *) (value? value : ""));
104  pcmk__insert_dup((GHashTable *) user_data, key, pcmk__s(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 
147  // Tell the fence agent what action to perform
149 
150  /* If this is a fencing operation against another node, add more standard
151  * arguments.
152  */
153  if ((target != NULL) && (device_args != NULL)) {
154  const char *param = NULL;
155 
156  /* Always pass the target's name, per
157  * https://github.com/ClusterLabs/fence-agents/blob/main/doc/FenceAgentAPI.md
158  */
159  pcmk__insert_dup(arg_list, "nodename", target);
160 
161  // If the target's node ID was specified, pass it, too
162  if (target_nodeid != 0) {
163  char *nodeid = crm_strdup_printf("%" PRIu32, target_nodeid);
164 
165  // cts-fencing looks for this log message
166  crm_info("Passing '%s' as nodeid with fence action '%s' targeting %s",
167  nodeid, action, pcmk__s(target, "no node"));
168  g_hash_table_insert(arg_list, strdup("nodeid"), nodeid);
169  }
170 
171  // Check whether target should be specified as some other argument
172  param = g_hash_table_lookup(device_args, PCMK_STONITH_HOST_ARGUMENT);
173  if (param == NULL) {
174  // Use caller's default (likely from agent metadata)
175  param = host_arg;
176  }
177  if ((param != NULL)
178  && !pcmk__str_eq(agent, "fence_legacy", pcmk__str_none)
179  && !pcmk__str_eq(param, PCMK_VALUE_NONE, pcmk__str_casei)) {
180 
181  value = g_hash_table_lookup(device_args, param);
182  if (pcmk__str_eq(value, "dynamic",
184  /* If the host argument is "dynamic" or not configured,
185  * reset it to the target
186  */
187  const char *alias = NULL;
188 
189  if (port_map) {
190  alias = g_hash_table_lookup(port_map, target);
191  }
192  if (alias == NULL) {
193  alias = target;
194  }
195  crm_debug("Passing %s='%s' with fence action %s targeting %s",
196  param, alias, action, pcmk__s(target, "no node"));
197  pcmk__insert_dup(arg_list, param, alias);
198  }
199  }
200  }
201 
202  if (device_args) {
203  g_hash_table_foreach(device_args, append_config_arg, arg_list);
204  }
205 
206  return arg_list;
207 }
208 
215 void
217 {
218  if (action) {
219  free(action->agent);
220  if (action->args) {
221  g_hash_table_destroy(action->args);
222  }
223  free(action->action);
224  if (action->svc_action) {
225  services_action_free(action->svc_action);
226  }
227  pcmk__reset_result(&(action->result));
228  free(action);
229  }
230 }
231 
242 {
243  return (action == NULL)? NULL : &(action->result);
244 }
245 
246 #define FAILURE_MAX_RETRIES 2
247 
264 stonith__action_create(const char *agent, const char *action_name,
265  const char *target, uint32_t target_nodeid,
266  int timeout_sec, GHashTable *device_args,
267  GHashTable *port_map, const char *host_arg)
268 {
270 
271  action->args = make_args(agent, action_name, target, target_nodeid,
272  device_args, port_map, host_arg);
273  crm_debug("Preparing '%s' action targeting %s using agent %s",
274  action_name, pcmk__s(target, "no node"), agent);
275  action->agent = strdup(agent);
276  action->action = strdup(action_name);
277  action->timeout = action->remaining_timeout = timeout_sec;
278  action->max_retries = FAILURE_MAX_RETRIES;
279 
281  "Initialization bug in fencing library");
282 
283  if (device_args) {
284  char buffer[512];
285  const char *value = NULL;
286 
287  snprintf(buffer, sizeof(buffer), "pcmk_%s_retries", action_name);
288  value = g_hash_table_lookup(device_args, buffer);
289 
290  if (value) {
291  action->max_retries = atoi(value);
292  }
293  }
294 
295  return action;
296 }
297 
298 static gboolean
299 update_remaining_timeout(stonith_action_t * action)
300 {
301  int diff = time(NULL) - action->initial_start_time;
302 
303  if (action->tries >= action->max_retries) {
304  crm_info("Attempted to execute agent %s (%s) the maximum number of times (%d) allowed",
305  action->agent, action->action, action->max_retries);
306  action->remaining_timeout = 0;
307  } else if ((action->result.execution_status != PCMK_EXEC_TIMEOUT)
308  && (diff < (action->timeout * 0.7))) {
309  /* only set remaining timeout period if there is 30%
310  * or greater of the original timeout period left */
311  action->remaining_timeout = action->timeout - diff;
312  } else {
313  action->remaining_timeout = 0;
314  }
315  return action->remaining_timeout ? TRUE : FALSE;
316 }
317 
326 int
328 {
329  if (pcmk__result_ok(result)) {
330  return pcmk_rc_ok;
331  }
332 
333  switch (result->execution_status) {
334  case PCMK_EXEC_PENDING: return EINPROGRESS;
335  case PCMK_EXEC_CANCELLED: return ECANCELED;
336  case PCMK_EXEC_TIMEOUT: return ETIME;
337  case PCMK_EXEC_NOT_INSTALLED: return ENOENT;
338  case PCMK_EXEC_NOT_SUPPORTED: return EOPNOTSUPP;
339  case PCMK_EXEC_NOT_CONNECTED: return ENOTCONN;
340  case PCMK_EXEC_NO_FENCE_DEVICE: return ENODEV;
341  case PCMK_EXEC_NO_SECRETS: return EACCES;
342 
343  /* For the fencing API, PCMK_EXEC_INVALID is used with fencer API
344  * operations that don't involve executing an agent (for example,
345  * registering devices). This allows us to use the CRM_EX_* codes in the
346  * exit status for finer-grained responses.
347  */
348  case PCMK_EXEC_INVALID:
349  switch (result->exit_status) {
350  case CRM_EX_INVALID_PARAM: return EINVAL;
351  case CRM_EX_INSUFFICIENT_PRIV: return EACCES;
352  case CRM_EX_PROTOCOL: return EPROTO;
353 
354  /* CRM_EX_EXPIRED is used for orphaned fencing operations left
355  * over from a previous instance of the fencer. For API backward
356  * compatibility, this is mapped to the previously used code for
357  * this case, EHOSTUNREACH.
358  */
359  case CRM_EX_EXPIRED: return EHOSTUNREACH;
360  default: break;
361  }
362  break;
363 
364  default:
365  break;
366  }
367 
368  // Try to provide useful error code based on result's error output
369 
370  if (result->action_stderr == NULL) {
371  return ENODATA;
372 
373  } else if (strcasestr(result->action_stderr, "timed out")
374  || strcasestr(result->action_stderr, "timeout")) {
375  return ETIME;
376 
377  } else if (strcasestr(result->action_stderr, "unrecognised action")
378  || strcasestr(result->action_stderr, "unrecognized action")
379  || strcasestr(result->action_stderr, "unsupported action")) {
380  return EOPNOTSUPP;
381  }
382 
383  // Oh well, we tried
384  return pcmk_rc_error;
385 }
386 
400 int
402 {
403  if (rc >= 0) {
404  return PCMK_EXEC_DONE;
405  }
406  switch (-rc) {
407  case EACCES: return PCMK_EXEC_NO_SECRETS;
408  case ECANCELED: return PCMK_EXEC_CANCELLED;
409  case EHOSTUNREACH: return PCMK_EXEC_INVALID;
410  case EINPROGRESS: return PCMK_EXEC_PENDING;
411  case ENODEV: return PCMK_EXEC_NO_FENCE_DEVICE;
412  case ENOENT: return PCMK_EXEC_NOT_INSTALLED;
413  case ENOTCONN: return PCMK_EXEC_NOT_CONNECTED;
414  case EOPNOTSUPP: return PCMK_EXEC_NOT_SUPPORTED;
415  case EPROTO: return PCMK_EXEC_INVALID;
416  case EPROTONOSUPPORT: return PCMK_EXEC_NOT_SUPPORTED;
417  case ETIME: return PCMK_EXEC_TIMEOUT;
418  case ETIMEDOUT: return PCMK_EXEC_TIMEOUT;
419  default: return PCMK_EXEC_ERROR;
420  }
421 }
422 
430 void
432 {
433  int exit_status = CRM_EX_OK;
434  enum pcmk_exec_status execution_status = PCMK_EXEC_DONE;
435  const char *exit_reason = NULL;
436  const char *action_stdout = NULL;
437  int rc = pcmk_ok;
438 
439  CRM_CHECK(xml != NULL, return);
440 
441  if (result != NULL) {
442  exit_status = result->exit_status;
443  execution_status = result->execution_status;
444  exit_reason = result->exit_reason;
445  action_stdout = result->action_stdout;
447  }
448 
449  crm_xml_add_int(xml, PCMK__XA_OP_STATUS, (int) execution_status);
450  crm_xml_add_int(xml, PCMK__XA_RC_CODE, exit_status);
451  crm_xml_add(xml, PCMK_XA_EXIT_REASON, exit_reason);
452  crm_xml_add(xml, PCMK__XA_ST_OUTPUT, action_stdout);
453 
454  /* @COMPAT Peers in rolling upgrades, Pacemaker Remote nodes, and external
455  * code that use libstonithd <=2.1.2 don't check for the full result, and
456  * need a legacy return code instead.
457  */
459 }
460 
469 xmlNode *
471 {
472  xmlNode *match = get_xpath_object("//@" PCMK__XA_RC_CODE, xml, LOG_NEVER);
473 
474  if (match == NULL) {
475  /* @COMPAT Peers <=2.1.2 in a rolling upgrade provide only a legacy
476  * return code, not a full result, so check for that.
477  */
478  match = get_xpath_object("//@" PCMK__XA_ST_RC, xml, LOG_ERR);
479  }
480  return match;
481 }
482 
490 void
492 {
493  int exit_status = CRM_EX_OK;
494  int execution_status = PCMK_EXEC_DONE;
495  const char *exit_reason = NULL;
496  char *action_stdout = NULL;
497 
498  CRM_CHECK((xml != NULL) && (result != NULL), return);
499 
500  exit_reason = crm_element_value(xml, PCMK_XA_EXIT_REASON);
501  action_stdout = crm_element_value_copy(xml, PCMK__XA_ST_OUTPUT);
502 
503  // A result must include an exit status and execution status
504  if ((crm_element_value_int(xml, PCMK__XA_RC_CODE, &exit_status) < 0)
506  &execution_status) < 0)) {
507  int rc = pcmk_ok;
508  exit_status = CRM_EX_ERROR;
509 
510  /* @COMPAT Peers <=2.1.2 in rolling upgrades provide only a legacy
511  * return code, not a full result, so check for that.
512  */
513  if (crm_element_value_int(xml, PCMK__XA_ST_RC, &rc) == 0) {
514  if ((rc == pcmk_ok) || (rc == -EINPROGRESS)) {
515  exit_status = CRM_EX_OK;
516  }
517  execution_status = stonith__legacy2status(rc);
518  exit_reason = pcmk_strerror(rc);
519 
520  } else {
521  execution_status = PCMK_EXEC_ERROR;
522  exit_reason = "Fencer reply contained neither a full result "
523  "nor a legacy return code (bug?)";
524  }
525  }
526  pcmk__set_result(result, exit_status, execution_status, exit_reason);
527  pcmk__set_result_output(result, action_stdout, NULL);
528 }
529 
530 static void
531 stonith_action_async_done(svc_action_t *svc_action)
532 {
533  stonith_action_t *action = (stonith_action_t *) svc_action->cb_data;
534 
535  set_result_from_svc_action(action, svc_action);
536  svc_action->params = NULL;
537  log_action(action, action->pid);
538 
539  if (!pcmk__result_ok(&(action->result))
540  && update_remaining_timeout(action)) {
541 
542  int rc = internal_stonith_action_execute(action);
543  if (rc == pcmk_ok) {
544  return;
545  }
546  }
547 
548  if (action->done_cb) {
549  action->done_cb(action->pid, &(action->result), action->userdata);
550  }
551 
552  action->svc_action = NULL; // don't remove our caller
554 }
555 
556 static void
557 stonith_action_async_forked(svc_action_t *svc_action)
558 {
559  stonith_action_t *action = (stonith_action_t *) svc_action->cb_data;
560 
561  action->pid = svc_action->pid;
562  action->svc_action = svc_action;
563 
564  if (action->fork_cb) {
565  (action->fork_cb) (svc_action->pid, action->userdata);
566  }
567 
569  NULL);
570 
571  crm_trace("Child process %d performing action '%s' successfully forked",
572  action->pid, action->action);
573 }
574 
575 static int
576 internal_stonith_action_execute(stonith_action_t * action)
577 {
578  int rc = -EPROTO;
579  int is_retry = 0;
580  svc_action_t *svc_action = NULL;
581  static int stonith_sequence = 0;
582  char *buffer = NULL;
583 
584  CRM_CHECK(action != NULL, return -EINVAL);
585 
586  if ((action->action == NULL) || (action->args == NULL)
587  || (action->agent == NULL)) {
589  PCMK_EXEC_ERROR_FATAL, "Bug in fencing library");
590  return -EINVAL;
591  }
592 
593  if (!action->tries) {
594  action->initial_start_time = time(NULL);
595  }
596  action->tries++;
597 
598  if (action->tries > 1) {
599  crm_info("Attempt %d to execute %s (%s). remaining timeout is %d",
600  action->tries, action->agent, action->action, action->remaining_timeout);
601  is_retry = 1;
602  }
603 
604  buffer = crm_strdup_printf(PCMK__FENCE_BINDIR "/%s",
605  basename(action->agent));
606  svc_action = services_action_create_generic(buffer, NULL);
607  free(buffer);
608 
609  if (svc_action->rc != PCMK_OCF_UNKNOWN) {
610  set_result_from_svc_action(action, svc_action);
611  services_action_free(svc_action);
612  return -E2BIG;
613  }
614 
615  svc_action->timeout = 1000 * action->remaining_timeout;
616  svc_action->standard = strdup(PCMK_RESOURCE_CLASS_STONITH);
617  svc_action->id = crm_strdup_printf("%s_%s_%dof%d", basename(action->agent),
618  action->action, action->tries,
619  action->max_retries);
620  svc_action->agent = strdup(action->agent);
621  svc_action->sequence = stonith_sequence++;
622  svc_action->params = action->args;
623  svc_action->cb_data = (void *) action;
624  svc_action->flags = pcmk__set_flags_as(__func__, __LINE__,
625  LOG_TRACE, "Action",
626  svc_action->id, svc_action->flags,
628  "SVC_ACTION_NON_BLOCKED");
629 
630  /* keep retries from executing out of control and free previous results */
631  if (is_retry) {
632  pcmk__reset_result(&(action->result));
633  sleep(1);
634  }
635 
636  if (action->async) {
637  // We never create a recurring action, so this should always return TRUE
639  &stonith_action_async_done,
640  &stonith_action_async_forked));
641  return pcmk_ok;
642 
643  } else if (services_action_sync(svc_action)) { // sync success
644  rc = pcmk_ok;
645 
646  } else { // sync failure
647  rc = -ECONNABORTED;
648  }
649 
650  set_result_from_svc_action(action, svc_action);
651  svc_action->params = NULL;
652  services_action_free(svc_action);
653  return rc;
654 }
655 
667 int
669  void (*done) (int pid,
671  void *user_data),
672  void (*fork_cb) (int pid, void *user_data))
673 {
674  if (!action) {
675  return -EINVAL;
676  }
677 
678  action->userdata = userdata;
679  action->done_cb = done;
680  action->fork_cb = fork_cb;
681  action->async = true;
682 
683  return internal_stonith_action_execute(action);
684 }
685 
694 int
696 {
697  int rc = pcmk_ok;
698 
699  CRM_CHECK(action != NULL, return -EINVAL);
700 
701  // Keep trying until success, max retries, or timeout
702  do {
703  rc = internal_stonith_action_execute(action);
704  } while ((rc != pcmk_ok) && update_remaining_timeout(action));
705 
706  return rc;
707 }
#define LOG_TRACE
Definition: logging.h:38
int rc
Exit status of action (set by library upon completion)
Definition: services.h:132
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:213
struct stonith_action_s stonith_action_t
Definition: internal.h:56
A dumping ground.
const char * pcmk_strerror(int rc)
Definition: results.c:257
No connection to executor.
Definition: results.h:317
#define ETIME
Definition: portability.h:66
void services_action_free(svc_action_t *op)
Definition: services.c:565
#define PCMK__FENCE_BINDIR
Definition: config.h:496
int pcmk_rc2legacy(int rc)
Definition: results.c:654
char * standard
Resource standard for resource actions, otherwise NULL.
Definition: services.h:115
#define PCMK__XA_RC_CODE
void stonith__xe_get_result(const xmlNode *xml, pcmk__action_result_t *result)
Definition: st_actions.c:491
#define PCMK__XA_ST_OUTPUT
#define crm_log_output(level, prefix, output)
Definition: logging.h:83
char * id
Definition: services.h:103
void void pcmk__set_result_output(pcmk__action_result_t *result, char *out, char *err)
Definition: results.c:1143
bool pcmk_stonith_param(const char *param)
Check whether a given stonith parameter is handled by Pacemaker.
Definition: agents.c:166
#define PCMK_XA_EXIT_REASON
Definition: xml_names.h:274
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:349
Unspecified error.
Definition: results.h:232
int stonith__legacy2status(int rc)
Definition: st_actions.c:401
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:840
Necessary CIB secrets are unavailable.
Definition: results.h:320
#define CRM_LOG_ASSERT(expr)
Definition: logging.h:196
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:264
int timeout
Action timeout (in milliseconds)
Definition: services.h:123
Action did not complete in time.
Definition: results.h:311
#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:310
No fence device is configured for target.
Definition: results.h:319
const char * action
Definition: pcmk_fence.c:32
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
Definition: xml_element.c:1015
#define FAILURE_MAX_RETRIES
Definition: st_actions.c:246
enum svc_action_flags flags
Flag group of enum svc_action_flags.
Definition: services.h:153
Protocol violated.
Definition: results.h:257
char * services__grab_stderr(svc_action_t *action)
Definition: services.c:1352
uint32_t pid
Definition: cpg.c:49
#define crm_debug(fmt, args...)
Definition: logging.h:370
const char * services__exit_reason(const svc_action_t *action)
Definition: services.c:1317
Used only to initialize variables.
Definition: results.h:307
gboolean services_action_sync(svc_action_t *op)
Definition: services.c:990
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
Definition: xml_element.c:1466
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: xml_element.c:1168
#define PCMK_VALUE_NONE
Definition: options.h:179
GHashTable * params
Definition: services.h:130
#define crm_trace(fmt, args...)
Definition: logging.h:372
#define PCMK_RESOURCE_CLASS_STONITH
Definition: agents.h:31
Object for executing external actions.
Definition: services.h:99
char * services__grab_stdout(svc_action_t *action)
Definition: services.c:1333
char * agent
Resource agent name for resource actions, otherwise NULL.
Definition: services.h:121
Wrappers for and extensions to libxml2.
Action completed, result is known.
Definition: results.h:309
Success.
Definition: results.h:231
Execution failed, do not retry anywhere.
Definition: results.h:315
int sequence
Definition: services.h:145
#define STONITH_ATTR_ACTION_OP
Definition: internal.h:114
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:668
Requested item has expired.
Definition: results.h:272
Unspecified error.
Definition: results.h:177
const char * target
Definition: pcmk_fence.c:31
#define PCMK_XA_CRM_FEATURE_SET
Definition: xml_names.h:254
#define ENODATA
Definition: portability.h:61
#define PCMK_STONITH_HOST_ARGUMENT
Definition: agents.h:40
Agent does not implement requested action.
Definition: results.h:312
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
Definition: strings.c:685
pcmk__action_result_t result
Definition: pcmk_fence.c:37
Insufficient privileges.
Definition: results.h:237
pcmk__action_result_t * stonith__action_result(stonith_action_t *action)
Definition: st_actions.c:241
#define CRM_META
Definition: crm.h:75
int stonith__result2rc(const pcmk__action_result_t *result)
Definition: st_actions.c:327
int status
Execution status (enum pcmk_exec_status set by library)
Definition: services.h:140
Action is pending.
Definition: results.h:199
Fencing aka. STONITH.
#define PCMK__XA_OP_STATUS
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute.
Definition: xml_element.c:1201
Agent or dependency not available locally.
Definition: results.h:316
#define pcmk_ok
Definition: results.h:65
Action is in progress.
Definition: results.h:308
int stonith__execute(stonith_action_t *action)
Definition: st_actions.c:695
xmlNode * stonith__find_xe_with_result(xmlNode *xml)
Definition: st_actions.c:470
void * cb_data
For caller&#39;s use (not used by library)
Definition: services.h:156
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:1074
pcmk_exec_status
Execution status.
Definition: results.h:306
Parameter invalid (in local context)
Definition: results.h:235
Action cannot be attempted (e.g. shutdown)
Definition: results.h:318
#define PCMK__XA_ST_RC
#define pcmk__assert_alloc(nmemb, size)
Definition: internal.h:257
void pcmk__reset_result(pcmk__action_result_t *result)
Definition: results.c:1163
unsigned int timeout
Definition: pcmk_fence.c:34
void stonith__destroy_action(stonith_action_t *action)
Definition: st_actions.c:216
Execution failed, may be retried.
Definition: results.h:313
#define crm_info(fmt, args...)
Definition: logging.h:367
void pcmk__insert_dup(GHashTable *table, const char *name, const char *value)
Definition: strings.c:703
void stonith__xe_set_result(xmlNode *xml, const pcmk__action_result_t *result)
Definition: st_actions.c:431
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
Definition: xml_element.c:1070