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

totemudp: Retry if bind fails

If bind call fails it's retried for BIND_MAX_RETRIES.
If it's still unsuccessful, corosync exists instead
of working incorrectly.

Slightly modified by reviewer.

(backported from master 5b38aa721a3e3bf9c66c415c8058a73c5d48738a)

Signed-off-by: Masse Nicolas <nicolas.masse@stormshield.eu>
Reviewed-by: Jan Friesse <jfriesse@redhat.com>
Masse Nicolas 8 лет назад
Родитель
Сommit
8bbd6c9530
3 измененных файлов с 89 добавлено и 10 удалено
  1. 62 8
      exec/totemudp.c
  2. 24 2
      exec/totemudpu.c
  3. 3 0
      include/corosync/totem/totem.h

+ 62 - 8
exec/totemudp.c

@@ -724,8 +724,9 @@ static int totemudp_build_sockets_ip (
 	struct sockaddr_in  *mcast_sin = (struct sockaddr_in *)&mcast_ss;
 	struct sockaddr_in  *boundto_sin = (struct sockaddr_in *)&boundto_ss;
 	unsigned int sendbuf_size;
-        unsigned int recvbuf_size;
-        unsigned int optlen = sizeof (sendbuf_size);
+	unsigned int recvbuf_size;
+	unsigned int optlen = sizeof (sendbuf_size);
+	unsigned int retries;
 	int addrlen;
 	int res;
 	int flag;
@@ -811,10 +812,25 @@ static int totemudp_build_sockets_ip (
 
 	totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_interface->ip_port - 1,
 		&sockaddr, &addrlen);
-	res = bind (sockets->mcast_send, (struct sockaddr *)&sockaddr, addrlen);
-	if (res == -1) {
+
+	retries = 0;
+	while (1) {
+		res = bind (sockets->mcast_send, (struct sockaddr *)&sockaddr, addrlen);
+		if (res == 0) {
+			break;
+		}
 		LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
 			"Unable to bind the socket to send multicast packets");
+		if (++retries > BIND_MAX_RETRIES) {
+			break;
+		}
+
+		/*
+		 * Wait for a while
+		 */
+		(void)poll(NULL, 0, BIND_RETRIES_INTERVAL * retries);
+	}
+	if (res == -1) {
 		return (-1);
 	}
 
@@ -851,10 +867,25 @@ static int totemudp_build_sockets_ip (
 	 * This has the side effect of binding to the correct interface
 	 */
 	totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_interface->ip_port, &sockaddr, &addrlen);
-	res = bind (sockets->token, (struct sockaddr *)&sockaddr, addrlen);
-	if (res == -1) {
+
+	retries = 0;
+	while (1) {
+		res = bind (sockets->token, (struct sockaddr *)&sockaddr, addrlen);
+		if (res == 0) {
+			break;
+		}
 		LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
 			"Unable to bind UDP unicast socket");
+		if (++retries > BIND_MAX_RETRIES) {
+			break;
+		}
+
+		/*
+		 * Wait for a while
+		 */
+		(void)poll(NULL, 0, BIND_RETRIES_INTERVAL * retries);
+	}
+	if (res == -1) {
 		return (-1);
 	}
 
@@ -1050,10 +1081,26 @@ static int totemudp_build_sockets_ip (
 	 */
 	totemip_totemip_to_sockaddr_convert(mcast_address,
 		instance->totem_interface->ip_port, &sockaddr, &addrlen);
-	res = bind (sockets->mcast_recv, (struct sockaddr *)&sockaddr, addrlen);
-	if (res == -1) {
+
+	retries = 0;
+	while (1) {
+		res = bind (sockets->mcast_recv, (struct sockaddr *)&sockaddr, addrlen);
+		if (res == 0) {
+			break;
+		}
 		LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
 				"Unable to bind the socket to receive multicast packets");
+		if (++retries > BIND_MAX_RETRIES) {
+			break;
+		}
+
+		/*
+		 * Wait for a while
+		 */
+		(void)poll(NULL, 0, BIND_RETRIES_INTERVAL * retries);
+	}
+
+	if (res == -1) {
 		return (-1);
 	}
 	return 0;
@@ -1088,6 +1135,13 @@ static int totemudp_build_sockets (
 	res = totemudp_build_sockets_ip (instance, mcast_address,
 		bindnet_address, sockets, bound_to, interface_num);
 
+	if (res == -1) {
+		/* if we get here, corosync won't work anyway, so better leaving than faking to work */
+		LOGSYS_PERROR (errno, instance->totemudp_log_level_error,
+			"Unable to create sockets, exiting");
+		exit(EXIT_FAILURE);
+	}
+
 	/* We only send out of the token socket */
 	totemudp_traffic_control_set(instance, sockets->token);
 	return res;

+ 24 - 2
exec/totemudpu.c

@@ -668,6 +668,7 @@ static int totemudpu_build_sockets_ip (
 	int res;
 	unsigned int recvbuf_size;
 	unsigned int optlen = sizeof (recvbuf_size);
+	unsigned int retries = 0;
 
 	/*
 	 * Setup unicast socket
@@ -692,10 +693,24 @@ static int totemudpu_build_sockets_ip (
 	 * This has the side effect of binding to the correct interface
 	 */
 	totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_interface->ip_port, &sockaddr, &addrlen);
-	res = bind (instance->token_socket, (struct sockaddr *)&sockaddr, addrlen);
-	if (res == -1) {
+	while (1) {
+		res = bind (instance->token_socket, (struct sockaddr *)&sockaddr, addrlen);
+		if (res == 0) {
+			break;
+		}
 		LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
 			"bind token socket failed");
+		if (++retries > BIND_MAX_RETRIES) {
+			break;
+		}
+
+		/*
+		 * Wait for a while
+		 */
+		(void)poll(NULL, 0, BIND_RETRIES_INTERVAL * retries);
+	}
+
+	if (res == -1) {
 		return (-1);
 	}
 
@@ -741,6 +756,13 @@ static int totemudpu_build_sockets (
 	res = totemudpu_build_sockets_ip (instance,
 		bindnet_address, bound_to, interface_num);
 
+	if (res == -1) {
+		/* if we get here, corosync won't work anyway, so better leaving than faking to work */
+		LOGSYS_PERROR (errno, instance->totemudpu_log_level_error,
+					"Unable to create sockets, exiting");
+		exit(EXIT_FAILURE);
+	}
+
 	/* We only send out of the token socket */
 	totemudpu_traffic_control_set(instance, instance->token_socket);
 

+ 3 - 0
include/corosync/totem/totem.h

@@ -52,6 +52,9 @@
 #define SEND_THREADS_MAX	16
 #define INTERFACE_MAX		2
 
+#define BIND_MAX_RETRIES	10
+#define BIND_RETRIES_INTERVAL	100
+
 /**
  * Maximum number of continuous gather states
  */