/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 2005-2007 The OpenLDAP Foundation.
+ * Copyright 2005-2009 The OpenLDAP Foundation.
* Portions copyright 2004-2005 Symas Corporation.
* All rights reserved.
*
Entry *li_old;
log_attr *li_oldattrs;
int li_success;
- int li_unlock;
ldap_pvt_thread_rmutex_t li_op_rmutex;
ldap_pvt_thread_mutex_t li_log_mutex;
} log_info;
if ( dd ) {
len = snprintf( ptr, size, "%d+", dd );
- assert( len >= 0 && len < size );
+ assert( len >= 0 && (unsigned) len < size );
size -= len;
ptr += len;
}
len = snprintf( ptr, size, "%02d:%02d", hh, mm );
- assert( len >= 0 && len < size );
+ assert( len >= 0 && (unsigned) len < size );
size -= len;
ptr += len;
if ( ss ) {
len = snprintf( ptr, size, ":%02d", ss );
- assert( len >= 0 && len < size );
+ assert( len >= 0 && (unsigned) len < size );
size -= len;
ptr += len;
}
log_old_lookup( Operation *op, SlapReply *rs )
{
purge_data *pd = op->o_callback->sc_private;
+ Attribute *a;
if ( rs->sr_type != REP_SEARCH) return 0;
if ( slapd_shutdown ) return 0;
- /* Remember old CSN */
- if ( pd->csn.bv_val[0] == '\0' ) {
- Attribute *a = attr_find( rs->sr_entry->e_attrs,
- slap_schema.si_ad_entryCSN );
- if ( a ) {
- int len = a->a_vals[0].bv_len;
- if ( len > pd->csn.bv_len )
- len = pd->csn.bv_len;
+ /* Remember max CSN: should always be the last entry
+ * seen, since log entries are ordered chronologically...
+ */
+ a = attr_find( rs->sr_entry->e_attrs,
+ slap_schema.si_ad_entryCSN );
+ if ( a ) {
+ ber_len_t len = a->a_vals[0].bv_len;
+ if ( len > pd->csn.bv_len )
+ len = pd->csn.bv_len;
+ if ( memcmp( a->a_vals[0].bv_val, pd->csn.bv_val, len ) > 0 ) {
AC_MEMCPY( pd->csn.bv_val, a->a_vals[0].bv_val, len );
pd->csn.bv_len = len;
}
if ( pd.used ) {
int i;
+ /* delete the expired entries */
op->o_tag = LDAP_REQ_DELETE;
op->o_callback = &nullsc;
op->o_csn = pd.csn;
}
ch_free( pd.ndn );
ch_free( pd.dn );
+
+ {
+ Modifications mod;
+ struct berval bv[2];
+ /* update context's entryCSN to reflect oldest CSN */
+ mod.sml_numvals = 1;
+ mod.sml_values = bv;
+ bv[0] = pd.csn;
+ BER_BVZERO(&bv[1]);
+ mod.sml_nvalues = NULL;
+ mod.sml_desc = slap_schema.si_ad_entryCSN;
+ mod.sml_op = LDAP_MOD_REPLACE;
+ mod.sml_flags = SLAP_MOD_INTERNAL;
+ mod.sml_next = NULL;
+
+ op->o_tag = LDAP_REQ_MODIFY;
+ op->orm_modlist = &mod;
+ op->orm_no_opattrs = 1;
+ op->o_req_dn = li->li_db->be_suffix[0];
+ op->o_req_ndn = li->li_db->be_nsuffix[0];
+ op->o_no_schema_check = 1;
+ op->o_managedsait = SLAP_CONTROL_NONCRITICAL;
+ op->o_bd->be_modify( op, &rs );
+ if ( mod.sml_next ) {
+ slap_mods_free( mod.sml_next, 1 );
+ }
+ }
}
ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
if ( li->li_task ) {
struct re_s *re = li->li_task;
li->li_task = NULL;
+ ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ))
ldap_pvt_runqueue_stoptask( &slapd_rq, re );
ldap_pvt_runqueue_remove( &slapd_rq, re );
+ ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
}
li->li_age = 0;
li->li_cycle = 0;
struct re_s *re = li->li_task;
if ( re )
re->interval.tv_sec = li->li_cycle;
- else
+ else {
+ ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
li->li_task = ldap_pvt_runqueue_insert( &slapd_rq,
li->li_cycle, accesslog_purge, li,
"accesslog_purge", li->li_db ?
li->li_db->be_suffix[0].bv_val :
c->be->be_suffix[0].bv_val );
+ ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
+ }
}
}
break;
struct berval *valp )
{
struct berval val, bv;
- int i;
+ ber_len_t i;
int rc = LDAP_SUCCESS;
assert( valp != NULL );
}
if ( !BER_BVISNULL( &ctrls[ i ]->ldctl_value ) ) {
- int j;
+ ber_len_t j;
ptr = lutil_strcopy( ptr, " controlValue \"" );
for ( j = 0; j < ctrls[ i ]->ldctl_value.bv_len; j++ )
return SLAP_CB_CONTINUE;
if ( lo->mask & LOG_OP_WRITES ) {
+ slap_callback *cb;
ldap_pvt_thread_mutex_lock( &li->li_log_mutex );
old = li->li_old;
li->li_old = NULL;
- li->li_unlock = 0;
+ /* Disarm mod_cleanup */
+ for ( cb = op->o_callback; cb; cb = cb->sc_next ) {
+ if ( cb->sc_private == (void *)on ) {
+ cb->sc_private = NULL;
+ break;
+ }
+ }
ldap_pvt_thread_rmutex_unlock( &li->li_op_rmutex, op->o_tid );
}
attr_merge_one( e, ad_reqMessage, &bv, NULL );
}
bv.bv_len = snprintf( timebuf, sizeof( timebuf ), "%d", rs->sr_err );
- if ( bv.bv_len >= 0 && bv.bv_len < sizeof( timebuf ) ) {
+ if ( bv.bv_len < sizeof( timebuf ) ) {
bv.bv_val = timebuf;
attr_merge_one( e, ad_reqResult, &bv, NULL );
}
}
bv.bv_val = timebuf;
bv.bv_len = snprintf( bv.bv_val, sizeof( timebuf ), "%d", rs->sr_nentries );
- if ( bv.bv_len >= 0 && bv.bv_len < sizeof( timebuf ) ) {
+ if ( bv.bv_len < sizeof( timebuf ) ) {
attr_merge_one( e, ad_reqEntries, &bv, NULL );
} /* else? */
bv.bv_len = snprintf( bv.bv_val, sizeof( timebuf ), "%d", op->ors_tlimit );
- if ( bv.bv_len >= 0 && bv.bv_len < sizeof( timebuf ) ) {
+ if ( bv.bv_len < sizeof( timebuf ) ) {
attr_merge_one( e, ad_reqTimeLimit, &bv, NULL );
} /* else? */
bv.bv_len = snprintf( bv.bv_val, sizeof( timebuf ), "%d", op->ors_slimit );
- if ( bv.bv_len >= 0 && bv.bv_len < sizeof( timebuf ) ) {
+ if ( bv.bv_len < sizeof( timebuf ) ) {
attr_merge_one( e, ad_reqSizeLimit, &bv, NULL );
} /* else? */
break;
case LOG_EN_BIND:
bv.bv_val = timebuf;
bv.bv_len = snprintf( bv.bv_val, sizeof( timebuf ), "%d", op->o_protocol );
- if ( bv.bv_len >= 0 && bv.bv_len < sizeof( timebuf ) ) {
+ if ( bv.bv_len < sizeof( timebuf ) ) {
attr_merge_one( e, ad_reqVersion, &bv, NULL );
} /* else? */
if ( op->orb_method == LDAP_AUTH_SIMPLE ) {
{
slap_callback *sc = op->o_callback;
slap_overinst *on = sc->sc_private;
- log_info *li = on->on_bi.bi_private;
op->o_callback = sc->sc_next;
op->o_tmpfree( sc, op->o_tmpmemctx );
- if ( li->li_unlock ) {
+ if ( on ) {
BackendInfo *bi = op->o_bd->bd_info;
op->o_bd->bd_info = (BackendInfo *)on;
accesslog_response( op, rs );
log_info *li = on->on_bi.bi_private;
if ( li->li_ops & LOG_OP_WRITES ) {
- slap_callback *cb = op->o_tmpalloc( sizeof( slap_callback ), op->o_tmpmemctx );
+ slap_callback *cb = op->o_tmpalloc( sizeof( slap_callback ), op->o_tmpmemctx ), *cb2;
cb->sc_cleanup = accesslog_mod_cleanup;
cb->sc_response = NULL;
cb->sc_private = on;
- cb->sc_next = op->o_callback;
- op->o_callback = cb;
+ cb->sc_next = NULL;
+ for ( cb2 = op->o_callback; cb2->sc_next; cb2 = cb2->sc_next );
+ cb2->sc_next = cb;
ldap_pvt_thread_rmutex_lock( &li->li_op_rmutex, op->o_tid );
- li->li_unlock = 1;
if ( li->li_oldf && ( op->o_tag == LDAP_REQ_DELETE ||
op->o_tag == LDAP_REQ_MODIFY ||
( op->o_tag == LDAP_REQ_MODRDN && li->li_oldattrs ))) {
int rc;
Entry *e;
- op->o_bd->bd_info = on->on_info->oi_orig;
+ op->o_bd->bd_info = (BackendInfo *)on->on_info;
rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &e );
if ( e ) {
if ( test_filter( op, e, li->li_oldf ) == LDAP_COMPARE_TRUE )
e = accesslog_entry( op, rs, LOG_EN_ABANDON, &op2 );
bv.bv_val = buf;
bv.bv_len = snprintf( buf, sizeof( buf ), "%d", op->orn_msgid );
- if ( bv.bv_len >= 0 && bv.bv_len < sizeof( buf ) ) {
+ if ( bv.bv_len < sizeof( buf ) ) {
attr_merge_one( e, ad_reqId, &bv, NULL );
} /* else? */
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
log_info *li = on->on_bi.bi_private;
+ if ( op->o_sync != SLAP_CONTROL_NONE )
+ return SLAP_CB_CONTINUE;
+
if ( rs->sr_entry != NULL
&& dn_match( &op->o_bd->be_nsuffix[0], &rs->sr_entry->e_nname ) )
{
ber_dupbv( &li->li_db->be_rootndn, li->li_db->be_nsuffix );
}
+ ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
ldap_pvt_runqueue_insert( &slapd_rq, 3600, accesslog_db_root, on,
"accesslog_db_root", li->li_db->be_suffix[0].bv_val );
+ ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
return 0;
}