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