]> git.sur5r.net Git - openldap/commitdiff
Additional TXN changes
authorKurt Zeilenga <kurt@openldap.org>
Tue, 7 Mar 2006 02:21:27 +0000 (02:21 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Tue, 7 Mar 2006 02:21:27 +0000 (02:21 +0000)
libraries/libldap/txn.c
servers/slapd/slap.h
servers/slapd/txn.c

index c25460a8e764fdf9931bf8e9b6a3e249096cb114..8c17ea6948a2dbdfa705ff8001590f664a8e4c08 100644 (file)
@@ -74,7 +74,13 @@ ldap_txn_end(
        assert( txnid != NULL );
 
        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 );
 
        rc = ldap_extended_operation( ld, LDAP_EXOP_X_TXN_END,
@@ -93,30 +99,23 @@ ldap_txn_end_s(
        LDAPControl **cctrls,
        int *retidp )
 {
-       int rc, msgid;
-       struct berval *retdata = NULL;
-       LDAPMessage *res;
+       int rc;
+       BerElement *txnber = NULL;
+       struct berval *txnval = NULL;
 
-       rc = ldap_txn_end( ld, commit, txnid, sctrls, cctrls, &msgid );
-       if( rc != LDAP_SUCCESS ) return rc;
+       txnber = ber_alloc_t( LBER_USE_DER );
 
-       if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res )
-               == -1 )
-       {
-               return ld->ld_errno;
+       if( commit ) {
+               ber_printf( txnber, "{o}", txnid );
+       } else {
+               ber_printf( txnber, "{bo}", commit, txnid );
        }
 
-       rc = ldap_parse_extended_result( ld, res, NULL, &retdata, 0 );
-       if( rc != LDAP_SUCCESS ) {
-               ldap_msgfree( res );
-               return rc;
-       }
+       ber_flatten( txnber, &txnval );
 
-       /* don't bother parsing the retdata (yet) */
-       if( retidp != NULL ) {
-               *retidp = 0;
-       }
+       rc = ldap_extended_operation_s( ld, LDAP_EXOP_X_TXN_END,
+               txnval, sctrls, cctrls, NULL, NULL );
 
-       return ldap_result2error( ld, res, 1 );
+       return rc;
 }
 #endif
index 46f5b9104cb08cd114e067b5b82dc73c09d585b8..f0dd9296bff10d780fe5aa4a6b53e21d394e7d93 100644 (file)
@@ -2634,6 +2634,10 @@ typedef struct slap_conn {
        void    *c_sasl_extra;          /* SASL session extra stuff */
        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 */
 
        long    c_n_ops_received;       /* num of ops received (next op_id) */
index e0d46670f07de77561870c6a2cdb24e1c7ff1643..d1451c52d45d373903ea44a73ffa296513bfa881 100644 (file)
@@ -35,16 +35,17 @@ const struct berval slap_EXOP_TXN_END = BER_BVC(LDAP_EXOP_X_TXN_END);
 int txn_start_extop(
        Operation *op, SlapReply *rs )
 {
+       int rc;
        struct berval *bv;
 
+       Statslog( LDAP_DEBUG_STATS, "%s TXN START\n",
+               op->o_log_prefix, 0, 0, 0, 0 );
+
        if( op->ore_reqdata != NULL ) {
                rs->sr_text = "no request data expected";
                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;
        if( backend_check_restrictions( op, rs,
                (struct berval *)&slap_EXOP_TXN_START ) != LDAP_SUCCESS )
@@ -52,12 +53,28 @@ int txn_start_extop(
                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->bv_len = 0;
        bv->bv_val = NULL;
 
        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(
@@ -88,13 +105,25 @@ int txn_spec_ctrl(
 int txn_end_extop(
        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 ) {
                rs->sr_text = "request data expected";
                return LDAP_PROTOCOL_ERROR;
        }
-
-       Statslog( LDAP_DEBUG_STATS, "%s TXN END\n",
-               op->o_log_prefix, 0, 0, 0, 0 );
+       if( op->ore_reqdata->bv_len == 0 ) {
+               rs->sr_text = "empty request data";
+               return LDAP_PROTOCOL_ERROR;
+       }
 
        op->o_bd = op->o_conn->c_authz_backend;
        if( backend_check_restrictions( op, rs,
@@ -103,8 +132,60 @@ int txn_end_extop(
                return rs->sr_err;
        }
 
-       rs->sr_text = "not yet implemented";
-       return LDAP_UNWILLING_TO_PERFORM;
+       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";
+               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 */