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

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