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

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