Branch '389-ds-base-1.3.3' - ldap/servers
by Noriko Hosoi
ldap/servers/slapd/opshared.c | 41 ++++++--------
ldap/servers/slapd/pagedresults.c | 110 ++++++++++++++++++++++++--------------
2 files changed, 89 insertions(+), 62 deletions(-)
New commits:
commit 97c707df4e11936202310e99bcf5f45d15b49f0f
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Thu Jun 4 16:27:05 2015 -0700
Ticket #48192 - Individual abandoned simple paged results request has no chance to be cleaned up
Description: When allocating a slot in simple paged results array stashed
in a connection in pagedresults_parse_control_value, a new code is added
to scan the array if the existing slot is timed out or not. If it is, the
slot is released and a search results is released if it is attached.
Also, if a request is abandoned, instead of returning a valid cookie, it
changed to return an empty cookie to inform the client the request was not
successfully completed.
https://fedorahosted.org/389/ticket/48192
Reviewed by rmeggins(a)redhat.com (Thank you, Rich!!)
(cherry picked from commit f3c3125fc9fd4dc1cbd41027d6442cb525efd014)
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
index fa88053..1623fb0 100644
--- a/ldap/servers/slapd/opshared.c
+++ b/ldap/servers/slapd/opshared.c
@@ -517,8 +517,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
rc = pagedresults_parse_control_value(pb, ctl_value, &pagesize, &pr_idx, be);
/* Let's set pr_idx even if it fails; in case, pr_idx == -1. */
slapi_pblock_set(pb, SLAPI_PAGED_RESULTS_INDEX, &pr_idx);
- if ((LDAP_SUCCESS == rc) ||
- (LDAP_CANCELLED == rc) || (0 == pagesize)) {
+ if ((LDAP_SUCCESS == rc) || (LDAP_CANCELLED == rc) || (0 == pagesize)) {
unsigned int opnote = SLAPI_OP_NOTE_SIMPLEPAGED;
op_set_pagedresults(operation);
pr_be = pagedresults_get_current_be(pb->pb_conn, pr_idx);
@@ -545,9 +544,8 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
}
slapi_pblock_set( pb, SLAPI_OPERATION_NOTES, &opnote );
if ((LDAP_CANCELLED == rc) || (0 == pagesize)) {
- /* paged-results-request was abandoned */
- pagedresults_set_response_control(pb, 0, estimate,
- curr_search_count, pr_idx);
+ /* paged-results-request was abandoned; making an empty cookie. */
+ pagedresults_set_response_control(pb, 0, estimate, -1, pr_idx);
send_ldap_result(pb, 0, NULL,
"Simple Paged Results Search abandoned",
0, NULL);
@@ -574,10 +572,21 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
/* adjust time and size limits */
compute_limits (pb);
-
- /* call the pre-search plugins. if they succeed, call the backend
- search function. then call the post-search plugins. */
+ /* set the timelimit to clean up the too-long-lived-paged results requests */
+ if (op_is_pagedresults(operation)) {
+ time_t optime, time_up;
+ int tlimit;
+ slapi_pblock_get( pb, SLAPI_SEARCH_TIMELIMIT, &tlimit );
+ slapi_pblock_get( pb, SLAPI_OPINITIATED_TIME, &optime );
+ time_up = (tlimit==-1 ? -1 : optime + tlimit); /* -1: no time limit */
+ pagedresults_set_timelimit(pb->pb_conn, pb->pb_op, time_up, pr_idx);
+ }
+
+ /*
+ * call the pre-search plugins. if they succeed, call the backend
+ * search function. then call the post-search plugins.
+ */
/* ONREPL - should regular plugin be called for internal searches ? */
if (plugin_call_plugins(pb, SLAPI_PLUGIN_PRE_SEARCH_FN) == 0)
{
@@ -642,16 +651,6 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
}
}
- /* set the timelimit to clean up the too-long-lived-paged results requests */
- if (op_is_pagedresults(operation)) {
- time_t optime, time_up;
- int tlimit;
- slapi_pblock_get( pb, SLAPI_SEARCH_TIMELIMIT, &tlimit );
- slapi_pblock_get( pb, SLAPI_OPINITIATED_TIME, &optime );
- time_up = (tlimit==-1 ? -1 : optime + tlimit); /* -1: no time limit */
- pagedresults_set_timelimit(pb->pb_conn, pb->pb_op, time_up, pr_idx);
- }
-
/* PAR: now filters have been rewritten, we can assign plugins to work on them */
index_subsys_assign_filter_decoders(pb);
@@ -880,10 +879,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &sr);
if (PAGEDRESULTS_SEARCH_END == pr_stat) {
if (sr) { /* in case a left over sr is found, clean it up */
- PR_Lock(pb->pb_conn->c_mutex);
- pagedresults_set_search_result(pb->pb_conn, operation, NULL, 1, pr_idx);
- be->be_search_results_release(&sr);
- PR_Unlock(pb->pb_conn->c_mutex);
+ pagedresults_free_one(pb->pb_conn, operation, pr_idx);
}
if (NULL == next_be) {
/* no more entries && no more backends */
@@ -1306,7 +1302,6 @@ iterate(Slapi_PBlock *pb, Slapi_Backend *be, int send_result,
operation_out_of_disk_space();
}
pr_stat = PAGEDRESULTS_SEARCH_END;
- pagedresults_set_timelimit(pb->pb_conn, pb->pb_op, 0, pr_idx);
rval = -1;
done = 1;
continue;
diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c
index 327da54..402dd10 100644
--- a/ldap/servers/slapd/pagedresults.c
+++ b/ldap/servers/slapd/pagedresults.c
@@ -41,6 +41,27 @@
#include "slap.h"
+/* helper function to clean up one prp slot */
+static void
+_pr_cleanup_one_slot(PagedResults *prp)
+{
+ PRLock *prmutex = NULL;
+ if (!prp) {
+ return;
+ }
+ if (prp->pr_current_be && prp->pr_current_be->be_search_results_release) {
+ /* sr is left; release it. */
+ prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set));
+ }
+ /* clean up the slot */
+ if (prp->pr_mutex) {
+ /* pr_mutex is reused; back it up and reset it. */
+ prmutex = prp->pr_mutex;
+ }
+ memset(prp, '\0', sizeof(PagedResults));
+ prp->pr_mutex = prmutex;
+}
+
/*
* Parse the value from an LDAPv3 "Simple Paged Results" control. They look
* like this:
@@ -65,6 +86,7 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
Connection *conn = pb->pb_conn;
Operation *op = pb->pb_op;
BerElement *ber = NULL;
+ PagedResults *prp = NULL;
LDAPDebug0Args(LDAP_DEBUG_TRACE, "--> pagedresults_parse_control_value\n");
if ( NULL == conn || NULL == op || NULL == pagesize || NULL == index ) {
@@ -117,13 +139,31 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
}
*index = maxlen; /* the first position in the new area */
} else {
- for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) {
- if (!conn->c_pagedresults.prl_list[i].pr_current_be) {
- conn->c_pagedresults.prl_list[i].pr_current_be = be;
+ time_t ctime = current_time();
+ prp = conn->c_pagedresults.prl_list;
+ for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++, prp++) {
+ if (!prp->pr_current_be) { /* unused slot; take it */
+ prp->pr_current_be = be;
+ *index = i;
+ break;
+ } else if (((prp->pr_timelimit > 0) && (ctime < prp->pr_timelimit)) || /* timelimit exceeded */
+ (prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED) /* abandoned */) {
+ _pr_cleanup_one_slot(prp);
+ conn->c_pagedresults.prl_count--;
+ prp->pr_current_be = be;
*index = i;
break;
}
}
+ /* cleaning up the rest of the timedout if any */
+ for (++i; i < conn->c_pagedresults.prl_maxlen; i++, prp++) {
+ if (prp->pr_current_be &&
+ (((prp->pr_timelimit > 0) && (ctime < prp->pr_timelimit)) || /* timelimit exceeded */
+ (prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED)) /* abandoned */) {
+ _pr_cleanup_one_slot(prp);
+ conn->c_pagedresults.prl_count--;
+ }
+ }
}
if ((*index > -1) && (*index < conn->c_pagedresults.prl_maxlen) &&
!conn->c_pagedresults.prl_list[*index].pr_mutex) {
@@ -131,7 +171,6 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
}
conn->c_pagedresults.prl_count++;
} else {
- PagedResults *prp = NULL;
/* Repeated paged results request.
* PagedResults is already allocated. */
char *ptr = slapi_ch_malloc(cookie.bv_len + 1);
@@ -156,8 +195,10 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
slapi_ch_free((void **)&cookie.bv_val);
if ((*index > -1) && (*index < conn->c_pagedresults.prl_maxlen)) {
- if (conn->c_pagedresults.prl_list[*index].pr_flags &
- CONN_FLAG_PAGEDRESULTS_ABANDONED) {
+ if (conn->c_pagedresults.prl_list[*index].pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED) {
+ /* repeated case? */
+ prp = conn->c_pagedresults.prl_list + *index;
+ _pr_cleanup_one_slot(prp);
rc = LDAP_CANCELLED;
} else {
/* Need to keep the latest msgid to prepare for the abandon. */
@@ -273,20 +314,8 @@ pagedresults_free_one( Connection *conn, Operation *op, int index )
"conn=%d paged requests list count is %d\n",
conn->c_connid, conn->c_pagedresults.prl_count);
} else if (index < conn->c_pagedresults.prl_maxlen) {
- PRLock *prmutex = NULL;
PagedResults *prp = conn->c_pagedresults.prl_list + index;
- if (prp && prp->pr_current_be &&
- prp->pr_current_be->be_search_results_release &&
- prp->pr_search_result_set) {
- prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set));
- }
- prp->pr_current_be = NULL;
- if (prp->pr_mutex) {
- /* pr_mutex is reused; back it up and reset it. */
- prmutex = prp->pr_mutex;
- }
- memset(prp, '\0', sizeof(PagedResults));
- prp->pr_mutex = prmutex;
+ _pr_cleanup_one_slot(prp);
conn->c_pagedresults.prl_count--;
rc = 0;
}
@@ -309,7 +338,7 @@ pagedresults_free_one_msgid_nolock( Connection *conn, ber_int_t msgid )
; /* Not a paged result. */
} else {
LDAPDebug1Arg(LDAP_DEBUG_TRACE,
- "--> pagedresults_free_one: msgid=%d\n", msgid);
+ "--> pagedresults_free_one_msgid_nolock: msgid=%d\n", msgid);
for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) {
if (conn->c_pagedresults.prl_list[i].pr_msgid == msgid) {
PagedResults *prp = conn->c_pagedresults.prl_list + i;
@@ -318,16 +347,14 @@ pagedresults_free_one_msgid_nolock( Connection *conn, ber_int_t msgid )
prp->pr_search_result_set) {
prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set));
}
- prp->pr_current_be = NULL;
prp->pr_flags |= CONN_FLAG_PAGEDRESULTS_ABANDONED;
prp->pr_flags &= ~CONN_FLAG_PAGEDRESULTS_PROCESSING;
- conn->c_pagedresults.prl_count--;
rc = 0;
break;
}
}
LDAPDebug1Arg(LDAP_DEBUG_TRACE,
- "<-- pagedresults_free_one: %d\n", rc);
+ "<-- pagedresults_free_one_msgid_nolock: %d\n", rc);
}
}
@@ -845,37 +872,42 @@ pagedresults_reset_processing(Connection *conn, int index)
}
#endif
-/* Are all the paged results requests timed out? */
+/*
+ * This timedout is mainly for an end user leaves a commandline untouched
+ * for a long time. This should not affect a permanent connection which
+ * manages multiple simple paged results requests over the connection.
+ *
+ * [rule]
+ * If there is just one slot and it's timed out, we return it is timedout.
+ * If there are multiple slots, the connection may be a permanent one.
+ * Do not return timed out here. But let the next request take care the
+ * timedout slot(s).
+ */
int
pagedresults_is_timedout_nolock(Connection *conn)
{
- int i;
PagedResults *prp = NULL;
time_t ctime;
- int rc = 0;
LDAPDebug0Args(LDAP_DEBUG_TRACE, "--> pagedresults_is_timedout\n");
- if (NULL == conn || 0 == conn->c_pagedresults.prl_count) {
- LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_is_timedout: -\n");
- return rc;
+ if (!conn || (0 == conn->c_pagedresults.prl_maxlen)) {
+ LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_is_timedout: false\n");
+ return 0;
}
ctime = current_time();
- for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) {
- prp = conn->c_pagedresults.prl_list + i;
+ prp = conn->c_pagedresults.prl_list;
+ if (prp && (1 == conn->c_pagedresults.prl_maxlen)) {
if (prp->pr_current_be && (prp->pr_timelimit > 0)) {
- if (ctime < prp->pr_timelimit) {
- LDAPDebug0Args(LDAP_DEBUG_TRACE,
- "<-- pagedresults_is_timedout: 0\n");
- return 0; /* at least, one request is not timed out. */
- } else {
- rc = 1; /* possibly timed out */
+ if (ctime > prp->pr_timelimit) {
+ LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_is_timedout: true\n");
+ return 1;
}
}
}
- LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_is_timedout: 1\n");
- return rc; /* all requests are timed out. */
+ LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_is_timedout: false\n");
+ return 0;
}
/* reset all timeout */
8 years, 10 months
2 commits - ldap/servers
by Noriko Hosoi
ldap/servers/slapd/back-ldbm/dblayer.c | 30 ++-------
ldap/servers/slapd/opshared.c | 41 +++++-------
ldap/servers/slapd/pagedresults.c | 110 +++++++++++++++++++++------------
3 files changed, 98 insertions(+), 83 deletions(-)
New commits:
commit f3c3125fc9fd4dc1cbd41027d6442cb525efd014
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Thu Jun 4 16:27:05 2015 -0700
Ticket #48192 - Individual abandoned simple paged results request has no chance to be cleaned up
Description: When allocating a slot in simple paged results array stashed
in a connection in pagedresults_parse_control_value, a new code is added
to scan the array if the existing slot is timed out or not. If it is, the
slot is released and a search results is released if it is attached.
Also, if a request is abandoned, instead of returning a valid cookie, it
changed to return an empty cookie to inform the client the request was not
successfully completed.
https://fedorahosted.org/389/ticket/48192
Reviewed by rmeggins(a)redhat.com (Thank you, Rich!!)
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
index fa88053..1623fb0 100644
--- a/ldap/servers/slapd/opshared.c
+++ b/ldap/servers/slapd/opshared.c
@@ -517,8 +517,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
rc = pagedresults_parse_control_value(pb, ctl_value, &pagesize, &pr_idx, be);
/* Let's set pr_idx even if it fails; in case, pr_idx == -1. */
slapi_pblock_set(pb, SLAPI_PAGED_RESULTS_INDEX, &pr_idx);
- if ((LDAP_SUCCESS == rc) ||
- (LDAP_CANCELLED == rc) || (0 == pagesize)) {
+ if ((LDAP_SUCCESS == rc) || (LDAP_CANCELLED == rc) || (0 == pagesize)) {
unsigned int opnote = SLAPI_OP_NOTE_SIMPLEPAGED;
op_set_pagedresults(operation);
pr_be = pagedresults_get_current_be(pb->pb_conn, pr_idx);
@@ -545,9 +544,8 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
}
slapi_pblock_set( pb, SLAPI_OPERATION_NOTES, &opnote );
if ((LDAP_CANCELLED == rc) || (0 == pagesize)) {
- /* paged-results-request was abandoned */
- pagedresults_set_response_control(pb, 0, estimate,
- curr_search_count, pr_idx);
+ /* paged-results-request was abandoned; making an empty cookie. */
+ pagedresults_set_response_control(pb, 0, estimate, -1, pr_idx);
send_ldap_result(pb, 0, NULL,
"Simple Paged Results Search abandoned",
0, NULL);
@@ -574,10 +572,21 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
/* adjust time and size limits */
compute_limits (pb);
-
- /* call the pre-search plugins. if they succeed, call the backend
- search function. then call the post-search plugins. */
+ /* set the timelimit to clean up the too-long-lived-paged results requests */
+ if (op_is_pagedresults(operation)) {
+ time_t optime, time_up;
+ int tlimit;
+ slapi_pblock_get( pb, SLAPI_SEARCH_TIMELIMIT, &tlimit );
+ slapi_pblock_get( pb, SLAPI_OPINITIATED_TIME, &optime );
+ time_up = (tlimit==-1 ? -1 : optime + tlimit); /* -1: no time limit */
+ pagedresults_set_timelimit(pb->pb_conn, pb->pb_op, time_up, pr_idx);
+ }
+
+ /*
+ * call the pre-search plugins. if they succeed, call the backend
+ * search function. then call the post-search plugins.
+ */
/* ONREPL - should regular plugin be called for internal searches ? */
if (plugin_call_plugins(pb, SLAPI_PLUGIN_PRE_SEARCH_FN) == 0)
{
@@ -642,16 +651,6 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
}
}
- /* set the timelimit to clean up the too-long-lived-paged results requests */
- if (op_is_pagedresults(operation)) {
- time_t optime, time_up;
- int tlimit;
- slapi_pblock_get( pb, SLAPI_SEARCH_TIMELIMIT, &tlimit );
- slapi_pblock_get( pb, SLAPI_OPINITIATED_TIME, &optime );
- time_up = (tlimit==-1 ? -1 : optime + tlimit); /* -1: no time limit */
- pagedresults_set_timelimit(pb->pb_conn, pb->pb_op, time_up, pr_idx);
- }
-
/* PAR: now filters have been rewritten, we can assign plugins to work on them */
index_subsys_assign_filter_decoders(pb);
@@ -880,10 +879,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &sr);
if (PAGEDRESULTS_SEARCH_END == pr_stat) {
if (sr) { /* in case a left over sr is found, clean it up */
- PR_Lock(pb->pb_conn->c_mutex);
- pagedresults_set_search_result(pb->pb_conn, operation, NULL, 1, pr_idx);
- be->be_search_results_release(&sr);
- PR_Unlock(pb->pb_conn->c_mutex);
+ pagedresults_free_one(pb->pb_conn, operation, pr_idx);
}
if (NULL == next_be) {
/* no more entries && no more backends */
@@ -1306,7 +1302,6 @@ iterate(Slapi_PBlock *pb, Slapi_Backend *be, int send_result,
operation_out_of_disk_space();
}
pr_stat = PAGEDRESULTS_SEARCH_END;
- pagedresults_set_timelimit(pb->pb_conn, pb->pb_op, 0, pr_idx);
rval = -1;
done = 1;
continue;
diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c
index 327da54..402dd10 100644
--- a/ldap/servers/slapd/pagedresults.c
+++ b/ldap/servers/slapd/pagedresults.c
@@ -41,6 +41,27 @@
#include "slap.h"
+/* helper function to clean up one prp slot */
+static void
+_pr_cleanup_one_slot(PagedResults *prp)
+{
+ PRLock *prmutex = NULL;
+ if (!prp) {
+ return;
+ }
+ if (prp->pr_current_be && prp->pr_current_be->be_search_results_release) {
+ /* sr is left; release it. */
+ prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set));
+ }
+ /* clean up the slot */
+ if (prp->pr_mutex) {
+ /* pr_mutex is reused; back it up and reset it. */
+ prmutex = prp->pr_mutex;
+ }
+ memset(prp, '\0', sizeof(PagedResults));
+ prp->pr_mutex = prmutex;
+}
+
/*
* Parse the value from an LDAPv3 "Simple Paged Results" control. They look
* like this:
@@ -65,6 +86,7 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
Connection *conn = pb->pb_conn;
Operation *op = pb->pb_op;
BerElement *ber = NULL;
+ PagedResults *prp = NULL;
LDAPDebug0Args(LDAP_DEBUG_TRACE, "--> pagedresults_parse_control_value\n");
if ( NULL == conn || NULL == op || NULL == pagesize || NULL == index ) {
@@ -117,13 +139,31 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
}
*index = maxlen; /* the first position in the new area */
} else {
- for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) {
- if (!conn->c_pagedresults.prl_list[i].pr_current_be) {
- conn->c_pagedresults.prl_list[i].pr_current_be = be;
+ time_t ctime = current_time();
+ prp = conn->c_pagedresults.prl_list;
+ for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++, prp++) {
+ if (!prp->pr_current_be) { /* unused slot; take it */
+ prp->pr_current_be = be;
+ *index = i;
+ break;
+ } else if (((prp->pr_timelimit > 0) && (ctime < prp->pr_timelimit)) || /* timelimit exceeded */
+ (prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED) /* abandoned */) {
+ _pr_cleanup_one_slot(prp);
+ conn->c_pagedresults.prl_count--;
+ prp->pr_current_be = be;
*index = i;
break;
}
}
+ /* cleaning up the rest of the timedout if any */
+ for (++i; i < conn->c_pagedresults.prl_maxlen; i++, prp++) {
+ if (prp->pr_current_be &&
+ (((prp->pr_timelimit > 0) && (ctime < prp->pr_timelimit)) || /* timelimit exceeded */
+ (prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED)) /* abandoned */) {
+ _pr_cleanup_one_slot(prp);
+ conn->c_pagedresults.prl_count--;
+ }
+ }
}
if ((*index > -1) && (*index < conn->c_pagedresults.prl_maxlen) &&
!conn->c_pagedresults.prl_list[*index].pr_mutex) {
@@ -131,7 +171,6 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
}
conn->c_pagedresults.prl_count++;
} else {
- PagedResults *prp = NULL;
/* Repeated paged results request.
* PagedResults is already allocated. */
char *ptr = slapi_ch_malloc(cookie.bv_len + 1);
@@ -156,8 +195,10 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
slapi_ch_free((void **)&cookie.bv_val);
if ((*index > -1) && (*index < conn->c_pagedresults.prl_maxlen)) {
- if (conn->c_pagedresults.prl_list[*index].pr_flags &
- CONN_FLAG_PAGEDRESULTS_ABANDONED) {
+ if (conn->c_pagedresults.prl_list[*index].pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED) {
+ /* repeated case? */
+ prp = conn->c_pagedresults.prl_list + *index;
+ _pr_cleanup_one_slot(prp);
rc = LDAP_CANCELLED;
} else {
/* Need to keep the latest msgid to prepare for the abandon. */
@@ -273,20 +314,8 @@ pagedresults_free_one( Connection *conn, Operation *op, int index )
"conn=%d paged requests list count is %d\n",
conn->c_connid, conn->c_pagedresults.prl_count);
} else if (index < conn->c_pagedresults.prl_maxlen) {
- PRLock *prmutex = NULL;
PagedResults *prp = conn->c_pagedresults.prl_list + index;
- if (prp && prp->pr_current_be &&
- prp->pr_current_be->be_search_results_release &&
- prp->pr_search_result_set) {
- prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set));
- }
- prp->pr_current_be = NULL;
- if (prp->pr_mutex) {
- /* pr_mutex is reused; back it up and reset it. */
- prmutex = prp->pr_mutex;
- }
- memset(prp, '\0', sizeof(PagedResults));
- prp->pr_mutex = prmutex;
+ _pr_cleanup_one_slot(prp);
conn->c_pagedresults.prl_count--;
rc = 0;
}
@@ -309,7 +338,7 @@ pagedresults_free_one_msgid_nolock( Connection *conn, ber_int_t msgid )
; /* Not a paged result. */
} else {
LDAPDebug1Arg(LDAP_DEBUG_TRACE,
- "--> pagedresults_free_one: msgid=%d\n", msgid);
+ "--> pagedresults_free_one_msgid_nolock: msgid=%d\n", msgid);
for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) {
if (conn->c_pagedresults.prl_list[i].pr_msgid == msgid) {
PagedResults *prp = conn->c_pagedresults.prl_list + i;
@@ -318,16 +347,14 @@ pagedresults_free_one_msgid_nolock( Connection *conn, ber_int_t msgid )
prp->pr_search_result_set) {
prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set));
}
- prp->pr_current_be = NULL;
prp->pr_flags |= CONN_FLAG_PAGEDRESULTS_ABANDONED;
prp->pr_flags &= ~CONN_FLAG_PAGEDRESULTS_PROCESSING;
- conn->c_pagedresults.prl_count--;
rc = 0;
break;
}
}
LDAPDebug1Arg(LDAP_DEBUG_TRACE,
- "<-- pagedresults_free_one: %d\n", rc);
+ "<-- pagedresults_free_one_msgid_nolock: %d\n", rc);
}
}
@@ -845,37 +872,42 @@ pagedresults_reset_processing(Connection *conn, int index)
}
#endif
-/* Are all the paged results requests timed out? */
+/*
+ * This timedout is mainly for an end user leaves a commandline untouched
+ * for a long time. This should not affect a permanent connection which
+ * manages multiple simple paged results requests over the connection.
+ *
+ * [rule]
+ * If there is just one slot and it's timed out, we return it is timedout.
+ * If there are multiple slots, the connection may be a permanent one.
+ * Do not return timed out here. But let the next request take care the
+ * timedout slot(s).
+ */
int
pagedresults_is_timedout_nolock(Connection *conn)
{
- int i;
PagedResults *prp = NULL;
time_t ctime;
- int rc = 0;
LDAPDebug0Args(LDAP_DEBUG_TRACE, "--> pagedresults_is_timedout\n");
- if (NULL == conn || 0 == conn->c_pagedresults.prl_count) {
- LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_is_timedout: -\n");
- return rc;
+ if (!conn || (0 == conn->c_pagedresults.prl_maxlen)) {
+ LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_is_timedout: false\n");
+ return 0;
}
ctime = current_time();
- for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) {
- prp = conn->c_pagedresults.prl_list + i;
+ prp = conn->c_pagedresults.prl_list;
+ if (prp && (1 == conn->c_pagedresults.prl_maxlen)) {
if (prp->pr_current_be && (prp->pr_timelimit > 0)) {
- if (ctime < prp->pr_timelimit) {
- LDAPDebug0Args(LDAP_DEBUG_TRACE,
- "<-- pagedresults_is_timedout: 0\n");
- return 0; /* at least, one request is not timed out. */
- } else {
- rc = 1; /* possibly timed out */
+ if (ctime > prp->pr_timelimit) {
+ LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_is_timedout: true\n");
+ return 1;
}
}
}
- LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_is_timedout: 1\n");
- return rc; /* all requests are timed out. */
+ LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_is_timedout: false\n");
+ return 0;
}
/* reset all timeout */
commit 460b764e846df7f41c62eec7015331c0caf7481c
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Thu Jun 4 23:07:39 2015 -0700
Revert "Ticket 48149 - ns-slapd double free or corruption crash"
This reverts commit 8d64b8e348bbfca51411723d396beec7db5c34b9.
This workaround is not needed since the latest libdb has no problem.
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index 568b7c4..ac315bb 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -102,19 +102,15 @@
#endif
#if 1000*DB_VERSION_MAJOR + 100*DB_VERSION_MINOR >= 4100
-#define DB_OPEN(priv, oflags, db, txnid, file, database, type, flags, mode, rval) \
+#define DB_OPEN(oflags, db, txnid, file, database, type, flags, mode, rval) \
{ \
if (((oflags) & DB_INIT_TXN) && ((oflags) & DB_INIT_LOG)) \
{ \
- if ((priv)) slapi_rwlock_rdlock((priv)->dblayer_env_lock); \
(rval) = ((db)->open)((db), (txnid), (file), (database), (type), (flags)|DB_AUTO_COMMIT, (mode)); \
- if ((priv)) slapi_rwlock_unlock((priv)->dblayer_env_lock); \
} \
else \
{ \
- if ((priv)) slapi_rwlock_rdlock((priv)->dblayer_env_lock); \
(rval) = ((db)->open)((db), (txnid), (file), (database), (type), (flags), (mode)); \
- if ((priv)) slapi_rwlock_unlock((priv)->dblayer_env_lock); \
} \
}
/* 608145: db4.1 and newer does not require exclusive lock for checkpointing
@@ -122,7 +118,7 @@
#define DB_CHECKPOINT_LOCK(use_lock, lock) ;
#define DB_CHECKPOINT_UNLOCK(use_lock, lock) ;
#else /* older then db 41 */
-#define DB_OPEN(env, oflags, db, txnid, file, database, type, flags, mode, rval) \
+#define DB_OPEN(oflags, db, txnid, file, database, type, flags, mode, rval) \
(rval) = (db)->open((db), (file), (database), (type), (flags), (mode))
#define DB_CHECKPOINT_LOCK(use_lock, lock) if(use_lock) slapi_rwlock_wrlock(lock);
#define DB_CHECKPOINT_UNLOCK(use_lock, lock) if(use_lock) slapi_rwlock_unlock(lock);
@@ -2344,7 +2340,7 @@ int dblayer_instance_start(backend *be, int mode)
abs_id2entry_file = slapi_ch_smprintf( "%s%c%s", inst_dirp,
get_sep(inst_dirp), ID2ENTRY LDBM_FILENAME_SUFFIX);
- DB_OPEN(mypEnv, mypEnv->dblayer_openflags,
+ DB_OPEN(mypEnv->dblayer_openflags,
dbp, NULL/* txnid */, abs_id2entry_file, subname, DB_BTREE,
open_flags, priv->dblayer_file_mode, return_value);
dbp->close(dbp, 0);
@@ -2375,7 +2371,7 @@ int dblayer_instance_start(backend *be, int mode)
#endif
slapi_ch_free_string(&abs_id2entry_file);
}
- DB_OPEN(mypEnv, mypEnv->dblayer_openflags,
+ DB_OPEN(mypEnv->dblayer_openflags,
dbp, NULL/* txnid */, id2entry_file, subname, DB_BTREE,
open_flags, priv->dblayer_file_mode, return_value);
if (0 != return_value) {
@@ -2652,7 +2648,7 @@ dblayer_get_aux_id2entry_ext(backend *be, DB **ppDB, DB_ENV **ppEnv,
}
PR_ASSERT(dblayer_inst_exists(inst, NULL));
- DB_OPEN(mypEnv, envflags, dbp, NULL/* txnid */, id2entry_file, subname, DB_BTREE,
+ DB_OPEN(envflags, dbp, NULL/* txnid */, id2entry_file, subname, DB_BTREE,
dbflags, priv->dblayer_file_mode, rval);
if (rval) {
LDAPDebug(LDAP_DEBUG_ANY,
@@ -3224,7 +3220,7 @@ dblayer_open_file(backend *be, char* indexname, int open_flag,
}
abs_file_name = slapi_ch_smprintf("%s%c%s",
inst_dirp, get_sep(inst_dirp), file_name);
- DB_OPEN(pENV, pENV->dblayer_openflags,
+ DB_OPEN(pENV->dblayer_openflags,
dbp, NULL/* txnid */, abs_file_name, subname, DB_BTREE,
open_flags, priv->dblayer_file_mode, return_value);
dbp->close(dbp, 0);
@@ -3240,7 +3236,7 @@ dblayer_open_file(backend *be, char* indexname, int open_flag,
slapi_ch_free_string(&abs_file_name);
}
- DB_OPEN(pENV, pENV->dblayer_openflags,
+ DB_OPEN(pENV->dblayer_openflags,
dbp, NULL, /* txnid */ rel_path, subname, DB_BTREE,
open_flags, priv->dblayer_file_mode, return_value);
#if 1000*DB_VERSION_MAJOR + 100*DB_VERSION_MINOR == 4100
@@ -5170,7 +5166,6 @@ int dblayer_memp_stat(struct ldbminfo *li, DB_MPOOL_STAT **gsp,
{
dblayer_private *priv = NULL;
DB_ENV *env = NULL;
- int rc;
PR_ASSERT(NULL != li);
@@ -5180,10 +5175,7 @@ int dblayer_memp_stat(struct ldbminfo *li, DB_MPOOL_STAT **gsp,
env = priv->dblayer_env->dblayer_DB_ENV;
PR_ASSERT(NULL != env);
- slapi_rwlock_wrlock(priv->dblayer_env->dblayer_env_lock);
- rc = MEMP_STAT(env, gsp, fsp, 0, (void *)slapi_ch_malloc);
- slapi_rwlock_unlock(priv->dblayer_env->dblayer_env_lock);
- return rc;
+ return MEMP_STAT(env, gsp, fsp, 0, (void *)slapi_ch_malloc);
}
/* import wants this one */
@@ -5192,7 +5184,6 @@ int dblayer_memp_stat_instance(ldbm_instance *inst, DB_MPOOL_STAT **gsp,
{
DB_ENV *env = NULL;
dblayer_private *priv = NULL;
- int rc;
PR_ASSERT(NULL != inst);
@@ -5205,10 +5196,7 @@ int dblayer_memp_stat_instance(ldbm_instance *inst, DB_MPOOL_STAT **gsp,
}
PR_ASSERT(NULL != env);
- slapi_rwlock_wrlock(priv->dblayer_env->dblayer_env_lock);
- rc = MEMP_STAT(env, gsp, fsp, 0, (void *)slapi_ch_malloc);
- slapi_rwlock_unlock(priv->dblayer_env->dblayer_env_lock);
- return rc;
+ return MEMP_STAT(env, gsp, fsp, 0, (void *)slapi_ch_malloc);
}
/* Helper functions for recovery */
8 years, 10 months
Branch '389-ds-base-1.2.11' - ldap/servers
by Ludwig Krispenz
ldap/servers/plugins/acl/acl.c | 121 ++++++++++-------------------------------
1 file changed, 30 insertions(+), 91 deletions(-)
New commits:
commit 6024a7731c1888668f1efc163fb55e118a373366
Author: Ludwig Krispenz <lkrispen(a)redhat.com>
Date: Tue May 12 10:07:24 2015 +0200
Ticket 48175 - Avoid using regex in ACL if possible
Bug Description: aci code uses regex to do substring matching for targets
but this is a huge overhead for a simple sequence of
string matching
Fix Description: directly do the str match for the initial, any, final
parts of the filter
https://fedorahosted.org/389/ticket/48175
Reviewed by: Noriko, thanks
diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c
index 6edc367..3b0a7ce 100644
--- a/ldap/servers/plugins/acl/acl.c
+++ b/ldap/servers/plugins/acl/acl.c
@@ -3209,119 +3209,58 @@ acl__TestRights(Acl_PBlock *aclpb,int access, char **right, char ** map_generic,
int
acl_match_substring ( Slapi_Filter *f, char *str, int exact_match)
{
- int i, rc, len;
- char *p = NULL;
- char *end, *realval, *tmp;
- char pat[BUFSIZ];
- char buf[BUFSIZ];
+ int i, len, tlen;
+ char *p = str;
char *type, *initial, *final;
char **any;
- Slapi_Regex *re = NULL;
- const char *re_result = NULL;
if ( 0 != slapi_filter_get_subfilt ( f, &type, &initial, &any, &final ) ) {
return (ACL_FALSE);
}
- /* convert the input to lower. */
- for (p = str; *p; p++)
- *p = TOLOWER ( *p );
-
- /* construct a regular expression corresponding to the filter: */
- pat[0] = '\0';
- p = pat;
- end = pat + sizeof(pat) - 2; /* leave room for null */
-
-
+ /* this assumes that str and the filter components are already
+ * normalized. If not, it shoul be done
+ */
if ( initial != NULL) {
- strcpy (p, "^");
- p = strchr (p, '\0');
-
- /* 2 * in case every char is special */
- if (p + 2 * strlen ( initial ) > end) {
- slapi_log_error (SLAPI_LOG_ACL, plugin_name,
- "not enough pattern space\n");
-
- return (ACL_ERR);
- }
-
- if (!exact_match) {
- strcpy (p, ".*");
- p = strchr (p, '\0');
+ len = strlen(initial);
+ if (exact_match) {
+ int rc = strncmp(p, initial, len);
+ if (rc) {
+ return ACL_FALSE;
+ } else {
+ p += len;
+ }
+ } else {
+ p = strstr(p, initial);
+ if (p) {
+ p += len;
+ } else {
+ return ACL_FALSE;
+ }
}
- acl_strcpy_special (p, initial);
- p = strchr (p, '\0');
}
if ( any != NULL) {
for (i = 0; any && any[i] != NULL; i++) {
- /* ".*" + value */
- if (p + 2 * strlen ( any[i]) + 2 > end) {
- slapi_log_error (SLAPI_LOG_ACL, plugin_name,
- "not enough pattern space\n");
- return (ACL_ERR);
+ p = strstr(p, any[i]);
+ if (p) {
+ p += strlen(any[i]);
+ } else {
+ return ACL_FALSE;
}
-
- strcpy (p, ".*");
- p = strchr (p, '\0');
- acl_strcpy_special (p, any[i]);
- p = strchr (p, '\0');
}
}
if ( final != NULL) {
- /* ".*" + value */
- if (p + 2 * strlen ( final ) + 2 > end) {
- slapi_log_error (SLAPI_LOG_ACL, plugin_name,
- "not enough pattern space\n");
- return (ACL_ERR);
- }
-
- strcpy (p, ".*");
- p = strchr (p, '\0');
- acl_strcpy_special (p, final);
- p = strchr (p, '\0');
- strcpy (p, "$");
+ len = strlen(final);
+ tlen = strlen(p);
+ if (len > tlen) return ACL_FALSE;
+ if (strcmp(p+tlen-len, final)) return ACL_FALSE;
}
- /* see if regex matches with the input string */
- tmp = NULL;
- len = strlen(str);
-
- if (len < sizeof(buf)) {
- strcpy (buf, str);
- realval = buf;
- } else {
- tmp = (char*) slapi_ch_malloc (len + 1);
- strcpy (tmp, str);
- realval = tmp;
- }
+ return ACL_TRUE;
- /* What we have built is a regular pattaren expression.
- ** Now we will compile the pattern and compare wth the string to
- ** see if the input string matches with the patteren or not.
- */
- re = slapi_re_comp( pat, &re_result );
- if (NULL == re) {
- slapi_log_error (SLAPI_LOG_ACL, plugin_name,
- "acl_match_substring:re_comp failed (%s)\n", re_result?re_result:"unknown");
- return (ACL_ERR);
- }
-
- /* slapi_re_exec() returns 1 if the string p1 matches the last compiled
- ** regular expression, 0 if the string p1 failed to match
- */
- rc = slapi_re_exec( re, realval, -1 /* no timelimit */ );
-
- slapi_re_free(re);
- slapi_ch_free ( (void **) &tmp );
-
- if (rc == 1) {
- return ACL_TRUE;
- } else {
- return ACL_FALSE;
- }
}
/***************************************************************************
*
8 years, 10 months
ldap/servers
by Ludwig Krispenz
ldap/servers/plugins/acl/acl.c | 121 ++++++++++-------------------------------
1 file changed, 30 insertions(+), 91 deletions(-)
New commits:
commit 25c3b83af5c0ed9a37db9d4928dd429682029dd6
Author: Ludwig Krispenz <lkrispen(a)redhat.com>
Date: Tue May 12 10:07:24 2015 +0200
Ticket 48175 - Avoid using regex in ACL if possible
Bug Description: aci code uses regex to do substring matching for targets
but this is a huge overhead for a simple sequence of
string matching
Fix Description: directly do the str match for the initial, any, final
parts of the filter
https://fedorahosted.org/389/ticket/48175
Reviewed by: Noriko, thanks
diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c
index cd307d9..c73e58c 100644
--- a/ldap/servers/plugins/acl/acl.c
+++ b/ldap/servers/plugins/acl/acl.c
@@ -3412,119 +3412,58 @@ acl__TestRights(Acl_PBlock *aclpb,int access, const char **right, const char **
int
acl_match_substring ( Slapi_Filter *f, char *str, int exact_match)
{
- int i, rc, len;
- char *p = NULL;
- char *end, *realval, *tmp;
- char pat[BUFSIZ];
- char buf[BUFSIZ];
+ int i, len, tlen;
+ char *p = str;
char *type, *initial, *final;
char **any;
- Slapi_Regex *re = NULL;
- const char *re_result = NULL;
if ( 0 != slapi_filter_get_subfilt ( f, &type, &initial, &any, &final ) ) {
return (ACL_FALSE);
}
- /* convert the input to lower. */
- for (p = str; *p; p++)
- *p = TOLOWER ( *p );
-
- /* construct a regular expression corresponding to the filter: */
- pat[0] = '\0';
- p = pat;
- end = pat + sizeof(pat) - 2; /* leave room for null */
-
-
+ /* this assumes that str and the filter components are already
+ * normalized. If not, it shoul be done
+ */
if ( initial != NULL) {
- strcpy (p, "^");
- p = strchr (p, '\0');
-
- /* 2 * in case every char is special */
- if (p + 2 * strlen ( initial ) > end) {
- slapi_log_error (SLAPI_LOG_ACL, plugin_name,
- "not enough pattern space\n");
-
- return (ACL_ERR);
- }
-
- if (!exact_match) {
- strcpy (p, ".*");
- p = strchr (p, '\0');
+ len = strlen(initial);
+ if (exact_match) {
+ int rc = strncmp(p, initial, len);
+ if (rc) {
+ return ACL_FALSE;
+ } else {
+ p += len;
+ }
+ } else {
+ p = strstr(p, initial);
+ if (p) {
+ p += len;
+ } else {
+ return ACL_FALSE;
+ }
}
- acl_strcpy_special (p, initial);
- p = strchr (p, '\0');
}
if ( any != NULL) {
for (i = 0; any && any[i] != NULL; i++) {
- /* ".*" + value */
- if (p + 2 * strlen ( any[i]) + 2 > end) {
- slapi_log_error (SLAPI_LOG_ACL, plugin_name,
- "not enough pattern space\n");
- return (ACL_ERR);
+ p = strstr(p, any[i]);
+ if (p) {
+ p += strlen(any[i]);
+ } else {
+ return ACL_FALSE;
}
-
- strcpy (p, ".*");
- p = strchr (p, '\0');
- acl_strcpy_special (p, any[i]);
- p = strchr (p, '\0');
}
}
if ( final != NULL) {
- /* ".*" + value */
- if (p + 2 * strlen ( final ) + 2 > end) {
- slapi_log_error (SLAPI_LOG_ACL, plugin_name,
- "not enough pattern space\n");
- return (ACL_ERR);
- }
-
- strcpy (p, ".*");
- p = strchr (p, '\0');
- acl_strcpy_special (p, final);
- p = strchr (p, '\0');
- strcpy (p, "$");
+ len = strlen(final);
+ tlen = strlen(p);
+ if (len > tlen) return ACL_FALSE;
+ if (strcmp(p+tlen-len, final)) return ACL_FALSE;
}
- /* see if regex matches with the input string */
- tmp = NULL;
- len = strlen(str);
-
- if (len < sizeof(buf)) {
- strcpy (buf, str);
- realval = buf;
- } else {
- tmp = (char*) slapi_ch_malloc (len + 1);
- strcpy (tmp, str);
- realval = tmp;
- }
+ return ACL_TRUE;
- /* What we have built is a regular pattaren expression.
- ** Now we will compile the pattern and compare wth the string to
- ** see if the input string matches with the patteren or not.
- */
- re = slapi_re_comp( pat, &re_result );
- if (NULL == re) {
- slapi_log_error (SLAPI_LOG_ACL, plugin_name,
- "acl_match_substring:re_comp failed (%s)\n", re_result?re_result:"unknown");
- return (ACL_ERR);
- }
-
- /* slapi_re_exec() returns 1 if the string p1 matches the last compiled
- ** regular expression, 0 if the string p1 failed to match
- */
- rc = slapi_re_exec( re, realval, -1 /* no timelimit */ );
-
- slapi_re_free(re);
- slapi_ch_free ( (void **) &tmp );
-
- if (rc == 1) {
- return ACL_TRUE;
- } else {
- return ACL_FALSE;
- }
}
/***************************************************************************
*
8 years, 10 months
Branch '389-ds-base-1.2.11' - ldap/servers
by Ludwig Krispenz
ldap/servers/slapd/back-ldbm/dblayer.c | 30 +++++++++++++++++++++---------
1 file changed, 21 insertions(+), 9 deletions(-)
New commits:
commit d620bb644a9b71ca9259edba42d62058e628cc0a
Author: Ludwig Krispenz <lkrispen(a)redhat.com>
Date: Tue May 12 10:24:29 2015 +0200
Ticket 48149 - ns-slapd double free or corruption crash
Bug Description: if the per file statistics are retrived from
the BDB backend, there is a race condition, which
corrupts the memory allcated for the statistics.
It happens id a new file with a longer backend/filename
is openend between the alloaction for the statistics
data and the actual populating if it
Fix Description: The bug is in BDB and there is a fix from Oracle for the
latest versions, it is unclear if it will be backported
to the versions used in current supported389 platforms.
A fix in DS code is to lock the open calls from the
file statistic call
https://fedorahosted.org/389/ticket/48149
Reviewed by: ?
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index 9186adf..c0e278a 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -97,15 +97,19 @@
#include "dblayer.h"
#if 1000*DB_VERSION_MAJOR + 100*DB_VERSION_MINOR >= 4100
-#define DB_OPEN(oflags, db, txnid, file, database, type, flags, mode, rval) \
+#define DB_OPEN(priv, oflags, db, txnid, file, database, type, flags, mode, rval) \
{ \
if (((oflags) & DB_INIT_TXN) && ((oflags) & DB_INIT_LOG)) \
{ \
+ if ((priv)) slapi_rwlock_rdlock((priv)->dblayer_env_lock); \
(rval) = ((db)->open)((db), (txnid), (file), (database), (type), (flags)|DB_AUTO_COMMIT, (mode)); \
+ if ((priv)) slapi_rwlock_unlock((priv)->dblayer_env_lock); \
} \
else \
{ \
+ if ((priv)) slapi_rwlock_rdlock((priv)->dblayer_env_lock); \
(rval) = ((db)->open)((db), (txnid), (file), (database), (type), (flags), (mode)); \
+ if ((priv)) slapi_rwlock_unlock((priv)->dblayer_env_lock); \
} \
}
/* 608145: db4.1 and newer does not require exclusive lock for checkpointing
@@ -113,7 +117,7 @@
#define DB_CHECKPOINT_LOCK(use_lock, lock) ;
#define DB_CHECKPOINT_UNLOCK(use_lock, lock) ;
#else /* older then db 41 */
-#define DB_OPEN(oflags, db, txnid, file, database, type, flags, mode, rval) \
+#define DB_OPEN(env, oflags, db, txnid, file, database, type, flags, mode, rval) \
(rval) = (db)->open((db), (file), (database), (type), (flags), (mode))
#define DB_CHECKPOINT_LOCK(use_lock, lock) if(use_lock) slapi_rwlock_wrlock(lock);
#define DB_CHECKPOINT_UNLOCK(use_lock, lock) if(use_lock) slapi_rwlock_unlock(lock);
@@ -2225,7 +2229,7 @@ int dblayer_instance_start(backend *be, int mode)
abs_id2entry_file = slapi_ch_smprintf( "%s%c%s", inst_dirp,
get_sep(inst_dirp), ID2ENTRY LDBM_FILENAME_SUFFIX);
- DB_OPEN(mypEnv->dblayer_openflags,
+ DB_OPEN(mypEnv, mypEnv->dblayer_openflags,
dbp, NULL/* txnid */, abs_id2entry_file, subname, DB_BTREE,
open_flags, priv->dblayer_file_mode, return_value);
dbp->close(dbp, 0);
@@ -2256,7 +2260,7 @@ int dblayer_instance_start(backend *be, int mode)
#endif
slapi_ch_free_string(&abs_id2entry_file);
}
- DB_OPEN(mypEnv->dblayer_openflags,
+ DB_OPEN(mypEnv, mypEnv->dblayer_openflags,
dbp, NULL/* txnid */, id2entry_file, subname, DB_BTREE,
open_flags, priv->dblayer_file_mode, return_value);
if (0 != return_value) {
@@ -2533,7 +2537,7 @@ dblayer_get_aux_id2entry_ext(backend *be, DB **ppDB, DB_ENV **ppEnv,
}
PR_ASSERT(dblayer_inst_exists(inst, NULL));
- DB_OPEN(envflags, dbp, NULL/* txnid */, id2entry_file, subname, DB_BTREE,
+ DB_OPEN(mypEnv, envflags, dbp, NULL/* txnid */, id2entry_file, subname, DB_BTREE,
dbflags, priv->dblayer_file_mode, rval);
if (rval) {
LDAPDebug(LDAP_DEBUG_ANY,
@@ -3085,7 +3089,7 @@ dblayer_open_file(backend *be, char* indexname, int open_flag,
}
abs_file_name = slapi_ch_smprintf("%s%c%s",
inst_dirp, get_sep(inst_dirp), file_name);
- DB_OPEN(pENV->dblayer_openflags,
+ DB_OPEN(pENV, pENV->dblayer_openflags,
dbp, NULL/* txnid */, abs_file_name, subname, DB_BTREE,
open_flags, priv->dblayer_file_mode, return_value);
dbp->close(dbp, 0);
@@ -3101,7 +3105,7 @@ dblayer_open_file(backend *be, char* indexname, int open_flag,
slapi_ch_free_string(&abs_file_name);
}
- DB_OPEN(pENV->dblayer_openflags,
+ DB_OPEN(pENV, pENV->dblayer_openflags,
dbp, NULL, /* txnid */ rel_path, subname, DB_BTREE,
open_flags, priv->dblayer_file_mode, return_value);
#if 1000*DB_VERSION_MAJOR + 100*DB_VERSION_MINOR == 4100
@@ -4743,6 +4747,7 @@ int dblayer_memp_stat(struct ldbminfo *li, DB_MPOOL_STAT **gsp,
{
dblayer_private *priv = NULL;
DB_ENV *env = NULL;
+ int rc;
PR_ASSERT(NULL != li);
@@ -4752,7 +4757,10 @@ int dblayer_memp_stat(struct ldbminfo *li, DB_MPOOL_STAT **gsp,
env = priv->dblayer_env->dblayer_DB_ENV;
PR_ASSERT(NULL != env);
- return MEMP_STAT(env, gsp, fsp, 0, (void *)slapi_ch_malloc);
+ slapi_rwlock_wrlock(priv->dblayer_env->dblayer_env_lock);
+ rc = MEMP_STAT(env, gsp, fsp, 0, (void *)slapi_ch_malloc);
+ slapi_rwlock_unlock(priv->dblayer_env->dblayer_env_lock);
+ return rc;
}
/* import wants this one */
@@ -4761,6 +4769,7 @@ int dblayer_memp_stat_instance(ldbm_instance *inst, DB_MPOOL_STAT **gsp,
{
DB_ENV *env = NULL;
dblayer_private *priv = NULL;
+ int rc;
PR_ASSERT(NULL != inst);
@@ -4773,7 +4782,10 @@ int dblayer_memp_stat_instance(ldbm_instance *inst, DB_MPOOL_STAT **gsp,
}
PR_ASSERT(NULL != env);
- return MEMP_STAT(env, gsp, fsp, 0, (void *)slapi_ch_malloc);
+ slapi_rwlock_wrlock(priv->dblayer_env->dblayer_env_lock);
+ rc = MEMP_STAT(env, gsp, fsp, 0, (void *)slapi_ch_malloc);
+ slapi_rwlock_unlock(priv->dblayer_env->dblayer_env_lock);
+ return rc;
}
/* Helper functions for recovery */
8 years, 10 months
ldap/servers
by Ludwig Krispenz
ldap/servers/slapd/back-ldbm/dblayer.c | 30 +++++++++++++++++++++---------
1 file changed, 21 insertions(+), 9 deletions(-)
New commits:
commit 8d64b8e348bbfca51411723d396beec7db5c34b9
Author: Ludwig Krispenz <lkrispen(a)redhat.com>
Date: Tue May 12 10:24:29 2015 +0200
Ticket 48149 - ns-slapd double free or corruption crash
Bug Description: if the per file statistics are retrived from
the BDB backend, there is a race condition, which
corrupts the memory allcated for the statistics.
It happens id a new file with a longer backend/filename
is openend between the alloaction for the statistics
data and the actual populating if it
Fix Description: The bug is in BDB and there is a fix from Oracle for the
latest versions, it is unclear if it will be backported
to the versions used in current supported389 platforms.
A fix in DS code is to lock the open calls from the
file statistic call
https://fedorahosted.org/389/ticket/48149
Reviewed by: ?
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index ac315bb..568b7c4 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -102,15 +102,19 @@
#endif
#if 1000*DB_VERSION_MAJOR + 100*DB_VERSION_MINOR >= 4100
-#define DB_OPEN(oflags, db, txnid, file, database, type, flags, mode, rval) \
+#define DB_OPEN(priv, oflags, db, txnid, file, database, type, flags, mode, rval) \
{ \
if (((oflags) & DB_INIT_TXN) && ((oflags) & DB_INIT_LOG)) \
{ \
+ if ((priv)) slapi_rwlock_rdlock((priv)->dblayer_env_lock); \
(rval) = ((db)->open)((db), (txnid), (file), (database), (type), (flags)|DB_AUTO_COMMIT, (mode)); \
+ if ((priv)) slapi_rwlock_unlock((priv)->dblayer_env_lock); \
} \
else \
{ \
+ if ((priv)) slapi_rwlock_rdlock((priv)->dblayer_env_lock); \
(rval) = ((db)->open)((db), (txnid), (file), (database), (type), (flags), (mode)); \
+ if ((priv)) slapi_rwlock_unlock((priv)->dblayer_env_lock); \
} \
}
/* 608145: db4.1 and newer does not require exclusive lock for checkpointing
@@ -118,7 +122,7 @@
#define DB_CHECKPOINT_LOCK(use_lock, lock) ;
#define DB_CHECKPOINT_UNLOCK(use_lock, lock) ;
#else /* older then db 41 */
-#define DB_OPEN(oflags, db, txnid, file, database, type, flags, mode, rval) \
+#define DB_OPEN(env, oflags, db, txnid, file, database, type, flags, mode, rval) \
(rval) = (db)->open((db), (file), (database), (type), (flags), (mode))
#define DB_CHECKPOINT_LOCK(use_lock, lock) if(use_lock) slapi_rwlock_wrlock(lock);
#define DB_CHECKPOINT_UNLOCK(use_lock, lock) if(use_lock) slapi_rwlock_unlock(lock);
@@ -2340,7 +2344,7 @@ int dblayer_instance_start(backend *be, int mode)
abs_id2entry_file = slapi_ch_smprintf( "%s%c%s", inst_dirp,
get_sep(inst_dirp), ID2ENTRY LDBM_FILENAME_SUFFIX);
- DB_OPEN(mypEnv->dblayer_openflags,
+ DB_OPEN(mypEnv, mypEnv->dblayer_openflags,
dbp, NULL/* txnid */, abs_id2entry_file, subname, DB_BTREE,
open_flags, priv->dblayer_file_mode, return_value);
dbp->close(dbp, 0);
@@ -2371,7 +2375,7 @@ int dblayer_instance_start(backend *be, int mode)
#endif
slapi_ch_free_string(&abs_id2entry_file);
}
- DB_OPEN(mypEnv->dblayer_openflags,
+ DB_OPEN(mypEnv, mypEnv->dblayer_openflags,
dbp, NULL/* txnid */, id2entry_file, subname, DB_BTREE,
open_flags, priv->dblayer_file_mode, return_value);
if (0 != return_value) {
@@ -2648,7 +2652,7 @@ dblayer_get_aux_id2entry_ext(backend *be, DB **ppDB, DB_ENV **ppEnv,
}
PR_ASSERT(dblayer_inst_exists(inst, NULL));
- DB_OPEN(envflags, dbp, NULL/* txnid */, id2entry_file, subname, DB_BTREE,
+ DB_OPEN(mypEnv, envflags, dbp, NULL/* txnid */, id2entry_file, subname, DB_BTREE,
dbflags, priv->dblayer_file_mode, rval);
if (rval) {
LDAPDebug(LDAP_DEBUG_ANY,
@@ -3220,7 +3224,7 @@ dblayer_open_file(backend *be, char* indexname, int open_flag,
}
abs_file_name = slapi_ch_smprintf("%s%c%s",
inst_dirp, get_sep(inst_dirp), file_name);
- DB_OPEN(pENV->dblayer_openflags,
+ DB_OPEN(pENV, pENV->dblayer_openflags,
dbp, NULL/* txnid */, abs_file_name, subname, DB_BTREE,
open_flags, priv->dblayer_file_mode, return_value);
dbp->close(dbp, 0);
@@ -3236,7 +3240,7 @@ dblayer_open_file(backend *be, char* indexname, int open_flag,
slapi_ch_free_string(&abs_file_name);
}
- DB_OPEN(pENV->dblayer_openflags,
+ DB_OPEN(pENV, pENV->dblayer_openflags,
dbp, NULL, /* txnid */ rel_path, subname, DB_BTREE,
open_flags, priv->dblayer_file_mode, return_value);
#if 1000*DB_VERSION_MAJOR + 100*DB_VERSION_MINOR == 4100
@@ -5166,6 +5170,7 @@ int dblayer_memp_stat(struct ldbminfo *li, DB_MPOOL_STAT **gsp,
{
dblayer_private *priv = NULL;
DB_ENV *env = NULL;
+ int rc;
PR_ASSERT(NULL != li);
@@ -5175,7 +5180,10 @@ int dblayer_memp_stat(struct ldbminfo *li, DB_MPOOL_STAT **gsp,
env = priv->dblayer_env->dblayer_DB_ENV;
PR_ASSERT(NULL != env);
- return MEMP_STAT(env, gsp, fsp, 0, (void *)slapi_ch_malloc);
+ slapi_rwlock_wrlock(priv->dblayer_env->dblayer_env_lock);
+ rc = MEMP_STAT(env, gsp, fsp, 0, (void *)slapi_ch_malloc);
+ slapi_rwlock_unlock(priv->dblayer_env->dblayer_env_lock);
+ return rc;
}
/* import wants this one */
@@ -5184,6 +5192,7 @@ int dblayer_memp_stat_instance(ldbm_instance *inst, DB_MPOOL_STAT **gsp,
{
DB_ENV *env = NULL;
dblayer_private *priv = NULL;
+ int rc;
PR_ASSERT(NULL != inst);
@@ -5196,7 +5205,10 @@ int dblayer_memp_stat_instance(ldbm_instance *inst, DB_MPOOL_STAT **gsp,
}
PR_ASSERT(NULL != env);
- return MEMP_STAT(env, gsp, fsp, 0, (void *)slapi_ch_malloc);
+ slapi_rwlock_wrlock(priv->dblayer_env->dblayer_env_lock);
+ rc = MEMP_STAT(env, gsp, fsp, 0, (void *)slapi_ch_malloc);
+ slapi_rwlock_unlock(priv->dblayer_env->dblayer_env_lock);
+ return rc;
}
/* Helper functions for recovery */
8 years, 10 months
Branch '389-ds-base-1.3.3' - ldap/servers
by Noriko Hosoi
ldap/servers/slapd/back-ldbm/dblayer.c | 7 -------
ldap/servers/slapd/back-ldbm/ldbm_instance_config.c | 6 ++++--
2 files changed, 4 insertions(+), 9 deletions(-)
New commits:
commit a805e25a576231c48250c0dc2d3325a90e2c4886
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Sun May 31 17:08:29 2015 -0700
Ticket #48190 - idm/ipa 389-ds-base entry cache converges to 500 KB in dblayer_is_cachesize_sane
Description: This issue was introduced by the fix for Ticket 47499
commit 1e035d1111f6abcb87e760a2b9e41fa9e05a7ebd.
The function dblayer_is_cachesize_sane was originally implemented for
db cache to check if the given db cache size is larger than the available
memory or not. The function resets the size to the available memory size
if it is larger. Also, considering the extra metadata size needed for the
db cache, it multiplies by 0.8 every time it starts the server. It is not
needed even for the db cache. The code is old and we don't have to save
the memory there. Thus, this patch removes the resetting code.
https://fedorahosted.org/389/ticket/48190
Reviewed by mreynolds(a)redhat.com (Thank you, Mark!!)
(cherry picked from commit bf9ef718cfd48c26eaf11662f522451d866e7681)
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index 51fbc64..f9a8e4a 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -1116,13 +1116,6 @@ int dblayer_is_cachesize_sane(size_t *cachesize)
if (!issane) {
*cachesize = (size_t)((pages - procpages) * pagesize);
}
- /* We now compensate for DB's own compensation for metadata size
- * They increase the actual cache size by 25%, but only for sizes
- * less than 500Meg.
- */
- if (*cachesize < 500*MEGABYTE) {
- *cachesize = (size_t)((double)*cachesize * (double)0.8);
- }
return issane;
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
index 9b93f9a..f75ca97 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
@@ -121,11 +121,12 @@ ldbm_instance_config_cachememsize_set(void *arg, void *value, char *errorbuf, in
ldbm_instance *inst = (ldbm_instance *) arg;
int retval = LDAP_SUCCESS;
size_t val = (size_t) value;
+ size_t chkval = val;
/* Do whatever we can to make sure the data is ok. */
if (apply) {
- if (!dblayer_is_cachesize_sane(&val)){
+ if (!dblayer_is_cachesize_sane(&chkval)){
PR_snprintf(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
"Error: cachememsize value is too large.");
LDAPDebug( LDAP_DEBUG_ANY,"Error: cachememsize value is too large.\n",
@@ -152,11 +153,12 @@ ldbm_instance_config_dncachememsize_set(void *arg, void *value, char *errorbuf,
ldbm_instance *inst = (ldbm_instance *) arg;
int retval = LDAP_SUCCESS;
size_t val = (size_t)value;
+ size_t chkval = val;
/* Do whatever we can to make sure the data is ok. */
if (apply) {
- if (!dblayer_is_cachesize_sane(&val)){
+ if (!dblayer_is_cachesize_sane(&chkval)){
PR_snprintf(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
"Error: dncachememsize value is too large.");
LDAPDebug( LDAP_DEBUG_ANY,"Error: dncachememsize value is too large.\n",
8 years, 11 months
ldap/servers
by Noriko Hosoi
ldap/servers/slapd/back-ldbm/dblayer.c | 7 -------
ldap/servers/slapd/back-ldbm/ldbm_instance_config.c | 6 ++++--
2 files changed, 4 insertions(+), 9 deletions(-)
New commits:
commit bf9ef718cfd48c26eaf11662f522451d866e7681
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Sun May 31 17:08:29 2015 -0700
Ticket #48190 - idm/ipa 389-ds-base entry cache converges to 500 KB in dblayer_is_cachesize_sane
Description: This issue was introduced by the fix for Ticket 47499
commit 1e035d1111f6abcb87e760a2b9e41fa9e05a7ebd.
The function dblayer_is_cachesize_sane was originally implemented for
db cache to check if the given db cache size is larger than the available
memory or not. The function resets the size to the available memory size
if it is larger. Also, considering the extra metadata size needed for the
db cache, it multiplies by 0.8 every time it starts the server. It is not
needed even for the db cache. The code is old and we don't have to save
the memory there. Thus, this patch removes the resetting code.
https://fedorahosted.org/389/ticket/48190
Reviewed by mreynolds(a)redhat.com (Thank you, Mark!!)
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index 21a560e..ac315bb 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -1116,13 +1116,6 @@ int dblayer_is_cachesize_sane(size_t *cachesize)
if (!issane) {
*cachesize = (size_t)((pages - procpages) * pagesize);
}
- /* We now compensate for DB's own compensation for metadata size
- * They increase the actual cache size by 25%, but only for sizes
- * less than 500Meg.
- */
- if (*cachesize < 500*MEGABYTE) {
- *cachesize = (size_t)((double)*cachesize * (double)0.8);
- }
return issane;
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
index 9b93f9a..f75ca97 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
@@ -121,11 +121,12 @@ ldbm_instance_config_cachememsize_set(void *arg, void *value, char *errorbuf, in
ldbm_instance *inst = (ldbm_instance *) arg;
int retval = LDAP_SUCCESS;
size_t val = (size_t) value;
+ size_t chkval = val;
/* Do whatever we can to make sure the data is ok. */
if (apply) {
- if (!dblayer_is_cachesize_sane(&val)){
+ if (!dblayer_is_cachesize_sane(&chkval)){
PR_snprintf(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
"Error: cachememsize value is too large.");
LDAPDebug( LDAP_DEBUG_ANY,"Error: cachememsize value is too large.\n",
@@ -152,11 +153,12 @@ ldbm_instance_config_dncachememsize_set(void *arg, void *value, char *errorbuf,
ldbm_instance *inst = (ldbm_instance *) arg;
int retval = LDAP_SUCCESS;
size_t val = (size_t)value;
+ size_t chkval = val;
/* Do whatever we can to make sure the data is ok. */
if (apply) {
- if (!dblayer_is_cachesize_sane(&val)){
+ if (!dblayer_is_cachesize_sane(&chkval)){
PR_snprintf(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
"Error: dncachememsize value is too large.");
LDAPDebug( LDAP_DEBUG_ANY,"Error: dncachememsize value is too large.\n",
8 years, 11 months
Branch '389-ds-base-1.2.11' - ldap/servers
by Noriko Hosoi
ldap/servers/slapd/opshared.c | 87 +++++++++++++++++++-----------------------
1 file changed, 41 insertions(+), 46 deletions(-)
New commits:
commit b50095835b1889f8578ea3da579b543ed1619885
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Sat May 30 16:44:14 2015 -0700
Ticket #48146 - async simple paged results issue
Description: commit 5e9c4f1f09596dd076a6c3a0bb419580e8fd705e broke the
CI test case ticket47824_test.py.
If the simple paged results search is operated on a backend having one
or more sub-backends underneath, it fails to pick up the next sub-back
ends, but repeats the search on the parent backend. The problem was
fixed.
https://fedorahosted.org/389/ticket/48146
Reviewed by mreynolds(a)redhat.com (Thank you, Mark!!)
(cherry picked from commit 03d3455dfbe84f034a234df2ebd8cfdd7ad15f48)
(cherry picked from commit f6fe5bfe4c1fb1402af789a0f935c765c299d103)
(cherry picked from commit 64b54d416e75eaeb611ece982c1be9acf3f56161)
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
index bfacb9e..d446f50 100644
--- a/ldap/servers/slapd/opshared.c
+++ b/ldap/servers/slapd/opshared.c
@@ -463,46 +463,31 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
}
}
- if (be_name == NULL)
- {
- /* no specific backend was requested, use the mapping tree
- */
- err_code = slapi_mapping_tree_select_all(pb, be_list, referral_list, errorbuf);
- if (((err_code != LDAP_SUCCESS) && (err_code != LDAP_OPERATIONS_ERROR) && (err_code != LDAP_REFERRAL))
- || ((err_code == LDAP_OPERATIONS_ERROR) && (be_list[0] == NULL)))
- {
- send_ldap_result(pb, err_code, NULL, errorbuf, 0, NULL);
- rc = -1;
- goto free_and_return;
- }
- if (be_list[0] != NULL)
- {
- index = 0;
- if (pr_be) { /* PAGED RESULT: be is found from the previous paging. */
- /* move the index in the be_list which matches pr_be */
- while (be_list[index] && be_list[index+1] && pr_be != be_list[index])
- index++;
+ if (be_name == NULL) {
+ /* no specific backend was requested, use the mapping tree
+ */
+ err_code = slapi_mapping_tree_select_all(pb, be_list, referral_list, errorbuf);
+ if (((err_code != LDAP_SUCCESS) && (err_code != LDAP_OPERATIONS_ERROR) && (err_code != LDAP_REFERRAL))
+ || ((err_code == LDAP_OPERATIONS_ERROR) && (be_list[0] == NULL))) {
+ send_ldap_result(pb, err_code, NULL, errorbuf, 0, NULL);
+ rc = -1;
+ goto free_and_return;
+ }
+ if (be_list[0] != NULL) {
+ index = 0;
+ while (be_list[index] && be_list[index+1]) {
+ index++;
+ }
+ be = be_list[index];
} else {
- while (be_list[index] && be_list[index+1])
- index++;
+ be = NULL;
}
- /* "be" is either pr_be or the last backend */
- be = be_list[index];
- }
- else
- be = pr_be?pr_be:NULL;
- }
- else
- {
+ } else {
/* specific backend be_name was requested, use slapi_be_select_by_instance_name
*/
- if (pr_be) {
- be_single = be = pr_be;
- } else {
- be_single = be = slapi_be_select_by_instance_name(be_name);
- }
+ be_single = be = slapi_be_select_by_instance_name(be_name);
if (be_single) {
- slapi_be_Rlock(be_single);
+ slapi_be_Rlock(be_single);
}
be_list[0] = NULL;
referral_list[0] = NULL;
@@ -521,6 +506,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
if ( slapi_control_present (ctrlp, LDAP_CONTROL_PAGEDRESULTS,
&ctl_value, &iscritical) )
{
+ /* be is set only when this request is new. otherwise, prev be is honored. */
rc = pagedresults_parse_control_value(pb, ctl_value, &pagesize, &pr_idx, be);
/* Let's set pr_idx even if it fails; in case, pr_idx == -1. */
slapi_pblock_set(pb, SLAPI_PAGED_RESULTS_INDEX, &pr_idx);
@@ -529,13 +515,24 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
unsigned int opnote = SLAPI_OP_NOTE_SIMPLEPAGED;
op_set_pagedresults(operation);
pr_be = pagedresults_get_current_be(pb->pb_conn, pr_idx);
- pr_search_result = pagedresults_get_search_result(pb->pb_conn,
- operation,
- pr_idx);
- estimate =
- pagedresults_get_search_result_set_size_estimate(pb->pb_conn,
- operation,
- pr_idx);
+ if (be_name) {
+ if (pr_be != be_single) {
+ slapi_be_Unlock(be_single);
+ be_single = be = pr_be;
+ slapi_be_Rlock(be_single);
+ }
+ } else if (be_list[0]) {
+ if (pr_be) { /* PAGED RESULT: be is found from the previous paging. */
+ /* move the index in the be_list which matches pr_be */
+ index = 0;
+ while (be_list[index] && be_list[index+1] && pr_be != be_list[index]) {
+ index++;
+ }
+ be = be_list[index];
+ }
+ }
+ pr_search_result = pagedresults_get_search_result(pb->pb_conn, operation, pr_idx);
+ estimate = pagedresults_get_search_result_set_size_estimate(pb->pb_conn, operation, pr_idx);
if (pagedresults_get_unindexed(pb->pb_conn, operation, pr_idx)) {
opnote |= SLAPI_OP_NOTE_UNINDEXED;
}
@@ -680,7 +677,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
* change ONE-LEVEL searches to BASE
*/
- /* that's mean we only support one suffix per backend */
+ /* that means we only support one suffix per backend */
be_suffix = slapi_be_getsuffix(be, 0);
if (be_list[0] == NULL)
@@ -704,9 +701,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
* In async paged result case, the search result might be released
* by other theads. We need to double check it in the locked region.
*/
- pr_search_result = pagedresults_get_search_result(pb->pb_conn,
- operation,
- pr_idx);
+ pr_search_result = pagedresults_get_search_result(pb->pb_conn, operation, pr_idx);
if (pr_search_result) {
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, pr_search_result );
rc = send_results_ext (pb, 1, &pnentries, pagesize, &pr_stat);
8 years, 11 months
Branch '389-ds-base-1.3.2' - ldap/servers
by Noriko Hosoi
ldap/servers/slapd/opshared.c | 87 +++++++++++++++++++-----------------------
1 file changed, 41 insertions(+), 46 deletions(-)
New commits:
commit 64b54d416e75eaeb611ece982c1be9acf3f56161
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Sat May 30 16:44:14 2015 -0700
Ticket #48146 - async simple paged results issue
Description: commit 5e9c4f1f09596dd076a6c3a0bb419580e8fd705e broke the
CI test case ticket47824_test.py.
If the simple paged results search is operated on a backend having one
or more sub-backends underneath, it fails to pick up the next sub-back
ends, but repeats the search on the parent backend. The problem was
fixed.
https://fedorahosted.org/389/ticket/48146
Reviewed by mreynolds(a)redhat.com (Thank you, Mark!!)
(cherry picked from commit 03d3455dfbe84f034a234df2ebd8cfdd7ad15f48)
(cherry picked from commit f6fe5bfe4c1fb1402af789a0f935c765c299d103)
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
index c42aaa0..bceb9f5 100644
--- a/ldap/servers/slapd/opshared.c
+++ b/ldap/servers/slapd/opshared.c
@@ -470,46 +470,31 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
}
}
- if (be_name == NULL)
- {
- /* no specific backend was requested, use the mapping tree
- */
- err_code = slapi_mapping_tree_select_all(pb, be_list, referral_list, errorbuf);
- if (((err_code != LDAP_SUCCESS) && (err_code != LDAP_OPERATIONS_ERROR) && (err_code != LDAP_REFERRAL))
- || ((err_code == LDAP_OPERATIONS_ERROR) && (be_list[0] == NULL)))
- {
- send_ldap_result(pb, err_code, NULL, errorbuf, 0, NULL);
- rc = -1;
- goto free_and_return;
- }
- if (be_list[0] != NULL)
- {
- index = 0;
- if (pr_be) { /* PAGED RESULT: be is found from the previous paging. */
- /* move the index in the be_list which matches pr_be */
- while (be_list[index] && be_list[index+1] && pr_be != be_list[index])
- index++;
+ if (be_name == NULL) {
+ /* no specific backend was requested, use the mapping tree
+ */
+ err_code = slapi_mapping_tree_select_all(pb, be_list, referral_list, errorbuf);
+ if (((err_code != LDAP_SUCCESS) && (err_code != LDAP_OPERATIONS_ERROR) && (err_code != LDAP_REFERRAL))
+ || ((err_code == LDAP_OPERATIONS_ERROR) && (be_list[0] == NULL))) {
+ send_ldap_result(pb, err_code, NULL, errorbuf, 0, NULL);
+ rc = -1;
+ goto free_and_return;
+ }
+ if (be_list[0] != NULL) {
+ index = 0;
+ while (be_list[index] && be_list[index+1]) {
+ index++;
+ }
+ be = be_list[index];
} else {
- while (be_list[index] && be_list[index+1])
- index++;
+ be = NULL;
}
- /* "be" is either pr_be or the last backend */
- be = be_list[index];
- }
- else
- be = pr_be?pr_be:NULL;
- }
- else
- {
+ } else {
/* specific backend be_name was requested, use slapi_be_select_by_instance_name
*/
- if (pr_be) {
- be_single = be = pr_be;
- } else {
- be_single = be = slapi_be_select_by_instance_name(be_name);
- }
+ be_single = be = slapi_be_select_by_instance_name(be_name);
if (be_single) {
- slapi_be_Rlock(be_single);
+ slapi_be_Rlock(be_single);
}
be_list[0] = NULL;
referral_list[0] = NULL;
@@ -528,6 +513,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
if ( slapi_control_present (ctrlp, LDAP_CONTROL_PAGEDRESULTS,
&ctl_value, &iscritical) )
{
+ /* be is set only when this request is new. otherwise, prev be is honored. */
rc = pagedresults_parse_control_value(pb, ctl_value, &pagesize, &pr_idx, be);
/* Let's set pr_idx even if it fails; in case, pr_idx == -1. */
slapi_pblock_set(pb, SLAPI_PAGED_RESULTS_INDEX, &pr_idx);
@@ -536,13 +522,24 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
unsigned int opnote = SLAPI_OP_NOTE_SIMPLEPAGED;
op_set_pagedresults(operation);
pr_be = pagedresults_get_current_be(pb->pb_conn, pr_idx);
- pr_search_result = pagedresults_get_search_result(pb->pb_conn,
- operation,
- pr_idx);
- estimate =
- pagedresults_get_search_result_set_size_estimate(pb->pb_conn,
- operation,
- pr_idx);
+ if (be_name) {
+ if (pr_be != be_single) {
+ slapi_be_Unlock(be_single);
+ be_single = be = pr_be;
+ slapi_be_Rlock(be_single);
+ }
+ } else if (be_list[0]) {
+ if (pr_be) { /* PAGED RESULT: be is found from the previous paging. */
+ /* move the index in the be_list which matches pr_be */
+ index = 0;
+ while (be_list[index] && be_list[index+1] && pr_be != be_list[index]) {
+ index++;
+ }
+ be = be_list[index];
+ }
+ }
+ pr_search_result = pagedresults_get_search_result(pb->pb_conn, operation, pr_idx);
+ estimate = pagedresults_get_search_result_set_size_estimate(pb->pb_conn, operation, pr_idx);
if (pagedresults_get_unindexed(pb->pb_conn, operation, pr_idx)) {
opnote |= SLAPI_OP_NOTE_UNINDEXED;
}
@@ -687,7 +684,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
* change ONE-LEVEL searches to BASE
*/
- /* that's mean we only support one suffix per backend */
+ /* that means we only support one suffix per backend */
be_suffix = slapi_be_getsuffix(be, 0);
if (be_list[0] == NULL)
@@ -711,9 +708,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
* In async paged result case, the search result might be released
* by other theads. We need to double check it in the locked region.
*/
- pr_search_result = pagedresults_get_search_result(pb->pb_conn,
- operation,
- pr_idx);
+ pr_search_result = pagedresults_get_search_result(pb->pb_conn, operation, pr_idx);
if (pr_search_result) {
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, pr_search_result );
rc = send_results_ext (pb, 1, &pnentries, pagesize, &pr_stat);
8 years, 11 months