This source file includes following definitions.
- 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
- crm_cluster_connect
- name_for_cluster_type
- get_cluster_type
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 const char *
44 pcmk__cluster_node_uuid(pcmk__node_status_t *node)
45 {
46 const enum pcmk_cluster_layer cluster_layer = pcmk_get_cluster_layer();
47
48 if (node == NULL) {
49 return NULL;
50 }
51 if (node->xml_id != NULL) {
52 return node->xml_id;
53 }
54
55 switch (cluster_layer) {
56 #if SUPPORT_COROSYNC
57 case pcmk_cluster_layer_corosync:
58 node->xml_id = pcmk__corosync_uuid(node);
59 return node->xml_id;
60 #endif
61
62 default:
63 crm_err("Unsupported cluster layer %s",
64 pcmk_cluster_layer_text(cluster_layer));
65 return NULL;
66 }
67 }
68
69
70
71
72
73
74
75
76
77 int
78 pcmk_cluster_connect(pcmk_cluster_t *cluster)
79 {
80 const enum pcmk_cluster_layer cluster_layer = pcmk_get_cluster_layer();
81 const char *cluster_layer_s = pcmk_cluster_layer_text(cluster_layer);
82
83 if (cluster == NULL) {
84 return EINVAL;
85 }
86
87
88 crm_notice("Connecting to %s cluster layer", cluster_layer_s);
89
90 switch (cluster_layer) {
91 #if SUPPORT_COROSYNC
92 case pcmk_cluster_layer_corosync:
93 return pcmk__corosync_connect(cluster);
94 #endif
95
96 default:
97 break;
98 }
99
100 crm_err("Failed to connect to unsupported cluster layer %s",
101 cluster_layer_s);
102 return EPROTONOSUPPORT;
103 }
104
105
106
107
108
109
110
111
112 int
113 pcmk_cluster_disconnect(pcmk_cluster_t *cluster)
114 {
115 const enum pcmk_cluster_layer cluster_layer = pcmk_get_cluster_layer();
116 const char *cluster_layer_s = pcmk_cluster_layer_text(cluster_layer);
117
118 crm_info("Disconnecting from %s cluster layer", cluster_layer_s);
119
120 switch (cluster_layer) {
121 #if SUPPORT_COROSYNC
122 case pcmk_cluster_layer_corosync:
123 pcmk__corosync_disconnect(cluster);
124 pcmk__cluster_destroy_node_caches();
125 return pcmk_rc_ok;
126 #endif
127
128 default:
129 break;
130 }
131
132 crm_err("Failed to disconnect from unsupported cluster layer %s",
133 cluster_layer_s);
134 return EPROTONOSUPPORT;
135 }
136
137
138
139
140
141
142
143
144 pcmk_cluster_t *
145 pcmk_cluster_new(void)
146 {
147 pcmk_cluster_t *cluster = pcmk__assert_alloc(1, sizeof(pcmk_cluster_t));
148
149 cluster->priv = pcmk__assert_alloc(1, sizeof(pcmk__cluster_private_t));
150 cluster->priv->server = pcmk__parse_server(crm_system_name);
151 return cluster;
152 }
153
154
155
156
157
158
159 void
160 pcmk_cluster_free(pcmk_cluster_t *cluster)
161 {
162 if (cluster == NULL) {
163 return;
164 }
165 election_fini(cluster);
166 free(cluster->priv->node_name);
167 free(cluster->priv);
168 free(cluster);
169 }
170
171
172
173
174
175
176
177
178
179 int
180 pcmk_cluster_set_destroy_fn(pcmk_cluster_t *cluster, void (*fn)(gpointer))
181 {
182 if (cluster == NULL) {
183 return EINVAL;
184 }
185 cluster->destroy = fn;
186 return pcmk_rc_ok;
187 }
188
189
190
191
192
193
194
195
196
197
198
199 bool
200 pcmk__cluster_send_message(const pcmk__node_status_t *node,
201 enum pcmk_ipc_server service, const xmlNode *data)
202 {
203
204 switch (pcmk_get_cluster_layer()) {
205 #if SUPPORT_COROSYNC
206 case pcmk_cluster_layer_corosync:
207 return pcmk__cpg_send_xml(data, node, service);
208 #endif
209
210 default:
211 break;
212 }
213 return false;
214 }
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232 char *
233 pcmk__cluster_node_name(uint32_t nodeid)
234 {
235 char *name = NULL;
236 const enum pcmk_cluster_layer cluster_layer = pcmk_get_cluster_layer();
237 const char *cluster_layer_s = pcmk_cluster_layer_text(cluster_layer);
238
239 switch (cluster_layer) {
240 #if SUPPORT_COROSYNC
241 case pcmk_cluster_layer_corosync:
242 name = pcmk__corosync_name(0, nodeid);
243 if (name != NULL) {
244 return name;
245 }
246 break;
247 #endif
248
249 default:
250 crm_err("Unsupported cluster layer: %s", cluster_layer_s);
251 break;
252 }
253
254 if (nodeid == 0) {
255 struct utsname hostinfo;
256
257 crm_notice("Could not get local node name from %s cluster layer, "
258 "defaulting to local hostname",
259 cluster_layer_s);
260
261 if (uname(&hostinfo) < 0) {
262
263 crm_err("Failed to get the local hostname");
264 crm_exit(CRM_EX_FATAL);
265 }
266 return pcmk__str_copy(hostinfo.nodename);
267 }
268
269 crm_notice("Could not obtain a node name for node with "
270 PCMK_XA_ID "=" PRIu32,
271 nodeid);
272 return NULL;
273 }
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288 const char *
289 pcmk__cluster_local_node_name(void)
290 {
291
292 static char *name = NULL;
293
294 if (name == NULL) {
295 name = pcmk__cluster_node_name(0);
296 }
297 return name;
298 }
299
300
301
302
303
304
305
306
307
308
309
310 const char *
311 pcmk__node_name_from_uuid(const char *uuid)
312 {
313
314
315
316
317
318
319
320
321
322
323
324
325 GHashTableIter iter;
326 pcmk__node_status_t *node = NULL;
327
328 CRM_CHECK(uuid != NULL, return NULL);
329
330
331 if (g_hash_table_lookup(pcmk__remote_peer_cache, uuid)) {
332 return uuid;
333 }
334
335 g_hash_table_iter_init(&iter, pcmk__peer_cache);
336 while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
337 if (pcmk__str_eq(node->xml_id, uuid, pcmk__str_casei)) {
338 return node->name;
339 }
340 }
341 return NULL;
342 }
343
344
345
346
347
348
349
350
351 const char *
352 pcmk_cluster_layer_text(enum pcmk_cluster_layer layer)
353 {
354 switch (layer) {
355 case pcmk_cluster_layer_corosync:
356 return "corosync";
357 case pcmk_cluster_layer_unknown:
358 return "unknown";
359 case pcmk_cluster_layer_invalid:
360 return "invalid";
361 default:
362 crm_err("Invalid cluster layer: %d", layer);
363 return "invalid";
364 }
365 }
366
367
368
369
370
371
372
373
374
375
376
377
378 enum pcmk_cluster_layer
379 pcmk_get_cluster_layer(void)
380 {
381 static enum pcmk_cluster_layer cluster_layer = pcmk_cluster_layer_unknown;
382 const char *cluster = NULL;
383
384
385 if (cluster_layer != pcmk_cluster_layer_unknown) {
386 return cluster_layer;
387 }
388
389 cluster = pcmk__env_option(PCMK__ENV_CLUSTER_TYPE);
390
391 if (cluster != NULL) {
392 crm_info("Verifying configured cluster layer '%s'", cluster);
393 cluster_layer = pcmk_cluster_layer_invalid;
394
395 #if SUPPORT_COROSYNC
396 if (pcmk__str_eq(cluster, PCMK_VALUE_COROSYNC, pcmk__str_casei)) {
397 cluster_layer = pcmk_cluster_layer_corosync;
398 }
399 #endif
400
401 if (cluster_layer == pcmk_cluster_layer_invalid) {
402 crm_notice("This installation does not support the '%s' cluster "
403 "infrastructure: terminating",
404 cluster);
405 crm_exit(CRM_EX_FATAL);
406 }
407 crm_info("Assuming an active '%s' cluster", cluster);
408
409 } else {
410
411 #if SUPPORT_COROSYNC
412 crm_debug("Testing with Corosync");
413 if (pcmk__corosync_is_active()) {
414 cluster_layer = pcmk_cluster_layer_corosync;
415 }
416 #endif
417
418 if (cluster_layer == pcmk_cluster_layer_unknown) {
419 crm_notice("Could not determine the current cluster layer");
420 } else {
421 crm_info("Detected an active '%s' cluster",
422 pcmk_cluster_layer_text(cluster_layer));
423 }
424 }
425
426 return cluster_layer;
427 }
428
429
430
431
432 #include <crm/cluster/compat.h>
433
434 gboolean
435 crm_cluster_connect(pcmk_cluster_t *cluster)
436 {
437 if (cluster == NULL) {
438 return FALSE;
439 }
440 if (cluster->priv == NULL) {
441
442
443
444 cluster->priv = pcmk__assert_alloc(1, sizeof(pcmk__cluster_private_t));
445 }
446 return pcmk_cluster_connect(cluster) == pcmk_rc_ok;
447 }
448
449 const char *
450 name_for_cluster_type(enum cluster_type_e type)
451 {
452 switch (type) {
453 case pcmk_cluster_corosync:
454 return "corosync";
455 case pcmk_cluster_unknown:
456 return "unknown";
457 case pcmk_cluster_invalid:
458 return "invalid";
459 }
460 crm_err("Invalid cluster type: %d", type);
461 return "invalid";
462 }
463
464 enum cluster_type_e
465 get_cluster_type(void)
466 {
467 return (enum cluster_type_e) pcmk_get_cluster_layer();
468 }
469
470
471