When a reload is in progress, wait until the whole thing has
finished before setting parameters

Signed-off-by: Christine Caulfield <[email protected]>
---
 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
[email protected]
http://lists.corosync.org/mailman/listinfo/discuss

Reply via email to