pacemaker  3.0.0-d8340737c4
Scalable High-Availability cluster resource manager
internal.h
Go to the documentation of this file.
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_CLUSTER_INTERNAL__H
11 #define PCMK__CRM_CLUSTER_INTERNAL__H
12 
13 #include <stdbool.h>
14 #include <stdint.h> // uint32_t, uint64_t
15 
16 #include <glib.h> // gboolean
17 #include <libxml/tree.h> // xmlNode
18 
19 #include <crm/common/ipc.h> // enum crm_ipc_server
20 #include <crm/cluster.h>
21 
22 #if SUPPORT_COROSYNC
23 #include <corosync/cpg.h> // cpg_name, cpg_handle_t
24 #endif
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 // @TODO Replace this with a pcmk__node_status_flags value
32  crm_proc_none = 0x00000001,
33 
34  // Cluster layers
35  crm_proc_cpg = 0x04000000,
36 };
37 
52  pcmk__node_status_remote = (UINT32_C(1) << 0),
53 
55  pcmk__node_status_dirty = (UINT32_C(1) << 1),
56 };
57 
58 // Used with node cache search functions
62 
65 
68 
72 
75 };
76 
86 };
87 
88 typedef struct pcmk__election pcmk__election_t;
89 
93  char *node_name;
95 
96  /* @TODO Corosync uses an integer node ID, but cluster layers in the
97  * abstract do not necessarily need to
98  */
99  uint32_t node_id;
100 
101 #if SUPPORT_COROSYNC
102  /* @TODO Make these members a separate struct and use void *cluster_data
103  * here instead, to abstract the cluster layer further.
104  */
105  struct cpg_name group;
106 
107  cpg_handle_t cpg_handle;
108 #endif // SUPPORT_COROSYNC
109 };
110 
112 typedef struct pcmk__node_status {
114  char *name;
115 
116  /* @COMPAT This is less than ideal since the value is not a valid XML ID
117  * (for Corosync, it's the string equivalent of the node's numeric node ID,
118  * but XML IDs can't start with a number) and the three elements should have
119  * different IDs.
120  *
121  * Ideally, we would use something like node-NODEID, node_state-NODEID, and
122  * transient_attributes-NODEID as the element IDs. Unfortunately changing it
123  * would be impractical due to backward compatibility; older nodes in a
124  * rolling upgrade will always write and expect the value in the old format.
125  */
126 
132  char *xml_id;
133 
134  char *state; // @TODO change to enum
135 
137  uint32_t flags;
138 
143  uint64_t membership_id;
144 
145  uint32_t processes; // @TODO most not needed, merge into flags
146 
147  /* @TODO When we can break public API compatibility, we can make the rest of
148  * these members separate structs and use void *cluster_data and
149  * void *user_data here instead, to abstract the cluster layer further.
150  */
151 
153  void *user_data;
154 
155  char *expected;
156 
157  time_t peer_lost;
158  char *conn_host;
159 
160  time_t when_member; // Since when node has been a cluster member
161  time_t when_online; // Since when peer has been online in CPG
162 
163  /* @TODO The following are currently needed only by the Corosync stack.
164  * Eventually consider moving them to a cluster-layer-specific data object.
165  */
166  uint32_t cluster_layer_id;
167  time_t when_lost;
169 
176 static inline uint32_t
177 crm_get_cluster_proc(void)
178 {
179  switch (pcmk_get_cluster_layer()) {
181  return crm_proc_cpg;
182 
183  default:
184  break;
185  }
186  return crm_proc_none;
187 }
188 
197 static inline const char *
198 pcmk__cs_err_str(int error)
199 {
200 # if SUPPORT_COROSYNC
201  switch (error) {
202  case CS_OK: return "OK";
203  case CS_ERR_LIBRARY: return "Library error";
204  case CS_ERR_VERSION: return "Version error";
205  case CS_ERR_INIT: return "Initialization error";
206  case CS_ERR_TIMEOUT: return "Timeout";
207  case CS_ERR_TRY_AGAIN: return "Try again";
208  case CS_ERR_INVALID_PARAM: return "Invalid parameter";
209  case CS_ERR_NO_MEMORY: return "No memory";
210  case CS_ERR_BAD_HANDLE: return "Bad handle";
211  case CS_ERR_BUSY: return "Busy";
212  case CS_ERR_ACCESS: return "Access error";
213  case CS_ERR_NOT_EXIST: return "Doesn't exist";
214  case CS_ERR_NAME_TOO_LONG: return "Name too long";
215  case CS_ERR_EXIST: return "Exists";
216  case CS_ERR_NO_SPACE: return "No space";
217  case CS_ERR_INTERRUPT: return "Interrupt";
218  case CS_ERR_NAME_NOT_FOUND: return "Name not found";
219  case CS_ERR_NO_RESOURCES: return "No resources";
220  case CS_ERR_NOT_SUPPORTED: return "Not supported";
221  case CS_ERR_BAD_OPERATION: return "Bad operation";
222  case CS_ERR_FAILED_OPERATION: return "Failed operation";
223  case CS_ERR_MESSAGE_ERROR: return "Message error";
224  case CS_ERR_QUEUE_FULL: return "Queue full";
225  case CS_ERR_QUEUE_NOT_AVAILABLE: return "Queue not available";
226  case CS_ERR_BAD_FLAGS: return "Bad flags";
227  case CS_ERR_TOO_BIG: return "Too big";
228  case CS_ERR_NO_SECTIONS: return "No sections";
229  }
230 # endif
231  return "Corosync error";
232 }
233 
234 # if SUPPORT_COROSYNC
235 
236 #if 0
237 /* This is the new way to do it, but we still support all Corosync 2 versions,
238  * and this isn't always available. A better alternative here would be to check
239  * for support in the configure script and enable this conditionally.
240  */
241 #define pcmk__init_cmap(handle) cmap_initialize_map((handle), CMAP_MAP_ICMAP)
242 #else
243 #define pcmk__init_cmap(handle) cmap_initialize(handle)
244 #endif
245 
246 char *pcmk__corosync_cluster_name(void);
247 bool pcmk__corosync_add_nodes(xmlNode *xml_parent);
248 
249 void pcmk__cpg_confchg_cb(cpg_handle_t handle,
250  const struct cpg_name *group_name,
251  const struct cpg_address *member_list,
252  size_t member_list_entries,
253  const struct cpg_address *left_list,
254  size_t left_list_entries,
255  const struct cpg_address *joined_list,
256  size_t joined_list_entries);
257 
258 char *pcmk__cpg_message_data(cpg_handle_t handle, uint32_t sender_id,
259  uint32_t pid, void *content, const char **from);
260 
261 # endif
262 
264 char *pcmk__cluster_node_name(uint32_t nodeid);
265 const char *pcmk__cluster_local_node_name(void);
266 const char *pcmk__node_name_from_uuid(const char *uuid);
267 
268 pcmk__node_status_t *crm_update_peer_proc(const char *source,
269  pcmk__node_status_t *peer,
270  uint32_t flag, const char *status);
271 pcmk__node_status_t *pcmk__update_peer_state(const char *source,
272  pcmk__node_status_t *node,
273  const char *state,
274  uint64_t membership);
275 
276 void pcmk__update_peer_expected(const char *source, pcmk__node_status_t *node,
277  const char *expected);
278 void pcmk__reap_unseen_nodes(uint64_t ring_id);
279 
280 void pcmk__corosync_quorum_connect(gboolean (*dispatch)(unsigned long long,
281  gboolean),
282  void (*destroy) (gpointer));
283 
285  enum pcmk_ipc_server service,
286  const xmlNode *data);
287 
288 // Membership
289 
290 extern GHashTable *pcmk__peer_cache;
291 extern GHashTable *pcmk__remote_peer_cache;
292 
293 bool pcmk__cluster_has_quorum(void);
294 
297 
298 void pcmk__cluster_set_autoreap(bool enable);
299 void pcmk__cluster_set_status_callback(void (*dispatch)(enum pcmk__node_update,
301  const void *));
302 
304 unsigned int pcmk__cluster_num_active_nodes(void);
305 unsigned int pcmk__cluster_num_remote_nodes(void);
306 
308 void pcmk__cluster_forget_cluster_node(uint32_t id, const char *node_name);
309 void pcmk__cluster_forget_remote_node(const char *node_name);
311  const char *uname,
312  uint32_t flags);
313 void pcmk__purge_node_from_cache(const char *node_name, uint32_t node_id);
314 
315 void pcmk__refresh_node_caches_from_cib(xmlNode *cib);
316 
317 pcmk__node_status_t *pcmk__get_node(unsigned int id, const char *uname,
318  const char *xml_id, uint32_t flags);
319 
320 #ifdef __cplusplus
321 }
322 #endif
323 
324 #endif // PCMK__CRM_CLUSTER_INTERNAL__H
pcmk__node_status_t * pcmk__get_node(unsigned int id, const char *uname, const char *xml_id, uint32_t flags)
Definition: membership.c:927
pcmk__node_status_flags
Definition: internal.h:47
char data[0]
Definition: cpg.c:58
Implementation of pcmk__cluster_private_t.
Definition: internal.h:91
Node name updated.
Definition: internal.h:83
uint32_t flags
Group of enum pcmk__node_status_flags
Definition: internal.h:137
Corosync Cluster Engine.
Definition: cluster.h:75
void pcmk__reap_unseen_nodes(uint64_t ring_id)
Definition: membership.c:1334
void pcmk__cluster_forget_cluster_node(uint32_t id, const char *node_name)
Definition: membership.c:465
const char * pcmk__node_name_from_uuid(const char *uuid)
Definition: cluster.c:311
time_t when_member
Definition: internal.h:160
pcmk__node_update
Definition: internal.h:82
Search for cluster nodes from membership cache.
Definition: internal.h:64
bool pcmk__corosync_add_nodes(xmlNode *xml_parent)
Definition: corosync.c:558
Node connection state updated.
Definition: internal.h:84
void pcmk__cluster_forget_remote_node(const char *node_name)
Definition: membership.c:218
const char * pcmk__cluster_local_node_name(void)
Definition: cluster.c:289
void pcmk__cpg_confchg_cb(cpg_handle_t handle, const struct cpg_name *group_name, const struct cpg_address *member_list, size_t member_list_entries, const struct cpg_address *left_list, size_t left_list_entries, const struct cpg_address *joined_list, size_t joined_list_entries)
Definition: cpg.c:640
char * node_name
Local node name at cluster layer.
Definition: internal.h:93
uint32_t cluster_layer_id
Cluster-layer numeric node ID.
Definition: internal.h:166
pcmk__node_status_t * pcmk__search_node_caches(unsigned int id, const char *uname, uint32_t flags)
Definition: membership.c:801
enum pcmk_ipc_server server
Server this connection is for (if any)
Definition: internal.h:92
char * pcmk__corosync_cluster_name(void)
Definition: corosync.c:673
pcmk__election_t * election
Election state (if election is needed)
Definition: internal.h:94
Node process group membership updated.
Definition: internal.h:85
void * user_data
Arbitrary data (must be freeable by free())
Definition: internal.h:153
unsigned int pcmk__cluster_num_active_nodes(void)
Definition: membership.c:530
bool pcmk__cluster_is_node_active(const pcmk__node_status_t *node)
Definition: membership.c:368
pcmk_ipc_server
Available IPC interfaces.
Definition: ipc.h:48
Search for remote nodes.
Definition: internal.h:67
uint32_t pid
Definition: cpg.c:49
bool pcmk__cluster_has_quorum(void)
Definition: membership.c:96
void pcmk__update_peer_expected(const char *source, pcmk__node_status_t *node, const char *expected)
Definition: membership.c:1192
Node&#39;s cache entry is dirty.
Definition: internal.h:55
Does not affect search.
Definition: internal.h:61
pcmk__node_status_t * pcmk__cluster_lookup_remote_node(const char *node_name)
Definition: membership.c:144
uint32_t processes
Definition: internal.h:145
void pcmk__cluster_init_node_caches(void)
Definition: membership.c:562
unsigned int pcmk__cluster_num_remote_nodes(void)
Definition: membership.c:120
uint32_t node_id
Local node ID at cluster layer.
Definition: internal.h:99
struct pcmk__node_status pcmk__node_status_t
Node status data (may be a cluster node or a Pacemaker Remote node)
GHashTable * pcmk__remote_peer_cache
Definition: membership.c:55
Search for cluster member nodes and remote nodes.
Definition: internal.h:70
void pcmk__cluster_set_autoreap(bool enable)
Definition: membership.c:643
char * conn_host
Definition: internal.h:158
Search for cluster nodes from CIB (as of last cache refresh)
Definition: internal.h:74
void pcmk__cluster_destroy_node_caches(void)
Definition: membership.c:582
void pcmk__corosync_quorum_connect(gboolean(*dispatch)(unsigned long long, gboolean), void(*destroy)(gpointer))
Definition: corosync.c:347
const char * pcmk__cluster_node_uuid(pcmk__node_status_t *node)
Definition: cluster.c:44
pcmk__node_status_t * pcmk__update_peer_state(const char *source, pcmk__node_status_t *node, const char *state, uint64_t membership)
Update a node&#39;s state and membership information.
Definition: membership.c:1321
GHashTable * pcmk__peer_cache
Definition: membership.c:37
pcmk__node_search_flags
Definition: internal.h:59
char uname[MAX_NAME]
Definition: cpg.c:53
char * pcmk__cluster_node_name(uint32_t nodeid)
Definition: cluster.c:233
struct pcmk__election pcmk__election_t
Definition: internal.h:88
IPC interface to Pacemaker daemons.
void pcmk__purge_node_from_cache(const char *node_name, uint32_t node_id)
Definition: membership.c:844
time_t when_lost
When CPG membership was last lost.
Definition: internal.h:167
uint64_t membership_id
Definition: internal.h:143
bool pcmk__cluster_send_message(const pcmk__node_status_t *node, enum pcmk_ipc_server service, const xmlNode *data)
Definition: cluster.c:200
time_t peer_lost
Definition: internal.h:157
pcmk__node_status_t * crm_update_peer_proc(const char *source, pcmk__node_status_t *peer, uint32_t flag, const char *status)
Definition: membership.c:1095
Node status data (may be a cluster node or a Pacemaker Remote node)
Definition: internal.h:112
void pcmk__cluster_set_status_callback(void(*dispatch)(enum pcmk__node_update, pcmk__node_status_t *, const void *))
Definition: membership.c:620
enum pcmk_cluster_layer pcmk_get_cluster_layer(void)
Get and validate the local cluster layer.
Definition: cluster.c:379
crm_proc_flag
Definition: internal.h:31
uint64_t flags
Definition: remote.c:211
char * name
Node name as known to cluster layer, or Pacemaker Remote node name.
Definition: internal.h:114
char * pcmk__cpg_message_data(cpg_handle_t handle, uint32_t sender_id, uint32_t pid, void *content, const char **from)
Definition: cpg.c:397
time_t when_online
Definition: internal.h:161
void pcmk__refresh_node_caches_from_cib(xmlNode *cib)
Definition: membership.c:1480