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