mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-20 22:59:34 -05:00
ITS#9751 Do not drop out of order deletes completely
This commit is contained in:
parent
74ed5163ed
commit
70e6bd6777
1 changed files with 57 additions and 8 deletions
|
|
@ -2580,6 +2580,7 @@ static Modifications *mods_dup( Operation *op, Modifications *modlist, int match
|
||||||
|
|
||||||
typedef struct resolve_ctxt {
|
typedef struct resolve_ctxt {
|
||||||
syncinfo_t *rx_si;
|
syncinfo_t *rx_si;
|
||||||
|
Entry *rx_entry;
|
||||||
Modifications *rx_mods;
|
Modifications *rx_mods;
|
||||||
} resolve_ctxt;
|
} resolve_ctxt;
|
||||||
|
|
||||||
|
|
@ -2624,6 +2625,7 @@ syncrepl_resolve_cb( Operation *op, SlapReply *rs )
|
||||||
Attribute *a = attr_find( rs->sr_entry->e_attrs, ad_reqMod );
|
Attribute *a = attr_find( rs->sr_entry->e_attrs, ad_reqMod );
|
||||||
if ( a ) {
|
if ( a ) {
|
||||||
Modifications *oldmods, *newmods, *m1, *m2, **prev;
|
Modifications *oldmods, *newmods, *m1, *m2, **prev;
|
||||||
|
Entry *e = rx->rx_entry;
|
||||||
oldmods = rx->rx_mods;
|
oldmods = rx->rx_mods;
|
||||||
syncrepl_accesslog_mods( rx->rx_si, a->a_vals, &newmods );
|
syncrepl_accesslog_mods( rx->rx_si, a->a_vals, &newmods );
|
||||||
for ( m2 = newmods; m2; m2=m2->sml_next ) {
|
for ( m2 = newmods; m2; m2=m2->sml_next ) {
|
||||||
|
|
@ -2664,14 +2666,51 @@ drop:
|
||||||
|
|
||||||
if ( m2->sml_op == LDAP_MOD_ADD ||
|
if ( m2->sml_op == LDAP_MOD_ADD ||
|
||||||
m2->sml_op == LDAP_MOD_REPLACE ) {
|
m2->sml_op == LDAP_MOD_REPLACE ) {
|
||||||
if ( m1->sml_op == LDAP_MOD_DELETE ) {
|
|
||||||
if ( !m1->sml_numvals ) goto drop;
|
|
||||||
compare_vals( m1, m2 );
|
|
||||||
if ( !m1->sml_numvals )
|
|
||||||
goto drop;
|
|
||||||
}
|
|
||||||
if ( m2->sml_desc->ad_type->sat_atype.at_single_value )
|
if ( m2->sml_desc->ad_type->sat_atype.at_single_value )
|
||||||
goto drop;
|
goto drop;
|
||||||
|
if ( m1->sml_op == LDAP_MOD_DELETE ) {
|
||||||
|
if ( m2->sml_op == LDAP_MOD_REPLACE ) {
|
||||||
|
goto drop;
|
||||||
|
}
|
||||||
|
if ( !m1->sml_numvals ) {
|
||||||
|
Modifications *m;
|
||||||
|
unsigned int size, i;
|
||||||
|
/*
|
||||||
|
* ITS#9751 An ADD might supersede parts of
|
||||||
|
* this delete, but we still need to honour the
|
||||||
|
* rest. Keep resolving as if it was deleting
|
||||||
|
* specific values
|
||||||
|
*/
|
||||||
|
a = attr_find( e->e_attrs, m1->sml_desc );
|
||||||
|
if ( !a ) {
|
||||||
|
goto drop;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = (a->a_numvals+1) * sizeof(struct berval);
|
||||||
|
if ( a->a_nvals ) size *= 2;
|
||||||
|
size += sizeof(Modifications);
|
||||||
|
m = op->o_tmpalloc( size, op->o_tmpmemctx );
|
||||||
|
*m = *m1;
|
||||||
|
|
||||||
|
m->sml_numvals = a->a_numvals;
|
||||||
|
m->sml_values = (BerVarray)(m+1);
|
||||||
|
|
||||||
|
for ( i=0; i < a->a_numvals; i++ )
|
||||||
|
m->sml_values[i] = a->a_vals[i];
|
||||||
|
BER_BVZERO( &m->sml_values[i] );
|
||||||
|
|
||||||
|
if ( a->a_nvals ) {
|
||||||
|
m->sml_nvalues = m->sml_values + m->sml_numvals + 1;
|
||||||
|
for ( i=0; i < a->a_numvals; i++ )
|
||||||
|
m->sml_nvalues[i] = a->a_nvals[i];
|
||||||
|
BER_BVZERO( &m->sml_nvalues[i] );
|
||||||
|
} else {
|
||||||
|
m->sml_nvalues = NULL;
|
||||||
|
}
|
||||||
|
op->o_tmpfree( m1, op->o_tmpmemctx );
|
||||||
|
*prev = m1 = m;
|
||||||
|
}
|
||||||
|
}
|
||||||
compare_vals( m1, m2 );
|
compare_vals( m1, m2 );
|
||||||
if ( !m1->sml_numvals )
|
if ( !m1->sml_numvals )
|
||||||
goto drop;
|
goto drop;
|
||||||
|
|
@ -2689,6 +2728,7 @@ drop:
|
||||||
typedef struct modify_ctxt {
|
typedef struct modify_ctxt {
|
||||||
Modifications *mx_orig;
|
Modifications *mx_orig;
|
||||||
Modifications *mx_free;
|
Modifications *mx_free;
|
||||||
|
Entry *mx_entry;
|
||||||
} modify_ctxt;
|
} modify_ctxt;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -2704,6 +2744,9 @@ syncrepl_modify_cb( Operation *op, SlapReply *rs )
|
||||||
mx->mx_free = ml->sml_next;
|
mx->mx_free = ml->sml_next;
|
||||||
op->o_tmpfree( ml, op->o_tmpmemctx );
|
op->o_tmpfree( ml, op->o_tmpmemctx );
|
||||||
}
|
}
|
||||||
|
if ( mx->mx_entry ) {
|
||||||
|
entry_free( mx->mx_entry );
|
||||||
|
}
|
||||||
op->o_callback = sc->sc_next;
|
op->o_callback = sc->sc_next;
|
||||||
op->o_tmpfree( sc, op->o_tmpmemctx );
|
op->o_tmpfree( sc, op->o_tmpmemctx );
|
||||||
return SLAP_CB_CONTINUE;
|
return SLAP_CB_CONTINUE;
|
||||||
|
|
@ -2715,7 +2758,7 @@ syncrepl_op_modify( Operation *op, SlapReply *rs )
|
||||||
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
|
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
|
||||||
OpExtra *oex;
|
OpExtra *oex;
|
||||||
syncinfo_t *si;
|
syncinfo_t *si;
|
||||||
Entry *e;
|
Entry *e, *e_dup;
|
||||||
int rc, match = 0;
|
int rc, match = 0;
|
||||||
Modifications *mod, *newlist;
|
Modifications *mod, *newlist;
|
||||||
|
|
||||||
|
|
@ -2769,6 +2812,7 @@ syncrepl_op_modify( Operation *op, SlapReply *rs )
|
||||||
/* no entryCSN? shouldn't happen. assume mod is newer. */
|
/* no entryCSN? shouldn't happen. assume mod is newer. */
|
||||||
match = 1;
|
match = 1;
|
||||||
}
|
}
|
||||||
|
e_dup = entry_dup( e );
|
||||||
overlay_entry_release_ov( op, e, 0, on );
|
overlay_entry_release_ov( op, e, 0, on );
|
||||||
} else {
|
} else {
|
||||||
return SLAP_CB_CONTINUE;
|
return SLAP_CB_CONTINUE;
|
||||||
|
|
@ -2779,6 +2823,7 @@ syncrepl_op_modify( Operation *op, SlapReply *rs )
|
||||||
slap_graduate_commit_csn( op );
|
slap_graduate_commit_csn( op );
|
||||||
/* tell accesslog this was a failure */
|
/* tell accesslog this was a failure */
|
||||||
rs->sr_err = LDAP_TYPE_OR_VALUE_EXISTS;
|
rs->sr_err = LDAP_TYPE_OR_VALUE_EXISTS;
|
||||||
|
entry_free( e_dup );
|
||||||
return LDAP_SUCCESS;
|
return LDAP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2793,7 +2838,8 @@ syncrepl_op_modify( Operation *op, SlapReply *rs )
|
||||||
* delete X delete all drop
|
* delete X delete all drop
|
||||||
* delete X delete X drop
|
* delete X delete X drop
|
||||||
* delete X delete Y OK
|
* delete X delete Y OK
|
||||||
* delete all add X drop
|
* delete all add X convert to delete current values,
|
||||||
|
* drop delete X from it
|
||||||
* delete X add X drop
|
* delete X add X drop
|
||||||
* delete X add Y OK
|
* delete X add Y OK
|
||||||
* add X delete all drop
|
* add X delete all drop
|
||||||
|
|
@ -2826,6 +2872,7 @@ syncrepl_op_modify( Operation *op, SlapReply *rs )
|
||||||
AttributeAssertion aa[2] = {0};
|
AttributeAssertion aa[2] = {0};
|
||||||
|
|
||||||
rx.rx_si = si;
|
rx.rx_si = si;
|
||||||
|
rx.rx_entry = e_dup;
|
||||||
rx.rx_mods = newlist;
|
rx.rx_mods = newlist;
|
||||||
cb.sc_private = ℞
|
cb.sc_private = ℞
|
||||||
|
|
||||||
|
|
@ -2888,6 +2935,7 @@ syncrepl_op_modify( Operation *op, SlapReply *rs )
|
||||||
op->orm_no_opattrs = 1;
|
op->orm_no_opattrs = 1;
|
||||||
mx->mx_orig = op->orm_modlist;
|
mx->mx_orig = op->orm_modlist;
|
||||||
mx->mx_free = newlist;
|
mx->mx_free = newlist;
|
||||||
|
mx->mx_entry = e_dup;
|
||||||
for ( ml = newlist; ml; ml=ml->sml_next ) {
|
for ( ml = newlist; ml; ml=ml->sml_next ) {
|
||||||
if ( ml->sml_flags == SLAP_MOD_INTERNAL ) {
|
if ( ml->sml_flags == SLAP_MOD_INTERNAL ) {
|
||||||
ml->sml_flags = 0;
|
ml->sml_flags = 0;
|
||||||
|
|
@ -2902,6 +2950,7 @@ syncrepl_op_modify( Operation *op, SlapReply *rs )
|
||||||
op->orm_modlist = newlist;
|
op->orm_modlist = newlist;
|
||||||
op->o_csn = mod->sml_nvalues[0];
|
op->o_csn = mod->sml_nvalues[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
return SLAP_CB_CONTINUE;
|
return SLAP_CB_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue