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

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