corosync  2.3.2
totemconfig.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2002-2005 MontaVista Software, Inc.
3  * Copyright (c) 2006-2013 Red Hat, Inc.
4  *
5  * All rights reserved.
6  *
7  * Author: Steven Dake (sdake@redhat.com)
8  * Jan Friesse (jfriesse@redhat.com)
9  *
10  * This software licensed under BSD license, the text of which follows:
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions are met:
14  *
15  * - Redistributions of source code must retain the above copyright notice,
16  * this list of conditions and the following disclaimer.
17  * - Redistributions in binary form must reproduce the above copyright notice,
18  * this list of conditions and the following disclaimer in the documentation
19  * and/or other materials provided with the distribution.
20  * - Neither the name of the MontaVista Software, Inc. nor the names of its
21  * contributors may be used to endorse or promote products derived from this
22  * software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
34  * THE POSSIBILITY OF SUCH DAMAGE.
35  */
36 
37 #include <config.h>
38 
39 #include <stdio.h>
40 #include <string.h>
41 #include <stdlib.h>
42 #include <errno.h>
43 #include <unistd.h>
44 #include <sys/socket.h>
45 #include <sys/types.h>
46 #include <sys/stat.h>
47 #include <fcntl.h>
48 #include <netinet/in.h>
49 #include <arpa/inet.h>
50 #include <sys/param.h>
51 
52 #include <corosync/swab.h>
53 #include <corosync/list.h>
54 #include <qb/qbdefs.h>
55 #include <corosync/totem/totem.h>
56 #include <corosync/config.h>
57 #include <corosync/logsys.h>
58 #include <corosync/icmap.h>
59 
60 #include "util.h"
61 #include "totemconfig.h"
62 
63 #define TOKEN_RETRANSMITS_BEFORE_LOSS_CONST 4
64 #define TOKEN_TIMEOUT 1000
65 #define JOIN_TIMEOUT 50
66 #define MERGE_TIMEOUT 200
67 #define DOWNCHECK_TIMEOUT 1000
68 #define FAIL_TO_RECV_CONST 2500
69 #define SEQNO_UNCHANGED_CONST 30
70 #define MINIMUM_TIMEOUT (int)(1000/HZ)*3
71 #define MAX_NETWORK_DELAY 50
72 #define WINDOW_SIZE 50
73 #define MAX_MESSAGES 17
74 #define MISS_COUNT_CONST 5
75 #define RRP_PROBLEM_COUNT_TIMEOUT 2000
76 #define RRP_PROBLEM_COUNT_THRESHOLD_DEFAULT 10
77 #define RRP_PROBLEM_COUNT_THRESHOLD_MIN 2
78 #define RRP_AUTORECOVERY_CHECK_TIMEOUT 1000
79 
80 #define DEFAULT_PORT 5405
81 
82 static char error_string_response[512];
83 
84 static void add_totem_config_notification(struct totem_config *totem_config);
85 
86 
87 /* All the volatile parameters are uint32s, luckily */
88 static uint32_t *totem_get_param_by_name(struct totem_config *totem_config, const char *param_name)
89 {
90  if (strcmp(param_name, "totem.token") == 0)
91  return &totem_config->token_timeout;
92  if (strcmp(param_name, "totem.token_retransmit") == 0)
93  return &totem_config->token_retransmit_timeout;
94  if (strcmp(param_name, "totem.hold") == 0)
95  return &totem_config->token_hold_timeout;
96  if (strcmp(param_name, "totem.token_retransmits_before_loss_const") == 0)
97  return &totem_config->token_retransmits_before_loss_const;
98  if (strcmp(param_name, "totem.join") == 0)
99  return &totem_config->join_timeout;
100  if (strcmp(param_name, "totem.send_join") == 0)
101  return &totem_config->send_join_timeout;
102  if (strcmp(param_name, "totem.consensus") == 0)
103  return &totem_config->consensus_timeout;
104  if (strcmp(param_name, "totem.merge") == 0)
105  return &totem_config->merge_timeout;
106  if (strcmp(param_name, "totem.downcheck") == 0)
107  return &totem_config->downcheck_timeout;
108  if (strcmp(param_name, "totem.fail_recv_const") == 0)
109  return &totem_config->fail_to_recv_const;
110  if (strcmp(param_name, "totem.seqno_unchanged_const") == 0)
111  return &totem_config->seqno_unchanged_const;
112  if (strcmp(param_name, "totem.rrp_token_expired_timeout") == 0)
113  return &totem_config->rrp_token_expired_timeout;
114  if (strcmp(param_name, "totem.rrp_problem_count_timeout") == 0)
115  return &totem_config->rrp_problem_count_timeout;
116  if (strcmp(param_name, "totem.rrp_problem_count_threshold") == 0)
117  return &totem_config->rrp_problem_count_threshold;
118  if (strcmp(param_name, "totem.rrp_problem_count_mcast_threshold") == 0)
119  return &totem_config->rrp_problem_count_mcast_threshold;
120  if (strcmp(param_name, "totem.rrp_autorecovery_check_timeout") == 0)
121  return &totem_config->rrp_autorecovery_check_timeout;
122  if (strcmp(param_name, "totem.heartbeat_failures_allowed") == 0)
123  return &totem_config->heartbeat_failures_allowed;
124  if (strcmp(param_name, "totem.max_network_delay") == 0)
125  return &totem_config->max_network_delay;
126  if (strcmp(param_name, "totem.window_size") == 0)
127  return &totem_config->window_size;
128  if (strcmp(param_name, "totem.max_messages") == 0)
129  return &totem_config->max_messages;
130  if (strcmp(param_name, "totem.miss_count_const") == 0)
131  return &totem_config->miss_count_const;
132 
133  return NULL;
134 }
135 
136 
137 static void totem_volatile_config_read (struct totem_config *totem_config)
138 {
139  char *str;
140 
141  icmap_get_uint32("totem.token", &totem_config->token_timeout);
142  icmap_get_uint32("totem.token_retransmit", &totem_config->token_retransmit_timeout);
143  icmap_get_uint32("totem.hold", &totem_config->token_hold_timeout);
144  icmap_get_uint32("totem.token_retransmits_before_loss_const", &totem_config->token_retransmits_before_loss_const);
145  icmap_get_uint32("totem.join", &totem_config->join_timeout);
146  icmap_get_uint32("totem.send_join", &totem_config->send_join_timeout);
147  icmap_get_uint32("totem.consensus", &totem_config->consensus_timeout);
148  icmap_get_uint32("totem.merge", &totem_config->merge_timeout);
149  icmap_get_uint32("totem.downcheck", &totem_config->downcheck_timeout);
150  icmap_get_uint32("totem.fail_recv_const", &totem_config->fail_to_recv_const);
151  icmap_get_uint32("totem.seqno_unchanged_const", &totem_config->seqno_unchanged_const);
152  icmap_get_uint32("totem.rrp_token_expired_timeout", &totem_config->rrp_token_expired_timeout);
153  icmap_get_uint32("totem.rrp_problem_count_timeout", &totem_config->rrp_problem_count_timeout);
154  icmap_get_uint32("totem.rrp_problem_count_threshold", &totem_config->rrp_problem_count_threshold);
155  icmap_get_uint32("totem.rrp_problem_count_mcast_threshold", &totem_config->rrp_problem_count_mcast_threshold);
156  icmap_get_uint32("totem.rrp_autorecovery_check_timeout", &totem_config->rrp_autorecovery_check_timeout);
157  icmap_get_uint32("totem.heartbeat_failures_allowed", &totem_config->heartbeat_failures_allowed);
158  icmap_get_uint32("totem.max_network_delay", &totem_config->max_network_delay);
159  icmap_get_uint32("totem.window_size", &totem_config->window_size);
160  icmap_get_uint32("totem.max_messages", &totem_config->max_messages);
161  icmap_get_uint32("totem.miss_count_const", &totem_config->miss_count_const);
162  if (icmap_get_string("totem.vsftype", &str) == CS_OK) {
163  totem_config->vsf_type = str;
164  }
165 }
166 
167 
168 static int totem_get_crypto(struct totem_config *totem_config)
169 {
170  char *str;
171  const char *tmp_cipher;
172  const char *tmp_hash;
173 
174  tmp_hash = "sha1";
175  tmp_cipher = "aes256";
176 
177  if (icmap_get_string("totem.secauth", &str) == CS_OK) {
178  if (strcmp (str, "off") == 0) {
179  tmp_hash = "none";
180  tmp_cipher = "none";
181  }
182  free(str);
183  }
184 
185  if (icmap_get_string("totem.crypto_cipher", &str) == CS_OK) {
186  if (strcmp(str, "none") == 0) {
187  tmp_cipher = "none";
188  }
189  if (strcmp(str, "aes256") == 0) {
190  tmp_cipher = "aes256";
191  }
192  if (strcmp(str, "aes192") == 0) {
193  tmp_cipher = "aes192";
194  }
195  if (strcmp(str, "aes128") == 0) {
196  tmp_cipher = "aes128";
197  }
198  if (strcmp(str, "3des") == 0) {
199  tmp_cipher = "3des";
200  }
201  free(str);
202  }
203 
204  if (icmap_get_string("totem.crypto_hash", &str) == CS_OK) {
205  if (strcmp(str, "none") == 0) {
206  tmp_hash = "none";
207  }
208  if (strcmp(str, "md5") == 0) {
209  tmp_hash = "md5";
210  }
211  if (strcmp(str, "sha1") == 0) {
212  tmp_hash = "sha1";
213  }
214  if (strcmp(str, "sha256") == 0) {
215  tmp_hash = "sha256";
216  }
217  if (strcmp(str, "sha384") == 0) {
218  tmp_hash = "sha384";
219  }
220  if (strcmp(str, "sha512") == 0) {
221  tmp_hash = "sha512";
222  }
223  free(str);
224  }
225 
226  if ((strcmp(tmp_cipher, "none") != 0) &&
227  (strcmp(tmp_hash, "none") == 0)) {
228  return -1;
229  }
230 
231  free(totem_config->crypto_cipher_type);
232  free(totem_config->crypto_hash_type);
233 
234  totem_config->crypto_cipher_type = strdup(tmp_cipher);
235  totem_config->crypto_hash_type = strdup(tmp_hash);
236 
237  return 0;
238 }
239 
240 static uint16_t generate_cluster_id (const char *cluster_name)
241 {
242  int i;
243  int value = 0;
244 
245  for (i = 0; i < strlen(cluster_name); i++) {
246  value <<= 1;
247  value += cluster_name[i];
248  }
249 
250  return (value & 0xFFFF);
251 }
252 
253 static int get_cluster_mcast_addr (
254  const char *cluster_name,
255  const struct totem_ip_address *bindnet,
256  unsigned int ringnumber,
257  int ip_version,
258  struct totem_ip_address *res)
259 {
260  uint16_t clusterid;
261  char addr[INET6_ADDRSTRLEN + 1];
262  int err;
263 
264  if (cluster_name == NULL) {
265  return (-1);
266  }
267 
268  clusterid = generate_cluster_id(cluster_name) + ringnumber;
269  memset (res, 0, sizeof(*res));
270 
271  switch (bindnet->family) {
272  case AF_INET:
273  snprintf(addr, sizeof(addr), "239.192.%d.%d", clusterid >> 8, clusterid % 0xFF);
274  break;
275  case AF_INET6:
276  snprintf(addr, sizeof(addr), "ff15::%x", clusterid);
277  break;
278  default:
279  /*
280  * Unknown family
281  */
282  return (-1);
283  }
284 
285  err = totemip_parse (res, addr, ip_version);
286 
287  return (err);
288 }
289 
290 static int find_local_node_in_nodelist(struct totem_config *totem_config)
291 {
292  icmap_iter_t iter;
293  const char *iter_key;
294  int res = 0;
295  int node_pos;
296  int local_node_pos = -1;
297  struct totem_ip_address bind_addr;
298  int interface_up, interface_num;
299  char tmp_key[ICMAP_KEYNAME_MAXLEN];
300  char *node_addr_str;
301  struct totem_ip_address node_addr;
302 
303  res = totemip_iface_check(&totem_config->interfaces[0].bindnet,
304  &bind_addr, &interface_up, &interface_num,
305  totem_config->clear_node_high_bit);
306  if (res == -1) {
307  return (-1);
308  }
309 
310  iter = icmap_iter_init("nodelist.node.");
311  while ((iter_key = icmap_iter_next(iter, NULL, NULL)) != NULL) {
312  res = sscanf(iter_key, "nodelist.node.%u.%s", &node_pos, tmp_key);
313  if (res != 2) {
314  continue;
315  }
316 
317  if (strcmp(tmp_key, "ring0_addr") != 0) {
318  continue;
319  }
320 
321  snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.ring0_addr", node_pos);
322  if (icmap_get_string(tmp_key, &node_addr_str) != CS_OK) {
323  continue;
324  }
325 
326  res = totemip_parse (&node_addr, node_addr_str, totem_config->ip_version);
327  free(node_addr_str);
328  if (res == -1) {
329  continue ;
330  }
331 
332  if (totemip_equal(&bind_addr, &node_addr)) {
333  local_node_pos = node_pos;
334  }
335  }
336  icmap_iter_finalize(iter);
337 
338  return (local_node_pos);
339 }
340 
341 static void put_nodelist_members_to_config(struct totem_config *totem_config)
342 {
343  icmap_iter_t iter, iter2;
344  const char *iter_key, *iter_key2;
345  int res = 0;
346  int node_pos;
347  char tmp_key[ICMAP_KEYNAME_MAXLEN];
348  char tmp_key2[ICMAP_KEYNAME_MAXLEN];
349  char *node_addr_str;
350  int member_count;
351  unsigned int ringnumber = 0;
352 
353  iter = icmap_iter_init("nodelist.node.");
354  while ((iter_key = icmap_iter_next(iter, NULL, NULL)) != NULL) {
355  res = sscanf(iter_key, "nodelist.node.%u.%s", &node_pos, tmp_key);
356  if (res != 2) {
357  continue;
358  }
359 
360  if (strcmp(tmp_key, "ring0_addr") != 0) {
361  continue;
362  }
363 
364  snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.", node_pos);
365  iter2 = icmap_iter_init(tmp_key);
366  while ((iter_key2 = icmap_iter_next(iter2, NULL, NULL)) != NULL) {
367  res = sscanf(iter_key2, "nodelist.node.%u.ring%u%s", &node_pos, &ringnumber, tmp_key2);
368  if (res != 3 || strcmp(tmp_key2, "_addr") != 0) {
369  continue;
370  }
371 
372  if (icmap_get_string(iter_key2, &node_addr_str) != CS_OK) {
373  continue;
374  }
375 
376  member_count = totem_config->interfaces[ringnumber].member_count;
377 
378  res = totemip_parse(&totem_config->interfaces[ringnumber].member_list[member_count],
379  node_addr_str, totem_config->ip_version);
380  if (res != -1) {
381  totem_config->interfaces[ringnumber].member_count++;
382  }
383  free(node_addr_str);
384  }
385 
386  icmap_iter_finalize(iter2);
387  }
388 
389  icmap_iter_finalize(iter);
390 }
391 
392 static void config_convert_nodelist_to_interface(struct totem_config *totem_config)
393 {
394  icmap_iter_t iter;
395  const char *iter_key;
396  int res = 0;
397  int node_pos;
398  char tmp_key[ICMAP_KEYNAME_MAXLEN];
399  char tmp_key2[ICMAP_KEYNAME_MAXLEN];
400  char *node_addr_str;
401  unsigned int ringnumber = 0;
402  struct list_head addrs;
403  struct list_head *list;
404  struct totem_ip_if_address *if_addr;
405  struct totem_ip_address node_addr;
406  int node_found = 0;
407 
408  if (totemip_getifaddrs(&addrs) == -1) {
409  return ;
410  }
411 
412  iter = icmap_iter_init("nodelist.node.");
413  while ((iter_key = icmap_iter_next(iter, NULL, NULL)) != NULL) {
414  res = sscanf(iter_key, "nodelist.node.%u.%s", &node_pos, tmp_key);
415  if (res != 2) {
416  continue;
417  }
418 
419  if (strcmp(tmp_key, "ring0_addr") != 0) {
420  continue;
421  }
422 
423  if (icmap_get_string(iter_key, &node_addr_str) != CS_OK) {
424  continue ;
425  }
426 
427  if (totemip_parse(&node_addr, node_addr_str, totem_config->ip_version) == -1) {
428  free(node_addr_str);
429  continue ;
430  }
431  free(node_addr_str);
432 
433  /*
434  * Try to find node in if_addrs
435  */
436  node_found = 0;
437  for (list = addrs.next; list != &addrs; list = list->next) {
438  if_addr = list_entry(list, struct totem_ip_if_address, list);
439 
440  if (totemip_equal(&node_addr, &if_addr->ip_addr)) {
441  node_found = 1;
442  break;
443  }
444  }
445 
446  if (node_found) {
447  break ;
448  }
449  }
450 
451  icmap_iter_finalize(iter);
452 
453  if (node_found) {
454  /*
455  * We found node, so create interface section
456  */
457  snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.", node_pos);
458  iter = icmap_iter_init(tmp_key);
459  while ((iter_key = icmap_iter_next(iter, NULL, NULL)) != NULL) {
460  res = sscanf(iter_key, "nodelist.node.%u.ring%u%s", &node_pos, &ringnumber, tmp_key2);
461  if (res != 3 || strcmp(tmp_key2, "_addr") != 0) {
462  continue ;
463  }
464 
465  if (icmap_get_string(iter_key, &node_addr_str) != CS_OK) {
466  continue;
467  }
468 
469  snprintf(tmp_key2, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.bindnetaddr", ringnumber);
470  icmap_set_string(tmp_key2, node_addr_str);
471  free(node_addr_str);
472  }
473  icmap_iter_finalize(iter);
474  }
475 }
476 
477 
478 extern int totem_config_read (
479  struct totem_config *totem_config,
480  const char **error_string,
481  uint64_t *warnings)
482 {
483  int res = 0;
484  char *str;
485  unsigned int ringnumber = 0;
486  int member_count = 0;
487  icmap_iter_t iter, member_iter;
488  const char *iter_key;
489  const char *member_iter_key;
490  char ringnumber_key[ICMAP_KEYNAME_MAXLEN];
491  char tmp_key[ICMAP_KEYNAME_MAXLEN];
492  uint8_t u8;
493  uint16_t u16;
494  char *cluster_name = NULL;
495  int i;
496  int local_node_pos;
497  int nodeid_set;
498 
499  *warnings = 0;
500 
501  memset (totem_config, 0, sizeof (struct totem_config));
502  totem_config->interfaces = malloc (sizeof (struct totem_interface) * INTERFACE_MAX);
503  if (totem_config->interfaces == 0) {
504  *error_string = "Out of memory trying to allocate ethernet interface storage area";
505  return -1;
506  }
507 
508  memset (totem_config->interfaces, 0,
509  sizeof (struct totem_interface) * INTERFACE_MAX);
510 
511  strcpy (totem_config->rrp_mode, "none");
512 
513  icmap_get_uint32("totem.version", (uint32_t *)&totem_config->version);
514 
515  if (totem_get_crypto(totem_config) != 0) {
516  *error_string = "crypto_cipher requires crypto_hash with value other than none";
517  return -1;
518  }
519 
520  if (icmap_get_string("totem.rrp_mode", &str) == CS_OK) {
521  if (strlen(str) >= TOTEM_RRP_MODE_BYTES) {
522  *error_string = "totem.rrp_mode is too long";
523  free(str);
524 
525  return -1;
526  }
527  strcpy (totem_config->rrp_mode, str);
528  free(str);
529  }
530 
531  icmap_get_uint32("totem.nodeid", &totem_config->node_id);
532 
533  totem_config->clear_node_high_bit = 0;
534  if (icmap_get_string("totem.clear_node_high_bit", &str) == CS_OK) {
535  if (strcmp (str, "yes") == 0) {
536  totem_config->clear_node_high_bit = 1;
537  }
538  free(str);
539  }
540 
541  icmap_get_uint32("totem.threads", &totem_config->threads);
542 
543  icmap_get_uint32("totem.netmtu", &totem_config->net_mtu);
544 
545  if (icmap_get_string("totem.cluster_name", &cluster_name) != CS_OK) {
546  cluster_name = NULL;
547  }
548 
549  totem_config->ip_version = AF_INET;
550  if (icmap_get_string("totem.ip_version", &str) == CS_OK) {
551  if (strcmp(str, "ipv4") == 0) {
552  totem_config->ip_version = AF_INET;
553  }
554  if (strcmp(str, "ipv6") == 0) {
555  totem_config->ip_version = AF_INET6;
556  }
557  free(str);
558  }
559 
560  /*
561  * Get things that might change in the future
562  */
563  totem_volatile_config_read(totem_config);
564 
565  if (icmap_get_string("totem.interface.0.bindnetaddr", &str) != CS_OK) {
566  /*
567  * We were not able to find ring 0 bindnet addr. Try to use nodelist informations
568  */
569  config_convert_nodelist_to_interface(totem_config);
570  } else {
571  free(str);
572  }
573 
574  iter = icmap_iter_init("totem.interface.");
575  while ((iter_key = icmap_iter_next(iter, NULL, NULL)) != NULL) {
576  res = sscanf(iter_key, "totem.interface.%[^.].%s", ringnumber_key, tmp_key);
577  if (res != 2) {
578  continue;
579  }
580 
581  if (strcmp(tmp_key, "bindnetaddr") != 0) {
582  continue;
583  }
584 
585  member_count = 0;
586 
587  ringnumber = atoi(ringnumber_key);
588 
589  if (ringnumber >= INTERFACE_MAX) {
590  free(cluster_name);
591 
592  snprintf (error_string_response, sizeof(error_string_response),
593  "parse error in config: interface ring number %u is bigger then allowed maximum %u\n",
594  ringnumber, INTERFACE_MAX - 1);
595 
596  *error_string = error_string_response;
597  return -1;
598  }
599 
600  /*
601  * Get the bind net address
602  */
603  if (icmap_get_string(iter_key, &str) == CS_OK) {
604  res = totemip_parse (&totem_config->interfaces[ringnumber].bindnet, str,
605  totem_config->interfaces[ringnumber].mcast_addr.family);
606  free(str);
607  }
608 
609  /*
610  * Get interface multicast address
611  */
612  snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.mcastaddr", ringnumber);
613  if (icmap_get_string(tmp_key, &str) == CS_OK) {
614  res = totemip_parse (&totem_config->interfaces[ringnumber].mcast_addr, str, totem_config->ip_version);
615  free(str);
616  } else {
617  /*
618  * User not specified address -> autogenerate one from cluster_name key
619  * (if available)
620  */
621  res = get_cluster_mcast_addr (cluster_name,
622  &totem_config->interfaces[ringnumber].bindnet,
623  ringnumber,
624  totem_config->ip_version,
625  &totem_config->interfaces[ringnumber].mcast_addr);
626  }
627 
628  totem_config->broadcast_use = 0;
629  snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.broadcast", ringnumber);
630  if (icmap_get_string(tmp_key, &str) == CS_OK) {
631  if (strcmp (str, "yes") == 0) {
632  totem_config->broadcast_use = 1;
633  totemip_parse (
634  &totem_config->interfaces[ringnumber].mcast_addr,
635  "255.255.255.255", totem_config->ip_version);
636  }
637  free(str);
638  }
639 
640  /*
641  * Get mcast port
642  */
643  snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.mcastport", ringnumber);
644  if (icmap_get_uint16(tmp_key, &totem_config->interfaces[ringnumber].ip_port) != CS_OK) {
645  if (totem_config->broadcast_use) {
646  totem_config->interfaces[ringnumber].ip_port = DEFAULT_PORT + (2 * ringnumber);
647  } else {
648  totem_config->interfaces[ringnumber].ip_port = DEFAULT_PORT;
649  }
650  }
651 
652  /*
653  * Get the TTL
654  */
655  totem_config->interfaces[ringnumber].ttl = 1;
656 
657  snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.ttl", ringnumber);
658 
659  if (icmap_get_uint8(tmp_key, &u8) == CS_OK) {
660  totem_config->interfaces[ringnumber].ttl = u8;
661  }
662 
663  snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.member.", ringnumber);
664  member_iter = icmap_iter_init(tmp_key);
665  while ((member_iter_key = icmap_iter_next(member_iter, NULL, NULL)) != NULL) {
666  if (member_count == 0) {
667  if (icmap_get_string("nodelist.node.0.ring0_addr", &str) == CS_OK) {
668  free(str);
670  break;
671  } else {
673  }
674  }
675 
676  if (icmap_get_string(member_iter_key, &str) == CS_OK) {
677  res = totemip_parse (&totem_config->interfaces[ringnumber].member_list[member_count++],
678  str, totem_config->ip_version);
679  }
680  }
681  icmap_iter_finalize(member_iter);
682 
683  totem_config->interfaces[ringnumber].member_count = member_count;
684  totem_config->interface_count++;
685  }
686  icmap_iter_finalize(iter);
687 
688  /*
689  * Store automatically generated items back to icmap
690  */
691  for (i = 0; i < totem_config->interface_count; i++) {
692  snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.mcastaddr", i);
693  if (icmap_get_string(tmp_key, &str) == CS_OK) {
694  free(str);
695  } else {
696  str = (char *)totemip_print(&totem_config->interfaces[i].mcast_addr);
697  icmap_set_string(tmp_key, str);
698  }
699 
700  snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.mcastport", i);
701  if (icmap_get_uint16(tmp_key, &u16) != CS_OK) {
702  icmap_set_uint16(tmp_key, totem_config->interfaces[i].ip_port);
703  }
704  }
705 
706  totem_config->transport_number = TOTEM_TRANSPORT_UDP;
707  if (icmap_get_string("totem.transport", &str) == CS_OK) {
708  if (strcmp (str, "udpu") == 0) {
709  totem_config->transport_number = TOTEM_TRANSPORT_UDPU;
710  }
711 
712  if (strcmp (str, "iba") == 0) {
713  totem_config->transport_number = TOTEM_TRANSPORT_RDMA;
714  }
715  free(str);
716  }
717 
718  free(cluster_name);
719 
720  /*
721  * Check existence of nodelist
722  */
723  if (icmap_get_string("nodelist.node.0.ring0_addr", &str) == CS_OK) {
724  free(str);
725  /*
726  * find local node
727  */
728  local_node_pos = find_local_node_in_nodelist(totem_config);
729  if (local_node_pos != -1) {
730  icmap_set_uint32("nodelist.local_node_pos", local_node_pos);
731 
732  snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.nodeid", local_node_pos);
733 
734  nodeid_set = (totem_config->node_id != 0);
735  if (icmap_get_uint32(tmp_key, &totem_config->node_id) == CS_OK && nodeid_set) {
737  }
738 
739  /*
740  * Make localnode ring0_addr read only, so we can be sure that local
741  * node never changes. If rebinding to other IP would be in future
742  * supported, this must be changed and handled properly!
743  */
744  snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.ring0_addr", local_node_pos);
745  icmap_set_ro_access(tmp_key, 0, 1);
746  icmap_set_ro_access("nodelist.local_node_pos", 0, 1);
747  }
748 
749  put_nodelist_members_to_config(totem_config);
750  }
751 
752  add_totem_config_notification(totem_config);
753 
754  return 0;
755 }
756 
757 static int totem_set_volatile_defaults (
758  struct totem_config *totem_config,
759  const char **error_string)
760 {
761  static char local_error_reason[512];
762  const char *error_reason = local_error_reason;
763 
764  if (totem_config->token_retransmits_before_loss_const == 0) {
767  }
768 
769  /*
770  * Setup timeout values that are not setup by user
771  */
772  if (totem_config->token_timeout == 0) {
773  totem_config->token_timeout = TOKEN_TIMEOUT;
774  }
775 
776  if (totem_config->max_network_delay == 0) {
777  totem_config->max_network_delay = MAX_NETWORK_DELAY;
778  }
779 
780  if (totem_config->max_network_delay < MINIMUM_TIMEOUT) {
781  snprintf (local_error_reason, sizeof(local_error_reason),
782  "The max_network_delay parameter (%d ms) may not be less then (%d ms).",
783  totem_config->max_network_delay, MINIMUM_TIMEOUT);
784  goto parse_error;
785  }
786 
787  if (totem_config->window_size == 0) {
788  totem_config->window_size = WINDOW_SIZE;
789  }
790 
791  if (totem_config->max_messages == 0) {
792  totem_config->max_messages = MAX_MESSAGES;
793  }
794 
795  if (totem_config->miss_count_const == 0) {
796  totem_config->miss_count_const = MISS_COUNT_CONST;
797  }
798 
799  if (totem_config->token_timeout < MINIMUM_TIMEOUT) {
800  snprintf (local_error_reason, sizeof(local_error_reason),
801  "The token timeout parameter (%d ms) may not be less then (%d ms).",
802  totem_config->token_timeout, MINIMUM_TIMEOUT);
803  goto parse_error;
804  }
805 
806  if (totem_config->token_retransmit_timeout == 0) {
807  totem_config->token_retransmit_timeout =
808  (int)(totem_config->token_timeout /
809  (totem_config->token_retransmits_before_loss_const + 0.2));
810  }
811  if (totem_config->token_hold_timeout == 0) {
812  totem_config->token_hold_timeout =
813  (int)(totem_config->token_retransmit_timeout * 0.8 -
814  (1000/HZ));
815  }
816  if (totem_config->token_retransmit_timeout < MINIMUM_TIMEOUT) {
817  snprintf (local_error_reason, sizeof(local_error_reason),
818  "The token retransmit timeout parameter (%d ms) may not be less then (%d ms).",
820  goto parse_error;
821  }
822 
823  if (totem_config->token_hold_timeout < MINIMUM_TIMEOUT) {
824  snprintf (local_error_reason, sizeof(local_error_reason),
825  "The token hold timeout parameter (%d ms) may not be less then (%d ms).",
826  totem_config->token_hold_timeout, MINIMUM_TIMEOUT);
827  goto parse_error;
828  }
829 
830  if (totem_config->join_timeout == 0) {
831  totem_config->join_timeout = JOIN_TIMEOUT;
832  }
833 
834  if (totem_config->join_timeout < MINIMUM_TIMEOUT) {
835  snprintf (local_error_reason, sizeof(local_error_reason),
836  "The join timeout parameter (%d ms) may not be less then (%d ms).",
837  totem_config->join_timeout, MINIMUM_TIMEOUT);
838  goto parse_error;
839  }
840 
841  if (totem_config->consensus_timeout == 0) {
842  totem_config->consensus_timeout = (int)(float)(1.2 * totem_config->token_timeout);
843  }
844 
845  if (totem_config->consensus_timeout < MINIMUM_TIMEOUT) {
846  snprintf (local_error_reason, sizeof(local_error_reason),
847  "The consensus timeout parameter (%d ms) may not be less then (%d ms).",
848  totem_config->consensus_timeout, MINIMUM_TIMEOUT);
849  goto parse_error;
850  }
851 
852  if (totem_config->merge_timeout == 0) {
853  totem_config->merge_timeout = MERGE_TIMEOUT;
854  }
855 
856  if (totem_config->merge_timeout < MINIMUM_TIMEOUT) {
857  snprintf (local_error_reason, sizeof(local_error_reason),
858  "The merge timeout parameter (%d ms) may not be less then (%d ms).",
859  totem_config->merge_timeout, MINIMUM_TIMEOUT);
860  goto parse_error;
861  }
862 
863  if (totem_config->downcheck_timeout == 0) {
864  totem_config->downcheck_timeout = DOWNCHECK_TIMEOUT;
865  }
866 
867  if (totem_config->downcheck_timeout < MINIMUM_TIMEOUT) {
868  snprintf (local_error_reason, sizeof(local_error_reason),
869  "The downcheck timeout parameter (%d ms) may not be less then (%d ms).",
870  totem_config->downcheck_timeout, MINIMUM_TIMEOUT);
871  goto parse_error;
872  }
873 
874  if (totem_config->fail_to_recv_const == 0) {
875  totem_config->fail_to_recv_const = FAIL_TO_RECV_CONST;
876  }
877  if (totem_config->seqno_unchanged_const == 0) {
879  }
880 
881 /* RRP volatile values */
882 
883  if (totem_config->rrp_problem_count_timeout == 0) {
885  }
886  if (totem_config->rrp_problem_count_timeout < MINIMUM_TIMEOUT) {
887  snprintf (local_error_reason, sizeof(local_error_reason),
888  "The RRP problem count timeout parameter (%d ms) may not be less then (%d ms).",
890  goto parse_error;
891  }
892  if (totem_config->rrp_problem_count_threshold == 0) {
894  }
895  if (totem_config->rrp_problem_count_mcast_threshold == 0) {
896  totem_config->rrp_problem_count_mcast_threshold = totem_config->rrp_problem_count_threshold * 10;
897  }
899  snprintf (local_error_reason, sizeof(local_error_reason),
900  "The RRP problem count threshold (%d problem count) may not be less then (%d problem count).",
902  goto parse_error;
903  }
905  snprintf (local_error_reason, sizeof(local_error_reason),
906  "The RRP multicast problem count threshold (%d problem count) may not be less then (%d problem count).",
908  goto parse_error;
909  }
910  if (totem_config->rrp_token_expired_timeout == 0) {
911  totem_config->rrp_token_expired_timeout =
912  totem_config->token_retransmit_timeout;
913  }
914 
915  if (totem_config->rrp_token_expired_timeout < MINIMUM_TIMEOUT) {
916  snprintf (local_error_reason, sizeof(local_error_reason),
917  "The RRP token expired timeout parameter (%d ms) may not be less then (%d ms).",
919  goto parse_error;
920  }
921 
922  if (totem_config->rrp_autorecovery_check_timeout == 0) {
924  }
925 
926  return 0;
927 
928 parse_error:
929  snprintf (error_string_response, sizeof(error_string_response),
930  "parse error in config: %s\n", error_reason);
931  *error_string = error_string_response;
932  return (-1);
933 
934 }
935 
937  struct totem_config *totem_config,
938  const char **error_string)
939 {
940  static char local_error_reason[512];
941  char parse_error[512];
942  const char *error_reason = local_error_reason;
943  int i;
944  unsigned int interface_max = INTERFACE_MAX;
945 
946  if (totem_config->interface_count == 0) {
947  error_reason = "No interfaces defined";
948  goto parse_error;
949  }
950 
951  for (i = 0; i < totem_config->interface_count; i++) {
952  /*
953  * Some error checking of parsed data to make sure its valid
954  */
955 
956  struct totem_ip_address null_addr;
957  memset (&null_addr, 0, sizeof (struct totem_ip_address));
958 
959  if ((totem_config->transport_number == 0) &&
960  memcmp (&totem_config->interfaces[i].mcast_addr, &null_addr,
961  sizeof (struct totem_ip_address)) == 0) {
962  error_reason = "No multicast address specified";
963  goto parse_error;
964  }
965 
966  if (totem_config->interfaces[i].ip_port == 0) {
967  error_reason = "No multicast port specified";
968  goto parse_error;
969  }
970 
971  if (totem_config->interfaces[i].ttl > 255) {
972  error_reason = "Invalid TTL (should be 0..255)";
973  goto parse_error;
974  }
975  if (totem_config->transport_number != TOTEM_TRANSPORT_UDP &&
976  totem_config->interfaces[i].ttl != 1) {
977  error_reason = "Can only set ttl on multicast transport types";
978  goto parse_error;
979  }
980 
981  if (totem_config->interfaces[i].mcast_addr.family == AF_INET6 &&
982  totem_config->node_id == 0) {
983 
984  error_reason = "An IPV6 network requires that a node ID be specified.";
985  goto parse_error;
986  }
987 
988  if (totem_config->broadcast_use == 0 && totem_config->transport_number == 0) {
989  if (totem_config->interfaces[i].mcast_addr.family != totem_config->interfaces[i].bindnet.family) {
990  error_reason = "Multicast address family does not match bind address family";
991  goto parse_error;
992  }
993 
994  if (totem_config->interfaces[i].mcast_addr.family != totem_config->interfaces[i].bindnet.family) {
995  error_reason = "Not all bind address belong to the same IP family";
996  goto parse_error;
997  }
998  if (totemip_is_mcast (&totem_config->interfaces[i].mcast_addr) != 0) {
999  error_reason = "mcastaddr is not a correct multicast address.";
1000  goto parse_error;
1001  }
1002  }
1003  }
1004 
1005  if (totem_config->version != 2) {
1006  error_reason = "This totem parser can only parse version 2 configurations.";
1007  goto parse_error;
1008  }
1009 
1010  totem_set_volatile_defaults(totem_config, error_string);
1011 
1012  /*
1013  * RRP values validation
1014  */
1015  if (strcmp (totem_config->rrp_mode, "none") &&
1016  strcmp (totem_config->rrp_mode, "active") &&
1017  strcmp (totem_config->rrp_mode, "passive")) {
1018  snprintf (local_error_reason, sizeof(local_error_reason),
1019  "The RRP mode \"%s\" specified is invalid. It must be none, active, or passive.\n", totem_config->rrp_mode);
1020  goto parse_error;
1021  }
1022 
1023  if (strcmp (totem_config->rrp_mode, "none") == 0) {
1024  interface_max = 1;
1025  }
1026  if (interface_max < totem_config->interface_count) {
1027  snprintf (parse_error, sizeof(parse_error),
1028  "%d is too many configured interfaces for the rrp_mode setting %s.",
1029  totem_config->interface_count,
1030  totem_config->rrp_mode);
1031  error_reason = parse_error;
1032  goto parse_error;
1033  }
1034 
1035  if (totem_config->net_mtu == 0) {
1036  totem_config->net_mtu = 1500;
1037  }
1038 
1039  return 0;
1040 
1041 parse_error:
1042  snprintf (error_string_response, sizeof(error_string_response),
1043  "parse error in config: %s\n", error_reason);
1044  *error_string = error_string_response;
1045  return (-1);
1046 
1047 }
1048 
1049 static int read_keyfile (
1050  const char *key_location,
1051  struct totem_config *totem_config,
1052  const char **error_string)
1053 {
1054  int fd;
1055  int res;
1056  ssize_t expected_key_len = sizeof (totem_config->private_key);
1057  int saved_errno;
1058  char error_str[100];
1059  const char *error_ptr;
1060 
1061  fd = open (key_location, O_RDONLY);
1062  if (fd == -1) {
1063  error_ptr = qb_strerror_r(errno, error_str, sizeof(error_str));
1064  snprintf (error_string_response, sizeof(error_string_response),
1065  "Could not open %s: %s\n",
1066  key_location, error_ptr);
1067  goto parse_error;
1068  }
1069 
1070  res = read (fd, totem_config->private_key, expected_key_len);
1071  saved_errno = errno;
1072  close (fd);
1073 
1074  if (res == -1) {
1075  error_ptr = qb_strerror_r (saved_errno, error_str, sizeof(error_str));
1076  snprintf (error_string_response, sizeof(error_string_response),
1077  "Could not read %s: %s\n",
1078  key_location, error_ptr);
1079  goto parse_error;
1080  }
1081 
1082  totem_config->private_key_len = expected_key_len;
1083 
1084  if (res != expected_key_len) {
1085  snprintf (error_string_response, sizeof(error_string_response),
1086  "Could only read %d bits of 1024 bits from %s.\n",
1087  res * 8, key_location);
1088  goto parse_error;
1089  }
1090 
1091  return 0;
1092 
1093 parse_error:
1094  *error_string = error_string_response;
1095  return (-1);
1096 }
1097 
1099  struct totem_config *totem_config,
1100  const char **error_string)
1101 {
1102  int got_key = 0;
1103  char *key_location = NULL;
1104  int res;
1105  size_t key_len;
1106 
1107  memset (totem_config->private_key, 0, 128);
1108  totem_config->private_key_len = 128;
1109 
1110  if (strcmp(totem_config->crypto_cipher_type, "none") == 0 &&
1111  strcmp(totem_config->crypto_hash_type, "none") == 0) {
1112  return (0);
1113  }
1114 
1115  /* cmap may store the location of the key file */
1116  if (icmap_get_string("totem.keyfile", &key_location) == CS_OK) {
1117  res = read_keyfile(key_location, totem_config, error_string);
1118  free(key_location);
1119  if (res) {
1120  goto key_error;
1121  }
1122  got_key = 1;
1123  } else { /* Or the key itself may be in the cmap */
1124  if (icmap_get("totem.key", NULL, &key_len, NULL) == CS_OK) {
1125  if (key_len > sizeof (totem_config->private_key)) {
1126  sprintf(error_string_response, "key is too long");
1127  goto key_error;
1128  }
1129  if (icmap_get("totem.key", totem_config->private_key, &key_len, NULL) == CS_OK) {
1130  totem_config->private_key_len = key_len;
1131  got_key = 1;
1132  } else {
1133  sprintf(error_string_response, "can't store private key");
1134  goto key_error;
1135  }
1136  }
1137  }
1138 
1139  /* In desperation we read the default filename */
1140  if (!got_key) {
1141  const char *filename = getenv("COROSYNC_TOTEM_AUTHKEY_FILE");
1142  if (!filename)
1143  filename = COROSYSCONFDIR "/authkey";
1144  res = read_keyfile(filename, totem_config, error_string);
1145  if (res)
1146  goto key_error;
1147 
1148  }
1149 
1150  return (0);
1151 
1152 key_error:
1153  *error_string = error_string_response;
1154  return (-1);
1155 
1156 }
1157 
1158 static void totem_change_notify(
1159  int32_t event,
1160  const char *key_name,
1161  struct icmap_notify_value new_val,
1162  struct icmap_notify_value old_val,
1163  void *user_data)
1164 {
1165  uint32_t *param;
1166  const char *error_string;
1167  uint8_t reloading;
1168 
1169  /*
1170  * If a full reload is in progress then don't do anything until it's done and
1171  * can reconfigure it all atomically
1172  */
1173  if (icmap_get_uint8("config.reload_in_progress", &reloading) == CS_OK && reloading)
1174  return;
1175 
1176  param = totem_get_param_by_name((struct totem_config *)user_data, key_name);
1177  if (!param)
1178  return;
1179 
1180  switch (event)
1181  {
1182  case ICMAP_TRACK_DELETE:
1183  if (new_val.type == ICMAP_VALUETYPE_UINT32)
1184  *param = 0;
1185  totem_set_volatile_defaults((struct totem_config *)user_data, &error_string);
1186  break;
1187  case ICMAP_TRACK_ADD:
1188  case ICMAP_TRACK_MODIFY:
1189  if (new_val.type == ICMAP_VALUETYPE_UINT32)
1190  memcpy(param, new_val.data, new_val.len);
1191  /* Other value types not supported, or needed (yet) */
1192  break;
1193  default:
1194  break;
1195  }
1196 }
1197 
1198 static void totem_reload_notify(
1199  int32_t event,
1200  const char *key_name,
1201  struct icmap_notify_value new_val,
1202  struct icmap_notify_value old_val,
1203  void *user_data)
1204 {
1205  struct totem_config *totem_config = (struct totem_config *)user_data;
1206  uint32_t local_node_pos;
1207 
1208  /* Reload has completed */
1209  if (*(uint8_t *)new_val.data == 0) {
1210  int i, j;
1211 
1212  /* Clear out udpu nodelist so we can put the new one in if neede */
1213  for (i=0; i<totem_config->interface_count; i++) {
1214  for (j=0; j<PROCESSOR_COUNT_MAX; j++) {
1215  memset(&totem_config->interfaces[i].member_list[j], 0, sizeof(struct totem_ip_address));
1216  }
1217  }
1218 
1219  put_nodelist_members_to_config (totem_config);
1220  totem_volatile_config_read (totem_config);
1221 
1222  /* Reinstate the local_node_pos */
1223  local_node_pos = find_local_node_in_nodelist(totem_config);
1224  if (local_node_pos != -1) {
1225  icmap_set_uint32("nodelist.local_node_pos", local_node_pos);
1226  }
1227  }
1228 }
1229 
1230 static void add_totem_config_notification(struct totem_config *totem_config)
1231 {
1233 
1234  icmap_track_add("totem.",
1236  totem_change_notify,
1237  totem_config,
1238  &icmap_track);
1239 
1240  icmap_track_add("config.reload_in_progress",
1242  totem_reload_notify,
1243  totem_config,
1244  &icmap_track);
1245 }
unsigned int clear_node_high_bit
Definition: totem.h:111
unsigned short family
Definition: coroapi.h:97
size_t len
Definition: icmap.h:92
const char * icmap_iter_next(icmap_iter_t iter, size_t *value_len, icmap_value_types_t *type)
Definition: icmap.c:1103
const char * vsf_type
Definition: totem.h:171
#define RRP_PROBLEM_COUNT_TIMEOUT
Definition: totemconfig.c:75
uint32_t value
struct totem_interface * interfaces
Definition: totem.h:108
unsigned int interface_count
Definition: totem.h:109
struct list_head * next
Definition: list.h:47
#define DEFAULT_PORT
Definition: totemconfig.c:80
const char * totemip_print(const struct totem_ip_address *addr)
Definition: totemip.c:214
void icmap_iter_finalize(icmap_iter_t iter)
Definition: icmap.c:1124
totem_transport_t transport_number
Definition: totem.h:179
int totemip_parse(struct totem_ip_address *totemip, const char *addr, int family)
Definition: totemip.c:263
#define DOWNCHECK_TIMEOUT
Definition: totemconfig.c:67
unsigned int token_hold_timeout
Definition: totem.h:127
int member_count
Definition: totem.h:70
struct totem_ip_address member_list[PROCESSOR_COUNT_MAX]
Definition: totem.h:71
unsigned char private_key[TOTEM_PRIVATE_KEY_LEN]
Definition: totem.h:116
char rrp_mode[TOTEM_RRP_MODE_BYTES]
Definition: totem.h:155
unsigned char addr[TOTEMIP_ADDRLEN]
Definition: coroapi.h:67
#define COROSYSCONFDIR
Definition: config.h:11
unsigned int rrp_problem_count_timeout
Definition: totem.h:147
cs_error_t icmap_set_string(const char *key_name, const char *value)
Definition: icmap.c:641
int totemip_is_mcast(struct totem_ip_address *addr)
Definition: totemip.c:114
#define RRP_AUTORECOVERY_CHECK_TIMEOUT
Definition: totemconfig.c:78
unsigned int downcheck_timeout
Definition: totem.h:139
unsigned int private_key_len
Definition: totem.h:118
Definition: list.h:46
#define SEQNO_UNCHANGED_CONST
Definition: totemconfig.c:69
unsigned int max_network_delay
Definition: totem.h:165
unsigned int heartbeat_failures_allowed
Definition: totem.h:163
unsigned int send_join_timeout
Definition: totem.h:133
unsigned int window_size
Definition: totem.h:167
unsigned int rrp_problem_count_threshold
Definition: totem.h:149
#define ICMAP_TRACK_DELETE
Definition: icmap.h:77
#define INTERFACE_MAX
Definition: coroapi.h:75
#define RRP_PROBLEM_COUNT_THRESHOLD_MIN
Definition: totemconfig.c:77
#define ICMAP_KEYNAME_MAXLEN
Definition: icmap.h:48
#define MINIMUM_TIMEOUT
Definition: totemconfig.c:70
cs_error_t icmap_get_uint8(const char *key_name, uint8_t *u8)
Definition: icmap.c:842
uint16_t ttl
Definition: totem.h:69
unsigned int node_id
Definition: totem.h:110
int totem_config_keyread(struct totem_config *totem_config, const char **error_string)
Definition: totemconfig.c:1098
#define ICMAP_TRACK_MODIFY
Definition: icmap.h:78
unsigned int token_retransmits_before_loss_const
Definition: totem.h:129
int totemip_iface_check(struct totem_ip_address *bindnet, struct totem_ip_address *boundto, int *interface_up, int *interface_num, int mask_high_bit)
Definition: totemip.c:405
#define FAIL_TO_RECV_CONST
Definition: totemconfig.c:68
cs_error_t icmap_set_uint32(const char *key_name, uint32_t value)
Definition: icmap.c:611
unsigned int seqno_unchanged_const
Definition: totem.h:143
void * user_data
Definition: sam.c:126
unsigned int miss_count_const
Definition: totem.h:181
unsigned int join_timeout
Definition: totem.h:131
int totem_config_validate(struct totem_config *totem_config, const char **error_string)
Definition: totemconfig.c:936
const void * data
Definition: icmap.h:93
#define ICMAP_TRACK_ADD
Definition: icmap.h:76
icmap_value_types_t type
Definition: icmap.h:91
char * crypto_hash_type
Definition: totem.h:177
struct totem_ip_address mcast_addr
Definition: totem.h:67
Linked list API.
unsigned int rrp_autorecovery_check_timeout
Definition: totem.h:153
cs_error_t icmap_get(const char *key_name, void *value, size_t *value_len, icmap_value_types_t *type)
Definition: icmap.c:739
cs_error_t icmap_set_uint16(const char *key_name, uint16_t value)
Definition: icmap.c:599
unsigned int fail_to_recv_const
Definition: totem.h:141
#define TOTEM_CONFIG_WARNING_MEMBERS_DEPRECATED
Definition: totemconfig.h:47
cs_error_t icmap_get_uint32(const char *key_name, uint32_t *u32)
Definition: icmap.c:866
uint8_t param
#define TOTEM_CONFIG_WARNING_MEMBERS_IGNORED
Definition: totemconfig.h:46
uint16_t ip_port
Definition: totem.h:68
#define WINDOW_SIZE
Definition: totemconfig.c:72
int version
Definition: totem.h:103
unsigned int net_mtu
Definition: totem.h:159
#define MAX_NETWORK_DELAY
Definition: totemconfig.c:71
#define TOKEN_TIMEOUT
Definition: totemconfig.c:64
int ip_version
Definition: totem.h:183
#define MERGE_TIMEOUT
Definition: totemconfig.c:66
unsigned int token_timeout
Definition: totem.h:123
#define JOIN_TIMEOUT
Definition: totemconfig.c:65
unsigned int consensus_timeout
Definition: totem.h:135
int totemip_getifaddrs(struct list_head *addrs)
Definition: totemip.c:321
#define PROCESSOR_COUNT_MAX
Definition: coroapi.h:83
#define TOKEN_RETRANSMITS_BEFORE_LOSS_CONST
Definition: totemconfig.c:63
#define MISS_COUNT_CONST
Definition: totemconfig.c:74
unsigned int broadcast_use
Definition: totem.h:173
unsigned int rrp_problem_count_mcast_threshold
Definition: totem.h:151
cs_error_t icmap_get_string(const char *key_name, char **str)
Definition: icmap.c:896
#define list_entry(ptr, type, member)
Definition: list.h:84
unsigned int max_messages
Definition: totem.h:169
char * crypto_cipher_type
Definition: totem.h:175
cs_error_t icmap_set_ro_access(const char *key_name, int prefix, int ro_access)
Definition: icmap.c:1233
unsigned int merge_timeout
Definition: totem.h:137
unsigned int token_retransmit_timeout
Definition: totem.h:125
struct totem_ip_address bindnet
Definition: totem.h:65
icmap_iter_t icmap_iter_init(const char *prefix)
Definition: icmap.c:1097
int totemip_equal(const struct totem_ip_address *addr1, const struct totem_ip_address *addr2)
Definition: totemip.c:71
struct totem_ip_address ip_addr
Definition: totemip.h:72
cs_error_t icmap_get_uint16(const char *key_name, uint16_t *u16)
Definition: icmap.c:854
#define TOTEM_CONFIG_WARNING_TOTEM_NODEID_IGNORED
Definition: totemconfig.h:48
#define MAX_MESSAGES
Definition: totemconfig.c:73
unsigned int rrp_token_expired_timeout
Definition: totem.h:145
unsigned int threads
Definition: totem.h:161
qb_map_iter_t * icmap_iter_t
Definition: icmap.h:121
cs_error_t icmap_track_add(const char *key_name, int32_t track_type, icmap_notify_fn_t notify_fn, void *user_data, icmap_track_t *icmap_track)
Definition: icmap.c:1167
int totem_config_read(struct totem_config *totem_config, const char **error_string, uint64_t *warnings)
Definition: totemconfig.c:478
#define ICMAP_TRACK_PREFIX
Definition: icmap.h:84
#define RRP_PROBLEM_COUNT_THRESHOLD_DEFAULT
Definition: totemconfig.c:76