diff --git a/server/core/gateway.c b/server/core/gateway.c index b558dd0d4..80cfa6ff5 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -216,7 +216,7 @@ memset(dcb_fake_write_errno, 0, sizeof(unsigned char)*1024); memset(dcb_fake_write_ev, 0, sizeof(__int32_t)*1024); fail_next_backend_fd = false; fail_next_client_fd = false; -fail_next_accept = false; +fail_next_accept = 0; fail_accept_errno = 0; #endif l = atexit(skygw_logmanager_exit); diff --git a/server/include/dcb.h b/server/include/dcb.h index 84725dcfc..3cd8d6a11 100644 --- a/server/include/dcb.h +++ b/server/include/dcb.h @@ -190,7 +190,7 @@ unsigned char dcb_fake_write_errno[1024]; __int32_t dcb_fake_write_ev[1024]; bool fail_next_backend_fd; bool fail_next_client_fd; -bool fail_next_accept; +int fail_next_accept; int fail_accept_errno; #endif diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index 8d7a3e57d..be90519bd 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -921,19 +921,23 @@ int gw_MySQLAccept(DCB *listener) while (1) { retry_accept: - // new connection from client - c_sock = accept(listener->fd, - (struct sockaddr *) &local, - &addrlen); - eno = errno; #if defined(SS_DEBUG) - if (fail_next_accept) { + if (fail_next_accept > 0) + { c_sock = -1; eno = fail_accept_errno; - i = 10; - fail_next_accept = false; - fail_accept_errno = 0; + fail_next_accept -= 1; + } else { + fail_accept_errno = 0; +#endif /* SS_DEBUG */ + // new connection from client + c_sock = accept(listener->fd, + (struct sockaddr *) &local, + &addrlen); + eno = errno; + errno = 0; +#if defined(SS_DEBUG) } #endif /* SS_DEBUG */ @@ -946,10 +950,11 @@ int gw_MySQLAccept(DCB *listener) /* We have processed all incoming connections. */ break; } - else if (eno == ENFILE) + else if (eno == ENFILE || eno == EMFILE) { /** - * Exceeded system's max. number of files limit. + * Exceeded system's (ENFILE) or processes + * (EMFILE) max. number of files limit. */ skygw_log_write_flush( LOGFILE_ERROR, @@ -966,26 +971,6 @@ int gw_MySQLAccept(DCB *listener) rc = 1; goto return_rc; } - else if (eno == EMFILE) - { - /** - * Exceeded processes max. number of files limit. - */ - skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [gw_MySQLAccept] Error %d, %s.", - pthread_self(), - eno, - strerror(eno)); - i++; - usleep(100*i*i); - - if (i<10) { - goto retry_accept; - } - rc = 1; - goto return_rc; - } else { /** diff --git a/server/modules/routing/debugcmd.c b/server/modules/routing/debugcmd.c index 348dec469..a4491eb41 100644 --- a/server/modules/routing/debugcmd.c +++ b/server/modules/routing/debugcmd.c @@ -233,7 +233,7 @@ struct subcommand disableoptions[] = { static void fail_backendfd(void); static void fail_clientfd(void); -static void fail_accept(DCB* dcb, char* arg1); +static void fail_accept(DCB* dcb, char* arg1, char* arg2); /** * * The subcommands of the fail command * */ @@ -254,10 +254,10 @@ struct subcommand failoptions[] = { }, { "accept", - 1, + 2, fail_accept, "Fail to accept next client connection.", - {ARG_TYPE_STRING, 0, 0} + {ARG_TYPE_STRING, ARG_TYPE_STRING, 0} }, { NULL, @@ -775,10 +775,13 @@ static void fail_clientfd(void) static void fail_accept( DCB* dcb, - char* arg1) + char* arg1, + char* arg2) { + int failcount = MIN(atoi(arg2), 100); fail_accept_errno = atoi(arg1); + switch(fail_accept_errno) { case EAGAIN: // case EWOULDBLOCK: @@ -792,7 +795,7 @@ static void fail_accept( case ENOBUFS: case ENOMEM: case EPROTO: - fail_next_accept = true; + fail_next_accept = failcount; break; default: