|
|
dc8c34 |
From 0ae7a17ae868530ae461ea70ffcead0a8a8d1880 Mon Sep 17 00:00:00 2001
|
|
|
dc8c34 |
From: Noriko Hosoi <nhosoi@totoro.usersys.redhat.com>
|
|
|
dc8c34 |
Date: Mon, 29 Oct 2012 10:55:05 -0700
|
|
|
dc8c34 |
Subject: [PATCH 10/10] Trac Ticket #498 - Cannot abaondon simple paged result search
|
|
|
dc8c34 |
|
|
|
dc8c34 |
https://fedorahosted.org/389/ticket/498
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Bug Description: The enhancement "Ticket #260 - 389 DS does not
|
|
|
dc8c34 |
support multiple paging controls on a single connection (commit
|
|
|
dc8c34 |
add880accaa28de8304da1c2c2f58fe8af002ebb)" broke the ability to
|
|
|
dc8c34 |
abandon the on-going simple paged result search.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
1) The abandon request expects the operation exist. When sending
|
|
|
dc8c34 |
an abort request, the search operation could have already finished
|
|
|
dc8c34 |
and the operation object has been released.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
2) Plus, request page size is 0, it should be interpreted as abandoned.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Fix Description:
|
|
|
dc8c34 |
1) In do_abandon, this patch eliminates to check if the operation
|
|
|
dc8c34 |
is a simplepaged results oriented or not, since the operation object
|
|
|
dc8c34 |
is often already released. Instead, it directly checks the internal
|
|
|
dc8c34 |
paged results info in the connection object.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
To make sure the abandoned search won't go further, a flag value
|
|
|
dc8c34 |
CONN_FLAG_PAGEDRESULTS_ABANDONED is introduced. If it is set in
|
|
|
dc8c34 |
the pagedresults structure in the connection object, it skips any
|
|
|
dc8c34 |
further process of the search.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
2) This patch is adding a check if the given page size is 0 in the
|
|
|
dc8c34 |
simple-paged-results control or not. If it is 0, treat is as an
|
|
|
dc8c34 |
abandoned operation.
|
|
|
dc8c34 |
(cherry picked from commit 47c0d96ac28c0b1cc15e7bbb77648551c309ccf5)
|
|
|
dc8c34 |
(cherry picked from commit 973886082b1c695a55d503f96b2e74188cbfded6)
|
|
|
dc8c34 |
---
|
|
|
dc8c34 |
ldap/servers/slapd/abandon.c | 10 +++-----
|
|
|
dc8c34 |
ldap/servers/slapd/opshared.c | 17 ++++++++++++--
|
|
|
dc8c34 |
ldap/servers/slapd/pagedresults.c | 41 +++++++++++++++++++++++++-----------
|
|
|
dc8c34 |
ldap/servers/slapd/slap.h | 15 +++++++------
|
|
|
dc8c34 |
4 files changed, 54 insertions(+), 29 deletions(-)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/abandon.c b/ldap/servers/slapd/abandon.c
|
|
|
dc8c34 |
index 094ae95..9639701 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/abandon.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/abandon.c
|
|
|
dc8c34 |
@@ -152,12 +152,10 @@ do_abandon( Slapi_PBlock *pb )
|
|
|
dc8c34 |
0 );
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- if ( op_is_pagedresults(o) ) {
|
|
|
dc8c34 |
- if ( 0 == pagedresults_free_one_msgid_nolock(pb->pb_conn, id) ) {
|
|
|
dc8c34 |
- slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64
|
|
|
dc8c34 |
- " op=%d ABANDON targetop=Simple Paged Results\n",
|
|
|
dc8c34 |
- pb->pb_conn->c_connid, pb->pb_op->o_opid );
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
+ if ( 0 == pagedresults_free_one_msgid_nolock(pb->pb_conn, id) ) {
|
|
|
dc8c34 |
+ slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64
|
|
|
dc8c34 |
+ " op=%d ABANDON targetop=Simple Paged Results\n",
|
|
|
dc8c34 |
+ pb->pb_conn->c_connid, pb->pb_op->o_opid );
|
|
|
dc8c34 |
} else if ( NULL == o ) {
|
|
|
dc8c34 |
slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d ABANDON"
|
|
|
dc8c34 |
" targetop=NOTFOUND msgid=%d\n",
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
|
|
|
dc8c34 |
index 22a3822..2701250 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/opshared.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/opshared.c
|
|
|
dc8c34 |
@@ -197,8 +197,8 @@ void modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods)
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- slapi_mods_add_modbvps(smods, LDAP_MOD_REPLACE | LDAP_MOD_BVALUES,
|
|
|
dc8c34 |
- "modifiersname", bvals);
|
|
|
dc8c34 |
+ slapi_mods_add_modbvps(smods, LDAP_MOD_REPLACE | LDAP_MOD_BVALUES,
|
|
|
dc8c34 |
+ "modifiersname", bvals);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* fill in modifytimestamp */
|
|
|
dc8c34 |
curtime = current_time();
|
|
|
dc8c34 |
@@ -461,7 +461,8 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
|
|
|
dc8c34 |
&pagesize, &pr_idx);
|
|
|
dc8c34 |
/* Let's set pr_idx even if it fails; in case, pr_idx == -1. */
|
|
|
dc8c34 |
slapi_pblock_set(pb, SLAPI_PAGED_RESULTS_INDEX, &pr_idx);
|
|
|
dc8c34 |
- if (LDAP_SUCCESS == rc) {
|
|
|
dc8c34 |
+ if ((LDAP_SUCCESS == rc) ||
|
|
|
dc8c34 |
+ (LDAP_CANCELLED == rc) || (0 == pagesize)) {
|
|
|
dc8c34 |
unsigned int opnote = SLAPI_OP_NOTE_SIMPLEPAGED;
|
|
|
dc8c34 |
if (pagedresults_check_or_set_processing(pb->pb_conn, pr_idx)) {
|
|
|
dc8c34 |
send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM,
|
|
|
dc8c34 |
@@ -483,6 +484,16 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
|
|
|
dc8c34 |
opnote |= SLAPI_OP_NOTE_UNINDEXED;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
slapi_pblock_set( pb, SLAPI_OPERATION_NOTES, &opnote );
|
|
|
dc8c34 |
+ if ((LDAP_CANCELLED == rc) || (0 == pagesize)) {
|
|
|
dc8c34 |
+ /* paged-results-request was abandoned */
|
|
|
dc8c34 |
+ pagedresults_set_response_control(pb, 0, estimate,
|
|
|
dc8c34 |
+ curr_search_count, pr_idx);
|
|
|
dc8c34 |
+ send_ldap_result(pb, 0, NULL,
|
|
|
dc8c34 |
+ "Simple Paged Results Search abandoned",
|
|
|
dc8c34 |
+ 0, NULL);
|
|
|
dc8c34 |
+ rc = LDAP_SUCCESS;
|
|
|
dc8c34 |
+ goto free_and_return;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
/* parse paged-results-control failed */
|
|
|
dc8c34 |
if (iscritical) { /* return an error since it's critical */
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c
|
|
|
dc8c34 |
index d445c06..9b294eb 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/pagedresults.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/pagedresults.c
|
|
|
dc8c34 |
@@ -143,8 +143,13 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
|
|
|
dc8c34 |
slapi_ch_free((void **)&cookie.bv_val);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if ((*index > -1) && (*index < conn->c_pagedresults.prl_maxlen)) {
|
|
|
dc8c34 |
- /* Need to keep the latest msgid to prepare for the abandon. */
|
|
|
dc8c34 |
- conn->c_pagedresults.prl_list[*index].pr_msgid = op->o_msgid;
|
|
|
dc8c34 |
+ if (conn->c_pagedresults.prl_list[*index].pr_flags &
|
|
|
dc8c34 |
+ CONN_FLAG_PAGEDRESULTS_ABANDONED) {
|
|
|
dc8c34 |
+ rc = LDAP_CANCELLED;
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ /* Need to keep the latest msgid to prepare for the abandon. */
|
|
|
dc8c34 |
+ conn->c_pagedresults.prl_list[*index].pr_msgid = op->o_msgid;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
rc = LDAP_PROTOCOL_ERROR;
|
|
|
dc8c34 |
LDAPDebug1Arg(LDAP_DEBUG_ANY,
|
|
|
dc8c34 |
@@ -251,8 +256,13 @@ pagedresults_free_one( Connection *conn, int index )
|
|
|
dc8c34 |
"conn=%d paged requests list count is %d\n",
|
|
|
dc8c34 |
conn->c_connid, conn->c_pagedresults.prl_count);
|
|
|
dc8c34 |
} else if (index < conn->c_pagedresults.prl_maxlen) {
|
|
|
dc8c34 |
- memset(&conn->c_pagedresults.prl_list[index],
|
|
|
dc8c34 |
- '\0', sizeof(PagedResults));
|
|
|
dc8c34 |
+ PagedResults *prp = conn->c_pagedresults.prl_list + index;
|
|
|
dc8c34 |
+ if (prp && prp->pr_current_be &&
|
|
|
dc8c34 |
+ prp->pr_current_be->be_search_results_release &&
|
|
|
dc8c34 |
+ prp->pr_search_result_set) {
|
|
|
dc8c34 |
+ prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set));
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ memset(prp, '\0', sizeof(PagedResults));
|
|
|
dc8c34 |
conn->c_pagedresults.prl_count--;
|
|
|
dc8c34 |
rc = 0;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
@@ -263,34 +273,39 @@ pagedresults_free_one( Connection *conn, int index )
|
|
|
dc8c34 |
return rc;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
+/* Used for abandoning */
|
|
|
dc8c34 |
int
|
|
|
dc8c34 |
pagedresults_free_one_msgid_nolock( Connection *conn, ber_int_t msgid )
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
int rc = -1;
|
|
|
dc8c34 |
int i;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- LDAPDebug1Arg(LDAP_DEBUG_TRACE,
|
|
|
dc8c34 |
- "--> pagedresults_free_one: msgid=%d\n", msgid);
|
|
|
dc8c34 |
if (conn && (msgid > -1)) {
|
|
|
dc8c34 |
if (conn->c_pagedresults.prl_count <= 0) {
|
|
|
dc8c34 |
- LDAPDebug2Args(LDAP_DEBUG_TRACE,
|
|
|
dc8c34 |
- "pagedresults_free_one_msgid_nolock: "
|
|
|
dc8c34 |
- "conn=%d paged requests list count is %d\n",
|
|
|
dc8c34 |
- conn->c_connid, conn->c_pagedresults.prl_count);
|
|
|
dc8c34 |
+ ; /* Not a paged result. */
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
+ LDAPDebug1Arg(LDAP_DEBUG_TRACE,
|
|
|
dc8c34 |
+ "--> pagedresults_free_one: msgid=%d\n", msgid);
|
|
|
dc8c34 |
for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) {
|
|
|
dc8c34 |
if (conn->c_pagedresults.prl_list[i].pr_msgid == msgid) {
|
|
|
dc8c34 |
- memset(&conn->c_pagedresults.prl_list[i],
|
|
|
dc8c34 |
- '\0', sizeof(PagedResults));
|
|
|
dc8c34 |
+ PagedResults *prp = conn->c_pagedresults.prl_list + i;
|
|
|
dc8c34 |
+ if (prp && prp->pr_current_be &&
|
|
|
dc8c34 |
+ prp->pr_current_be->be_search_results_release &&
|
|
|
dc8c34 |
+ prp->pr_search_result_set) {
|
|
|
dc8c34 |
+ prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set));
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ prp->pr_flags |= CONN_FLAG_PAGEDRESULTS_ABANDONED;
|
|
|
dc8c34 |
+ prp->pr_flags &= ~CONN_FLAG_PAGEDRESULTS_PROCESSING;
|
|
|
dc8c34 |
conn->c_pagedresults.prl_count--;
|
|
|
dc8c34 |
rc = 0;
|
|
|
dc8c34 |
break;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
+ LDAPDebug1Arg(LDAP_DEBUG_TRACE,
|
|
|
dc8c34 |
+ "<-- pagedresults_free_one: %d\n", rc);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- LDAPDebug1Arg(LDAP_DEBUG_TRACE, "<-- pagedresults_free_one: %d\n", rc);
|
|
|
dc8c34 |
return rc;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
|
|
|
dc8c34 |
index d0f2b33..e3cbc72 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/slap.h
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/slap.h
|
|
|
dc8c34 |
@@ -1461,16 +1461,17 @@ typedef struct conn {
|
|
|
dc8c34 |
* successfully completed.
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
|
|
|
dc8c34 |
-#define CONN_FLAG_PAGEDRESULTS_WITH_SORT 64 /* paged results control is
|
|
|
dc8c34 |
- * sent with server side sorting
|
|
|
dc8c34 |
- */
|
|
|
dc8c34 |
+#define CONN_FLAG_PAGEDRESULTS_WITH_SORT 64/* paged results control is
|
|
|
dc8c34 |
+ * sent with server side sorting
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
|
|
|
dc8c34 |
-#define CONN_FLAG_PAGEDRESULTS_UNINDEXED 128 /* If the search is unindexed,
|
|
|
dc8c34 |
+#define CONN_FLAG_PAGEDRESULTS_UNINDEXED 128/* If the search is unindexed,
|
|
|
dc8c34 |
* store the info in c_flags
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
-#define CONN_FLAG_PAGEDRESULTS_PROCESSING 256 /* there is an operation
|
|
|
dc8c34 |
- * processing a pagedresults search
|
|
|
dc8c34 |
- */
|
|
|
dc8c34 |
+#define CONN_FLAG_PAGEDRESULTS_PROCESSING 256/* there is an operation
|
|
|
dc8c34 |
+ * processing a pagedresults search
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+#define CONN_FLAG_PAGEDRESULTS_ABANDONED 512/* pagedresults abandoned */
|
|
|
dc8c34 |
#define CONN_GET_SORT_RESULT_CODE (-1)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
#define START_TLS_OID "1.3.6.1.4.1.1466.20037"
|
|
|
dc8c34 |
--
|
|
|
dc8c34 |
1.7.1
|
|
|
dc8c34 |
|