pacemaker  1.1.14-70404b0
Scalable High-Availability cluster resource manager
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
corosync.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include <crm_internal.h>
20 #include <bzlib.h>
21 #include <sys/socket.h>
22 #include <netinet/in.h>
23 #include <arpa/inet.h>
24 #include <netdb.h>
25 
26 #include <crm/common/ipc.h>
27 #include <crm/cluster/internal.h>
28 #include <crm/common/mainloop.h>
29 #include <sys/utsname.h>
30 
31 #include <qb/qbipcc.h>
32 #include <qb/qbutil.h>
33 
34 #include <corosync/corodefs.h>
35 #include <corosync/corotypes.h>
36 #include <corosync/hdb.h>
37 #include <corosync/cfg.h>
38 #include <corosync/cmap.h>
39 #include <corosync/quorum.h>
40 
41 #include <crm/msg_xml.h>
42 
43 quorum_handle_t pcmk_quorum_handle = 0;
44 
45 gboolean(*quorum_app_callback) (unsigned long long seq, gboolean quorate) = NULL;
46 
47 /*
48  * CFG functionality stolen from node_name() in corosync-quorumtool.c
49  * This resolves the first address assigned to a node and returns the name or IP address.
50  */
51 char *
52 corosync_node_name(uint64_t /*cmap_handle_t */ cmap_handle, uint32_t nodeid)
53 {
54  int lpc = 0;
55  int rc = CS_OK;
56  int retries = 0;
57  char *name = NULL;
58  cmap_handle_t local_handle = 0;
59 
60  /* nodeid == 0 == CMAN_NODEID_US */
61  if (nodeid == 0) {
62  nodeid = get_local_nodeid(0);
63  }
64 
65  if (cmap_handle == 0 && local_handle == 0) {
66  retries = 0;
67  crm_trace("Initializing CMAP connection");
68  do {
69  rc = cmap_initialize(&local_handle);
70  if (rc != CS_OK) {
71  retries++;
72  crm_debug("API connection setup failed: %s. Retrying in %ds", cs_strerror(rc),
73  retries);
74  sleep(retries);
75  }
76 
77  } while (retries < 5 && rc != CS_OK);
78 
79  if (rc != CS_OK) {
80  crm_warn("Could not connect to Cluster Configuration Database API, error %s",
81  cs_strerror(rc));
82  local_handle = 0;
83  }
84  }
85 
86  if (cmap_handle == 0) {
87  cmap_handle = local_handle;
88  }
89 
90  while (name == NULL && cmap_handle != 0) {
91  uint32_t id = 0;
92  char *key = NULL;
93 
94  key = crm_strdup_printf("nodelist.node.%d.nodeid", lpc);
95  rc = cmap_get_uint32(cmap_handle, key, &id);
96  crm_trace("Checking %u vs %u from %s", nodeid, id, key);
97  free(key);
98 
99  if (rc != CS_OK) {
100  break;
101  }
102 
103  if (nodeid == id) {
104  crm_trace("Searching for node name for %u in nodelist.node.%d %s", nodeid, lpc, name);
105  if (name == NULL) {
106  key = crm_strdup_printf("nodelist.node.%d.ring0_addr", lpc);
107  cmap_get_string(cmap_handle, key, &name);
108  crm_trace("%s = %s", key, name);
109 
110  if (node_name_is_valid(key, name) == FALSE) {
111  free(name);
112  name = NULL;
113  }
114  free(key);
115  }
116 
117  if (name == NULL) {
118  key = crm_strdup_printf("nodelist.node.%d.name", lpc);
119  cmap_get_string(cmap_handle, key, &name);
120  crm_trace("%s = %s %d", key, name, rc);
121  free(key);
122  }
123  break;
124  }
125 
126  lpc++;
127  }
128 
129  if(local_handle) {
130  cmap_finalize(local_handle);
131  }
132 
133  if (name == NULL) {
134  crm_info("Unable to get node name for nodeid %u", nodeid);
135  }
136  return name;
137 }
138 
139 void
141 {
142  crm_notice("Disconnecting from Corosync");
143 
144  cluster_disconnect_cpg(cluster);
145 
146  if (pcmk_quorum_handle) {
147  crm_trace("Disconnecting quorum");
148  quorum_finalize(pcmk_quorum_handle);
149  pcmk_quorum_handle = 0;
150 
151  } else {
152  crm_info("No Quorum connection");
153  }
154 }
155 
157 gboolean ais_membership_force = FALSE;
158 
159 
160 static int
161 pcmk_quorum_dispatch(gpointer user_data)
162 {
163  int rc = 0;
164 
165  rc = quorum_dispatch(pcmk_quorum_handle, CS_DISPATCH_ALL);
166  if (rc < 0) {
167  crm_err("Connection to the Quorum API failed: %d", rc);
168  pcmk_quorum_handle = 0;
169  return -1;
170  }
171  return 0;
172 }
173 
174 static void
175 pcmk_quorum_notification(quorum_handle_t handle,
177  uint64_t ring_id, uint32_t view_list_entries, uint32_t * view_list)
178 {
179  int i;
180  GHashTableIter iter;
181  crm_node_t *node = NULL;
182  static gboolean init_phase = TRUE;
183 
184  if (quorate != crm_have_quorum) {
185  crm_notice("Membership " U64T ": quorum %s (%lu)", ring_id,
186  quorate ? "acquired" : "lost", (long unsigned int)view_list_entries);
188 
189  } else {
190  crm_info("Membership " U64T ": quorum %s (%lu)", ring_id,
191  quorate ? "retained" : "still lost", (long unsigned int)view_list_entries);
192  }
193 
194  if (view_list_entries == 0 && init_phase) {
195  crm_info("Corosync membership is still forming, ignoring");
196  return;
197  }
198 
199  init_phase = FALSE;
200 
201  /* Reset last_seen for all cached nodes so we can tell which ones aren't
202  * in the view list */
203  g_hash_table_iter_init(&iter, crm_peer_cache);
204  while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
205  node->last_seen = 0;
206  }
207 
208  /* Update the peer cache for each node in view list */
209  for (i = 0; i < view_list_entries; i++) {
210  uint32_t id = view_list[i];
211 
212  crm_debug("Member[%d] %u ", i, id);
213 
214  /* Get this node's peer cache entry (adding one if not already there) */
215  node = crm_get_peer(id, NULL);
216  if (node->uname == NULL) {
217  char *name = corosync_node_name(0, id);
218 
219  crm_info("Obtaining name for new node %u", id);
220  node = crm_get_peer(id, name);
221  free(name);
222  }
223 
224  /* Update the node state (including updating last_seen to ring_id) */
225  crm_update_peer_state(__FUNCTION__, node, CRM_NODE_MEMBER, ring_id);
226  }
227 
228  /* Remove any peer cache entries we didn't update */
229  crm_reap_unseen_nodes(ring_id);
230 
231  if (quorum_app_callback) {
232  quorum_app_callback(ring_id, quorate);
233  }
234 }
235 
236 quorum_callbacks_t quorum_callbacks = {
237  .quorum_notify_fn = pcmk_quorum_notification,
238 };
239 
240 gboolean
241 cluster_connect_quorum(gboolean(*dispatch) (unsigned long long, gboolean),
242  void (*destroy) (gpointer))
243 {
244  int rc = -1;
245  int fd = 0;
246  int quorate = 0;
247  uint32_t quorum_type = 0;
248  struct mainloop_fd_callbacks quorum_fd_callbacks;
249 
250  quorum_fd_callbacks.dispatch = pcmk_quorum_dispatch;
251  quorum_fd_callbacks.destroy = destroy;
252 
253  crm_debug("Configuring Pacemaker to obtain quorum from Corosync");
254 
255  rc = quorum_initialize(&pcmk_quorum_handle, &quorum_callbacks, &quorum_type);
256  if (rc != CS_OK) {
257  crm_err("Could not connect to the Quorum API: %d\n", rc);
258  goto bail;
259 
260  } else if (quorum_type != QUORUM_SET) {
261  crm_err("Corosync quorum is not configured\n");
262  goto bail;
263  }
264 
265  rc = quorum_getquorate(pcmk_quorum_handle, &quorate);
266  if (rc != CS_OK) {
267  crm_err("Could not obtain the current Quorum API state: %d\n", rc);
268  goto bail;
269  }
270 
271  crm_notice("Quorum %s", quorate ? "acquired" : "lost");
274 
275  rc = quorum_trackstart(pcmk_quorum_handle, CS_TRACK_CHANGES | CS_TRACK_CURRENT);
276  if (rc != CS_OK) {
277  crm_err("Could not setup Quorum API notifications: %d\n", rc);
278  goto bail;
279  }
280 
281  rc = quorum_fd_get(pcmk_quorum_handle, &fd);
282  if (rc != CS_OK) {
283  crm_err("Could not obtain the Quorum API connection: %d\n", rc);
284  goto bail;
285  }
286 
287  mainloop_add_fd("quorum", G_PRIORITY_HIGH, fd, dispatch, &quorum_fd_callbacks);
288 
289  corosync_initialize_nodelist(NULL, FALSE, NULL);
290 
291  bail:
292  if (rc != CS_OK) {
293  quorum_finalize(pcmk_quorum_handle);
294  return FALSE;
295  }
296  return TRUE;
297 }
298 
299 gboolean
301 {
302  int retries = 0;
303 
304  while (retries < 5) {
305  int rc = init_cs_connection_once(cluster);
306 
307  retries++;
308 
309  switch (rc) {
310  case CS_OK:
311  return TRUE;
312  break;
313  case CS_ERR_TRY_AGAIN:
314  case CS_ERR_QUEUE_FULL:
315  sleep(retries);
316  break;
317  default:
318  return FALSE;
319  }
320  }
321 
322  crm_err("Could not connect to corosync after %d retries", retries);
323  return FALSE;
324 }
325 
326 gboolean
328 {
329  crm_node_t *peer = NULL;
330  enum cluster_type_e stack = get_cluster_type();
331 
332  crm_peer_init();
333 
334  /* Here we just initialize comms */
335  if (stack != pcmk_cluster_corosync) {
336  crm_err("Invalid cluster type: %s (%d)", name_for_cluster_type(stack), stack);
337  return FALSE;
338  }
339 
340  if (cluster_connect_cpg(cluster) == FALSE) {
341  return FALSE;
342  }
343  crm_info("Connection to '%s': established", name_for_cluster_type(stack));
344 
345  cluster->nodeid = get_local_nodeid(0);
346  if(cluster->nodeid == 0) {
347  crm_err("Could not establish local nodeid");
348  return FALSE;
349  }
350 
351  cluster->uname = get_node_name(0);
352  if(cluster->uname == NULL) {
353  crm_err("Could not establish local node name");
354  return FALSE;
355  }
356 
357  /* Ensure the local node always exists */
358  peer = crm_get_peer(cluster->nodeid, cluster->uname);
359  cluster->uuid = get_corosync_uuid(peer);
360 
361  return TRUE;
362 }
363 
364 gboolean
365 check_message_sanity(const AIS_Message * msg, const char *data)
366 {
367  gboolean sane = TRUE;
368  int dest = msg->host.type;
369  int tmp_size = msg->header.size - sizeof(AIS_Message);
370 
371  if (sane && msg->header.size == 0) {
372  crm_warn("Message with no size");
373  sane = FALSE;
374  }
375 
376  if (sane && msg->header.error != CS_OK) {
377  crm_warn("Message header contains an error: %d", msg->header.error);
378  sane = FALSE;
379  }
380 
381  if (sane && ais_data_len(msg) != tmp_size) {
382  crm_warn("Message payload size is incorrect: expected %d, got %d", ais_data_len(msg),
383  tmp_size);
384  sane = TRUE;
385  }
386 
387  if (sane && ais_data_len(msg) == 0) {
388  crm_warn("Message with no payload");
389  sane = FALSE;
390  }
391 
392  if (sane && data && msg->is_compressed == FALSE) {
393  int str_size = strlen(data) + 1;
394 
395  if (ais_data_len(msg) != str_size) {
396  int lpc = 0;
397 
398  crm_warn("Message payload is corrupted: expected %d bytes, got %d",
399  ais_data_len(msg), str_size);
400  sane = FALSE;
401  for (lpc = (str_size - 10); lpc < msg->size; lpc++) {
402  if (lpc < 0) {
403  lpc = 0;
404  }
405  crm_debug("bad_data[%d]: %d / '%c'", lpc, data[lpc], data[lpc]);
406  }
407  }
408  }
409 
410  if (sane == FALSE) {
411  crm_err("Invalid message %d: (dest=%s:%s, from=%s:%s.%u, compressed=%d, size=%d, total=%d)",
412  msg->id, ais_dest(&(msg->host)), msg_type2text(dest),
413  ais_dest(&(msg->sender)), msg_type2text(msg->sender.type),
414  msg->sender.pid, msg->is_compressed, ais_data_len(msg), msg->header.size);
415 
416  } else {
417  crm_trace
418  ("Verified message %d: (dest=%s:%s, from=%s:%s.%u, compressed=%d, size=%d, total=%d)",
419  msg->id, ais_dest(&(msg->host)), msg_type2text(dest), ais_dest(&(msg->sender)),
420  msg_type2text(msg->sender.type), msg->sender.pid, msg->is_compressed,
421  ais_data_len(msg), msg->header.size);
422  }
423 
424  return sane;
425 }
426 
427 enum cluster_type_e
429 {
430  int rc = CS_OK;
431  cmap_handle_t handle;
432 
433  rc = cmap_initialize(&handle);
434 
435  switch(rc) {
436  case CS_OK:
437  break;
438  case CS_ERR_SECURITY:
439  crm_debug("Failed to initialize the cmap API: Permission denied (%d)", rc);
440  /* It's there, we just can't talk to it.
441  * Good enough for us to identify as 'corosync'
442  */
443  return pcmk_cluster_corosync;
444 
445  default:
446  crm_info("Failed to initialize the cmap API: %s (%d)",
447  ais_error2text(rc), rc);
448  return pcmk_cluster_unknown;
449  }
450 
451  cmap_finalize(handle);
452  return pcmk_cluster_corosync;
453 }
454 
455 gboolean
457 {
458  if (node == NULL) {
459  crm_trace("NULL");
460  return FALSE;
461 
462  } else if (safe_str_neq(node->state, CRM_NODE_MEMBER)) {
463  crm_trace("%s: state=%s", node->uname, node->state);
464  return FALSE;
465 
466  } else if ((node->processes & crm_proc_cpg) == 0) {
467  crm_trace("%s: processes=%.16x", node->uname, node->processes);
468  return FALSE;
469  }
470  return TRUE;
471 }
472 
473 gboolean
474 corosync_initialize_nodelist(void *cluster, gboolean force_member, xmlNode * xml_parent)
475 {
476  int lpc = 0;
477  int rc = CS_OK;
478  int retries = 0;
479  gboolean any = FALSE;
480  cmap_handle_t cmap_handle;
481 
482  do {
483  rc = cmap_initialize(&cmap_handle);
484  if (rc != CS_OK) {
485  retries++;
486  crm_debug("API connection setup failed: %s. Retrying in %ds", cs_strerror(rc),
487  retries);
488  sleep(retries);
489  }
490 
491  } while (retries < 5 && rc != CS_OK);
492 
493  if (rc != CS_OK) {
494  crm_warn("Could not connect to Cluster Configuration Database API, error %d", rc);
495  return FALSE;
496  }
497 
498  crm_peer_init();
499  crm_trace("Initializing corosync nodelist");
500  for (lpc = 0;; lpc++) {
501  uint32_t nodeid = 0;
502  char *name = NULL;
503  char *key = NULL;
504 
505  key = crm_strdup_printf("nodelist.node.%d.nodeid", lpc);
506  rc = cmap_get_uint32(cmap_handle, key, &nodeid);
507  free(key);
508 
509  if (rc != CS_OK) {
510  break;
511  }
512 
513  name = corosync_node_name(cmap_handle, nodeid);
514  if (name != NULL) {
515  GHashTableIter iter;
516  crm_node_t *node = NULL;
517 
518  g_hash_table_iter_init(&iter, crm_peer_cache);
519  while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
520  if(node && node->uname && strcasecmp(node->uname, name) == 0) {
521  if (node->id && node->id != nodeid) {
522  crm_crit("Nodes %u and %u share the same name '%s': shutting down", node->id,
523  nodeid, name);
525  }
526  }
527  }
528  }
529 
530  if (nodeid > 0 || name != NULL) {
531  crm_trace("Initializing node[%d] %u = %s", lpc, nodeid, name);
532  crm_get_peer(nodeid, name);
533  }
534 
535  if (nodeid > 0 && name != NULL) {
536  any = TRUE;
537 
538  if (xml_parent) {
539  char buffer[64];
540  xmlNode *node = create_xml_node(xml_parent, XML_CIB_TAG_NODE);
541 
542  if(snprintf(buffer, 63, "%u", nodeid) > 0) {
543  crm_xml_add(node, XML_ATTR_ID, buffer);
544  }
545  crm_xml_add(node, XML_ATTR_UNAME, name);
546  if (force_member) {
548  }
549  }
550  }
551 
552  free(name);
553  }
554  cmap_finalize(cmap_handle);
555  return any;
556 }
557 
558 char *
560 {
561  cmap_handle_t handle;
562  char *cluster_name = NULL;
563  int rc = CS_OK;
564 
565  rc = cmap_initialize(&handle);
566  if (rc != CS_OK) {
567  crm_info("Failed to initialize the cmap API: %s (%d)", ais_error2text(rc), rc);
568  return NULL;
569  }
570 
571  rc = cmap_get_string(handle, "totem.cluster_name", &cluster_name);
572  if (rc != CS_OK) {
573  crm_info("Cannot get totem.cluster_name: %s (%d)", ais_error2text(rc), rc);
574 
575  } else {
576  crm_debug("cmap totem.cluster_name = '%s'", cluster_name);
577  }
578 
579  cmap_finalize(handle);
580 
581  return cluster_name;
582 }
583 
584 int
585 corosync_cmap_has_config(const char *prefix)
586 {
587  int rc = CS_OK;
588  int retries = 0;
589  static int found = -1;
590  cmap_handle_t cmap_handle;
591  cmap_iter_handle_t iter_handle;
592  char key_name[CMAP_KEYNAME_MAXLEN + 1];
593 
594  if(found != -1) {
595  return found;
596  }
597 
598  do {
599  rc = cmap_initialize(&cmap_handle);
600  if (rc != CS_OK) {
601  retries++;
602  crm_debug("API connection setup failed: %s. Retrying in %ds", cs_strerror(rc),
603  retries);
604  sleep(retries);
605  }
606 
607  } while (retries < 5 && rc != CS_OK);
608 
609  if (rc != CS_OK) {
610  crm_warn("Could not connect to Cluster Configuration Database API: %s (rc=%d)",
611  cs_strerror(rc), rc);
612  return -1;
613  }
614 
615  rc = cmap_iter_init(cmap_handle, prefix, &iter_handle);
616  if (rc != CS_OK) {
617  crm_warn("Failed to initialize iteration for corosync cmap '%s': %s (rc=%d)",
618  prefix, cs_strerror(rc), rc);
619  goto bail;
620  }
621 
622  found = 0;
623  while ((rc = cmap_iter_next(cmap_handle, iter_handle, key_name, NULL, NULL)) == CS_OK) {
624  crm_trace("'%s' is configured in corosync cmap: %s", prefix, key_name);
625  found++;
626  break;
627  }
628  cmap_iter_finalize(cmap_handle, iter_handle);
629 
630 bail:
631  cmap_finalize(cmap_handle);
632 
633  return found;
634 }
enum crm_ais_msg_types type
Definition: internal.h:39
gboolean check_message_sanity(const AIS_Message *msg, const char *data)
Definition: corosync.c:365
#define crm_notice(fmt, args...)
Definition: logging.h:250
gboolean is_compressed
Definition: internal.h:48
uint32_t size
Definition: internal.h:53
#define crm_crit(fmt, args...)
Definition: logging.h:247
gboolean safe_str_neq(const char *a, const char *b)
Definition: utils.c:668
mainloop_io_t * mainloop_add_fd(const char *name, int priority, int fd, void *userdata, struct mainloop_fd_callbacks *callbacks)
Definition: mainloop.c:806
uint32_t nodeid
Definition: cluster.h:94
quorum_callbacks_t quorum_callbacks
Definition: corosync.c:236
void crm_reap_unseen_nodes(uint64_t ring_id)
Definition: membership.c:918
char * corosync_node_name(uint64_tcmap_handle, uint32_t nodeid)
Definition: corosync.c:52
quorum_handle_t pcmk_quorum_handle
Definition: corosync.c:43
uint32_t quorate
Definition: internal.h:52
uint32_t id
Definition: cluster.h:70
#define XML_ATTR_TYPE
Definition: msg_xml.h:103
gboolean crm_have_quorum
Definition: membership.c:38
char * get_corosync_uuid(crm_node_t *peer)
Definition: cluster.c:106
void terminate_cs_connection(crm_cluster_t *cluster)
Definition: corosync.c:140
void crm_peer_init(void)
Definition: membership.c:262
gboolean cluster_connect_quorum(gboolean(*dispatch)(unsigned long long, gboolean), void(*destroy)(gpointer))
Definition: corosync.c:241
crm_node_t * crm_get_peer(unsigned int id, const char *uname)
Definition: membership.c:519
int(* dispatch)(gpointer userdata)
Definition: mainloop.h:90
char * uuid
Definition: cluster.h:92
char * get_node_name(uint32_t nodeid)
Definition: cluster.c:301
Wrappers for and extensions to glib mainloop.
gboolean init_cs_connection(crm_cluster_t *cluster)
Definition: corosync.c:300
gboolean crm_is_corosync_peer_active(const crm_node_t *node)
Definition: corosync.c:456
void cluster_disconnect_cpg(crm_cluster_t *cluster)
Definition: cpg.c:58
#define crm_warn(fmt, args...)
Definition: logging.h:249
uint32_t processes
Definition: cluster.h:76
char * corosync_cluster_name(void)
Definition: corosync.c:559
#define crm_debug(fmt, args...)
Definition: logging.h:253
#define XML_ATTR_ID
Definition: msg_xml.h:100
void(* destroy)(gpointer userdata)
Definition: mainloop.h:91
cluster_type_e
Definition: cluster.h:206
gboolean(* quorum_app_callback)(unsigned long long seq, gboolean quorate)
Definition: corosync.c:45
#define crm_trace(fmt, args...)
Definition: logging.h:254
AIS_Host sender
Definition: internal.h:51
uint32_t id
Definition: internal.h:47
#define XML_ATTR_UNAME
Definition: msg_xml.h:128
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:2793
struct crm_ais_msg_s AIS_Message
Definition: internal.h:33
#define ais_data_len(msg)
Definition: internal.h:210
int corosync_cmap_has_config(const char *prefix)
Definition: corosync.c:585
#define CRM_NODE_MEMBER
Definition: cluster.h:44
enum cluster_type_e find_corosync_variant(void)
Definition: corosync.c:428
gboolean ais_membership_force
Definition: corosync.c:157
int ais_membership_timer
Definition: corosync.c:156
#define XML_CIB_TAG_NODE
Definition: msg_xml.h:167
const char * name_for_cluster_type(enum cluster_type_e type)
Definition: cluster.c:457
#define DAEMON_RESPAWN_STOP
Definition: crm.h:67
gboolean init_cs_connection_once(crm_cluster_t *cluster)
Definition: corosync.c:327
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Definition: xml.c:2695
crm_node_t * crm_update_peer_state(const char *source, crm_node_t *node, const char *state, int membership)
Update a node's state and membership information.
Definition: membership.c:906
char * uname
Definition: cluster.h:93
uint32_t get_local_nodeid(cpg_handle_t handle)
Definition: cpg.c:72
gboolean node_name_is_valid(const char *key, const char *name)
Definition: cluster.c:640
#define crm_err(fmt, args...)
Definition: logging.h:248
#define uint32_t
Definition: stdint.in.h:158
char data[0]
Definition: internal.h:58
int crm_exit(int rc)
Definition: utils.c:87
char * state
Definition: cluster.h:81
#define U64T
Definition: config.h:629
Wrappers for and extensions to libqb IPC.
uint32_t pid
Definition: internal.h:37
char * uname
Definition: cluster.h:79
uint64_t last_seen
Definition: cluster.h:72
AIS_Host host
Definition: internal.h:50
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
GHashTable * crm_peer_cache
Definition: membership.c:35
#define crm_info(fmt, args...)
Definition: logging.h:251
gboolean corosync_initialize_nodelist(void *cluster, gboolean force_member, xmlNode *xml_parent)
Definition: corosync.c:474
gboolean cluster_connect_cpg(crm_cluster_t *cluster)
Definition: cpg.c:433
enum cluster_type_e get_cluster_type(void)
Definition: cluster.c:502