|
|
dc8c34 |
From f50e991828321e3e19ac704f0b2e0968a0c6704e Mon Sep 17 00:00:00 2001
|
|
|
dc8c34 |
From: Noriko Hosoi <nhosoi@redhat.com>
|
|
|
dc8c34 |
Date: Thu, 5 Nov 2015 10:44:08 -0800
|
|
|
dc8c34 |
Subject: [PATCH 365/365] Ticket #48338 - SimplePagedResults -- abandon could
|
|
|
dc8c34 |
happen between the abandon check and sending results
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Description: An abandon request for a SimplePagedResults request could
|
|
|
dc8c34 |
happened between the abandon check and the code for sending the search
|
|
|
dc8c34 |
results. The abandon frees the search results although sending result
|
|
|
dc8c34 |
code still refers it.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Fix description: The code (from getting search results through sending
|
|
|
dc8c34 |
the search results) in op_shared_search is protected by c_mutex locking.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
https://fedorahosted.org/389/ticket/48338
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Reviewed by rmeggins@redhat.com (Thank you, Rich!!)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
(cherry picked from commit 390b8bd9076e8976facc0858e60985d6b4fac05c)
|
|
|
dc8c34 |
(cherry picked from commit 8f49d33d30fade7b579062414250a0ddb1a66c62)
|
|
|
dc8c34 |
(cherry picked from commit a7a8b2d3cb8452cc629ec5228bea6571d72e6538)
|
|
|
dc8c34 |
(cherry picked from commit d5ccc06cefa6f423d80c6cc0e527b57c116b0cb8)
|
|
|
dc8c34 |
---
|
|
|
dc8c34 |
ldap/servers/slapd/opshared.c | 13 ++++++++-----
|
|
|
dc8c34 |
ldap/servers/slapd/pagedresults.c | 28 ++++++++++++++++++----------
|
|
|
dc8c34 |
ldap/servers/slapd/proto-slap.h | 5 ++---
|
|
|
dc8c34 |
3 files changed, 28 insertions(+), 18 deletions(-)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
|
|
|
dc8c34 |
index 31d41e8..391d1c3 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/opshared.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/opshared.c
|
|
|
dc8c34 |
@@ -530,7 +530,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
|
|
|
dc8c34 |
be = be_list[index];
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
- pr_search_result = pagedresults_get_search_result(pb->pb_conn, operation, pr_idx);
|
|
|
dc8c34 |
+ pr_search_result = pagedresults_get_search_result(pb->pb_conn, operation, 0/*not locked*/, pr_idx);
|
|
|
dc8c34 |
estimate = pagedresults_get_search_result_set_size_estimate(pb->pb_conn, operation, pr_idx);
|
|
|
dc8c34 |
if (pagedresults_get_unindexed(pb->pb_conn, operation, pr_idx)) {
|
|
|
dc8c34 |
opnote |= SLAPI_OP_NOTE_UNINDEXED;
|
|
|
dc8c34 |
@@ -700,13 +700,15 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
|
|
|
dc8c34 |
* In async paged result case, the search result might be released
|
|
|
dc8c34 |
* by other theads. We need to double check it in the locked region.
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
- pr_search_result = pagedresults_get_search_result(pb->pb_conn, operation, pr_idx);
|
|
|
dc8c34 |
+ PR_Lock(pb->pb_conn->c_mutex);
|
|
|
dc8c34 |
+ pr_search_result = pagedresults_get_search_result(pb->pb_conn, operation, 1/*locked*/, pr_idx);
|
|
|
dc8c34 |
if (pr_search_result) {
|
|
|
dc8c34 |
- if (pagedresults_is_abandoned_or_notavailable(pb->pb_conn, pr_idx)) {
|
|
|
dc8c34 |
+ if (pagedresults_is_abandoned_or_notavailable(pb->pb_conn, 1/*locked*/, pr_idx)) {
|
|
|
dc8c34 |
pagedresults_unlock(pb->pb_conn, pr_idx);
|
|
|
dc8c34 |
/* Previous operation was abandoned and the simplepaged object is not in use. */
|
|
|
dc8c34 |
send_ldap_result(pb, 0, NULL, "Simple Paged Results Search abandoned", 0, NULL);
|
|
|
dc8c34 |
rc = LDAP_SUCCESS;
|
|
|
dc8c34 |
+ PR_Unlock(pb->pb_conn->c_mutex);
|
|
|
dc8c34 |
goto free_and_return;
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, pr_search_result );
|
|
|
dc8c34 |
@@ -714,7 +716,8 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* search result could be reset in the backend/dse */
|
|
|
dc8c34 |
slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &sr);
|
|
|
dc8c34 |
- pagedresults_set_search_result(pb->pb_conn, operation, sr, 0, pr_idx);
|
|
|
dc8c34 |
+ pagedresults_set_search_result(pb->pb_conn, operation, sr, 1/*locked*/, pr_idx);
|
|
|
dc8c34 |
+ PR_Unlock(pb->pb_conn->c_mutex);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
pr_stat = PAGEDRESULTS_SEARCH_END;
|
|
|
dc8c34 |
@@ -745,7 +748,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
|
|
|
dc8c34 |
if (PAGEDRESULTS_SEARCH_END == pr_stat) {
|
|
|
dc8c34 |
pagedresults_lock(pb->pb_conn, pr_idx);
|
|
|
dc8c34 |
slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_SET, NULL);
|
|
|
dc8c34 |
- if (!pagedresults_is_abandoned_or_notavailable(pb->pb_conn, pr_idx)) {
|
|
|
dc8c34 |
+ if (!pagedresults_is_abandoned_or_notavailable(pb->pb_conn, 0/*not locked*/, pr_idx)) {
|
|
|
dc8c34 |
pagedresults_free_one(pb->pb_conn, operation, pr_idx);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
pagedresults_unlock(pb->pb_conn, pr_idx);
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c
|
|
|
dc8c34 |
index 434e48d..c1947f1 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/pagedresults.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/pagedresults.c
|
|
|
dc8c34 |
@@ -408,20 +408,25 @@ pagedresults_set_current_be(Connection *conn, Slapi_Backend *be, int index, int
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
void *
|
|
|
dc8c34 |
-pagedresults_get_search_result(Connection *conn, Operation *op, int index)
|
|
|
dc8c34 |
+pagedresults_get_search_result(Connection *conn, Operation *op, int locked, int index)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
void *sr = NULL;
|
|
|
dc8c34 |
if (!op_is_pagedresults(op)) {
|
|
|
dc8c34 |
return sr; /* noop */
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
- LDAPDebug1Arg(LDAP_DEBUG_TRACE,
|
|
|
dc8c34 |
- "--> pagedresults_get_search_result: idx=%d\n", index);
|
|
|
dc8c34 |
+ LDAPDebug2Args(LDAP_DEBUG_TRACE,
|
|
|
dc8c34 |
+ "--> pagedresults_get_search_result(%s): idx=%d\n",
|
|
|
dc8c34 |
+ locked?"locked":"not locked", index);
|
|
|
dc8c34 |
if (conn && (index > -1)) {
|
|
|
dc8c34 |
- PR_Lock(conn->c_mutex);
|
|
|
dc8c34 |
+ if (!locked) {
|
|
|
dc8c34 |
+ PR_Lock(conn->c_mutex);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
if (index < conn->c_pagedresults.prl_maxlen) {
|
|
|
dc8c34 |
sr = conn->c_pagedresults.prl_list[index].pr_search_result_set;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
- PR_Unlock(conn->c_mutex);
|
|
|
dc8c34 |
+ if (!locked) {
|
|
|
dc8c34 |
+ PR_Unlock(conn->c_mutex);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
LDAPDebug1Arg(LDAP_DEBUG_TRACE,
|
|
|
dc8c34 |
"<-- pagedresults_get_search_result: %p\n", sr);
|
|
|
dc8c34 |
@@ -429,8 +434,7 @@ pagedresults_get_search_result(Connection *conn, Operation *op, int index)
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
int
|
|
|
dc8c34 |
-pagedresults_set_search_result(Connection *conn, Operation *op, void *sr,
|
|
|
dc8c34 |
- int locked, int index)
|
|
|
dc8c34 |
+pagedresults_set_search_result(Connection *conn, Operation *op, void *sr, int locked, int index)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
int rc = -1;
|
|
|
dc8c34 |
if (!op_is_pagedresults(op)) {
|
|
|
dc8c34 |
@@ -1016,15 +1020,19 @@ pagedresults_unlock( Connection *conn, int index )
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
int
|
|
|
dc8c34 |
-pagedresults_is_abandoned_or_notavailable( Connection *conn, int index )
|
|
|
dc8c34 |
+pagedresults_is_abandoned_or_notavailable(Connection *conn, int locked, int index)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
PagedResults *prp;
|
|
|
dc8c34 |
if (!conn || (index < 0) || (index >= conn->c_pagedresults.prl_maxlen)) {
|
|
|
dc8c34 |
return 1; /* not abandoned, but do not want to proceed paged results op. */
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
- PR_Lock(conn->c_mutex);
|
|
|
dc8c34 |
+ if (!locked) {
|
|
|
dc8c34 |
+ PR_Lock(conn->c_mutex);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
prp = conn->c_pagedresults.prl_list + index;
|
|
|
dc8c34 |
- PR_Unlock(conn->c_mutex);
|
|
|
dc8c34 |
+ if (!locked) {
|
|
|
dc8c34 |
+ PR_Unlock(conn->c_mutex);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
return prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
|
|
|
dc8c34 |
index 8f86eb7..decc29e 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/proto-slap.h
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/proto-slap.h
|
|
|
dc8c34 |
@@ -1438,8 +1438,7 @@ void pagedresults_set_response_control(Slapi_PBlock *pb, int iscritical,
|
|
|
dc8c34 |
int curr_search_count, int index);
|
|
|
dc8c34 |
Slapi_Backend *pagedresults_get_current_be(Connection *conn, int index);
|
|
|
dc8c34 |
int pagedresults_set_current_be(Connection *conn, Slapi_Backend *be, int index, int nolock);
|
|
|
dc8c34 |
-void *pagedresults_get_search_result(Connection *conn, Operation *op,
|
|
|
dc8c34 |
- int index);
|
|
|
dc8c34 |
+void *pagedresults_get_search_result(Connection *conn, Operation *op, int locked, int index);
|
|
|
dc8c34 |
int pagedresults_set_search_result(Connection *conn, Operation *op, void *sr,
|
|
|
dc8c34 |
int locked, int index);
|
|
|
dc8c34 |
int pagedresults_get_search_result_count(Connection *conn, Operation *op,
|
|
|
dc8c34 |
@@ -1480,7 +1479,7 @@ int pagedresults_cleanup_all(Connection *conn, int needlock);
|
|
|
dc8c34 |
void op_set_pagedresults(Operation *op);
|
|
|
dc8c34 |
void pagedresults_lock(Connection *conn, int index);
|
|
|
dc8c34 |
void pagedresults_unlock(Connection *conn, int index);
|
|
|
dc8c34 |
-int pagedresults_is_abandoned_or_notavailable(Connection *conn, int index);
|
|
|
dc8c34 |
+int pagedresults_is_abandoned_or_notavailable(Connection *conn, int locked, int index);
|
|
|
dc8c34 |
int pagedresults_set_search_result_pb(Slapi_PBlock *pb, void *sr, int locked);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/*
|
|
|
dc8c34 |
--
|
|
|
dc8c34 |
2.4.3
|
|
|
dc8c34 |
|