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