From: Aki Tuomi Date: Tue, 24 Feb 2015 09:53:42 +0000 (+0200) Subject: Properly lock lmdb database, fixes #1954 X-Git-Tag: dnsdist-1.0.0-alpha1~248^2~112^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=08631edd7867234cc3d88e3d5645c2b3e37e8b71;p=pdns 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. --- diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index eb3c57b80..07d449d9e 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: " <