pacemaker 2.1.5-a3f44794f94
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>
17
18#include <glib.h>
19#include <libxml/tree.h>
20#include <pacemaker.h>
21#include <pacemaker-internal.h>
22
23static const int st_opts = st_opt_sync_call | st_opt_allow_suicide;
24
25static GMainLoop *mainloop = NULL;
26
27static 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
38static int
39handle_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
76static stonith_history_t *
77reduce_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
119static void
120notify_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
133static void
134fence_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
142static gboolean
143async_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,
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
181int
182pcmk__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);
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
218int
219pcmk_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
228int
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
297int
298pcmk_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
318int
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
340int
341pcmk_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
358int
359pcmk__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
376int
377pcmk_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
394int
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
420int
421pcmk_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
439int
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
456int
457pcmk_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
475int
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
502int
503pcmk_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
521int
523 stonith_key_value_t *devices) {
524 return handle_level(st, target, fence_level, devices, true);
525}
526
527#ifdef BUILD_PUBLIC_LIBPACEMAKER
528int
529pcmk_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
535int
537 return handle_level(st, target, fence_level, NULL, false);
538}
539
540#ifdef BUILD_PUBLIC_LIBPACEMAKER
541int
542pcmk_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
547int
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
562int
563pcmk_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
582int
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}
char data[0]
Definition: cpg.c:10
const char * stonith__event_exit_reason(stonith_event_t *event)
Definition: st_client.c:2607
int stonith__exit_status(stonith_callback_data_t *data)
Definition: st_client.c:2516
GList * stonith__parse_targets(const char *hosts)
Definition: st_client.c:2204
const char * stonith__later_succeeded(stonith_history_t *event, stonith_history_t *top_history)
Definition: st_client.c:2248
stonith_history_t * stonith__sort_history(stonith_history_t *history)
Definition: st_client.c:2287
#define stonith__set_call_options(st_call_opts, call_for, flags_to_set)
Definition: internal.h:36
int stonith__event_execution_status(stonith_event_t *event)
Definition: st_client.c:2587
int stonith__execution_status(stonith_callback_data_t *data)
Definition: st_client.c:2533
const char * stonith__exit_reason(stonith_callback_data_t *data)
Definition: st_client.c:2550
int stonith__result2rc(const pcmk__action_result_t *result)
Definition: st_actions.c:330
void stonith__register_messages(pcmk__output_t *out)
Definition: st_output.c:578
int stonith__event_exit_status(stonith_event_t *event)
Definition: st_client.c:2567
Wrappers for and extensions to glib mainloop.
void mainloop_set_trigger(crm_trigger_t *source)
Definition: mainloop.c:200
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
struct trigger_s crm_trigger_t
Definition: mainloop.h:32
Control output from tools.
@ pcmk_show_failed_detail
Definition: output.h:67
Formatted output for pacemaker tools.
int pcmk__xml_output_new(pcmk__output_t **out, xmlNodePtr *xml)
Definition: output.c:201
void pcmk__xml_output_finish(pcmk__output_t *out, xmlNodePtr *xml)
Definition: output.c:223
High Level API.
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
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
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
unsigned int timeout
Definition: pcmk_fence.c:32
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
char * name
Definition: pcmk_fence.c:31
int delay
Definition: pcmk_fence.c:34
unsigned int tolerance
Definition: pcmk_fence.c:33
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 pcmk__fence_installed(pcmk__output_t *out, stonith_t *st, unsigned int timeout)
List all installed STONITH agents.
Definition: pcmk_fence.c:319
stonith_t * st
Definition: pcmk_fence.c:28
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
const char * action
Definition: pcmk_fence.c:30
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
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 pcmk__fence_last(pcmk__output_t *out, const char *target, bool as_nodeid)
When was a device last fenced?
Definition: pcmk_fence.c:359
pcmk__action_result_t result
Definition: pcmk_fence.c:35
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
const char * target
Definition: pcmk_fence.c:29
pcmk__fence_history
Control how much of the fencing history is output.
Definition: pcmki_fence.h:18
@ pcmk__fence_history_reduced
Definition: pcmki_fence.h:20
@ pcmk__fence_history_none
Definition: pcmki_fence.h:19
Function and executable result codes.
const char * pcmk_strerror(int rc)
Definition: results.c:148
@ CRM_EX_ERROR
Unspecified error.
Definition: results.h:235
@ pcmk_rc_ok
Definition: results.h:148
#define pcmk_ok
Definition: results.h:68
@ PCMK_EXEC_ERROR
Execution failed, may be retried.
Definition: results.h:316
@ PCMK_EXEC_UNKNOWN
Used only to initialize variables.
Definition: results.h:310
@ PCMK_EXEC_NOT_CONNECTED
No connection to executor.
Definition: results.h:320
int pcmk_legacy2rc(int legacy_rc)
Definition: results.c:534
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
void pcmk__reset_result(pcmk__action_result_t *result)
Definition: results.c:984
Fencing aka. STONITH.
time_t stonith_api_time(uint32_t nodeid, const char *uname, bool in_progress)
Definition: st_client.c:2001
#define T_STONITH_NOTIFY_FENCE
Definition: stonith-ng.h:36
void stonith_history_free(stonith_history_t *history)
Definition: st_client.c:755
@ st_opt_cleanup
Definition: stonith-ng.h:65
@ st_opt_timeout_updates
Definition: stonith-ng.h:61
@ st_opt_broadcast
Definition: stonith-ng.h:67
@ st_opt_allow_suicide
Definition: stonith-ng.h:50
@ st_opt_sync_call
Definition: stonith-ng.h:58
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
void stonith_key_value_freeall(stonith_key_value_t *kvp, int keys, int values)
Definition: st_client.c:1938
@ st_failed
Definition: stonith-ng.h:77
@ st_done
Definition: stonith-ng.h:75
@ pcmk__str_none
@ pcmk__str_casei
This structure contains everything that makes up a single output formatter.
void(*) void(*) void(* increment_list)(pcmk__output_t *out)
void(* end_list)(pcmk__output_t *out)
int(* message)(pcmk__output_t *out, const char *message_id,...)
bool(* is_quiet)(pcmk__output_t *out)
int(*) void(*) void(* output_xml)(pcmk__output_t *out, const char *name, const char *buf)
void(*) void(* list_item)(pcmk__output_t *out, const char *name, const char *format,...) G_GNUC_PRINTF(3
void(* begin_list)(pcmk__output_t *out, const char *singular_noun, const char *plural_noun, const char *format,...) G_GNUC_PRINTF(4
bool quiet
Should this formatter supress most output?
int(* info)(pcmk__output_t *out, const char *format,...) G_GNUC_PRINTF(2
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
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
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
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
int(* metadata)(stonith_t *stonith, int call_options, const char *agent, const char *namespace, char **output, int timeout_sec)
Retrieve a fence agent's metadata.
Definition: stonith-ng.h:258
int(* list)(stonith_t *stonith, int call_options, const char *id, char **list_info, int timeout)
Get the output of a fence device's list action.
Definition: stonith-ng.h:295
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
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(* 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
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
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
struct stonith_history_s * next
Definition: stonith-ng.h:112
struct stonith_key_value_s * next
Definition: stonith-ng.h:101
stonith_api_operations_t * cmds
Definition: stonith-ng.h:556