From f5ed8e84a50b27135ed30e7662a29cf0a071244e Mon Sep 17 00:00:00 2001 From: Rich Megginson Date: Jul 08 2011 21:20:35 +0000 Subject: Bug 709468 - RSA Authentication Server timeouts when using simple paged results on RHDS 8.2. https://bugzilla.redhat.com/show_bug.cgi?id=709468 Resolves: bug 709468 Bug Description: RSA Authentication Server timeouts when using simple paged results on RHDS 8.2. Reviewed by: nkinder, nhosoi (Thanks!) Branch: Directory_Server_8_2_Branch Fix Description: When returning the last page of the last result set, in the searchResultDone message, the paged results cookie is set to NULL. This means the client cannot issue another search using this result set/cookie, which means the server can free/reset the simple paged resources associated with this result set. Use pagedresults_cleanup() to do this. Since before it was assumed pagedresults_cleanup was called with the connection lock, a new parameter tells it if it needs to lock or not. Platforms tested: RHEL6 x86_64 Flag Day: no Doc impact: no --- diff --git a/ldap/servers/slapd/abandon.c b/ldap/servers/slapd/abandon.c index 4e87a71..8870364 100644 --- a/ldap/servers/slapd/abandon.c +++ b/ldap/servers/slapd/abandon.c @@ -152,7 +152,12 @@ do_abandon( Slapi_PBlock *pb ) 0 ); } - if ( NULL == o ) { + if (pagedresults_cleanup(pb->pb_conn, 0 /* already locked */)) { + /* Cleaned up paged result connection */ + slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d ABANDON" + " targetop=Simple Paged Results\n", + pb->pb_conn->c_connid, pb->pb_op->o_opid ); + } else if ( NULL == o ) { slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d ABANDON" " targetop=NOTFOUND msgid=%d\n", pb->pb_conn->c_connid, pb->pb_op->o_opid, id ); diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c index 768f959..ec2b6bd 100644 --- a/ldap/servers/slapd/connection.c +++ b/ldap/servers/slapd/connection.c @@ -200,16 +200,7 @@ connection_cleanup(Connection *conn) /* destroy any sasl context */ sasl_dispose((sasl_conn_t**)&conn->c_sasl_conn); /* PAGED_RESULTS */ - if (conn->c_search_result_set) { - if (conn->c_current_be->be_search_results_release) { - conn->c_current_be->be_search_results_release(&(conn->c_search_result_set)); - } - conn->c_search_result_set = NULL; - } - conn->c_current_be = NULL; - conn->c_search_result_count = 0; - conn->c_timelimit = 0; - /* PAGED_RESULTS ENDS */ + pagedresults_cleanup(conn, 0 /* do not need to lock inside */); /* free the connection socket buffer */ connection_free_private_buffer(conn); @@ -2723,6 +2714,9 @@ disconnect_server_nomutex( Connection *conn, PRUint64 opconnid, int opid, PRErro conn->c_gettingber = 0; connection_abandon_operations( conn ); + pagedresults_cleanup(conn, 0 /* already locked */); /* In case the connection is on pagedresult. + Better to call it after the op is abandened. */ + if (! config_check_referral_mode()) { /* * If any of the outstanding operations on this diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c index 08243dd..2761886 100644 --- a/ldap/servers/slapd/opshared.c +++ b/ldap/servers/slapd/opshared.c @@ -587,6 +587,9 @@ op_shared_search (Slapi_PBlock *pb, int send_result) sort_make_sort_response_control(pb, CONN_GET_SORT_RESULT_CODE, NULL); } next_be = NULL; /* to break the loop */ + if (curr_search_count == -1) { + pagedresults_cleanup(pb->pb_conn, 1 /* need to lock */); + } } else { /* be_suffix null means that we are searching the default backend * -> don't change the search parameters in pblock @@ -725,6 +728,9 @@ op_shared_search (Slapi_PBlock *pb, int send_result) pagesize, curr_search_count); slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, NULL ); next_be = NULL; /* to break the loop */ + if (curr_search_count == -1) { + pagedresults_cleanup(pb->pb_conn, 1 /* need to lock */); + } } /* if rc != 0 an error occurred while sending back the entries diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c index 919dd4c..270a074 100644 --- a/ldap/servers/slapd/pagedresults.c +++ b/ldap/servers/slapd/pagedresults.c @@ -314,6 +314,39 @@ pagedresults_set_timelimit(Connection *conn, time_t timelimit) } /* + * must be called with conn->c_mutex held + * return values + * 0: not a simple paged result connection + * 1: simple paged result and successfully abandoned + */ +int +pagedresults_cleanup(Connection *conn, int needlock) +{ + int rc = 0; + + if (needlock) { + PR_Lock(conn->c_mutex); + } + if (conn->c_current_be) { + if (conn->c_search_result_set) { + if (conn->c_current_be->be_search_results_release) { + conn->c_current_be->be_search_results_release(&(conn->c_search_result_set)); + } + conn->c_search_result_set = NULL; + } + conn->c_current_be = 0; + rc = 1; + } + conn->c_search_result_count = 0; + conn->c_timelimit = 0; + conn->c_flags &= ~CONN_FLAG_PAGEDRESULTS_PROCESSING; + if (needlock) { + PR_Unlock(conn->c_mutex); + } + return rc; +} + +/* * check to see if this connection is currently processing * a pagedresults search - if it is, return True - if not, * mark that it is processing, and return False diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h index f11565c..2c85b20 100644 --- a/ldap/servers/slapd/proto-slap.h +++ b/ldap/servers/slapd/proto-slap.h @@ -1349,6 +1349,7 @@ int pagedresults_set_with_sort(Connection *conn, int flags); int pagedresults_get_sort_result_code(Connection *conn); int pagedresults_set_sort_result_code(Connection *conn, int code); int pagedresults_set_timelimit(Connection *conn, time_t timelimit); +int pagedresults_cleanup(Connection *conn, int needlock); int pagedresults_check_or_set_processing(Connection *conn); int pagedresults_reset_processing(Connection *conn);