From 218dbbe419f941e291707afcb37b1ee1ef080a1a Mon Sep 17 00:00:00 2001 From: Quanah Gibson-Mount Date: Sun, 12 Dec 2010 05:11:53 +0000 Subject: [PATCH] ITS#6709 --- CHANGES | 1 + servers/slapd/overlays/syncprov.c | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/CHANGES b/CHANGES index c3e80b16e0..10b114ec2c 100644 --- a/CHANGES +++ b/CHANGES @@ -24,6 +24,7 @@ OpenLDAP 2.4.24 Engineering Fixed slapo-sssvlv initialization (ITS#6649) Fixed slapo-syncprov to send error if consumer is newer (ITS#6606) Fixed slapo-syncprov properly mutex filter (ITS#6708) + Fixed slapo-syncprov active mod race (ITS#6709) Fixed contrib/nssov to only close socket on shutdown (ITS#6676) Documentation admin24 guide typo fixes (ITS#6609) diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c index c708dc6db6..49a4af766a 100644 --- a/servers/slapd/overlays/syncprov.c +++ b/servers/slapd/overlays/syncprov.c @@ -133,6 +133,7 @@ typedef struct syncprov_info_t { int si_numops; /* number of ops since last checkpoint */ int si_nopres; /* Skip present phase */ int si_usehint; /* use reload hint */ + int si_active; /* True if there are active mods */ time_t si_chklast; /* time of last checkpoint */ Avlnode *si_mods; /* entries being modified */ sessionlog *si_logs; @@ -1376,6 +1377,11 @@ syncprov_op_cleanup( Operation *op, SlapReply *rs ) syncmatches *sm, *snext; modtarget *mt, mtdummy; + ldap_pvt_thread_mutex_lock( &si->si_ops_mutex ); + if ( si->si_active ) + si->si_active--; + ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex ); + for (sm = opc->smatches; sm; sm=snext) { snext = sm->sm_next; syncprov_free_syncop( sm->sm_op ); @@ -1976,6 +1982,7 @@ syncprov_op_mod( Operation *op, SlapReply *rs ) ldap_pvt_thread_mutex_lock( &si->si_ops_mutex ); have_psearches = ( si->si_ops != NULL ); + si->si_active++; ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex ); cbsize = sizeof(slap_callback) + sizeof(opcookie) + @@ -2410,6 +2417,20 @@ syncprov_op_search( Operation *op, SlapReply *rs ) sop->s_inuse = 1; ldap_pvt_thread_mutex_lock( &si->si_ops_mutex ); + while ( si->si_active ) { + /* Wait for active mods to finish before proceeding, as they + * may already have inspected the si_ops list looking for + * consumers to replicate the change to. Using the log + * doesn't help, as we may finish playing it before the + * active mods gets added to it. + */ + ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex ); + if ( slapd_shutdown ) + return SLAPD_ABANDON; + if ( !ldap_pvt_thread_pool_pausecheck( &connection_pool )) + ldap_pvt_thread_yield(); + ldap_pvt_thread_mutex_lock( &si->si_ops_mutex ); + } sop->s_next = si->si_ops; si->si_ops = sop; ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex ); -- 2.39.5