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) /* */ 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) /* */ 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