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

ITS#4261 replication



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

While waiting for this patch to get cleaned up, I wrote this up to allow 
configuring the multimaster mode.

-- 
  -- Howard Chu
  Chief Architect, Symas Corp.  http://www.symas.com
  Director, Highland Sun        http://highlandsun.com/hyc
  OpenLDAP Core Team            http://www.openldap.org/project/


--------------000708000308030507070003
Content-Type: text/plain;
 name="dif.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="dif.txt"

Index: add.c
===================================================================
RCS file: /var/CVSROOT/ldap23/servers/slapd/add.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- add.c	5 Feb 2006 01:04:53 -0000	1.9
+++ add.c	5 Feb 2006 08:16:40 -0000	1.10
@@ -284,9 +284,7 @@
 	if ( op->o_bd->be_add ) {
 		/* do the update here */
 		int repl_user = be_isupdate( op );
-#ifndef SLAPD_MULTIMASTER
-		if ( !SLAP_SHADOW(op->o_bd) || repl_user )
-#endif
+		if ( !SLAP_SINGLE_SHADOW(op->o_bd) || repl_user )
 		{
 			int		update = !BER_BVISEMPTY( &op->o_bd->be_update_ndn );
 			slap_callback	cb = { NULL, slap_replog_cb, NULL, NULL };
@@ -328,15 +326,11 @@
 					send_ldap_result( op, rs );
 					goto done;
 				}
-			}
 
-#ifdef SLAPD_MULTIMASTER
-			if ( !repl_user )
-#endif
-			{
 				cb.sc_next = op->o_callback;
 				op->o_callback = &cb;
 			}
+
 			rc = op->o_bd->be_add( op, rs );
 			if ( rc == LDAP_SUCCESS ) {
 				/* NOTE: be_entry_release_w() is
@@ -346,7 +340,6 @@
 				op->o_private = op->o_bd;
 			}
 
-#ifndef SLAPD_MULTIMASTER
 		} else {
 			BerVarray defref = NULL;
 
@@ -369,7 +362,6 @@
 					LDAP_UNWILLING_TO_PERFORM,
 					"shadow context; no update referral" );
 			}
-#endif /* SLAPD_MULTIMASTER */
 		}
 	} else {
 	    Debug( LDAP_DEBUG_ARGS, "	 do_add: no backend support\n", 0, 0, 0 );
Index: bconfig.c
===================================================================
RCS file: /var/CVSROOT/ldap23/servers/slapd/bconfig.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- bconfig.c	18 Jan 2006 14:40:35 -0000	1.11
+++ bconfig.c	5 Feb 2006 08:16:40 -0000	1.12
@@ -162,6 +162,7 @@
 	CFG_SSTR_IF_MAX,
 	CFG_SSTR_IF_MIN,
 	CFG_TTHREADS,
+	CFG_MULTIMASTER,
 
 	CFG_LAST
 };
@@ -361,6 +362,9 @@
 #endif
 		"( OLcfgGlAt:31 NAME 'olcModulePath' "
 			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+	{ "multimaster", "on|off", 2, 2, 0, ARG_DB|ARG_ON_OFF|ARG_MAGIC|CFG_MULTIMASTER,
+		&config_generic, "( OLcfgDbAt:0.16 NAME 'olcMultiMaster' "
+			"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
 	{ "objectclass", "objectclass", 2, 0, 0, ARG_PAREN|ARG_MAGIC|CFG_OC|ARG_NO_DELETE|ARG_NO_INSERT,
 		&config_generic, "( OLcfgGlAt:32 NAME 'olcObjectClasses' "
 		"DESC 'OpenLDAP object classes' "
@@ -667,7 +671,7 @@
 		 "olcMaxDerefDepth $ olcPlugin $ olcReadOnly $ olcReplica $ "
 		 "olcReplogFile $ olcRequires $ olcRestrict $ olcRootDN $ olcRootPW $ "
 		 "olcSchemaDN $ olcSecurity $ olcSizeLimit $ olcSyncrepl $ "
-		 "olcTimeLimit $ olcUpdateDN $ olcUpdateRef ) )",
+		 "olcTimeLimit $ olcUpdateDN $ olcUpdateRef $ olcMultiMaster ) )",
 		 	Cft_Database, NULL, cfAddDatabase },
 	{ "( OLcfgGlOc:5 "
 		"NAME 'olcOverlayConfig' "
@@ -875,6 +879,9 @@
 		case CFG_LASTMOD:
 			c->value_int = (SLAP_NOLASTMOD(c->be) == 0);
 			break;
+		case CFG_MULTIMASTER:
+			c->value_int = (SLAP_SINGLE_SHADOW(c->be) == 0);
+			break;
 		case CFG_SSTR_IF_MAX:
 			c->value_int = index_substr_if_maxlen;
 			break;
@@ -961,6 +968,7 @@
 		case CFG_AZPOLICY:
 		case CFG_DEPTH:
 		case CFG_LASTMOD:
+		case CFG_MULTIMASTER:
 		case CFG_SASLSECP:
 		case CFG_SSTR_IF_MAX:
 		case CFG_SSTR_IF_MIN:
@@ -1235,6 +1243,20 @@
 				SLAP_DBFLAGS(c->be) |= SLAP_DBFLAG_NOLASTMOD;
 			break;
 
+		case CFG_MULTIMASTER:
+			if(!SLAP_SHADOW(c->be)) {
+				snprintf( c->msg, sizeof( c->msg ), "<%s> database is not a shadow",
+					c->argv[0] );
+				Debug(LDAP_DEBUG_ANY, "%s: %s\n",
+					c->log, c->msg, 0 );
+				return(1);
+			}
+			if(c->value_int)
+				SLAP_DBFLAGS(c->be) &= ~SLAP_DBFLAG_SINGLE_SHADOW;
+			else
+				SLAP_DBFLAGS(c->be) |= SLAP_DBFLAG_SINGLE_SHADOW;
+			break;
+
 		case CFG_SSTR_IF_MAX:
 			if (c->value_int < index_substr_if_minlen) {
 				snprintf( c->msg, sizeof( c->msg ), "<%s> invalid value", c->argv[0] );
@@ -2576,7 +2598,7 @@
 		return 1;
 	}
 
-	SLAP_DBFLAGS(c->be) |= (SLAP_DBFLAG_SHADOW | flag);
+	SLAP_DBFLAGS(c->be) |= (SLAP_DBFLAG_SHADOW | SLAP_DBFLAG_SINGLE_SHADOW | flag);
 
 	return 0;
 }
Index: delete.c
===================================================================
RCS file: /var/CVSROOT/ldap23/servers/slapd/delete.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- delete.c	18 Jan 2006 14:40:35 -0000	1.6
+++ delete.c	5 Feb 2006 08:16:40 -0000	1.7
@@ -155,9 +155,7 @@
 	if ( op->o_bd->be_delete ) {
 		/* do the update here */
 		int repl_user = be_isupdate( op );
-#ifndef SLAPD_MULTIMASTER
-		if ( !SLAP_SHADOW(op->o_bd) || repl_user )
-#endif
+		if ( !SLAP_SINGLE_SHADOW(op->o_bd) || repl_user )
 		{
 			struct berval	org_req_dn = BER_BVNULL;
 			struct berval	org_req_ndn = BER_BVNULL;
@@ -168,9 +166,7 @@
 
 			op->o_bd = op_be;
 
-#ifdef SLAPD_MULTIMASTER
 			if ( !op->o_bd->be_update_ndn.bv_len || !repl_user )
-#endif
 			{
 				cb.sc_next = op->o_callback;
 				op->o_callback = &cb;
@@ -211,7 +207,6 @@
 			op->o_req_ndn = org_req_ndn;
 			op->o_delete_glue_parent = 0;
 
-#ifndef SLAPD_MULTIMASTER
 		} else {
 			BerVarray defref = op->o_bd->be_update_refs
 				? op->o_bd->be_update_refs : default_referral;
@@ -230,7 +225,6 @@
 					LDAP_UNWILLING_TO_PERFORM,
 					"shadow context; no update referral" );
 			}
-#endif
 		}
 
 	} else {
Index: modify.c
===================================================================
RCS file: /var/CVSROOT/ldap23/servers/slapd/modify.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- modify.c	5 Feb 2006 01:04:53 -0000	1.9
+++ modify.c	5 Feb 2006 08:16:40 -0000	1.10
@@ -364,9 +364,7 @@
 		/* Multimaster slapd does not have to check for replicator dn
 		 * because it accepts each modify request
 		 */
-#ifndef SLAPD_MULTIMASTER
-		if ( !SLAP_SHADOW(op->o_bd) || repl_user )
-#endif
+		if ( !SLAP_SINGLE_SHADOW(op->o_bd) || repl_user )
 		{
 			int		update = !BER_BVISEMPTY( &op->o_bd->be_update_ndn );
 			slap_callback	cb = { NULL, slap_replog_cb, NULL, NULL };
@@ -383,9 +381,7 @@
 			}
 
 			op->orm_modlist = modlist;
-#ifdef SLAPD_MULTIMASTER
 			if ( !repl_user )
-#endif
 			{
 				/* but multimaster slapd logs only the ones 
 				 * not from a replicator user */
@@ -394,7 +390,6 @@
 			}
 			op->o_bd->be_modify( op, rs );
 
-#ifndef SLAPD_MULTIMASTER
 		/* send a referral */
 		} else {
 			BerVarray defref = op->o_bd->be_update_refs
@@ -418,7 +413,6 @@
 				send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
 					"shadow context; no update referral" );
 			}
-#endif
 		}
 	} else {
 		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
Index: modrdn.c
===================================================================
RCS file: /var/CVSROOT/ldap23/servers/slapd/modrdn.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- modrdn.c	18 Jan 2006 14:40:35 -0000	1.6
+++ modrdn.c	5 Feb 2006 08:16:40 -0000	1.7
@@ -286,17 +286,13 @@
 	if ( op->o_bd->be_modrdn ) {
 		/* do the update here */
 		int repl_user = be_isupdate( op );
-#ifndef SLAPD_MULTIMASTER
-		if ( !SLAP_SHADOW(op->o_bd) || repl_user )
-#endif /* ! SLAPD_MULTIMASTER */
+		if ( !SLAP_SINGLE_SHADOW(op->o_bd) || repl_user )
 		{
 			slap_callback cb = { NULL, slap_replog_cb, NULL, NULL };
 
 			op->o_bd = op_be;
 
-#ifdef SLAPD_MULTIMASTER
 			if ( !op->o_bd->be_update_ndn.bv_len || !repl_user )
-#endif /* SLAPD_MULTIMASTER */
 			{
 				cb.sc_next = op->o_callback;
 				op->o_callback = &cb;
@@ -342,7 +338,6 @@
 				op->o_delete_glue_parent = 0;
 			}
 
-#ifndef SLAPD_MULTIMASTER
 		} else {
 			BerVarray defref = op->o_bd->be_update_refs
 				? op->o_bd->be_update_refs : default_referral;
@@ -360,7 +355,6 @@
 				send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
 					"shadow context; no update referral" );
 			}
-#endif /* ! SLAPD_MULTIMASTER */
 		}
 	} else {
 		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
Index: passwd.c
===================================================================
RCS file: /var/CVSROOT/ldap23/servers/slapd/passwd.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- passwd.c	12 Jan 2006 17:27:10 -0000	1.4
+++ passwd.c	5 Feb 2006 08:16:40 -0000	1.5
@@ -153,9 +153,8 @@
 		goto error_return;
 	}
 
-#ifndef SLAPD_MULTIMASTER
 	/* This does not apply to multi-master case */
-	if(!( !SLAP_SHADOW( op->o_bd ) || be_isupdate( op ))) {
+	if(!( !SLAP_SINGLE_SHADOW( op->o_bd ) || be_isupdate( op ))) {
 		/* we SHOULD return a referral in this case */
 		BerVarray defref = op->o_bd->be_update_refs
 			? op->o_bd->be_update_refs : default_referral; 
@@ -177,7 +176,6 @@
 		rc = LDAP_UNWILLING_TO_PERFORM;
 		goto error_return;
 	}
-#endif /* !SLAPD_MULTIMASTER */
 
 	/* generate a new password if none was provided */
 	if ( qpw->rs_new.bv_len == 0 ) {
Index: slap.h
===================================================================
RCS file: /var/CVSROOT/ldap23/servers/slapd/slap.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- slap.h	12 Jan 2006 17:27:11 -0000	1.8
+++ slap.h	5 Feb 2006 08:16:40 -0000	1.9
@@ -1738,6 +1738,7 @@
 #define SLAP_DBFLAG_OVERLAY		0x0100U	/* this db struct is an overlay */
 #define	SLAP_DBFLAG_GLOBAL_OVERLAY	0x0200U	/* this db struct is a global overlay */
 #define SLAP_DBFLAG_SHADOW		0x8000U /* a shadow */
+#define	SLAP_DBFLAG_SINGLE_SHADOW	0x4000U	/* a single-master shadow */
 #define SLAP_DBFLAG_SYNC_SHADOW		0x1000U /* a sync shadow */
 #define SLAP_DBFLAG_SLURP_SHADOW	0x2000U /* a slurp shadow */
 	slap_mask_t	be_flags;
@@ -1758,6 +1759,8 @@
 #define SLAP_SHADOW(be)				(SLAP_DBFLAGS(be) & SLAP_DBFLAG_SHADOW)
 #define SLAP_SYNC_SHADOW(be)			(SLAP_DBFLAGS(be) & SLAP_DBFLAG_SYNC_SHADOW)
 #define SLAP_SLURP_SHADOW(be)			(SLAP_DBFLAGS(be) & SLAP_DBFLAG_SLURP_SHADOW)
+#define SLAP_SINGLE_SHADOW(be)			(SLAP_DBFLAGS(be) & SLAP_DBFLAG_SINGLE_SHADOW)
+#define SLAP_MULTIMASTER(be)			(!SLAP_SINGLE_SHADOW(be))
 
 	slap_mask_t	be_restrictops;		/* restriction operations */
 #define SLAP_RESTRICT_OP_ADD		0x0001U

--------------000708000308030507070003
Content-Type: text/plain;
 name="mandif.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="mandif.txt"

Index: slapd.conf.5
===================================================================
RCS file: /var/CVSROOT/ldap23/doc/man/man5/slapd.conf.5,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- slapd.conf.5	26 Jan 2006 01:00:13 -0000	1.9
+++ slapd.conf.5	5 Feb 2006 08:22:24 -0000	1.10
@@ -1295,6 +1295,12 @@
 Specifies the maximum number of aliases to dereference when trying to
 resolve an entry, used to avoid infinite alias loops. The default is 1.
 .TP
+.B multimaster on | off
+This option puts a replica database into "multimaster" mode.  Update
+operations will be accepted from any user, not just the updatedn.  The
+database must already be configured as a slurpd or syncrepl consumer
+before this keyword may be set.  By default, multimaster is off.
+.TP
 .B overlay <overlay-name>
 Add the specified overlay to this database. An overlay is a piece of
 code that intercepts database operations in order to extend or change

--------------000708000308030507070003--