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 PCMK_META_GLOBALLY_UNIQUE from the
  50          * config.
  51          */
  52         return pcmk_ra_cap_params | pcmk_ra_cap_unique | pcmk_ra_cap_stdin
  53                | pcmk_ra_cap_fence_params;
  54 
  55     } else if (!strcasecmp(standard, PCMK_RESOURCE_CLASS_SYSTEMD)
  56                || !strcasecmp(standard, PCMK_RESOURCE_CLASS_SERVICE)
  57                || !strcasecmp(standard, PCMK_RESOURCE_CLASS_LSB)
  58                || !strcasecmp(standard, PCMK_RESOURCE_CLASS_UPSTART)) {
  59 
  60         /* Since service can map to LSB, systemd, or upstart, these should
  61          * have identical capabilities
  62          */
  63         return pcmk_ra_cap_status;
  64 
  65     } else if (!strcasecmp(standard, PCMK_RESOURCE_CLASS_NAGIOS)) {
  66         return pcmk_ra_cap_params;
  67     }
  68     return pcmk_ra_cap_none;
  69 }
  70 
  71 int
  72 pcmk__effective_rc(int rc)
     /* [previous][next][first][last][top][bottom][index][help] */
  73 {
  74     int remapped_rc = rc;
  75 
  76     switch (rc) {
  77         case PCMK_OCF_DEGRADED:
  78             remapped_rc = PCMK_OCF_OK;
  79             break;
  80 
  81         case PCMK_OCF_DEGRADED_PROMOTED:
  82             remapped_rc = PCMK_OCF_RUNNING_PROMOTED;
  83             break;
  84 
  85         default:
  86             break;
  87     }
  88 
  89     return remapped_rc;
  90 }
  91 
  92 char *
  93 crm_generate_ra_key(const char *standard, const char *provider,
     /* [previous][next][first][last][top][bottom][index][help] */
  94                     const char *type)
  95 {
  96     bool std_empty = pcmk__str_empty(standard);
  97     bool prov_empty = pcmk__str_empty(provider);
  98     bool ty_empty = pcmk__str_empty(type);
  99 
 100     if (std_empty || ty_empty) {
 101         return NULL;
 102     }
 103 
 104     return crm_strdup_printf("%s%s%s:%s",
 105                              standard,
 106                              (prov_empty ? "" : ":"), (prov_empty ? "" : provider),
 107                              type);
 108 }
 109 
 110 /*!
 111  * \brief Parse a "standard[:provider]:type" agent specification
 112  *
 113  * \param[in]  spec      Agent specification
 114  * \param[out] standard  Newly allocated memory containing agent standard (or NULL)
 115  * \param[out] provider  Newly allocated memory containing agent provider (or NULL)
 116  * \param[put] type      Newly allocated memory containing agent type (or NULL)
 117  *
 118  * \return pcmk_ok if the string could be parsed, -EINVAL otherwise
 119  *
 120  * \note It is acceptable for the type to contain a ':' if the standard supports
 121  *       that. For example, systemd supports the form "systemd:UNIT@A:B".
 122  * \note It is the caller's responsibility to free the returned values.
 123  */
 124 int
 125 crm_parse_agent_spec(const char *spec, char **standard, char **provider,
     /* [previous][next][first][last][top][bottom][index][help] */
 126                      char **type)
 127 {
 128     char *colon;
 129 
 130     CRM_CHECK(spec && standard && provider && type, return -EINVAL);
 131     *standard = NULL;
 132     *provider = NULL;
 133     *type = NULL;
 134 
 135     colon = strchr(spec, ':');
 136     if ((colon == NULL) || (colon == spec)) {
 137         return -EINVAL;
 138     }
 139 
 140     *standard = strndup(spec, colon - spec);
 141     spec = colon + 1;
 142 
 143     if (pcmk_is_set(pcmk_get_ra_caps(*standard), pcmk_ra_cap_provider)) {
 144         colon = strchr(spec, ':');
 145         if ((colon == NULL) || (colon == spec)) {
 146             free(*standard);
 147             return -EINVAL;
 148         }
 149         *provider = strndup(spec, colon - spec);
 150         spec = colon + 1;
 151     }
 152 
 153     if (*spec == '\0') {
 154         free(*standard);
 155         free(*provider);
 156         return -EINVAL;
 157     }
 158 
 159     *type = strdup(spec);
 160     return pcmk_ok;
 161 }
 162 
 163 /*!
 164  * \brief Check whether a given stonith parameter is handled by Pacemaker
 165  *
 166  * Return true if a given string is the name of one of the special resource
 167  * instance attributes interpreted directly by Pacemaker for stonith-class
 168  * resources.
 169  *
 170  * \param[in] param  Parameter name to check
 171  *
 172  * \return true if \p param is a special fencing parameter
 173  */
 174 bool
 175 pcmk_stonith_param(const char *param)
     /* [previous][next][first][last][top][bottom][index][help] */
 176 {
 177     if (param == NULL) {
 178         return false;
 179     }
 180     if (pcmk__str_any_of(param, PCMK_STONITH_PROVIDES,
 181                          PCMK_STONITH_STONITH_TIMEOUT, NULL)) {
 182         return true;
 183     }
 184     if (!pcmk__starts_with(param, "pcmk_")) { // Short-circuit common case
 185         return false;
 186     }
 187     if (pcmk__str_any_of(param,
 188                          PCMK_STONITH_ACTION_LIMIT,
 189                          PCMK_STONITH_DELAY_BASE,
 190                          PCMK_STONITH_DELAY_MAX,
 191                          PCMK_STONITH_HOST_ARGUMENT,
 192                          PCMK_STONITH_HOST_CHECK,
 193                          PCMK_STONITH_HOST_LIST,
 194                          PCMK_STONITH_HOST_MAP,
 195                          NULL)) {
 196         return true;
 197     }
 198     param = strchr(param + 5, '_'); // Skip past "pcmk_ACTION"
 199     return pcmk__str_any_of(param, "_action", "_timeout", "_retries", NULL);
 200 }
 201 
 202 // Deprecated functions kept only for backward API compatibility
 203 // LCOV_EXCL_START
 204 
 205 #include <crm/common/agents_compat.h>
 206 
 207 bool
 208 crm_provider_required(const char *standard)
     /* [previous][next][first][last][top][bottom][index][help] */
 209 {
 210     return pcmk_is_set(pcmk_get_ra_caps(standard), pcmk_ra_cap_provider);
 211 }
 212 
 213 // LCOV_EXCL_STOP
 214 // End deprecated API

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