root/lib/common/nodes.c

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

DEFINITIONS

This source file includes following definitions.
  1. pcmk__free_node_copy
  2. pcmk_node_is_online
  3. pcmk_node_is_pending
  4. pcmk_node_is_clean
  5. pcmk_node_is_shutting_down
  6. pcmk_node_is_in_maintenance
  7. pcmk_foreach_active_resource
  8. pcmk__xe_add_node
  9. pcmk__find_node_in_list
  10. pcmk_cib_node_shutdown

   1 /*
   2  * Copyright 2022-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 #include <crm_internal.h>
  11 
  12 #include <libxml/tree.h>        // xmlNode
  13 #include <crm/common/nvpair.h>
  14 
  15 /*!
  16  * \internal
  17  * \brief Free a copy of a node object
  18  *
  19  * \param[in] data  Node copy (created by pe__copy_node()) to free
  20  */
  21 void
  22 pcmk__free_node_copy(void *data)
     /* [previous][next][first][last][top][bottom][index][help] */
  23 {
  24     if (data != NULL) {
  25         pcmk_node_t *node = data;
  26 
  27         if (node->assign != NULL) {
  28             // This is the only member allocated separately for a node copy
  29             free(node->assign);
  30         }
  31         free(node);
  32     }
  33 }
  34 
  35 /*!
  36  * \internal
  37  * \brief Check whether a node is online
  38  *
  39  * \param[in] node  Node to check
  40  *
  41  * \return true if \p node is online, otherwise false
  42  */
  43 bool
  44 pcmk_node_is_online(const pcmk_node_t *node)
     /* [previous][next][first][last][top][bottom][index][help] */
  45 {
  46     return (node != NULL) && node->details->online;
  47 }
  48 
  49 /*!
  50  * \internal
  51  * \brief Check whether a node is pending
  52  *
  53  * Check whether a node is pending. A node is pending if it is a member of the
  54  * cluster but not the controller group, which means it is in the process of
  55  * either joining or leaving the cluster.
  56  *
  57  * \param[in] node  Node to check
  58  *
  59  * \return true if \p node is pending, otherwise false
  60  */
  61 bool
  62 pcmk_node_is_pending(const pcmk_node_t *node)
     /* [previous][next][first][last][top][bottom][index][help] */
  63 {
  64     return (node != NULL) && node->details->pending;
  65 }
  66 
  67 /*!
  68  * \internal
  69  * \brief Check whether a node is clean
  70  *
  71  * Check whether a node is clean. A node is clean if it is a cluster node or
  72  * remote node that has been seen by the cluster at least once, or the
  73  * startup-fencing cluster option is false; and the node, and its host if a
  74  * guest or bundle node, are not scheduled to be fenced.
  75  *
  76  * \param[in] node  Node to check
  77  *
  78  * \return true if \p node is clean, otherwise false
  79  */
  80 bool
  81 pcmk_node_is_clean(const pcmk_node_t *node)
     /* [previous][next][first][last][top][bottom][index][help] */
  82 {
  83     return (node != NULL) && !(node->details->unclean);
  84 }
  85 
  86 /*!
  87  * \internal
  88  * \brief Check whether a node is shutting down
  89  *
  90  * \param[in] node  Node to check
  91  *
  92  * \return true if \p node is shutting down, otherwise false
  93  */
  94 bool
  95 pcmk_node_is_shutting_down(const pcmk_node_t *node)
     /* [previous][next][first][last][top][bottom][index][help] */
  96 {
  97     return (node != NULL) && node->details->shutdown;
  98 }
  99 
 100 /*!
 101  * \internal
 102  * \brief Check whether a node is in maintenance mode
 103  *
 104  * \param[in] node  Node to check
 105  *
 106  * \return true if \p node is in maintenance mode, otherwise false
 107  */
 108 bool
 109 pcmk_node_is_in_maintenance(const pcmk_node_t *node)
     /* [previous][next][first][last][top][bottom][index][help] */
 110 {
 111     return (node != NULL) && node->details->maintenance;
 112 }
 113 
 114 /*!
 115  * \internal
 116  * \brief Call a function for each resource active on a node
 117  *
 118  * Call a caller-supplied function with a caller-supplied argument for each
 119  * resource that is active on a given node. If the function returns false, this
 120  * function will return immediately without processing any remaining resources.
 121  *
 122  * \param[in] node  Node to check
 123  *
 124  * \return Result of last call of \p fn (or false if none)
 125  */
 126 bool
 127 pcmk_foreach_active_resource(pcmk_node_t *node,
     /* [previous][next][first][last][top][bottom][index][help] */
 128                              bool (*fn)(pcmk_resource_t *, void *),
 129                              void *user_data)
 130 {
 131     bool result = false;
 132 
 133     if ((node != NULL) && (fn != NULL)) {
 134         for (GList *item = node->details->running_rsc; item != NULL;
 135              item = item->next) {
 136 
 137             result = fn((pcmk_resource_t *) item->data, user_data);
 138             if (!result) {
 139                 break;
 140             }
 141         }
 142     }
 143     return result;
 144 }
 145 
 146 void
 147 pcmk__xe_add_node(xmlNode *xml, const char *node, int nodeid)
     /* [previous][next][first][last][top][bottom][index][help] */
 148 {
 149     pcmk__assert(xml != NULL);
 150 
 151     if (node != NULL) {
 152         crm_xml_add(xml, PCMK__XA_ATTR_HOST, node);
 153     }
 154 
 155     if (nodeid > 0) {
 156         crm_xml_add_int(xml, PCMK__XA_ATTR_HOST_ID, nodeid);
 157     }
 158 }
 159 
 160 /*!
 161  * \internal
 162  * \brief Find a node by name in a list of nodes
 163  *
 164  * \param[in] nodes      List of nodes (as pcmk_node_t*)
 165  * \param[in] node_name  Name of node to find
 166  *
 167  * \return Node from \p nodes that matches \p node_name if any, otherwise NULL
 168  */
 169 pcmk_node_t *
 170 pcmk__find_node_in_list(const GList *nodes, const char *node_name)
     /* [previous][next][first][last][top][bottom][index][help] */
 171 {
 172     if (node_name != NULL) {
 173         for (const GList *iter = nodes; iter != NULL; iter = iter->next) {
 174             pcmk_node_t *node = (pcmk_node_t *) iter->data;
 175 
 176             if (pcmk__str_eq(node->priv->name, node_name, pcmk__str_casei)) {
 177                 return node;
 178             }
 179         }
 180     }
 181     return NULL;
 182 }
 183 
 184 #define XP_SHUTDOWN "//" PCMK__XE_NODE_STATE "[@" PCMK_XA_UNAME "='%s']/"   \
 185     PCMK__XE_TRANSIENT_ATTRIBUTES "/" PCMK_XE_INSTANCE_ATTRIBUTES "/"       \
 186     PCMK_XE_NVPAIR "[@" PCMK_XA_NAME "='" PCMK__NODE_ATTR_SHUTDOWN "']"
 187 
 188 /*!
 189  * \brief Get value of a node's shutdown attribute from CIB, if present
 190  *
 191  * \param[in] cib   CIB to check
 192  * \param[in] node  Name of node to check
 193  *
 194  * \return Value of shutdown attribute for \p node in \p cib if any,
 195  *         otherwise NULL
 196  * \note The return value is a pointer into \p cib and so is valid only for the
 197  *       lifetime of that object.
 198  */
 199 const char *
 200 pcmk_cib_node_shutdown(xmlNode *cib, const char *node)
     /* [previous][next][first][last][top][bottom][index][help] */
 201 {
 202     if ((cib != NULL) && (node != NULL)) {
 203         char *xpath = crm_strdup_printf(XP_SHUTDOWN, node);
 204         xmlNode *match = get_xpath_object(xpath, cib, LOG_TRACE);
 205 
 206         free(xpath);
 207         if (match != NULL) {
 208             return crm_element_value(match, PCMK_XA_VALUE);
 209         }
 210     }
 211     return NULL;
 212 }

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