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-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;
 123     char *message;
 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 the stonith api structure.
 154      */
 155     int (*free) (stonith_t *st);
 156 
 157     /*!
 158      * \brief Connect to the local stonith daemon.
 159      *
 160      * \return Legacy Pacemaker return code
 161      */
 162     int (*connect) (stonith_t *st, const char *name, int *stonith_fd);
 163 
 164     /*!
 165      * \brief Disconnect from the local stonith daemon.
 166      *
 167      * \return Legacy Pacemaker return code
 168      */
 169     int (*disconnect)(stonith_t *st);
 170 
 171     /*!
 172      * \brief Unregister a fence device with the local fencer
 173      *
 174      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 175      *         on success, otherwise a negative legacy Pacemaker return code
 176      */
 177     int (*remove_device)(
 178         stonith_t *st, int options, const char *name);
 179 
 180     /*!
 181      * \brief Register a fence device with the local fencer
 182      *
 183      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 184      *         on success, otherwise a negative legacy Pacemaker return code
 185      */
 186     int (*register_device)(
 187         stonith_t *st, int options, const char *id,
 188         const char *provider, const char *agent, stonith_key_value_t *params);
 189 
 190     /*!
 191      * \brief Unregister a fencing level for specified node with local fencer
 192      *
 193      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 194      *         on success, otherwise a negative legacy Pacemaker return code
 195      */
 196     int (*remove_level)(
 197         stonith_t *st, int options, const char *node, int level);
 198 
 199     /*!
 200      * \brief Register a fencing level for specified node with local fencer
 201      *
 202      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 203      *         on success, otherwise a negative legacy Pacemaker return code
 204      */
 205     int (*register_level)(
 206         stonith_t *st, int options, const char *node, int level, stonith_key_value_t *device_list);
 207 
 208     /*!
 209      * \brief Get the metadata documentation for a resource.
 210      *
 211      * \note Value is returned in output.  Output must be freed when set.
 212      *
 213      * \return Legacy Pacemaker return code
 214      */
 215     int (*metadata)(stonith_t *st, int options,
 216             const char *device, const char *provider, char **output, int timeout);
 217 
 218     /*!
 219      * \brief Retrieve a list of installed stonith agents
 220      *
 221      * \note if provider is not provided, all known agents will be returned
 222      * \note list must be freed using stonith_key_value_freeall()
 223      * \note call_options parameter is not used, it is reserved for future use.
 224      *
 225      * \return Number of items in list on success, or negative errno otherwise
 226      */
 227     int (*list_agents)(stonith_t *stonith, int call_options, const char *provider,
 228             stonith_key_value_t **devices, int timeout);
 229 
 230     /*!
 231      * \brief Retrieve string listing hosts and port assignments from a local stonith device.
 232      *
 233      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 234      *         on success, otherwise a negative legacy Pacemaker return code
 235      */
 236     int (*list)(stonith_t *st, int options, const char *id, char **list_output, int timeout);
 237 
 238     /*!
 239      * \brief Check to see if a local stonith device is reachable
 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 (*monitor)(stonith_t *st, int options, const char *id, int timeout);
 245 
 246     /*!
 247      * \brief Check to see if a local stonith device's port is reachable
 248      *
 249      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 250      *         on success, otherwise a negative legacy Pacemaker return code
 251      */
 252     int (*status)(stonith_t *st, int options, const char *id, const char *port, int timeout);
 253 
 254     /*!
 255      * \brief Retrieve a list of registered stonith devices.
 256      *
 257      * \note If node is provided, only devices that can fence the node id
 258      *       will be returned.
 259      *
 260      * \return Number of items in list on success, or negative errno otherwise
 261      */
 262     int (*query)(stonith_t *st, int options, const char *node,
 263             stonith_key_value_t **devices, int timeout);
 264 
 265     /*!
 266      * \brief Issue a fencing action against a node.
 267      *
 268      * \note Possible actions are, 'on', 'off', and 'reboot'.
 269      *
 270      * \param st, stonith connection
 271      * \param options, call options
 272      * \param node, The target node to fence
 273      * \param action, The fencing action to take
 274      * \param timeout, The default per device timeout to use with each device
 275      *                 capable of fencing the target.
 276      *
 277      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 278      *         on success, otherwise a negative legacy Pacemaker return code
 279      */
 280     int (*fence)(stonith_t *st, int options, const char *node, const char *action,
 281                  int timeout, int tolerance);
 282 
 283     /*!
 284      * \brief Manually confirm that a node is down.
 285      *
 286      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 287      *         on success, otherwise a negative legacy Pacemaker return code
 288      */
 289     int (*confirm)(stonith_t *st, int options, const char *node);
 290 
 291     /*!
 292      * \brief Retrieve a list of fencing operations that have occurred for a specific node.
 293      *
 294      * \return Legacy Pacemaker return code
 295      */
 296     int (*history)(stonith_t *st, int options, const char *node, stonith_history_t **output, int timeout);
 297 
 298     int (*register_notification)(
 299         stonith_t *st, const char *event,
 300         void (*notify)(stonith_t *st, stonith_event_t *e));
 301 
 302     /*!
 303      * \brief Remove a previously registered notification for \c event, or all
 304      *        notifications if NULL.
 305      *
 306      * \param[in] st     Fencer connection to use
 307      * \param[in] event  The event to remove notifications for (may be NULL).
 308      *
 309      * \return Legacy Pacemaker return code
 310      */
 311     int (*remove_notification)(stonith_t *st, const char *event);
 312 
 313     /*!
 314      * \brief Register a callback to receive the result of an asynchronous call
 315      *
 316      * \param[in] call_id        The call ID to register callback for
 317      * \param[in] timeout        Default time to wait until callback expires
 318      * \param[in] options        Bitmask of \c stonith_call_options (respects
 319      *                           \c st_opt_timeout_updates and
 320      *                           \c st_opt_report_only_success)
 321      * \param[in] userdata       Pointer that will be given to callback
 322      * \param[in] callback_name  Unique name to identify callback
 323      * \param[in] callback       The callback function to register
 324      *
 325      * \return \c TRUE on success, \c FALSE if call_id is negative, -errno otherwise
 326      */
 327     int (*register_callback)(stonith_t *st,
 328         int call_id,
 329         int timeout,
 330         int options,
 331         void *userdata,
 332         const char *callback_name,
 333         void (*callback)(stonith_t *st, stonith_callback_data_t *data));
 334 
 335     /*!
 336      * \brief Remove a registered callback for a given call id
 337      *
 338      * \return pcmk_ok
 339      */
 340     int (*remove_callback)(stonith_t *st, int call_id, bool all_callbacks);
 341 
 342     /*!
 343      * \brief Unregister fencing level for specified node, pattern or attribute
 344      *
 345      * \param[in] st      Fencer connection to use
 346      * \param[in] options Bitmask of stonith_call_options to pass to the fencer
 347      * \param[in] node    If not NULL, target level by this node name
 348      * \param[in] pattern If not NULL, target by node name using this regex
 349      * \param[in] attr    If not NULL, target by this node attribute
 350      * \param[in] value   If not NULL, target by this node attribute value
 351      * \param[in] level   Index number of level to remove
 352      *
 353      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 354      *         on success, otherwise a negative legacy Pacemaker return code
 355      *
 356      * \note The caller should set only one of node, pattern or attr/value.
 357      */
 358     int (*remove_level_full)(stonith_t *st, int options,
 359                              const char *node, const char *pattern,
 360                              const char *attr, const char *value, int level);
 361 
 362     /*!
 363      * \brief Register fencing level for specified node, pattern or attribute
 364      *
 365      * \param[in] st          Fencer connection to use
 366      * \param[in] options     Bitmask of stonith_call_options to pass to fencer
 367      * \param[in] node        If not NULL, target level by this node name
 368      * \param[in] pattern     If not NULL, target by node name using this regex
 369      * \param[in] attr        If not NULL, target by this node attribute
 370      * \param[in] value       If not NULL, target by this node attribute value
 371      * \param[in] level       Index number of level to add
 372      * \param[in] device_list Devices to use in level
 373      *
 374      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 375      *         on success, otherwise a negative legacy Pacemaker return code
 376      *
 377      * \note The caller should set only one of node, pattern or attr/value.
 378      */
 379     int (*register_level_full)(stonith_t *st, int options,
 380                                const char *node, const char *pattern,
 381                                const char *attr, const char *value,
 382                                int level, stonith_key_value_t *device_list);
 383 
 384     /*!
 385      * \brief Validate an arbitrary stonith device configuration
 386      *
 387      * \param[in]  st            Stonithd connection to use
 388      * \param[in]  call_options  Bitmask of stonith_call_options to use with fencer
 389      * \param[in]  rsc_id        ID used to replace CIB secrets in params
 390      * \param[in]  namespace_s   Namespace of fence agent to validate (optional)
 391      * \param[in]  agent         Fence agent to validate
 392      * \param[in]  params        Configuration parameters to pass to fence agent
 393      * \param[in]  timeout       Fail if no response within this many seconds
 394      * \param[out] output        If non-NULL, where to store any agent output
 395      * \param[out] error_output  If non-NULL, where to store agent error output
 396      *
 397      * \return pcmk_ok if validation succeeds, -errno otherwise
 398      *
 399      * \note If pcmk_ok is returned, the caller is responsible for freeing
 400      *       the output (if requested).
 401      */
 402     int (*validate)(stonith_t *st, int call_options, const char *rsc_id,
 403                     const char *namespace_s, const char *agent,
 404                     stonith_key_value_t *params, int timeout, char **output,
 405                     char **error_output);
 406 
 407     /*!
 408      * \brief Issue a fencing action against a node with requested fencing delay.
 409      *
 410      * \note Possible actions are, 'on', 'off', and 'reboot'.
 411      *
 412      * \param st, stonith connection
 413      * \param options, call options
 414      * \param node, The target node to fence
 415      * \param action, The fencing action to take
 416      * \param timeout, The default per device timeout to use with each device
 417      *                 capable of fencing the target.
 418      * \param delay, Apply a fencing delay. Value -1 means disable also any
 419      *               static/random fencing delays from pcmk_delay_base/max
 420      *
 421      * \return pcmk_ok (if synchronous) or positive call ID (if asynchronous)
 422      *         on success, otherwise a negative legacy Pacemaker return code
 423      */
 424     int (*fence_with_delay)(stonith_t *st, int options, const char *node, const char *action,
 425                             int timeout, int tolerance, int delay);
 426 
 427 } stonith_api_operations_t;
 428 
 429 struct stonith_s
 430 {
 431     enum stonith_state state;
 432 
 433     int call_id;
 434     int call_timeout;   //!< \deprecated Unused
 435     void *st_private;
 436 
 437     stonith_api_operations_t *cmds;
 438 };
 439 /* *INDENT-ON* */
 440 
 441 /* Core functions */
 442 stonith_t *stonith_api_new(void);
 443 void stonith_api_delete(stonith_t * st);
 444 
 445 void stonith_dump_pending_callbacks(stonith_t * st);
 446 
 447 bool stonith_dispatch(stonith_t * st);
 448 
 449 stonith_key_value_t *stonith_key_value_add(stonith_key_value_t * kvp, const char *key,
 450                                            const char *value);
 451 void stonith_key_value_freeall(stonith_key_value_t * kvp, int keys, int values);
 452 
 453 void stonith_history_free(stonith_history_t *history);
 454 
 455 // Convenience functions
 456 int stonith_api_connect_retry(stonith_t *st, const char *name,
 457                               int max_attempts);
 458 const char *stonith_op_state_str(enum op_state state);
 459 
 460 /* Basic helpers that allows nodes to be fenced and the history to be
 461  * queried without mainloop or the caller understanding the full API
 462  *
 463  * At least one of nodeid and uname are required
 464  */
 465 int stonith_api_kick(uint32_t nodeid, const char *uname, int timeout, bool off);
 466 time_t stonith_api_time(uint32_t nodeid, const char *uname, bool in_progress);
 467 
 468 /*
 469  * Helpers for using the above functions without install-time dependencies
 470  *
 471  * Usage:
 472  *  #include <crm/stonith-ng.h>
 473  *
 474  * To turn a node off by corosync nodeid:
 475  *  stonith_api_kick_helper(nodeid, 120, 1);
 476  *
 477  * To check the last fence date/time (also by nodeid):
 478  *  last = stonith_api_time_helper(nodeid, 0);
 479  *
 480  * To check if fencing is in progress:
 481  *  if(stonith_api_time_helper(nodeid, 1) > 0) { ... }
 482  *
 483  * eg.
 484 
 485  #include <stdio.h>
 486  #include <time.h>
 487  #include <crm/stonith-ng.h>
 488  int
 489  main(int argc, char ** argv)
 490  {
 491      int rc = 0;
 492      int nodeid = 102;
 493 
 494      rc = stonith_api_time_helper(nodeid, 0);
 495      printf("%d last fenced at %s\n", nodeid, ctime(rc));
 496 
 497      rc = stonith_api_kick_helper(nodeid, 120, 1);
 498      printf("%d fence result: %d\n", nodeid, rc);
 499 
 500      rc = stonith_api_time_helper(nodeid, 0);
 501      printf("%d last fenced at %s\n", nodeid, ctime(rc));
 502 
 503      return 0;
 504  }
 505 
 506  */
 507 
 508 #  define STONITH_LIBRARY "libstonithd.so.26"
 509 
 510 typedef int (*st_api_kick_fn) (int nodeid, const char *uname, int timeout, bool off);
 511 typedef time_t (*st_api_time_fn) (int nodeid, const char *uname, bool in_progress);
 512 
 513 static inline int
 514 stonith_api_kick_helper(uint32_t nodeid, int timeout, bool off)
     /* [previous][next][first][last][top][bottom][index][help] */
 515 {
 516     static void *st_library = NULL;
 517     static st_api_kick_fn st_kick_fn;
 518 
 519     if (st_library == NULL) {
 520         st_library = dlopen(STONITH_LIBRARY, RTLD_LAZY);
 521     }
 522     if (st_library && st_kick_fn == NULL) {
 523         st_kick_fn = (st_api_kick_fn) dlsym(st_library, "stonith_api_kick");
 524     }
 525     if (st_kick_fn == NULL) {
 526 #ifdef ELIBACC
 527         return -ELIBACC;
 528 #else
 529         return -ENOSYS;
 530 #endif
 531     }
 532 
 533     return (*st_kick_fn) (nodeid, NULL, timeout, off);
 534 }
 535 
 536 static inline time_t
 537 stonith_api_time_helper(uint32_t nodeid, bool in_progress)
     /* [previous][next][first][last][top][bottom][index][help] */
 538 {
 539     static void *st_library = NULL;
 540     static st_api_time_fn st_time_fn;
 541 
 542     if (st_library == NULL) {
 543         st_library = dlopen(STONITH_LIBRARY, RTLD_LAZY);
 544     }
 545     if (st_library && st_time_fn == NULL) {
 546         st_time_fn = (st_api_time_fn) dlsym(st_library, "stonith_api_time");
 547     }
 548     if (st_time_fn == NULL) {
 549         return 0;
 550     }
 551 
 552     return (*st_time_fn) (nodeid, NULL, in_progress);
 553 }
 554 
 555 /**
 556  * Does the given agent describe a stonith resource that can exist?
 557  *
 558  * \param[in] agent     What is the name of the agent?
 559  * \param[in] timeout   Timeout to use when querying.  If 0 is given,
 560  *                      use a default of 120.
 561  *
 562  * \return A boolean
 563  */
 564 bool stonith_agent_exists(const char *agent, int timeout);
 565 
 566 /*!
 567  * \brief Turn stonith action into a more readable string.
 568  *
 569  * \param action Stonith action
 570  */
 571 const char *stonith_action_str(const char *action);
 572 
 573 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
 574 /* Normally we'd put this section in a separate file (crm/fencing/compat.h), but
 575  * we can't do that for the reason noted at the top of this file. That does mean
 576  * we have to duplicate these declarations where they're implemented.
 577  */
 578 
 579 //! \deprecated Use stonith_get_namespace() instead
 580 const char *get_stonith_provider(const char *agent, const char *provider);
 581 
 582 #endif
 583 
 584 #ifdef __cplusplus
 585 }
 586 #endif
 587 
 588 #endif

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