From: Howard Chu Date: Mon, 2 Feb 2015 10:48:39 +0000 (+0000) Subject: ITS#8040 experimental Lazy Commit X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=24a6af6f46a635158ba5fc902b7cc49a1cf299c7;p=openldap ITS#8040 experimental Lazy Commit --- diff --git a/include/ldap.h b/include/ldap.h index 824c50e4f9..9524e89489 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -332,6 +332,7 @@ typedef struct ldapcontrol { #define LDAP_REFERRALS_REQUIRED 3 /* MS Active Directory controls (for compatibility) */ +#define LDAP_CONTROL_X_LAZY_COMMIT "1.2.840.113556.1.4.619" #define LDAP_CONTROL_X_INCREMENTAL_VALUES "1.2.840.113556.1.4.802" #define LDAP_CONTROL_X_DOMAIN_SCOPE "1.2.840.113556.1.4.1339" #define LDAP_CONTROL_X_PERMISSIVE_MODIFY "1.2.840.113556.1.4.1413" diff --git a/servers/slapd/back-bdb/add.c b/servers/slapd/back-bdb/add.c index 03f415b494..c59e584122 100644 --- a/servers/slapd/back-bdb/add.c +++ b/servers/slapd/back-bdb/add.c @@ -111,8 +111,12 @@ retry: /* transaction retry */ } /* begin transaction */ - rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, <id, - bdb->bi_db_opflags ); + { + int tflags = bdb->bi_db_opflags; + if ( get_lazyCommit( op )) + tflags |= DB_TXN_NOSYNC; + rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, <id, tflags ); + } rs->sr_text = NULL; if( rs->sr_err != 0 ) { Debug( LDAP_DEBUG_TRACE, diff --git a/servers/slapd/back-bdb/delete.c b/servers/slapd/back-bdb/delete.c index a88e03c406..96e7a64843 100644 --- a/servers/slapd/back-bdb/delete.c +++ b/servers/slapd/back-bdb/delete.c @@ -104,8 +104,12 @@ retry: /* transaction retry */ } /* begin transaction */ - rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, <id, - bdb->bi_db_opflags ); + { + int tflags = bdb->bi_db_opflags; + if ( get_lazyCommit( op )) + tflags |= DB_TXN_NOSYNC; + rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, <id, tflags ); + } Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_delete) ": txn1 id: %x\n", ltid->id(ltid), 0, 0 ); rs->sr_text = NULL; diff --git a/servers/slapd/back-bdb/modify.c b/servers/slapd/back-bdb/modify.c index 540280ab5b..3aa05ba8f2 100644 --- a/servers/slapd/back-bdb/modify.c +++ b/servers/slapd/back-bdb/modify.c @@ -515,8 +515,12 @@ retry: /* transaction retry */ } /* begin transaction */ - rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, <id, - bdb->bi_db_opflags ); + { + int tflags = bdb->bi_db_opflags; + if ( get_lazyCommit( op )) + tflags |= DB_TXN_NOSYNC; + rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, <id, tflags ); + } rs->sr_text = NULL; if( rs->sr_err != 0 ) { Debug( LDAP_DEBUG_TRACE, diff --git a/servers/slapd/back-bdb/modrdn.c b/servers/slapd/back-bdb/modrdn.c index 42f5669483..b0bcf6ee06 100644 --- a/servers/slapd/back-bdb/modrdn.c +++ b/servers/slapd/back-bdb/modrdn.c @@ -114,8 +114,12 @@ retry: /* transaction retry */ } /* begin transaction */ - rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, <id, - bdb->bi_db_opflags ); + { + int tflags = bdb->bi_db_opflags; + if ( get_lazyCommit( op )) + tflags |= DB_TXN_NOSYNC; + rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, <id, tflags ); + } rs->sr_text = NULL; if( rs->sr_err != 0 ) { Debug( LDAP_DEBUG_TRACE, diff --git a/servers/slapd/back-mdb/id2entry.c b/servers/slapd/back-mdb/id2entry.c index 7e5b8cc2e2..119c8fa423 100644 --- a/servers/slapd/back-mdb/id2entry.c +++ b/servers/slapd/back-mdb/id2entry.c @@ -466,7 +466,10 @@ mdb_opinfo_get( Operation *op, struct mdb_info *mdb, int rdonly, mdb_op_info **m if (( slapMode & SLAP_TOOL_MODE ) && mdb_tool_txn ) { moi->moi_txn = mdb_tool_txn; } else { - rc = mdb_txn_begin( mdb->mi_dbenv, NULL, 0, &moi->moi_txn ); + int flag = 0; + if ( get_lazyCommit( op )) + flag |= MDB_NOSYNC; + rc = mdb_txn_begin( mdb->mi_dbenv, NULL, flag, &moi->moi_txn ); if (rc) { Debug( LDAP_DEBUG_ANY, "mdb_opinfo_get: err %s(%d)\n", mdb_strerror(rc), rc, 0 ); diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c index 7b285feabf..7ca7d58998 100644 --- a/servers/slapd/controls.c +++ b/servers/slapd/controls.c @@ -51,6 +51,9 @@ static SLAP_CTRL_PARSE_FN parseSessionTracking; #ifdef SLAP_CONTROL_X_WHATFAILED static SLAP_CTRL_PARSE_FN parseWhatFailed; #endif +#ifdef SLAP_CONTROL_X_LAZY_COMMIT +static SLAP_CTRL_PARSE_FN parseLazyCommit; +#endif #undef sc_mask /* avoid conflict with Irix 6.5 */ @@ -226,6 +229,13 @@ static struct slap_control control_defs[] = { NULL, NULL, parseWhatFailed, LDAP_SLIST_ENTRY_INITIALIZER(next) }, #endif +#ifdef SLAP_CONTROL_X_LAZY_COMMIT + { LDAP_CONTROL_X_LAZY_COMMIT, + (int)offsetof(struct slap_control_ids, sc_lazyCommit), + SLAP_CTRL_GLOBAL|SLAP_CTRL_ACCESS|SLAP_CTRL_HIDE, + NULL, NULL, + parseLazyCommit, LDAP_SLIST_ENTRY_INITIALIZER(next) }, +#endif { NULL, 0, 0, NULL, 0, NULL, LDAP_SLIST_ENTRY_INITIALIZER(next) } }; @@ -2155,3 +2165,27 @@ done:; return rc; } #endif + +#ifdef SLAP_CONTROL_X_LAZY_COMMIT +static int parseLazyCommit( + Operation *op, + SlapReply *rs, + LDAPControl *ctrl ) +{ + if ( op->o_lazyCommit != SLAP_CONTROL_NONE ) { + rs->sr_text = "\"Lazy Commit?\" control specified multiple times"; + return LDAP_PROTOCOL_ERROR; + } + + if ( !BER_BVISNULL( &ctrl->ldctl_value )) { + rs->sr_text = "\"Lazy Commit?\" control value not absent"; + return LDAP_PROTOCOL_ERROR; + } + + op->o_lazyCommit = ctrl->ldctl_iscritical + ? SLAP_CONTROL_CRITICAL + : SLAP_CONTROL_NONCRITICAL; + + return LDAP_SUCCESS; +} +#endif diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 1790545c16..f89da27048 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -62,6 +62,7 @@ LDAP_BEGIN_DECL #define LDAP_COMP_MATCH #define LDAP_SYNC_TIMESTAMP #define SLAP_CONTROL_X_WHATFAILED +#define SLAP_CONTROL_X_LAZY_COMMIT #define SLAP_CONFIG_DELETE #define SLAP_AUXPROP_DONTUSECOPY #ifndef SLAP_SCHEMA_EXPOSE @@ -2504,6 +2505,9 @@ struct slap_control_ids { #ifdef SLAP_CONTROL_X_WHATFAILED int sc_whatFailed; #endif +#ifdef LDAP_CONTROL_X_LAZY_COMMIT + int sc_lazyCommit; +#endif }; /* @@ -2779,6 +2783,11 @@ struct Operation { #define get_whatFailed(op) _SCM((op)->o_whatFailed) #endif +#ifdef SLAP_CONTROL_X_LAZY_COMMIT +#define o_lazyCommit o_ctrlflag[slap_cids.sc_lazyCommit] +#define get_lazyCommit(op) _SCM((op)->o_lazyCommit) +#endif + #define o_sync o_ctrlflag[slap_cids.sc_LDAPsync] AuthorizationInformation o_authz; diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index ac65a46b2a..23b638d24f 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -112,6 +112,7 @@ typedef struct syncinfo_s { int si_refreshDone; int si_syncdata; int si_logstate; + int si_lazyCommit; int si_got; int si_strict_refresh; /* stop listening during fallback refresh */ int si_too_old; @@ -2932,6 +2933,9 @@ syncrepl_entry( slap_queue_csn( op, syncCSN ); } + if ( !si->si_refreshDone && si->si_lazyCommit ) + op->o_lazyCommit = SLAP_CONTROL_NONCRITICAL; + slap_op_time( &op->o_time, &op->o_tincr ); switch ( syncstate ) { case LDAP_SYNC_ADD: @@ -4687,6 +4691,7 @@ config_suffixm( ConfigArgs *c, syncinfo_t *si ) /* FIXME: undocumented */ #define EXATTRSSTR "exattrs" #define MANAGEDSAITSTR "manageDSAit" +#define LAZY_COMMIT "lazycommit" /* mandatory */ enum { @@ -5185,6 +5190,10 @@ parse_syncrepl_line( STRLENOF( STRICT_REFRESH ) ) ) { si->si_strict_refresh = 1; + } else if ( !strncasecmp( c->argv[ i ], LAZY_COMMIT, + STRLENOF( LAZY_COMMIT ) ) ) + { + si->si_lazyCommit = 1; } else if ( !bindconf_parse( c->argv[i], &si->si_bindconf ) ) { si->si_got |= GOT_BINDCONF; } else { @@ -5585,6 +5594,11 @@ syncrepl_unparse( syncinfo_t *si, struct berval *bv ) ptr = lutil_strcopy( ptr, bc.bv_val ); } } + + if ( si->si_lazyCommit ) { + ptr = lutil_strcopy( ptr, " " LAZY_COMMIT ); + } + bc.bv_len = ptr - buf; bc.bv_val = buf; ber_dupbv( bv, &bc );