1 /*
2 * Copyright 2004-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 PCMK__CRM_COMMON_NODES__H
11 #define PCMK__CRM_COMMON_NODES__H
12
13 #include <stdbool.h> // bool
14 #include <glib.h> // gboolean, GList, GHashTable
15
16 #include <crm/common/scheduler_types.h> // pcmk_resource_t, pcmk_scheduler_t
17
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21
22 /*!
23 * \file
24 * \brief Scheduler API for nodes
25 * \ingroup core
26 */
27
28 // Special node attributes
29
30 #define PCMK_NODE_ATTR_MAINTENANCE "maintenance"
31 #define PCMK_NODE_ATTR_STANDBY "standby"
32 #define PCMK_NODE_ATTR_TERMINATE "terminate"
33
34
35 // @COMPAT Make this internal when we can break API backward compatibility
36 //!@{
37 //! \deprecated Do not use (public access will be removed in a future release)
38 enum node_type { // Possible node types
39 pcmk_node_variant_cluster = 1, // Cluster layer node
40 pcmk_node_variant_remote = 2, // Pacemaker Remote node
41
42 node_ping = 0, // deprecated
43 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
44 node_member = pcmk_node_variant_cluster,
45 node_remote = pcmk_node_variant_remote,
46 #endif
47 };
48 //!@}
49
50 // When to probe a resource on a node (as specified in location constraints)
51 // @COMPAT Make this internal when we can break API backward compatibility
52 //!@{
53 //! \deprecated Do not use (public access will be removed in a future release)
54 enum pe_discover_e {
55 pcmk_probe_always = 0, // Always probe resource on node
56 pcmk_probe_never = 1, // Never probe resource on node
57 pcmk_probe_exclusive = 2, // Probe only on designated nodes
58
59 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
60 pe_discover_always = pcmk_probe_always,
61 pe_discover_never = pcmk_probe_never,
62 pe_discover_exclusive = pcmk_probe_exclusive,
63 #endif
64 };
65 //!@}
66
67 // Basic node information (all node objects for the same node share this)
68 // @COMPAT Make this internal when we can break API backward compatibility
69 //!@{
70 //! \deprecated Do not use (public access will be removed in a future release)
71 struct pe_node_shared_s {
72 const char *id; // Node ID at the cluster layer
73 const char *uname; // Node name in cluster
74 enum node_type type; // Node variant
75
76 // @TODO Convert these into a flag group
77
78 // NOTE: sbd (as of at least 1.5.2) uses this
79 //! \deprecated Call pcmk_node_is_online() instead
80 gboolean online; // Whether online
81
82 gboolean standby; // Whether in standby mode
83 gboolean standby_onfail; // Whether in standby mode due to on-fail
84
85 // NOTE: sbd (as of at least 1.5.2) uses this
86 //! \deprecated Call pcmk_node_is_pending() instead
87 gboolean pending; // Whether controller membership is pending
88
89 // NOTE: sbd (as of at least 1.5.2) uses this
90 //! \deprecated Call !pcmk_node_is_clean() instead
91 gboolean unclean; // Whether node requires fencing
92
93 gboolean unseen; // Whether node has never joined cluster
94
95 // NOTE: sbd (as of at least 1.5.2) uses this
96 //! \deprecated Call pcmk_node_is_shutting_down() instead
97 gboolean shutdown; // Whether shutting down
98
99 gboolean expected_up; // Whether expected join state is member
100 gboolean is_dc; // Whether node is cluster's DC
101
102 // NOTE: sbd (as of at least 1.5.2) uses this
103 //! \deprecated Call pcmk_node_is_in_maintenance() instead
104 gboolean maintenance; // Whether in maintenance mode
105
106 gboolean rsc_discovery_enabled; // Whether probes are allowed on node
107
108 /*
109 * Whether this is a guest node whose guest resource must be recovered or a
110 * remote node that must be fenced
111 */
112 gboolean remote_requires_reset;
113
114 /*
115 * Whether this is a Pacemaker Remote node that was fenced since it was last
116 * connected by the cluster
117 */
118 gboolean remote_was_fenced;
119
120 /*
121 * Whether this is a Pacemaker Remote node previously marked in its
122 * node state as being in maintenance mode
123 */
124 gboolean remote_maintenance;
125
126 gboolean unpacked; // Whether node history has been unpacked
127
128 /*
129 * Number of resources active on this node (valid after CIB status section
130 * has been unpacked, as long as pcmk_sched_no_counts was not set)
131 */
132 int num_resources;
133
134 // Remote connection resource for node, if it is a Pacemaker Remote node
135 pcmk_resource_t *remote_rsc;
136
137 // NOTE: sbd (as of at least 1.5.2) uses this
138 // \deprecated Call pcmk_foreach_active_resource() instead
139 GList *running_rsc; // List of resources active on node
140
141 GList *allocated_rsc; // List of resources assigned to node
142 GHashTable *attrs; // Node attributes
143 GHashTable *utilization; // Node utilization attributes
144 GHashTable *digest_cache; // Cache of calculated resource digests
145
146 /*
147 * Sum of priorities of all resources active on node and on any guest nodes
148 * connected to this node, with +1 for promoted instances (used to compare
149 * nodes for PCMK_OPT_PRIORITY_FENCING_DELAY)
150 */
151 int priority;
152
153 pcmk_scheduler_t *data_set; // Cluster that node is part of
154 };
155 //!@}
156
157 // Implementation of pcmk_node_t
158 // @COMPAT Make contents internal when we can break API backward compatibility
159 //!@{
160 //! \deprecated Do not use (public access will be removed in a future release)
161 struct pe_node_s {
162 int weight; // Node score for a given resource
163 gboolean fixed; // \deprecated Do not use
164 int count; // Counter reused by assignment and promotion code
165
166 // NOTE: sbd (as of at least 1.5.2) uses this
167 struct pe_node_shared_s *details; // Basic node information
168
169 // @COMPAT This should be enum pe_discover_e
170 int rsc_discover_mode; // Probe mode (enum pe_discover_e)
171 };
172 //!@}
173
174 bool pcmk_node_is_online(const pcmk_node_t *node);
175 bool pcmk_node_is_pending(const pcmk_node_t *node);
176 bool pcmk_node_is_clean(const pcmk_node_t *node);
177 bool pcmk_node_is_shutting_down(const pcmk_node_t *node);
178 bool pcmk_node_is_in_maintenance(const pcmk_node_t *node);
179
180 bool pcmk_foreach_active_resource(pcmk_node_t *node,
181 bool (*fn)(pcmk_resource_t *, void *),
182 void *user_data);
183 /*!
184 * \internal
185 * \brief Return a string suitable for logging as a node name
186 *
187 * \param[in] node Node to return a node name string for
188 *
189 * \return Node name if available, otherwise node ID if available,
190 * otherwise "unspecified node" if node is NULL or "unidentified node"
191 * if node has neither a name nor ID.
192 */
193 static inline const char *
194 pcmk__node_name(const pcmk_node_t *node)
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
195 {
196 if (node == NULL) {
197 return "unspecified node";
198
199 } else if (node->details->uname != NULL) {
200 return node->details->uname;
201
202 } else if (node->details->id != NULL) {
203 return node->details->id;
204
205 } else {
206 return "unidentified node";
207 }
208 }
209
210 /*!
211 * \internal
212 * \brief Check whether two node objects refer to the same node
213 *
214 * \param[in] node1 First node object to compare
215 * \param[in] node2 Second node object to compare
216 *
217 * \return true if \p node1 and \p node2 refer to the same node
218 */
219 static inline bool
220 pcmk__same_node(const pcmk_node_t *node1, const pcmk_node_t *node2)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
221 {
222 return (node1 != NULL) && (node2 != NULL)
223 && (node1->details == node2->details);
224 }
225
226 #ifdef __cplusplus
227 }
228 #endif
229
230 #endif // PCMK__CRM_COMMON_NODES__H