]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#9620 Fix deadlocks between searches and register_entry
authorOndřej Kuzník <okuznik@symas.com>
Thu, 23 Sep 2021 09:31:03 +0000 (10:31 +0100)
committerOndřej Kuzník <okuznik@symas.com>
Tue, 5 Oct 2021 10:05:25 +0000 (11:05 +0100)
The cache is again protected by a simple mutex and mp_children/mp_next
is protected by mp_mutex. Each monitor_send_children is called holding
the corresponding mp_mutex meaning the whole path from search base to
the current entry is off limits - cn=monitor searches cannot run in
parallel right now.

15 files changed:
servers/slapd/back-monitor/back-monitor.h
servers/slapd/back-monitor/backend.c
servers/slapd/back-monitor/cache.c
servers/slapd/back-monitor/conn.c
servers/slapd/back-monitor/database.c
servers/slapd/back-monitor/init.c
servers/slapd/back-monitor/listener.c
servers/slapd/back-monitor/operation.c
servers/slapd/back-monitor/overlay.c
servers/slapd/back-monitor/proto-back-monitor.h
servers/slapd/back-monitor/rww.c
servers/slapd/back-monitor/search.c
servers/slapd/back-monitor/sent.c
servers/slapd/back-monitor/thread.c
servers/slapd/back-monitor/time.c

index b7126d025bec77a6bb5678f80ce18f4c17237b21..3b3a3d77a727a7ac17cba91c44b26cd4db097032 100644 (file)
@@ -56,6 +56,7 @@ typedef struct monitor_entry_t {
        ldap_pvt_thread_mutex_t mp_mutex;       /* entry mutex */
        Entry                   *mp_next;       /* pointer to next sibling */
        Entry                   *mp_children;   /* pointer to first child */
+       Entry                   *mp_last;       /* pointer to last child */
        struct monitor_subsys_t *mp_info;       /* subsystem info */
 #define mp_type                mp_info->mss_type
        unsigned long           mp_flags;       /* flags */
@@ -81,9 +82,13 @@ typedef struct monitor_info_t {
 
        /*
         * Internal data
+        *
+        * Lock order:
+        * - cache first, then entry
+        * - DIT in preorder DFS
         */
        Avlnode                 *mi_cache;
-       ldap_pvt_thread_rdwr_t  mi_cache_rwlock;
+       ldap_pvt_thread_mutex_t mi_cache_lock;
 
        /*
         * Config parameters
index 03f0d3624a70fe4a007e0cf420e337dc004089d8..8e48bd2d52756a6a55c4dc86eddb8fb7f5af2653 100644 (file)
@@ -38,7 +38,7 @@ monitor_subsys_backend_init(
 )
 {
        monitor_info_t          *mi;
-       Entry                   *e_backend, **ep;
+       Entry                   *e_backend;
        int                     i;
        monitor_entry_t         *mp;
        monitor_subsys_t        *ms_database;
@@ -64,10 +64,6 @@ monitor_subsys_backend_init(
                return( -1 );
        }
 
-       mp = ( monitor_entry_t * )e_backend->e_private;
-       mp->mp_children = NULL;
-       ep = &mp->mp_children;
-
        i = -1;
        LDAP_STAILQ_FOREACH( bi, &backendInfo, bi_next ) {
                char            buf[ BACKMONITOR_BUFSIZE ];
@@ -139,7 +135,7 @@ monitor_subsys_backend_init(
                mp->mp_info = ms;
                mp->mp_flags = ms->mss_flags | MONITOR_F_SUB;
 
-               if ( monitor_cache_add( mi, e ) ) {
+               if ( monitor_cache_add( mi, e, e_backend ) ) {
                        Debug( LDAP_DEBUG_ANY,
                                "monitor_subsys_backend_init: "
                                "unable to add entry \"cn=Backend %d,%s\"\n",
@@ -147,9 +143,6 @@ monitor_subsys_backend_init(
                                        ms->mss_ndn.bv_val );
                        return( -1 );
                }
-
-               *ep = e;
-               ep = &mp->mp_next;
        }
        
        monitor_cache_release( mi, e_backend );
index 4815756709e7d350aa939f72cd8915701e19e329..3d3817495a0e096de1dc21fee96d66d914635c12 100644 (file)
@@ -79,22 +79,74 @@ monitor_cache_dup(
 int
 monitor_cache_add(
        monitor_info_t  *mi,
-       Entry           *e )
+       Entry           *e,
+       Entry           *parent )
 {
-       monitor_cache_t *mc;
-       int             rc;
+       monitor_cache_t tmp_mc, *mc, *pmc = NULL;
+       Entry **ep = NULL, *prev = NULL;
+       int             rc = -1;
 
        assert( mi != NULL );
        assert( e != NULL );
 
+       dnParent( &e->e_nname, &tmp_mc.mc_ndn );
+
        mc = ( monitor_cache_t * )ch_malloc( sizeof( monitor_cache_t ) );
        mc->mc_ndn = e->e_nname;
        mc->mc_e = e;
-       ldap_pvt_thread_rdwr_wlock( &mi->mi_cache_rwlock );
-       rc = ldap_avl_insert( &mi->mi_cache, ( caddr_t )mc,
+
+       if ( parent ) {
+               /* Shortcut, but follow lock order as a fallback */
+               if ( ldap_pvt_thread_mutex_trylock( &mi->mi_cache_lock ) ) {
+                       monitor_cache_release( mi, parent );
+                       ldap_pvt_thread_mutex_lock( &mi->mi_cache_lock );
+                       monitor_cache_lock( parent );
+               }
+       } else {
+               ldap_pvt_thread_mutex_lock( &mi->mi_cache_lock );
+       }
+
+       /* Allow database root be added */
+       if ( parent == NULL && mi->mi_cache != NULL ) {
+               pmc = ldap_avl_find( mi->mi_cache, &tmp_mc, monitor_cache_cmp );
+               if ( pmc == NULL ) {
+                       goto done;
+               }
+               parent = pmc->mc_e;
+               monitor_cache_lock( parent );
+       }
+
+       rc = ldap_avl_insert( &mi->mi_cache, mc,
                        monitor_cache_cmp, monitor_cache_dup );
-       ldap_pvt_thread_rdwr_wunlock( &mi->mi_cache_rwlock );
+       if ( rc != LDAP_SUCCESS ) {
+               goto done;
+       }
+
+       if ( parent != NULL ) {
+               monitor_entry_t *mp = parent->e_private;
+
+               if ( mp->mp_children ) {
+                       monitor_entry_t *tail;
+
+                       monitor_cache_lock( mp->mp_last );
+                       tail = mp->mp_last->e_private;
+                       tail->mp_next = e;
+                       monitor_cache_release( mi, mp->mp_last );
+                       mp->mp_last = e;
+               } else {
+                       mp->mp_children = mp->mp_last = e;
+               }
+       }
+
+done:
+       if ( pmc != NULL ) {
+               monitor_cache_release( mi, parent );
+       }
+       ldap_pvt_thread_mutex_unlock( &mi->mi_cache_lock );
 
+       if ( rc != LDAP_SUCCESS ) {
+               ch_free( mc );
+       }
        return rc;
 }
 
@@ -151,22 +203,18 @@ monitor_cache_get(
        *ep = NULL;
 
        tmp_mc.mc_ndn = *ndn;
-retry:;
-       ldap_pvt_thread_rdwr_rlock( &mi->mi_cache_rwlock );
+
+       ldap_pvt_thread_mutex_lock( &mi->mi_cache_lock );
        mc = ( monitor_cache_t * )ldap_avl_find( mi->mi_cache,
                        ( caddr_t )&tmp_mc, monitor_cache_cmp );
 
        if ( mc != NULL ) {
                /* entry is returned with mutex locked */
-               if ( monitor_cache_trylock( mc->mc_e ) ) {
-                       ldap_pvt_thread_rdwr_runlock( &mi->mi_cache_rwlock );
-                       ldap_pvt_thread_yield();
-                       goto retry;
-               }
+               monitor_cache_lock( mc->mc_e );
                *ep = mc->mc_e;
        }
 
-       ldap_pvt_thread_rdwr_runlock( &mi->mi_cache_rwlock );
+       ldap_pvt_thread_mutex_unlock( &mi->mi_cache_lock );
 
        return ( *ep == NULL ? -1 : 0 );
 }
@@ -193,7 +241,7 @@ monitor_cache_remove(
        dnParent( ndn, &pndn );
 
 retry:;
-       ldap_pvt_thread_rdwr_wlock( &mi->mi_cache_rwlock );
+       ldap_pvt_thread_mutex_lock( &mi->mi_cache_lock );
 
        tmp_mc.mc_ndn = *ndn;
        mc = ( monitor_cache_t * )ldap_avl_find( mi->mi_cache,
@@ -202,35 +250,38 @@ retry:;
        if ( mc != NULL ) {
                monitor_cache_t *pmc;
 
-               if ( monitor_cache_trylock( mc->mc_e ) ) {
-                       ldap_pvt_thread_rdwr_wunlock( &mi->mi_cache_rwlock );
-                       goto retry;
-               }
-
                tmp_mc.mc_ndn = pndn;
                pmc = ( monitor_cache_t * )ldap_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;
+                       Entry           **entryp, *prev = NULL;
 
-                       if ( monitor_cache_trylock( pmc->mc_e ) ) {
-                               monitor_cache_release( mi, mc->mc_e );
-                               ldap_pvt_thread_rdwr_wunlock( &mi->mi_cache_rwlock );
-                               goto retry;
-                       }
+                       monitor_cache_lock( pmc->mc_e );
 
                        for ( entryp = &pmp->mp_children; *entryp != NULL;  ) {
                                monitor_entry_t *next = (monitor_entry_t *)(*entryp)->e_private;
+
+                               monitor_cache_lock( *entryp );
                                if ( next == mp ) {
+                                       if ( mc->mc_e == pmp->mp_last ) {
+                                               pmp->mp_last = prev;
+                                       }
                                        *entryp = next->mp_next;
                                        entryp = NULL;
                                        break;
                                }
 
+                               if ( prev != NULL ) {
+                                       monitor_cache_release( mi, prev );
+                               }
+                               prev = *entryp;
                                entryp = &next->mp_next;
                        }
+                       if ( prev ) {
+                               monitor_cache_release( mi, prev );
+                       }
 
                        if ( entryp != NULL ) {
                                Debug( LDAP_DEBUG_ANY,
@@ -263,6 +314,7 @@ retry:;
                                ldap_pvt_thread_mutex_destroy( &mp->mp_mutex );
                                mp->mp_next = NULL;
                                mp->mp_children = NULL;
+                               mp->mp_last = NULL;
                        }
 
                }
@@ -272,7 +324,7 @@ retry:;
                }
        }
 
-       ldap_pvt_thread_rdwr_wunlock( &mi->mi_cache_rwlock );
+       ldap_pvt_thread_mutex_unlock( &mi->mi_cache_lock );
 
        return ( *ep == NULL ? -1 : 0 );
 }
index f586e94deb8d696b30066ef1146b181737f96249..6e0d40e890cf188295f462806a5c794bee74f778 100644 (file)
@@ -48,7 +48,7 @@ monitor_subsys_conn_init(
        monitor_subsys_t        *ms )
 {
        monitor_info_t  *mi;
-       Entry           *e, **ep, *e_conn;
+       Entry           *e, *e_conn;
        monitor_entry_t *mp;
        char            buf[ BACKMONITOR_BUFSIZE ];
        struct berval   bv;
@@ -69,8 +69,6 @@ monitor_subsys_conn_init(
        }
 
        mp = ( monitor_entry_t * )e_conn->e_private;
-       mp->mp_children = NULL;
-       ep = &mp->mp_children;
 
        /*
         * Max file descriptors
@@ -106,7 +104,7 @@ monitor_subsys_conn_init(
                | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
        mp->mp_flags &= ~MONITOR_F_VOLATILE_CH;
 
-       if ( monitor_cache_add( mi, e ) ) {
+       if ( monitor_cache_add( mi, e, e_conn ) ) {
                Debug( LDAP_DEBUG_ANY,
                        "monitor_subsys_conn_init: "
                        "unable to add entry \"cn=Total,%s\"\n",
@@ -114,9 +112,6 @@ monitor_subsys_conn_init(
                return( -1 );
        }
 
-       *ep = e;
-       ep = &mp->mp_next;
-       
        /*
         * Total conns
         */
@@ -145,7 +140,7 @@ monitor_subsys_conn_init(
                | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
        mp->mp_flags &= ~MONITOR_F_VOLATILE_CH;
 
-       if ( monitor_cache_add( mi, e ) ) {
+       if ( monitor_cache_add( mi, e, e_conn ) ) {
                Debug( LDAP_DEBUG_ANY,
                        "monitor_subsys_conn_init: "
                        "unable to add entry \"cn=Total,%s\"\n",
@@ -153,9 +148,6 @@ monitor_subsys_conn_init(
                return( -1 );
        }
 
-       *ep = e;
-       ep = &mp->mp_next;
-       
        /*
         * Current conns
         */
@@ -184,7 +176,7 @@ monitor_subsys_conn_init(
                | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
        mp->mp_flags &= ~MONITOR_F_VOLATILE_CH;
 
-       if ( monitor_cache_add( mi, e ) ) {
+       if ( monitor_cache_add( mi, e, e_conn ) ) {
                Debug( LDAP_DEBUG_ANY,
                        "monitor_subsys_conn_init: "
                        "unable to add entry \"cn=Current,%s\"\n",
@@ -192,9 +184,6 @@ monitor_subsys_conn_init(
                return( -1 );
        }
        
-       *ep = e;
-       ep = &mp->mp_next;
-
        monitor_cache_release( mi, e_conn );
 
        return( 0 );
index 611d9f50461df13cbe6751e5b86247bba6924fad..5737d87441812afe6a556dee54fa7550643b4166 100644 (file)
@@ -179,7 +179,7 @@ monitor_subsys_overlay_init_one(
        mp_overlay->mp_info = ms;
        mp_overlay->mp_flags = ms->mss_flags | MONITOR_F_SUB;
        
-       if ( monitor_cache_add( mi, e_overlay ) ) {
+       if ( monitor_cache_add( mi, e_overlay, e_database ) ) {
                Debug( LDAP_DEBUG_ANY,
                        "monitor_subsys_overlay_init_one: "
                        "unable to add entry "
@@ -189,8 +189,6 @@ monitor_subsys_overlay_init_one(
        }
 
        *ep_overlay = e_overlay;
-       ep_overlay = &mp_overlay->mp_next;
-
        return 0;
 }
 
@@ -203,7 +201,8 @@ monitor_subsys_database_init_one(
        monitor_subsys_t        *ms_overlay,
        struct berval           *rdn,
        Entry                   *e_database,
-       Entry                   ***epp )
+       struct slap_overinst    *overlay,
+       Entry                   **ep )
 {
        char                    buf[ BACKMONITOR_BUFSIZE ];
        int                     j;
@@ -348,7 +347,7 @@ monitor_subsys_database_init_one(
                | MONITOR_F_SUB;
        mp->mp_private = be;
 
-       if ( monitor_cache_add( mi, e ) ) {
+       if ( monitor_cache_add( mi, e, e_database ) ) {
                Debug( LDAP_DEBUG_ANY,
                        "monitor_subsys_database_init_one: "
                        "unable to add entry \"%s,%s\"\n",
@@ -361,17 +360,20 @@ monitor_subsys_database_init_one(
 #endif /* defined(LDAP_SLAPI) */
 
        if ( oi != NULL ) {
-               Entry           **ep_overlay = &mp->mp_children;
+               Entry           *e_overlay;
                slap_overinst   *on = oi->oi_list;
 
                for ( ; on; on = on->on_next ) {
                        monitor_subsys_overlay_init_one( mi, be,
-                               ms, ms_overlay, on, e, ep_overlay );
+                               ms, ms_overlay, on, e, &e_overlay );
+                       if ( overlay == on ) {
+                               *ep = e_overlay;
+                       }
                }
        }
-
-       **epp = e;
-       *epp = &mp->mp_next;
+       if ( overlay == NULL ) {
+               *ep = e;
+       }
 
        return 0;
 }
@@ -383,7 +385,7 @@ monitor_back_register_database_and_overlay(
        struct berval           *ndn_out )
 {
        monitor_info_t          *mi;
-       Entry                   *e_database, **ep;
+       Entry                   *e_database, *e = NULL;
        int                     i, rc;
        monitor_entry_t         *mp;
        monitor_subsys_t        *ms_backend,
@@ -443,16 +445,17 @@ monitor_back_register_database_and_overlay(
                return( -1 );
        }
 
+       /* FIXME: It's only safe since we're paused */
        mp = ( monitor_entry_t * )e_database->e_private;
-       for ( i = -1, ep = &mp->mp_children; *ep; i++ ) {
-               mp = ( monitor_entry_t * )(*ep)->e_private;
+       for ( i = -1, e = mp->mp_children; e; i++ ) {
+               mp = ( monitor_entry_t * )e->e_private;
 
                assert( mp != NULL );
                if ( mp->mp_private == be->bd_self ) {
                        rc = 0;
                        goto done;
                }
-               ep = &mp->mp_next;
+               e = mp->mp_next;
        }
 
        bv.bv_val = buf;
@@ -463,40 +466,15 @@ monitor_back_register_database_and_overlay(
        }
        
        rc = monitor_subsys_database_init_one( mi, be,
-               ms_database, ms_backend, ms_overlay, &bv, e_database, &ep );
+               ms_database, ms_backend, ms_overlay, &bv, e_database, on, &e );
        if ( rc != 0 ) {
                goto done;
        }
-       /* database_init_one advanced ep past where we want.
-        * But it stored the entry we want in mp->mp_next.
-        */
-       ep = &mp->mp_next;
 
 done:;
        monitor_cache_release( mi, e_database );
-       if ( rc == 0 && ndn_out && ep && *ep ) {
-               if ( on ) {
-                       Entry *e_ov;
-                       struct berval ov_type;
-
-                       ber_str2bv( on->on_bi.bi_type, 0, 0, &ov_type );
-
-                       mp = ( monitor_entry_t * ) (*ep)->e_private;
-                       for ( e_ov = mp->mp_children; e_ov; ) {
-                               Attribute *a = attr_find( e_ov->e_attrs, mi->mi_ad_monitoredInfo );
-
-                               if ( a != NULL && bvmatch( &a->a_nvals[ 0 ], &ov_type ) ) {
-                                       *ndn_out = e_ov->e_nname;
-                                       break;
-                               }
-
-                               mp = ( monitor_entry_t * ) e_ov->e_private;
-                               e_ov = mp->mp_next;
-                       }
-                       
-               } else {
-                       *ndn_out = (*ep)->e_nname;
-               }
+       if ( rc == 0 && ndn_out && e ) {
+               *ndn_out = e->e_nname;
        }
 
        return rc;
@@ -525,9 +503,8 @@ monitor_subsys_database_init(
        monitor_subsys_t        *ms )
 {
        monitor_info_t          *mi;
-       Entry                   *e_database, **ep;
+       Entry                   *e_database, *e;
        int                     i, rc;
-       monitor_entry_t         *mp;
        monitor_subsys_t        *ms_backend,
                                *ms_overlay;
        struct berval           bv;
@@ -569,13 +546,9 @@ monitor_subsys_database_init(
        (void)init_readOnly( mi, e_database, frontendDB->be_restrictops );
        (void)init_restrictedOperation( mi, e_database, frontendDB->be_restrictops );
 
-       mp = ( monitor_entry_t * )e_database->e_private;
-       mp->mp_children = NULL;
-       ep = &mp->mp_children;
-
        BER_BVSTR( &bv, "cn=Frontend" );
        rc = monitor_subsys_database_init_one( mi, frontendDB,
-               ms, ms_backend, ms_overlay, &bv, e_database, &ep );
+               ms, ms_backend, ms_overlay, &bv, e_database, NULL, &e );
        if ( rc != 0 ) {
                return rc;
        }
@@ -591,7 +564,7 @@ monitor_subsys_database_init(
                }
                
                rc = monitor_subsys_database_init_one( mi, be,
-                       ms, ms_backend, ms_overlay, &bv, e_database, &ep );
+                       ms, ms_backend, ms_overlay, &bv, e_database, NULL, &e );
                if ( rc != 0 ) {
                        return rc;
                }
index 52ec170238c1600aaebb5ccce0db0ef40adbd3bf..68ac915e80ecf917059511eebbf4fade26b27c5d 100644 (file)
@@ -479,9 +479,7 @@ monitor_back_register_entry(
        assert( e->e_private == NULL );
        
        if ( monitor_subsys_is_opened() ) {
-               Entry           *e_parent = NULL,
-                               *e_new = NULL,
-                               **ep = NULL;
+               Entry           *e_parent = NULL, *e_new = NULL;
                struct berval   pdn = BER_BVNULL;
                monitor_entry_t *mp = NULL,
                                *mp_parent = NULL;
@@ -550,14 +548,7 @@ monitor_back_register_entry(
                }
                mp->mp_cb = cb;
 
-               ep = &mp_parent->mp_children;
-               for ( ; *ep; ) {
-                       mp_parent = ( monitor_entry_t * )(*ep)->e_private;
-                       ep = &mp_parent->mp_next;
-               }
-               *ep = e_new;
-
-               if ( monitor_cache_add( mi, e_new ) ) {
+               if ( monitor_cache_add( mi, e_new, e_parent ) ) {
                        Debug( LDAP_DEBUG_ANY,
                                "monitor_back_register_entry(\"%s\"): "
                                "unable to add entry\n",
@@ -656,9 +647,7 @@ monitor_back_register_entry_parent(
        }
 
        if ( monitor_subsys_is_opened() ) {
-               Entry           *e_parent = NULL,
-                               *e_new = NULL,
-                               **ep = NULL;
+               Entry           *e_parent = NULL, *e_new = NULL;
                struct berval   e_name = BER_BVNULL,
                                e_nname = BER_BVNULL;
                monitor_entry_t *mp = NULL,
@@ -750,14 +739,7 @@ monitor_back_register_entry_parent(
                }
                mp->mp_cb = cb;
 
-               ep = &mp_parent->mp_children;
-               for ( ; *ep; ) {
-                       mp_parent = ( monitor_entry_t * )(*ep)->e_private;
-                       ep = &mp_parent->mp_next;
-               }
-               *ep = e_new;
-
-               if ( monitor_cache_add( mi, e_new ) ) {
+               if ( monitor_cache_add( mi, e_new, e_parent ) ) {
                        Debug( LDAP_DEBUG_ANY,
                                "monitor_back_register_entry(\"%s\"): "
                                "unable to add entry\n",
@@ -2162,7 +2144,7 @@ monitor_back_db_init(
 
        /* NOTE: only one monitor database is allowed,
         * so we use static storage */
-       ldap_pvt_thread_rdwr_init( &monitor_info.mi_cache_rwlock );
+       ldap_pvt_thread_mutex_init( &monitor_info.mi_cache_lock );
 
        be->be_private = &monitor_info;
 
@@ -2229,7 +2211,7 @@ monitor_back_db_open(
 {
        monitor_info_t          *mi = (monitor_info_t *)be->be_private;
        struct monitor_subsys_t **ms;
-       Entry                   *e, **ep, *root;
+       Entry                   *e, *root;
        monitor_entry_t         *mp;
        int                     i;
        struct berval           bv, rdn = BER_BVC(SLAPD_MONITOR_DN);
@@ -2318,9 +2300,8 @@ monitor_back_db_open(
                return -1;
        }
        e->e_private = ( void * )mp;
-       ep = &mp->mp_children;
 
-       if ( monitor_cache_add( mi, e ) ) {
+       if ( monitor_cache_add( mi, e, NULL ) ) {
                Debug( LDAP_DEBUG_ANY,
                        "unable to add entry \"%s\" to cache\n",
                        SLAPD_MONITOR_DN );
@@ -2375,15 +2356,12 @@ monitor_back_db_open(
                mp->mp_info = monitor_subsys[ i ];
                mp->mp_flags = monitor_subsys[ i ]->mss_flags;
 
-               if ( monitor_cache_add( mi, e ) ) {
+               if ( monitor_cache_add( mi, e, root ) ) {
                        Debug( LDAP_DEBUG_ANY,
                                "unable to add entry \"%s\" to cache\n",
                                monitor_subsys[ i ]->mss_dn.bv_val );
                        return -1;
                }
-
-               *ep = e;
-               ep = &mp->mp_next;
        }
 
        assert( be != NULL );
@@ -2565,7 +2543,7 @@ monitor_back_db_destroy(
                }
        }
        
-       ldap_pvt_thread_rdwr_destroy( &monitor_info.mi_cache_rwlock );
+       ldap_pvt_thread_mutex_destroy( &monitor_info.mi_cache_lock );
 
        be->be_private = NULL;
 
index 84b94e3387251b27603129cb351d8151cdbfff74..a0afb8c2ad8bc51a5567eb6394b07c87037fc588 100644 (file)
@@ -34,7 +34,7 @@ monitor_subsys_listener_init(
 )
 {
        monitor_info_t  *mi;
-       Entry           *e_listener, **ep;
+       Entry           *e_listener;
        int             i;
        monitor_entry_t *mp;
        Listener        **l;
@@ -62,10 +62,6 @@ monitor_subsys_listener_init(
                return( -1 );
        }
 
-       mp = ( monitor_entry_t * )e_listener->e_private;
-       mp->mp_children = NULL;
-       ep = &mp->mp_children;
-
        for ( i = 0; l[ i ]; i++ ) {
                char            buf[ BACKMONITOR_BUFSIZE ];
                Entry           *e;
@@ -119,16 +115,13 @@ monitor_subsys_listener_init(
                mp->mp_flags = ms->mss_flags
                        | MONITOR_F_SUB;
 
-               if ( monitor_cache_add( mi, e ) ) {
+               if ( monitor_cache_add( mi, e, e_listener ) ) {
                        Debug( LDAP_DEBUG_ANY,
                                "monitor_subsys_listener_init: "
                                "unable to add entry \"cn=Listener %d,%s\"\n",
                                i, ms->mss_ndn.bv_val );
                        return( -1 );
                }
-
-               *ep = e;
-               ep = &mp->mp_next;
        }
        
        monitor_cache_release( mi, e_listener );
index e245683cadf70014be22d91e26552172a9fcecf9..b22cc01e36f9e02ca01f307e0ad04e89a94ccac4 100644 (file)
@@ -63,7 +63,7 @@ monitor_subsys_ops_init(
 {
        monitor_info_t  *mi;
        
-       Entry           *e_op, **ep;
+       Entry           *e_op;
        monitor_entry_t *mp;
        int             i;
        struct berval   bv_zero = BER_BVC( "0" );
@@ -88,10 +88,6 @@ monitor_subsys_ops_init(
        attr_merge_one( e_op, mi->mi_ad_monitorOpInitiated, &bv_zero, NULL );
        attr_merge_one( e_op, mi->mi_ad_monitorOpCompleted, &bv_zero, NULL );
 
-       mp = ( monitor_entry_t * )e_op->e_private;
-       mp->mp_children = NULL;
-       ep = &mp->mp_children;
-
        for ( i = 0; i < SLAP_OP_LAST; i++ ) {
                struct berval   rdn;
                Entry           *e;
@@ -129,7 +125,7 @@ monitor_subsys_ops_init(
                mp->mp_flags = ms->mss_flags \
                        | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
 
-               if ( monitor_cache_add( mi, e ) ) {
+               if ( monitor_cache_add( mi, e, e_op ) ) {
                        Debug( LDAP_DEBUG_ANY,
                                "monitor_subsys_ops_init: "
                                "unable to add entry \"%s,%s\"\n",
@@ -137,9 +133,6 @@ monitor_subsys_ops_init(
                                ms->mss_ndn.bv_val );
                        return( -1 );
                }
-
-               *ep = e;
-               ep = &mp->mp_next;
        }
 
        monitor_cache_release( mi, e_op );
index 7026ab4a40df3afa820b5cb8613ab939bf1c85f2..f72da015c717420c02277a4da47cd2fbd5c37e24 100644 (file)
@@ -37,7 +37,7 @@ monitor_subsys_overlay_init(
 )
 {
        monitor_info_t          *mi;
-       Entry                   *e_overlay, **ep;
+       Entry                   *e_overlay;
        int                     i;
        monitor_entry_t         *mp;
        slap_overinst           *on;
@@ -63,10 +63,6 @@ monitor_subsys_overlay_init(
                return( -1 );
        }
 
-       mp = ( monitor_entry_t * )e_overlay->e_private;
-       mp->mp_children = NULL;
-       ep = &mp->mp_children;
-
        for ( on = overlay_next( NULL ), i = 0; on; on = overlay_next( on ), i++ ) {
                char            buf[ BACKMONITOR_BUFSIZE ];
                struct berval   bv;
@@ -121,16 +117,13 @@ monitor_subsys_overlay_init(
                mp->mp_flags = ms->mss_flags
                        | MONITOR_F_SUB;
 
-               if ( monitor_cache_add( mi, e ) ) {
+               if ( monitor_cache_add( mi, e, e_overlay ) ) {
                        Debug( LDAP_DEBUG_ANY,
                                "monitor_subsys_overlay_init: "
                                "unable to add entry \"cn=Overlay %d,%s\"\n",
                                i, ms->mss_ndn.bv_val );
                        return( -1 );
                }
-
-               *ep = e;
-               ep = &mp->mp_next;
        }
        
        monitor_cache_release( mi, e_overlay );
index e7c73e72e86caccc43b94833e94833138d4a4a4a..864360bd6f7f6e3088e090afde2edff104622540 100644 (file)
@@ -47,7 +47,8 @@ monitor_cache_dup LDAP_P((
 extern int
 monitor_cache_add LDAP_P((
        monitor_info_t          *mi,
-       Entry                   *e ));
+       Entry                   *e,
+       Entry                   *parent ));
 extern int
 monitor_cache_get LDAP_P((
        monitor_info_t          *mi,
index 85f0a2b81fec800fead2427a5418172686231b95..eb64af1abe22f67fbe778dc1857536368c644fac 100644 (file)
@@ -62,7 +62,7 @@ monitor_subsys_rww_init(
 {
        monitor_info_t  *mi;
        
-       Entry           **ep, *e_conn;
+       Entry           *e_conn;
        monitor_entry_t *mp;
        int                     i;
 
@@ -81,10 +81,6 @@ monitor_subsys_rww_init(
                return( -1 );
        }
 
-       mp = ( monitor_entry_t * )e_conn->e_private;
-       mp->mp_children = NULL;
-       ep = &mp->mp_children;
-
        for ( i = 0; i < MONITOR_RWW_LAST; i++ ) {
                struct berval           nrdn, bv;
                Entry                   *e;
@@ -115,7 +111,7 @@ monitor_subsys_rww_init(
                mp->mp_flags = ms->mss_flags \
                        | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
 
-               if ( monitor_cache_add( mi, e ) ) {
+               if ( monitor_cache_add( mi, e, e_conn ) ) {
                        Debug( LDAP_DEBUG_ANY,
                                "monitor_subsys_rww_init: "
                                "unable to add entry \"%s,%s\"\n",
@@ -123,9 +119,6 @@ monitor_subsys_rww_init(
                                ms->mss_ndn.bv_val );
                        return( -1 );
                }
-       
-               *ep = e;
-               ep = &mp->mp_next;
        }
 
        monitor_cache_release( mi, e_conn );
index 49702788f8bf4d593775b21ca1f81b8a79dcf047..8bf758f68db54958dd843d16944fcb1e65a949d5 100644 (file)
@@ -120,7 +120,6 @@ monitor_send_children(
                rc = test_filter( op, e, op->oq_search.rs_filter );
                if ( rc == LDAP_COMPARE_TRUE ) {
                        rs->sr_entry = e;
-                       rs->sr_flags = REP_ENTRY_MUSTRELEASE;
                        rc = send_search_entry( op, rs );
                        if ( rc ) {
                                for ( e = sub_ch; e != NULL; e = sub_nv ) {
@@ -131,7 +130,8 @@ monitor_send_children(
                                }
                                goto freeout;
                        }
-               } else {
+               }
+               if ( sub_nv == NULL ) {
                        monitor_cache_release( mi, e );
                }
 
@@ -139,6 +139,7 @@ monitor_send_children(
                        rc = monitor_send_children( op, rs, sub_nv, sub_ch, sub );
                        if ( rc ) {
 freeout:
+                               monitor_cache_release( mi, e );
                                if ( nonvolatile == 0 ) {
                                        for ( ; e_tmp != NULL; ) {
                                                mp = ( monitor_entry_t * )e_tmp->e_private;
@@ -156,6 +157,9 @@ freeout:
                                return( rc );
                        }
                }
+               if ( sub_nv != NULL ) {
+                       monitor_cache_release( mi, e );
+               }
        }
        
        return LDAP_SUCCESS;
@@ -215,9 +219,6 @@ monitor_back_search( Operation *op, SlapReply *rs )
                return rs->sr_err;
        }
 
-       /* Freeze the cache while we're using it */
-       ldap_pvt_thread_rdwr_rlock( &mi->mi_cache_rwlock );
-
        rs->sr_attrs = op->oq_search.rs_attrs;
        switch ( op->oq_search.rs_scope ) {
        case LDAP_SCOPE_BASE:
@@ -237,9 +238,9 @@ monitor_back_search( Operation *op, SlapReply *rs )
        case LDAP_SCOPE_ONELEVEL:
        case LDAP_SCOPE_SUBORDINATE:
                monitor_find_children( op, rs, e, &e_nv, &e_ch );
-               monitor_cache_release( mi, e );
                rc = monitor_send_children( op, rs, e_nv, e_ch,
                        op->oq_search.rs_scope == LDAP_SCOPE_SUBORDINATE );
+               monitor_cache_release( mi, e );
                break;
 
        case LDAP_SCOPE_SUBTREE:
@@ -248,14 +249,12 @@ monitor_back_search( Operation *op, SlapReply *rs )
                rc = test_filter( op, e, op->oq_search.rs_filter );
                if ( rc == LDAP_COMPARE_TRUE ) {
                        rs->sr_entry = e;
-                       rs->sr_flags = REP_ENTRY_MUSTRELEASE;
                        send_search_entry( op, rs );
                        rs->sr_entry = NULL;
-               } else {
-                       monitor_cache_release( mi, e );
                }
 
                rc = monitor_send_children( op, rs, e_nv, e_ch, 1 );
+               monitor_cache_release( mi, e );
                break;
 
        default:
@@ -263,8 +262,6 @@ monitor_back_search( Operation *op, SlapReply *rs )
                monitor_cache_release( mi, e );
        }
 
-       ldap_pvt_thread_rdwr_runlock( &mi->mi_cache_rwlock );
-
        rs->sr_attrs = NULL;
        rs->sr_err = rc;
        if ( rs->sr_err != SLAPD_ABANDON ) {
index bfdcc0fed16f15dd7815532be25cb85346f2e4f7..1c3d7b2ff5893e801e06e823e9d544daebe0bf6e 100644 (file)
@@ -65,7 +65,7 @@ monitor_subsys_sent_init(
 {
        monitor_info_t  *mi;
        
-       Entry           **ep, *e_sent;
+       Entry           *e_sent;
        monitor_entry_t *mp;
        int                     i;
 
@@ -84,10 +84,6 @@ monitor_subsys_sent_init(
                return( -1 );
        }
 
-       mp = ( monitor_entry_t * )e_sent->e_private;
-       mp->mp_children = NULL;
-       ep = &mp->mp_children;
-
        for ( i = 0; i < MONITOR_SENT_LAST; i++ ) {
                struct berval           nrdn, bv;
                Entry                   *e;
@@ -121,7 +117,7 @@ monitor_subsys_sent_init(
                mp->mp_flags = ms->mss_flags \
                        | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
 
-               if ( monitor_cache_add( mi, e ) ) {
+               if ( monitor_cache_add( mi, e, e_sent ) ) {
                        Debug( LDAP_DEBUG_ANY,
                                "monitor_subsys_sent_init: "
                                "unable to add entry \"%s,%s\"\n",
@@ -129,9 +125,6 @@ monitor_subsys_sent_init(
                                ms->mss_ndn.bv_val );
                        return( -1 );
                }
-       
-               *ep = e;
-               ep = &mp->mp_next;
        }
 
        monitor_cache_release( mi, e_sent );
index 8e517d6b09806706437602e159f37028a38faece..ff70a997e193f09b47b3763a85c2481fd43b5fc2 100644 (file)
@@ -106,7 +106,7 @@ monitor_subsys_thread_init(
 {
        monitor_info_t  *mi;
        monitor_entry_t *mp;
-       Entry           *e, **ep, *e_thread;
+       Entry           *e, *e_thread;
        int             i;
 
        ms->mss_update = monitor_subsys_thread_update;
@@ -120,10 +120,6 @@ monitor_subsys_thread_init(
                return( -1 );
        }
 
-       mp = ( monitor_entry_t * )e_thread->e_private;
-       mp->mp_children = NULL;
-       ep = &mp->mp_children;
-
        for ( i = 0; !BER_BVISNULL( &mt[ i ].rdn ); i++ ) {
                static char     buf[ BACKMONITOR_BUFSIZE ];
                int             count = -1;
@@ -192,7 +188,7 @@ monitor_subsys_thread_init(
                mp->mp_flags = ms->mss_flags \
                        | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
 
-               if ( monitor_cache_add( mi, e ) ) {
+               if ( monitor_cache_add( mi, e, e_thread ) ) {
                        Debug( LDAP_DEBUG_ANY,
                                "monitor_subsys_thread_init: "
                                "unable to add entry \"%s,%s\"\n",
@@ -200,9 +196,6 @@ monitor_subsys_thread_init(
                                ms->mss_dn.bv_val );
                        return( -1 );
                }
-       
-               *ep = e;
-               ep = &mp->mp_next;
        }
 
        monitor_cache_release( mi, e_thread );
index 3e11f957416f8b28c1a5f84aff4a8b1735cb0029..2f07d8f9d89415e97dfed31e3058d1bab411cff4 100644 (file)
@@ -44,7 +44,7 @@ monitor_subsys_time_init(
 {
        monitor_info_t  *mi;
        
-       Entry           *e, **ep, *e_time;
+       Entry           *e, *e_time;
        monitor_entry_t *mp;
        struct berval   bv, value;
 
@@ -63,10 +63,6 @@ monitor_subsys_time_init(
                return( -1 );
        }
 
-       mp = ( monitor_entry_t * )e_time->e_private;
-       mp->mp_children = NULL;
-       ep = &mp->mp_children;
-
        BER_BVSTR( &bv, "cn=Start" );
        e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
                mi->mi_oc_monitoredObject, NULL, NULL );
@@ -89,7 +85,7 @@ monitor_subsys_time_init(
        mp->mp_flags = ms->mss_flags \
                | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
 
-       if ( monitor_cache_add( mi, e ) ) {
+       if ( monitor_cache_add( mi, e, e_time ) ) {
                Debug( LDAP_DEBUG_ANY,
                        "monitor_subsys_time_init: "
                        "unable to add entry \"%s,%s\"\n",
@@ -97,9 +93,6 @@ monitor_subsys_time_init(
                return( -1 );
        }
        
-       *ep = e;
-       ep = &mp->mp_next;
-
        /*
         * Current
         */
@@ -125,7 +118,7 @@ monitor_subsys_time_init(
        mp->mp_flags = ms->mss_flags \
                | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
 
-       if ( monitor_cache_add( mi, e ) ) {
+       if ( monitor_cache_add( mi, e, e_time ) ) {
                Debug( LDAP_DEBUG_ANY,
                        "monitor_subsys_time_init: "
                        "unable to add entry \"%s,%s\"\n",
@@ -133,9 +126,6 @@ monitor_subsys_time_init(
                return( -1 );
        }
        
-       *ep = e;
-       ep = &mp->mp_next;
-
        /*
         * Uptime
         */
@@ -162,7 +152,7 @@ monitor_subsys_time_init(
        mp->mp_flags = ms->mss_flags \
                | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
 
-       if ( monitor_cache_add( mi, e ) ) {
+       if ( monitor_cache_add( mi, e, e_time ) ) {
                Debug( LDAP_DEBUG_ANY,
                        "monitor_subsys_time_init: "
                        "unable to add entry \"%s,%s\"\n",
@@ -170,9 +160,6 @@ monitor_subsys_time_init(
                return( -1 );
        }
        
-       *ep = e;
-       ep = &mp->mp_next;
-
        monitor_cache_release( mi, e_time );
 
        return( 0 );