[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: (ITS#7616) syncrepl enhancement: defer requests when refreshing



This is a multi-part message in MIME format.
--------------050807020608030505070800
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8bit

hyc@symas.com wrote:
> 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--