Răsfoiți Sursa

Support for lib_cpg_finalize

Add support for MESSAGE_REQ_CPG_FINALIZE message. This will allow us
remove cpg_pd from list of active connections, and remove problem, when
cpg_finalize + cpg_initialize + cpg_join can result in CPG_ERR_EXIST
error.


git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2676 fd59a12c-fef9-0310-b244-a6a79926bd2f
Jan Friesse 16 ani în urmă
părinte
comite
009dfc090e
3 a modificat fișierele cu 70 adăugiri și 1 ștergeri
  1. 11 1
      include/corosync/ipc_cpg.h
  2. 27 0
      lib/cpg.c
  3. 32 0
      services/cpg.c

+ 11 - 1
include/corosync/ipc_cpg.h

@@ -47,7 +47,8 @@ enum req_cpg_types {
 	MESSAGE_REQ_CPG_LOCAL_GET = 4,
 	MESSAGE_REQ_CPG_ITERATIONINITIALIZE = 5,
 	MESSAGE_REQ_CPG_ITERATIONNEXT = 6,
-	MESSAGE_REQ_CPG_ITERATIONFINALIZE = 7
+	MESSAGE_REQ_CPG_ITERATIONFINALIZE = 7,
+	MESSAGE_REQ_CPG_FINALIZE = 8
 };
 
 enum res_cpg_types {
@@ -63,6 +64,7 @@ enum res_cpg_types {
 	MESSAGE_RES_CPG_ITERATIONINITIALIZE = 9,
 	MESSAGE_RES_CPG_ITERATIONNEXT = 10,
 	MESSAGE_RES_CPG_ITERATIONFINALIZE = 11,
+	MESSAGE_RES_CPG_FINALIZE = 12,
 };
 
 enum lib_cpg_confchg_reason {
@@ -157,6 +159,14 @@ struct res_lib_cpg_join {
 	coroipc_response_header_t header __attribute__((aligned(8)));
 };
 
+struct req_lib_cpg_finalize {
+	coroipc_request_header_t header __attribute__((aligned(8)));
+};
+
+struct res_lib_cpg_finalize {
+	coroipc_response_header_t header __attribute__((aligned(8)));
+};
+
 struct req_lib_cpg_trackstart {
 	coroipc_request_header_t header __attribute__((aligned(8)));
 	mar_cpg_name_t group_name __attribute__((aligned(8)));

+ 27 - 0
lib/cpg.c

@@ -164,6 +164,9 @@ cs_error_t cpg_finalize (
 	cpg_handle_t handle)
 {
 	struct cpg_inst *cpg_inst;
+	struct iovec iov;
+	struct req_lib_cpg_finalize req_lib_cpg_finalize;
+	struct res_lib_cpg_finalize res_lib_cpg_finalize;
 	cs_error_t error;
 
 	error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
@@ -181,12 +184,36 @@ cs_error_t cpg_finalize (
 
 	cpg_inst->finalize = 1;
 
+	/*
+	 * Send service request
+	 */
+	req_lib_cpg_finalize.header.size = sizeof (struct req_lib_cpg_finalize);
+	req_lib_cpg_finalize.header.id = MESSAGE_REQ_CPG_FINALIZE;
+
+	iov.iov_base = (void *)&req_lib_cpg_finalize;
+	iov.iov_len = sizeof (struct req_lib_cpg_finalize);
+
+	error = coroipcc_msg_send_reply_receive (cpg_inst->handle,
+		&iov,
+		1,
+		&res_lib_cpg_finalize,
+		sizeof (struct req_lib_cpg_finalize));
+
+	if (error != CS_OK) {
+		goto error_put;
+	}
+
 	coroipcc_service_disconnect (cpg_inst->handle);
 
 	cpg_inst_finalize (cpg_inst, handle);
 	hdb_handle_put (&cpg_handle_t_db, handle);
 
 	return (CPG_OK);
+
+error_put:
+	hdb_handle_put (&cpg_iteration_handle_t_db, handle);
+	cpg_inst->finalize = 0;
+	return (error);
 }
 
 cs_error_t cpg_fd_get (

+ 32 - 0
services/cpg.c

@@ -214,6 +214,8 @@ static void message_handler_req_lib_cpg_join (void *conn, const void *message);
 
 static void message_handler_req_lib_cpg_leave (void *conn, const void *message);
 
+static void message_handler_req_lib_cpg_finalize (void *conn, const void *message);
+
 static void message_handler_req_lib_cpg_mcast (void *conn, const void *message);
 
 static void message_handler_req_lib_cpg_membership (void *conn,
@@ -290,6 +292,10 @@ static struct corosync_lib_handler cpg_lib_engine[] =
 		.lib_handler_fn				= message_handler_req_lib_cpg_iteration_finalize,
 		.flow_control				= CS_LIB_FLOW_CONTROL_NOT_REQUIRED
 	},
+	{ /* 8 */
+		.lib_handler_fn				= message_handler_req_lib_cpg_finalize,
+		.flow_control				= CS_LIB_FLOW_CONTROL_REQUIRED
+	},
 };
 
 static struct corosync_exec_handler cpg_exec_engine[] =
@@ -1149,6 +1155,32 @@ static void message_handler_req_lib_cpg_leave (void *conn, const void *message)
 	api->ipc_response_send(conn, &res_lib_cpg_leave, sizeof(res_lib_cpg_leave));
 }
 
+/* Finalize message from library */
+static void message_handler_req_lib_cpg_finalize (
+	void *conn,
+	const void *message)
+{
+	struct cpg_pd *cpd = (struct cpg_pd *)api->ipc_private_data_get (conn);
+	struct res_lib_cpg_finalize res_lib_cpg_finalize;
+	cs_error_t error = CS_OK;
+
+	log_printf (LOGSYS_LEVEL_DEBUG, "cpg finalize for conn=%p\n", conn);
+
+	/*
+	 * We will just remove cpd from list. After this call, connection will be
+	 * closed on lib side, and cpg_lib_exit_fn will be called
+	 */
+	list_del (&cpd->list);
+	list_init (&cpd->list);
+
+	res_lib_cpg_finalize.header.size = sizeof (res_lib_cpg_finalize);
+	res_lib_cpg_finalize.header.id = MESSAGE_RES_CPG_FINALIZE;
+	res_lib_cpg_finalize.header.error = error;
+
+	api->ipc_response_send (conn, &res_lib_cpg_finalize,
+		sizeof (res_lib_cpg_finalize));
+}
+
 /* Mcast message from the library */
 static void message_handler_req_lib_cpg_mcast (void *conn, const void *message)
 {