root/include/crm/stonith-ng.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. stonith_api_kick_helper
  2. stonith_api_time_helper

   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     char *id;
 146     char *operation;
 147     int result;
 148     char *origin;
 149     char *target;
 150     char *action;
 151     char *executioner;
 152 
 153     char *device;
 154 
 155     /*! The name of the client that initiated the action. */
 156     char *client_origin;
 157 
 158     //! \internal This field should be treated as internal to Pacemaker
 159     void *opaque;
 160 } stonith_event_t;
 161 
 162 typedef struct stonith_callback_data_s {
 163     int rc;
 164     int call_id;
 165     void *userdata;
 166 
 167     //! \internal This field should be treated as internal to Pacemaker
 168     void *opaque;
 169 } stonith_callback_data_t;
 170 
 171 typedef struct stonith_api_operations_s
 172 {
 173     /*!
 174      * \brief Destroy a fencer connection
 175      *
 176      * \param[in,out] st  Fencer connection to destroy
 177      */
 178     int (*free) (stonith_t *st);
 179 
 180     /*!
 181      * \brief Connect to the local fencer
 182      *
 183      * \param[in,out] st          Fencer connection to connect
 184      * \param[in]     name        Client name to use
 185      * \param[out]    stonith_fd  If NULL, use a main loop, otherwise
 186      *                            store IPC file descriptor here
 187      *
 188      * \return Legacy Pacemaker return code
 189      */
 190     int (*connect) (stonith_t *st, const char *name, int *stonith_fd);
 191 
 192     /*!
 193      * \brief Disconnect from the local stonith daemon.
 194      *
 195      * \param[in,out] st  Fencer connection to disconnect
 196      *
 197      * \return Legacy Pacemaker return code
 198      */
 199     int (*disconnect)(stonith_t *st);
 200 
 201     /*!
 202      * \brief Unregister a fence device with the local fencer
 203      *
 204      * \param[in,out] st       Fencer connection to disconnect
 205      * \param[in]     options  Group of enum stonith_call_options
 206      * \param[in]     name     ID of fence device to unregister
 207      *
 208      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 209      *         on success, otherwise a negative legacy Pacemaker return code
 210      */
 211     int (*remove_device)(stonith_t *st, int options, const char *name);
 212 
 213     /*!
 214      * \brief Register a fence device with the local fencer
 215      *
 216      * \param[in,out] st           Fencer connection to use
 217      * \param[in]     options      Group of enum stonith_call_options
 218      * \param[in]     id           ID of fence device to register
 219      * \param[in]     namespace_s  Type of fence agent to search for ("redhat"
 220      *                             or "stonith-ng" for RHCS-style, "internal"
 221      *                             for Pacemaker-internal devices, "heartbeat"
 222      *                             for LHA-style, or "any" or NULL for any)
 223      * \param[in]     agent        Name of fence agent for device
 224      * \param[in]     params       Fence agent parameters for device
 225      *
 226      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 227      *         on success, otherwise a negative legacy Pacemaker return code
 228      */
 229     int (*register_device)(stonith_t *st, int options, const char *id,
 230                            const char *namespace_s, const char *agent,
 231                            const stonith_key_value_t *params);
 232 
 233     /*!
 234      * \brief Unregister a fencing level for specified node with local fencer
 235      *
 236      * \param[in,out] st       Fencer connection to use
 237      * \param[in]     options  Group of enum stonith_call_options
 238      * \param[in]     node     Target node to unregister level for
 239      * \param[in]     level    Topology level number to unregister
 240      *
 241      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 242      *         on success, otherwise a negative legacy Pacemaker return code
 243      */
 244     int (*remove_level)(stonith_t *st, int options, const char *node,
 245                         int level);
 246 
 247     /*!
 248      * \brief Register a fencing level for specified node with local fencer
 249      *
 250      * \param[in,out] st           Fencer connection to use
 251      * \param[in]     options      Group of enum stonith_call_options
 252      * \param[in]     node         Target node to register level for
 253      * \param[in]     level        Topology level number to register
 254      * \param[in]     device_list  Devices to register in level
 255      *
 256      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 257      *         on success, otherwise a negative legacy Pacemaker return code
 258      */
 259     int (*register_level)(stonith_t *st, int options, const char *node,
 260                           int level, const stonith_key_value_t *device_list);
 261 
 262     /*!
 263      * \brief Retrieve a fence agent's metadata
 264      *
 265      * \param[in,out] stonith       Fencer connection
 266      * \param[in]     call_options  Group of enum stonith_call_options
 267      *                              (currently ignored)
 268      * \param[in]     agent         Fence agent to query
 269      * \param[in]     namespace_s   Type of fence agent to search for ("redhat"
 270      *                              or "stonith-ng" for RHCS-style, "internal"
 271      *                              for Pacemaker-internal devices, "heartbeat"
 272      *                              for LHA-style, or "any" or NULL for any)
 273      * \param[out]    output        Where to store metadata
 274      * \param[in]     timeout_sec   Error if not complete within this time
 275      *
 276      * \return Legacy Pacemaker return code
 277      * \note The caller is responsible for freeing *output using free().
 278      */
 279     int (*metadata)(stonith_t *stonith, int call_options, const char *agent,
 280                     const char *namespace_s, char **output, int timeout_sec);
 281 
 282     /*!
 283      * \brief Retrieve a list of installed fence agents
 284      *
 285      * \param[in,out] stonith       Fencer connection to use
 286      * \param[in]     call_options  Group of enum stonith_call_options
 287      *                              (currently ignored)
 288      * \param[in]     namespace_s   Type of fence agents to list ("redhat"
 289      *                              or "stonith-ng" for RHCS-style, "internal" for
 290      *                              Pacemaker-internal devices, "heartbeat" for
 291      *                              LHA-style, or "any" or NULL for all)
 292      * \param[out]    devices       Where to store agent list
 293      * \param[in]     timeout       Error if unable to complete within this
 294      *                              (currently ignored)
 295      *
 296      * \return Number of items in list on success, or negative errno otherwise
 297      * \note The caller is responsible for freeing the returned list with
 298      *       stonith_key_value_freeall().
 299      */
 300     int (*list_agents)(stonith_t *stonith, int call_options,
 301                        const char *namespace_s, stonith_key_value_t **devices,
 302                        int timeout);
 303 
 304     /*!
 305      * \brief Get the output of a fence device's list action
 306      *
 307      * \param[in,out] stonith       Fencer connection to use
 308      * \param[in]     call_options  Group of enum stonith_call_options
 309      * \param[in]     id            Fence device ID to run list for
 310      * \param[out]    list_info     Where to store list output
 311      * \param[in]     timeout       Error if unable to complete within this
 312      *
 313      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 314      *         on success, otherwise a negative legacy Pacemaker return code
 315      */
 316     int (*list)(stonith_t *stonith, int call_options, const char *id,
 317                 char **list_info, int timeout);
 318 
 319     /*!
 320      * \brief Check whether a fence device is reachable by monitor action
 321      *
 322      * \param[in,out] stonith       Fencer connection to use
 323      * \param[in]     call_options  Group of enum stonith_call_options
 324      * \param[in]     id            Fence device ID to run monitor for
 325      * \param[in]     timeout       Error if unable to complete within this
 326      *
 327      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 328      *         on success, otherwise a negative legacy Pacemaker return code
 329      */
 330     int (*monitor)(stonith_t *stonith, int call_options, const char *id,
 331                    int timeout);
 332 
 333     /*!
 334      * \brief Check whether a fence device target is reachable by status action
 335      *
 336      * \param[in,out] stonith       Fencer connection to use
 337      * \param[in]     call_options  Group of enum stonith_call_options
 338      * \param[in]     id            Fence device ID to run status for
 339      * \param[in]     port          Fence target to run status for
 340      * \param[in]     timeout       Error if unable to complete within this
 341      *
 342      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 343      *         on success, otherwise a negative legacy Pacemaker return code
 344      */
 345     int (*status)(stonith_t *stonith, int call_options, const char *id,
 346                   const char *port, int timeout);
 347 
 348     /*!
 349      * \brief List registered fence devices
 350      *
 351      * \param[in,out] stonith       Fencer connection to use
 352      * \param[in]     call_options  Group of enum stonith_call_options
 353      * \param[in]     target        Fence target to run status for
 354      * \param[out]    devices       Where to store list of fence devices
 355      * \param[in]     timeout       Error if unable to complete within this
 356      *
 357      * \note If node is provided, only devices that can fence the node id
 358      *       will be returned.
 359      *
 360      * \return Number of items in list on success, or negative errno otherwise
 361      */
 362     int (*query)(stonith_t *stonith, int call_options, const char *target,
 363                  stonith_key_value_t **devices, int timeout);
 364 
 365     /*!
 366      * \brief Request that a target get fenced
 367      *
 368      * \param[in,out] stonith       Fencer connection to use
 369      * \param[in]     call_options  Group of enum stonith_call_options
 370      * \param[in]     node          Fence target
 371      * \param[in]     action        "on", "off", or "reboot"
 372      * \param[in]     timeout       Default per-device timeout to use with
 373      *                              each executed device
 374      * \param[in]     tolerance     Accept result of identical fence action
 375      *                              completed within this time
 376      *
 377      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 378      *         on success, otherwise a negative legacy Pacemaker return code
 379      */
 380     int (*fence)(stonith_t *stonith, int call_options, const char *node,
 381                  const char *action, int timeout, int tolerance);
 382 
 383     /*!
 384      * \brief Manually confirm that a node has been fenced
 385      *
 386      * \param[in,out] stonith       Fencer connection to use
 387      * \param[in]     call_options  Group of enum stonith_call_options
 388      * \param[in]     target        Fence target
 389      *
 390      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 391      *         on success, otherwise a negative legacy Pacemaker return code
 392      */
 393     int (*confirm)(stonith_t *stonith, int call_options, const char *target);
 394 
 395     /*!
 396      * \brief List fencing actions that have occurred for a target
 397      *
 398      * \param[in,out] stonith       Fencer connection to use
 399      * \param[in]     call_options  Group of enum stonith_call_options
 400      * \param[in]     node          Fence target
 401      * \param[out]    history       Where to store list of fencing actions
 402      * \param[in]     timeout       Error if unable to complete within this
 403      *
 404      * \return Legacy Pacemaker return code
 405      */
 406     int (*history)(stonith_t *stonith, int call_options, const char *node,
 407                    stonith_history_t **history, int timeout);
 408 
 409     /*!
 410      * \brief Register a callback for fence notifications
 411      *
 412      * \param[in,out] stonith       Fencer connection to use
 413      * \param[in]     event         Event to register for
 414      * \param[in]     callback      Callback to register
 415      *
 416      * \return Legacy Pacemaker return code
 417      */
 418     int (*register_notification)(stonith_t *stonith, const char *event,
 419                                  void (*callback)(stonith_t *st,
 420                                                   stonith_event_t *e));
 421 
 422     /*!
 423      * \brief Unregister callbacks for fence notifications
 424      *
 425      * \param[in,out] stonith  Fencer connection to use
 426      * \param[in]     event    Event to unregister callbacks for (NULL for all)
 427      *
 428      * \return Legacy Pacemaker return code
 429      */
 430     int (*remove_notification)(stonith_t *stonith, const char *event);
 431 
 432     /*!
 433      * \brief Register a callback for an asynchronous fencing result
 434      *
 435      * \param[in,out] stonith        Fencer connection to use
 436      * \param[in]     call_id        Call ID to register callback for
 437      * \param[in]     timeout        Error if result not received in this time
 438      * \param[in]     options        Group of enum stonith_call_options
 439      *                               (respects \c st_opt_timeout_updates and
 440      *                               \c st_opt_report_only_success)
 441      * \param[in,out] user_data      Pointer to pass to callback
 442      * \param[in]     callback_name  Unique identifier for callback
 443      * \param[in]     callback       Callback to register (may be called
 444      *                               immediately if \p call_id indicates error)
 445      *
 446      * \return \c TRUE on success, \c FALSE if call_id indicates error,
 447      *         or -EINVAL if \p stonith is not valid
 448      */
 449     int (*register_callback)(stonith_t *stonith, int call_id, int timeout,
 450                              int options, void *user_data,
 451                              const char *callback_name,
 452                              void (*callback)(stonith_t *st,
 453                                               stonith_callback_data_t *data));
 454 
 455     /*!
 456      * \brief Unregister callbacks for asynchronous fencing results
 457      *
 458      * \param[in,out] stonith        Fencer connection to use
 459      * \param[in]     call_id        If \p all_callbacks is false, call ID
 460      *                               to unregister callback for
 461      * \param[in]     all_callbacks  If true, unregister all callbacks
 462      *
 463      * \return pcmk_ok
 464      */
 465     int (*remove_callback)(stonith_t *stonith, int call_id, bool all_callbacks);
 466 
 467     /*!
 468      * \brief Unregister fencing level for specified node, pattern or attribute
 469      *
 470      * \param[in,out] st       Fencer connection to use
 471      * \param[in]     options  Group of enum stonith_call_options
 472      * \param[in]     node     If not NULL, unregister level targeting this node
 473      * \param[in]     pattern  If not NULL, unregister level targeting nodes
 474      *                         whose names match this regular expression
 475      * \param[in]     attr     If this and \p value are not NULL, unregister
 476      *                         level targeting nodes with this node attribute
 477      *                         set to \p value
 478      * \param[in]     value    If this and \p attr are not NULL, unregister
 479      *                         level targeting nodes with node attribute \p attr
 480      *                         set to this
 481      * \param[in]     level    Topology level number to remove
 482      *
 483      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 484      *         on success, otherwise a negative legacy Pacemaker return code
 485      * \note The caller should set only one of \p node, \p pattern, or \p attr
 486      *       and \p value.
 487      */
 488     int (*remove_level_full)(stonith_t *st, int options,
 489                              const char *node, const char *pattern,
 490                              const char *attr, const char *value, int level);
 491 
 492     /*!
 493      * \brief Register fencing level for specified node, pattern or attribute
 494      *
 495      * \param[in,out] st           Fencer connection to use
 496      * \param[in]     options      Group of enum stonith_call_options
 497      * \param[in]     node         If not NULL, register level targeting this
 498      *                             node by name
 499      * \param[in]     pattern      If not NULL, register level targeting nodes
 500      *                             whose names match this regular expression
 501      * \param[in]     attr         If this and \p value are not NULL, register
 502      *                             level targeting nodes with this node
 503      *                             attribute set to \p value
 504      * \param[in]     value        If this and \p attr are not NULL, register
 505      *                             level targeting nodes with node attribute
 506      *                             \p attr set to this
 507      * \param[in]     level        Topology level number to remove
 508      * \param[in]     device_list  Devices to use in level
 509      *
 510      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 511      *         on success, otherwise a negative legacy Pacemaker return code
 512      *
 513      * \note The caller should set only one of node, pattern or attr/value.
 514      */
 515     int (*register_level_full)(stonith_t *st, int options,
 516                                const char *node, const char *pattern,
 517                                const char *attr, const char *value, int level,
 518                                const stonith_key_value_t *device_list);
 519 
 520     /*!
 521      * \brief Validate an arbitrary stonith device configuration
 522      *
 523      * \param[in,out] st            Fencer connection to use
 524      * \param[in]     call_options  Group of enum stonith_call_options
 525      * \param[in]     rsc_id        ID used to replace CIB secrets in \p params
 526      * \param[in]     namespace_s   Type of fence agent to validate ("redhat"
 527      *                              or "stonith-ng" for RHCS-style, "internal"
 528      *                              for Pacemaker-internal devices, "heartbeat"
 529      *                              for LHA-style, or "any" or NULL for any)
 530      * \param[in]     agent         Fence agent to validate
 531      * \param[in]     params        Configuration parameters to pass to agent
 532      * \param[in]     timeout       Fail if no response within this many seconds
 533      * \param[out]    output        If non-NULL, where to store any agent output
 534      * \param[out]    error_output  If non-NULL, where to store agent error output
 535      *
 536      * \return pcmk_ok if validation succeeds, -errno otherwise
 537      * \note If pcmk_ok is returned, the caller is responsible for freeing
 538      *       the output (if requested) with free().
 539      */
 540     int (*validate)(stonith_t *st, int call_options, const char *rsc_id,
 541                     const char *namespace_s, const char *agent,
 542                     const stonith_key_value_t *params, int timeout,
 543                     char **output, char **error_output);
 544 
 545     /*!
 546      * \brief Request delayed fencing of a target
 547      *
 548      * \param[in,out] stonith       Fencer connection to use
 549      * \param[in]     call_options  Group of enum stonith_call_options
 550      * \param[in]     node          Fence target
 551      * \param[in]     action        "on", "off", or "reboot"
 552      * \param[in]     timeout       Default per-device timeout to use with
 553      *                              each executed device
 554      * \param[in]     tolerance     Accept result of identical fence action
 555      *                              completed within this time
 556      * \param[in]     delay         Execute fencing after this delay (-1
 557      *                              disables any delay from pcmk_delay_base
 558      *                              and pcmk_delay_max)
 559      *
 560      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 561      *         on success, otherwise a negative legacy Pacemaker return code
 562      */
 563     int (*fence_with_delay)(stonith_t *stonith, int call_options,
 564                             const char *node, const char *action, int timeout,
 565                             int tolerance, int delay);
 566 
 567 } stonith_api_operations_t;
 568 
 569 struct stonith_s {
 570     enum stonith_state state;
 571     int call_id;
 572     void *st_private;
 573     stonith_api_operations_t *cmds;
 574 };
 575 /* *INDENT-ON* */
 576 
 577 /* Core functions */
 578 stonith_t *stonith_api_new(void);
 579 void stonith_api_delete(stonith_t * st);
 580 
 581 void stonith_dump_pending_callbacks(stonith_t * st);
 582 
 583 bool stonith_dispatch(stonith_t * st);
 584 
 585 stonith_key_value_t *stonith_key_value_add(stonith_key_value_t * kvp, const char *key,
 586                                            const char *value);
 587 void stonith_key_value_freeall(stonith_key_value_t * kvp, int keys, int values);
 588 
 589 void stonith_history_free(stonith_history_t *history);
 590 
 591 // Convenience functions
 592 int stonith_api_connect_retry(stonith_t *st, const char *name,
 593                               int max_attempts);
 594 const char *stonith_op_state_str(enum op_state state);
 595 
 596 /* Basic helpers that allows nodes to be fenced and the history to be
 597  * queried without mainloop or the caller understanding the full API
 598  *
 599  * At least one of nodeid and uname are required
 600  *
 601  * NOTE: DLM uses both of these
 602  */
 603 int stonith_api_kick(uint32_t nodeid, const char *uname, int timeout, bool off);
 604 time_t stonith_api_time(uint32_t nodeid, const char *uname, bool in_progress);
 605 
 606 /*
 607  * Helpers for using the above functions without install-time dependencies
 608  *
 609  * Usage:
 610  *  #include <crm/stonith-ng.h>
 611  *
 612  * To turn a node off by corosync nodeid:
 613  *  stonith_api_kick_helper(nodeid, 120, 1);
 614  *
 615  * To check the last fence date/time (also by nodeid):
 616  *  last = stonith_api_time_helper(nodeid, 0);
 617  *
 618  * To check if fencing is in progress:
 619  *  if(stonith_api_time_helper(nodeid, 1) > 0) { ... }
 620  *
 621  * eg.
 622 
 623  #include <stdio.h>
 624  #include <time.h>
 625  #include <crm/stonith-ng.h>
 626  int
 627  main(int argc, char ** argv)
 628  {
 629      int rc = 0;
 630      int nodeid = 102;
 631 
 632      rc = stonith_api_time_helper(nodeid, 0);
 633      printf("%d last fenced at %s\n", nodeid, ctime(rc));
 634 
 635      rc = stonith_api_kick_helper(nodeid, 120, 1);
 636      printf("%d fence result: %d\n", nodeid, rc);
 637 
 638      rc = stonith_api_time_helper(nodeid, 0);
 639      printf("%d last fenced at %s\n", nodeid, ctime(rc));
 640 
 641      return 0;
 642  }
 643 
 644  */
 645 
 646 #  define STONITH_LIBRARY "libstonithd.so.26"
 647 
 648 typedef int (*st_api_kick_fn) (int nodeid, const char *uname, int timeout, bool off);
 649 typedef time_t (*st_api_time_fn) (int nodeid, const char *uname, bool in_progress);
 650 
 651 static inline int
 652 stonith_api_kick_helper(uint32_t nodeid, int timeout, bool off)
     /* [previous][next][first][last][top][bottom][index][help] */
 653 {
 654     static void *st_library = NULL;
 655     static st_api_kick_fn st_kick_fn;
 656 
 657     if (st_library == NULL) {
 658         st_library = dlopen(STONITH_LIBRARY, RTLD_LAZY);
 659     }
 660     if (st_library && st_kick_fn == NULL) {
 661         st_kick_fn = (st_api_kick_fn) dlsym(st_library, "stonith_api_kick");
 662     }
 663     if (st_kick_fn == NULL) {
 664 #ifdef ELIBACC
 665         return -ELIBACC;
 666 #else
 667         return -ENOSYS;
 668 #endif
 669     }
 670 
 671     return (*st_kick_fn) (nodeid, NULL, timeout, off);
 672 }
 673 
 674 static inline time_t
 675 stonith_api_time_helper(uint32_t nodeid, bool in_progress)
     /* [previous][next][first][last][top][bottom][index][help] */
 676 {
 677     static void *st_library = NULL;
 678     static st_api_time_fn st_time_fn;
 679 
 680     if (st_library == NULL) {
 681         st_library = dlopen(STONITH_LIBRARY, RTLD_LAZY);
 682     }
 683     if (st_library && st_time_fn == NULL) {
 684         st_time_fn = (st_api_time_fn) dlsym(st_library, "stonith_api_time");
 685     }
 686     if (st_time_fn == NULL) {
 687         return 0;
 688     }
 689 
 690     return (*st_time_fn) (nodeid, NULL, in_progress);
 691 }
 692 
 693 /**
 694  * Does the given agent describe a stonith resource that can exist?
 695  *
 696  * \param[in] agent     What is the name of the agent?
 697  * \param[in] timeout   Timeout to use when querying.  If 0 is given,
 698  *                      use a default of 120.
 699  *
 700  * \return A boolean
 701  */
 702 bool stonith_agent_exists(const char *agent, int timeout);
 703 
 704 /*!
 705  * \brief Turn fence action into a more readable string
 706  *
 707  * \param[in] action  Fence action
 708  */
 709 const char *stonith_action_str(const char *action);
 710 
 711 #ifdef __cplusplus
 712 }
 713 #endif
 714 
 715 #endif

/* [previous][next][first][last][top][bottom][index][help] */