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 #ifndef PCMK__CRM_STONITH_NG__H
11 # define PCMK__CRM_STONITH_NG__H
12
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16
17 /**
18 * \file
19 * \brief Fencing aka. STONITH
20 * \ingroup fencing
21 */
22
23 /* IMPORTANT: DLM source code includes this file directly, without having access
24 * to other Pacemaker headers on its include path, so this file should *not*
25 * include any other Pacemaker headers. (DLM might be updated to avoid the
26 * issue, but we should still follow this guideline for a long time after.)
27 */
28
29 # include <dlfcn.h>
30 # include <errno.h>
31 # include <stdbool.h> // bool
32 # include <stdint.h> // uint32_t
33 # include <time.h> // time_t
34
35 /* *INDENT-OFF* */
36 enum stonith_state {
37 stonith_connected_command,
38 stonith_connected_query,
39 stonith_disconnected,
40 };
41
42 //! Flags that can be set in call options for API requests
43 enum stonith_call_options {
44 //! No options
45 st_opt_none = 0,
46
47 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
48 //! \deprecated Unused
49 st_opt_verbose = (1 << 0),
50 #endif
51
52 //! The fencing target is allowed to execute the request
53 st_opt_allow_self_fencing = (1 << 1),
54
55 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
56 //! \deprecated Use st_opt_allow_self_fencing instead
57 st_opt_allow_suicide = st_opt_allow_self_fencing,
58 #endif
59
60 // Used internally to indicate that request is manual fence confirmation
61 //! \internal Do not use
62 st_opt_manual_ack = (1 << 3),
63
64 //! Do not return any reply from server
65 st_opt_discard_reply = (1 << 4),
66
67 // Used internally to indicate that request requires a fencing topology
68 //! \internal Do not use
69 st_opt_topology = (1 << 6),
70
71 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
72 //! \deprecated Unused
73 st_opt_scope_local = (1 << 8),
74 #endif
75
76 //! Interpret target as node cluster layer ID instead of name
77 st_opt_cs_nodeid = (1 << 9),
78
79 //! Wait for request to be completed before returning
80 st_opt_sync_call = (1 << 12),
81
82 //! Request that server send an update with optimal callback timeout
83 st_opt_timeout_updates = (1 << 13),
84
85 //! Invoke callback only if request succeeded
86 st_opt_report_only_success = (1 << 14),
87
88 //! For a fence history request, request that the history be cleared
89 st_opt_cleanup = (1 << 19),
90
91 //! For a fence history request, broadcast the request to all nodes
92 st_opt_broadcast = (1 << 20),
93 };
94
95 /*! Order matters here, do not change values */
96 enum op_state
97 {
98 st_query,
99 st_exec,
100 st_done,
101 st_duplicate,
102 st_failed,
103 };
104
105 // Supported fence agent interface standards
106 enum stonith_namespace {
107 st_namespace_invalid,
108 st_namespace_any,
109 st_namespace_internal, // Implemented internally by Pacemaker
110
111 /* Neither of these projects are active any longer, but the fence agent
112 * interfaces they created are still in use and supported by Pacemaker.
113 */
114 st_namespace_rhcs, // Red Hat Cluster Suite compatible
115 st_namespace_lha, // Linux-HA compatible
116 };
117
118 enum stonith_namespace stonith_text2namespace(const char *namespace_s);
119 const char *stonith_namespace2text(enum stonith_namespace st_namespace);
120 enum stonith_namespace stonith_get_namespace(const char *agent,
121 const char *namespace_s);
122
123 typedef struct stonith_key_value_s {
124 char *key;
125 char *value;
126 struct stonith_key_value_s *next;
127 } stonith_key_value_t;
128
129 typedef struct stonith_history_s {
130 char *target;
131 char *action;
132 char *origin;
133 char *delegate;
134 char *client;
135 int state;
136 time_t completed;
137 struct stonith_history_s *next;
138 long completed_nsec;
139 char *exit_reason;
140 } stonith_history_t;
141
142 typedef struct stonith_s stonith_t;
143
144 typedef struct stonith_event_s
145 {
146 char *id;
147 char *type; //!< \deprecated Will be removed in future release
148 char *message; //!< \deprecated Will be removed in future release
149 char *operation;
150
151 int result;
152 char *origin;
153 char *target;
154 char *action;
155 char *executioner;
156
157 char *device;
158
159 /*! The name of the client that initiated the action. */
160 char *client_origin;
161
162 //! \internal This field should be treated as internal to Pacemaker
163 void *opaque;
164 } stonith_event_t;
165
166 typedef struct stonith_callback_data_s {
167 int rc;
168 int call_id;
169 void *userdata;
170
171 //! \internal This field should be treated as internal to Pacemaker
172 void *opaque;
173 } stonith_callback_data_t;
174
175 typedef struct stonith_api_operations_s
176 {
177 /*!
178 * \brief Destroy a fencer connection
179 *
180 * \param[in,out] st Fencer connection to destroy
181 */
182 int (*free) (stonith_t *st);
183
184 /*!
185 * \brief Connect to the local fencer
186 *
187 * \param[in,out] st Fencer connection to connect
188 * \param[in] name Client name to use
189 * \param[out] stonith_fd If NULL, use a main loop, otherwise
190 * store IPC file descriptor here
191 *
192 * \return Legacy Pacemaker return code
193 */
194 int (*connect) (stonith_t *st, const char *name, int *stonith_fd);
195
196 /*!
197 * \brief Disconnect from the local stonith daemon.
198 *
199 * \param[in,out] st Fencer connection to disconnect
200 *
201 * \return Legacy Pacemaker return code
202 */
203 int (*disconnect)(stonith_t *st);
204
205 /*!
206 * \brief Unregister a fence device with the local fencer
207 *
208 * \param[in,out] st Fencer connection to disconnect
209 * \param[in] options Group of enum stonith_call_options
210 * \param[in] name ID of fence device to unregister
211 *
212 * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
213 * on success, otherwise a negative legacy Pacemaker return code
214 */
215 int (*remove_device)(stonith_t *st, int options, const char *name);
216
217 /*!
218 * \brief Register a fence device with the local fencer
219 *
220 * \param[in,out] st Fencer connection to use
221 * \param[in] options Group of enum stonith_call_options
222 * \param[in] id ID of fence device to register
223 * \param[in] namespace_s Type of fence agent to search for ("redhat"
224 * or "stonith-ng" for RHCS-style, "internal"
225 * for Pacemaker-internal devices, "heartbeat"
226 * for LHA-style, or "any" or NULL for any)
227 * \param[in] agent Name of fence agent for device
228 * \param[in] params Fence agent parameters for device
229 *
230 * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
231 * on success, otherwise a negative legacy Pacemaker return code
232 */
233 int (*register_device)(stonith_t *st, int options, const char *id,
234 const char *namespace_s, const char *agent,
235 const stonith_key_value_t *params);
236
237 /*!
238 * \brief Unregister a fencing level for specified node with local fencer
239 *
240 * \param[in,out] st Fencer connection to use
241 * \param[in] options Group of enum stonith_call_options
242 * \param[in] node Target node to unregister level for
243 * \param[in] level Topology level number to unregister
244 *
245 * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
246 * on success, otherwise a negative legacy Pacemaker return code
247 */
248 int (*remove_level)(stonith_t *st, int options, const char *node,
249 int level);
250
251 /*!
252 * \brief Register a fencing level for specified node with local fencer
253 *
254 * \param[in,out] st Fencer connection to use
255 * \param[in] options Group of enum stonith_call_options
256 * \param[in] node Target node to register level for
257 * \param[in] level Topology level number to register
258 * \param[in] device_list Devices to register in level
259 *
260 * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
261 * on success, otherwise a negative legacy Pacemaker return code
262 */
263 int (*register_level)(stonith_t *st, int options, const char *node,
264 int level, const stonith_key_value_t *device_list);
265
266 /*!
267 * \brief Retrieve a fence agent's metadata
268 *
269 * \param[in,out] stonith Fencer connection
270 * \param[in] call_options Group of enum stonith_call_options
271 * (currently ignored)
272 * \param[in] agent Fence agent to query
273 * \param[in] namespace_s Type of fence agent to search for ("redhat"
274 * or "stonith-ng" for RHCS-style, "internal"
275 * for Pacemaker-internal devices, "heartbeat"
276 * for LHA-style, or "any" or NULL for any)
277 * \param[out] output Where to store metadata
278 * \param[in] timeout_sec Error if not complete within this time
279 *
280 * \return Legacy Pacemaker return code
281 * \note The caller is responsible for freeing *output using free().
282 */
283 int (*metadata)(stonith_t *stonith, int call_options, const char *agent,
284 const char *namespace_s, char **output, int timeout_sec);
285
286 /*!
287 * \brief Retrieve a list of installed fence agents
288 *
289 * \param[in,out] stonith Fencer connection to use
290 * \param[in] call_options Group of enum stonith_call_options
291 * (currently ignored)
292 * \param[in] namespace_s Type of fence agents to list ("redhat"
293 * or "stonith-ng" for RHCS-style, "internal" for
294 * Pacemaker-internal devices, "heartbeat" for
295 * LHA-style, or "any" or NULL for all)
296 * \param[out] devices Where to store agent list
297 * \param[in] timeout Error if unable to complete within this
298 * (currently ignored)
299 *
300 * \return Number of items in list on success, or negative errno otherwise
301 * \note The caller is responsible for freeing the returned list with
302 * stonith_key_value_freeall().
303 */
304 int (*list_agents)(stonith_t *stonith, int call_options,
305 const char *namespace_s, stonith_key_value_t **devices,
306 int timeout);
307
308 /*!
309 * \brief Get the output of a fence device's list action
310 *
311 * \param[in,out] stonith Fencer connection to use
312 * \param[in] call_options Group of enum stonith_call_options
313 * \param[in] id Fence device ID to run list for
314 * \param[out] list_info Where to store list output
315 * \param[in] timeout Error if unable to complete within this
316 *
317 * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
318 * on success, otherwise a negative legacy Pacemaker return code
319 */
320 int (*list)(stonith_t *stonith, int call_options, const char *id,
321 char **list_info, int timeout);
322
323 /*!
324 * \brief Check whether a fence device is reachable by monitor action
325 *
326 * \param[in,out] stonith Fencer connection to use
327 * \param[in] call_options Group of enum stonith_call_options
328 * \param[in] id Fence device ID to run monitor for
329 * \param[in] timeout Error if unable to complete within this
330 *
331 * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
332 * on success, otherwise a negative legacy Pacemaker return code
333 */
334 int (*monitor)(stonith_t *stonith, int call_options, const char *id,
335 int timeout);
336
337 /*!
338 * \brief Check whether a fence device target is reachable by status action
339 *
340 * \param[in,out] stonith Fencer connection to use
341 * \param[in] call_options Group of enum stonith_call_options
342 * \param[in] id Fence device ID to run status for
343 * \param[in] port Fence target to run status for
344 * \param[in] timeout Error if unable to complete within this
345 *
346 * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
347 * on success, otherwise a negative legacy Pacemaker return code
348 */
349 int (*status)(stonith_t *stonith, int call_options, const char *id,
350 const char *port, int timeout);
351
352 /*!
353 * \brief List registered fence devices
354 *
355 * \param[in,out] stonith Fencer connection to use
356 * \param[in] call_options Group of enum stonith_call_options
357 * \param[in] target Fence target to run status for
358 * \param[out] devices Where to store list of fence devices
359 * \param[in] timeout Error if unable to complete within this
360 *
361 * \note If node is provided, only devices that can fence the node id
362 * will be returned.
363 *
364 * \return Number of items in list on success, or negative errno otherwise
365 */
366 int (*query)(stonith_t *stonith, int call_options, const char *target,
367 stonith_key_value_t **devices, int timeout);
368
369 /*!
370 * \brief Request that a target get fenced
371 *
372 * \param[in,out] stonith Fencer connection to use
373 * \param[in] call_options Group of enum stonith_call_options
374 * \param[in] node Fence target
375 * \param[in] action "on", "off", or "reboot"
376 * \param[in] timeout Default per-device timeout to use with
377 * each executed device
378 * \param[in] tolerance Accept result of identical fence action
379 * completed within this time
380 *
381 * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
382 * on success, otherwise a negative legacy Pacemaker return code
383 */
384 int (*fence)(stonith_t *stonith, int call_options, const char *node,
385 const char *action, int timeout, int tolerance);
386
387 /*!
388 * \brief Manually confirm that a node has been fenced
389 *
390 * \param[in,out] stonith Fencer connection to use
391 * \param[in] call_options Group of enum stonith_call_options
392 * \param[in] target Fence target
393 *
394 * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
395 * on success, otherwise a negative legacy Pacemaker return code
396 */
397 int (*confirm)(stonith_t *stonith, int call_options, const char *target);
398
399 /*!
400 * \brief List fencing actions that have occurred for a target
401 *
402 * \param[in,out] stonith Fencer connection to use
403 * \param[in] call_options Group of enum stonith_call_options
404 * \param[in] node Fence target
405 * \param[out] history Where to store list of fencing actions
406 * \param[in] timeout Error if unable to complete within this
407 *
408 * \return Legacy Pacemaker return code
409 */
410 int (*history)(stonith_t *stonith, int call_options, const char *node,
411 stonith_history_t **history, int timeout);
412
413 /*!
414 * \brief Register a callback for fence notifications
415 *
416 * \param[in,out] stonith Fencer connection to use
417 * \param[in] event Event to register for
418 * \param[in] callback Callback to register
419 *
420 * \return Legacy Pacemaker return code
421 */
422 int (*register_notification)(stonith_t *stonith, const char *event,
423 void (*callback)(stonith_t *st,
424 stonith_event_t *e));
425
426 /*!
427 * \brief Unregister callbacks for fence notifications
428 *
429 * \param[in,out] stonith Fencer connection to use
430 * \param[in] event Event to unregister callbacks for (NULL for all)
431 *
432 * \return Legacy Pacemaker return code
433 */
434 int (*remove_notification)(stonith_t *stonith, const char *event);
435
436 /*!
437 * \brief Register a callback for an asynchronous fencing result
438 *
439 * \param[in,out] stonith Fencer connection to use
440 * \param[in] call_id Call ID to register callback for
441 * \param[in] timeout Error if result not received in this time
442 * \param[in] options Group of enum stonith_call_options
443 * (respects \c st_opt_timeout_updates and
444 * \c st_opt_report_only_success)
445 * \param[in,out] user_data Pointer to pass to callback
446 * \param[in] callback_name Unique identifier for callback
447 * \param[in] callback Callback to register (may be called
448 * immediately if \p call_id indicates error)
449 *
450 * \return \c TRUE on success, \c FALSE if call_id indicates error,
451 * or -EINVAL if \p stonith is not valid
452 */
453 int (*register_callback)(stonith_t *stonith, int call_id, int timeout,
454 int options, void *user_data,
455 const char *callback_name,
456 void (*callback)(stonith_t *st,
457 stonith_callback_data_t *data));
458
459 /*!
460 * \brief Unregister callbacks for asynchronous fencing results
461 *
462 * \param[in,out] stonith Fencer connection to use
463 * \param[in] call_id If \p all_callbacks is false, call ID
464 * to unregister callback for
465 * \param[in] all_callbacks If true, unregister all callbacks
466 *
467 * \return pcmk_ok
468 */
469 int (*remove_callback)(stonith_t *stonith, int call_id, bool all_callbacks);
470
471 /*!
472 * \brief Unregister fencing level for specified node, pattern or attribute
473 *
474 * \param[in,out] st Fencer connection to use
475 * \param[in] options Group of enum stonith_call_options
476 * \param[in] node If not NULL, unregister level targeting this node
477 * \param[in] pattern If not NULL, unregister level targeting nodes
478 * whose names match this regular expression
479 * \param[in] attr If this and \p value are not NULL, unregister
480 * level targeting nodes with this node attribute
481 * set to \p value
482 * \param[in] value If this and \p attr are not NULL, unregister
483 * level targeting nodes with node attribute \p attr
484 * set to this
485 * \param[in] level Topology level number to remove
486 *
487 * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
488 * on success, otherwise a negative legacy Pacemaker return code
489 * \note The caller should set only one of \p node, \p pattern, or \p attr
490 * and \p value.
491 */
492 int (*remove_level_full)(stonith_t *st, int options,
493 const char *node, const char *pattern,
494 const char *attr, const char *value, int level);
495
496 /*!
497 * \brief Register fencing level for specified node, pattern or attribute
498 *
499 * \param[in,out] st Fencer connection to use
500 * \param[in] options Group of enum stonith_call_options
501 * \param[in] node If not NULL, register level targeting this
502 * node by name
503 * \param[in] pattern If not NULL, register level targeting nodes
504 * whose names match this regular expression
505 * \param[in] attr If this and \p value are not NULL, register
506 * level targeting nodes with this node
507 * attribute set to \p value
508 * \param[in] value If this and \p attr are not NULL, register
509 * level targeting nodes with node attribute
510 * \p attr set to this
511 * \param[in] level Topology level number to remove
512 * \param[in] device_list Devices to use in level
513 *
514 * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
515 * on success, otherwise a negative legacy Pacemaker return code
516 *
517 * \note The caller should set only one of node, pattern or attr/value.
518 */
519 int (*register_level_full)(stonith_t *st, int options,
520 const char *node, const char *pattern,
521 const char *attr, const char *value, int level,
522 const stonith_key_value_t *device_list);
523
524 /*!
525 * \brief Validate an arbitrary stonith device configuration
526 *
527 * \param[in,out] st Fencer connection to use
528 * \param[in] call_options Group of enum stonith_call_options
529 * \param[in] rsc_id ID used to replace CIB secrets in \p params
530 * \param[in] namespace_s Type of fence agent to validate ("redhat"
531 * or "stonith-ng" for RHCS-style, "internal"
532 * for Pacemaker-internal devices, "heartbeat"
533 * for LHA-style, or "any" or NULL for any)
534 * \param[in] agent Fence agent to validate
535 * \param[in] params Configuration parameters to pass to agent
536 * \param[in] timeout Fail if no response within this many seconds
537 * \param[out] output If non-NULL, where to store any agent output
538 * \param[out] error_output If non-NULL, where to store agent error output
539 *
540 * \return pcmk_ok if validation succeeds, -errno otherwise
541 * \note If pcmk_ok is returned, the caller is responsible for freeing
542 * the output (if requested) with free().
543 */
544 int (*validate)(stonith_t *st, int call_options, const char *rsc_id,
545 const char *namespace_s, const char *agent,
546 const stonith_key_value_t *params, int timeout,
547 char **output, char **error_output);
548
549 /*!
550 * \brief Request delayed fencing of a target
551 *
552 * \param[in,out] stonith Fencer connection to use
553 * \param[in] call_options Group of enum stonith_call_options
554 * \param[in] node Fence target
555 * \param[in] action "on", "off", or "reboot"
556 * \param[in] timeout Default per-device timeout to use with
557 * each executed device
558 * \param[in] tolerance Accept result of identical fence action
559 * completed within this time
560 * \param[in] delay Execute fencing after this delay (-1
561 * disables any delay from pcmk_delay_base
562 * and pcmk_delay_max)
563 *
564 * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
565 * on success, otherwise a negative legacy Pacemaker return code
566 */
567 int (*fence_with_delay)(stonith_t *stonith, int call_options,
568 const char *node, const char *action, int timeout,
569 int tolerance, int delay);
570
571 } stonith_api_operations_t;
572
573 struct stonith_s
574 {
575 enum stonith_state state;
576
577 int call_id;
578 int call_timeout; //!< \deprecated Unused
579 void *st_private;
580
581 stonith_api_operations_t *cmds;
582 };
583 /* *INDENT-ON* */
584
585 /* Core functions */
586 stonith_t *stonith_api_new(void);
587 void stonith_api_delete(stonith_t * st);
588
589 void stonith_dump_pending_callbacks(stonith_t * st);
590
591 bool stonith_dispatch(stonith_t * st);
592
593 stonith_key_value_t *stonith_key_value_add(stonith_key_value_t * kvp, const char *key,
594 const char *value);
595 void stonith_key_value_freeall(stonith_key_value_t * kvp, int keys, int values);
596
597 void stonith_history_free(stonith_history_t *history);
598
599 // Convenience functions
600 int stonith_api_connect_retry(stonith_t *st, const char *name,
601 int max_attempts);
602 const char *stonith_op_state_str(enum op_state state);
603
604 /* Basic helpers that allows nodes to be fenced and the history to be
605 * queried without mainloop or the caller understanding the full API
606 *
607 * At least one of nodeid and uname are required
608 *
609 * NOTE: DLM uses both of these
610 */
611 int stonith_api_kick(uint32_t nodeid, const char *uname, int timeout, bool off);
612 time_t stonith_api_time(uint32_t nodeid, const char *uname, bool in_progress);
613
614 /*
615 * Helpers for using the above functions without install-time dependencies
616 *
617 * Usage:
618 * #include <crm/stonith-ng.h>
619 *
620 * To turn a node off by corosync nodeid:
621 * stonith_api_kick_helper(nodeid, 120, 1);
622 *
623 * To check the last fence date/time (also by nodeid):
624 * last = stonith_api_time_helper(nodeid, 0);
625 *
626 * To check if fencing is in progress:
627 * if(stonith_api_time_helper(nodeid, 1) > 0) { ... }
628 *
629 * eg.
630
631 #include <stdio.h>
632 #include <time.h>
633 #include <crm/stonith-ng.h>
634 int
635 main(int argc, char ** argv)
636 {
637 int rc = 0;
638 int nodeid = 102;
639
640 rc = stonith_api_time_helper(nodeid, 0);
641 printf("%d last fenced at %s\n", nodeid, ctime(rc));
642
643 rc = stonith_api_kick_helper(nodeid, 120, 1);
644 printf("%d fence result: %d\n", nodeid, rc);
645
646 rc = stonith_api_time_helper(nodeid, 0);
647 printf("%d last fenced at %s\n", nodeid, ctime(rc));
648
649 return 0;
650 }
651
652 */
653
654 # define STONITH_LIBRARY "libstonithd.so.26"
655
656 typedef int (*st_api_kick_fn) (int nodeid, const char *uname, int timeout, bool off);
657 typedef time_t (*st_api_time_fn) (int nodeid, const char *uname, bool in_progress);
658
659 static inline int
660 stonith_api_kick_helper(uint32_t nodeid, int timeout, bool off)
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
661 {
662 static void *st_library = NULL;
663 static st_api_kick_fn st_kick_fn;
664
665 if (st_library == NULL) {
666 st_library = dlopen(STONITH_LIBRARY, RTLD_LAZY);
667 }
668 if (st_library && st_kick_fn == NULL) {
669 st_kick_fn = (st_api_kick_fn) dlsym(st_library, "stonith_api_kick");
670 }
671 if (st_kick_fn == NULL) {
672 #ifdef ELIBACC
673 return -ELIBACC;
674 #else
675 return -ENOSYS;
676 #endif
677 }
678
679 return (*st_kick_fn) (nodeid, NULL, timeout, off);
680 }
681
682 static inline time_t
683 stonith_api_time_helper(uint32_t nodeid, bool in_progress)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
684 {
685 static void *st_library = NULL;
686 static st_api_time_fn st_time_fn;
687
688 if (st_library == NULL) {
689 st_library = dlopen(STONITH_LIBRARY, RTLD_LAZY);
690 }
691 if (st_library && st_time_fn == NULL) {
692 st_time_fn = (st_api_time_fn) dlsym(st_library, "stonith_api_time");
693 }
694 if (st_time_fn == NULL) {
695 return 0;
696 }
697
698 return (*st_time_fn) (nodeid, NULL, in_progress);
699 }
700
701 /**
702 * Does the given agent describe a stonith resource that can exist?
703 *
704 * \param[in] agent What is the name of the agent?
705 * \param[in] timeout Timeout to use when querying. If 0 is given,
706 * use a default of 120.
707 *
708 * \return A boolean
709 */
710 bool stonith_agent_exists(const char *agent, int timeout);
711
712 /*!
713 * \brief Turn fence action into a more readable string
714 *
715 * \param[in] action Fence action
716 */
717 const char *stonith_action_str(const char *action);
718
719 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
720 /* Normally we'd put this section in a separate file (crm/fencing/compat.h), but
721 * we can't do that for the reason noted at the top of this file. That does mean
722 * we have to duplicate these declarations where they're implemented.
723 */
724
725 //! \deprecated Do not use
726 #define T_STONITH_NOTIFY_DISCONNECT "st_notify_disconnect"
727
728 //! \deprecated Do not use
729 #define T_STONITH_NOTIFY_FENCE "st_notify_fence"
730
731 //! \deprecated Do not use
732 #define T_STONITH_NOTIFY_HISTORY "st_notify_history"
733
734 //! \deprecated Do not use
735 #define T_STONITH_NOTIFY_HISTORY_SYNCED "st_notify_history_synced"
736
737 //! \deprecated Use stonith_get_namespace() instead
738 const char *get_stonith_provider(const char *agent, const char *provider);
739
740 #endif
741
742 #ifdef __cplusplus
743 }
744 #endif
745
746 #endif