When a reload is in progress, wait until the whole thing has finished before setting parameters Signed-off-by: Christine Caulfield <ccaulfie@xxxxxxxxxx> --- exec/totemconfig.c | 335 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 229 insertions(+), 106 deletions(-) diff --git a/exec/totemconfig.c b/exec/totemconfig.c index 62daeaf..de63043 100644 --- a/exec/totemconfig.c +++ b/exec/totemconfig.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2002-2005 MontaVista Software, Inc. - * Copyright (c) 2006-2012 Red Hat, Inc. + * Copyright (c) 2006-2013 Red Hat, Inc. * * All rights reserved. * @@ -83,6 +83,57 @@ static char error_string_response[512]; static void add_totem_config_notification(struct totem_config *totem_config); + +/* All the volatile parameters are uint32s, luckily */ +static uint32_t *totem_get_param_by_name(struct totem_config *totem_config, const char *param_name) +{ + if (strcmp(param_name, "totem.token") == 0) + return &totem_config->token_timeout; + if (strcmp(param_name, "totem.token_retransmit") == 0) + return &totem_config->token_retransmit_timeout; + if (strcmp(param_name, "totem.hold") == 0) + return &totem_config->token_hold_timeout; + if (strcmp(param_name, "totem.token_retransmits_before_loss_const") == 0) + return &totem_config->token_retransmits_before_loss_const; + if (strcmp(param_name, "totem.join") == 0) + return &totem_config->join_timeout; + if (strcmp(param_name, "totem.send_join") == 0) + return &totem_config->send_join_timeout; + if (strcmp(param_name, "totem.consensus") == 0) + return &totem_config->consensus_timeout; + if (strcmp(param_name, "totem.merge") == 0) + return &totem_config->merge_timeout; + if (strcmp(param_name, "totem.downcheck") == 0) + return &totem_config->downcheck_timeout; + if (strcmp(param_name, "totem.fail_recv_const") == 0) + return &totem_config->fail_to_recv_const; + if (strcmp(param_name, "totem.seqno_unchanged_const") == 0) + return &totem_config->seqno_unchanged_const; + if (strcmp(param_name, "totem.rrp_token_expired_timeout") == 0) + return &totem_config->rrp_token_expired_timeout; + if (strcmp(param_name, "totem.rrp_problem_count_timeout") == 0) + return &totem_config->rrp_problem_count_timeout; + if (strcmp(param_name, "totem.rrp_problem_count_threshold") == 0) + return &totem_config->rrp_problem_count_threshold; + if (strcmp(param_name, "totem.rrp_problem_count_mcast_threshold") == 0) + return &totem_config->rrp_problem_count_mcast_threshold; + if (strcmp(param_name, "totem.rrp_autorecovery_check_timeout") == 0) + return &totem_config->rrp_autorecovery_check_timeout; + if (strcmp(param_name, "totem.heartbeat_failures_allowed") == 0) + return &totem_config->heartbeat_failures_allowed; + if (strcmp(param_name, "totem.max_network_delay") == 0) + return &totem_config->max_network_delay; + if (strcmp(param_name, "totem.window_size") == 0) + return &totem_config->window_size; + if (strcmp(param_name, "totem.max_messages") == 0) + return &totem_config->max_messages; + if (strcmp(param_name, "totem.miss_count_const") == 0) + return &totem_config->miss_count_const; + + return NULL; +} + + static void totem_volatile_config_read (struct totem_config *totem_config) { char *str; @@ -703,80 +754,12 @@ extern int totem_config_read ( return 0; } -int totem_config_validate ( +static int totem_set_volatile_defaults ( struct totem_config *totem_config, const char **error_string) { static char local_error_reason[512]; - char parse_error[512]; const char *error_reason = local_error_reason; - int i; - unsigned int interface_max = INTERFACE_MAX; - - if (totem_config->interface_count == 0) { - error_reason = "No interfaces defined"; - goto parse_error; - } - - for (i = 0; i < totem_config->interface_count; i++) { - /* - * Some error checking of parsed data to make sure its valid - */ - - struct totem_ip_address null_addr; - memset (&null_addr, 0, sizeof (struct totem_ip_address)); - - if ((totem_config->transport_number == 0) && - memcmp (&totem_config->interfaces[i].mcast_addr, &null_addr, - sizeof (struct totem_ip_address)) == 0) { - error_reason = "No multicast address specified"; - goto parse_error; - } - - if (totem_config->interfaces[i].ip_port == 0) { - error_reason = "No multicast port specified"; - goto parse_error; - } - - if (totem_config->interfaces[i].ttl > 255) { - error_reason = "Invalid TTL (should be 0..255)"; - goto parse_error; - } - if (totem_config->transport_number != TOTEM_TRANSPORT_UDP && - totem_config->interfaces[i].ttl != 1) { - error_reason = "Can only set ttl on multicast transport types"; - goto parse_error; - } - - if (totem_config->interfaces[i].mcast_addr.family == AF_INET6 && - totem_config->node_id == 0) { - - error_reason = "An IPV6 network requires that a node ID be specified."; - goto parse_error; - } - - if (totem_config->broadcast_use == 0 && totem_config->transport_number == 0) { - if (totem_config->interfaces[i].mcast_addr.family != totem_config->interfaces[i].bindnet.family) { - error_reason = "Multicast address family does not match bind address family"; - goto parse_error; - } - - if (totem_config->interfaces[i].mcast_addr.family != totem_config->interfaces[i].bindnet.family) { - error_reason = "Not all bind address belong to the same IP family"; - goto parse_error; - } - if (totemip_is_mcast (&totem_config->interfaces[i].mcast_addr) != 0) { - error_reason = "mcastaddr is not a correct multicast address."; - goto parse_error; - } - } - } - - if (totem_config->version != 2) { - error_reason = "This totem parser can only parse version 2 configurations."; - goto parse_error; - } - if (totem_config->token_retransmits_before_loss_const == 0) { totem_config->token_retransmits_before_loss_const = @@ -888,16 +871,15 @@ int totem_config_validate ( goto parse_error; } - /* - * RRP values validation - */ - if (strcmp (totem_config->rrp_mode, "none") && - strcmp (totem_config->rrp_mode, "active") && - strcmp (totem_config->rrp_mode, "passive")) { - snprintf (local_error_reason, sizeof(local_error_reason), - "The RRP mode \"%s\" specified is invalid. It must be none, active, or passive.\n", totem_config->rrp_mode); - goto parse_error; + if (totem_config->fail_to_recv_const == 0) { + totem_config->fail_to_recv_const = FAIL_TO_RECV_CONST; } + if (totem_config->seqno_unchanged_const == 0) { + totem_config->seqno_unchanged_const = SEQNO_UNCHANGED_CONST; + } + +/* RRP volatile values */ + if (totem_config->rrp_problem_count_timeout == 0) { totem_config->rrp_problem_count_timeout = RRP_PROBLEM_COUNT_TIMEOUT; } @@ -941,54 +923,127 @@ int totem_config_validate ( totem_config->rrp_autorecovery_check_timeout = RRP_AUTORECOVERY_CHECK_TIMEOUT; } - if (strcmp (totem_config->rrp_mode, "none") == 0) { - interface_max = 1; - } - if (interface_max < totem_config->interface_count) { - snprintf (parse_error, sizeof(parse_error), - "%d is too many configured interfaces for the rrp_mode setting %s.", - totem_config->interface_count, - totem_config->rrp_mode); - error_reason = parse_error; + return 0; + +parse_error: + snprintf (error_string_response, sizeof(error_string_response), + "parse error in config: %s\n", error_reason); + *error_string = error_string_response; + return (-1); + +} + +int totem_config_validate ( + struct totem_config *totem_config, + const char **error_string) +{ + static char local_error_reason[512]; + char parse_error[512]; + const char *error_reason = local_error_reason; + int i; + unsigned int interface_max = INTERFACE_MAX; + + if (totem_config->interface_count == 0) { + error_reason = "No interfaces defined"; goto parse_error; } + for (i = 0; i < totem_config->interface_count; i++) { + /* + * Some error checking of parsed data to make sure its valid + */ - if (totem_config->fail_to_recv_const == 0) { - totem_config->fail_to_recv_const = FAIL_TO_RECV_CONST; - } - if (totem_config->seqno_unchanged_const == 0) { - totem_config->seqno_unchanged_const = SEQNO_UNCHANGED_CONST; + struct totem_ip_address null_addr; + memset (&null_addr, 0, sizeof (struct totem_ip_address)); + + if ((totem_config->transport_number == 0) && + memcmp (&totem_config->interfaces[i].mcast_addr, &null_addr, + sizeof (struct totem_ip_address)) == 0) { + error_reason = "No multicast address specified"; + goto parse_error; + } + + if (totem_config->interfaces[i].ip_port == 0) { + error_reason = "No multicast port specified"; + goto parse_error; + } + + if (totem_config->interfaces[i].ttl > 255) { + error_reason = "Invalid TTL (should be 0..255)"; + goto parse_error; + } + if (totem_config->transport_number != TOTEM_TRANSPORT_UDP && + totem_config->interfaces[i].ttl != 1) { + error_reason = "Can only set ttl on multicast transport types"; + goto parse_error; + } + + if (totem_config->interfaces[i].mcast_addr.family == AF_INET6 && + totem_config->node_id == 0) { + + error_reason = "An IPV6 network requires that a node ID be specified."; + goto parse_error; + } + + if (totem_config->broadcast_use == 0 && totem_config->transport_number == 0) { + if (totem_config->interfaces[i].mcast_addr.family != totem_config->interfaces[i].bindnet.family) { + error_reason = "Multicast address family does not match bind address family"; + goto parse_error; + } + + if (totem_config->interfaces[i].mcast_addr.family != totem_config->interfaces[i].bindnet.family) { + error_reason = "Not all bind address belong to the same IP family"; + goto parse_error; + } + if (totemip_is_mcast (&totem_config->interfaces[i].mcast_addr) != 0) { + error_reason = "mcastaddr is not a correct multicast address."; + goto parse_error; + } + } } - if (totem_config->net_mtu == 0) { - totem_config->net_mtu = 1500; + + if (totem_config->version != 2) { + error_reason = "This totem parser can only parse version 2 configurations."; + goto parse_error; } - if ((MESSAGE_QUEUE_MAX) < totem_config->max_messages) { + totem_set_volatile_defaults(totem_config, error_string); + + /* + * RRP values validation + */ + if (strcmp (totem_config->rrp_mode, "none") && + strcmp (totem_config->rrp_mode, "active") && + strcmp (totem_config->rrp_mode, "passive")) { snprintf (local_error_reason, sizeof(local_error_reason), - "The max_messages parameter (%d messages) may not be greater then (%d messages).", - totem_config->max_messages, MESSAGE_QUEUE_MAX); + "The RRP mode \"%s\" specified is invalid. It must be none, active, or passive.\n", totem_config->rrp_mode); goto parse_error; } - if (totem_config->threads > SEND_THREADS_MAX) { - totem_config->threads = SEND_THREADS_MAX; + if (strcmp (totem_config->rrp_mode, "none") == 0) { + interface_max = 1; } - if (totem_config->net_mtu > FRAME_SIZE_MAX) { - error_reason = "This net_mtu parameter is greater then the maximum frame size"; + if (interface_max < totem_config->interface_count) { + snprintf (parse_error, sizeof(parse_error), + "%d is too many configured interfaces for the rrp_mode setting %s.", + totem_config->interface_count, + totem_config->rrp_mode); + error_reason = parse_error; goto parse_error; } - if (totem_config->vsf_type == NULL) { - totem_config->vsf_type = "none"; + + if (totem_config->net_mtu == 0) { + totem_config->net_mtu = 1500; } - return (0); + return 0; parse_error: snprintf (error_string_response, sizeof(error_string_response), "parse error in config: %s\n", error_reason); *error_string = error_string_response; return (-1); + } static int read_keyfile ( @@ -1107,7 +1162,69 @@ static void totem_change_notify( struct icmap_notify_value old_val, void *user_data) { - totem_volatile_config_read((struct totem_config *)user_data); + uint32_t *param; + const char *error_string; + uint8_t reloading; + + /* + * If a full reload is in progress then don't do anything until it's done and + * can reconfigure it all atomically + */ + if (icmap_get_uint8("config.reload_in_progress", &reloading) == CS_OK && reloading) + return; + + param = totem_get_param_by_name((struct totem_config *)user_data, key_name); + if (!param) + return; + + switch (event) + { + case ICMAP_TRACK_DELETE: + if (new_val.type == ICMAP_VALUETYPE_UINT32) + *param = 0; + totem_set_volatile_defaults((struct totem_config *)user_data, &error_string); + break; + case ICMAP_TRACK_ADD: + case ICMAP_TRACK_MODIFY: + if (new_val.type == ICMAP_VALUETYPE_UINT32) + memcpy(param, new_val.data, new_val.len); + /* Other value types not supported, or needed (yet) */ + break; + default: + break; + } +} + +static void totem_reload_notify( + int32_t event, + const char *key_name, + struct icmap_notify_value new_val, + struct icmap_notify_value old_val, + void *user_data) +{ + struct totem_config *totem_config = (struct totem_config *)user_data; + uint32_t local_node_pos; + + /* Reload has completed */ + if (*(uint8_t *)new_val.data == 0) { + int i, j; + + /* Clear out udpu nodelist so we can put the new one in if neede */ + for (i=0; i<totem_config->interface_count; i++) { + for (j=0; j<PROCESSOR_COUNT_MAX; j++) { + memset(&totem_config->interfaces[i].member_list[j], 0, sizeof(struct totem_ip_address)); + } + } + + put_nodelist_members_to_config (totem_config); + totem_volatile_config_read (totem_config); + + /* Reinstate the local_node_pos */ + local_node_pos = find_local_node_in_nodelist(totem_config); + if (local_node_pos != -1) { + icmap_set_uint32("nodelist.local_node_pos", local_node_pos); + } + } } static void add_totem_config_notification(struct totem_config *totem_config) @@ -1119,4 +1236,10 @@ static void add_totem_config_notification(struct totem_config *totem_config) totem_change_notify, totem_config, &icmap_track); + + icmap_track_add("config.reload_in_progress", + ICMAP_TRACK_ADD | ICMAP_TRACK_MODIFY, + totem_reload_notify, + totem_config, + &icmap_track); } -- 1.8.1.4 _______________________________________________ discuss mailing list discuss@xxxxxxxxxxxx http://lists.corosync.org/mailman/listinfo/discuss