44 #include <sys/socket.h>
45 #include <sys/types.h>
50 #include <netinet/in.h>
51 #include <arpa/inet.h>
52 #include <sys/param.h>
53 #include <sys/utsname.h>
56 #include <qb/qblist.h>
57 #include <qb/qbdefs.h>
67 #define TOKEN_RETRANSMITS_BEFORE_LOSS_CONST 4
68 #define TOKEN_TIMEOUT 1000
69 #define TOKEN_WARNING 75
70 #define TOKEN_COEFFICIENT 650
71 #define JOIN_TIMEOUT 50
72 #define MERGE_TIMEOUT 200
73 #define DOWNCHECK_TIMEOUT 1000
74 #define FAIL_TO_RECV_CONST 2500
75 #define SEQNO_UNCHANGED_CONST 30
76 #define MINIMUM_TIMEOUT (int)(1000/HZ)*3
77 #define MINIMUM_TIMEOUT_HOLD (int)(MINIMUM_TIMEOUT * 0.8 - (1000/HZ))
78 #define MAX_NETWORK_DELAY 50
79 #define WINDOW_SIZE 50
80 #define MAX_MESSAGES 17
81 #define MISS_COUNT_CONST 5
82 #define BLOCK_UNLISTED_IPS 1
85 #define KNET_PING_INTERVAL 1000
86 #define KNET_PING_TIMEOUT 2000
87 #define KNET_PING_PRECISION 2048
88 #define KNET_PONG_COUNT 2
89 #define KNET_PMTUD_INTERVAL 30
90 #define KNET_DEFAULT_TRANSPORT KNET_TRANSPORT_UDP
92 #define DEFAULT_PORT 5405
94 static char error_string_response[768];
100 if (strcmp(param_name,
"totem.token") == 0)
102 if (strcmp(param_name,
"totem.token_warning") == 0)
104 if (strcmp(param_name,
"totem.token_retransmit") == 0)
106 if (strcmp(param_name,
"totem.hold") == 0)
108 if (strcmp(param_name,
"totem.token_retransmits_before_loss_const") == 0)
110 if (strcmp(param_name,
"totem.join") == 0)
112 if (strcmp(param_name,
"totem.send_join") == 0)
114 if (strcmp(param_name,
"totem.consensus") == 0)
116 if (strcmp(param_name,
"totem.merge") == 0)
118 if (strcmp(param_name,
"totem.downcheck") == 0)
120 if (strcmp(param_name,
"totem.fail_recv_const") == 0)
122 if (strcmp(param_name,
"totem.seqno_unchanged_const") == 0)
124 if (strcmp(param_name,
"totem.heartbeat_failures_allowed") == 0)
126 if (strcmp(param_name,
"totem.max_network_delay") == 0)
128 if (strcmp(param_name,
"totem.window_size") == 0)
130 if (strcmp(param_name,
"totem.max_messages") == 0)
132 if (strcmp(param_name,
"totem.miss_count_const") == 0)
134 if (strcmp(param_name,
"totem.knet_pmtud_interval") == 0)
136 if (strcmp(param_name,
"totem.knet_compression_threshold") == 0)
138 if (strcmp(param_name,
"totem.knet_compression_level") == 0)
140 if (strcmp(param_name,
"totem.knet_compression_model") == 0)
142 if (strcmp(param_name,
"totem.block_unlisted_ips") == 0)
153 const char *key_name,
const char *deleted_key,
unsigned int default_value,
154 int allow_zero_value)
159 (deleted_key != NULL && strcmp(deleted_key, key_name) == 0) ||
160 (!allow_zero_value && *(uint32_t *)totem_get_param_by_name(
totem_config, key_name) == 0)) {
161 *(uint32_t *)totem_get_param_by_name(
totem_config, key_name) = default_value;
174 strcpy(runtime_key_name,
"runtime.config.");
175 strcat(runtime_key_name, key_name);
181 const char *key_name,
const char *deleted_key,
int default_value,
182 int allow_zero_value)
187 (deleted_key != NULL && strcmp(deleted_key, key_name) == 0) ||
188 (!allow_zero_value && *(int32_t *)totem_get_param_by_name(
totem_config, key_name) == 0)) {
189 *(int32_t *)totem_get_param_by_name(
totem_config, key_name) = default_value;
202 strcpy(runtime_key_name,
"runtime.config.");
203 strcat(runtime_key_name, key_name);
209 const char *key_name,
const char *deleted_key,
const char *default_value)
213 void *old_config_ptr;
215 config_value = totem_get_param_by_name(
totem_config, key_name);
216 old_config_ptr = *config_value;
218 (deleted_key != NULL && strcmp(deleted_key, key_name) == 0)) {
221 *config_value = strdup(default_value);
223 free(old_config_ptr);
235 strcpy(runtime_key_name,
"runtime.config.");
236 strcat(runtime_key_name, key_name);
249 const char *key_name,
const char *deleted_key,
unsigned int default_value)
258 if ((deleted_key != NULL && strcmp(deleted_key, key_name) == 0) ||
265 if (strcmp(str,
"yes") == 0) {
267 }
else if (strcmp(str,
"no") == 0) {
283 strcpy(runtime_key_name,
"runtime.config.");
284 strcat(runtime_key_name, key_name);
286 *(uint32_t *)totem_get_param_by_name(
totem_config, key_name) = val;
300 totem_volatile_config_set_uint32_value(
totem_config,
"totem.token_retransmits_before_loss_const", deleted_key,
327 totem_volatile_config_set_uint32_value(
totem_config,
"totem.token_retransmit", deleted_key,
330 totem_volatile_config_set_uint32_value(
totem_config,
"totem.hold", deleted_key,
335 totem_volatile_config_set_uint32_value(
totem_config,
"totem.consensus", deleted_key,
344 totem_volatile_config_set_uint32_value(
totem_config,
"totem.seqno_unchanged_const", deleted_key,
347 totem_volatile_config_set_uint32_value(
totem_config,
"totem.send_join", deleted_key, 0, 1);
349 totem_volatile_config_set_uint32_value(
totem_config,
"totem.heartbeat_failures_allowed", deleted_key, 0, 1);
351 totem_volatile_config_set_uint32_value(
totem_config,
"totem.knet_compression_threshold", deleted_key, 0, 1);
353 totem_volatile_config_set_int32_value(
totem_config,
"totem.knet_compression_level", deleted_key, 0, 1);
355 totem_volatile_config_set_string_value(
totem_config,
"totem.knet_compression_model", deleted_key,
"none");
357 totem_volatile_config_set_boolean_value(
totem_config,
"totem.block_unlisted_ips", deleted_key,
361 static int totem_volatile_config_validate (
363 const char **error_string)
365 static char local_error_reason[512];
366 const char *error_reason = local_error_reason;
369 int i, num_configured, members;
370 uint32_t tmp_config_value;
373 snprintf (local_error_reason,
sizeof(local_error_reason),
374 "The max_network_delay parameter (%d ms) may not be less than (%d ms).",
380 snprintf (local_error_reason,
sizeof(local_error_reason),
381 "The token timeout parameter (%d ms) may not be less than (%d ms).",
387 snprintf (local_error_reason,
sizeof(local_error_reason),
388 "The token warning parameter (%d%%) must be between 0 (disabled) and 100.",
395 snprintf (local_error_reason,
sizeof(local_error_reason),
396 "The token retransmit timeout parameter (%d ms) may not be less than (%d ms).",
400 snprintf (local_error_reason,
sizeof(local_error_reason),
401 "Not appropriate token or token_retransmits_before_loss_const value set");
407 snprintf (local_error_reason,
sizeof(local_error_reason),
408 "The token hold timeout parameter (%d ms) may not be less than (%d ms).",
414 snprintf (local_error_reason,
sizeof(local_error_reason),
415 "The join timeout parameter (%d ms) may not be less than (%d ms).",
421 snprintf (local_error_reason,
sizeof(local_error_reason),
422 "The consensus timeout parameter (%d ms) may not be less than (%d ms).",
428 snprintf (local_error_reason,
sizeof(local_error_reason),
429 "The consensus timeout parameter (%d ms) may not be less than join timeout (%d ms).",
435 snprintf (local_error_reason,
sizeof(local_error_reason),
436 "The merge timeout parameter (%d ms) may not be less than (%d ms).",
442 snprintf (local_error_reason,
sizeof(local_error_reason),
443 "The downcheck timeout parameter (%d ms) may not be less than (%d ms).",
456 if (num_configured > 1) {
460 snprintf(name_key,
sizeof(name_key),
"nodelist.node.%d.name", i);
463 snprintf (local_error_reason,
sizeof(local_error_reason),
464 "for a multi-link configuration, all nodes must have a 'name' attribute");
469 for (i=0; i<num_configured; i++) {
471 snprintf (local_error_reason,
sizeof(local_error_reason),
472 "Not all nodes have the same number of links");
484 snprintf (error_string_response,
sizeof(error_string_response),
485 "parse error in config: %s\n", error_reason);
486 *error_string = error_string_response;
494 const char *tmp_cipher;
495 const char *tmp_hash;
496 const char *tmp_model;
503 if (strcmp(str,
"nss") == 0) {
506 if (strcmp(str,
"openssl") == 0) {
507 tmp_model =
"openssl";
515 if (strcmp(str,
"on") == 0) {
516 tmp_cipher =
"aes256";
523 if (strcmp(str,
"none") == 0) {
526 if (strcmp(str,
"aes256") == 0) {
527 tmp_cipher =
"aes256";
529 if (strcmp(str,
"aes192") == 0) {
530 tmp_cipher =
"aes192";
532 if (strcmp(str,
"aes128") == 0) {
533 tmp_cipher =
"aes128";
539 if (strcmp(str,
"none") == 0) {
542 if (strcmp(str,
"md5") == 0) {
545 if (strcmp(str,
"sha1") == 0) {
548 if (strcmp(str,
"sha256") == 0) {
551 if (strcmp(str,
"sha384") == 0) {
554 if (strcmp(str,
"sha512") == 0) {
560 if ((strcmp(tmp_cipher,
"none") != 0) &&
561 (strcmp(tmp_hash,
"none") == 0)) {
562 *error_string =
"crypto_cipher requires crypto_hash with value other than none";
566 if (strcmp(tmp_model,
"none") == 0) {
567 *error_string =
"crypto_model should be 'nss' or 'openssl'";
582 static int nodelist_byname(
const char *find_name,
int strip_domain)
585 const char *iter_key;
588 unsigned int node_pos;
590 unsigned int namelen;
594 res = sscanf(iter_key,
"nodelist.node.%u.%s", &node_pos, name_str);
599 if (strcmp(name_str,
"name") && strcmp(name_str,
"ring0_addr")) {
605 namelen = strlen(name);
609 dot = strchr(name,
'.');
611 namelen = name - dot - 1;
614 if (strncmp(find_name, name, namelen) == 0 &&
615 strlen(find_name) == strlen(name)) {
625 static int ipaddr_equal(
const struct sockaddr *addr1,
const struct sockaddr *addr2)
628 const void *addr1p, *addr2p;
630 if (addr1->sa_family != addr2->sa_family)
633 switch (addr1->sa_family) {
635 addrlen =
sizeof(
struct in_addr);
636 addr1p = &((
struct sockaddr_in *)addr1)->sin_addr;
637 addr2p = &((
struct sockaddr_in *)addr2)->sin_addr;
640 addrlen =
sizeof(
struct in6_addr);
641 addr1p = &((
struct sockaddr_in6 *)addr1)->sin6_addr;
642 addr2p = &((
struct sockaddr_in6 *)addr2)->sin6_addr;
648 return (memcmp(addr1p, addr2p, addrlen) == 0);
655 static int find_local_node(
int use_cache)
657 char nodename2[PATH_MAX];
660 const char *iter_key;
661 unsigned int cached_pos;
664 struct ifaddrs *ifa, *ifa_list;
669 struct utsname utsname;
678 res = uname(&utsname);
682 node = utsname.nodename;
685 node_pos = nodelist_byname(node, 0);
694 strcpy(nodename2, node);
695 dot = strrchr(nodename2,
'.');
699 node_pos = nodelist_byname(nodename2, 0);
704 dot = strrchr(nodename2,
'.');
707 node_pos = nodelist_byname(nodename2, 1);
717 if (getifaddrs(&ifa_list))
720 for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) {
724 strcpy(nodename2, node);
729 if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6) {
733 if (sa->sa_family == AF_INET) {
734 salen =
sizeof(
struct sockaddr_in);
736 if (sa->sa_family == AF_INET6) {
737 salen =
sizeof(
struct sockaddr_in6);
740 if (getnameinfo(sa, salen,
741 nodename2,
sizeof(nodename2),
744 node_pos = nodelist_byname(nodename2, 0);
751 dot = strchr(nodename2,
'.');
755 node_pos = nodelist_byname(nodename2, 0);
764 if (getnameinfo(sa,
sizeof(*sa),
765 nodename2,
sizeof(nodename2),
766 NULL, 0, NI_NUMERICHOST))
769 node_pos = nodelist_byname(nodename2, 0);
778 freeifaddrs(ifa_list);
797 char *dbnodename = NULL;
798 struct addrinfo hints;
799 struct addrinfo *result = NULL, *rp = NULL;
801 res = sscanf(iter_key,
"nodelist.node.%u.%s", &node_pos, name_str);
808 if (strcmp(name_str,
"name") && strcmp(name_str,
"ring0_addr")) {
815 memset(&hints, 0,
sizeof(
struct addrinfo));
816 hints.ai_family = AF_UNSPEC;
817 hints.ai_socktype = SOCK_DGRAM;
819 hints.ai_protocol = IPPROTO_UDP;
821 if (getaddrinfo(dbnodename, NULL, &hints, &result)) {
825 for (rp = result; rp != NULL; rp = rp->ai_next) {
826 for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) {
828 ipaddr_equal(rp->ai_addr, ifa->ifa_addr)) {
829 freeaddrinfo(result);
836 freeaddrinfo(result);
840 freeifaddrs(ifa_list);
862 if (strcmp(str,
"ipv4") == 0) {
865 if (strcmp(str,
"ipv6") == 0) {
868 if (strcmp(str,
"ipv6-4") == 0) {
871 if (strcmp(str,
"ipv4-6") == 0) {
880 static uint16_t generate_cluster_id (
const char *cluster_name)
885 for (i = 0; i < strlen(cluster_name); i++) {
887 value += cluster_name[i];
890 return (
value & 0xFFFF);
893 static int get_cluster_mcast_addr (
894 const char *cluster_name,
895 unsigned int linknumber,
900 char addr[INET6_ADDRSTRLEN + 1];
903 if (cluster_name == NULL) {
907 clusterid = generate_cluster_id(cluster_name) + linknumber;
908 memset (res, 0,
sizeof(*res));
910 switch (ip_version) {
913 snprintf(
addr,
sizeof(
addr),
"239.192.%d.%d", clusterid >> 8, clusterid % 0xFF);
917 snprintf(
addr,
sizeof(
addr),
"ff15::%x", clusterid);
931 static unsigned int generate_nodeid(
943 memcpy (&
nodeid, &totemip.addr, sizeof (
unsigned int));
945 #if __BYTE_ORDER == __LITTLE_ENDIAN
955 static int check_for_duplicate_nodeids(
957 const char **error_string)
961 const char *iter_key;
965 char *ring0_addr=NULL;
966 char *ring0_addr1=NULL;
967 unsigned int node_pos;
968 unsigned int node_pos1;
969 unsigned int last_node_pos = -1;
971 unsigned int nodeid1;
976 res = sscanf(iter_key,
"nodelist.node.%u.%s", &node_pos, tmp_key);
986 if (last_node_pos == node_pos) {
989 last_node_pos = node_pos;
1012 while (((iter_key =
icmap_iter_next(subiter, NULL, NULL)) != NULL) && (node_pos1 < node_pos)) {
1013 res = sscanf(iter_key,
"nodelist.node.%u.%s", &node_pos1, tmp_key);
1014 if ((res != 2) || (node_pos1 >= node_pos)) {
1018 if (strcmp(tmp_key,
"nodeid") != 0) {
1030 if (nodeid1 == -1) {
1037 snprintf (error_string_response,
sizeof(error_string_response),
1038 "Nodeid %u%s%s%s appears twice in corosync.conf",
nodeid,
1039 autogenerated?
"(autogenerated from ":
"",
1040 autogenerated?ring0_addr:
"",
1041 autogenerated?
")":
"");
1043 *error_string = error_string_response;
1064 for (interface = 0;
interface <
INTERFACE_MAX; interface++) {
1074 snprintf(runtime_key_name,
sizeof(runtime_key_name),
1075 "runtime.config.totem.interface.%d.knet_ping_timeout", interface);
1082 snprintf(runtime_key_name,
sizeof(runtime_key_name),
1083 "runtime.config.totem.interface.%d.knet_ping_interval", interface);
1098 int ring_no, set1_pos, set2_pos;
1101 memset(&empty_ip_address, 0,
sizeof(empty_ip_address));
1104 if (!set1[ring_no].configured && !set2[ring_no].configured) {
1108 for (set1_pos = 0; set1_pos < set1[ring_no].
member_count; set1_pos++) {
1109 for (set2_pos = 0; set2_pos < set2[ring_no].
member_count; set2_pos++) {
1114 if (memcmp(&set1[ring_no].member_list[set1_pos],
1115 &set2[ring_no].member_list[set2_pos],
1117 memset(&set1[ring_no].member_list[set1_pos], 0,
1119 memset(&set2[ring_no].member_list[set2_pos], 0,
1127 for (set1_pos = 0; set1_pos < set1[ring_no].
member_count; set1_pos++) {
1132 if (memcmp(&set1[ring_no].member_list[set1_pos], &empty_ip_address,
sizeof(empty_ip_address)) != 0) {
1134 "removing dynamic member %s for ring %u",
1141 if (!set2[ring_no].configured) {
1144 for (set2_pos = 0; set2_pos < set2[ring_no].
member_count; set2_pos++) {
1149 if (memcmp(&set2[ring_no].member_list[set2_pos], &empty_ip_address,
sizeof(empty_ip_address)) != 0) {
1151 "adding dynamic member %s for ring %u",
1171 int local_node_pos = find_local_node(0);
1215 char addr_buf[INET6_ADDRSTRLEN];
1224 "New config has different knet transport for link %d. Internal value was NOT changed.\n", i);
1236 strncpy(addr_buf, ip_str,
sizeof(addr_buf));
1237 addr_buf[
sizeof(addr_buf) - 1] =
'\0';
1239 "new config has different address for link %d (addr changed from %s to %s). Internal value was NOT changed.\n",
1249 log_printf(
LOGSYS_LEVEL_ERROR,
"To reconfigure an interface it must be deleted and recreated. A working interface needs to be available to corosync at all times");
1254 static int put_nodelist_members_to_config(
struct totem_config *
totem_config,
int reload,
const char **error_string)
1257 const char *iter_key, *iter_key2;
1259 unsigned int node_pos;
1262 char *node_addr_str;
1264 unsigned int linknumber = 0;
1266 int last_node_pos = -1;
1276 assert(new_interfaces != NULL);
1289 res = sscanf(iter_key,
"nodelist.node.%u.%s", &node_pos, tmp_key);
1294 if (node_pos == last_node_pos) {
1297 last_node_pos = node_pos;
1310 res = sscanf(iter_key2,
"nodelist.node.%u.ring%u%s", &node_pos, &linknumber, tmp_key2);
1311 if (res != 3 || strcmp(tmp_key2,
"_addr") != 0) {
1327 sprintf(error_string_response,
1328 "An IPV6 network requires that a node ID be specified "
1329 "for address '%s'.", node_addr_str);
1330 *error_string = error_string_response;
1337 "Generated nodeid = 0x%x for %s",
nodeid, str);
1350 sprintf(error_string_response,
"failed to parse node address '%s'\n", node_addr_str);
1351 *error_string = error_string_response;
1356 free(node_addr_str);
1362 free(node_addr_str);
1380 free(new_interfaces);
1391 char *node_addr_str;
1392 unsigned int linknumber = 0;
1394 const char *iter_key;
1396 node_pos = find_local_node(1);
1397 if (node_pos > -1) {
1404 res = sscanf(iter_key,
"nodelist.node.%u.ring%u%s", &node_pos, &linknumber, tmp_key2);
1405 if (res != 3 || strcmp(tmp_key2,
"_addr") != 0) {
1415 free(node_addr_str);
1422 const char **error_string, uint64_t *warnings,
1426 unsigned int linknumber = 0;
1430 const char *iter_key;
1431 const char *member_iter_key;
1437 char *cluster_name = NULL;
1455 cluster_name = NULL;
1460 res = sscanf(iter_key,
"totem.interface.%[^.].%s", linknumber_key, tmp_key);
1470 linknumber = atoi(linknumber_key);
1475 snprintf (error_string_response,
sizeof(error_string_response),
1476 "parse error in config: interface ring number %u is bigger than allowed maximum %u\n",
1479 *error_string = error_string_response;
1495 sprintf(error_string_response,
"failed to parse bindnet address '%s'\n", str);
1496 *error_string = error_string_response;
1514 sprintf(error_string_response,
"failed to parse mcast address '%s'\n", str);
1515 *error_string = error_string_response;
1536 (void)get_cluster_mcast_addr (cluster_name,
1544 if (strcmp (str,
"yes") == 0) {
1580 if (strcmp(str,
"sctp") == 0) {
1583 else if (strcmp(str,
"udp") == 0) {
1587 *error_string =
"Unrecognised knet_transport. expected 'udp' or 'sctp'";
1627 while ((member_iter_key =
icmap_iter_next(member_iter, NULL, NULL)) != NULL) {
1642 sprintf(error_string_response,
"failed to parse node address '%s'\n", str);
1643 *error_string = error_string_response;
1666 const char **error_string,
1670 char *str, *ring0_addr_str;
1682 *error_string =
"Out of memory trying to allocate ethernet interface storage area";
1688 if (strcmp (str,
"udpu") == 0) {
1692 if (strcmp (str,
"udp") == 0) {
1696 if (strcmp (str,
"knet") == 0) {
1710 if (totem_get_crypto(
totem_config, error_string) != 0) {
1716 *error_string =
"totem.link_mode is too long";
1729 if (strcmp (str,
"yes") == 0) {
1756 free(ring0_addr_str);
1768 res = get_interface_params(
totem_config, error_string, warnings, 0);
1815 local_node_pos = find_local_node(1);
1816 if (local_node_pos != -1) {
1825 *error_string =
"Knet requires an explicit nodeid for the local node";
1837 *error_string =
"An IPV6 network requires that a node ID be specified";
1852 if (put_nodelist_members_to_config(
totem_config, 0, error_string)) {
1874 const char **error_string)
1876 static char local_error_reason[512];
1877 char parse_error[512];
1878 static char addr_str_buf[INET6_ADDRSTRLEN];
1879 const char *error_reason = local_error_reason;
1882 int num_configured = 0;
1890 if (num_configured == 0) {
1891 error_reason =
"No interfaces defined";
1897 error_reason =
"No valid name found for local host";
1917 error_reason =
"No multicast address specified";
1922 error_reason =
"No multicast port specified";
1927 error_reason =
"Invalid TTL (should be 0..255)";
1932 error_reason =
"Can only set ttl on multicast transport types";
1936 error_reason =
"Invalid link priority (should be 0..255)";
1941 error_reason =
"Can only set link priority on knet transport type";
1948 error_reason =
"An IPV6 network requires that a node ID be specified.";
1954 error_reason =
"Multicast address family does not match bind address family";
1959 error_reason =
"mcastaddr is not a correct multicast address.";
1968 memcpy(addr_str_buf,
1970 sizeof(addr_str_buf));
1972 snprintf (local_error_reason,
sizeof(local_error_reason),
1973 "Nodes for link %d have different IP families "
1974 "(compared %s with %s)", i,
1984 error_reason =
"This totem parser can only parse version 2 configurations.";
1988 if (totem_volatile_config_validate(
totem_config, error_string) == -1) {
1992 if (check_for_duplicate_nodeids(
totem_config, error_string) == -1) {
2002 snprintf (local_error_reason,
sizeof(local_error_reason),
2003 "The Knet link mode \"%s\" specified is invalid. It must be active, passive or rr.\n",
totem_config->
link_mode);
2012 if (interface_max < num_configured) {
2013 snprintf (parse_error,
sizeof(parse_error),
2014 "%d is too many configured interfaces for non-Knet transport.",
2016 error_reason = parse_error;
2025 snprintf (parse_error,
sizeof(parse_error),
2026 "crypto_cipher & crypto_hash are only valid for the Knet transport.");
2027 error_reason = parse_error;
2044 snprintf (error_string_response,
sizeof(error_string_response),
2045 "parse error in config: %s\n", error_reason);
2046 *error_string = error_string_response;
2051 static int read_keyfile (
2052 const char *key_location,
2054 const char **error_string)
2059 char error_str[100];
2060 const char *error_ptr;
2062 fd = open (key_location, O_RDONLY);
2064 error_ptr = qb_strerror_r(errno, error_str,
sizeof(error_str));
2065 snprintf (error_string_response,
sizeof(error_string_response),
2066 "Could not open %s: %s\n",
2067 key_location, error_ptr);
2072 saved_errno = errno;
2076 error_ptr = qb_strerror_r (saved_errno, error_str,
sizeof(error_str));
2077 snprintf (error_string_response,
sizeof(error_string_response),
2078 "Could not read %s: %s\n",
2079 key_location, error_ptr);
2084 snprintf (error_string_response,
sizeof(error_string_response),
2085 "Could only read %d bits of minimum %u bits from %s.\n",
2095 *error_string = error_string_response;
2101 const char **error_string)
2104 char *key_location = NULL;
2118 res = read_keyfile(key_location,
totem_config, error_string);
2127 sprintf(error_string_response,
"key is too long");
2131 sprintf(error_string_response,
"key is too short");
2138 sprintf(error_string_response,
"can't load private key");
2154 *error_string = error_string_response;
2168 if (token_warning_ms < totem_config->token_retransmit_timeout)
2170 "The token warning interval (%d ms) is less than the token retransmit timeout (%d ms) "
2171 "which can lead to spurious token warnings. Consider increasing the token_warning parameter.",
2184 "seqno unchanged const (%d rotations) Maximum network MTU %d",
2187 "window size per rotation (%d messages) maximum messages per rotation (%d messages)",
2195 static void totem_change_notify(
2197 const char *key_name,
2205 const char *deleted_key = NULL;
2206 const char *error_string;
2221 if (!
param && strcmp(key_name,
"totem.token_coefficient") != 0)
2229 deleted_key = key_name;
2239 totem_volatile_config_read (
totem_config, deleted_key);
2242 if (totem_volatile_config_validate(
totem_config, &error_string) == -1) {
2251 static void totem_reload_notify(
2253 const char *key_name,
2259 const char *error_string;
2263 if (*(uint8_t *)new_val.
data == 0) {
2269 get_interface_params(
totem_config, &error_string, &warnings, 1);
2270 if (put_nodelist_members_to_config (
totem_config, 1, &error_string)) {
2279 if (totem_volatile_config_validate(
totem_config, &error_string) == -1) {
2288 (void)find_local_node(0);
2307 totem_change_notify,
2313 totem_reload_notify,