LCOV - code coverage report
Current view: top level - common - attrs.c (source / functions) Hit Total Coverage
Test: Pacemaker code coverage Lines: 0 63 0.0 %
Date: 2024-05-07 11:09:47 Functions: 0 3 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2011-2024 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 _GNU_SOURCE
      11             : #  define _GNU_SOURCE
      12             : #endif
      13             : 
      14             : #include <crm_internal.h>
      15             : 
      16             : #include <stdio.h>
      17             : 
      18             : #include <crm/common/xml.h>
      19             : #include <crm/common/scheduler.h>
      20             : #include <crm/common/scheduler_internal.h>
      21             : 
      22             : #define OCF_RESKEY_PREFIX "OCF_RESKEY_"
      23             : #define LRM_TARGET_ENV OCF_RESKEY_PREFIX CRM_META "_" PCMK__META_ON_NODE
      24             : 
      25             : /*!
      26             :  * \internal
      27             :  * \brief Get the node name that should be used to set node attributes
      28             :  *
      29             :  * If given NULL, "auto", or "localhost" as an argument, check the environment
      30             :  * to detect the node name that should be used to set node attributes. (The
      31             :  * caller might not know the correct name, for example if the target is part of
      32             :  * a bundle with \c PCMK_META_CONTAINER_ATTRIBUTE_TARGET set to
      33             :  * \c PCMK_VALUE_HOST.)
      34             :  *
      35             :  * \param[in] name  NULL, "auto" or "localhost" to check environment variables,
      36             :  *                  or anything else to return NULL
      37             :  *
      38             :  * \return Node name that should be used for node attributes based on the
      39             :  *         environment if known, otherwise NULL
      40             :  */
      41             : const char *
      42           0 : pcmk__node_attr_target(const char *name)
      43             : {
      44           0 :     if (name == NULL || pcmk__strcase_any_of(name, "auto", "localhost", NULL)) {
      45           0 :         char buf[128] = OCF_RESKEY_PREFIX;
      46           0 :         size_t offset = sizeof(OCF_RESKEY_PREFIX) - 1;
      47           0 :         char *target_var = crm_meta_name(PCMK_META_CONTAINER_ATTRIBUTE_TARGET);
      48           0 :         char *phys_var = crm_meta_name(PCMK__META_PHYSICAL_HOST);
      49           0 :         const char *target = NULL;
      50           0 :         const char *host_physical = NULL;
      51             : 
      52           0 :         snprintf(buf + offset, sizeof(buf) - offset, "%s", target_var);
      53           0 :         target = getenv(buf);
      54             : 
      55           0 :         snprintf(buf + offset, sizeof(buf) - offset, "%s", phys_var);
      56           0 :         host_physical = getenv(buf);
      57             : 
      58             :         // It is important to use the name by which the scheduler knows us
      59           0 :         if (host_physical
      60           0 :             && pcmk__str_eq(target, PCMK_VALUE_HOST, pcmk__str_casei)) {
      61           0 :             name = host_physical;
      62             : 
      63             :         } else {
      64           0 :             const char *host_pcmk = getenv(LRM_TARGET_ENV);
      65             : 
      66           0 :             if (host_pcmk) {
      67           0 :                 name = host_pcmk;
      68             :             }
      69             :         }
      70           0 :         free(target_var);
      71           0 :         free(phys_var);
      72             : 
      73             :         // TODO? Call pcmk__cluster_local_node_name() if name == NULL
      74             :         // (currently would require linkage against libcrmcluster)
      75           0 :         return name;
      76             :     } else {
      77           0 :         return NULL;
      78             :     }
      79             : }
      80             : 
      81             : /*!
      82             :  * \brief Return the name of the node attribute used as a promotion score
      83             :  *
      84             :  * \param[in] rsc_id  Resource ID that promotion score is for (or NULL to
      85             :  *                    check the OCF_RESOURCE_INSTANCE environment variable)
      86             :  *
      87             :  * \return Newly allocated string with the node attribute name (or NULL on
      88             :  *         error, including no ID or environment variable specified)
      89             :  * \note It is the caller's responsibility to free() the result.
      90             :  */
      91             : char *
      92           0 : pcmk_promotion_score_name(const char *rsc_id)
      93             : {
      94           0 :     if (pcmk__str_empty(rsc_id)) {
      95           0 :         rsc_id = getenv("OCF_RESOURCE_INSTANCE");
      96           0 :         if (pcmk__str_empty(rsc_id)) {
      97           0 :             return NULL;
      98             :         }
      99             :     }
     100           0 :     return crm_strdup_printf("master-%s", rsc_id);
     101             : }
     102             : 
     103             : /*!
     104             :  * \internal
     105             :  * \brief Get the value of a node attribute
     106             :  *
     107             :  * \param[in] node       Node to get attribute for
     108             :  * \param[in] name       Name of node attribute to get
     109             :  * \param[in] target     If this is \c PCMK_VALUE_HOST and \p node is a guest
     110             :  *                       (bundle) node, get the value from the guest's host,
     111             :  *                       otherwise get the value from \p node itself
     112             :  * \param[in] node_type  If getting the value from \p node's host, this
     113             :  *                       indicates whether to check the current or assigned host
     114             :  *
     115             :  * \return Value of \p name attribute for \p node
     116             :  */
     117             : const char *
     118           0 : pcmk__node_attr(const pcmk_node_t *node, const char *name, const char *target,
     119             :                 enum pcmk__rsc_node node_type)
     120             : {
     121           0 :     const char *value = NULL;       // Attribute value to return
     122           0 :     const char *node_type_s = NULL; // Readable equivalent of node_type
     123           0 :     const pcmk_node_t *host = NULL;
     124           0 :     const pcmk_resource_t *container = NULL;
     125             : 
     126           0 :     if ((node == NULL) || (name == NULL)) {
     127           0 :         return NULL;
     128             :     }
     129             : 
     130             :     /* Check the node's own attributes unless this is a guest (bundle) node with
     131             :      * the container host as the attribute target.
     132             :      */
     133           0 :     if (!pcmk__is_guest_or_bundle_node(node)
     134           0 :         || !pcmk__str_eq(target, PCMK_VALUE_HOST, pcmk__str_casei)) {
     135           0 :         value = g_hash_table_lookup(node->details->attrs, name);
     136           0 :         crm_trace("%s='%s' on %s",
     137             :                   name, pcmk__s(value, ""), pcmk__node_name(node));
     138           0 :         return value;
     139             :     }
     140             : 
     141             :     /* This resource needs attributes set for the container's host instead of
     142             :      * for the container itself (useful when the container uses the host's
     143             :      * storage).
     144             :      */
     145           0 :     container = node->details->remote_rsc->container;
     146             : 
     147           0 :     switch (node_type) {
     148           0 :         case pcmk__rsc_node_assigned:
     149           0 :             host = container->allocated_to;
     150           0 :             if (host == NULL) {
     151           0 :                 crm_trace("Skipping %s lookup for %s because "
     152             :                           "its container %s is unassigned",
     153             :                           name, pcmk__node_name(node), container->id);
     154           0 :                 return NULL;
     155             :             }
     156           0 :             node_type_s = "assigned";
     157           0 :             break;
     158             : 
     159           0 :         case pcmk__rsc_node_current:
     160           0 :             if (container->running_on != NULL) {
     161           0 :                 host = container->running_on->data;
     162             :             }
     163           0 :             if (host == NULL) {
     164           0 :                 crm_trace("Skipping %s lookup for %s because "
     165             :                           "its container %s is inactive",
     166             :                           name, pcmk__node_name(node), container->id);
     167           0 :                 return NULL;
     168             :             }
     169           0 :             node_type_s = "current";
     170           0 :             break;
     171             : 
     172           0 :         default:
     173             :             // Add support for other enum pcmk__rsc_node values if needed
     174           0 :             CRM_ASSERT(false);
     175           0 :             break;
     176             :     }
     177             : 
     178           0 :     value = g_hash_table_lookup(host->details->attrs, name);
     179           0 :     crm_trace("%s='%s' for %s on %s container host %s",
     180             :               name, pcmk__s(value, ""), pcmk__node_name(node), node_type_s,
     181             :               pcmk__node_name(host));
     182           0 :     return value;
     183             : }

Generated by: LCOV version 1.14