]> git.sur5r.net Git - openldap/commitdiff
Added replica attr=<attribute list> support to filter replog content
authorHoward Chu <hyc@openldap.org>
Fri, 8 Feb 2002 06:44:33 +0000 (06:44 +0000)
committerHoward Chu <hyc@openldap.org>
Fri, 8 Feb 2002 06:44:33 +0000 (06:44 +0000)
servers/slapd/config.c
servers/slapd/proto-slap.h
servers/slapd/repl.c
servers/slapd/slap.h
servers/slapd/tools/mimic.c
servers/slurpd/config.c
servers/slurpd/slurp.h

index 4056bad667458bc5facfa1c5c33527d7dd498499..9cf0bd91173d30584bcb57b973470bc1dd844689 100644 (file)
@@ -1817,6 +1817,19 @@ read_config( const char *fname )
 #endif
                                                                break;
                                                        }
+                                               } else if ( strncasecmp( cargv[i], "attr=", 5 ) == 0 ) {
+                                                       if ( add_replica_attrs( be, nr, cargv[i] + 5 ) ) {
+#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 ));
+#else
+                                                               Debug( LDAP_DEBUG_ANY,
+                                                                               "%s: line %d: attribute \"%s\" in \"replica\" line is unknown\n",
+                                                                               fname, lineno, cargv[i] + 5 );
+#endif
+                                                               return( 1 );
+                                                       }
                                                }
                                        }
                                }
index 8c520dc30d649c40c1241b81a2edac6c766c58e3..7b5ed869582023df4209abd3b438ed601723e706 100644 (file)
@@ -720,6 +720,8 @@ LDAP_SLAPD_F (int) add_replica_info LDAP_P(( Backend *be,
        const char *host ));
 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 ));
 LDAP_SLAPD_F (void) replog LDAP_P(( Backend *be, Operation *op,
        struct berval *dn, struct berval *ndn, void *change ));
 
index 5f004475895d324afc38092aeca0cd5f10025929..16c203a9f0dca76ff6cc51017deea7ebfc1f070a 100644 (file)
@@ -73,6 +73,23 @@ add_replica_suffix(
        return 0;
 }
 
+int
+add_replica_attrs(
+       Backend *be,
+       int     nr,
+       char    *attrs
+)
+{
+       be->be_replica[nr]->ri_attrs = str2anlist( be->be_replica[nr]->ri_attrs,
+               attrs, "," );
+       return ( be->be_replica[nr]->ri_attrs == NULL );
+}
+   
+static void
+print_vals( FILE *fp, struct berval *type, struct berval *bv );
+static void
+replog1( struct slap_replica_info *ri, Operation *op, void *change, FILE *fp, void *first);
+
 void
 replog(
     Backend    *be,
@@ -82,16 +99,17 @@ replog(
     void       *change
 )
 {
-       Modifications   *ml;
+       Modifications   *ml = NULL;
+       Attribute       *a = NULL;
        Entry   *e;
-       struct slap_replog_moddn *moddn;
-       char *tmp;
        FILE    *fp, *lfp;
-       int     len, i;
+       int     i;
 /* undef NO_LOG_WHEN_NO_REPLICAS */
 #ifdef NO_LOG_WHEN_NO_REPLICAS
        int     count = 0;
 #endif
+       int     subsets = 0;
+       long now = slap_get_time();
 
        if ( be->be_replogfile == NULL && replogfile == NULL ) {
                return;
@@ -120,6 +138,15 @@ replog(
                                continue;
                        }
                }
+               /* See if we only want a subset of attributes */
+               if ( be->be_replica[i]->ri_attrs != NULL &&
+                       ( op->o_tag == LDAP_REQ_MODIFY || op->o_tag == LDAP_REQ_ADD || op->o_tag == LDAP_REQ_EXTENDED ) ) {
+                       if ( !subsets ) {
+                               subsets = i + 1;
+                       }
+                       /* Do attribute subsets by themselves in a second pass */
+                       continue;
+               }
 
                fprintf( fp, "replica: %s\n", be->be_replica[i]->ri_host );
 #ifdef NO_LOG_WHEN_NO_REPLICAS
@@ -128,7 +155,7 @@ replog(
        }
 
 #ifdef NO_LOG_WHEN_NO_REPLICAS
-       if ( count == 0 ) {
+       if ( count == 0 && subsets == 0 ) {
                /* if no replicas matched, drop the log 
                 * (should we log it anyway?) */
                lock_fclose( fp, lfp );
@@ -138,9 +165,97 @@ replog(
        }
 #endif
 
-       fprintf( fp, "time: %ld\n", (long) slap_get_time() );
+       fprintf( fp, "time: %ld\n", now );
        fprintf( fp, "dn: %s\n", dn->bv_val );
 
+       replog1( NULL, op, change, fp, NULL );
+
+       if ( subsets > 0 ) {
+               void *first;
+               for ( i = subsets - 1; be->be_replica != NULL && be->be_replica[i] != NULL; i++ ) {
+
+                       /* If no attrs, we already did this above */
+                       if ( be->be_replica[i]->ri_attrs == NULL ) {
+                               continue;
+                       }
+
+                       /* check if dn's suffix matches legal suffixes, if any */
+                       if ( be->be_replica[i]->ri_nsuffix != NULL ) {
+                               int j;
+
+                               for ( j = 0; be->be_replica[i]->ri_nsuffix[j]; j++ ) {
+                                       if ( dnIsSuffix( ndn, be->be_replica[i]->ri_nsuffix[j] ) ) {
+                                               break;
+                                       }
+                               }
+
+                               if ( !be->be_replica[i]->ri_nsuffix[j] ) {
+                                       /* do not add "replica:" line */
+                                       continue;
+                               }
+                       }
+                       subsets = 0;
+                       first = NULL;
+                       switch( op->o_tag ) {
+                       case LDAP_REQ_EXTENDED:
+                               /* quick hack for extended operations */
+                               /* assume change parameter is a Modfications* */
+                               /* 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 ) ) {
+                                               subsets = 1;
+                                               first = ml;
+                                               break;
+                                       }
+                               }
+                               if ( !subsets ) {
+                                       continue;
+                               }
+                               break;
+                       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 ) ) {
+                                               subsets = 1;
+                                               first = a;
+                                               break;
+                                       }
+                               }
+                               if ( !subsets ) {
+                                       continue;
+                               }
+                               break;
+                       default:
+                               /* Other operations were logged in the first pass */
+                               continue;
+                       }
+                       fprintf( fp, "replica: %s\n", be->be_replica[i]->ri_host );
+                       fprintf( fp, "time: %ld\n", now );
+                       fprintf( fp, "dn: %s\n", dn->bv_val );
+                       replog1( be->be_replica[i], op, change, fp, first );
+               }
+       }
+
+       lock_fclose( fp, lfp );
+       ldap_pvt_thread_mutex_unlock( &replog_mutex );
+}
+
+
+static void
+replog1(
+    struct slap_replica_info *ri,
+    Operation *op,
+    void       *change,
+    FILE       *fp,
+       void    *first
+)
+{
+       Modifications   *ml;
+       Attribute       *a;
+       Entry           *e;
+       struct slap_replog_moddn *moddn;
+
        switch ( op->o_tag ) {
        case LDAP_REQ_EXTENDED:
                /* quick hack for extended operations */
@@ -149,10 +264,12 @@ replog(
 
        case LDAP_REQ_MODIFY:
                fprintf( fp, "changetype: modify\n" );
-               ml = change;
+               ml = first ? first : change;
                for ( ; ml != NULL; ml = ml->sml_next ) {
                        char *type;
-                       struct berval *bv;
+                       if ( ri && ri->ri_attrs && !ad_inlist( ml->sml_desc, ri->ri_attrs ) ) {
+                               continue;
+                       }
                        type = ml->sml_desc->ad_cname.bv_val;
                        switch ( ml->sml_op ) {
                        case LDAP_MOD_ADD:
@@ -168,24 +285,7 @@ replog(
                                break;
                        }
 
-                       for ( bv = ml->sml_bvalues; bv && bv->bv_val; bv++ )
-                       {
-                               char    *buf, *bufp;
-
-                               len = ml->sml_desc->ad_cname.bv_len;
-                               len = LDIF_SIZE_NEEDED( len,
-                                   bv->bv_len ) + 1;
-                               buf = (char *) ch_malloc( len );
-
-                               bufp = buf;
-                               ldif_sput( &bufp, LDIF_PUT_VALUE, type,
-                                   bv->bv_val, bv->bv_len );
-                               *bufp = '\0';
-
-                               fputs( buf, fp );
-
-                               free( buf );
-                       }
+                       print_vals( fp, &ml->sml_desc->ad_cname, ml->sml_bvalues );
                        fprintf( fp, "-\n" );
                }
                break;
@@ -193,15 +293,13 @@ replog(
        case LDAP_REQ_ADD:
                e = change;
                fprintf( fp, "changetype: add\n" );
-               ldap_pvt_thread_mutex_lock( &entry2str_mutex );
-               tmp = entry2str( e, &len );
-               while ( (tmp = strchr( tmp, '\n' )) != NULL ) {
-                       tmp++;
-                       if ( ! isspace( (unsigned char) *tmp ) )
-                               break;
+               a = first ? first : e->e_attrs;
+               for ( ; a != NULL; a=a->a_next ) {
+                       if ( ri && ri->ri_attrs && !ad_inlist( a->a_desc, ri->ri_attrs ) ) {
+                               continue;
+                       }
+                       print_vals( fp, &a->a_desc->ad_cname, a->a_vals );
                }
-               fprintf( fp, "%s", tmp );
-               ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
                break;
 
        case LDAP_REQ_DELETE:
@@ -218,7 +316,30 @@ replog(
                }
        }
        fprintf( fp, "\n" );
+}
 
-       lock_fclose( fp, lfp );
-       ldap_pvt_thread_mutex_unlock( &replog_mutex );
+static void
+print_vals(
+       FILE *fp,
+       struct berval *type,
+       struct berval *bv )
+{
+       int len;
+       char    *buf, *bufp;
+
+       for ( ; bv && bv->bv_val; bv++ )
+       {
+               len = type->bv_len;
+               len = LDIF_SIZE_NEEDED( len, bv->bv_len ) + 1;
+               buf = (char *) ch_malloc( len );
+
+               bufp = buf;
+               ldif_sput( &bufp, LDIF_PUT_VALUE, type->bv_val,
+                                   bv->bv_val, bv->bv_len );
+               *bufp = '\0';
+
+               fputs( buf, fp );
+
+               free( buf );
+       }
 }
index 9bf1b8dd1f78ff03517395bb8a1d4cb8ca59a72d..12d91995ab216ad21b63cf4e3d8340c30e87eaca 100644 (file)
@@ -981,6 +981,7 @@ LDAP_SLAPD_V (int) slapMode;
 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 */
 };
 
 struct slap_limits_set {
index b6e75dc6aff6f8a4a6d9a998deebf547cdc01b77..f53f1bde64d97a5aff907d87f882601a3dcb482f 100644 (file)
@@ -201,6 +201,11 @@ int add_replica_suffix( Backend *be, int nr, const char *suffix )
        return 0;
 }
 
+int add_replica_attrs( Backend *be, int nr, char *attrs )
+{
+       return 0;
+}
+
 int parse_limits( Backend *be, const char *fname, int lineno, int argc, char **argv )
 {
        return 0;
index 56b8367ef52a55373b2eefa58aa380e7048337e1..a9c44d35df85ef14375a845e97d366cff866a368 100644 (file)
@@ -381,6 +381,9 @@ parse_replica_line(
            }
            ri->ri_hostname = strdup( val );
            gots |= GOT_HOST;
+       } else if ( !strncasecmp( cargv[ i ], 
+                       ATTRSTR, sizeof( ATTRSTR ) - 1 ) ) {
+           /* ignore it */ ;
        } else if ( !strncasecmp( cargv[ i ], 
                        SUFFIXSTR, sizeof( SUFFIXSTR ) - 1 ) ) {
            /* ignore it */ ;
index 8f9834ec78f9da1bb56c6e0bca24b8f2385204af..b8a84bcedcf9b88f417a782297492c4e9e814457 100644 (file)
 
 /* Config file keywords */
 #define        HOSTSTR                 "host"
+#define        ATTRSTR                 "attr"
 #define        SUFFIXSTR               "suffix"
 #define        BINDDNSTR               "binddn"
 #define        BINDMETHSTR             "bindmethod"