root/include/crm/services.h

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. services_lrm_status_str
  2. services_ocf_exitcode_str
  3. services_get_ocf_exitcode

   1 /*
   2  * Copyright 2010-2020 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_SERVICES__
  11 #  define __PCMK_SERVICES__
  12 
  13 #ifdef __cplusplus
  14 extern "C" {
  15 #endif
  16 
  17 /**
  18  * \file
  19  * \brief Services API
  20  * \ingroup core
  21  */
  22 
  23 #  include <glib.h>
  24 #  include <stdio.h>
  25 #  include <stdint.h>
  26 #  include <string.h>
  27 #  include <stdbool.h>
  28 #  include <sys/types.h>
  29 
  30 #  include "common/results.h"
  31 
  32 #  ifndef OCF_ROOT_DIR
  33 #    define OCF_ROOT_DIR "/usr/lib/ocf"
  34 #  endif
  35 
  36 #  ifndef LSB_ROOT_DIR
  37 #    define LSB_ROOT_DIR "/etc/init.d"
  38 #  endif
  39 
  40 /* TODO: Autodetect these two ?*/
  41 #  ifndef SYSTEMCTL
  42 #    define SYSTEMCTL "/bin/systemctl"
  43 #  endif
  44 
  45 /* Known resource classes */
  46 #define PCMK_RESOURCE_CLASS_OCF     "ocf"
  47 #define PCMK_RESOURCE_CLASS_SERVICE "service"
  48 #define PCMK_RESOURCE_CLASS_LSB     "lsb"
  49 #define PCMK_RESOURCE_CLASS_SYSTEMD "systemd"
  50 #define PCMK_RESOURCE_CLASS_UPSTART "upstart"
  51 #define PCMK_RESOURCE_CLASS_NAGIOS  "nagios"
  52 #define PCMK_RESOURCE_CLASS_STONITH "stonith"
  53 
  54 /* This is the string passed in the OCF_EXIT_REASON_PREFIX environment variable.
  55  * The stderr output that occurs after this prefix is encountered is considered
  56  * the exit reason for a completed operation.
  57  */
  58 #define PCMK_OCF_REASON_PREFIX "ocf-exit-reason:"
  59 
  60 // Agent version to use if agent doesn't specify one
  61 #define PCMK_DEFAULT_AGENT_VERSION "0.1"
  62 
  63 enum lsb_exitcode {
  64     PCMK_LSB_OK                  = 0,
  65     PCMK_LSB_UNKNOWN_ERROR       = 1,
  66     PCMK_LSB_INVALID_PARAM       = 2,
  67     PCMK_LSB_UNIMPLEMENT_FEATURE = 3,
  68     PCMK_LSB_INSUFFICIENT_PRIV   = 4,
  69     PCMK_LSB_NOT_INSTALLED       = 5,
  70     PCMK_LSB_NOT_CONFIGURED      = 6,
  71     PCMK_LSB_NOT_RUNNING         = 7,
  72 };
  73 
  74 /* The return codes for the status operation are not the same for other
  75  * operatios - go figure
  76  */
  77 enum lsb_status_exitcode {
  78     PCMK_LSB_STATUS_OK             = 0,
  79     PCMK_LSB_STATUS_VAR_PID        = 1,
  80     PCMK_LSB_STATUS_VAR_LOCK       = 2,
  81     PCMK_LSB_STATUS_NOT_RUNNING    = 3,
  82     PCMK_LSB_STATUS_UNKNOWN        = 4,
  83 
  84     /* custom codes should be in the 150-199 range reserved for application use */
  85     PCMK_LSB_STATUS_NOT_INSTALLED      = 150,
  86     PCMK_LSB_STATUS_INSUFFICIENT_PRIV  = 151,
  87 };
  88 
  89 enum op_status {
  90     PCMK_LRM_OP_UNKNOWN = -2,
  91     PCMK_LRM_OP_PENDING = -1,
  92     PCMK_LRM_OP_DONE,
  93     PCMK_LRM_OP_CANCELLED,
  94     PCMK_LRM_OP_TIMEOUT,
  95     PCMK_LRM_OP_NOTSUPPORTED,
  96     PCMK_LRM_OP_ERROR,
  97     PCMK_LRM_OP_ERROR_HARD,
  98     PCMK_LRM_OP_ERROR_FATAL,
  99     PCMK_LRM_OP_NOT_INSTALLED,
 100     PCMK_LRM_OP_NOT_CONNECTED,
 101     PCMK_LRM_OP_INVALID,
 102 };
 103 
 104 enum nagios_exitcode {
 105     NAGIOS_STATE_OK        = 0,
 106     NAGIOS_STATE_WARNING   = 1,
 107     NAGIOS_STATE_CRITICAL  = 2,
 108     NAGIOS_STATE_UNKNOWN   = 3,
 109     NAGIOS_STATE_DEPENDENT = 4,
 110 
 111     NAGIOS_INSUFFICIENT_PRIV = 100,
 112     NAGIOS_NOT_INSTALLED     = 101,
 113 };
 114 
 115 enum svc_action_flags {
 116     /* On timeout, only kill pid, do not kill entire pid group */
 117     SVC_ACTION_LEAVE_GROUP = 0x01,
 118     SVC_ACTION_NON_BLOCKED = 0x02,
 119 };
 120 
 121 typedef struct svc_action_private_s svc_action_private_t;
 122 typedef struct svc_action_s {
 123     char *id;
 124     char *rsc;
 125     char *action;
 126     guint interval_ms;
 127 
 128     char *standard;
 129     char *provider;
 130     char *agent;
 131 
 132     int timeout;
 133     GHashTable *params; /* used for setting up environment for ocf-ra &
 134                            alert agents
 135                            and to be sent via stdin for fence-agents
 136                          */
 137 
 138     int rc;
 139     int pid;
 140     int cancel;
 141     int status;
 142     int sequence;
 143     int expected_rc;
 144     int synchronous;
 145     enum svc_action_flags flags;
 146 
 147     char *stderr_data;
 148     char *stdout_data;
 149 
 150     /*!
 151      * Data stored by the creator of the action.
 152      *
 153      * This may be used to hold data that is needed later on by a callback,
 154      * for example.
 155      */
 156     void *cb_data;
 157 
 158     svc_action_private_t *opaque;
 159 } svc_action_t;
 160 
 161 /**
 162  * \brief Get a list of files or directories in a given path
 163  *
 164  * \param[in] root       full path to a directory to read
 165  * \param[in] files      return list of files if TRUE or directories if FALSE
 166  * \param[in] executable if TRUE and files is TRUE, only return executable files
 167  *
 168  * \return a list of what was found.  The list items are char *.
 169  * \note It is the caller's responsibility to free the result with g_list_free_full(list, free).
 170  */
 171     GList *get_directory_list(const char *root, gboolean files, gboolean executable);
 172 
 173 /**
 174  * Get a list of services
 175  *
 176  * \return a list of services.  The list items are gchar *.  This list _must_
 177  *         be destroyed using g_list_free_full(list, free).
 178  */
 179     GList *services_list(void);
 180 
 181 /**
 182  * \brief Get a list of providers
 183  *
 184  * \param[in] standard  list providers of this standard (e.g. ocf, lsb, etc.)
 185  *
 186  * \return a list of providers as char * list items (or NULL if standard does not support providers)
 187  * \note The caller is responsible for freeing the result using g_list_free_full(list, free).
 188  */
 189     GList *resources_list_providers(const char *standard);
 190 
 191 /**
 192  * \brief Get a list of resource agents
 193  *
 194  * \param[in] standard  list agents using this standard (e.g. ocf, lsb, etc.) (or NULL for all)
 195  * \param[in] provider  list agents from this provider (or NULL for all)
 196  *
 197  * \return a list of resource agents.  The list items are char *.
 198  * \note The caller is responsible for freeing the result using g_list_free_full(list, free).
 199  */
 200     GList *resources_list_agents(const char *standard, const char *provider);
 201 
 202 /**
 203  * Get list of available standards
 204  *
 205  * \return a list of resource standards. The list items are char *. This list _must_
 206  *         be destroyed using g_list_free_full(list, free).
 207  */
 208     GList *resources_list_standards(void);
 209 
 210 /**
 211  * Does the given standard, provider, and agent describe a resource that can exist?
 212  *
 213  * \param[in] standard  Which class of agent does the resource belong to?
 214  * \param[in] provider  What provides the agent (NULL for most standards)?
 215  * \param[in] agent     What is the name of the agent?
 216  *
 217  * \return A boolean
 218  */
 219     gboolean resources_agent_exists(const char *standard, const char *provider, const char *agent);
 220 
 221 svc_action_t *services_action_create(const char *name, const char *action,
 222                                      guint interval_ms, int timeout /* ms */);
 223 
 224 /**
 225  * \brief Create a new resource action
 226  *
 227  * \param[in] name        Name of resource
 228  * \param[in] standard    Resource agent standard (ocf, lsb, etc.)
 229  * \param[in] provider    Resource agent provider
 230  * \param[in] agent       Resource agent name
 231  * \param[in] action      action (start, stop, monitor, etc.)
 232  * \param[in] interval_ms How often to repeat this action (if 0, execute once)
 233  * \param[in] timeout     Consider action failed if it does not complete in this many milliseconds
 234  * \param[in] params      Action parameters
 235  *
 236  * \return newly allocated action instance
 237  *
 238  * \post After the call, 'params' is owned, and later free'd by the svc_action_t result
 239  * \note The caller is responsible for freeing the return value using
 240  *       services_action_free().
 241  */
 242 svc_action_t *resources_action_create(const char *name, const char *standard,
 243                                       const char *provider, const char *agent,
 244                                       const char *action, guint interval_ms,
 245                                       int timeout /* ms */, GHashTable *params,
 246                                       enum svc_action_flags flags);
 247 
 248 /**
 249  * Kick a recurring action so it is scheduled immediately for re-execution
 250  */
 251 gboolean services_action_kick(const char *name, const char *action,
 252                               guint interval_ms);
 253 
 254     const char *resources_find_service_class(const char *agent);
 255 
 256 /**
 257  * Utilize services API to execute an arbitrary command.
 258  *
 259  * This API has useful infrastructure in place to be able to run a command
 260  * in the background and get notified via a callback when the command finishes.
 261  *
 262  * \param[in] exec command to execute
 263  * \param[in] args arguments to the command, NULL terminated
 264  *
 265  * \return a svc_action_t object, used to pass to the execute function
 266  * (services_action_sync() or services_action_async()) and is
 267  * provided to the callback.
 268  */
 269     svc_action_t *services_action_create_generic(const char *exec, const char *args[]);
 270 
 271     void services_action_cleanup(svc_action_t * op);
 272     void services_action_free(svc_action_t * op);
 273     int services_action_user(svc_action_t *op, const char *user);
 274 
 275     gboolean services_action_sync(svc_action_t * op);
 276 
 277 /**
 278  * Run an action asynchronously.
 279  *
 280  * \param[in] op services action data
 281  * \param[in] action_callback callback for when the action completes
 282  * \param[in] action_fork_callback callback for when action forked successfully
 283  *
 284  * \retval TRUE succesfully started execution
 285  * \retval FALSE failed to start execution, no callback will be received
 286  */
 287     gboolean services_action_async_fork_notify(svc_action_t * op,
 288         void (*action_callback) (svc_action_t *),
 289         void (*action_fork_callback) (svc_action_t *));
 290 
 291     gboolean services_action_async(svc_action_t * op,
 292                                    void (*action_callback) (svc_action_t *));
 293 
 294 gboolean services_action_cancel(const char *name, const char *action,
 295                                 guint interval_ms);
 296 
 297 /* functions for alert agents */
 298 svc_action_t *services_alert_create(const char *id, const char *exec,
 299                                    int timeout, GHashTable *params,
 300                                    int sequence, void *cb_data);
 301 gboolean services_alert_async(svc_action_t *action,
 302                               void (*cb)(svc_action_t *op));
 303 
 304     static inline const char *services_lrm_status_str(enum op_status status) {
     /* [previous][next][first][last][top][bottom][index][help] */
 305         switch (status) {
 306             case PCMK_LRM_OP_PENDING:
 307                 return "pending";
 308                 case PCMK_LRM_OP_DONE:return "complete";
 309                 case PCMK_LRM_OP_CANCELLED:return "Cancelled";
 310                 case PCMK_LRM_OP_TIMEOUT:return "Timed Out";
 311                 case PCMK_LRM_OP_NOTSUPPORTED:return "NOT SUPPORTED";
 312                 case PCMK_LRM_OP_ERROR:return "Error";
 313                 case PCMK_LRM_OP_NOT_INSTALLED:return "Not installed";
 314                 case PCMK_LRM_OP_NOT_CONNECTED:return "No executor connection";
 315                 case PCMK_LRM_OP_INVALID:return "Cannot execute now";
 316                 default:return "UNKNOWN!";
 317         }
 318     }
 319 
 320     static inline const char *services_ocf_exitcode_str(enum ocf_exitcode code) {
     /* [previous][next][first][last][top][bottom][index][help] */
 321         switch (code) {
 322             case PCMK_OCF_OK:
 323                 return "ok";
 324             case PCMK_OCF_UNKNOWN_ERROR:
 325                 return "error";
 326             case PCMK_OCF_INVALID_PARAM:
 327                 return "invalid parameter";
 328             case PCMK_OCF_UNIMPLEMENT_FEATURE:
 329                 return "unimplemented feature";
 330             case PCMK_OCF_INSUFFICIENT_PRIV:
 331                 return "insufficient privileges";
 332             case PCMK_OCF_NOT_INSTALLED:
 333                 return "not installed";
 334             case PCMK_OCF_NOT_CONFIGURED:
 335                 return "not configured";
 336             case PCMK_OCF_NOT_RUNNING:
 337                 return "not running";
 338             case PCMK_OCF_RUNNING_MASTER:
 339                 return "master";
 340             case PCMK_OCF_FAILED_MASTER:
 341                 return "master (failed)";
 342             case PCMK_OCF_SIGNAL:
 343                 return "OCF_SIGNAL";
 344             case PCMK_OCF_NOT_SUPPORTED:
 345                 return "OCF_NOT_SUPPORTED";
 346             case PCMK_OCF_PENDING:
 347                 return "OCF_PENDING";
 348             case PCMK_OCF_CANCELLED:
 349                 return "OCF_CANCELLED";
 350             case PCMK_OCF_TIMEOUT:
 351                 return "OCF_TIMEOUT";
 352             case PCMK_OCF_OTHER_ERROR:
 353                 return "OCF_OTHER_ERROR";
 354             case PCMK_OCF_DEGRADED:
 355                 return "OCF_DEGRADED";
 356             case PCMK_OCF_DEGRADED_MASTER:
 357                 return "OCF_DEGRADED_MASTER";
 358             default:
 359                 return "unknown";
 360         }
 361     }
 362 
 363     /**
 364      * \brief Get OCF equivalent of LSB exit code
 365      *
 366      * \param[in] action        LSB action that produced exit code
 367      * \param[in] lsb_exitcode  Exit code of LSB action
 368      *
 369      * \return PCMK_OCF_* constant that corresponds to LSB exit code
 370      */
 371     static inline enum ocf_exitcode
 372     services_get_ocf_exitcode(const char *action, int lsb_exitcode)
     /* [previous][next][first][last][top][bottom][index][help] */
 373     {
 374         /* For non-status actions, LSB and OCF share error code meaning <= 7 */
 375         if (action && strcmp(action, "status") && strcmp(action, "monitor")) {
 376             if ((lsb_exitcode < 0) || (lsb_exitcode > PCMK_LSB_NOT_RUNNING)) {
 377                 return PCMK_OCF_UNKNOWN_ERROR;
 378             }
 379             return (enum ocf_exitcode)lsb_exitcode;
 380         }
 381 
 382         /* status has different return codes */
 383         switch (lsb_exitcode) {
 384             case PCMK_LSB_STATUS_OK:
 385                 return PCMK_OCF_OK;
 386             case PCMK_LSB_STATUS_NOT_INSTALLED:
 387                 return PCMK_OCF_NOT_INSTALLED;
 388             case PCMK_LSB_STATUS_INSUFFICIENT_PRIV:
 389                 return PCMK_OCF_INSUFFICIENT_PRIV;
 390             case PCMK_LSB_STATUS_VAR_PID:
 391             case PCMK_LSB_STATUS_VAR_LOCK:
 392             case PCMK_LSB_STATUS_NOT_RUNNING:
 393                 return PCMK_OCF_NOT_RUNNING;
 394         }
 395         return PCMK_OCF_UNKNOWN_ERROR;
 396     }
 397 
 398 #  ifdef __cplusplus
 399 }
 400 #  endif
 401 
 402 #endif                          /* __PCMK_SERVICES__ */

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