root/lib/common/agents.c

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

DEFINITIONS

This source file includes following definitions.
  1. pcmk_get_ra_caps
  2. pcmk__effective_rc
  3. crm_generate_ra_key
  4. crm_parse_agent_spec
  5. pcmk_stonith_param
  6. crm_provider_required

   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 #include <crm_internal.h>
  11 
  12 #ifndef _GNU_SOURCE
  13 #  define _GNU_SOURCE
  14 #endif
  15 
  16 #include <stdio.h>
  17 #include <string.h>
  18 #include <strings.h>
  19 
  20 #include <crm/crm.h>
  21 #include <crm/common/util.h>
  22 
  23 /*!
  24  * \brief Get capabilities of a resource agent standard
  25  *
  26  * \param[in] standard  Standard name
  27  *
  28  * \return Bitmask of enum pcmk_ra_caps values
  29  */
  30 uint32_t
  31 pcmk_get_ra_caps(const char *standard)
     /* [previous][next][first][last][top][bottom][index][help] */
  32 {
  33     /* @COMPAT This should probably be case-sensitive, but isn't,
  34      * for backward compatibility.
  35      */
  36     if (standard == NULL) {
  37         return pcmk_ra_cap_none;
  38 
  39     } else if (!strcasecmp(standard, PCMK_RESOURCE_CLASS_OCF)) {
  40         return pcmk_ra_cap_provider | pcmk_ra_cap_params
  41                | pcmk_ra_cap_unique | pcmk_ra_cap_promotable;
  42 
  43     } else if (!strcasecmp(standard, PCMK_RESOURCE_CLASS_STONITH)) {
  44         /* @COMPAT Stonith resources can't really be unique clones, but we've
  45          * allowed it in the past and have it in some scheduler regression tests
  46          * (which were likely never used as real configurations).
  47          *
  48          * @TODO Remove pcmk_ra_cap_unique at the next major schema version
  49          * bump, with a transform to remove globally-unique from the config.
  50          */
  51         return pcmk_ra_cap_params | pcmk_ra_cap_unique | pcmk_ra_cap_stdin
  52                | pcmk_ra_cap_fence_params;
  53 
  54     } else if (!strcasecmp(standard, PCMK_RESOURCE_CLASS_SYSTEMD)
  55                || !strcasecmp(standard, PCMK_RESOURCE_CLASS_SERVICE)
  56                || !strcasecmp(standard, PCMK_RESOURCE_CLASS_LSB)
  57                || !strcasecmp(standard, PCMK_RESOURCE_CLASS_UPSTART)) {
  58 
  59         /* Since service can map to LSB, systemd, or upstart, these should
  60          * have identical capabilities
  61          */
  62         return pcmk_ra_cap_status;
  63 
  64     } else if (!strcasecmp(standard, PCMK_RESOURCE_CLASS_NAGIOS)) {
  65         return pcmk_ra_cap_params;
  66     }
  67     return pcmk_ra_cap_none;
  68 }
  69 
  70 int
  71 pcmk__effective_rc(int rc)
     /* [previous][next][first][last][top][bottom][index][help] */
  72 {
  73     int remapped_rc = rc;
  74 
  75     switch (rc) {
  76         case PCMK_OCF_DEGRADED:
  77             remapped_rc = PCMK_OCF_OK;
  78             break;
  79 
  80         case PCMK_OCF_DEGRADED_PROMOTED:
  81             remapped_rc = PCMK_OCF_RUNNING_PROMOTED;
  82             break;
  83 
  84         default:
  85             break;
  86     }
  87 
  88     return remapped_rc;
  89 }
  90 
  91 char *
  92 crm_generate_ra_key(const char *standard, const char *provider,
     /* [previous][next][first][last][top][bottom][index][help] */
  93                     const char *type)
  94 {
  95     bool std_empty = pcmk__str_empty(standard);
  96     bool prov_empty = pcmk__str_empty(provider);
  97     bool ty_empty = pcmk__str_empty(type);
  98 
  99     if (std_empty || ty_empty) {
 100         return NULL;
 101     }
 102 
 103     return crm_strdup_printf("%s%s%s:%s",
 104                              standard,
 105                              (prov_empty ? "" : ":"), (prov_empty ? "" : provider),
 106                              type);
 107 }
 108 
 109 /*!
 110  * \brief Parse a "standard[:provider]:type" agent specification
 111  *
 112  * \param[in]  spec      Agent specification
 113  * \param[out] standard  Newly allocated memory containing agent standard (or NULL)
 114  * \param[out] provider  Newly allocated memory containing agent provider (or NULL)
 115  * \param[put] type      Newly allocated memory containing agent type (or NULL)
 116  *
 117  * \return pcmk_ok if the string could be parsed, -EINVAL otherwise
 118  *
 119  * \note It is acceptable for the type to contain a ':' if the standard supports
 120  *       that. For example, systemd supports the form "systemd:UNIT@A:B".
 121  * \note It is the caller's responsibility to free the returned values.
 122  */
 123 int
 124 crm_parse_agent_spec(const char *spec, char **standard, char **provider,
     /* [previous][next][first][last][top][bottom][index][help] */
 125                      char **type)
 126 {
 127     char *colon;
 128 
 129     CRM_CHECK(spec && standard && provider && type, return -EINVAL);
 130     *standard = NULL;
 131     *provider = NULL;
 132     *type = NULL;
 133 
 134     colon = strchr(spec, ':');
 135     if ((colon == NULL) || (colon == spec)) {
 136         return -EINVAL;
 137     }
 138 
 139     *standard = strndup(spec, colon - spec);
 140     spec = colon + 1;
 141 
 142     if (pcmk_is_set(pcmk_get_ra_caps(*standard), pcmk_ra_cap_provider)) {
 143         colon = strchr(spec, ':');
 144         if ((colon == NULL) || (colon == spec)) {
 145             free(*standard);
 146             return -EINVAL;
 147         }
 148         *provider = strndup(spec, colon - spec);
 149         spec = colon + 1;
 150     }
 151 
 152     if (*spec == '\0') {
 153         free(*standard);
 154         free(*provider);
 155         return -EINVAL;
 156     }
 157 
 158     *type = strdup(spec);
 159     return pcmk_ok;
 160 }
 161 
 162 /*!
 163  * \brief Check whether a given stonith parameter is handled by Pacemaker
 164  *
 165  * Return true if a given string is the name of one of the special resource
 166  * instance attributes interpreted directly by Pacemaker for stonith-class
 167  * resources.
 168  *
 169  * \param[in] param  Parameter name to check
 170  *
 171  * \return true if \p param is a special fencing parameter
 172  */
 173 bool
 174 pcmk_stonith_param(const char *param)
     /* [previous][next][first][last][top][bottom][index][help] */
 175 {
 176     if (param == NULL) {
 177         return false;
 178     }
 179     if (pcmk__str_any_of(param, PCMK_STONITH_PROVIDES,
 180                          PCMK_STONITH_STONITH_TIMEOUT, NULL)) {
 181         return true;
 182     }
 183     if (!pcmk__starts_with(param, "pcmk_")) { // Short-circuit common case
 184         return false;
 185     }
 186     if (pcmk__str_any_of(param,
 187                          PCMK_STONITH_ACTION_LIMIT,
 188                          PCMK_STONITH_DELAY_BASE,
 189                          PCMK_STONITH_DELAY_MAX,
 190                          PCMK_STONITH_HOST_ARGUMENT,
 191                          PCMK_STONITH_HOST_CHECK,
 192                          PCMK_STONITH_HOST_LIST,
 193                          PCMK_STONITH_HOST_MAP,
 194                          NULL)) {
 195         return true;
 196     }
 197     param = strchr(param + 5, '_'); // Skip past "pcmk_ACTION"
 198     return pcmk__str_any_of(param, "_action", "_timeout", "_retries", NULL);
 199 }
 200 
 201 // Deprecated functions kept only for backward API compatibility
 202 // LCOV_EXCL_START
 203 
 204 #include <crm/common/agents_compat.h>
 205 
 206 bool
 207 crm_provider_required(const char *standard)
     /* [previous][next][first][last][top][bottom][index][help] */
 208 {
 209     return pcmk_is_set(pcmk_get_ra_caps(standard), pcmk_ra_cap_provider);
 210 }
 211 
 212 // LCOV_EXCL_STOP
 213 // End deprecated API

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