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

Allow AMF to handle health check responses while syncing.


git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1233 fd59a12c-fef9-0310-b244-a6a79926bd2f
Hans Feldt 19 лет назад
Родитель
Сommit
6e34536ead
1 измененных файлов с 53 добавлено и 12 удалено
  1. 53 12
      exec/amf.c

+ 53 - 12
exec/amf.c

@@ -304,7 +304,7 @@ static struct openais_lib_handler amf_lib_service[] =
 		.lib_handler_fn		= message_handler_req_lib_amf_response,
 		.lib_handler_fn		= message_handler_req_lib_amf_response,
 		.response_size		= sizeof (struct res_lib_amf_response),
 		.response_size		= sizeof (struct res_lib_amf_response),
 		.response_id		= MESSAGE_RES_AMF_RESPONSE,
 		.response_id		= MESSAGE_RES_AMF_RESPONSE,
-		.flow_control		= OPENAIS_FLOW_CONTROL_REQUIRED
+		.flow_control		= OPENAIS_FLOW_CONTROL_NOT_REQUIRED
 	},
 	},
 };
 };
 
 
@@ -2231,16 +2231,36 @@ static void message_handler_req_lib_amf_componenterrorclear (
 
 
 }
 }
 
 
+/**
+ * Handle a response from a component.
+ * 
+ * Healthcheck responses are handled locally and directly. This
+ * way we do not get healthcheck duration timeouts during e.g.
+ * AMF sync.
+ * 
+ * Other events need to be multicasted. If we are syncing, defer
+ * these event by returning TRY-AGAIN to the component.
+ * 
+ * No flow control was requested by AMF from the IPC layer (on
+ * purpose) for this lib handler. It is needed to handle
+ * healthcheck responses if it takes longer to sync than the
+ * duration period.
+ * 
+ * When multicasting, check for space in the TOTEM outbound
+ * queue and return TRY-AGAIN if the queue is full.
+ * 
+ * @param conn
+ * @param msg
+ */
 static void message_handler_req_lib_amf_response (void *conn, void *msg)
 static void message_handler_req_lib_amf_response (void *conn, void *msg)
 {
 {
+	struct res_lib_amf_response res_lib;
 	struct req_lib_amf_response *req_lib = msg;
 	struct req_lib_amf_response *req_lib = msg;
-	int multicast;
+	int multicast, send_ok;
 	SaAisErrorT retval;
 	SaAisErrorT retval;
 	SaUint32T interface;
 	SaUint32T interface;
 	SaNameT dn;
 	SaNameT dn;
 
 
-	assert (scsm.state == NORMAL_OPERATION);
-
 	/*
 	/*
 	* This is an optimisation to avoid multicast of healthchecks while keeping
 	* This is an optimisation to avoid multicast of healthchecks while keeping
 	* a nice design. We multicast and make lib responses from this file.
 	* a nice design. We multicast and make lib responses from this file.
@@ -2252,6 +2272,11 @@ static void message_handler_req_lib_amf_response (void *conn, void *msg)
 		struct req_exec_amf_response req_exec;
 		struct req_exec_amf_response req_exec;
 		struct iovec iovec;
 		struct iovec iovec;
 
 
+		if (scsm.state != NORMAL_OPERATION) {
+			retval = SA_AIS_ERR_TRY_AGAIN;
+			goto send_response;
+		}
+
 		req_exec.header.size = sizeof (struct req_exec_amf_response);
 		req_exec.header.size = sizeof (struct req_exec_amf_response);
 		req_exec.header.id = SERVICE_ID_MAKE (AMF_SERVICE,
 		req_exec.header.id = SERVICE_ID_MAKE (AMF_SERVICE,
 			MESSAGE_REQ_EXEC_AMF_RESPONSE);
 			MESSAGE_REQ_EXEC_AMF_RESPONSE);
@@ -2260,14 +2285,30 @@ static void message_handler_req_lib_amf_response (void *conn, void *msg)
 		req_exec.error = req_lib->error;
 		req_exec.error = req_lib->error;
 		iovec.iov_base = (char *)&req_exec;
 		iovec.iov_base = (char *)&req_exec;
 		iovec.iov_len = sizeof (req_exec);
 		iovec.iov_len = sizeof (req_exec);
-		assert (totempg_groups_mcast_joined (
-			openais_group_handle, &iovec, 1, TOTEMPG_AGREED) == 0);
-	} else {
-		struct res_lib_amf_response res_lib;
-		res_lib.header.id = MESSAGE_RES_AMF_RESPONSE;
-		res_lib.header.size = sizeof (struct res_lib_amf_response);
-		res_lib.header.error = retval;
-		openais_conn_send_response (conn, &res_lib, sizeof (res_lib));
+		send_ok = totempg_groups_send_ok_joined (openais_group_handle, &iovec, 1);
+
+		if (send_ok) {
+			if (totempg_groups_mcast_joined (
+				openais_group_handle, &iovec, 1, TOTEMPG_AGREED) == 0) {
+				goto end;
+			} else {
+				openais_exit_error (AIS_DONE_FATAL_ERR);
+			}
+		} else {
+			/* TOTEM queue is full, try again later */
+			retval = SA_AIS_ERR_TRY_AGAIN;
+		}
+	}
+
+send_response:
+	res_lib.header.id = MESSAGE_RES_AMF_RESPONSE;
+	res_lib.header.size = sizeof (struct res_lib_amf_response);
+	res_lib.header.error = retval;
+
+	if (openais_conn_send_response (conn, &res_lib, sizeof (res_lib)) != 0) {
+		openais_exit_error (AIS_DONE_FATAL_ERR);
 	}
 	}
+end:
+	return;
 }
 }