This is a multi-part message in MIME format.
--------------050807020608030505070800
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8bit
Michael Ströder wrote:
hyc@symas.com wrote:
I was considering returning LDAP_BUSY for this case, but it may make more
sense to return a REFERRAL to the provider instead. (Although again, if we
have two MMR servers pointed at each other starting at the same time, they
would just refer to each other and clients would get nowhere until one of them
finishes its refresh.)
IMO referrals are harmful.
Just returning LDAP_BUSY seems best to me because if reliable HA is really
important for a deployment you have decent load-balancers in front of your
LDAP server which should do a proper health-check.
The attached patch should provide the desired behavior. It needs more testing
though.
--
-- Howard Chu
CTO, Symas Corp.
http://www.symas.com
Director, Highland Sun
http://highlandsun.com/hyc/
Chief Architect, OpenLDAP
http://www.openldap.org/project/
--------------050807020608030505070800
Content-Type: text/plain; charset=UTF-8;
name="diff.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="diff.txt"
diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c
index 9b5c0f3..4ea8a70 100644
--- a/servers/slapd/syncrepl.c
+++ b/servers/slapd/syncrepl.c
@@ -148,6 +148,8 @@ static int syncrepl_add_glue_ancestors(
/* delta-mmr overlay handler */
static int syncrepl_op_modify( Operation *op, SlapReply *rs );
+static int syncrepl_op_search( Operation *op, SlapReply *rs );
+
/* callback functions */
static int dn_callback( Operation *, SlapReply * );
static int nonpresent_callback( Operation *, SlapReply * );
@@ -216,16 +218,14 @@ init_syncrepl(syncinfo_t *si)
if ( !syncrepl_ov.on_bi.bi_type ) {
syncrepl_ov.on_bi.bi_type = "syncrepl";
syncrepl_ov.on_bi.bi_op_modify = syncrepl_op_modify;
+ syncrepl_ov.on_bi.bi_op_search = syncrepl_op_search;
overlay_register( &syncrepl_ov );
}
- /* delta-MMR needs the overlay, nothing else does.
- * This must happen before accesslog overlay is configured.
- */
- if ( si->si_syncdata &&
- !overlay_is_inst( si->si_be, syncrepl_ov.on_bi.bi_type )) {
+ if (!overlay_is_inst( si->si_be, syncrepl_ov.on_bi.bi_type )) {
overlay_config( si->si_be, syncrepl_ov.on_bi.bi_type, -1, NULL, NULL );
- if ( !ad_reqMod ) {
+ /* delta-MMR needs this. Must happen before accesslog overlay is configured. */
+ if ( si->si_syncdata && !ad_reqMod ) {
const char *text;
logschema *ls = &accesslog_sc;
@@ -1179,6 +1179,7 @@ do_syncrep2(
} else {
rc = -2;
}
+ si->si_refreshDone = 1;
goto done;
case LDAP_RES_INTERMEDIATE:
@@ -2164,6 +2165,31 @@ syncrepl_op_modify( Operation *op, SlapReply *rs )
}
static int
+syncrepl_op_search( Operation *op, SlapReply *rs )
+{
+ slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
+ syncinfo_t *si;
+
+ /* Allow syncrepl internal searches */
+ if ( op->o_conn->c_conn_idx == -1 )
+ return SLAP_CB_CONTINUE;
+
+ /* Check if any of our consumers are refreshing */
+ for ( si = op->o_bd->be_syncinfo; si; si = si->si_next ) {
+ /* If we have some state, allow other consumers to progress */
+ if ( si->si_cookieState->cs_num > 0 &&
+ op->o_sync > SLAP_CONTROL_IGNORED )
+ return SLAP_CB_CONTINUE;
+ /* If we have any consumer refreshing, reject searches */
+ if ( !si->si_refreshDone ) {
+ send_ldap_error( op, rs, LDAP_BUSY, "syncrepl refresh in progress" );
+ return rs->sr_err;
+ }
+ }
+ return SLAP_CB_CONTINUE;
+}
+
+static int
syncrepl_message_to_op(
syncinfo_t *si,
Operation *op,
--------------050807020608030505070800--