Additional TXN changes

This commit is contained in:
Kurt Zeilenga 2006-03-07 02:21:27 +00:00
parent 8ac8d70a55
commit fad69dbef8
3 changed files with 113 additions and 29 deletions

View file

@ -74,7 +74,13 @@ ldap_txn_end(
assert( txnid != NULL ); assert( txnid != NULL );
txnber = ber_alloc_t( LBER_USE_DER ); txnber = ber_alloc_t( LBER_USE_DER );
ber_printf( txnber, "{io}", commit, txnid );
if( commit ) {
ber_printf( txnber, "{o}", txnid );
} else {
ber_printf( txnber, "{bo}", commit, txnid );
}
ber_flatten( txnber, &txnval ); ber_flatten( txnber, &txnval );
rc = ldap_extended_operation( ld, LDAP_EXOP_X_TXN_END, rc = ldap_extended_operation( ld, LDAP_EXOP_X_TXN_END,
@ -93,30 +99,23 @@ ldap_txn_end_s(
LDAPControl **cctrls, LDAPControl **cctrls,
int *retidp ) int *retidp )
{ {
int rc, msgid; int rc;
struct berval *retdata = NULL; BerElement *txnber = NULL;
LDAPMessage *res; struct berval *txnval = NULL;
rc = ldap_txn_end( ld, commit, txnid, sctrls, cctrls, &msgid ); txnber = ber_alloc_t( LBER_USE_DER );
if( rc != LDAP_SUCCESS ) return rc;
if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res ) if( commit ) {
== -1 ) ber_printf( txnber, "{o}", txnid );
{ } else {
return ld->ld_errno; ber_printf( txnber, "{bo}", commit, txnid );
} }
rc = ldap_parse_extended_result( ld, res, NULL, &retdata, 0 ); ber_flatten( txnber, &txnval );
if( rc != LDAP_SUCCESS ) {
ldap_msgfree( res ); rc = ldap_extended_operation_s( ld, LDAP_EXOP_X_TXN_END,
txnval, sctrls, cctrls, NULL, NULL );
return rc; return rc;
} }
/* don't bother parsing the retdata (yet) */
if( retidp != NULL ) {
*retidp = 0;
}
return ldap_result2error( ld, res, 1 );
}
#endif #endif

View file

@ -2634,6 +2634,10 @@ typedef struct slap_conn {
void *c_sasl_extra; /* SASL session extra stuff */ void *c_sasl_extra; /* SASL session extra stuff */
struct slap_op *c_sasl_bindop; /* set to current op if it's a bind */ struct slap_op *c_sasl_bindop; /* set to current op if it's a bind */
#ifdef LDAP_X_TXN
int c_txn; /* in transaction */
#endif
PagedResultsState c_pagedresults_state; /* paged result state */ PagedResultsState c_pagedresults_state; /* paged result state */
long c_n_ops_received; /* num of ops received (next op_id) */ long c_n_ops_received; /* num of ops received (next op_id) */

View file

@ -35,16 +35,17 @@ const struct berval slap_EXOP_TXN_END = BER_BVC(LDAP_EXOP_X_TXN_END);
int txn_start_extop( int txn_start_extop(
Operation *op, SlapReply *rs ) Operation *op, SlapReply *rs )
{ {
int rc;
struct berval *bv; struct berval *bv;
Statslog( LDAP_DEBUG_STATS, "%s TXN START\n",
op->o_log_prefix, 0, 0, 0, 0 );
if( op->ore_reqdata != NULL ) { if( op->ore_reqdata != NULL ) {
rs->sr_text = "no request data expected"; rs->sr_text = "no request data expected";
return LDAP_PROTOCOL_ERROR; return LDAP_PROTOCOL_ERROR;
} }
Statslog( LDAP_DEBUG_STATS, "%s TXN START\n",
op->o_log_prefix, 0, 0, 0, 0 );
op->o_bd = op->o_conn->c_authz_backend; op->o_bd = op->o_conn->c_authz_backend;
if( backend_check_restrictions( op, rs, if( backend_check_restrictions( op, rs,
(struct berval *)&slap_EXOP_TXN_START ) != LDAP_SUCCESS ) (struct berval *)&slap_EXOP_TXN_START ) != LDAP_SUCCESS )
@ -52,12 +53,28 @@ int txn_start_extop(
return rs->sr_err; return rs->sr_err;
} }
/* acquire connection lock */
ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
if( op->o_conn->c_txn ) {
rs->sr_text = "Too many transactions";
rc = LDAP_BUSY;
goto done;
}
++op->o_conn->c_txn;
bv = (struct berval *) ch_malloc( sizeof (struct berval) ); bv = (struct berval *) ch_malloc( sizeof (struct berval) );
bv->bv_len = 0; bv->bv_len = 0;
bv->bv_val = NULL; bv->bv_val = NULL;
rs->sr_rspdata = bv; rs->sr_rspdata = bv;
return LDAP_SUCCESS; rc = LDAP_SUCCESS;
done:
/* release connection lock */
ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
return rc;
} }
int txn_spec_ctrl( int txn_spec_ctrl(
@ -88,13 +105,25 @@ int txn_spec_ctrl(
int txn_end_extop( int txn_end_extop(
Operation *op, SlapReply *rs ) Operation *op, SlapReply *rs )
{ {
int rc;
BerElementBuffer berbuf;
BerElement *ber = (BerElement *)&berbuf;
ber_tag_t tag;
ber_len_t len;
ber_int_t commit=1;
struct berval txnid;
Statslog( LDAP_DEBUG_STATS, "%s TXN END\n",
op->o_log_prefix, 0, 0, 0, 0 );
if( op->ore_reqdata == NULL ) { if( op->ore_reqdata == NULL ) {
rs->sr_text = "request data expected"; rs->sr_text = "request data expected";
return LDAP_PROTOCOL_ERROR; return LDAP_PROTOCOL_ERROR;
} }
if( op->ore_reqdata->bv_len == 0 ) {
Statslog( LDAP_DEBUG_STATS, "%s TXN END\n", rs->sr_text = "empty request data";
op->o_log_prefix, 0, 0, 0, 0 ); return LDAP_PROTOCOL_ERROR;
}
op->o_bd = op->o_conn->c_authz_backend; op->o_bd = op->o_conn->c_authz_backend;
if( backend_check_restrictions( op, rs, if( backend_check_restrictions( op, rs,
@ -103,8 +132,60 @@ int txn_end_extop(
return rs->sr_err; return rs->sr_err;
} }
ber_init2( ber, op->ore_reqdata, 0 );
tag = ber_scanf( ber, "{" /*}*/ );
if( tag == LBER_ERROR ) {
rs->sr_text = "request data decoding error";
return LDAP_PROTOCOL_ERROR;
}
tag = ber_peek_tag( ber, &len );
assert( tag == LBER_BOOLEAN );
if( tag == LBER_BOOLEAN ) {
tag = ber_scanf( ber, "b", &commit );
if( tag == LBER_ERROR ) {
rs->sr_text = "request data decoding error";
return LDAP_PROTOCOL_ERROR;
}
}
tag = ber_scanf( ber, /*{*/ "m}", &txnid );
if( tag == LBER_ERROR ) {
rs->sr_text = "request data decoding error";
return LDAP_PROTOCOL_ERROR;
}
if( txnid.bv_len ) {
rs->sr_text = "invalid transaction identifier";
return LDAP_X_TXN_ID_INVALID;
}
/* 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";
rc = LDAP_X_TXN_ID_INVALID;
goto done;
}
if( commit ) {
rs->sr_text = "not yet implemented"; rs->sr_text = "not yet implemented";
return LDAP_UNWILLING_TO_PERFORM; rc = LDAP_UNWILLING_TO_PERFORM;
} else {
rs->sr_text = "transaction aborted";
rc = LDAP_SUCCESS;;
}
op->o_conn->c_txn = 0;
done:
/* release connection lock */
ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
return rc;
} }
#endif /* LDAP_X_TXN */ #endif /* LDAP_X_TXN */