implement support for unregistering registered stuff

This commit is contained in:
Pierangelo Masarati 2006-09-06 12:06:42 +00:00
parent 829685e218
commit 127ac65c44
4 changed files with 326 additions and 97 deletions

View File

@ -119,6 +119,22 @@ monitor_cache_lock(
return( 0 );
}
/*
* tries to lock the entry (no r/w)
*/
int
monitor_cache_trylock(
Entry *e )
{
monitor_entry_t *mp;
assert( e != NULL );
assert( e->e_private != NULL );
mp = ( monitor_entry_t * )e->e_private;
return ldap_pvt_thread_mutex_trylock( &mp->mp_mutex );
}
/*
* gets an entry from the cache based on the normalized dn
* with mutex locked
@ -153,6 +169,109 @@ monitor_cache_get(
return ( *ep == NULL ? -1 : 0 );
}
/*
* gets an entry from the cache based on the normalized dn
* with mutex locked
*/
int
monitor_cache_remove(
monitor_info_t *mi,
struct berval *ndn,
Entry **ep )
{
monitor_cache_t tmp_mc, *mc;
struct berval pndn;
assert( mi != NULL );
assert( ndn != NULL );
assert( ep != NULL );
*ep = NULL;
dnParent( ndn, &pndn );
retry:;
ldap_pvt_thread_mutex_lock( &mi->mi_cache_mutex );
tmp_mc.mc_ndn = *ndn;
mc = ( monitor_cache_t * )avl_find( mi->mi_cache,
( caddr_t )&tmp_mc, monitor_cache_cmp );
if ( mc != NULL ) {
monitor_cache_t *pmc;
if ( monitor_cache_trylock( mc->mc_e ) ) {
ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
goto retry;
}
tmp_mc.mc_ndn = pndn;
pmc = ( monitor_cache_t * )avl_find( mi->mi_cache,
( caddr_t )&tmp_mc, monitor_cache_cmp );
if ( pmc != NULL ) {
monitor_entry_t *mp = (monitor_entry_t *)mc->mc_e->e_private,
*pmp = (monitor_entry_t *)pmc->mc_e->e_private;
Entry **entryp;
if ( monitor_cache_trylock( pmc->mc_e ) ) {
monitor_cache_release( mi, mc->mc_e );
ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
goto retry;
}
for ( entryp = &pmp->mp_children; *entryp != NULL; ) {
monitor_entry_t *next = (monitor_entry_t *)(*entryp)->e_private;
if ( next == mp ) {
*entryp = next->mp_next;
entryp = NULL;
break;
}
entryp = &next->mp_next;
}
if ( entryp != NULL ) {
Debug( LDAP_DEBUG_ANY,
"monitor_cache_remove(\"%s\"): "
"not in parent's list\n",
ndn->bv_val, 0, 0 );
}
/* either succeeded, and the entry is no longer
* in its parent's list, or failed, and the
* entry is neither mucked with nor returned */
monitor_cache_release( mi, pmc->mc_e );
if ( entryp == NULL ) {
monitor_cache_t *tmpmc;
tmp_mc.mc_ndn = *ndn;
tmpmc = avl_delete( &mi->mi_cache,
( caddr_t )&tmp_mc, monitor_cache_cmp );
assert( tmpmc == mc );
*ep = mc->mc_e;
ch_free( mc );
mc = NULL;
/* NOTE: we destroy the mutex, but otherwise
* leave the private data around; specifically,
* callbacks need be freed by someone else */
ldap_pvt_thread_mutex_destroy( &mp->mp_mutex );
mp->mp_next = NULL;
mp->mp_children = NULL;
}
}
monitor_cache_release( mi, mc->mc_e );
}
ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
return ( *ep == NULL ? -1 : 0 );
}
/*
* If the entry exists in cache, it is returned in locked status;
* otherwise, if the parent exists, if it may generate volatile
@ -277,11 +396,18 @@ monitor_entry_destroy( void *v_mc )
mp = ( monitor_entry_t * )mc->mc_e->e_private;
if ( mp->mp_cb ) {
if ( mp->mp_cb->mc_free ) {
mp->mp_cb->mc_free( mc->mc_e,
mp->mp_cb->mc_private );
monitor_callback_t *cb;
for ( cb = mp->mp_cb; cb != NULL; ) {
monitor_callback_t *next = cb->mc_next;
if ( cb->mc_free ) {
cb->mc_free( mc->mc_e, cb->mc_private );
}
ch_free( mp->mp_cb );
cb = next;
}
ch_free( mp->mp_cb );
}
ldap_pvt_thread_mutex_destroy( &mp->mp_mutex );

View File

@ -33,14 +33,6 @@
static int monitor_back_add_plugin( monitor_info_t *mi, Backend *be, Entry *e );
#endif /* defined(LDAP_SLAPI) */
#if 0 /* moved to back-bdb/monitor.c */
#if defined(SLAPD_BDB)
#include "../back-bdb/back-bdb.h"
#endif /* defined(SLAPD_BDB) */
#if defined(SLAPD_HDB)
#include "../back-hdb/back-bdb.h"
#endif /* defined(SLAPD_HDB) */
#endif
#if defined(SLAPD_LDAP)
#include "../back-ldap/back-ldap.h"
#endif /* defined(SLAPD_LDAP) */
@ -293,54 +285,6 @@ monitor_subsys_database_init(
if ( 0 ) {
assert( 0 );
#if 0 /* moved into back-bdb/monitor.c */
#if defined(SLAPD_BDB) || defined(SLAPD_HDB)
} else if ( strcmp( bi->bi_type, "bdb" ) == 0
|| strcmp( bi->bi_type, "hdb" ) == 0 )
{
struct berval bv;
ber_len_t pathlen = 0, len = 0;
char path[ PATH_MAX ] = { '\0' };
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
char *fname = bdb->bi_dbenv_home;
len = strlen( fname );
if ( fname[ 0 ] != '/' ) {
/* get full path name */
getcwd( path, sizeof( path ) );
pathlen = strlen( path );
if ( fname[ 0 ] == '.' && fname[ 1 ] == '/' ) {
fname += 2;
len -= 2;
}
}
bv.bv_len = STRLENOF( "file://" ) + pathlen
+ STRLENOF( "/" ) + len;
bv.bv_val = ch_malloc( bv.bv_len + STRLENOF( "/" ) + 1 );
AC_MEMCPY( bv.bv_val, "file://", STRLENOF( "file://" ) );
if ( pathlen ) {
AC_MEMCPY( &bv.bv_val[ STRLENOF( "file://" ) ],
path, pathlen );
bv.bv_val[ STRLENOF( "file://" ) + pathlen ] = '/';
pathlen++;
}
AC_MEMCPY( &bv.bv_val[ STRLENOF( "file://" ) + pathlen ],
fname, len );
if ( bv.bv_val[ bv.bv_len - 1 ] != '/' ) {
bv.bv_val[ bv.bv_len ] = '/';
bv.bv_len++;
}
bv.bv_val[ bv.bv_len ] = '\0';
attr_merge_normalize_one( e, slap_schema.si_ad_labeledURI,
&bv, NULL );
ch_free( bv.bv_val );
#endif /* defined(SLAPD_BDB) || defined(SLAPD_HDB) */
#endif
#if defined(SLAPD_LDAP)
} else if ( strcmp( bi->bi_type, "ldap" ) == 0 ) {
ldapinfo_t *li = (ldapinfo_t *)be->be_private;

View File

@ -437,7 +437,7 @@ monitor_back_register_entry_parent(
"monitor_back_register_entry_parent(base=\"%s\" scope=%s filter=\"%s\"): "
"monitor database not configured.\n",
BER_BVISNULL( base ) ? "" : base->bv_val,
scope == LDAP_SCOPE_BASE ? "base" : ( scope == LDAP_SCOPE_ONELEVEL ? "one" : "subtree" ),
ldap_pvt_scope2str( scope ),
BER_BVISNULL( filter ) ? "" : filter->bv_val );
return -1;
}
@ -752,7 +752,7 @@ monitor_back_register_entry_attrs(
"monitor database not configured.\n",
fname,
BER_BVISNULL( base ) ? "" : base->bv_val,
scope == LDAP_SCOPE_BASE ? "base" : ( scope == LDAP_SCOPE_ONELEVEL ? "one" : "subtree" ),
ldap_pvt_scope2str( scope ),
BER_BVISNULL( filter ) ? "" : filter->bv_val );
Debug( LDAP_DEBUG_ANY, "%s\n", buf, 0, 0 );
@ -942,48 +942,210 @@ monitor_back_register_entry_callback(
*/
int
monitor_back_unregister_entry(
Entry **ep,
monitor_callback_t **cbp )
Entry *target_e )
{
/* TODO */
return 1;
}
monitor_info_t *mi;
int
monitor_back_unregister_entry_parent(
Entry **ep,
monitor_callback_t **cbp,
struct berval *base,
int scope,
struct berval *filter )
{
/* TODO */
return 1;
if ( be_monitor == NULL ) {
Debug( LDAP_DEBUG_ANY,
"monitor_back_unregister_entry(\"%s\"): "
"monitor database not configured.\n",
target_e->e_name.bv_val, 0, 0 );
return -1;
}
mi = ( monitor_info_t * )be_monitor->be_private;
assert( mi != NULL );
if ( monitor_subsys_opened ) {
Entry *e = NULL;
monitor_entry_t *mp = NULL;
monitor_callback_t *cb = NULL;
if ( monitor_cache_remove( mi, &target_e->e_nname, &e ) != 0 ) {
/* entry does not exist */
Debug( LDAP_DEBUG_ANY,
"monitor_back_unregister_entry(\"%s\"): "
"entry removal failed.\n",
target_e->e_name.bv_val, 0, 0 );
return -1;
}
mp = (monitor_entry_t *)e->e_private;
assert( mp != NULL );
for ( cb = mp->mp_cb; cb != NULL; ) {
monitor_callback_t *next = cb->mc_next;
if ( cb->mc_free ) {
(void)cb->mc_free( e, cb->mc_private );
}
ch_free( cb );
cb = next;
}
} else {
/* TODO: remove from limbo */
return 1;
}
return 0;
}
int
monitor_back_unregister_entry_attrs(
struct berval *ndn,
Attribute **ap,
monitor_callback_t **cbp,
struct berval *ndn_in,
Attribute *target_a,
monitor_callback_t *target_cb,
struct berval *base,
int scope,
struct berval *filter )
{
/* TODO */
return 1;
monitor_info_t *mi;
struct berval ndn = BER_BVNULL;
char *fname = ( target_a == NULL ? "callback" : "attrs" );
if ( be_monitor == NULL ) {
char buf[ SLAP_TEXT_BUFLEN ];
snprintf( buf, sizeof( buf ),
"monitor_back_unregister_entry_%s(base=\"%s\" scope=%s filter=\"%s\"): "
"monitor database not configured.\n",
fname,
BER_BVISNULL( base ) ? "" : base->bv_val,
(char *)ldap_pvt_scope2str( scope ),
BER_BVISNULL( filter ) ? "" : filter->bv_val );
Debug( LDAP_DEBUG_ANY, "%s\n", buf, 0, 0 );
return -1;
}
mi = ( monitor_info_t * )be_monitor->be_private;
assert( mi != NULL );
if ( ndn_in != NULL ) {
ndn = *ndn_in;
}
if ( target_a == NULL && target_cb == NULL ) {
/* nothing to do */
return -1;
}
if ( ( ndn_in == NULL || BER_BVISNULL( &ndn ) )
&& BER_BVISNULL( filter ) )
{
/* need a filter */
Debug( LDAP_DEBUG_ANY,
"monitor_back_unregister_entry_%s(\"\"): "
"need a valid filter\n",
fname, 0, 0 );
return -1;
}
if ( monitor_subsys_opened ) {
Entry *e = NULL;
monitor_entry_t *mp = NULL;
int freeit = 0;
if ( BER_BVISNULL( &ndn ) ) {
if ( monitor_filter2ndn( base, scope, filter, &ndn ) ) {
char buf[ SLAP_TEXT_BUFLEN ];
snprintf( buf, sizeof( buf ),
"monitor_back_unregister_entry_%s(\"\"): "
"base=\"%s\" scope=%d filter=\"%s\": "
"unable to find entry\n",
fname,
base->bv_val ? base->bv_val : "\"\"",
scope, filter->bv_val );
/* entry does not exist */
Debug( LDAP_DEBUG_ANY, "%s\n", buf, 0, 0 );
return -1;
}
freeit = 1;
}
if ( monitor_cache_get( mi, &ndn, &e ) != 0 ) {
/* entry does not exist */
Debug( LDAP_DEBUG_ANY,
"monitor_back_unregister_entry(\"%s\"): "
"entry removal failed.\n",
ndn.bv_val, 0, 0 );
return -1;
}
mp = (monitor_entry_t *)e->e_private;
assert( mp != NULL );
if ( target_cb != NULL ) {
monitor_callback_t **cbp;
for ( cbp = &mp->mp_cb; *cbp != NULL; cbp = &(*cbp)->mc_next ) {
if ( *cbp == target_cb ) {
if ( (*cbp)->mc_free ) {
(void)(*cbp)->mc_free( e, (*cbp)->mc_private );
}
*cbp = (*cbp)->mc_next;
ch_free( target_cb );
break;
}
}
}
if ( target_a != NULL ) {
Attribute *a;
for ( a = target_a; a != NULL; a = a->a_next ) {
Modification mod = { 0 };
const char *text;
char textbuf[ SLAP_TEXT_BUFLEN ];
mod.sm_op = LDAP_MOD_DELETE;
mod.sm_desc = a->a_desc;
mod.sm_values = a->a_vals;
mod.sm_nvalues = a->a_nvals;
(void)modify_delete_values( e, &mod, 1,
&text, textbuf, sizeof( textbuf ) );
}
}
if ( freeit ) {
ber_memfree( ndn.bv_val );
}
if ( e ) {
monitor_cache_release( mi, e );
}
} else {
/* TODO: remove from limbo */
return 1;
}
return 0;
}
int
monitor_back_unregister_entry_callback(
struct berval *ndn,
monitor_callback_t **cbp,
monitor_callback_t *cb,
struct berval *base,
int scope,
struct berval *filter )
{
return monitor_back_unregister_entry_attrs( ndn, NULL, cbp,
base, scope, filter );
/* TODO: lookup entry (by ndn, if not NULL, and/or by callback);
* unregister the callback; if a is not null, unregister the
* given attrs. In any case, call cb->cb_free */
return monitor_back_unregister_entry_attrs( ndn,
NULL, cb, base, scope, filter );
}
monitor_subsys_t *

View File

@ -54,6 +54,11 @@ monitor_cache_get LDAP_P((
struct berval *ndn,
Entry **ep ));
extern int
monitor_cache_remove LDAP_P((
monitor_info_t *mi,
struct berval *ndn,
Entry **ep ));
extern int
monitor_cache_dn2entry LDAP_P((
Operation *op,
SlapReply *rs,
@ -175,27 +180,19 @@ monitor_back_register_entry_callback LDAP_P((
struct berval *filter ));
extern int
monitor_back_unregister_entry LDAP_P((
Entry **ep,
monitor_callback_t **cbp ));
extern int
monitor_back_unregister_entry_parent LDAP_P((
Entry **ep,
monitor_callback_t **cbp,
struct berval *base,
int scope,
struct berval *filter ));
Entry *e ));
extern int
monitor_back_unregister_entry_attrs LDAP_P((
struct berval *ndn,
Attribute **ap,
monitor_callback_t **cbp,
Attribute *a,
monitor_callback_t *cb,
struct berval *base,
int scope,
struct berval *filter ));
extern int
monitor_back_unregister_entry_callback LDAP_P((
struct berval *ndn,
monitor_callback_t **cbp,
monitor_callback_t *cb,
struct berval *base,
int scope,
struct berval *filter ));