Commit 9bf3ccd0 authored by Pierangelo Masarati's avatar Pierangelo Masarati
Browse files

allow attribute exclusion list in selective replica

parent bcc486df
......@@ -1830,16 +1830,29 @@ read_config( const char *fname )
#endif
break;
}
} else if ( strncasecmp( cargv[i], "attr=", 5 ) == 0 ) {
if ( add_replica_attrs( be, nr, cargv[i] + 5 ) ) {
} else if ( strncasecmp( cargv[i], "attr", 4 ) == 0 ) {
int exclude = 0;
char *arg = cargv[i] + 4;
if ( arg[0] == '!' ) {
arg++;
exclude = 1;
}
if ( arg[0] != '=' ) {
continue;
}
if ( add_replica_attrs( be, nr, arg + 1, exclude ) ) {
#ifdef NEW_LOGGING
LDAP_LOG(( "config", LDAP_LEVEL_INFO,
"%s: line %d: attribute \"%s\" in \"replica\" line is unknown\n",
fname, lineno, cargv[i] + 5 ));
fname, lineno, arg + 1 ));
#else
Debug( LDAP_DEBUG_ANY,
"%s: line %d: attribute \"%s\" in \"replica\" line is unknown\n",
fname, lineno, cargv[i] + 5 );
fname, lineno, arg + 1 );
#endif
return( 1 );
}
......
......@@ -715,7 +715,7 @@ LDAP_SLAPD_F (int) add_replica_info LDAP_P(( Backend *be,
LDAP_SLAPD_F (int) add_replica_suffix LDAP_P(( Backend *be,
int nr, const char *suffix ));
LDAP_SLAPD_F (int) add_replica_attrs LDAP_P(( Backend *be,
int nr, char *attrs ));
int nr, char *attrs, int exclude ));
LDAP_SLAPD_F (void) replog LDAP_P(( Backend *be, Operation *op,
struct berval *dn, struct berval *ndn, void *change ));
......
......@@ -41,6 +41,8 @@ add_replica_info(
be->be_replica[ i ]
= ch_calloc( sizeof( struct slap_replica_info ), 1 );
be->be_replica[ i ]->ri_host = ch_strdup( host );
be->be_replica[ i ]->ri_nsuffix = NULL;
be->be_replica[ i ]->ri_attrs = NULL;
be->be_replica[ i + 1 ] = NULL;
return( i );
......@@ -77,9 +79,19 @@ int
add_replica_attrs(
Backend *be,
int nr,
char *attrs
char *attrs,
int exclude
)
{
if ( be->be_replica[nr]->ri_attrs != NULL ) {
if ( be->be_replica[nr]->ri_exclude != exclude ) {
fprintf( stderr, "attr selective replication directive '%s' conflicts with previous one (discarded)\n", attrs );
ch_free( be->be_replica[nr]->ri_attrs );
be->be_replica[nr]->ri_attrs = NULL;
}
}
be->be_replica[nr]->ri_exclude = exclude;
be->be_replica[nr]->ri_attrs = str2anlist( be->be_replica[nr]->ri_attrs,
attrs, "," );
return ( be->be_replica[nr]->ri_attrs == NULL );
......@@ -203,7 +215,16 @@ replog(
/* fall thru */
case LDAP_REQ_MODIFY:
for ( ml = change; ml != NULL; ml = ml->sml_next ) {
if ( ad_inlist( ml->sml_desc, be->be_replica[i]->ri_attrs ) ) {
int is_in, exclude;
is_in = ad_inlist( ml->sml_desc, be->be_replica[i]->ri_attrs );
exclude = be->be_replica[i]->ri_exclude;
/*
* there might be a more clever way to do this test,
* but this way, at least, is comprehensible :)
*/
if ( ( is_in && !exclude ) || ( !is_in && exclude ) ) {
subsets = 1;
first = ml;
break;
......@@ -216,7 +237,12 @@ replog(
case LDAP_REQ_ADD:
e = change;
for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
if ( ad_inlist( a->a_desc, be->be_replica[i]->ri_attrs ) ) {
int is_in, exclude;
is_in = ad_inlist( a->a_desc, be->be_replica[i]->ri_attrs );
exclude = be->be_replica[i]->ri_exclude;
if ( ( is_in && !exclude ) || ( !is_in && exclude ) ) {
subsets = 1;
first = a;
break;
......@@ -267,8 +293,12 @@ replog1(
ml = first ? first : change;
for ( ; ml != NULL; ml = ml->sml_next ) {
char *type;
if ( ri && ri->ri_attrs && !ad_inlist( ml->sml_desc, ri->ri_attrs ) ) {
continue;
if ( ri && ri->ri_attrs ) {
int is_in = ad_inlist( ml->sml_desc, ri->ri_attrs );
if ( ( !is_in && !ri->ri_exclude ) || ( is_in && ri->ri_exclude ) ) {
continue;
}
}
type = ml->sml_desc->ad_cname.bv_val;
switch ( ml->sml_op ) {
......@@ -296,7 +326,8 @@ replog1(
a = first ? first : e->e_attrs;
for ( ; a != NULL; a=a->a_next ) {
if ( ri && ri->ri_attrs ) {
if ( !ad_inlist( a->a_desc, ri->ri_attrs ) ) {
int is_in = ad_inlist( a->a_desc, ri->ri_attrs );
if ( ( !is_in && !ri->ri_exclude ) || ( is_in && ri->ri_exclude ) ) {
continue;
}
/* If the list includes objectClass names,
......
......@@ -1006,6 +1006,7 @@ struct slap_replica_info {
char *ri_host; /* supersedes be_replica */
struct berval **ri_nsuffix; /* array of suffixes this replica accepts */
AttributeName *ri_attrs; /* attrs to replicate, NULL=all */
int ri_exclude; /* 1 => exclude ri_attrs */
};
struct slap_limits_set {
......
......@@ -201,7 +201,7 @@ int add_replica_suffix( Backend *be, int nr, const char *suffix )
return 0;
}
int add_replica_attrs( Backend *be, int nr, char *attrs )
int add_replica_attrs( Backend *be, int nr, char *attrs, int exclude )
{
return 0;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment