Line data Source code
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 Check whether a node is online 18 : * 19 : * \param[in] node Node to check 20 : * 21 : * \return true if \p node is online, otherwise false 22 : */ 23 : bool 24 3 : pcmk_node_is_online(const pcmk_node_t *node) 25 : { 26 3 : return (node != NULL) && node->details->online; 27 : } 28 : 29 : /*! 30 : * \internal 31 : * \brief Check whether a node is pending 32 : * 33 : * Check whether a node is pending. A node is pending if it is a member of the 34 : * cluster but not the controller group, which means it is in the process of 35 : * either joining or leaving the cluster. 36 : * 37 : * \param[in] node Node to check 38 : * 39 : * \return true if \p node is pending, otherwise false 40 : */ 41 : bool 42 3 : pcmk_node_is_pending(const pcmk_node_t *node) 43 : { 44 3 : return (node != NULL) && node->details->pending; 45 : } 46 : 47 : /*! 48 : * \internal 49 : * \brief Check whether a node is clean 50 : * 51 : * Check whether a node is clean. A node is clean if it is a cluster node or 52 : * remote node that has been seen by the cluster at least once, or the 53 : * startup-fencing cluster option is false; and the node, and its host if a 54 : * guest or bundle node, are not scheduled to be fenced. 55 : * 56 : * \param[in] node Node to check 57 : * 58 : * \return true if \p node is clean, otherwise false 59 : */ 60 : bool 61 3 : pcmk_node_is_clean(const pcmk_node_t *node) 62 : { 63 3 : return (node != NULL) && !(node->details->unclean); 64 : } 65 : 66 : /*! 67 : * \internal 68 : * \brief Check whether a node is shutting down 69 : * 70 : * \param[in] node Node to check 71 : * 72 : * \return true if \p node is shutting down, otherwise false 73 : */ 74 : bool 75 3 : pcmk_node_is_shutting_down(const pcmk_node_t *node) 76 : { 77 3 : return (node != NULL) && node->details->shutdown; 78 : } 79 : 80 : /*! 81 : * \internal 82 : * \brief Check whether a node is in maintenance mode 83 : * 84 : * \param[in] node Node to check 85 : * 86 : * \return true if \p node is in maintenance mode, otherwise false 87 : */ 88 : bool 89 3 : pcmk_node_is_in_maintenance(const pcmk_node_t *node) 90 : { 91 3 : return (node != NULL) && node->details->maintenance; 92 : } 93 : 94 : /*! 95 : * \internal 96 : * \brief Call a function for each resource active on a node 97 : * 98 : * Call a caller-supplied function with a caller-supplied argument for each 99 : * resource that is active on a given node. If the function returns false, this 100 : * function will return immediately without processing any remaining resources. 101 : * 102 : * \param[in] node Node to check 103 : * 104 : * \return Result of last call of \p fn (or false if none) 105 : */ 106 : bool 107 7 : pcmk_foreach_active_resource(pcmk_node_t *node, 108 : bool (*fn)(pcmk_resource_t *, void *), 109 : void *user_data) 110 : { 111 7 : bool result = false; 112 : 113 7 : if ((node != NULL) && (fn != NULL)) { 114 9 : for (GList *item = node->details->running_rsc; item != NULL; 115 5 : item = item->next) { 116 : 117 6 : result = fn((pcmk_resource_t *) item->data, user_data); 118 6 : if (!result) { 119 1 : break; 120 : } 121 : } 122 : } 123 7 : return result; 124 : } 125 : 126 : void 127 7 : pcmk__xe_add_node(xmlNode *xml, const char *node, int nodeid) 128 : { 129 7 : CRM_ASSERT(xml != NULL); 130 : 131 6 : if (node != NULL) { 132 4 : crm_xml_add(xml, PCMK__XA_ATTR_HOST, node); 133 : } 134 : 135 6 : if (nodeid > 0) { 136 4 : crm_xml_add_int(xml, PCMK__XA_ATTR_HOST_ID, nodeid); 137 : } 138 6 : } 139 : 140 : /*! 141 : * \internal 142 : * \brief Find a node by name in a list of nodes 143 : * 144 : * \param[in] nodes List of nodes (as pcmk_node_t*) 145 : * \param[in] node_name Name of node to find 146 : * 147 : * \return Node from \p nodes that matches \p node_name if any, otherwise NULL 148 : */ 149 : pcmk_node_t * 150 105 : pcmk__find_node_in_list(const GList *nodes, const char *node_name) 151 : { 152 105 : if (node_name != NULL) { 153 202 : for (const GList *iter = nodes; iter != NULL; iter = iter->next) { 154 109 : pcmk_node_t *node = (pcmk_node_t *) iter->data; 155 : 156 109 : if (pcmk__str_eq(node->details->uname, node_name, 157 : pcmk__str_casei)) { 158 11 : return node; 159 : } 160 : } 161 : } 162 94 : return NULL; 163 : }