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

RE: A couple of slapd/slurpd replication suggestions.



I have also added multiple master capability.  But did it by using
a second port for all replication updates.  This makes sure that
multiple masters/slaves are duplicates of each other regardless of where
the original update was done.

	Bob Rothlisberger
	rwroth@netdox.com

> -----Original Message-----
> From:	Stephen Rush [SMTP:Stephen.Rush@liffe.com]
> Sent:	Friday, January 15, 1999 9:11 AM
> To:	openldap-devel@OpenLDAP.org
> Subject:	A couple of slapd/slurpd replication suggestions.
> 
> Hi, 
> 
> After a couple of weeks configuring/playing around with slapd and
> slurpd I
> have a couple of suggestions: 
> 
> Firstly: Whilst writing some scripts to generate slapd configuration
> files
> for a number of machines I was quite surprised to find that slurpd
> does not
> read include files. Hence, if you have a configuration file of the
> form:
> 
> 	# Main Configuration File 
> 	database ldbm
> 	#    :
> 	#    :
> 	include    /usr/local/LDAP/slapd_replication_config
> 	#    :
> 
> together with a /usr/local/LDAP/slapd_replication_config file 
> 
> 		# Definition of replication details
> 		replica	host=xxx .......
> 
> Then slapd will read the replication configuration file but slurpd
> will not,
> hence slurpd will complain that there are no replicas specified in the
> config file and will abort. The changes to allow slurpd to read
> include
> files appear pretty simple and are based on the slapd configuration
> routines
> (see below).
> Is there any reason for not allowing this to be done? 
> 
> Secondly: Replication in LDAP has an obvious master slave relationship
> between a master who stores the data and a number of slaves which can
> be
> used for read access to it. slurpd allows the master to replicate data
> to
> the slaves, but there appears to be no way for slaves to replicate
> data back
> to the master if a client performs an update on one of the slaves
> rather
> than on the master. (If they use slurpd then the updates end up in an
> infinite cycle).
> However, for clients to use this model in write mode they must always
> be
> aware of which server is the master and which ones are not (otherwise
> their
> updates will not be replicated to the other servers). In our
> application at
> least, this seems to be a rather unnecessary restriction. 
> Whilst I'm sure the slaves could generate a referral and it could all
> be
> made to work, this seems rather a complicated way to do things. 
> Instead, slurpd/slapd currently have a configuration parameter which
> indicates the dn to use when performing replication. Would it not be
> reasonable to have a further configuration item which indicates a dn
> for a
> user who can perform updates to the database, but who's updates are
> not
> themselves replicated. 
> Again, the changes are not large (though they touch a few more files,
> see
> below) and perhaps other people may also find them useful. Are there
> any
> pressing reasons why this kind of functionality should not be allowed?
> 
> If this were allowed then the following configuration files would
> allow two
> slapd servers to replicate changes to each other. 
> 
> --------------- SLAPD_CONFIG_HOST_1
> -------------------------------------
> # SLAPD CONFIG FILE FOR HOST1 - REPLICTES TO HOST2
> # The backup database will replicate to us as this user, do NOT
> replicate 
> # these changes on to anyone else or we get in a loop. 
> updatenorepdn	"cn=replicator2,o=organisation,c=UK"
> 	
> # The root user can access anything, as can the replication users. 
> access to *	by "dn=cn=admin,o=organisation,c=UK" write 
> 				by
> "dn=cn=replicator2,o=organisation,c=UK"
> write 
> 	
> # Nobody else needs to be able to do anything at all.
> defaultaccess 	none
> 
> replica		host=host2
> 
> "binddn=cn=replicator1,o=organisation,c=UK"
> 				bindmethod=simple
> 				credentials=password
> # END
> 
> --------------- SLAPD_CONFIG_HOST_2
> -------------------------------------
> # SLAPD CONFIG FILE FOR HOST2 - REPLICTES TO HOST1
> # The backup database will replicate to us as this user, do NOT
> replicate 
> # these changes on to anyone else or we get in a loop. 
> updatenorepdn	"cn=replicator1,o=organisation,c=UK"
> 
> # The root user can access anything, as can the replication users. 
> access to *	by "dn=cn=admin,o=organisation,c=UK" write 
> 				by
> "dn=cn=replicator1,o=organisation,c=UK"
> write 
> 	
> 	# Nobody else needs to be able to do anything at all.
> defaultaccess 	none
> 
> replica		host=host1
> 
> "binddn=cn=replicator2,o=organisation,c=UK"
> 				bindmethod=simple
> 				credentials=password
> # END
> 
> 
> Any comments on either of these suggestions ? 
> 
> Steve R
> 
> 
> 1)	Changes to allow slurpd to read nested include files:
> 
> 	*** ldap/servers/slurpd/config.c	Fri Jan 15 14:27:30 1999
> 	--- ldap/servers/slurpd/config.c.save	Fri Jan 15 14:27:20 1999
> 	***************
> 	*** 56,61 ****
> 	--- 56,62 ----
> 	  {
> 	      FILE	*fp;
> 	      char	*line;
> 	+     char	*savefname;
> 	      int		cargc;
> 	      char	*cargv[MAXARGS];
> 	  
> 	***************
> 	*** 107,112 ****
> 	--- 108,123 ----
> 	  	    }
> 	  	} else if ( strcasecmp( cargv[0], "replica" ) == 0 ) {
> 	  	    add_replica( cargv, cargc );
> 	+ 	} else if ( strcasecmp( cargv[0], "include" ) == 0 ) {
> 	+ 		if ( cargc < 2 ) {
> 	+ 			Debug( LDAP_DEBUG_ANY,
> 	+ 			       "%s: missing filename in
> \"include
> <filename>\" line\n",
> 	+ 			       fname, 0, 0 );
> 	+ 			exit( 1 );
> 	+ 		}
> 	+ 		savefname = strdup( cargv[1] );
> 	+ 		slurpd_read_config( savefname);
> 	+ 		free( savefname );
> 	  	}
> 	      }
> 	      fclose( fp );
> 
> 2)	Changes to allow replication from slaves back to the master
> server.
> 
> *** ldap/servers/slapd/add.c	Fri Jan 15 15:00:14 1999
> --- ldap/servers/slapd/add.c.save	Fri Jan 15 14:57:37 1999
> ***************
> *** 119,125 ****
>   	if ( be->be_add != NULL ) {
>   		/* do the update here */
>   		if ( be->be_updatedn == NULL ||
> ! 			strcasecmp( be->be_updatedn, op->o_dn ) == 0 ) {
>   
>   			if ( (be->be_lastmod == ON || (be->be_lastmod ==
> UNDEFINED &&
>   				global_lastmod == ON)) &&
> be->be_updatedn ==
> NULL ) {
> --- 119,127 ----
>   	if ( be->be_add != NULL ) {
>   		/* do the update here */
>   		if ( be->be_updatedn == NULL ||
> ! 		     strcasecmp( be->be_updatedn, op->o_dn ) == 0 ||
> ! 		     (be->be_updatenorepdn && 
> ! 		      strcasecmp( be->be_updatenorepdn, op->o_dn ) == 0
> )) {
>   
>   			if ( (be->be_lastmod == ON || (be->be_lastmod ==
> UNDEFINED &&
>   				global_lastmod == ON)) &&
> be->be_updatedn ==
> NULL ) {
> ***************
> *** 127,133 ****
>   				add_created_attrs( op, e );
>   			}
>   			if ( (*be->be_add)( be, conn, op, e ) == 0 ) {
> ! 				replog( be, LDAP_REQ_ADD, e->e_dn, e, 0
> );
>   			}
>   
>   		} else {
> --- 129,138 ----
>   				add_created_attrs( op, e );
>   			}
>   			if ( (*be->be_add)( be, conn, op, e ) == 0 ) {
> ! 			  	if (!be->be_updatenorepdn ||
> ! 				    strcasecmp( be->be_updatenorepdn,
> op->o_dn ) != 0) {
> ! 				  	replog( be, LDAP_REQ_ADD,
> e->e_dn,
> e, 0 );
> ! 				}
>   			}
>   
>   		} else {
> *** ldap/servers/slapd/config.c	Fri Jan 15 15:00:14 1999
> --- ldap/servers/slapd/config.c.save	Fri Jan 15 14:57:37 1999
> ***************
> *** 355,360 ****
> --- 355,375 ----
>   				be->be_updatedn = ch_strdup( cargv[1] );
>   				(void) dn_normalize( be->be_updatedn );
>   			}
> + 		} else if ( strcasecmp( cargv[0], "updatenorepdn" ) == 0
> ) {
> + 			if ( cargc < 2 ) {
> + 				Debug( LDAP_DEBUG_ANY,
> + 		    "%s: line %d: missing dn in \"updatenorepdn <dn>\"
> line\n",
> + 				    fname, lineno, 0 );
> + 				exit( 1 );
> + 			}
> + 			if ( be == NULL ) {
> + 				Debug( LDAP_DEBUG_ANY,
> + "%s: line %d: updatenorepdn line must appear inside a database
> definition
> (ignored)\n",
> + 				    fname, lineno, 0 );
> + 			} else {
> + 				be->be_updatenorepdn = ch_strdup(
> cargv[1]
> );
> + 				(void) dn_normalize(
> be->be_updatenorepdn );
> + 			}
>   
>   		/* replication log file to which changes are appended */
>   		} else if ( strcasecmp( cargv[0], "replogfile" ) == 0 )
> {
> *** ldap/servers/slapd/delete.c	Fri Jan 15 15:00:14 1999
> --- ldap/servers/slapd/delete.c.save	Fri Jan 15 14:57:37 1999
> ***************
> *** 72,81 ****
>   	 */
>   	if ( be->be_delete != NULL ) {
>   		/* do the update here */
> ! 		if ( be->be_updatedn == NULL || strcasecmp(
> be->be_updatedn,
> ! 		    op->o_dn ) == 0 ) {
>   			if ( (*be->be_delete)( be, conn, op, dn ) == 0 )
> {
> ! 				replog( be, LDAP_REQ_DELETE, odn, NULL,
> 0 );
>   			}
>   		} else {
>   			send_ldap_result( conn, op,
> LDAP_PARTIAL_RESULTS,
> NULL,
> --- 72,85 ----
>   	 */
>   	if ( be->be_delete != NULL ) {
>   		/* do the update here */
> ! 		if ( be->be_updatedn == NULL || 
> ! 		     strcasecmp( be->be_updatedn, op->o_dn ) == 0 ||
> ! 		     (be->be_updatenorepdn && strcasecmp(
> be->be_updatenorepdn, op->o_dn ) == 0)) {
>   			if ( (*be->be_delete)( be, conn, op, dn ) == 0 )
> {
> ! 			  	if (!be->be_updatenorepdn || 
> ! 				    strcasecmp( be->be_updatenorepdn,
> op->o_dn ) != 0) {
> ! 				  	replog( be, LDAP_REQ_DELETE,
> odn,
> NULL, 0 );
> ! 				}
>   			}
>   		} else {
>   			send_ldap_result( conn, op,
> LDAP_PARTIAL_RESULTS,
> NULL,
> *** ldap/servers/slapd/modify.c	Fri Jan 15 15:00:14 1999
> --- ldap/servers/slapd/modify.c.save	Fri Jan 15 14:57:37 1999
> ***************
> *** 156,162 ****
>   	if ( be->be_modify != NULL ) {
>   		/* do the update here */
>   		if ( be->be_updatedn == NULL ||
> ! 			strcasecmp( be->be_updatedn, op->o_dn ) == 0 ) {
>   
>   			if ( (be->be_lastmod == ON || ( be->be_lastmod
> ==
> UNDEFINED &&
>   				global_lastmod == ON ) ) &&
> be->be_updatedn
> == NULL ) {
> --- 156,164 ----
>   	if ( be->be_modify != NULL ) {
>   		/* do the update here */
>   		if ( be->be_updatedn == NULL ||
> ! 		     strcasecmp( be->be_updatedn, op->o_dn ) == 0 ||
> ! 		     (be->be_updatenorepdn && 
> ! 		      strcasecmp( be->be_updatenorepdn, op->o_dn ) ==
> 0)) {
>   
>   			if ( (be->be_lastmod == ON || ( be->be_lastmod
> ==
> UNDEFINED &&
>   				global_lastmod == ON ) ) &&
> be->be_updatedn
> == NULL ) {
> ***************
> *** 163,171 ****
>   				add_lastmods( op, &mods );
>   			}
>   			if ( (*be->be_modify)( be, conn, op, odn, mods )
> ==
> 0 ) {
> ! 				replog( be, LDAP_REQ_MODIFY, dn, mods, 0
> );
>   			}
> ! 
>   		/* send a referral */
>   		} else {
>   			send_ldap_result( conn, op,
> LDAP_PARTIAL_RESULTS,
> NULL,
> --- 165,176 ----
>   				add_lastmods( op, &mods );
>   			}
>   			if ( (*be->be_modify)( be, conn, op, odn, mods )
> ==
> 0 ) {
> ! 			  	if (!be->be_updatenorepdn ||
> ! 				    strcasecmp( be->be_updatenorepdn,
> op->o_dn ) != 0) {
> ! 				  	replog( be, LDAP_REQ_MODIFY, dn,
> mods, 0 );
> ! 				}
>   			}
> ! 			
>   		/* send a referral */
>   		} else {
>   			send_ldap_result( conn, op,
> LDAP_PARTIAL_RESULTS,
> NULL,
> *** ldap/servers/slapd/modrdn.c	Fri Jan 15 15:00:14 1999
> --- ldap/servers/slapd/modrdn.c.save	Fri Jan 15 14:57:38 1999
> ***************
> *** 79,90 ****
>   	 */
>   	if ( be->be_modrdn != NULL ) {
>   		/* do the update here */
> ! 		if ( be->be_updatedn == NULL || strcasecmp(
> be->be_updatedn,
> ! 		    op->o_dn ) == 0 ) {
> ! 			if ( (*be->be_modrdn)( be, conn, op, dn, newrdn,
> ! 			    deloldrdn ) == 0 ) {
> ! 				replog( be, LDAP_REQ_MODRDN, odn,
> newrdn,
> ! 				    deloldrdn );
>   			}
>   		} else {
>   			send_ldap_result( conn, op,
> LDAP_PARTIAL_RESULTS,
> NULL,
> --- 79,93 ----
>   	 */
>   	if ( be->be_modrdn != NULL ) {
>   		/* do the update here */
> ! 	  	if ( be->be_updatedn == NULL || 
> ! 		     strcasecmp( be->be_updatedn, op->o_dn ) == 0 ||
> ! 		     (be->be_updatenorepdn && 
> ! 		      strcasecmp( be->be_updatenorepdn, op->o_dn ) == 0
> )) {
> ! 		  	if ( (*be->be_modrdn)( be, conn, op, dn, newrdn,
> deloldrdn ) == 0 ) {
> ! 			  	if (!be->be_updatenorepdn ||
> ! 				    strcasecmp( be->be_updatenorepdn,
> op->o_dn ) != 0) {
> ! 				  	replog( be, LDAP_REQ_MODRDN,
> odn,
> newrdn, deloldrdn );
> ! 				}
>   			}
>   		} else {
>   			send_ldap_result( conn, op,
> LDAP_PARTIAL_RESULTS,
> NULL,
> *** ldap/servers/slapd/slap.h	Fri Jan 15 15:00:14 1999
> --- ldap/servers/slapd/slap.h.save	Fri Jan 15 14:57:38 1999
> ***************
> *** 206,211 ****
> --- 206,212 ----
>   	char	**be_replica;	/* replicas of this backend (in master)
> */
>   	char	*be_replogfile;	/* replication log file (in master)
> */
>   	char	*be_updatedn;	/* allowed to make changes (in replicas)
> */
> + 	char	*be_updatenorepdn;	/* allowed to make changes no
> replication */
>   	int	be_lastmod;	/* keep track of lastmodified{by,time}
> */
>   	char	*be_type;	/* type of database
> */
>   
> 
> 
>