mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-06 10:46:21 +08:00
implement support for unregistering registered stuff
This commit is contained in:
parent
829685e218
commit
127ac65c44
@ -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 );
|
||||
|
@ -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;
|
||||
|
@ -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 *
|
||||
|
@ -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 ));
|
||||
|
Loading…
Reference in New Issue
Block a user