diff options
author | Rich Megginson <rmeggins@redhat.com> | 2010-07-16 14:26:19 -0600 |
---|---|---|
committer | Rich Megginson <rmeggins@redhat.com> | 2010-07-16 15:26:33 -0600 |
commit | 9d638b3fc25fbc57884a511744943499c7102f40 (patch) | |
tree | 13ac240d9a6ba45a886cae172c1ed218df9e20d0 | |
parent | 7b232907ffa20206c57e362cd8278eaefa7948d4 (diff) | |
download | ds-9d638b3fc25fbc57884a511744943499c7102f40.tar.gz ds-9d638b3fc25fbc57884a511744943499c7102f40.tar.xz ds-9d638b3fc25fbc57884a511744943499c7102f40.zip |
Bug 547503 - replication broken again, with 389 MMR replication and TCP errors
https://bugzilla.redhat.com/show_bug.cgi?id=547503
Resolves: bug 547503
Bug Description: replication broken again, with 389 MMR replication and TCP errors
Reviewed by: nhosoi (Thanks!)
Branch: 389-ds-base-1.2.6
Fix Description: When turbo mode is used for the connection, the server does
not poll for read ready status in the main loop, nor go through the code in
handle_pr_read_ready that updates conn->c_idlesince. So while the conn is in
turbo mode, the c_idlesince is not updated. If the conn gets a timeout while
reading, a flag will be set on the connection that will put it back in the
main loop. When it then hits handle_pr_read_ready, if there is still no
activity on the connection, it will go through idle timeout processing. It
may have been a long time since c_idlesince was updated, so the connection
may be closed wrongly.
The solution is to have c_idlesince updated in connection_threadmain() in
turbo mode if the connection really isn't idle.
In addition, the conn private turbo_mode flag was not being used correctly -
in the timeout case, the local variable was being updated but not the
conn private turbo_flag. Since the conn private turbo_flag is not used
anywhere else, it can be removed, and just use the local variable.
Platforms tested: RHEL5 x86_64
Flag Day: no
Doc impact: no
-rw-r--r-- | ldap/servers/slapd/connection.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c index cf88a590..d2a5eb43 100644 --- a/ldap/servers/slapd/connection.c +++ b/ldap/servers/slapd/connection.c @@ -1527,7 +1527,6 @@ static int counter= 0; /* JCM Dumb Name */ /* The connection private structure for UNIX turbo mode */ struct Conn_private { - int turbo_flag; /* set if we are currently in turbo mode */ int previous_op_count; /* the operation counter value last time we sampled it, used to compute operation rate */ int operation_rate; /* rate (ops/sample period) at which this connection has been processing operations */ time_t previous_count_check_time; /* The wall clock time we last sampled the operation count */ @@ -2062,7 +2061,7 @@ void connection_find_our_rank(Connection *conn,int *connection_count, int *our_r /* * Evaluate the turbo policy for this connection */ -void connection_enter_leave_turbo(Connection *conn, int *new_turbo_flag) +void connection_enter_leave_turbo(Connection *conn, int current_turbo_flag, int *new_turbo_flag) { int current_mode = 0; int new_mode = 0; @@ -2071,7 +2070,7 @@ void connection_enter_leave_turbo(Connection *conn, int *new_turbo_flag) int threshold_rank = 0; PR_Lock(conn->c_mutex); /* We can already be in turbo mode, or not */ - current_mode = conn->c_private->turbo_flag; + current_mode = current_turbo_flag; if (conn->c_search_result_set) { /* PAGED_RESULTS does not need turbo mode */ new_mode = 0; @@ -2125,7 +2124,6 @@ void connection_enter_leave_turbo(Connection *conn, int *new_turbo_flag) } } } - conn->c_private->turbo_flag = new_mode; PR_Unlock(conn->c_mutex); if (current_mode != new_mode) { if (current_mode) { @@ -2158,6 +2156,7 @@ connection_threadmain() while (1) { int is_timedout = 0; + time_t curtime = 0; if( op_shutdown ) { LDAPDebug( LDAP_DEBUG_TRACE, @@ -2218,15 +2217,16 @@ connection_threadmain() more_data = 0; ret = connection_read_operation(conn,op,&tag,&more_data); + curtime = current_time(); #define DB_PERF_TURBO 1 #if defined(DB_PERF_TURBO) /* If it's been a while since we last did it ... */ - if (current_time() - conn->c_private->previous_count_check_time > CONN_TURBO_CHECK_INTERVAL) { + if (curtime - conn->c_private->previous_count_check_time > CONN_TURBO_CHECK_INTERVAL) { int new_turbo_flag = 0; /* Check the connection's activity level */ connection_check_activity_level(conn); /* And if appropriate, change into or out of turbo mode */ - connection_enter_leave_turbo(conn,&new_turbo_flag); + connection_enter_leave_turbo(conn,thread_turbo_flag,&new_turbo_flag); thread_turbo_flag = new_turbo_flag; } @@ -2248,6 +2248,7 @@ connection_threadmain() * should call connection_make_readable after the op is removed * connection_make_readable(conn); */ + LDAPDebug(LDAP_DEBUG_CONNS,"conn %" NSPRIu64 " leaving turbo mode due to %d\n",conn->c_connid,ret,0); goto done; case CONN_SHUTDOWN: LDAPDebug( LDAP_DEBUG_TRACE, @@ -2258,6 +2259,14 @@ connection_threadmain() break; } + /* if we got here, then we had some read activity */ + if (thread_turbo_flag) { + /* turbo mode avoids handle_pr_read_ready which avoids setting c_idlesince + update c_idlesince here since, if we got some read activity, we are + not idle */ + conn->c_idlesince = curtime; + } + /* * Do not put the connection back to the read ready poll list * if the operation is unbind. Unbind will close the socket. |