pacemaker 2.1.7-2.1.7
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
cluster.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2023 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#include <dlfcn.h>
12
13#include <stdio.h>
14#include <unistd.h>
15#include <string.h>
16#include <stdlib.h>
17#include <time.h>
18#include <sys/param.h>
19#include <sys/types.h>
20
21#include <crm/crm.h>
22#include <crm/msg_xml.h>
23
24#include <crm/common/ipc.h>
26#include "crmcluster_private.h"
27
29
37const char *
39{
40 char *uuid = NULL;
41
42 // Check simple cases first, to avoid any calls that might block
43 if (peer == NULL) {
44 return NULL;
45 }
46 if (peer->uuid != NULL) {
47 return peer->uuid;
48 }
49
50 switch (get_cluster_type()) {
52#if SUPPORT_COROSYNC
53 uuid = pcmk__corosync_uuid(peer);
54#endif
55 break;
56
59 crm_err("Unsupported cluster type");
60 break;
61 }
62
63 peer->uuid = uuid;
64 return peer->uuid;
65}
66
74gboolean
76{
78
79 crm_notice("Connecting to %s cluster infrastructure",
81 switch (type) {
83#if SUPPORT_COROSYNC
85 return pcmk__corosync_connect(cluster);
86#else
87 break;
88#endif // SUPPORT_COROSYNC
89 default:
90 break;
91 }
92 return FALSE;
93}
94
100void
102{
104
105 crm_info("Disconnecting from %s cluster infrastructure",
107 switch (type) {
109#if SUPPORT_COROSYNC
112#endif // SUPPORT_COROSYNC
113 break;
114 default:
115 break;
116 }
117}
118
128{
129 crm_cluster_t *cluster = calloc(1, sizeof(crm_cluster_t));
130
131 CRM_ASSERT(cluster != NULL);
132 return cluster;
133}
134
140void
142{
143 if (cluster == NULL) {
144 return;
145 }
146 free(cluster->uuid);
147 free(cluster->uname);
148 free(cluster);
149}
150
161gboolean
163 const xmlNode *data, gboolean ordered)
164{
165 switch (get_cluster_type()) {
167#if SUPPORT_COROSYNC
168 return pcmk__cpg_send_xml(data, node, service);
169#endif
170 break;
171 default:
172 break;
173 }
174 return FALSE;
175}
176
183const char *
185{
186 static char *name = NULL;
187
188 if (name == NULL) {
189 name = get_node_name(0);
190 }
191 return name;
192}
193
203char *
204get_node_name(uint32_t nodeid)
205{
206 char *name = NULL;
207 enum cluster_type_e stack = get_cluster_type();
208
209 switch (stack) {
211#if SUPPORT_COROSYNC
212 name = pcmk__corosync_name(0, nodeid);
213 break;
214#endif // SUPPORT_COROSYNC
215
216 default:
217 crm_err("Unknown cluster type: %s (%d)", name_for_cluster_type(stack), stack);
218 }
219
220 if ((name == NULL) && (nodeid == 0)) {
222 if (name == NULL) {
223 // @TODO Maybe let the caller decide what to do
224 crm_err("Could not obtain the local %s node name",
225 name_for_cluster_type(stack));
227 }
228 crm_notice("Defaulting to uname -n for the local %s node name",
229 name_for_cluster_type(stack));
230 }
231
232 if (name == NULL) {
233 crm_notice("Could not obtain a node name for %s node with id %u",
234 name_for_cluster_type(stack), nodeid);
235 }
236 return name;
237}
238
249const char *
250crm_peer_uname(const char *uuid)
251{
252 GHashTableIter iter;
253 crm_node_t *node = NULL;
254
255 CRM_CHECK(uuid != NULL, return NULL);
256
257 /* remote nodes have the same uname and uuid */
258 if (g_hash_table_lookup(crm_remote_peer_cache, uuid)) {
259 return uuid;
260 }
261
262 /* avoid blocking calls where possible */
263 g_hash_table_iter_init(&iter, crm_peer_cache);
264 while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
265 if (pcmk__str_eq(node->uuid, uuid, pcmk__str_casei)) {
266 if (node->uname != NULL) {
267 return node->uname;
268 }
269 break;
270 }
271 }
272 node = NULL;
273
274 if (is_corosync_cluster()) {
275 long long id;
276
277 if ((pcmk__scan_ll(uuid, &id, 0LL) != pcmk_rc_ok)
278 || (id < 1LL) || (id > UINT32_MAX)) {
279 crm_err("Invalid Corosync node ID '%s'", uuid);
280 return NULL;
281 }
282
283 node = pcmk__search_cluster_node_cache((uint32_t) id, NULL, NULL);
284 if (node != NULL) {
285 crm_info("Setting uuid for node %s[%u] to %s",
286 node->uname, node->id, uuid);
287 node->uuid = strdup(uuid);
288 return node->uname;
289 }
290 return NULL;
291 }
292
293 return NULL;
294}
295
303const char *
305{
306 switch (type) {
308 return "corosync";
310 return "unknown";
312 return "invalid";
313 }
314 crm_err("Invalid cluster type: %d", type);
315 return "invalid";
316}
317
326{
327 bool detected = false;
328 const char *cluster = NULL;
329 static enum cluster_type_e cluster_type = pcmk_cluster_unknown;
330
331 /* Return the previous calculation, if any */
332 if (cluster_type != pcmk_cluster_unknown) {
333 return cluster_type;
334 }
335
337
338#if SUPPORT_COROSYNC
339 /* If nothing is defined in the environment, try corosync (if supported) */
340 if (cluster == NULL) {
341 crm_debug("Testing with Corosync");
342 cluster_type = pcmk__corosync_detect();
343 if (cluster_type != pcmk_cluster_unknown) {
344 detected = true;
345 goto done;
346 }
347 }
348#endif
349
350 /* Something was defined in the environment, test it against what we support */
351 crm_info("Verifying cluster type: '%s'",
352 ((cluster == NULL)? "-unspecified-" : cluster));
353 if (cluster == NULL) {
354
355#if SUPPORT_COROSYNC
356 } else if (pcmk__str_eq(cluster, "corosync", pcmk__str_casei)) {
357 cluster_type = pcmk_cluster_corosync;
358#endif
359
360 } else {
361 cluster_type = pcmk_cluster_invalid;
362 goto done; /* Keep the compiler happy when no stacks are supported */
363 }
364
365 done:
366 if (cluster_type == pcmk_cluster_unknown) {
367 crm_notice("Could not determine the current cluster type");
368
369 } else if (cluster_type == pcmk_cluster_invalid) {
370 crm_notice("This installation does not support the '%s' cluster infrastructure: terminating.",
371 cluster);
373
374 } else {
375 crm_info("%s an active '%s' cluster",
376 (detected? "Detected" : "Assuming"),
377 name_for_cluster_type(cluster_type));
378 }
379
380 return cluster_type;
381}
382
388gboolean
393
394// Deprecated functions kept only for backward API compatibility
395// LCOV_EXCL_START
396
397#include <crm/cluster/compat.h>
398
399void
400set_uuid(xmlNode *xml, const char *attr, crm_node_t *node)
401{
402 crm_xml_add(xml, attr, crm_peer_uuid(node));
403}
404
405// LCOV_EXCL_STOP
406// End deprecated API
const char * name
Definition cib.c:26
crm_node_t * pcmk__search_cluster_node_cache(unsigned int id, const char *uname, const char *uuid)
Definition membership.c:582
crm_cluster_t * pcmk_cluster_new(void)
Allocate a new crm_cluster_t object.
Definition cluster.c:127
gboolean is_corosync_cluster(void)
Check whether the local cluster is a Corosync cluster.
Definition cluster.c:389
gboolean crm_cluster_connect(crm_cluster_t *cluster)
Connect to the cluster layer.
Definition cluster.c:75
void set_uuid(xmlNode *xml, const char *attr, crm_node_t *node)
Definition cluster.c:400
const char * get_local_node_name(void)
Get the local node's name.
Definition cluster.c:184
void crm_cluster_disconnect(crm_cluster_t *cluster)
Disconnect from the cluster layer.
Definition cluster.c:101
enum cluster_type_e get_cluster_type(void)
Get (and validate) the local cluster type.
Definition cluster.c:325
gboolean send_cluster_message(const crm_node_t *node, enum crm_ais_msg_types service, const xmlNode *data, gboolean ordered)
Send an XML message via the cluster messaging layer.
Definition cluster.c:162
const char * crm_peer_uname(const char *uuid)
Get the node name corresponding to a node UUID.
Definition cluster.c:250
char * get_node_name(uint32_t nodeid)
Get the node name corresponding to a cluster node ID.
Definition cluster.c:204
const char * name_for_cluster_type(enum cluster_type_e type)
Get a log-friendly string equivalent of a cluster type.
Definition cluster.c:304
const char * crm_peer_uuid(crm_node_t *peer)
Get (and set if needed) a node's UUID.
Definition cluster.c:38
void pcmk_cluster_free(crm_cluster_t *cluster)
Free a crm_cluster_t object and its dynamically allocated members.
Definition cluster.c:141
GHashTable * crm_peer_cache
Definition membership.c:36
crm_ais_msg_types
Definition cluster.h:118
GHashTable * crm_remote_peer_cache
Definition membership.c:53
cluster_type_e
Definition cluster.h:191
@ pcmk_cluster_unknown
Definition cluster.h:192
@ pcmk_cluster_invalid
Definition cluster.h:193
@ pcmk_cluster_corosync
Definition cluster.h:196
void crm_peer_init(void)
Definition membership.c:401
void crm_peer_destroy(void)
Definition membership.c:417
char * pcmk_hostname(void)
Get the local hostname.
Definition utils.c:535
Deprecated Pacemaker cluster API.
void pcmk__corosync_disconnect(crm_cluster_t *cluster)
Definition corosync.c:223
char * pcmk__corosync_name(uint64_t cmap_handle, uint32_t nodeid)
Definition corosync.c:101
char * pcmk__corosync_uuid(const crm_node_t *node)
Definition corosync.c:55
gboolean pcmk__corosync_connect(crm_cluster_t *cluster)
Definition corosync.c:451
enum cluster_type_e pcmk__corosync_detect(void)
Definition corosync.c:496
bool pcmk__cpg_send_xml(const xmlNode *msg, const crm_node_t *node, enum crm_ais_msg_types dest)
Definition cpg.c:892
enum crm_ais_msg_types type
Definition cpg.c:3
char data[0]
Definition cpg.c:10
uint32_t id
Definition cpg.c:0
A dumping ground.
IPC interface to Pacemaker daemons.
#define CRM_TRACE_INIT_DATA(name)
Definition logging.h:137
#define crm_info(fmt, args...)
Definition logging.h:382
#define crm_notice(fmt, args...)
Definition logging.h:381
#define CRM_CHECK(expr, failure_action)
Definition logging.h:238
#define crm_debug(fmt, args...)
Definition logging.h:384
#define crm_err(fmt, args...)
Definition logging.h:379
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
Definition nvpair.c:302
#define PCMK__ENV_CLUSTER_TYPE
const char * pcmk__env_option(const char *option)
Definition options.c:58
#define CRM_ASSERT(expr)
Definition results.h:42
@ CRM_EX_FATAL
Do not respawn.
Definition results.h:271
_Noreturn crm_exit_t crm_exit(crm_exit_t rc)
Definition results.c:936
@ pcmk_rc_ok
Definition results.h:154
int pcmk__scan_ll(const char *text, long long *result, long long default_value)
Definition strings.c:97
@ pcmk__str_casei
char * uuid
Definition cluster.h:90
char * uname
Definition cluster.h:91
char * uname
Definition cluster.h:59
uint32_t id
Definition cluster.h:72
char * uuid
Definition cluster.h:60