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

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