Преглед изворни кода

totemudpu: Send msgs to all members occasionally

To follow spec it's needed to send messages to all nodes (not only
active members) from time to time to detect merge.

This is needed in situations when totemsrp merge timer isn't running
(because there is enough messages sent by processors) to detect merge.

Example scenario:
- 3 nodes, all of them running cpgverify
- One node is isolated (iptables for example)
- Node is un-isolated

Without this commit, node will not merge as long as the cpgverify is
running.

(backported from master 2429481b96d895c366ca27c82a2bd7cfee55af15)

Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
Jan Friesse пре 11 година
родитељ
комит
0bd2902541
1 измењених фајлова са 65 додато и 1 уклоњено
  1. 65 1
      exec/totemudpu.c

+ 65 - 1
exec/totemudpu.c

@@ -195,6 +195,12 @@ struct totemudpu_instance {
 	struct totem_ip_address token_target;
 
 	int token_socket;
+
+	poll_timer_handle timer_merge_detect_timeout;
+
+	int send_merge_detect_message;
+
+	unsigned int merge_detect_messages_sent_before_timeout;
 };
 
 struct work_item {
@@ -215,6 +221,12 @@ static int totemudpu_create_sending_socket(
 int totemudpu_member_list_rebind_ip (
 	void *udpu_context);
 
+static void totemudpu_start_merge_detect_timeout(
+	void *udpu_context);
+
+static void totemudpu_stop_merge_detect_timeout(
+	void *udpu_context);
+
 static struct totem_ip_address localhost;
 
 static void totemudpu_instance_initialize (struct totemudpu_instance *instance)
@@ -1035,7 +1047,11 @@ static inline void mcast_sendmsg (
 			struct totemudpu_member,
 			list);
 
-		if (only_active && !member->active)
+		/*
+		 * Do not send multicast message if message is not "flush", member
+		 * is inactive and timeout for sending merge message didn't expired.
+		 */
+		if (only_active && !member->active && !instance->send_merge_detect_message)
 			continue ;
 
 		totemip_totemip_to_sockaddr_convert(&member->member,
@@ -1063,6 +1079,14 @@ static inline void mcast_sendmsg (
 				"sendmsg(mcast) failed (non-critical)");
 		}
 	}
+
+	if (!only_active || instance->send_merge_detect_message) {
+		/*
+		 * Current message was sent to all nodes
+		 */
+		instance->merge_detect_messages_sent_before_timeout++;
+		instance->send_merge_detect_message = 0;
+	}
 }
 
 int totemudpu_finalize (
@@ -1077,6 +1101,8 @@ int totemudpu_finalize (
 			instance->token_socket);
 	}
 
+	totemudpu_stop_merge_detect_timeout(instance);
+
 	return (res);
 }
 
@@ -1500,6 +1526,8 @@ int totemudpu_initialize (
 		timer_function_netif_check_timeout,
 		&instance->timer_netif_check_timeout);
 
+	totemudpu_start_merge_detect_timeout(instance);
+
 	*udpu_context = instance;
 	return (0);
 }
@@ -1834,3 +1862,39 @@ int totemudpu_member_set_active (
 
 	return (0);
 }
+
+static void timer_function_merge_detect_timeout (
+	void *data)
+{
+	struct totemudpu_instance *instance = (struct totemudpu_instance *)data;
+
+	if (instance->merge_detect_messages_sent_before_timeout == 0) {
+		instance->send_merge_detect_message = 1;
+	}
+
+	instance->merge_detect_messages_sent_before_timeout = 0;
+
+	totemudpu_start_merge_detect_timeout(instance);
+}
+
+static void totemudpu_start_merge_detect_timeout(
+	void *udpu_context)
+{
+	struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
+
+	poll_timer_add(instance->totemudpu_poll_handle,
+	    instance->totem_config->merge_timeout * 2,
+	    (void *)instance,
+	    timer_function_merge_detect_timeout,
+	    &instance->timer_merge_detect_timeout);
+
+}
+
+static void totemudpu_stop_merge_detect_timeout(
+	void *udpu_context)
+{
+	struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
+
+	poll_timer_delete(instance->totemudpu_poll_handle,
+	    instance->timer_merge_detect_timeout);
+}