pacemaker  2.1.5-b7adf64e51
Scalable High-Availability cluster resource manager
pcmk_fence.c
Go to the documentation of this file.
1 /*
2  * Copyright 2009-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 General Public License version 2
7  * or later (GPLv2+) WITHOUT ANY WARRANTY.
8  */
9 
10 #include <crm_internal.h>
11 #include <crm/common/mainloop.h>
12 #include <crm/common/results.h>
13 #include <crm/common/output.h>
15 #include <crm/stonith-ng.h>
16 #include <crm/fencing/internal.h>
17 
18 #include <glib.h>
19 #include <libxml/tree.h>
20 #include <pacemaker.h>
21 #include <pacemaker-internal.h>
22 
23 static const int st_opts = st_opt_sync_call | st_opt_allow_suicide;
24 
25 static GMainLoop *mainloop = NULL;
26 
27 static struct {
29  const char *target;
30  const char *action;
31  char *name;
32  unsigned int timeout;
33  unsigned int tolerance;
34  int delay;
36 } async_fence_data = { NULL, };
37 
38 static int
39 handle_level(stonith_t *st, char *target, int fence_level,
40  stonith_key_value_t *devices, bool added) {
41  char *node = NULL;
42  char *pattern = NULL;
43  char *name = NULL;
44  char *value = NULL;
45  int rc = pcmk_rc_ok;
46 
47  if (target == NULL) {
48  // Not really possible, but makes static analysis happy
49  return EINVAL;
50  }
51 
52  /* Determine if targeting by attribute, node name pattern or node name */
53  value = strchr(target, '=');
54  if (value != NULL) {
55  name = target;
56  *value++ = '\0';
57  } else if (*target == '@') {
58  pattern = target + 1;
59  } else {
60  node = target;
61  }
62 
63  /* Register or unregister level as appropriate */
64  if (added) {
65  rc = st->cmds->register_level_full(st, st_opts, node, pattern,
66  name, value, fence_level,
67  devices);
68  } else {
69  rc = st->cmds->remove_level_full(st, st_opts, node, pattern,
70  name, value, fence_level);
71  }
72 
73  return pcmk_legacy2rc(rc);
74 }
75 
76 static stonith_history_t *
77 reduce_fence_history(stonith_history_t *history)
78 {
79  stonith_history_t *new, *hp, *np;
80 
81  if (!history) {
82  return history;
83  }
84 
85  new = history;
86  hp = new->next;
87  new->next = NULL;
88 
89  while (hp) {
90  stonith_history_t *hp_next = hp->next;
91 
92  hp->next = NULL;
93 
94  for (np = new; ; np = np->next) {
95  if ((hp->state == st_done) || (hp->state == st_failed)) {
96  /* action not in progress */
97  if (pcmk__str_eq(hp->target, np->target, pcmk__str_casei) &&
98  pcmk__str_eq(hp->action, np->action, pcmk__str_none) &&
99  (hp->state == np->state) &&
100  ((hp->state == st_done) ||
101  pcmk__str_eq(hp->delegate, np->delegate, pcmk__str_casei))) {
102  /* purge older hp */
104  break;
105  }
106  }
107 
108  if (!np->next) {
109  np->next = hp;
110  break;
111  }
112  }
113  hp = hp_next;
114  }
115 
116  return new;
117 }
118 
119 static void
120 notify_callback(stonith_t * st, stonith_event_t * e)
121 {
122  if (pcmk__str_eq(async_fence_data.target, e->target, pcmk__str_casei)
123  && pcmk__str_eq(async_fence_data.action, e->action, pcmk__str_none)) {
124 
125  pcmk__set_result(&async_fence_data.result,
129  g_main_loop_quit(mainloop);
130  }
131 }
132 
133 static void
134 fence_callback(stonith_t * stonith, stonith_callback_data_t * data)
135 {
136  pcmk__set_result(&async_fence_data.result, stonith__exit_status(data),
139  g_main_loop_quit(mainloop);
140 }
141 
142 static gboolean
143 async_fence_helper(gpointer user_data)
144 {
145  stonith_t *st = async_fence_data.st;
146  int call_id = 0;
147  int rc = stonith_api_connect_retry(st, async_fence_data.name, 10);
148 
149  if (rc != pcmk_ok) {
150  g_main_loop_quit(mainloop);
151  pcmk__set_result(&async_fence_data.result, CRM_EX_ERROR,
153  return TRUE;
154  }
155 
157 
158  call_id = st->cmds->fence_with_delay(st,
160  async_fence_data.target,
161  async_fence_data.action,
162  async_fence_data.timeout/1000,
163  async_fence_data.tolerance/1000,
164  async_fence_data.delay);
165 
166  if (call_id < 0) {
167  g_main_loop_quit(mainloop);
168  pcmk__set_result(&async_fence_data.result, CRM_EX_ERROR,
169  PCMK_EXEC_ERROR, pcmk_strerror(call_id));
170  return TRUE;
171  }
172 
174  call_id,
175  async_fence_data.timeout/1000,
176  st_opt_timeout_updates, NULL, "callback", fence_callback);
177 
178  return TRUE;
179 }
180 
181 int
182 pcmk__request_fencing(stonith_t *st, const char *target, const char *action,
183  const char *name, unsigned int timeout,
184  unsigned int tolerance, int delay, char **reason)
185 {
186  crm_trigger_t *trig;
187  int rc = pcmk_rc_ok;
188 
189  async_fence_data.st = st;
190  async_fence_data.name = strdup(name);
191  async_fence_data.target = target;
192  async_fence_data.action = action;
193  async_fence_data.timeout = timeout;
194  async_fence_data.tolerance = tolerance;
195  async_fence_data.delay = delay;
196  pcmk__set_result(&async_fence_data.result, CRM_EX_ERROR, PCMK_EXEC_UNKNOWN,
197  NULL);
198 
199  trig = mainloop_add_trigger(G_PRIORITY_HIGH, async_fence_helper, NULL);
200  mainloop_set_trigger(trig);
201 
202  mainloop = g_main_loop_new(NULL, FALSE);
203  g_main_loop_run(mainloop);
204 
205  free(async_fence_data.name);
206 
207  if (reason != NULL) {
208  // Give the caller ownership of the exit reason
209  *reason = async_fence_data.result.exit_reason;
210  async_fence_data.result.exit_reason = NULL;
211  }
212  rc = stonith__result2rc(&async_fence_data.result);
213  pcmk__reset_result(&async_fence_data.result);
214  return rc;
215 }
216 
217 #ifdef BUILD_PUBLIC_LIBPACEMAKER
218 int
219 pcmk_request_fencing(stonith_t *st, const char *target, const char *action,
220  const char *name, unsigned int timeout,
221  unsigned int tolerance, int delay, char **reason)
222 {
224  delay, reason);
225 }
226 #endif
227 
228 int
230  unsigned int timeout, int verbose, bool broadcast,
231  bool cleanup) {
232  stonith_history_t *history = NULL, *hp, *latest = NULL;
233  int rc = pcmk_rc_ok;
234  int opts = 0;
235 
236  if (cleanup) {
237  out->info(out, "cleaning up fencing-history%s%s",
238  target ? " for node " : "", target ? target : "");
239  }
240  if (broadcast) {
241  out->info(out, "gather fencing-history from all nodes");
242  }
243 
244  stonith__set_call_options(opts, target, st_opts);
245  if (cleanup) {
247  }
248  if (broadcast) {
250  }
251  rc = st->cmds->history(st, opts,
252  pcmk__str_eq(target, "*", pcmk__str_none)? NULL : target,
253  &history, timeout/1000);
254 
255  if (cleanup) {
256  // Cleanup doesn't return a history list
257  stonith_history_free(history);
258  return pcmk_legacy2rc(rc);
259  }
260 
261  out->begin_list(out, "event", "events", "Fencing history");
262 
263  history = stonith__sort_history(history);
264  for (hp = history; hp; hp = hp->next) {
265  if (hp->state == st_done) {
266  latest = hp;
267  }
268 
269  if (out->is_quiet(out) || !verbose) {
270  continue;
271  }
272 
273  out->message(out, "stonith-event", hp, true, false,
274  stonith__later_succeeded(hp, history),
275  (uint32_t) pcmk_show_failed_detail);
276  out->increment_list(out);
277  }
278 
279  if (latest) {
280  if (out->is_quiet(out)) {
281  out->message(out, "stonith-event", latest, false, true, NULL,
282  (uint32_t) pcmk_show_failed_detail);
283  } else if (!verbose) { // already printed if verbose
284  out->message(out, "stonith-event", latest, false, false, NULL,
285  (uint32_t) pcmk_show_failed_detail);
286  out->increment_list(out);
287  }
288  }
289 
290  out->end_list(out);
291 
292  stonith_history_free(history);
293  return pcmk_legacy2rc(rc);
294 }
295 
296 #ifdef BUILD_PUBLIC_LIBPACEMAKER
297 int
298 pcmk_fence_history(xmlNodePtr *xml, stonith_t *st, char *target, unsigned int timeout,
299  bool quiet, int verbose, bool broadcast, bool cleanup) {
300  pcmk__output_t *out = NULL;
301  int rc = pcmk_rc_ok;
302 
303  rc = pcmk__xml_output_new(&out, xml);
304  if (rc != pcmk_rc_ok) {
305  return rc;
306  }
307 
309 
310  out->quiet = quiet;
311 
312  rc = pcmk__fence_history(out, st, target, timeout, verbose, broadcast, cleanup);
313  pcmk__xml_output_finish(out, xml);
314  return rc;
315 }
316 #endif
317 
318 int
320  stonith_key_value_t *devices = NULL;
321  int rc = pcmk_rc_ok;
322 
323  rc = st->cmds->list_agents(st, st_opt_sync_call, NULL, &devices, timeout/1000);
324  /* list_agents returns a negative error code or a positive number of agents. */
325  if (rc < 0) {
326  return pcmk_legacy2rc(rc);
327  }
328 
329  out->begin_list(out, "fence device", "fence devices", "Installed fence devices");
330  for (stonith_key_value_t *dIter = devices; dIter; dIter = dIter->next) {
331  out->list_item(out, "device", "%s", dIter->value);
332  }
333  out->end_list(out);
334 
335  stonith_key_value_freeall(devices, 1, 1);
336  return pcmk_rc_ok;
337 }
338 
339 #ifdef BUILD_PUBLIC_LIBPACEMAKER
340 int
341 pcmk_fence_installed(xmlNodePtr *xml, stonith_t *st, unsigned int timeout) {
342  pcmk__output_t *out = NULL;
343  int rc = pcmk_rc_ok;
344 
345  rc = pcmk__xml_output_new(&out, xml);
346  if (rc != pcmk_rc_ok) {
347  return rc;
348  }
349 
351 
352  rc = pcmk__fence_installed(out, st, timeout);
353  pcmk__xml_output_finish(out, xml);
354  return rc;
355 }
356 #endif
357 
358 int
359 pcmk__fence_last(pcmk__output_t *out, const char *target, bool as_nodeid) {
360  time_t when = 0;
361 
362  if (target == NULL) {
363  return pcmk_rc_ok;
364  }
365 
366  if (as_nodeid) {
367  when = stonith_api_time(atol(target), NULL, FALSE);
368  } else {
369  when = stonith_api_time(0, target, FALSE);
370  }
371 
372  return out->message(out, "last-fenced", target, when);
373 }
374 
375 #ifdef BUILD_PUBLIC_LIBPACEMAKER
376 int
377 pcmk_fence_last(xmlNodePtr *xml, const char *target, bool as_nodeid) {
378  pcmk__output_t *out = NULL;
379  int rc = pcmk_rc_ok;
380 
381  rc = pcmk__xml_output_new(&out, xml);
382  if (rc != pcmk_rc_ok) {
383  return rc;
384  }
385 
387 
388  rc = pcmk__fence_last(out, target, as_nodeid);
389  pcmk__xml_output_finish(out, xml);
390  return rc;
391 }
392 #endif
393 
394 int
396  const char *device_id, unsigned int timeout) {
397  GList *targets = NULL;
398  char *lists = NULL;
399  int rc = pcmk_rc_ok;
400 
401  rc = st->cmds->list(st, st_opts, device_id, &lists, timeout/1000);
402  if (rc != pcmk_rc_ok) {
403  return pcmk_legacy2rc(rc);
404  }
405 
406  targets = stonith__parse_targets(lists);
407 
408  out->begin_list(out, "fence target", "fence targets", "Fence Targets");
409  while (targets != NULL) {
410  out->list_item(out, NULL, "%s", (const char *) targets->data);
411  targets = targets->next;
412  }
413  out->end_list(out);
414 
415  free(lists);
416  return rc;
417 }
418 
419 #ifdef BUILD_PUBLIC_LIBPACEMAKER
420 int
421 pcmk_fence_list_targets(xmlNodePtr *xml, stonith_t *st, const char *device_id,
422  unsigned int timeout) {
423  pcmk__output_t *out = NULL;
424  int rc = pcmk_rc_ok;
425 
426  rc = pcmk__xml_output_new(&out, xml);
427  if (rc != pcmk_rc_ok) {
428  return rc;
429  }
430 
432 
433  rc = pcmk__fence_list_targets(out, st, device_id, timeout);
434  pcmk__xml_output_finish(out, xml);
435  return rc;
436 }
437 #endif
438 
439 int
441  unsigned int timeout) {
442  char *buffer = NULL;
443  int rc = st->cmds->metadata(st, st_opt_sync_call, agent, NULL, &buffer,
444  timeout/1000);
445 
446  if (rc != pcmk_rc_ok) {
447  return pcmk_legacy2rc(rc);
448  }
449 
450  out->output_xml(out, "metadata", buffer);
451  free(buffer);
452  return rc;
453 }
454 
455 #ifdef BUILD_PUBLIC_LIBPACEMAKER
456 int
457 pcmk_fence_metadata(xmlNodePtr *xml, stonith_t *st, char *agent,
458  unsigned int timeout) {
459  pcmk__output_t *out = NULL;
460  int rc = pcmk_rc_ok;
461 
462  rc = pcmk__xml_output_new(&out, xml);
463  if (rc != pcmk_rc_ok) {
464  return rc;
465  }
466 
468 
469  rc = pcmk__fence_metadata(out, st, agent, timeout);
470  pcmk__xml_output_finish(out, xml);
471  return rc;
472 }
473 #endif
474 
475 int
477  unsigned int timeout) {
478  stonith_key_value_t *devices = NULL;
479  int rc = pcmk_rc_ok;
480 
481  rc = st->cmds->query(st, st_opts, target, &devices, timeout/1000);
482  /* query returns a negative error code or a positive number of results. */
483  if (rc < 0) {
484  return pcmk_legacy2rc(rc);
485  }
486 
487  out->begin_list(out, "fence device", "fence devices", "Registered fence devices");
488  for (stonith_key_value_t *dIter = devices; dIter; dIter = dIter->next) {
489  out->list_item(out, "device", "%s", dIter->value);
490  }
491  out->end_list(out);
492 
493  stonith_key_value_freeall(devices, 1, 1);
494 
495  /* Return pcmk_rc_ok here, not the number of results. Callers probably
496  * don't care.
497  */
498  return pcmk_rc_ok;
499 }
500 
501 #ifdef BUILD_PUBLIC_LIBPACEMAKER
502 int
503 pcmk_fence_registered(xmlNodePtr *xml, stonith_t *st, char *target,
504  unsigned int timeout) {
505  pcmk__output_t *out = NULL;
506  int rc = pcmk_rc_ok;
507 
508  rc = pcmk__xml_output_new(&out, xml);
509  if (rc != pcmk_rc_ok) {
510  return rc;
511  }
512 
514 
516  pcmk__xml_output_finish(out, xml);
517  return rc;
518 }
519 #endif
520 
521 int
523  stonith_key_value_t *devices) {
524  return handle_level(st, target, fence_level, devices, true);
525 }
526 
527 #ifdef BUILD_PUBLIC_LIBPACEMAKER
528 int
529 pcmk_fence_register_level(stonith_t *st, char *target, int fence_level,
530  stonith_key_value_t *devices) {
531  return pcmk__fence_register_level(st, target, fence_level, devices);
532 }
533 #endif
534 
535 int
536 pcmk__fence_unregister_level(stonith_t *st, char *target, int fence_level) {
537  return handle_level(st, target, fence_level, NULL, false);
538 }
539 
540 #ifdef BUILD_PUBLIC_LIBPACEMAKER
541 int
542 pcmk_fence_unregister_level(stonith_t *st, char *target, int fence_level) {
543  return pcmk__fence_unregister_level(st, target, fence_level);
544 }
545 #endif
546 
547 int
549  const char *id, stonith_key_value_t *params,
550  unsigned int timeout) {
551  char *output = NULL;
552  char *error_output = NULL;
553  int rc;
554 
555  rc = st->cmds->validate(st, st_opt_sync_call, id, NULL, agent, params,
556  timeout/1000, &output, &error_output);
557  out->message(out, "validate", agent, id, output, error_output, rc);
558  return pcmk_legacy2rc(rc);
559 }
560 
561 #ifdef BUILD_PUBLIC_LIBPACEMAKER
562 int
563 pcmk_fence_validate(xmlNodePtr *xml, stonith_t *st, const char *agent,
564  const char *id, stonith_key_value_t *params,
565  unsigned int timeout) {
566  pcmk__output_t *out = NULL;
567  int rc = pcmk_rc_ok;
568 
569  rc = pcmk__xml_output_new(&out, xml);
570  if (rc != pcmk_rc_ok) {
571  return rc;
572  }
573 
575 
576  rc = pcmk__fence_validate(out, st, agent, id, params, timeout);
577  pcmk__xml_output_finish(out, xml);
578  return rc;
579 }
580 #endif
581 
582 int
584  enum pcmk__fence_history fence_history)
585 {
586  int rc = pcmk_rc_ok;
587 
588  if (st == NULL) {
589  rc = ENOTCONN;
590  } else if (fence_history != pcmk__fence_history_none) {
591  rc = st->cmds->history(st, st_opt_sync_call, NULL, stonith_history, 120);
592 
593  rc = pcmk_legacy2rc(rc);
594  if (rc != pcmk_rc_ok) {
595  return rc;
596  }
597 
598  *stonith_history = stonith__sort_history(*stonith_history);
599  if (fence_history == pcmk__fence_history_reduced) {
600  *stonith_history = reduce_fence_history(*stonith_history);
601  }
602  }
603 
604  return rc;
605 }
void(* end_list)(pcmk__output_t *out)
int(* fence_with_delay)(stonith_t *stonith, int call_options, const char *node, const char *action, int timeout, int tolerance, int delay)
Request delayed fencing of a target.
Definition: stonith-ng.h:542
struct stonith_history_s * next
Definition: stonith-ng.h:112
const char * pcmk_strerror(int rc)
Definition: results.c:148
No connection to executor.
Definition: results.h:320
int pcmk__fence_last(pcmk__output_t *out, const char *target, bool as_nodeid)
When was a device last fenced?
Definition: pcmk_fence.c:359
char data[0]
Definition: cpg.c:55
Control output from tools.
void stonith__register_messages(pcmk__output_t *out)
Definition: st_output.c:578
int(* list_agents)(stonith_t *stonith, int call_options, const char *namespace, stonith_key_value_t **devices, int timeout)
Retrieve a list of installed fence agents.
Definition: stonith-ng.h:279
int stonith__event_exit_status(stonith_event_t *event)
Definition: st_client.c:2567
int(* message)(pcmk__output_t *out, const char *message_id,...)
pcmk__fence_history
Control how much of the fencing history is output.
Definition: pcmki_fence.h:18
const char * stonith__later_succeeded(stonith_history_t *event, stonith_history_t *top_history)
Definition: st_client.c:2248
int pcmk__fence_history(pcmk__output_t *out, stonith_t *st, char *target, unsigned int timeout, int verbose, bool broadcast, bool cleanup)
List the fencing operations that have occurred for a specific node.
Definition: pcmk_fence.c:229
int(* register_level_full)(stonith_t *st, int options, const char *node, const char *pattern, const char *attr, const char *value, int level, const stonith_key_value_t *device_list)
Register fencing level for specified node, pattern or attribute.
Definition: stonith-ng.h:494
bool(* is_quiet)(pcmk__output_t *out)
stonith_history_t * stonith__sort_history(stonith_history_t *history)
Definition: st_client.c:2287
int(* register_callback)(stonith_t *stonith, int call_id, int timeout, int options, void *user_data, const char *callback_name, void(*callback)(stonith_t *st, stonith_callback_data_t *data))
Register a callback for an asynchronous fencing result.
Definition: stonith-ng.h:428
struct stonith_key_value_s * next
Definition: stonith-ng.h:101
int stonith__result2rc(const pcmk__action_result_t *result)
Definition: st_actions.c:330
Unspecified error.
Definition: results.h:235
void mainloop_set_trigger(crm_trigger_t *source)
Definition: mainloop.c:200
int(* register_notification)(stonith_t *stonith, const char *event, void(*callback)(stonith_t *st, stonith_event_t *e))
Register a callback for fence notifications.
Definition: stonith-ng.h:397
High Level API.
int(*) void(*) void(* output_xml)(pcmk__output_t *out, const char *name, const char *buf)
int(* info)(pcmk__output_t *out, const char *format,...) G_GNUC_PRINTF(2
Wrappers for and extensions to glib mainloop.
const char * action
Definition: pcmk_fence.c:30
int stonith_api_connect_retry(stonith_t *st, const char *name, int max_attempts)
Make a blocking connection attempt to the fencer.
Definition: st_client.c:1894
struct trigger_s crm_trigger_t
Definition: mainloop.h:32
GList * stonith__parse_targets(const char *hosts)
Definition: st_client.c:2204
int(* validate)(stonith_t *st, int call_options, const char *rsc_id, const char *namespace_s, const char *agent, const stonith_key_value_t *params, int timeout, char **output, char **error_output)
Validate an arbitrary stonith device configuration.
Definition: stonith-ng.h:519
const char * stonith__exit_reason(stonith_callback_data_t *data)
Definition: st_client.c:2550
Formatted output for pacemaker tools.
stonith_t * st
Definition: pcmk_fence.c:28
int pcmk__fence_installed(pcmk__output_t *out, stonith_t *st, unsigned int timeout)
List all installed STONITH agents.
Definition: pcmk_fence.c:319
unsigned int tolerance
Definition: pcmk_fence.c:33
Used only to initialize variables.
Definition: results.h:310
int pcmk__xml_output_new(pcmk__output_t **out, xmlNodePtr *xml)
Definition: output.c:201
bool quiet
Should this formatter supress most output?
#define stonith__set_call_options(st_call_opts, call_for, flags_to_set)
Definition: internal.h:36
const char * stonith__event_exit_reason(stonith_event_t *event)
Definition: st_client.c:2607
crm_trigger_t * mainloop_add_trigger(int priority, int(*dispatch)(gpointer user_data), gpointer userdata)
Create a trigger to be used as a mainloop source.
Definition: mainloop.c:187
int pcmk__fence_unregister_level(stonith_t *st, char *target, int fence_level)
Unregister a fencing level for a specific node, node regex, or attribute.
Definition: pcmk_fence.c:536
void stonith_key_value_freeall(stonith_key_value_t *kvp, int keys, int values)
Definition: st_client.c:1938
int pcmk_legacy2rc(int legacy_rc)
Definition: results.c:534
int pcmk__request_fencing(stonith_t *st, const char *target, const char *action, const char *name, unsigned int timeout, unsigned int tolerance, int delay, char **reason)
Ask the cluster to perform fencing.
Definition: pcmk_fence.c:182
Function and executable result codes.
int pcmk__fence_register_level(stonith_t *st, char *target, int fence_level, stonith_key_value_t *devices)
Register a fencing level for a specific node, node regex, or attribute.
Definition: pcmk_fence.c:522
const char * target
Definition: pcmk_fence.c:29
int(* history)(stonith_t *stonith, int call_options, const char *node, stonith_history_t **history, int timeout)
List fencing actions that have occurred for a target.
Definition: stonith-ng.h:385
pcmk__action_result_t result
Definition: pcmk_fence.c:35
int pcmk__fence_list_targets(pcmk__output_t *out, stonith_t *st, const char *device_id, unsigned int timeout)
List nodes that can be fenced.
Definition: pcmk_fence.c:395
int stonith__execution_status(stonith_callback_data_t *data)
Definition: st_client.c:2533
void(*) void(* list_item)(pcmk__output_t *out, const char *name, const char *format,...) G_GNUC_PRINTF(3
int(* remove_level_full)(stonith_t *st, int options, const char *node, const char *pattern, const char *attr, const char *value, int level)
Unregister fencing level for specified node, pattern or attribute.
Definition: stonith-ng.h:467
stonith_api_operations_t * cmds
Definition: stonith-ng.h:556
int delay
Definition: pcmk_fence.c:34
int(* metadata)(stonith_t *stonith, int call_options, const char *agent, const char *namespace, char **output, int timeout_sec)
Retrieve a fence agent&#39;s metadata.
Definition: stonith-ng.h:258
void stonith_history_free(stonith_history_t *history)
Definition: st_client.c:755
Fencing aka. STONITH.
int pcmk__fence_validate(pcmk__output_t *out, stonith_t *st, const char *agent, const char *id, stonith_key_value_t *params, unsigned int timeout)
Validate a STONITH device configuration.
Definition: pcmk_fence.c:548
This structure contains everything that makes up a single output formatter.
void(* begin_list)(pcmk__output_t *out, const char *singular_noun, const char *plural_noun, const char *format,...) G_GNUC_PRINTF(4
int pcmk__fence_metadata(pcmk__output_t *out, stonith_t *st, char *agent, unsigned int timeout)
Get metadata for a resource.
Definition: pcmk_fence.c:440
int(* query)(stonith_t *stonith, int call_options, const char *target, stonith_key_value_t **devices, int timeout)
List registered fence devices.
Definition: stonith-ng.h:341
#define pcmk_ok
Definition: results.h:68
int pcmk__fence_registered(pcmk__output_t *out, stonith_t *st, char *target, unsigned int timeout)
List registered fence devices.
Definition: pcmk_fence.c:476
void pcmk__xml_output_finish(pcmk__output_t *out, xmlNodePtr *xml)
Definition: output.c:223
time_t stonith_api_time(uint32_t nodeid, const char *uname, bool in_progress)
Definition: st_client.c:2001
int stonith__exit_status(stonith_callback_data_t *data)
Definition: st_client.c:2516
int pcmk__get_fencing_history(stonith_t *st, stonith_history_t **stonith_history, enum pcmk__fence_history fence_history)
Fetch STONITH history, optionally reducing it.
Definition: pcmk_fence.c:583
int(* list)(stonith_t *stonith, int call_options, const char *id, char **list_info, int timeout)
Get the output of a fence device&#39;s list action.
Definition: stonith-ng.h:295
#define T_STONITH_NOTIFY_FENCE
Definition: stonith-ng.h:36
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:895
char * name
Definition: pcmk_fence.c:31
int stonith__event_execution_status(stonith_event_t *event)
Definition: st_client.c:2587
void pcmk__reset_result(pcmk__action_result_t *result)
Definition: results.c:984
unsigned int timeout
Definition: pcmk_fence.c:32
Execution failed, may be retried.
Definition: results.h:316
void(*) void(*) void(* increment_list)(pcmk__output_t *out)