Commit 7dcb68f6 authored by Howard Chu's avatar Howard Chu
Browse files

Move CSN invocations to backends

parent 408fa06f
......@@ -2603,7 +2603,7 @@ acl_set_gather( SetCookie *cookie, struct berval *name, AttributeDescription *de
op2.o_tag = LDAP_REQ_SEARCH;
op2.o_ndn = op2.o_bd->be_rootndn;
op2.o_callback = &cb;
op2.o_time = slap_get_time();
slap_op_time( &op2.o_time, &op2.o_tincr );
op2.o_do_not_cache = 1;
op2.o_is_auth_check = 0;
ber_dupbv_x( &op2.o_req_dn, &op2.o_req_ndn, cp->asc_op->o_tmpmemctx );
......
......@@ -30,6 +30,7 @@
#include <ac/time.h>
#include <ac/socket.h>
#include "lutil.h"
#include "slap.h"
int
......@@ -192,8 +193,6 @@ do_add( Operation *op, SlapReply *rs )
}
done:;
slap_graduate_commit_csn( op );
if ( modlist != NULL ) {
slap_mods_free( modlist, 0 );
}
......@@ -312,14 +311,6 @@ fe_op_add( Operation *op, SlapReply *rs )
}
rs->sr_err = slap_mods_opattrs( op, modlist,
modtail, &rs->sr_text,
textbuf, textlen, 1 );
if ( rs->sr_err != LDAP_SUCCESS ) {
send_ldap_result( op, rs );
goto done;
}
/* check for duplicate values */
rs->sr_err = slap_mods_no_repl_user_mod_check( op,
modlist, &rs->sr_text, textbuf, textlen );
......@@ -626,3 +617,119 @@ slap_entry2mods(
return LDAP_SUCCESS;
}
int slap_add_opattrs(
Operation *op,
const char **text,
char *textbuf,
size_t textlen,
int manage_ctxcsn )
{
struct berval name, timestamp, csn = BER_BVNULL;
struct berval nname, tmp;
char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
Attribute *a;
a = attr_find( op->ora_e->e_attrs,
slap_schema.si_ad_structuralObjectClass );
if ( !a ) {
Attribute *oc;
int rc;
oc = attr_find( op->ora_e->e_attrs, slap_schema.si_ad_objectClass );
if ( oc ) {
rc = structural_class( oc->a_vals, &tmp, NULL, text,
textbuf, textlen );
if( rc != LDAP_SUCCESS ) return rc;
attr_merge_one( op->ora_e, slap_schema.si_ad_structuralObjectClass,
&tmp, NULL );
}
}
if ( SLAP_LASTMOD( op->o_bd ) ) {
char *ptr;
timestamp.bv_val = timebuf;
if ( BER_BVISEMPTY( &op->o_csn )) {
if ( SLAP_SHADOW( op->o_bd ))
manage_ctxcsn = 0;
csn.bv_val = csnbuf;
csn.bv_len = sizeof(csnbuf);
slap_get_csn( op, &csn, manage_ctxcsn );
} else {
csn = op->o_csn;
}
ptr = strchr( csn.bv_val, '#' );
if ( ptr ) {
timestamp.bv_len = ptr - csn.bv_val;
if ( timestamp.bv_len >= sizeof(timebuf) )
timestamp.bv_len = sizeof(timebuf) - 1;
strncpy( timebuf, csn.bv_val, timestamp.bv_len );
timebuf[timestamp.bv_len] = '\0';
} else {
time_t now = slap_get_time();
timestamp.bv_len = sizeof(timebuf);
slap_timestamp( &now, &timestamp );
}
if ( BER_BVISEMPTY( &op->o_dn ) ) {
BER_BVSTR( &name, SLAPD_ANONYMOUS );
nname = name;
} else {
name = op->o_dn;
nname = op->o_ndn;
}
a = attr_find( op->ora_e->e_attrs,
slap_schema.si_ad_entryUUID );
if ( !a ) {
char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ];
tmp.bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) );
tmp.bv_val = uuidbuf;
attr_merge_normalize_one( op->ora_e,
slap_schema.si_ad_entryUUID, &tmp, op->o_tmpmemctx );
}
a = attr_find( op->ora_e->e_attrs,
slap_schema.si_ad_creatorsName );
if ( !a ) {
attr_merge_one( op->ora_e,
slap_schema.si_ad_creatorsName, &name, &nname );
}
a = attr_find( op->ora_e->e_attrs,
slap_schema.si_ad_createTimestamp );
if ( !a ) {
attr_merge_one( op->ora_e,
slap_schema.si_ad_createTimestamp, &timestamp, NULL );
}
a = attr_find( op->ora_e->e_attrs,
slap_schema.si_ad_entryCSN );
if ( !a ) {
attr_merge_one( op->ora_e,
slap_schema.si_ad_entryCSN, &csn, NULL );
}
a = attr_find( op->ora_e->e_attrs,
slap_schema.si_ad_modifiersName );
if ( !a ) {
attr_merge_one( op->ora_e,
slap_schema.si_ad_modifiersName, &name, &nname );
}
a = attr_find( op->ora_e->e_attrs,
slap_schema.si_ad_modifyTimestamp );
if ( !a ) {
attr_merge_one( op->ora_e,
slap_schema.si_ad_modifyTimestamp, &timestamp, NULL );
}
}
return LDAP_SUCCESS;
}
......@@ -51,6 +51,8 @@ bdb_add(Operation *op, SlapReply *rs )
ctrls[num_ctrls] = 0;
slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
/* check entry's schema */
rs->sr_err = entry_schema_check( op, op->oq_add.rs_e, NULL,
get_manageDIT(op), &rs->sr_text, textbuf, textlen );
......@@ -170,14 +172,8 @@ retry: /* transaction retry */
"does not exist\n", 0, 0, 0 );
rs->sr_err = LDAP_REFERRAL;
send_ldap_result( op, rs );
ber_bvarray_free( rs->sr_ref );
op->o_tmpfree( (char *)rs->sr_matched, op->o_tmpmemctx );
rs->sr_ref = NULL;
rs->sr_matched = NULL;
goto done;
rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
goto return_results;
}
rs->sr_err = access_allowed( op, p,
......@@ -221,22 +217,18 @@ retry: /* transaction retry */
if ( is_entry_referral( p ) ) {
/* parent is a referral, don't allow add */
rs->sr_matched = p->e_name.bv_val;
rs->sr_matched = ber_strdup_x( p->e_name.bv_val,
op->o_tmpmemctx );
rs->sr_ref = get_entry_referrals( op, p );
bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p );
p = NULL;
Debug( LDAP_DEBUG_TRACE,
LDAP_XSTRING(bdb_add) ": parent is referral\n",
0, 0, 0 );
rs->sr_err = LDAP_REFERRAL;
send_ldap_result( op, rs );
ber_bvarray_free( rs->sr_ref );
bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p );
rs->sr_ref = NULL;
rs->sr_matched = NULL;
p = NULL;
goto done;
rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
goto return_results;
}
#ifdef BDB_SUBENTRIES
......@@ -430,14 +422,9 @@ retry: /* transaction retry */
return_results:
send_ldap_result( op, rs );
if ( !SLAP_SHADOW( op->o_bd ))
slap_graduate_commit_csn( op );
if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
ldap_pvt_thread_yield();
TXN_CHECKPOINT( bdb->bi_dbenv,
bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
}
done:
if( ltid != NULL ) {
TXN_ABORT( ltid );
op->o_private = NULL;
......@@ -447,5 +434,11 @@ done:
slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
}
if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
ldap_pvt_thread_yield();
TXN_CHECKPOINT( bdb->bi_dbenv,
bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
}
return rs->sr_err;
}
......@@ -19,6 +19,7 @@
#include <stdio.h>
#include <ac/string.h>
#include "lutil.h"
#include "back-bdb.h"
int
......@@ -56,6 +57,16 @@ bdb_delete( Operation *op, SlapReply *rs )
Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(bdb_delete) ": %s\n",
op->o_req_dn.bv_val, 0, 0 );
/* allocate CSN */
if ( !SLAP_SHADOW( op->o_bd )) {
struct berval csn;
char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
csn.bv_val = csnbuf;
csn.bv_len = sizeof(csnbuf);
slap_get_csn( op, &csn, 1 );
}
if( 0 ) {
retry: /* transaction retry */
if( e != NULL ) {
......@@ -161,17 +172,8 @@ retry: /* transaction retry */
}
rs->sr_err = LDAP_REFERRAL;
send_ldap_result( op, rs );
if ( rs->sr_ref != default_referral ) {
ber_bvarray_free( rs->sr_ref );
}
free( (char *)rs->sr_matched );
rs->sr_ref = NULL;
rs->sr_matched = NULL;
rs->sr_err = -1;
goto done;
rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
goto return_results;
}
rc = bdb_cache_find_id( op, ltid, eip->bei_id, &eip, 0, locker, &plock );
......@@ -291,15 +293,9 @@ retry: /* transaction retry */
0, 0, 0 );
rs->sr_err = LDAP_REFERRAL;
rs->sr_matched = e->e_name.bv_val;
send_ldap_result( op, rs );
ber_bvarray_free( rs->sr_ref );
rs->sr_ref = NULL;
rs->sr_matched = NULL;
rs->sr_err = 1;
goto done;
rs->sr_matched = ch_strdup( e->e_name.bv_val );
rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
goto return_results;
}
/* pre-read */
......@@ -487,19 +483,10 @@ retry: /* transaction retry */
if( num_ctrls ) rs->sr_ctrls = ctrls;
return_results:
send_ldap_result( op, rs );
if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
ldap_pvt_thread_yield();
TXN_CHECKPOINT( bdb->bi_dbenv,
bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
}
if ( rs->sr_err == LDAP_SUCCESS && parent_is_glue && parent_is_leaf ) {
op->o_delete_glue_parent = 1;
}
done:
if ( p )
bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);
......@@ -518,9 +505,19 @@ done:
op->o_private = NULL;
}
send_ldap_result( op, rs );
if ( !SLAP_SHADOW( op->o_bd ))
slap_graduate_commit_csn( op );
if( preread_ctrl != NULL ) {
slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
slap_sl_free( *preread_ctrl, op->o_tmpmemctx );
}
if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
ldap_pvt_thread_yield();
TXN_CHECKPOINT( bdb->bi_dbenv,
bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
}
return rs->sr_err;
}
......@@ -289,6 +289,9 @@ bdb_modify( Operation *op, SlapReply *rs )
ctrls[num_ctrls] = NULL;
if ( !SLAP_SHADOW( op->o_bd ))
slap_mods_opattrs( op, op->orm_modlist, 1 );
if( 0 ) {
retry: /* transaction retry */
if ( dummy.e_attrs ) {
......@@ -573,6 +576,8 @@ return_results:
attrs_free( dummy.e_attrs );
}
send_ldap_result( op, rs );
if ( !SLAP_SHADOW( op->o_bd ))
slap_graduate_commit_csn( op );
if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
ldap_pvt_thread_yield();
......
......@@ -25,6 +25,16 @@
#include "back-ldbm.h"
#include "proto-back-ldbm.h"
static int
ldbm_csn_cb(
Operation *op,
SlapReply *rs )
{
op->o_callback = op->o_callback->sc_next;
slap_graduate_commit_csn( op );
return SLAP_CB_CONTINUE;
}
int
ldbm_back_add(
Operation *op,
......@@ -38,6 +48,7 @@ ldbm_back_add(
AttributeDescription *entry = slap_schema.si_ad_entry;
char textbuf[SLAP_TEXT_BUFLEN];
size_t textlen = sizeof textbuf;
slap_callback cb = { NULL };
#ifdef LDBM_SUBENTRIES
int subentry;
#endif
......@@ -45,6 +56,12 @@ ldbm_back_add(
Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_add: %s\n",
op->o_req_dn.bv_val, 0, 0);
slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
cb.sc_cleanup = ldbm_csn_cb;
cb.sc_next = op->o_callback;
op->o_callback = &cb;
rs->sr_err = entry_schema_check( op, op->oq_add.rs_e, NULL,
get_manageDIT(op), &rs->sr_text, textbuf, textlen );
......
......@@ -44,6 +44,16 @@ ldbm_back_delete(
/* grab giant lock for writing */
ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock);
/* allocate CSN */
if ( !SLAP_SHADOW( op->o_bd )) {
struct berval csn;
char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
csn.bv_val = csnbuf;
csn.bv_len = sizeof(csnbuf);
slap_get_csn( op, &csn, 1 );
}
/* get entry with writer lock */
e = dn2entry_w( op->o_bd, &op->o_req_ndn, &matched );
......@@ -64,16 +74,9 @@ ldbm_back_delete(
&op->o_req_dn, LDAP_SCOPE_DEFAULT );
}
ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
rs->sr_err = LDAP_REFERRAL;
send_ldap_result( op, rs );
if ( rs->sr_ref ) ber_bvarray_free( rs->sr_ref );
free( (char *)rs->sr_matched );
rs->sr_ref = NULL;
rs->sr_matched = NULL;
return( -1 );
rs->sr_flags |= REP_MATCHED_MUST_BE_FREED | REP_REF_MUSTBEFREED;
goto return_results;
}
/* check entry for "entry" acl */
......@@ -83,10 +86,8 @@ ldbm_back_delete(
"<=- ldbm_back_delete: no write access to entry\n", 0,
0, 0 );
send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS,
"no write access to entry" );
rc = LDAP_INSUFFICIENT_ACCESS;
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
rs->sr_text = "no write access to entry";
goto return_results;
}
......@@ -99,13 +100,8 @@ ldbm_back_delete(
0, 0 );
rs->sr_err = LDAP_REFERRAL;
rs->sr_matched = e->e_name.bv_val;
send_ldap_result( op, rs );
if ( rs->sr_ref ) ber_bvarray_free( rs->sr_ref );
rs->sr_ref = NULL;
rs->sr_matched = NULL;
rc = LDAP_REFERRAL;
rs->sr_matched = ch_strdup( e->e_name.bv_val );
rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
goto return_results;
}
......@@ -113,8 +109,8 @@ ldbm_back_delete(
Debug(LDAP_DEBUG_ARGS, "<=- ldbm_back_delete: non leaf %s\n",
op->o_req_dn.bv_val, 0, 0);
send_ldap_error( op, rs, LDAP_NOT_ALLOWED_ON_NONLEAF,
"subordinate objects must be deleted first");
rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF;
rs->sr_text = "subordinate objects must be deleted first";
goto return_results;
}
......@@ -126,8 +122,8 @@ ldbm_back_delete(
"<=- ldbm_back_delete: parent does not exist\n",
0, 0, 0);
send_ldap_error( op, rs, LDAP_OTHER,
"could not locate parent of entry" );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "could not locate parent of entry";
goto return_results;
}
......@@ -139,8 +135,8 @@ ldbm_back_delete(
"<=- ldbm_back_delete: no access to parent\n", 0,
0, 0 );
send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS,
"no write access to parent" );
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
rs->sr_text = "no write access to parent";
goto return_results;
}
......@@ -161,8 +157,8 @@ ldbm_back_delete(
"<=- ldbm_back_delete: no "
"access to parent\n", 0, 0, 0 );
send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS,
"no write access to parent" );
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
rs->sr_text = "no write access to parent";
goto return_results;
}
......@@ -171,9 +167,7 @@ ldbm_back_delete(
"<=- ldbm_back_delete: no parent & "
"not root\n", 0, 0, 0);
send_ldap_error( op, rs,
LDAP_INSUFFICIENT_ACCESS,
NULL );
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
goto return_results;
}
}
......@@ -185,8 +179,8 @@ ldbm_back_delete(
"<=- ldbm_back_delete: operations error %s\n",
op->o_req_dn.bv_val, 0, 0);
send_ldap_error( op, rs, LDAP_OTHER,
"DN index delete failed" );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "DN index delete failed";
goto return_results;
}
......@@ -196,8 +190,8 @@ ldbm_back_delete(
"<=- ldbm_back_delete: operations error %s\n",
op->o_req_dn.bv_val, 0, 0);
send_ldap_error( op, rs, LDAP_OTHER,
"entry delete failed" );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "entry delete failed";
goto return_results;
}
......@@ -205,19 +199,25 @@ ldbm_back_delete(
(void) index_entry_del( op, e );
rs->sr_err = LDAP_SUCCESS;
send_ldap_result( op, rs );
rc = LDAP_SUCCESS;
return_results:;
rc = rs->sr_err;
if( p != NULL ) {
/* free parent and writer lock */
cache_return_entry_w( &li->li_cache, p );
}
/* free entry and writer lock */
cache_return_entry_w( &li->li_cache, e );
if ( e != NULL ) {
/* free entry and writer lock */
cache_return_entry_w( &li->li_cache, e );
}
ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
send_ldap_result( op, rs );
if ( !SLAP_SHADOW( op->o_bd ))
slap_graduate_commit_csn( op );
return rc;
}
......@@ -241,6 +241,9 @@ ldbm_back_modify(
Debug(LDAP_DEBUG_ARGS, "ldbm_back_modify:\n", 0, 0, 0);
if ( !SLAP_SHADOW( op->o_bd ))
slap_mods_opattrs( op, op->orm_modlist, 1 );
/* grab giant lock for writing */
ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock);
......@@ -250,7 +253,7 @@ ldbm_back_modify(
/* FIXME: dn2entry() should return non-glue entry */
if (( e == NULL ) || ( !manageDSAit && e && is_entry_glue( e ))) {
if ( matched != NULL ) {
rs->sr_matched = ch_strdup( matched->e_dn );
rs->sr_matched = ber_strdup_x( matched->e_dn, op->o_tmpmemctx );
rs->sr_ref = is_entry_referral( matched )
? get_entry_referrals( op, matched )
: NULL;
......@@ -260,16 +263,9 @@ ldbm_back_modify(
&op->o_req_dn, LDAP_SCOPE_DEFAULT );
}
ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
rs->sr_err = LDAP_REFERRAL;
send_ldap_result( op, rs );
if ( rs->sr_ref ) ber_bvarray_free( rs->sr_ref );
free( (char *)rs->sr_matched );
rs->sr_ref = NULL;
rs->sr_matched = NULL;
return rs->sr_err;
rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
goto return_results;
}
if ( !manageDSAit && is_entry_referral( e ) )
......@@ -282,47 +278,31 @@ ldbm_back_modify(
0, 0 );
rs->sr_err = LDAP_REFERRAL;
rs->sr_matched = e->e_name.bv_val;
send_ldap_result( op, rs );
if ( rs->sr_ref ) ber_bvarray_free( rs->sr_ref );
<