From 247536744e2a2c8589eb73292ff7e1317ac05c0e Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Tue, 7 Mar 2006 08:07:21 +0000 Subject: [PATCH] Some more txn infrastructure --- servers/slapd/back-bdb/add.c | 30 +++++++++++++++++++++++++++++ servers/slapd/back-bdb/delete.c | 34 +++++++++++++++++++++++++++++++-- servers/slapd/back-bdb/init.c | 9 +++++---- servers/slapd/back-bdb/modify.c | 30 +++++++++++++++++++++++++++++ servers/slapd/back-bdb/modrdn.c | 34 +++++++++++++++++++++++++++++++-- servers/slapd/connection.c | 11 +++++++++++ servers/slapd/slap.h | 4 +++- servers/slapd/txn.c | 2 ++ 8 files changed, 145 insertions(+), 9 deletions(-) diff --git a/servers/slapd/back-bdb/add.c b/servers/slapd/back-bdb/add.c index cd37908a20..3377541de7 100644 --- a/servers/slapd/back-bdb/add.c +++ b/servers/slapd/back-bdb/add.c @@ -47,6 +47,36 @@ bdb_add(Operation *op, SlapReply *rs ) Debug(LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(bdb_add) ": %s\n", op->oq_add.rs_e->e_name.bv_val, 0, 0); + if( op->o_txnSpec ) { + /* acquire connection lock */ + ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); + if( op->o_conn->c_txn == 0 ) { + rs->sr_text = "invalid transaction identifier"; + rs->sr_err = LDAP_X_TXN_ID_INVALID; + goto txnReturn; + } + if( op->o_conn->c_txn_backend == NULL ) { + op->o_conn->c_txn_backend = op->o_bd; + + } else if( op->o_conn->c_txn_backend != op->o_bd ) { + rs->sr_text = "transaction cannot span multiple database contexts"; + rs->sr_err = LDAP_AFFECTS_MULTIPLE_DSAS; + goto txnReturn; + } + + /* insert operation into transaction */ + + rs->sr_text = "transaction specified"; + rs->sr_err = LDAP_SUCCESS; + +txnReturn: + /* release connection lock */ + ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); + + send_ldap_result( op, rs ); + return rs->sr_err; + } + ctrls[num_ctrls] = 0; /* add opattrs to shadow as well, only missing attrs will actually diff --git a/servers/slapd/back-bdb/delete.c b/servers/slapd/back-bdb/delete.c index 02038dc55c..7ecf66e03a 100644 --- a/servers/slapd/back-bdb/delete.c +++ b/servers/slapd/back-bdb/delete.c @@ -52,11 +52,41 @@ bdb_delete( Operation *op, SlapReply *rs ) int parent_is_glue = 0; int parent_is_leaf = 0; - ctrls[num_ctrls] = 0; - Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(bdb_delete) ": %s\n", op->o_req_dn.bv_val, 0, 0 ); + if( op->o_txnSpec ) { + /* acquire connection lock */ + ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); + if( op->o_conn->c_txn == 0 ) { + rs->sr_text = "invalid transaction identifier"; + rs->sr_err = LDAP_X_TXN_ID_INVALID; + goto txnReturn; + } + if( op->o_conn->c_txn_backend == NULL ) { + op->o_conn->c_txn_backend = op->o_bd; + + } else if( op->o_conn->c_txn_backend != op->o_bd ) { + rs->sr_text = "transaction cannot span multiple database contexts"; + rs->sr_err = LDAP_AFFECTS_MULTIPLE_DSAS; + goto txnReturn; + } + + /* insert operation into transaction */ + + rs->sr_text = "transaction specified"; + rs->sr_err = LDAP_SUCCESS; + +txnReturn: + /* release connection lock */ + ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); + + send_ldap_result( op, rs ); + return rs->sr_err; + } + + ctrls[num_ctrls] = 0; + /* allocate CSN */ if ( BER_BVISEMPTY( &op->o_csn )) { struct berval csn; diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c index da7b438f6e..b766f6b1c6 100644 --- a/servers/slapd/back-bdb/init.c +++ b/servers/slapd/back-bdb/init.c @@ -305,10 +305,8 @@ bdb_db_open( BackendDB *be ) #ifdef SLAP_ZONE_ALLOC if ( bdb->bi_cache.c_maxsize ) { bdb->bi_cache.c_zctx = slap_zn_mem_create( - SLAP_ZONE_INITSIZE, - SLAP_ZONE_MAXSIZE, - SLAP_ZONE_DELTA, - SLAP_ZONE_SIZE); + SLAP_ZONE_INITSIZE, SLAP_ZONE_MAXSIZE, + SLAP_ZONE_DELTA, SLAP_ZONE_SIZE); } #endif @@ -555,6 +553,9 @@ bdb_back_initialize( LDAP_CONTROL_PAGEDRESULTS, LDAP_CONTROL_SUBENTRIES, LDAP_CONTROL_X_PERMISSIVE_MODIFY, +#ifdef LDAP_X_TXN + LDAP_CONTROL_X_TXN_SPEC, +#endif NULL }; diff --git a/servers/slapd/back-bdb/modify.c b/servers/slapd/back-bdb/modify.c index 21faa993e6..60697881a8 100644 --- a/servers/slapd/back-bdb/modify.c +++ b/servers/slapd/back-bdb/modify.c @@ -296,6 +296,36 @@ bdb_modify( Operation *op, SlapReply *rs ) Debug( LDAP_DEBUG_ARGS, LDAP_XSTRING(bdb_modify) ": %s\n", op->o_req_dn.bv_val, 0, 0 ); + if( op->o_txnSpec ) { + /* acquire connection lock */ + ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); + if( op->o_conn->c_txn == 0 ) { + rs->sr_text = "invalid transaction identifier"; + rs->sr_err = LDAP_X_TXN_ID_INVALID; + goto txnReturn; + } + if( op->o_conn->c_txn_backend == NULL ) { + op->o_conn->c_txn_backend = op->o_bd; + + } else if( op->o_conn->c_txn_backend != op->o_bd ) { + rs->sr_text = "transaction cannot span multiple database contexts"; + rs->sr_err = LDAP_AFFECTS_MULTIPLE_DSAS; + goto txnReturn; + } + + /* insert operation into transaction */ + + rs->sr_text = "transaction specified"; + rs->sr_err = LDAP_SUCCESS; + +txnReturn: + /* release connection lock */ + ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); + + send_ldap_result( op, rs ); + return rs->sr_err; + } + ctrls[num_ctrls] = NULL; slap_mods_opattrs( op, &op->orm_modlist, 1 ); diff --git a/servers/slapd/back-bdb/modrdn.c b/servers/slapd/back-bdb/modrdn.c index cc0ffcb476..23b42a19e6 100644 --- a/servers/slapd/back-bdb/modrdn.c +++ b/servers/slapd/back-bdb/modrdn.c @@ -61,12 +61,42 @@ bdb_modrdn( Operation *op, SlapReply *rs ) int parent_is_glue = 0; int parent_is_leaf = 0; - ctrls[num_ctrls] = NULL; - Debug( LDAP_DEBUG_TRACE, "==>" LDAP_XSTRING(bdb_modrdn) "(%s,%s,%s)\n", op->o_req_dn.bv_val,op->oq_modrdn.rs_newrdn.bv_val, op->oq_modrdn.rs_newSup ? op->oq_modrdn.rs_newSup->bv_val : "NULL" ); + if( op->o_txnSpec ) { + /* acquire connection lock */ + ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); + if( op->o_conn->c_txn == 0 ) { + rs->sr_text = "invalid transaction identifier"; + rs->sr_err = LDAP_X_TXN_ID_INVALID; + goto txnReturn; + } + if( op->o_conn->c_txn_backend == NULL ) { + op->o_conn->c_txn_backend = op->o_bd; + + } else if( op->o_conn->c_txn_backend != op->o_bd ) { + rs->sr_text = "transaction cannot span multiple database contexts"; + rs->sr_err = LDAP_AFFECTS_MULTIPLE_DSAS; + goto txnReturn; + } + + /* insert operation into transaction */ + + rs->sr_text = "transaction specified"; + rs->sr_err = LDAP_SUCCESS; + +txnReturn: + /* release connection lock */ + ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); + + send_ldap_result( op, rs ); + return rs->sr_err; + } + + ctrls[num_ctrls] = NULL; + slap_mods_opattrs( op, &op->orr_modlist, 1 ); if( 0 ) { diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index 16d9b429fb..252570efcf 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -619,6 +619,12 @@ long connection_init( LDAP_STAILQ_INIT(&c->c_ops); LDAP_STAILQ_INIT(&c->c_pending_ops); +#ifdef LDAP_X_TXN + c->c_txn = 0; + c->c_txn_backend = NULL; + LDAP_STAILQ_INIT(&c->c_txn_ops); +#endif + BER_BVZERO( &c->c_sasl_bind_mech ); c->c_sasl_done = 0; c->c_sasl_authctx = NULL; @@ -660,6 +666,11 @@ long connection_init( assert( BER_BVISNULL( &c->c_peer_name ) ); assert( LDAP_STAILQ_EMPTY(&c->c_ops) ); assert( LDAP_STAILQ_EMPTY(&c->c_pending_ops) ); +#ifdef LDAP_X_TXN + assert( c->c_txn == 0 ); + assert( c->c_txn_backend == NULL ); + assert( LDAP_STAILQ_EMPTY(&c->c_txn_ops) ); +#endif assert( BER_BVISNULL( &c->c_sasl_bind_mech ) ); assert( c->c_sasl_done == 0 ); assert( c->c_sasl_authctx == NULL ); diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index f0dd9296bf..51d5ae3a9f 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -2635,7 +2635,9 @@ typedef struct slap_conn { struct slap_op *c_sasl_bindop; /* set to current op if it's a bind */ #ifdef LDAP_X_TXN - int c_txn; /* in transaction */ + int c_txn; /* true if transaction started */ + Backend *c_txn_backend; + LDAP_STAILQ_HEAD(c_to, slap_op) c_txn_ops; /* list of operations in txn */ #endif PagedResultsState c_pagedresults_state; /* paged result state */ diff --git a/servers/slapd/txn.c b/servers/slapd/txn.c index d1451c52d4..f8fb65785d 100644 --- a/servers/slapd/txn.c +++ b/servers/slapd/txn.c @@ -62,6 +62,7 @@ int txn_start_extop( goto done; } + assert( op->o_conn->c_txn_backend == NULL ); ++op->o_conn->c_txn; bv = (struct berval *) ch_malloc( sizeof (struct berval) ); @@ -180,6 +181,7 @@ int txn_end_extop( } op->o_conn->c_txn = 0; + op->o_conn->c_txn_backend = NULL; done: /* release connection lock */ -- 2.39.5