pacemaker 2.1.6-6fdc9deea29
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
cluster.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2022 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 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);
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
303void
304set_uuid(xmlNode *xml, const char *attr, crm_node_t *node)
305{
306 crm_xml_add(xml, attr, crm_peer_uuid(node));
307}
308
316const char *
318{
319 switch (type) {
321 return "corosync";
323 return "unknown";
325 return "invalid";
326 }
327 crm_err("Invalid cluster type: %d", type);
328 return "invalid";
329}
330
339{
340 bool detected = false;
341 const char *cluster = NULL;
342 static enum cluster_type_e cluster_type = pcmk_cluster_unknown;
343
344 /* Return the previous calculation, if any */
345 if (cluster_type != pcmk_cluster_unknown) {
346 return cluster_type;
347 }
348
350
351#if SUPPORT_COROSYNC
352 /* If nothing is defined in the environment, try corosync (if supported) */
353 if (cluster == NULL) {
354 crm_debug("Testing with Corosync");
355 cluster_type = pcmk__corosync_detect();
356 if (cluster_type != pcmk_cluster_unknown) {
357 detected = true;
358 goto done;
359 }
360 }
361#endif
362
363 /* Something was defined in the environment, test it against what we support */
364 crm_info("Verifying cluster type: '%s'",
365 ((cluster == NULL)? "-unspecified-" : cluster));
366 if (cluster == NULL) {
367
368#if SUPPORT_COROSYNC
369 } else if (pcmk__str_eq(cluster, "corosync", pcmk__str_casei)) {
370 cluster_type = pcmk_cluster_corosync;
371#endif
372
373 } else {
374 cluster_type = pcmk_cluster_invalid;
375 goto done; /* Keep the compiler happy when no stacks are supported */
376 }
377
378 done:
379 if (cluster_type == pcmk_cluster_unknown) {
380 crm_notice("Could not determine the current cluster type");
381
382 } else if (cluster_type == pcmk_cluster_invalid) {
383 crm_notice("This installation does not support the '%s' cluster infrastructure: terminating.",
384 cluster);
386
387 } else {
388 crm_info("%s an active '%s' cluster",
389 (detected? "Detected" : "Assuming"),
390 name_for_cluster_type(cluster_type));
391 }
392
393 return cluster_type;
394}
395
401gboolean
const char * name
Definition cib.c:24
crm_node_t * pcmk__search_cluster_node_cache(unsigned int id, const char *uname)
Definition membership.c:561
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:402
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)
Add a node's UUID as an XML attribute.
Definition cluster.c:304
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:338
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:317
const char * crm_peer_uuid(crm_node_t *peer)
Get (and set if needed) a node's UUID.
Definition cluster.c:38
gboolean send_cluster_message(const crm_node_t *node, enum crm_ais_msg_types service, xmlNode *data, gboolean ordered)
Send an XML message via the cluster messaging layer.
Definition cluster.c:162
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:115
GHashTable * crm_remote_peer_cache
Definition membership.c:53
cluster_type_e
Definition cluster.h:189
@ pcmk_cluster_unknown
Definition cluster.h:190
@ pcmk_cluster_invalid
Definition cluster.h:191
@ pcmk_cluster_corosync
Definition cluster.h:194
void crm_peer_init(void)
Definition membership.c:400
void crm_peer_destroy(void)
Definition membership.c:416
char * pcmk_hostname(void)
Get the local hostname.
Definition utils.c:535
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
enum crm_ais_msg_types type
Definition cpg.c:3
char data[0]
Definition cpg.c:10
uint32_t id
Definition cpg.c:0
gboolean pcmk__cpg_send_xml(xmlNode *msg, const crm_node_t *node, enum crm_ais_msg_types dest)
Definition cpg.c:892
A dumping ground.
IPC interface to Pacemaker daemons.
#define CRM_TRACE_INIT_DATA(name)
Definition logging.h:134
#define crm_info(fmt, args...)
Definition logging.h:378
#define crm_notice(fmt, args...)
Definition logging.h:377
#define CRM_CHECK(expr, failure_action)
Definition logging.h:235
#define crm_debug(fmt, args...)
Definition logging.h:380
#define crm_err(fmt, args...)
Definition logging.h:375
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:268
_Noreturn crm_exit_t crm_exit(crm_exit_t rc)
Definition results.c:874
@ pcmk_rc_ok
Definition results.h:151
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:87
char * uname
Definition cluster.h:88
char * uname
Definition cluster.h:59
uint32_t id
Definition cluster.h:72
char * uuid
Definition cluster.h:60