]> git.sur5r.net Git - openldap/commitdiff
syncrepl update: 1) improve error handling 2) glueing support for non-leaf deletion...
authorJong Hyuk Choi <jongchoi@openldap.org>
Sun, 22 Feb 2004 20:44:44 +0000 (20:44 +0000)
committerJong Hyuk Choi <jongchoi@openldap.org>
Sun, 22 Feb 2004 20:44:44 +0000 (20:44 +0000)
servers/slapd/back-bdb/modify.c
servers/slapd/proto-slap.h
servers/slapd/syncrepl.c

index ec57fd92a21a61f2e38fbdc0e6e64b706785e7e7..07764d0bf45dfafbff4018083b5026f450d52b83 100644 (file)
@@ -37,6 +37,7 @@ int bdb_modify_internal(
        Modifications   *ml;
        Attribute       *save_attrs;
        Attribute       *ap;
+       int                     glue_attr_delete = 0;
 
 #ifdef NEW_LOGGING
        LDAP_LOG ( OPERATION, ENTRY, "bdb_modify_internal: 0x%08lx: %s\n", 
@@ -54,6 +55,33 @@ int bdb_modify_internal(
        save_attrs = e->e_attrs;
        e->e_attrs = attrs_dup( e->e_attrs );
 
+       for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
+               mod = &ml->sml_mod;
+               switch( mod->sm_op ) {
+               case LDAP_MOD_ADD:
+               case LDAP_MOD_REPLACE:
+                       if ( mod->sm_desc == slap_schema.si_ad_structuralObjectClass ) {
+                       /* sc modify is internally allowed only to make an entry a glue */
+                               glue_attr_delete = 1;
+                       }
+               }
+               if ( glue_attr_delete )
+                       break;
+       }
+
+       if ( glue_attr_delete ) {
+               Attribute       **app = &e->e_attrs;
+               while ( *app != NULL ) {
+                       if ( !is_at_operational( (*app)->a_desc->ad_type )) {
+                               Attribute *save = *app;
+                               *app = (*app)->a_next;
+                               attr_free( save );
+                               continue;
+                       }
+                       app = &(*app)->a_next;
+               }
+       }
+
        for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
                mod = &ml->sml_mod;
 
@@ -78,6 +106,8 @@ int bdb_modify_internal(
                        break;
 
                case LDAP_MOD_DELETE:
+                       if ( glue_attr_delete )
+                               break;
 #ifdef NEW_LOGGING
                        LDAP_LOG ( OPERATION, DETAIL1, 
                                "bdb_modify_internal: delete\n", 0, 0, 0 );
@@ -203,6 +233,10 @@ int bdb_modify_internal(
                        e->e_ocflags = 0;
                }
 
+               if ( glue_attr_delete ) {
+                       e->e_ocflags = 0;
+               }
+
                /* check if modified attribute was indexed
                 * but not in case of NOOP... */
                err = bdb_index_is_indexed( op->o_bd, mod->sm_desc );
index 0276a46e33bcdf55237698192dadf53bcc0b1f69..67a6a2d85935632179a3c938a9cbd146f52fa4f6 100644 (file)
@@ -1105,9 +1105,9 @@ LDAP_SLAPD_V (struct runqueue_s) syncrepl_rq;
 
 LDAP_SLAPD_F (void) init_syncrepl LDAP_P((syncinfo_t *));
 LDAP_SLAPD_F (void*) do_syncrepl LDAP_P((void *, void *));
-LDAP_SLAPD_F (Entry*) syncrepl_message_to_entry LDAP_P((
+LDAP_SLAPD_F (int) syncrepl_message_to_entry LDAP_P((
                                        syncinfo_t *, Operation *, LDAPMessage *,
-                                       Modifications **, int ));
+                                       Modifications **, Entry **, int ));
 LDAP_SLAPD_F (int) syncrepl_entry LDAP_P((
                                        syncinfo_t *, Operation*, Entry*,
                                        Modifications*,int, struct berval*,
index 9953eee7a94d2602a80a5a788219c4b312b66bfd..8e3292ab095836f7c15aa4a80422aa5dac453d1b 100644 (file)
@@ -434,7 +434,7 @@ do_syncrep2(
        int     rc, err, i;
        ber_len_t       len;
 
-       int rc_efree;
+       int rc_efree = 1;
 
        struct berval   *psub;
        Modifications   *modlist = NULL;
@@ -507,12 +507,14 @@ do_syncrep2(
                                                        syncCookie.octet_str[0].bv_val )
                                                slap_parse_sync_cookie( &syncCookie );
                                }
-                               entry = syncrepl_message_to_entry( si, op, msg,
-                                       &modlist, syncstate );
-                               rc_efree = syncrepl_entry( si, op, entry, modlist, syncstate,
-                                                       &syncUUID, &syncCookie_req );
-                               if ( syncCookie.octet_str && syncCookie.octet_str[0].bv_val ) {
-                                       syncrepl_updateCookie( si, op, psub, &syncCookie );
+                               if ( syncrepl_message_to_entry( si, op, msg,
+                                       &modlist, &entry, syncstate ) == LDAP_SUCCESS ) {
+                                       rc_efree = syncrepl_entry( si, op, entry, modlist,
+                                                               syncstate, &syncUUID, &syncCookie_req );
+                                       if ( syncCookie.octet_str &&
+                                                syncCookie.octet_str[0].bv_val ) {
+                                               syncrepl_updateCookie( si, op, psub, &syncCookie );
+                                       }
                                }
                                ldap_controls_free( rctrls );
                                if ( modlist ) {
@@ -570,7 +572,7 @@ do_syncrep2(
                                                &syncCookie_req.ctxcsn[0], &syncCookie.ctxcsn[0], &text );
                                }
                                if ( syncCookie.octet_str && syncCookie.octet_str->bv_val
-                                        && match < 0 ) {
+                                        && match < 0 && err == LDAP_SUCCESS ) {
                                        syncrepl_updateCookie( si, op, psub, &syncCookie );
                                }
                                if ( rctrls ) {
@@ -581,7 +583,8 @@ do_syncrep2(
                                         *      1) err code : LDAP_BUSY ...
                                         *      2) on err policy : stop service, stop sync, retry
                                         */
-                                       if ( refreshDeletes == 0 && match < 0 ) {
+                                       if ( refreshDeletes == 0 && match < 0 &&
+                                                err == LDAP_SUCCESS ) {
                                                syncrepl_del_nonpresent( op, si );
                                        } else {
                                                avl_free( si->si_presentlist, avl_ber_bvfree );
@@ -894,12 +897,13 @@ do_syncrepl(
        return NULL;
 }
 
-Entry*
+int
 syncrepl_message_to_entry(
        syncinfo_t      *si,
        Operation       *op,
        LDAPMessage     *msg,
        Modifications   **modlist,
+       Entry                   **entry,
        int             syncstate
 )
 {
@@ -926,7 +930,7 @@ syncrepl_message_to_entry(
                Debug( LDAP_DEBUG_ANY,
                        "Message type should be entry (%d)", ldap_msgtype( msg ), 0, 0 );
 #endif
-               return NULL;
+               return -1;
        }
 
        op->o_tag = LDAP_REQ_ADD;
@@ -941,7 +945,7 @@ syncrepl_message_to_entry(
                Debug( LDAP_DEBUG_ANY,
                        "syncrepl_message_to_entry : dn get failed (%d)", rc, 0, 0 );
 #endif
-               return NULL;
+               return rc;
        }
 
        dnPrettyNormal( NULL, &bdn, &dn, &ndn, op->o_tmpmemctx );
@@ -952,10 +956,15 @@ syncrepl_message_to_entry(
 
        if ( syncstate == LDAP_SYNC_PRESENT || syncstate == LDAP_SYNC_DELETE )
        {
-               return NULL;
+               return LDAP_SUCCESS;
+       }
+
+       if ( entry == NULL ) {
+               return -1;
        }
 
        e = ( Entry * ) ch_calloc( 1, sizeof( Entry ) );
+       *entry = e;
        e->e_name = op->o_req_dn;
        e->e_nname = op->o_req_ndn;
 
@@ -1020,7 +1029,7 @@ done:
                e = NULL;
        }
 
-       return e;
+       return rc;
 }
 
 int
@@ -1216,6 +1225,12 @@ done :
        return ret;
 }
 
+static struct berval gcbva[] = {
+       BER_BVC("top"),
+       BER_BVC("glue"),
+       BER_BVNULL
+};
+
 static void
 syncrepl_del_nonpresent(
        Operation *op,
@@ -1226,6 +1241,13 @@ syncrepl_del_nonpresent(
        slap_callback   cb = { NULL };
        SlapReply       rs = {REP_RESULT};
        struct nonpresent_entry *np_list, *np_prev;
+       int rc;
+       Modifications *ml;
+       Modifications *mlnext;
+       Modifications *mod;
+       Modifications *modlist = NULL;
+       Modifications **modtail = &modlist;
+       Attribute       *attr;
 
        op->o_req_dn = si->si_base;
        op->o_req_ndn = si->si_base;
@@ -1245,7 +1267,9 @@ syncrepl_del_nonpresent(
        op->ors_filterstr = si->si_filterstr;
 
        op->o_nocaching = 1;
+       op->o_managedsait = 0;
        be->be_search( op, &rs );
+       op->o_managedsait = 1;
        op->o_nocaching = 0;
 
        if ( op->ors_filter ) filter_free_x( op, op->ors_filter );
@@ -1262,7 +1286,36 @@ syncrepl_del_nonpresent(
                        cb.sc_private = si;
                        op->o_req_dn = *np_prev->npe_name;
                        op->o_req_ndn = *np_prev->npe_nname;
-                       op->o_bd->be_delete( op, &rs );
+                       rc = op->o_bd->be_delete( op, &rs );
+
+                       if ( rc == LDAP_NOT_ALLOWED_ON_NONLEAF ) {
+                               mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ));
+                               mod->sml_op = LDAP_MOD_REPLACE;
+                               mod->sml_desc = slap_schema.si_ad_objectClass;
+                               mod->sml_type = mod->sml_desc->ad_cname;
+                               mod->sml_bvalues = &gcbva[0];
+                               *modtail = mod;
+                               modtail = &mod->sml_next;
+
+                               mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ));
+                               mod->sml_op = LDAP_MOD_REPLACE;
+                               mod->sml_desc = slap_schema.si_ad_structuralObjectClass;
+                               mod->sml_type = mod->sml_desc->ad_cname;
+                               mod->sml_bvalues = &gcbva[1];
+                               *modtail = mod;
+                               modtail = &mod->sml_next;
+
+                               op->o_tag = LDAP_REQ_MODIFY;
+                               op->orm_modlist = modlist;
+
+                               rc = be->be_modify( op, &rs );
+
+                               for ( ml = modlist; ml != NULL; ml = mlnext ) {
+                                       mlnext = ml->sml_next;
+                                       free( ml );
+                               }
+                       }
+
                        ber_bvfree( np_prev->npe_name );
                        ber_bvfree( np_prev->npe_nname );
                        op->o_req_dn.bv_val = NULL;
@@ -1275,11 +1328,6 @@ syncrepl_del_nonpresent(
 }
 
 
-static struct berval gcbva[] = {
-       BER_BVC("top"),
-       BER_BVC("glue")
-};
-
 void
 syncrepl_add_glue(
        Operation* op,
@@ -1349,8 +1397,7 @@ syncrepl_add_glue(
                a->a_vals = ch_calloc( 3, sizeof( struct berval ));
                ber_dupbv( &a->a_vals[0], &gcbva[0] );
                ber_dupbv( &a->a_vals[1], &gcbva[1] );
-               a->a_vals[2].bv_len = 0;
-               a->a_vals[2].bv_val = NULL;
+               ber_dupbv( &a->a_vals[2], &gcbva[2] );
 
                a->a_nvals = a->a_vals;
 
@@ -1362,8 +1409,7 @@ syncrepl_add_glue(
 
                a->a_vals = ch_calloc( 2, sizeof( struct berval ));
                ber_dupbv( &a->a_vals[0], &gcbva[1] );
-               a->a_vals[1].bv_len = 0;
-               a->a_vals[1].bv_val = NULL;
+               ber_dupbv( &a->a_vals[1], &gcbva[2] );
 
                a->a_nvals = a->a_vals;