From: Howard Chu Date: Sat, 24 Jan 2004 02:21:41 +0000 (+0000) Subject: Backport ITS#2512 replog order fix from HEAD X-Git-Tag: OPENLDAP_REL_ENG_2_1_27~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c9ceb19cdce8f02cd0553801317b106a13dc952c;p=thirdparty%2Fopenldap.git Backport ITS#2512 replog order fix from HEAD --- diff --git a/servers/slapd/add.c b/servers/slapd/add.c index 05c4ee17c3..8bf40157c5 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -258,6 +258,8 @@ do_add( Connection *conn, Operation *op ) int update = be->be_update_ndn.bv_len; char textbuf[SLAP_TEXT_BUFLEN]; size_t textlen = sizeof textbuf; + slap_replog_ctx ctx; + slap_callback cb = {0}; rc = slap_mods_check( modlist, update, &text, textbuf, textlen ); @@ -305,13 +307,21 @@ do_add( Connection *conn, Operation *op ) } #endif /* LDAP_SLAPI */ - if ( (*be->be_add)( be, conn, op, e ) == 0 ) { #ifdef SLAPD_MULTIMASTER - if ( !repl_user ) + if ( !repl_user ) #endif - { - replog( be, op, &e->e_name, &e->e_nname, e ); - } + { + ctx.prev = op->o_callback; + ctx.be = be; + ctx.dn = &e->e_name; + ctx.ndn = &e->e_nname; + ctx.change = e; + cb.sc_private = &ctx; + cb.sc_response = slap_replog_cb; + op->o_callback = &cb; + } + + if ( (*be->be_add)( be, conn, op, e ) == 0 ) { be_entry_release_w( be, conn, op, e ); e = NULL; } diff --git a/servers/slapd/delete.c b/servers/slapd/delete.c index 131dee6493..5b3df80eec 100644 --- a/servers/slapd/delete.c +++ b/servers/slapd/delete.c @@ -199,19 +199,27 @@ do_delete( */ if ( be->be_delete ) { /* do the update here */ + slap_replog_ctx ctx; + slap_callback cb = {0}; int repl_user = be_isupdate( be, &op->o_ndn ); #ifndef SLAPD_MULTIMASTER if ( !be->be_update_ndn.bv_len || repl_user ) #endif { - if ( (*be->be_delete)( be, conn, op, &pdn, &ndn ) == 0 ) { #ifdef SLAPD_MULTIMASTER - if ( !be->be_update_ndn.bv_len || !repl_user ) + if ( !be->be_update_ndn.bv_len || !repl_user ) #endif - { - replog( be, op, &pdn, &ndn, NULL ); - } + { + ctx.prev = op->o_callback; + ctx.be = be; + ctx.dn = &pdn; + ctx.ndn = &ndn; + ctx.change = NULL; + cb.sc_private = &ctx; + cb.sc_response = slap_replog_cb; + op->o_callback = &cb; } + rc = (*be->be_delete)( be, conn, op, &pdn, &ndn ); #ifndef SLAPD_MULTIMASTER } else { BerVarray defref = be->be_update_refs diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index 9e7a8d96c2..34bec6be28 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -399,6 +399,8 @@ do_modify( const char *text; char textbuf[SLAP_TEXT_BUFLEN]; size_t textlen = sizeof textbuf; + slap_replog_ctx ctx; + slap_callback cb = {0}; rc = slap_mods_check( modlist, update, &text, textbuf, textlen ); @@ -427,14 +429,20 @@ do_modify( } } - if ( (*be->be_modify)( be, conn, op, &pdn, &ndn, modlist ) == 0 #ifdef SLAPD_MULTIMASTER - && !repl_user + if ( !repl_user ) #endif - ) { - /* but we log only the ones not from a replicator user */ - replog( be, op, &pdn, &ndn, modlist ); + { + ctx.prev = op->o_callback; + ctx.be = be; + ctx.dn = &pdn; + ctx.ndn = &ndn; + ctx.change = modlist; + cb.sc_private = &ctx; + cb.sc_response = slap_replog_cb; + op->o_callback = &cb; } + rc = (*be->be_modify)( be, conn, op, &pdn, &ndn, modlist ); #ifndef SLAPD_MULTIMASTER /* send a referral */ diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c index 109e8f6ab5..0d2af6ab57 100644 --- a/servers/slapd/modrdn.c +++ b/servers/slapd/modrdn.c @@ -375,20 +375,28 @@ do_modrdn( if ( !be->be_update_ndn.bv_len || repl_user ) #endif { - if ( (*be->be_modrdn)( be, conn, op, &pdn, &ndn, - &pnewrdn, &nnewrdn, deloldrdn, - pnewS, nnewS ) == 0 + struct slap_replog_moddn moddn; + slap_replog_ctx ctx; + slap_callback cb = {0}; #ifdef SLAPD_MULTIMASTER - && ( !be->be_update_ndn.bv_len || !repl_user ) + if ( !repl_user ) #endif - ) { - struct slap_replog_moddn moddn; + { moddn.newrdn = &pnewrdn; moddn.deloldrdn = deloldrdn; moddn.newsup = &pnewSuperior; - - replog( be, op, &pdn, &ndn, &moddn ); + ctx.prev = op->o_callback; + ctx.be = be; + ctx.dn = &pdn; + ctx.ndn = &ndn; + ctx.change = &moddn; + cb.sc_private = &ctx; + cb.sc_response = slap_replog_cb; + op->o_callback = &cb; } + rc = (*be->be_modrdn)( be, conn, op, &pdn, &ndn, + &pnewrdn, &nnewrdn, deloldrdn, + pnewS, nnewS ); #ifndef SLAPD_MULTIMASTER } else { BerVarray defref = be->be_update_refs diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 9bfb3e3cdc..31227f6a63 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -796,6 +796,10 @@ LDAP_SLAPD_F (int) add_replica_attrs LDAP_P(( Backend *be, 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 )); +LDAP_SLAPD_F (void) slap_replog_cb LDAP_P(( Connection *c, Operation *op, + ber_tag_t tag, ber_int_t msgid, ber_int_t err, const char *matched, + const char *text, BerVarray ref, const char *resoid, + struct berval *resdata, struct berval *sasldata, LDAPControl **ct )); /* * result.c diff --git a/servers/slapd/repl.c b/servers/slapd/repl.c index 03630be949..43047585d3 100644 --- a/servers/slapd/repl.c +++ b/servers/slapd/repl.c @@ -102,6 +102,39 @@ print_vals( FILE *fp, struct berval *type, struct berval *bv ); static void replog1( struct slap_replica_info *ri, Operation *op, void *change, FILE *fp, struct berval *dn, long now); +/* invoke replog from a callback to preserve replog order */ +void +slap_replog_cb( + Connection *c, + Operation *op, + ber_tag_t tag, + ber_int_t msgid, + ber_int_t err, + const char *matched, + const char *text, + BerVarray ref, + const char *resoid, + struct berval *resdata, + struct berval *sasldata, + LDAPControl **ctrls +) +{ + slap_callback *tmp = op->o_callback; + slap_replog_ctx *ctx = tmp->sc_private; + + if ( err == LDAP_SUCCESS ) { + replog( ctx->be, op, ctx->dn, ctx->ndn, ctx->change ); + } + op->o_callback = ctx->prev; + if ( op->o_callback && op->o_callback->sc_response ) { + op->o_callback->sc_response(c, op, tag, msgid, err, matched, + text, ref, resoid, resdata, sasldata, ctrls ); + } else { + send_ldap_result( c, op, err, matched, text, ref, ctrls ); + } + op->o_callback = tmp; +} + void replog( Backend *be, diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 7d01cc666a..a218043f96 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1612,6 +1612,15 @@ typedef struct slap_callback { void *sc_private; } slap_callback; +/* callback context for invoking replog */ +typedef struct slap_replog_ctx { + slap_callback *prev; + BackendDB *be; + struct berval *dn; + struct berval *ndn; + void *change; +} slap_replog_ctx; + /* * Paged Results state */