This source file includes following definitions.
- pcmk__cluster_parse_msg_type
- pcmk__cluster_node_uuid
- pcmk_cluster_connect
- pcmk_cluster_disconnect
- pcmk_cluster_new
- pcmk_cluster_free
- pcmk_cluster_set_destroy_fn
- pcmk__cluster_send_message
- pcmk__cluster_node_name
- pcmk__cluster_local_node_name
- pcmk__node_name_from_uuid
- pcmk_cluster_layer_text
- pcmk_get_cluster_layer
- set_uuid
- crm_cluster_connect
- crm_cluster_disconnect
- name_for_cluster_type
- get_cluster_type
- is_corosync_cluster
- send_cluster_message
- crm_peer_uuid
- get_node_name
- get_local_node_name
- crm_peer_uname
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11 #include <dlfcn.h>
12
13 #include <inttypes.h>
14 #include <stdbool.h>
15 #include <stdio.h>
16 #include <unistd.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <time.h>
20 #include <sys/param.h>
21 #include <sys/types.h>
22 #include <sys/utsname.h>
23
24 #include <glib.h>
25
26 #include <crm/crm.h>
27
28 #include <crm/common/ipc.h>
29 #include <crm/common/xml.h>
30 #include <crm/cluster/internal.h>
31 #include "crmcluster_private.h"
32
33 CRM_TRACE_INIT_DATA(cluster);
34
35
36
37
38
39
40
41
42
43 enum crm_ais_msg_types
44 pcmk__cluster_parse_msg_type(const char *text)
45 {
46 CRM_CHECK(text != NULL, return crm_msg_none);
47
48 text = pcmk__message_name(text);
49
50 if (pcmk__str_eq(text, "ais", pcmk__str_none)) {
51 return crm_msg_ais;
52 }
53 if (pcmk__str_eq(text, CRM_SYSTEM_CIB, pcmk__str_none)) {
54 return crm_msg_cib;
55 }
56 if (pcmk__str_any_of(text, CRM_SYSTEM_CRMD, CRM_SYSTEM_DC, NULL)) {
57 return crm_msg_crmd;
58 }
59 if (pcmk__str_eq(text, CRM_SYSTEM_TENGINE, pcmk__str_none)) {
60 return crm_msg_te;
61 }
62 if (pcmk__str_eq(text, CRM_SYSTEM_PENGINE, pcmk__str_none)) {
63 return crm_msg_pe;
64 }
65 if (pcmk__str_eq(text, CRM_SYSTEM_LRMD, pcmk__str_none)) {
66 return crm_msg_lrmd;
67 }
68 if (pcmk__str_eq(text, CRM_SYSTEM_STONITHD, pcmk__str_none)) {
69 return crm_msg_stonithd;
70 }
71 if (pcmk__str_eq(text, "stonith-ng", pcmk__str_none)) {
72 return crm_msg_stonith_ng;
73 }
74 if (pcmk__str_eq(text, "attrd", pcmk__str_none)) {
75 return crm_msg_attrd;
76 }
77 return crm_msg_none;
78 }
79
80
81
82
83
84
85
86
87
88 const char *
89 pcmk__cluster_node_uuid(crm_node_t *node)
90 {
91 const enum pcmk_cluster_layer cluster_layer = pcmk_get_cluster_layer();
92
93 if (node == NULL) {
94 return NULL;
95 }
96 if (node->uuid != NULL) {
97 return node->uuid;
98 }
99
100 switch (cluster_layer) {
101 #if SUPPORT_COROSYNC
102 case pcmk_cluster_layer_corosync:
103 node->uuid = pcmk__corosync_uuid(node);
104 return node->uuid;
105 #endif
106
107 default:
108 crm_err("Unsupported cluster layer %s",
109 pcmk_cluster_layer_text(cluster_layer));
110 return NULL;
111 }
112 }
113
114
115
116
117
118
119
120
121
122 int
123 pcmk_cluster_connect(pcmk_cluster_t *cluster)
124 {
125 const enum pcmk_cluster_layer cluster_layer = pcmk_get_cluster_layer();
126 const char *cluster_layer_s = pcmk_cluster_layer_text(cluster_layer);
127
128
129 crm_notice("Connecting to %s cluster layer", cluster_layer_s);
130
131 switch (cluster_layer) {
132 #if SUPPORT_COROSYNC
133 case pcmk_cluster_layer_corosync:
134 return pcmk__corosync_connect(cluster);
135 #endif
136
137 default:
138 break;
139 }
140
141 crm_err("Failed to connect to unsupported cluster layer %s",
142 cluster_layer_s);
143 return EPROTONOSUPPORT;
144 }
145
146
147
148
149
150
151
152
153 int
154 pcmk_cluster_disconnect(pcmk_cluster_t *cluster)
155 {
156 const enum pcmk_cluster_layer cluster_layer = pcmk_get_cluster_layer();
157 const char *cluster_layer_s = pcmk_cluster_layer_text(cluster_layer);
158
159 crm_info("Disconnecting from %s cluster layer", cluster_layer_s);
160
161 switch (cluster_layer) {
162 #if SUPPORT_COROSYNC
163 case pcmk_cluster_layer_corosync:
164 pcmk__corosync_disconnect(cluster);
165 pcmk__cluster_destroy_node_caches();
166 return pcmk_rc_ok;
167 #endif
168
169 default:
170 break;
171 }
172
173 crm_err("Failed to disconnect from unsupported cluster layer %s",
174 cluster_layer_s);
175 return EPROTONOSUPPORT;
176 }
177
178
179
180
181
182
183
184
185 pcmk_cluster_t *
186 pcmk_cluster_new(void)
187 {
188 return (pcmk_cluster_t *) pcmk__assert_alloc(1, sizeof(pcmk_cluster_t));
189 }
190
191
192
193
194
195
196 void
197 pcmk_cluster_free(pcmk_cluster_t *cluster)
198 {
199 if (cluster == NULL) {
200 return;
201 }
202 free(cluster->uuid);
203 free(cluster->uname);
204 free(cluster);
205 }
206
207
208
209
210
211
212
213
214
215 int
216 pcmk_cluster_set_destroy_fn(pcmk_cluster_t *cluster, void (*fn)(gpointer))
217 {
218 if (cluster == NULL) {
219 return EINVAL;
220 }
221 cluster->destroy = fn;
222 return pcmk_rc_ok;
223 }
224
225
226
227
228
229
230
231
232
233
234
235 bool
236 pcmk__cluster_send_message(const crm_node_t *node,
237 enum crm_ais_msg_types service, const xmlNode *data)
238 {
239
240 switch (pcmk_get_cluster_layer()) {
241 #if SUPPORT_COROSYNC
242 case pcmk_cluster_layer_corosync:
243 return pcmk__cpg_send_xml(data, node, service);
244 #endif
245
246 default:
247 break;
248 }
249 return false;
250 }
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268 char *
269 pcmk__cluster_node_name(uint32_t nodeid)
270 {
271 char *name = NULL;
272 const enum pcmk_cluster_layer cluster_layer = pcmk_get_cluster_layer();
273 const char *cluster_layer_s = pcmk_cluster_layer_text(cluster_layer);
274
275 switch (cluster_layer) {
276 #if SUPPORT_COROSYNC
277 case pcmk_cluster_layer_corosync:
278 name = pcmk__corosync_name(0, nodeid);
279 if (name != NULL) {
280 return name;
281 }
282 break;
283 #endif
284
285 default:
286 crm_err("Unsupported cluster layer: %s", cluster_layer_s);
287 break;
288 }
289
290 if (nodeid == 0) {
291 struct utsname hostinfo;
292
293 crm_notice("Could not get local node name from %s cluster layer, "
294 "defaulting to local hostname",
295 cluster_layer_s);
296
297 if (uname(&hostinfo) < 0) {
298
299 crm_err("Failed to get the local hostname");
300 crm_exit(CRM_EX_FATAL);
301 }
302 return pcmk__str_copy(hostinfo.nodename);
303 }
304
305 crm_notice("Could not obtain a node name for node with "
306 PCMK_XA_ID "=" PRIu32,
307 nodeid);
308 return NULL;
309 }
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324 const char *
325 pcmk__cluster_local_node_name(void)
326 {
327
328 static char *name = NULL;
329
330 if (name == NULL) {
331 name = pcmk__cluster_node_name(0);
332 }
333 return name;
334 }
335
336
337
338
339
340
341
342
343
344
345
346 const char *
347 pcmk__node_name_from_uuid(const char *uuid)
348 {
349
350
351
352
353
354
355
356
357
358
359
360
361 GHashTableIter iter;
362 crm_node_t *node = NULL;
363
364 CRM_CHECK(uuid != NULL, return NULL);
365
366
367 if (g_hash_table_lookup(crm_remote_peer_cache, uuid)) {
368 return uuid;
369 }
370
371 g_hash_table_iter_init(&iter, crm_peer_cache);
372 while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
373 if (pcmk__str_eq(node->uuid, uuid, pcmk__str_casei)) {
374 return node->uname;
375 }
376 }
377 return NULL;
378 }
379
380
381
382
383
384
385
386
387 const char *
388 pcmk_cluster_layer_text(enum pcmk_cluster_layer layer)
389 {
390 switch (layer) {
391 case pcmk_cluster_layer_corosync:
392 return "corosync";
393 case pcmk_cluster_layer_unknown:
394 return "unknown";
395 case pcmk_cluster_layer_invalid:
396 return "invalid";
397 default:
398 crm_err("Invalid cluster layer: %d", layer);
399 return "invalid";
400 }
401 }
402
403
404
405
406
407
408
409
410
411
412
413
414 enum pcmk_cluster_layer
415 pcmk_get_cluster_layer(void)
416 {
417 static enum pcmk_cluster_layer cluster_layer = pcmk_cluster_layer_unknown;
418 const char *cluster = NULL;
419
420
421 if (cluster_layer != pcmk_cluster_layer_unknown) {
422 return cluster_layer;
423 }
424
425 cluster = pcmk__env_option(PCMK__ENV_CLUSTER_TYPE);
426
427 if (cluster != NULL) {
428 crm_info("Verifying configured cluster layer '%s'", cluster);
429 cluster_layer = pcmk_cluster_layer_invalid;
430
431 #if SUPPORT_COROSYNC
432 if (pcmk__str_eq(cluster, PCMK_VALUE_COROSYNC, pcmk__str_casei)) {
433 cluster_layer = pcmk_cluster_layer_corosync;
434 }
435 #endif
436
437 if (cluster_layer == pcmk_cluster_layer_invalid) {
438 crm_notice("This installation does not support the '%s' cluster "
439 "infrastructure: terminating",
440 cluster);
441 crm_exit(CRM_EX_FATAL);
442 }
443 crm_info("Assuming an active '%s' cluster", cluster);
444
445 } else {
446
447 #if SUPPORT_COROSYNC
448 crm_debug("Testing with Corosync");
449 if (pcmk__corosync_is_active()) {
450 cluster_layer = pcmk_cluster_layer_corosync;
451 }
452 #endif
453
454 if (cluster_layer == pcmk_cluster_layer_unknown) {
455 crm_notice("Could not determine the current cluster layer");
456 } else {
457 crm_info("Detected an active '%s' cluster",
458 pcmk_cluster_layer_text(cluster_layer));
459 }
460 }
461
462 return cluster_layer;
463 }
464
465
466
467
468 #include <crm/cluster/compat.h>
469
470 void
471 set_uuid(xmlNode *xml, const char *attr, crm_node_t *node)
472 {
473 crm_xml_add(xml, attr, pcmk__cluster_node_uuid(node));
474 }
475
476 gboolean
477 crm_cluster_connect(pcmk_cluster_t *cluster)
478 {
479 return pcmk_cluster_connect(cluster) == pcmk_rc_ok;
480 }
481
482 void
483 crm_cluster_disconnect(pcmk_cluster_t *cluster)
484 {
485 pcmk_cluster_disconnect(cluster);
486 }
487
488 const char *
489 name_for_cluster_type(enum cluster_type_e type)
490 {
491 switch (type) {
492 case pcmk_cluster_corosync:
493 return "corosync";
494 case pcmk_cluster_unknown:
495 return "unknown";
496 case pcmk_cluster_invalid:
497 return "invalid";
498 }
499 crm_err("Invalid cluster type: %d", type);
500 return "invalid";
501 }
502
503 enum cluster_type_e
504 get_cluster_type(void)
505 {
506 return (enum cluster_type_e) pcmk_get_cluster_layer();
507 }
508
509 gboolean
510 is_corosync_cluster(void)
511 {
512 return pcmk_get_cluster_layer() == pcmk_cluster_layer_corosync;
513 }
514
515 gboolean
516 send_cluster_message(const crm_node_t *node, enum crm_ais_msg_types service,
517 const xmlNode *data, gboolean ordered)
518 {
519 return pcmk__cluster_send_message(node, service, data);
520 }
521
522 const char *
523 crm_peer_uuid(crm_node_t *peer)
524 {
525 return pcmk__cluster_node_uuid(peer);
526 }
527
528 char *
529 get_node_name(uint32_t nodeid)
530 {
531 return pcmk__cluster_node_name(nodeid);
532 }
533
534 const char *
535 get_local_node_name(void)
536 {
537 return pcmk__cluster_local_node_name();
538 }
539
540 const char *
541 crm_peer_uname(const char *uuid)
542 {
543 return pcmk__node_name_from_uuid(uuid);
544 }
545
546
547