Просмотр исходного кода

totemrrp: Fix situation when all rings are faulty

Previously when all rings were marked as failed no message was sent via
any interface. This is problem because totemsrp relies on messages
delivered via localhost multicast loop socket so it never moved to
single node mode and it got stuck.

Solution is to send message via one of the interfaces (first one seems
to be obvious choice) if it was not sent via any interface.

Strictly speaking it should be enough to change just *_mcast_flush_send
functions, but changing others is just for sure.

Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
(cherry picked from commit 2901eceab43d8f0f3c5e8720ee4b906fd898791a)
Jan Friesse 8 лет назад
Родитель
Сommit
8ba08027e8
1 измененных файлов с 65 добавлено и 8 удалено
  1. 65 8
      exec/totemrrp.c

+ 65 - 8
exec/totemrrp.c

@@ -1092,9 +1092,15 @@ static void passive_mcast_flush_send (
 		i++;
 	} while ((i <= instance->interface_count) && (passive_instance->faulty[passive_instance->msg_xmit_iface] == 1));
 
-	if (i <= instance->interface_count) {
-		totemnet_mcast_flush_send (instance->net_handles[passive_instance->msg_xmit_iface], msg, msg_len);
+	if (i > instance->interface_count) {
+		/*
+		 * All interfaces are faulty. It's still needed to send mcast
+		 * message to local host so use first interface.
+		 */
+		passive_instance->msg_xmit_iface = 0;
 	}
+
+	totemnet_mcast_flush_send (instance->net_handles[passive_instance->msg_xmit_iface], msg, msg_len);
 }
 
 static void passive_mcast_noflush_send (
@@ -1110,9 +1116,16 @@ static void passive_mcast_noflush_send (
 		i++;
 	} while ((i <= instance->interface_count) && (passive_instance->faulty[passive_instance->msg_xmit_iface] == 1));
 
-	if (i <= instance->interface_count) {
-		totemnet_mcast_noflush_send (instance->net_handles[passive_instance->msg_xmit_iface], msg, msg_len);
+
+	if (i > instance->interface_count) {
+		/*
+		 * All interfaces are faulty. It's still needed to send mcast
+		 * message to local host so use first interface.
+		 */
+		passive_instance->msg_xmit_iface = 0;
 	}
+
+	totemnet_mcast_noflush_send (instance->net_handles[passive_instance->msg_xmit_iface], msg, msg_len);
 }
 
 static void passive_token_recv (
@@ -1154,12 +1167,17 @@ static void passive_token_send (
 		i++;
 	} while ((i <= instance->interface_count) && (passive_instance->faulty[passive_instance->token_xmit_iface] == 1));
 
-	if (i <= instance->interface_count) {
-		totemnet_token_send (
-		    instance->net_handles[passive_instance->token_xmit_iface],
-		    msg, msg_len);
+	if (i > instance->interface_count) {
+		/*
+		 * All interfaces are faulty. It's still needed to send token
+		 * message to (potentionally) local host so use first interface.
+		 */
+		passive_instance->msg_xmit_iface = 0;
 	}
 
+	totemnet_token_send (
+	    instance->net_handles[passive_instance->token_xmit_iface],
+	    msg, msg_len);
 }
 
 static void passive_recv_flush (struct totemrrp_instance *instance)
@@ -1525,13 +1543,25 @@ static void active_mcast_flush_send (
 	unsigned int msg_len)
 {
 	int i;
+	int msg_sent;
 	struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
 
+	msg_sent = 0;
+
 	for (i = 0; i < instance->interface_count; i++) {
 		if (rrp_algo_instance->faulty[i] == 0) {
+			msg_sent = 1;
 			totemnet_mcast_flush_send (instance->net_handles[i], msg, msg_len);
 		}
 	}
+
+	if (!msg_sent) {
+		/*
+		 * All interfaces are faulty. It's still needed to send mcast
+		 * message to local host so use first interface.
+		 */
+		totemnet_mcast_flush_send (instance->net_handles[0], msg, msg_len);
+	}
 }
 
 static void active_mcast_noflush_send (
@@ -1540,13 +1570,25 @@ static void active_mcast_noflush_send (
 	unsigned int msg_len)
 {
 	int i;
+	int msg_sent;
 	struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
 
+	msg_sent = 0;
+
 	for (i = 0; i < instance->interface_count; i++) {
 		if (rrp_algo_instance->faulty[i] == 0) {
+			msg_sent = 1;
 			totemnet_mcast_noflush_send (instance->net_handles[i], msg, msg_len);
 		}
 	}
+
+	if (!msg_sent) {
+		/*
+		 * All interfaces are faulty. It's still needed to send mcast
+		 * message to local host so use first interface.
+		 */
+		totemnet_mcast_noflush_send (instance->net_handles[0], msg, msg_len);
+	}
 }
 
 static void active_token_recv (
@@ -1602,15 +1644,30 @@ static void active_token_send (
 {
 	struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
 	int i;
+	int msg_sent;
+
+	msg_sent = 0;
 
 	for (i = 0; i < instance->interface_count; i++) {
 		if (rrp_algo_instance->faulty[i] == 0) {
+			msg_sent = 1;
 			totemnet_token_send (
 				instance->net_handles[i],
 				msg, msg_len);
 
 		}
 	}
+
+	if (!msg_sent) {
+		/*
+		 * All interfaces are faulty. It's still needed to send token
+		 * message to (potentionally) local host so use first interface.
+		 */
+		totemnet_token_send (
+			instance->net_handles[0],
+			msg, msg_len);
+
+	}
 }
 
 static void active_recv_flush (struct totemrrp_instance *instance)