This source file includes following definitions.
- crm_peer_uuid
- crm_cluster_connect
- crm_cluster_disconnect
- send_cluster_message
- get_local_node_name
- get_node_name
- crm_peer_uname
- set_uuid
- name_for_cluster_type
- get_cluster_type
- is_corosync_cluster
1
2
3
4
5
6
7
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>
25 #include <crm/cluster/internal.h>
26 #include "crmcluster_private.h"
27
28 CRM_TRACE_INIT_DATA(cluster);
29
30
31
32
33
34
35
36
37 const char *
38 crm_peer_uuid(crm_node_t *peer)
39 {
40 char *uuid = NULL;
41
42
43 if (peer == NULL) {
44 return NULL;
45 }
46 if (peer->uuid != NULL) {
47 return peer->uuid;
48 }
49
50 switch (get_cluster_type()) {
51 case pcmk_cluster_corosync:
52 #if SUPPORT_COROSYNC
53 uuid = pcmk__corosync_uuid(peer);
54 #endif
55 break;
56
57 case pcmk_cluster_unknown:
58 case pcmk_cluster_invalid:
59 crm_err("Unsupported cluster type");
60 break;
61 }
62
63 peer->uuid = uuid;
64 return peer->uuid;
65 }
66
67
68
69
70
71
72
73
74 gboolean
75 crm_cluster_connect(crm_cluster_t *cluster)
76 {
77 enum cluster_type_e type = get_cluster_type();
78
79 crm_notice("Connecting to %s cluster infrastructure",
80 name_for_cluster_type(type));
81 switch (type) {
82 case pcmk_cluster_corosync:
83 #if SUPPORT_COROSYNC
84 if (is_corosync_cluster()) {
85 crm_peer_init();
86 return pcmk__corosync_connect(cluster);
87 }
88 #endif
89 break;
90 default:
91 break;
92 }
93 return FALSE;
94 }
95
96
97
98
99
100
101 void
102 crm_cluster_disconnect(crm_cluster_t *cluster)
103 {
104 enum cluster_type_e type = get_cluster_type();
105
106 crm_info("Disconnecting from %s cluster infrastructure",
107 name_for_cluster_type(type));
108 switch (type) {
109 case pcmk_cluster_corosync:
110 #if SUPPORT_COROSYNC
111 if (is_corosync_cluster()) {
112 crm_peer_destroy();
113 pcmk__corosync_disconnect(cluster);
114 }
115 #endif
116 break;
117 default:
118 break;
119 }
120 }
121
122
123
124
125
126
127
128
129
130
131
132 gboolean
133 send_cluster_message(crm_node_t *node, enum crm_ais_msg_types service,
134 xmlNode *data, gboolean ordered)
135 {
136 switch (get_cluster_type()) {
137 case pcmk_cluster_corosync:
138 #if SUPPORT_COROSYNC
139 return pcmk__cpg_send_xml(data, node, service);
140 #endif
141 break;
142 default:
143 break;
144 }
145 return FALSE;
146 }
147
148
149
150
151
152
153
154 const char *
155 get_local_node_name(void)
156 {
157 static char *name = NULL;
158
159 if (name == NULL) {
160 name = get_node_name(0);
161 }
162 return name;
163 }
164
165
166
167
168
169
170
171
172
173
174 char *
175 get_node_name(uint32_t nodeid)
176 {
177 char *name = NULL;
178 enum cluster_type_e stack = get_cluster_type();
179
180 switch (stack) {
181 # if SUPPORT_COROSYNC
182 case pcmk_cluster_corosync:
183 name = pcmk__corosync_name(0, nodeid);
184 break;
185 # endif
186
187 default:
188 crm_err("Unknown cluster type: %s (%d)", name_for_cluster_type(stack), stack);
189 }
190
191 if ((name == NULL) && (nodeid == 0)) {
192 name = pcmk_hostname();
193 if (name == NULL) {
194
195 crm_err("Could not obtain the local %s node name",
196 name_for_cluster_type(stack));
197 crm_exit(CRM_EX_FATAL);
198 }
199 crm_notice("Defaulting to uname -n for the local %s node name",
200 name_for_cluster_type(stack));
201 }
202
203 if (name == NULL) {
204 crm_notice("Could not obtain a node name for %s node with id %u",
205 name_for_cluster_type(stack), nodeid);
206 }
207 return name;
208 }
209
210
211
212
213
214
215
216
217
218
219
220 const char *
221 crm_peer_uname(const char *uuid)
222 {
223 GHashTableIter iter;
224 crm_node_t *node = NULL;
225
226 CRM_CHECK(uuid != NULL, return NULL);
227
228
229 if (g_hash_table_lookup(crm_remote_peer_cache, uuid)) {
230 return uuid;
231 }
232
233
234 g_hash_table_iter_init(&iter, crm_peer_cache);
235 while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
236 if (pcmk__str_eq(node->uuid, uuid, pcmk__str_casei)) {
237 if (node->uname != NULL) {
238 return node->uname;
239 }
240 break;
241 }
242 }
243 node = NULL;
244
245 #if SUPPORT_COROSYNC
246 if (is_corosync_cluster()) {
247 long long id;
248
249 if ((pcmk__scan_ll(uuid, &id, 0LL) != pcmk_rc_ok)
250 || (id < 1LL) || (id > UINT32_MAX)) {
251 crm_err("Invalid Corosync node ID '%s'", uuid);
252 return NULL;
253 }
254
255 node = pcmk__search_cluster_node_cache((uint32_t) id, NULL);
256 if (node != NULL) {
257 crm_info("Setting uuid for node %s[%u] to %s",
258 node->uname, node->id, uuid);
259 node->uuid = strdup(uuid);
260 return node->uname;
261 }
262 return NULL;
263 }
264 #endif
265
266 return NULL;
267 }
268
269
270
271
272
273
274
275
276 void
277 set_uuid(xmlNode *xml, const char *attr, crm_node_t *node)
278 {
279 crm_xml_add(xml, attr, crm_peer_uuid(node));
280 }
281
282
283
284
285
286
287
288
289 const char *
290 name_for_cluster_type(enum cluster_type_e type)
291 {
292 switch (type) {
293 case pcmk_cluster_corosync:
294 return "corosync";
295 case pcmk_cluster_unknown:
296 return "unknown";
297 case pcmk_cluster_invalid:
298 return "invalid";
299 }
300 crm_err("Invalid cluster type: %d", type);
301 return "invalid";
302 }
303
304
305
306
307
308
309
310 enum cluster_type_e
311 get_cluster_type(void)
312 {
313 bool detected = false;
314 const char *cluster = NULL;
315 static enum cluster_type_e cluster_type = pcmk_cluster_unknown;
316
317
318 if (cluster_type != pcmk_cluster_unknown) {
319 return cluster_type;
320 }
321
322 cluster = pcmk__env_option("cluster_type");
323
324 #if SUPPORT_COROSYNC
325
326 if (cluster == NULL) {
327 crm_debug("Testing with Corosync");
328 cluster_type = pcmk__corosync_detect();
329 if (cluster_type != pcmk_cluster_unknown) {
330 detected = true;
331 goto done;
332 }
333 }
334 #endif
335
336
337 crm_info("Verifying cluster type: '%s'",
338 ((cluster == NULL)? "-unspecified-" : cluster));
339 if (cluster == NULL) {
340
341 #if SUPPORT_COROSYNC
342 } else if (pcmk__str_eq(cluster, "corosync", pcmk__str_casei)) {
343 cluster_type = pcmk_cluster_corosync;
344 #endif
345
346 } else {
347 cluster_type = pcmk_cluster_invalid;
348 goto done;
349 }
350
351 done:
352 if (cluster_type == pcmk_cluster_unknown) {
353 crm_notice("Could not determine the current cluster type");
354
355 } else if (cluster_type == pcmk_cluster_invalid) {
356 crm_notice("This installation does not support the '%s' cluster infrastructure: terminating.",
357 cluster);
358 crm_exit(CRM_EX_FATAL);
359
360 } else {
361 crm_info("%s an active '%s' cluster",
362 (detected? "Detected" : "Assuming"),
363 name_for_cluster_type(cluster_type));
364 }
365
366 return cluster_type;
367 }
368
369
370
371
372
373
374 gboolean
375 is_corosync_cluster(void)
376 {
377 return get_cluster_type() == pcmk_cluster_corosync;
378 }