From 77e5525436c180d70d417425f33317afb909891b Mon Sep 17 00:00:00 2001 From: VilhoRaatikka Date: Thu, 14 Aug 2014 15:15:22 +0300 Subject: [PATCH] mysql_client.c:gw_error_client_event & gw_client_hangup_event: added session state check, if session is already closing, don't start redundant call to dcb_close. mysql_common.c:mysql_protocol_done: added protocol state check. Used not to check it which caused double free of allocated memory. --- server/core/dcb.c | 7 +++--- server/modules/protocol/mysql_backend.c | 25 +++++++++---------- server/modules/protocol/mysql_client.c | 14 +++++++++++ server/modules/protocol/mysql_common.c | 5 ++++ .../routing/readwritesplit/readwritesplit.c | 2 +- 5 files changed, 36 insertions(+), 17 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 1dfde0b58..090d57554 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -978,9 +978,10 @@ int below_water; } if (dolog) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Writing to %s socket failed due %d, %s.", + LOGIF(LD, (skygw_log_write( + LOGFILE_DEBUG, + "%lu [dcb_write] Writing to %s socket failed due %d, %s.", + pthread_self(), dcb_isclient(dcb) ? "client" : "backend server", saved_errno, strerror(saved_errno)))); diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index 903c17022..da00de083 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -777,11 +777,6 @@ static int gw_error_backend_event(DCB *dcb) router = session->service->router; router_instance = session->service->router_instance; -#if defined(SS_DEBUG) - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Backend error event handling."))); -#endif /** * Avoid running redundant error handling procedure. * dcb_close is already called for the DCB. Thus, either connection is @@ -820,6 +815,11 @@ static int gw_error_backend_event(DCB *dcb) goto retblock; } +#if defined(SS_DEBUG) + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Backend error event handling."))); +#endif router->handleError(router_instance, rsession, errbuf, @@ -963,14 +963,7 @@ gw_backend_hangup(DCB *dcb) rsession = session->router_session; router = session->service->router; - router_instance = session->service->router_instance; - -#if defined(SS_DEBUG) - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Backend hangup error handling."))); -#endif - + router_instance = session->service->router_instance; errbuf = mysql_create_custom_error( 1, @@ -999,6 +992,12 @@ gw_backend_hangup(DCB *dcb) gwbuf_free(errbuf); goto retblock; } +#if defined(SS_DEBUG) + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Backend hangup error handling."))); +#endif + router->handleError(router_instance, rsession, errbuf, diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index fbe0589a5..0f243fb1d 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -1300,12 +1300,19 @@ static int gw_error_client_event( STRDCBSTATE(dcb->state), (session != NULL ? session : NULL)))); + if (session != NULL && session->state == SESSION_STATE_STOPPING) + { + goto retblock; + } + #if defined(SS_DEBUG) LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Client error event handling."))); #endif dcb_close(dcb); + +retblock: return 1; } @@ -1380,12 +1387,19 @@ gw_client_hangup_event(DCB *dcb) { CHK_SESSION(session); } + + if (session != NULL && session->state == SESSION_STATE_STOPPING) + { + goto retblock; + } #if defined(SS_DEBUG) LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Client hangup error handling."))); #endif dcb_close(dcb); + +retblock: return 1; } diff --git a/server/modules/protocol/mysql_common.c b/server/modules/protocol/mysql_common.c index ef9991554..cd1e5c5f9 100644 --- a/server/modules/protocol/mysql_common.c +++ b/server/modules/protocol/mysql_common.c @@ -117,6 +117,10 @@ void mysql_protocol_done ( spinlock_acquire(&p->protocol_lock); + if (p->protocol_state != MYSQL_PROTOCOL_ACTIVE) + { + goto retblock; + } scmd = p->protocol_cmd_history; while (scmd != NULL) @@ -127,6 +131,7 @@ void mysql_protocol_done ( } p->protocol_state = MYSQL_PROTOCOL_DONE; +retblock: spinlock_release(&p->protocol_lock); } diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index c10aca134..f09b29ae5 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -1548,7 +1548,7 @@ static void clientReply ( (uint8_t *)GWBUF_DATA((scur->scmd_cur_cmd->my_sescmd_buf)); size_t len = MYSQL_GET_PACKET_LEN(buf); char* cmdstr = (char *)malloc(len+1); - + /** data+termination character == len */ snprintf(cmdstr, len, "%s", &buf[5]); LOGIF(LE, (skygw_log_write_flush(