From c40307b09985cf8e109f0567a9c5c7f5b556d228 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Tue, 24 Feb 2015 11:53:42 +0200 Subject: [PATCH] Properly lock lmdb database, fixes #1954 The LMDB database needs to be reloaded without allowing requests, so we use readwrite lock to ensure that this cannot happen. --- modules/lmdbbackend/lmdbbackend.cc | 13 +++++++++++-- modules/lmdbbackend/lmdbbackend.hh | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index a1b12508f..b3fc5082e 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -31,7 +31,7 @@ #endif int LMDBBackend::s_reloadcount=0; -pthread_mutex_t LMDBBackend::s_initlock = PTHREAD_MUTEX_INITIALIZER; +pthread_rwlock_t LMDBBackend::s_initlock = PTHREAD_RWLOCK_INITIALIZER; LMDBBackend::LMDBBackend(const string &suffix) { @@ -43,6 +43,7 @@ LMDBBackend::LMDBBackend(const string &suffix) d_doDnssec = false; } d_lastreload = s_reloadcount; + WriteLock wl(&s_initlock); open_db(); } @@ -57,7 +58,6 @@ void LMDBBackend::open_db() { if( MDB_VERINT( major, minor, patch ) < MDB_VERINT( 0, 9, 8 ) ) throw PDNSException( "LMDB Library version too old (" + verstring + "). Needs to be 0.9.8 or greater" ); - Lock l(&s_initlock); if( (rc = mdb_env_create(&env)) ) throw PDNSException("Couldn't open LMDB database " + path + ": mdb_env_create() returned " + mdb_strerror(rc)); @@ -121,6 +121,7 @@ void LMDBBackend::close_db() { LMDBBackend::~LMDBBackend() { + WriteLock wl(&s_initlock); close_db(); } @@ -130,6 +131,7 @@ void LMDBBackend::reload() { void LMDBBackend::needReload() { if (s_reloadcount > d_lastreload) { + WriteLock wl(&s_initlock); d_lastreload = s_reloadcount; close_db(); open_db(); @@ -142,6 +144,7 @@ bool LMDBBackend::getDomainMetadata(const string& name, const std::string& kind, return false; needReload(); + ReadLock rl(&s_initlock); if (kind == "PRESIGNED" || kind == "NSEC3PARAM") { int rc; @@ -178,6 +181,7 @@ bool LMDBBackend::getDirectNSECx(uint32_t id, const string &hashed, const QType return false; needReload(); + ReadLock rl(&s_initlock); MDB_val key, data; string key_str, cur_key, cur_value; @@ -250,6 +254,7 @@ bool LMDBBackend::getDirectRRSIGs(const string &signer, const string &qname, con return false; needReload(); + ReadLock rl(&s_initlock); int rc; MDB_val key, data; @@ -292,6 +297,7 @@ bool LMDBBackend::getDirectRRSIGs(const string &signer, const string &qname, con bool LMDBBackend::getAuthZone( string &rev_zone ) { needReload(); + ReadLock rl(&s_initlock); MDB_val key, data; // XXX can do this just using char * @@ -333,6 +339,7 @@ bool LMDBBackend::getAuthZone( string &rev_zone ) bool LMDBBackend::getAuthData( SOAData &soa, DNSPacket *p ) { needReload(); + ReadLock rl(&s_initlock); MDB_val key, value; if( mdb_cursor_get(zone_cursor, &key, &value, MDB_GET_CURRENT) ) @@ -378,6 +385,7 @@ void LMDBBackend::lookup(const QType &type, const string &inQdomain, DNSPacket * DEBUGLOG("lookup: " <