static int bdb_tool_index_add( Operation *op, DB_TXN *txn, Entry *e ) { struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; if ( !bdb->bi_nattrs ) return 0; if ( bdb_tool_threads > 1 ) { IndexRec *ir; int i, rc; Attribute *a; ir = bdb_tool_index_rec; memset(ir, 0, bdb->bi_nattrs * sizeof( IndexRec )); for ( a = e->e_attrs; a != NULL; a = a->a_next ) { rc = bdb_index_recset( bdb, a, a->a_desc->ad_type, &a->a_desc->ad_tags, ir ); if ( rc ) return rc; } bdb_tool_ix_id = e->e_id; bdb_tool_ix_op = op; ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex ); /* Wait for all threads to be ready */ while ( bdb_tool_index_tcount > 0 ) { ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main, &bdb_tool_index_mutex ); } for ( i=1; i<bdb_tool_threads; i++ ) bdb_tool_index_threads[i] = LDAP_BUSY; bdb_tool_index_tcount = bdb_tool_threads - 1; ldap_pvt_thread_cond_broadcast( &bdb_tool_index_cond_work ); ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex ); rc = bdb_index_recrun( op, bdb, ir, e->e_id, 0 ); if ( rc ) return rc; ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex ); for ( i=1; i<bdb_tool_threads; i++ ) { if ( bdb_tool_index_threads[i] == LDAP_BUSY ) { ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main, &bdb_tool_index_mutex ); i--; continue; } if ( bdb_tool_index_threads[i] ) { rc = bdb_tool_index_threads[i]; break; } } ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex ); return rc; } else { return bdb_index_entry_add( op, txn, e ); } }
int mdb_tool_entry_close( BackendDB *be ) { if ( mdb_tool_info ) { slapd_shutdown = 1; ldap_pvt_thread_mutex_lock( &mdb_tool_index_mutex ); /* There might still be some threads starting */ while ( mdb_tool_index_tcount > 0 ) { ldap_pvt_thread_cond_wait( &mdb_tool_index_cond_main, &mdb_tool_index_mutex ); } mdb_tool_index_tcount = mdb_tool_threads - 1; ldap_pvt_thread_cond_broadcast( &mdb_tool_index_cond_work ); /* Make sure all threads are stopped */ while ( mdb_tool_index_tcount > 0 ) { ldap_pvt_thread_cond_wait( &mdb_tool_index_cond_main, &mdb_tool_index_mutex ); } ldap_pvt_thread_mutex_unlock( &mdb_tool_index_mutex ); mdb_tool_info = NULL; slapd_shutdown = 0; ch_free( mdb_tool_index_rec ); mdb_tool_index_tcount = mdb_tool_threads - 1; } if( idcursor ) { mdb_cursor_close( idcursor ); idcursor = NULL; } if( cursor ) { mdb_cursor_close( cursor ); cursor = NULL; } if( txn ) { MDB_TOOL_IDL_FLUSH( be, txn ); if ( mdb_txn_commit( txn )) return -1; txn = NULL; } if( nholes ) { unsigned i; fprintf( stderr, "Error, entries missing!\n"); for (i=0; i<nholes; i++) { fprintf(stderr, " entry %ld: %s\n", holes[i].id, holes[i].dn.bv_val); } nholes = 0; return -1; } return 0; }
int bdb_tool_entry_close( BackendDB *be ) { if ( bdb_tool_info ) { slapd_shutdown = 1; ldap_pvt_thread_mutex_lock( &bdb_tool_trickle_mutex ); ldap_pvt_thread_cond_signal( &bdb_tool_trickle_cond ); ldap_pvt_thread_mutex_unlock( &bdb_tool_trickle_mutex ); ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex ); bdb_tool_index_tcount = slap_tool_thread_max - 1; ldap_pvt_thread_cond_broadcast( &bdb_tool_index_cond_work ); ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex ); } if( eh.bv.bv_val ) { ch_free( eh.bv.bv_val ); eh.bv.bv_val = NULL; } if( cursor ) { cursor->c_close( cursor ); cursor = NULL; } #ifdef BDB_TOOL_IDL_CACHING bdb_tool_idl_flush( be ); #endif if( nholes ) { unsigned i; fprintf( stderr, "Error, entries missing!\n"); for (i=0; i<nholes; i++) { fprintf(stderr, " entry %ld: %s\n", holes[i].id, holes[i].dn.bv_val); } return -1; } return 0; }
int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rwlock ) { struct ldap_int_thread_rdwr_s *rw; assert( rwlock != NULL ); rw = *rwlock; assert( rw != NULL ); assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID ); if( rw->ltrw_valid != LDAP_PVT_THREAD_RDWR_VALID ) return LDAP_PVT_THREAD_EINVAL; ldap_pvt_thread_mutex_lock( &rw->ltrw_mutex ); rw->ltrw_w_active--; assert( rw->ltrw_w_active >= 0 ); assert( rw->ltrw_w_wait >= 0 ); assert( rw->ltrw_r_active >= 0 ); assert( rw->ltrw_r_wait >= 0 ); if (rw->ltrw_r_wait > 0) { ldap_pvt_thread_cond_broadcast( &rw->ltrw_read ); } else if (rw->ltrw_w_wait > 0) { ldap_pvt_thread_cond_signal( &rw->ltrw_write ); } #ifdef LDAP_RDWR_DEBUG assert( rw->ltrw_writer == ldap_pvt_thread_self() ); rw->ltrw_writer = 0; #endif ldap_pvt_thread_mutex_unlock( &rw->ltrw_mutex ); return 0; }
int bdb_tool_entry_close( BackendDB *be ) { if ( bdb_tool_info ) { slapd_shutdown = 1; #ifdef USE_TRICKLE ldap_pvt_thread_mutex_lock( &bdb_tool_trickle_mutex ); /* trickle thread may not have started yet */ while ( !bdb_tool_trickle_active ) ldap_pvt_thread_cond_wait( &bdb_tool_trickle_cond_end, &bdb_tool_trickle_mutex ); ldap_pvt_thread_cond_signal( &bdb_tool_trickle_cond ); while ( bdb_tool_trickle_active ) ldap_pvt_thread_cond_wait( &bdb_tool_trickle_cond_end, &bdb_tool_trickle_mutex ); ldap_pvt_thread_mutex_unlock( &bdb_tool_trickle_mutex ); #endif if ( bdb_tool_threads > 1 ) { ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex ); /* There might still be some threads starting */ while ( bdb_tool_index_tcount > 0 ) { ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main, &bdb_tool_index_mutex ); } bdb_tool_index_tcount = bdb_tool_threads - 1; ldap_pvt_thread_cond_broadcast( &bdb_tool_index_cond_work ); /* Make sure all threads are stopped */ while ( bdb_tool_index_tcount > 0 ) { ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main, &bdb_tool_index_mutex ); } ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex ); ch_free( bdb_tool_index_threads ); ch_free( bdb_tool_index_rec ); bdb_tool_index_tcount = bdb_tool_threads - 1; } bdb_tool_info = NULL; slapd_shutdown = 0; } if( eh.bv.bv_val ) { ch_free( eh.bv.bv_val ); eh.bv.bv_val = NULL; } if( cursor ) { cursor->c_close( cursor ); cursor = NULL; } #ifdef BDB_TOOL_IDL_CACHING bdb_tool_idl_flush( be ); #endif if( nholes ) { unsigned i; fprintf( stderr, "Error, entries missing!\n"); for (i=0; i<nholes; i++) { fprintf(stderr, " entry %ld: %s\n", holes[i].id, holes[i].dn.bv_val); } return -1; } return 0; }
/* * Main file manager routine. Watches for new data to be appended to the * slapd replication log. When new data is appended, fm does the following: * - appends the data to slurpd's private copy of the replication log. * - truncates the slapd replog * - adds items to the internal queue of replication work to do * - signals the replication threads to let them know new work has arrived. */ void * fm( void *arg ) { int rc; int i; fd_set readfds; /* Set up our signal handlers: * SIG{TERM,INT,HUP} causes a shutdown */ (void) SIGNAL( SIGTERM, slurp_set_shutdown ); (void) SIGNAL( SIGINT, slurp_set_shutdown ); #ifdef SIGHUP (void) SIGNAL( SIGHUP, slurp_set_shutdown ); #endif #if defined(SIGBREAK) && defined(HAVE_NT_SERVICE_MANAGER) (void) SIGNAL( SIGBREAK, do_nothing ); #endif if ( sglob->one_shot_mode ) { if ( file_nonempty( sglob->slapd_replogfile )) { populate_queue( sglob->slapd_replogfile ); } printf( "Processing in one-shot mode:\n" ); printf( "%d total replication records in file,\n", sglob->rq->rq_getcount( sglob->rq, RQ_COUNT_ALL )); printf( "%d replication records to process.\n", sglob->rq->rq_getcount( sglob->rq, RQ_COUNT_NZRC )); return NULL; } /* * There may be some leftover replication records in our own * copy of the replication log. If any exist, add them to the * queue. */ if ( file_nonempty( sglob->slurpd_replogfile )) { populate_queue( sglob->slurpd_replogfile ); } FD_ZERO( &readfds ); while ( !sglob->slurpd_shutdown ) { if ( file_nonempty( sglob->slapd_replogfile )) { /* New work found - copy to slurpd replog file */ #ifdef NEW_LOGGING LDAP_LOG ( SLURPD, ARGS, "fm: new work in %s\n", sglob->slapd_replogfile, 0, 0 ); #else Debug( LDAP_DEBUG_ARGS, "new work in %s\n", sglob->slapd_replogfile, 0, 0 ); #endif if (( rc = copy_replog( sglob->slapd_replogfile, sglob->slurpd_replogfile )) == 0 ) { populate_queue( sglob->slurpd_replogfile ); } else { if ( rc < 0 ) { #ifdef NEW_LOGGING LDAP_LOG ( SLURPD, CRIT, "fm: Fatal error while copying replication log\n" , 0, 0, 0); #else Debug( LDAP_DEBUG_ANY, "Fatal error while copying replication log\n", 0, 0, 0 ); #endif sglob->slurpd_shutdown = 1; } } } else { struct timeval tv; FD_SET( sglob->wake_sds[0], &readfds ); tv.tv_sec = sglob->no_work_interval; tv.tv_usec = 0; rc = select( sglob->wake_sds[0]+1, &readfds, NULL, NULL, &tv ); } /* Garbage-collect queue */ sglob->rq->rq_gc( sglob->rq ); /* Trim replication log file, if needed */ if ( sglob->rq->rq_needtrim( sglob->rq )) { FILE *fp, *lfp; if (( rc = acquire_lock( sglob->slurpd_replogfile, &fp, &lfp )) < 0 ) { #ifdef NEW_LOGGING LDAP_LOG ( SLURPD, ERR, "fm: Error: cannot acquire lock on \"%s\" for trimming\n", sglob->slurpd_replogfile, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "Error: cannot acquire lock on \"%s\" for trimming\n", sglob->slurpd_replogfile, 0, 0 ); #endif } else { sglob->rq->rq_write( sglob->rq, fp ); (void) relinquish_lock( sglob->slurpd_replogfile, fp, lfp ); } } } sglob->rq->rq_lock( sglob->rq ); /* lock queue */ ldap_pvt_thread_cond_broadcast( &(sglob->rq->rq_more) ); /* wake repl threads */ for ( i = 0; i < sglob->num_replicas; i++ ) { (sglob->replicas[ i ])->ri_wake( sglob->replicas[ i ]); } sglob->rq->rq_unlock( sglob->rq ); /* unlock queue */ #ifdef NEW_LOGGING LDAP_LOG ( SLURPD, RESULTS, "fm: exiting\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_ARGS, "fm: exiting\n", 0, 0, 0 ); #endif return NULL; }
static int mdb_tool_index_add( Operation *op, MDB_txn *txn, Entry *e ) { struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private; if ( !mdb->mi_nattrs ) return 0; if ( mdb_tool_threads > 1 ) { IndexRec *ir; int i, rc; Attribute *a; ir = mdb_tool_index_rec; for (i=0; i<mdb->mi_nattrs; i++) ir[i].ir_attrs = NULL; for ( a = e->e_attrs; a != NULL; a = a->a_next ) { rc = mdb_index_recset( mdb, a, a->a_desc->ad_type, &a->a_desc->ad_tags, ir ); if ( rc ) return rc; } for (i=0; i<mdb->mi_nattrs; i++) { if ( !ir[i].ir_ai ) break; rc = mdb_cursor_open( txn, ir[i].ir_ai->ai_dbi, &ir[i].ir_ai->ai_cursor ); if ( rc ) return rc; } mdb_tool_ix_id = e->e_id; mdb_tool_ix_op = op; mdb_tool_ix_txn = txn; ldap_pvt_thread_mutex_lock( &mdb_tool_index_mutex ); /* Wait for all threads to be ready */ while ( mdb_tool_index_tcount ) { ldap_pvt_thread_cond_wait( &mdb_tool_index_cond_main, &mdb_tool_index_mutex ); } for ( i=1; i<mdb_tool_threads; i++ ) mdb_tool_index_rec[i].ir_i = LDAP_BUSY; mdb_tool_index_tcount = mdb_tool_threads - 1; ldap_pvt_thread_mutex_unlock( &mdb_tool_index_mutex ); ldap_pvt_thread_cond_broadcast( &mdb_tool_index_cond_work ); rc = mdb_index_recrun( op, txn, mdb, ir, e->e_id, 0 ); if ( rc ) return rc; ldap_pvt_thread_mutex_lock( &mdb_tool_index_mutex ); for ( i=1; i<mdb_tool_threads; i++ ) { if ( mdb_tool_index_rec[i].ir_i == LDAP_BUSY ) { ldap_pvt_thread_cond_wait( &mdb_tool_index_cond_main, &mdb_tool_index_mutex ); i--; continue; } if ( mdb_tool_index_rec[i].ir_i ) { rc = mdb_tool_index_rec[i].ir_i; break; } } ldap_pvt_thread_mutex_unlock( &mdb_tool_index_mutex ); return rc; } else { return mdb_index_entry_add( op, txn, e ); } }
int mdb_tool_entry_close( BackendDB *be ) { if ( mdb_tool_info ) { slapd_shutdown = 1; ldap_pvt_thread_mutex_lock( &mdb_tool_index_mutex ); /* There might still be some threads starting */ while ( mdb_tool_index_tcount > 0 ) { ldap_pvt_thread_cond_wait( &mdb_tool_index_cond_main, &mdb_tool_index_mutex ); } mdb_tool_index_tcount = mdb_tool_threads - 1; ldap_pvt_thread_cond_broadcast( &mdb_tool_index_cond_work ); /* Make sure all threads are stopped */ while ( mdb_tool_index_tcount > 0 ) { ldap_pvt_thread_cond_wait( &mdb_tool_index_cond_main, &mdb_tool_index_mutex ); } ldap_pvt_thread_mutex_unlock( &mdb_tool_index_mutex ); mdb_tool_info = NULL; slapd_shutdown = 0; ch_free( mdb_tool_index_rec ); mdb_tool_index_tcount = mdb_tool_threads - 1; } if( idcursor ) { mdb_cursor_close( idcursor ); idcursor = NULL; } if( cursor ) { mdb_cursor_close( cursor ); cursor = NULL; } if( mdb_tool_txn ) { int rc; MDB_TOOL_IDL_FLUSH( be, mdb_tool_txn ); if (( rc = mdb_txn_commit( mdb_tool_txn ))) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_tool_entry_close) ": database %s: " "txn_commit failed: %s (%d)\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); return -1; } mdb_tool_txn = NULL; } if( nholes ) { unsigned i; fprintf( stderr, "Error, entries missing!\n"); for (i=0; i<nholes; i++) { fprintf(stderr, " entry %ld: %s\n", holes[i].id, holes[i].dn.bv_val); } nholes = 0; return -1; } return 0; }