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