From 009dfc090e25d09163af7c6d58717bb4f311709b Mon Sep 17 00:00:00 2001 From: Jan Friesse Date: Thu, 4 Mar 2010 12:17:47 +0000 Subject: [PATCH] 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 --- include/corosync/ipc_cpg.h | 12 +++++++++++- lib/cpg.c | 27 +++++++++++++++++++++++++++ services/cpg.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/include/corosync/ipc_cpg.h b/include/corosync/ipc_cpg.h index 7df1891a..8f55ae8b 100644 --- a/include/corosync/ipc_cpg.h +++ b/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))); diff --git a/lib/cpg.c b/lib/cpg.c index 780e79f5..79836e44 100644 --- a/lib/cpg.c +++ b/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 ( diff --git a/services/cpg.c b/services/cpg.c index af5f6c4e..7b57d577 100644 --- a/services/cpg.c +++ b/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) {