From: Aki Tuomi Date: Wed, 3 Sep 2014 07:10:14 +0000 (+0300) Subject: Fix issue #1689 X-Git-Tag: auth-3.4.0-rc2~19^2~2^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F1696%2Fhead;p=thirdparty%2Fpdns.git Fix issue #1689 --- diff --git a/modules/bindbackend/bindbackend2.cc b/modules/bindbackend/bindbackend2.cc index 41093ad278..28e38f1f04 100644 --- a/modules/bindbackend/bindbackend2.cc +++ b/modules/bindbackend/bindbackend2.cc @@ -332,43 +332,56 @@ void Bind2Backend::getUpdatedMasters(vector *changedDomains) void Bind2Backend::getAllDomains(vector *domains, bool include_disabled) { - ReadLock rl(&s_state_lock); SOAData soadata; - for(state_t::const_iterator i = s_state.begin(); i != s_state.end() ; ++i) { + // prevent deadlock by using getSOA() later on + { + ReadLock rl(&s_state_lock); + + for(state_t::const_iterator i = s_state.begin(); i != s_state.end() ; ++i) { + DomainInfo di; + di.id=i->d_id; + di.zone=i->d_name; + di.last_check=i->d_lastcheck; + di.kind=i->d_masters.empty() ? DomainInfo::Master : DomainInfo::Slave; //TODO: what about Native? + di.backend=this; + domains->push_back(di); + }; + } + + BOOST_FOREACH(DomainInfo &di, *domains) { soadata.db=(DNSBackend *)-1; // makes getSOA() skip the cache. - this->getSOA(i->d_name, soadata); - DomainInfo di; - di.id=i->d_id; + this->getSOA(di.zone, soadata); di.serial=soadata.serial; - di.zone=i->d_name; - di.last_check=i->d_lastcheck; - di.backend=this; - di.kind=i->d_masters.empty() ? DomainInfo::Master : DomainInfo::Slave; //TODO: what about Native? - - domains->push_back(di); } } void Bind2Backend::getUnfreshSlaveInfos(vector *unfreshDomains) { - ReadLock rl(&s_state_lock); - for(state_t::const_iterator i = s_state.begin(); i != s_state.end() ; ++i) { - if(i->d_masters.empty()) - continue; - DomainInfo sd; - sd.id=i->d_id; - sd.zone=i->d_name; - sd.masters=i->d_masters; - sd.last_check=i->d_lastcheck; - sd.backend=this; - sd.kind=DomainInfo::Slave; + vector domains; + { + ReadLock rl(&s_state_lock); + for(state_t::const_iterator i = s_state.begin(); i != s_state.end() ; ++i) { + if(i->d_masters.empty()) + continue; + DomainInfo sd; + sd.id=i->d_id; + sd.zone=i->d_name; + sd.masters=i->d_masters; + sd.last_check=i->d_lastcheck; + sd.backend=this; + sd.kind=DomainInfo::Slave; + domains.push_back(sd); + } + } + + BOOST_FOREACH(DomainInfo &sd, domains) { SOAData soadata; soadata.refresh=0; soadata.serial=0; soadata.db=(DNSBackend *)-1; // not sure if this is useful, inhibits any caches that might be around try { - getSOA(i->d_name,soadata); // we might not *have* a SOA yet + getSOA(sd.zone,soadata); // we might not *have* a SOA yet } catch(...){} sd.serial=soadata.serial;