LCOV - code coverage report
Current view: top level - common - agents.c (source / functions) Hit Total Coverage
Test: Pacemaker code coverage Lines: 68 68 100.0 %
Date: 2024-05-07 11:09:47 Functions: 5 5 100.0 %

          Line data    Source code
       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         183 : pcmk_get_ra_caps(const char *standard)
      32             : {
      33             :     /* @COMPAT This should probably be case-sensitive, but isn't,
      34             :      * for backward compatibility.
      35             :      */
      36         183 :     if (standard == NULL) {
      37           1 :         return pcmk_ra_cap_none;
      38             : 
      39         182 :     } else if (!strcasecmp(standard, PCMK_RESOURCE_CLASS_OCF)) {
      40         142 :         return pcmk_ra_cap_provider | pcmk_ra_cap_params
      41             :                | pcmk_ra_cap_unique | pcmk_ra_cap_promotable;
      42             : 
      43          40 :     } 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           7 :         return pcmk_ra_cap_params | pcmk_ra_cap_unique | pcmk_ra_cap_stdin
      53             :                | pcmk_ra_cap_fence_params;
      54             : 
      55          33 :     } else if (!strcasecmp(standard, PCMK_RESOURCE_CLASS_SYSTEMD)
      56          30 :                || !strcasecmp(standard, PCMK_RESOURCE_CLASS_SERVICE)
      57          28 :                || !strcasecmp(standard, PCMK_RESOURCE_CLASS_LSB)
      58           6 :                || !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          29 :         return pcmk_ra_cap_status;
      64             : 
      65           4 :     } else if (!strcasecmp(standard, PCMK_RESOURCE_CLASS_NAGIOS)) {
      66           2 :         return pcmk_ra_cap_params;
      67             :     }
      68           2 :     return pcmk_ra_cap_none;
      69             : }
      70             : 
      71             : int
      72         116 : pcmk__effective_rc(int rc)
      73             : {
      74         116 :     int remapped_rc = rc;
      75             : 
      76         116 :     switch (rc) {
      77           1 :         case PCMK_OCF_DEGRADED:
      78           1 :             remapped_rc = PCMK_OCF_OK;
      79           1 :             break;
      80             : 
      81           1 :         case PCMK_OCF_DEGRADED_PROMOTED:
      82           1 :             remapped_rc = PCMK_OCF_RUNNING_PROMOTED;
      83           1 :             break;
      84             : 
      85         114 :         default:
      86         114 :             break;
      87             :     }
      88             : 
      89         116 :     return remapped_rc;
      90             : }
      91             : 
      92             : char *
      93           8 : crm_generate_ra_key(const char *standard, const char *provider,
      94             :                     const char *type)
      95             : {
      96           8 :     bool std_empty = pcmk__str_empty(standard);
      97           8 :     bool prov_empty = pcmk__str_empty(provider);
      98           8 :     bool ty_empty = pcmk__str_empty(type);
      99             : 
     100           8 :     if (std_empty || ty_empty) {
     101           6 :         return NULL;
     102             :     }
     103             : 
     104           2 :     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          11 : crm_parse_agent_spec(const char *spec, char **standard, char **provider,
     126             :                      char **type)
     127             : {
     128             :     char *colon;
     129             : 
     130          11 :     CRM_CHECK(spec && standard && provider && type, return -EINVAL);
     131           7 :     *standard = NULL;
     132           7 :     *provider = NULL;
     133           7 :     *type = NULL;
     134             : 
     135           7 :     colon = strchr(spec, ':');
     136           7 :     if ((colon == NULL) || (colon == spec)) {
     137           1 :         return -EINVAL;
     138             :     }
     139             : 
     140           6 :     *standard = strndup(spec, colon - spec);
     141           6 :     spec = colon + 1;
     142             : 
     143           6 :     if (pcmk_is_set(pcmk_get_ra_caps(*standard), pcmk_ra_cap_provider)) {
     144           4 :         colon = strchr(spec, ':');
     145           4 :         if ((colon == NULL) || (colon == spec)) {
     146           2 :             free(*standard);
     147           2 :             return -EINVAL;
     148             :         }
     149           2 :         *provider = strndup(spec, colon - spec);
     150           2 :         spec = colon + 1;
     151             :     }
     152             : 
     153           4 :     if (*spec == '\0') {
     154           1 :         free(*standard);
     155           1 :         free(*provider);
     156           1 :         return -EINVAL;
     157             :     }
     158             : 
     159           3 :     *type = strdup(spec);
     160           3 :     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          19 : pcmk_stonith_param(const char *param)
     176             : {
     177          19 :     if (param == NULL) {
     178           1 :         return false;
     179             :     }
     180          18 :     if (pcmk__str_any_of(param, PCMK_STONITH_PROVIDES,
     181             :                          PCMK_STONITH_STONITH_TIMEOUT, NULL)) {
     182           2 :         return true;
     183             :     }
     184          16 :     if (!pcmk__starts_with(param, "pcmk_")) { // Short-circuit common case
     185           3 :         return false;
     186             :     }
     187          13 :     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           7 :         return true;
     197             :     }
     198           6 :     param = strchr(param + 5, '_'); // Skip past "pcmk_ACTION"
     199           6 :     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)
     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

Generated by: LCOV version 1.14