[rhmessaging-commits] rhmessaging commits: r4133 - store/trunk/cpp/lib.

rhmessaging-commits at lists.jboss.org rhmessaging-commits at lists.jboss.org
Tue Jul 20 13:07:24 EDT 2010


Author: kpvdr
Date: 2010-07-20 13:07:24 -0400 (Tue, 20 Jul 2010)
New Revision: 4133

Modified:
   store/trunk/cpp/lib/MessageStoreImpl.cpp
   store/trunk/cpp/lib/MessageStoreImpl.h
Log:
Bug 614944 - "qpidd broker crash in mrg::msgstore::TxnCtxt::abort() -> DbTxn::abort()": Fix part 1, which improves the exception handling so that there is no throw within a catch. This will not change the probability of occurance of this bug, but the logs and exception message outcome will be different.

Modified: store/trunk/cpp/lib/MessageStoreImpl.cpp
===================================================================
--- store/trunk/cpp/lib/MessageStoreImpl.cpp	2010-07-20 16:51:16 UTC (rev 4132)
+++ store/trunk/cpp/lib/MessageStoreImpl.cpp	2010-07-20 17:07:24 UTC (rev 4133)
@@ -306,57 +306,61 @@
 
 void MessageStoreImpl::init()
 {
-    journal::jdir::create_dir(getBdbBaseDir());
+        try {
+            journal::jdir::create_dir(getBdbBaseDir());
 
-    try {
-        dbenv.reset(new DbEnv(0));
-        dbenv->set_errpfx("msgstore");
-        dbenv->set_lg_regionmax(256000); // default = 65000
-        dbenv->open(getBdbBaseDir().c_str(), DB_THREAD | DB_CREATE | DB_INIT_TXN | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_USE_ENVIRON | DB_RECOVER, 0);
-    } catch (const DbException& e) {
-        if (e.get_errno() == DB_VERSION_MISMATCH)
-            THROW_STORE_EXCEPTION_2("Database environment mismatch: This version of bd4 does not match that which created the store database. "
-                                    "(If recovery is not important, delete the contents of the store directory. Otherwise, try upgrading the database using "
-                                    "db_upgrade or using db_recover - but the db4-utils package must also be installed to use these utilities.)", e);
-        THROW_STORE_EXCEPTION_2("Error opening environment", e);
-    }
+            dbenv.reset(new DbEnv(0));
+            dbenv->set_errpfx("msgstore");
+            dbenv->set_lg_regionmax(256000); // default = 65000
+            dbenv->open(getBdbBaseDir().c_str(), DB_THREAD | DB_CREATE | DB_INIT_TXN | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_USE_ENVIRON | DB_RECOVER, 0);
 
-    TxnCtxt txn;
-    try {
-        // Databases are constructed here instead of the constructor so that the DB_RECOVER flag can be used
-        // against the database environment. Recover can only be performed if no databases have been created
-        // against the environment at the time of recovery, as recovery invalidates the environment.
-        queueDb.reset(new Db(dbenv.get(), 0));
-        configDb.reset(new Db(dbenv.get(), 0));
-        exchangeDb.reset(new Db(dbenv.get(), 0));
-        mappingDb.reset(new Db(dbenv.get(), 0));
-        bindingDb.reset(new Db(dbenv.get(), 0));
-        generalDb.reset(new Db(dbenv.get(), 0));
+            // Databases are constructed here instead of the constructor so that the DB_RECOVER flag can be used
+            // against the database environment. Recover can only be performed if no databases have been created
+            // against the environment at the time of recovery, as recovery invalidates the environment.
+            queueDb.reset(new Db(dbenv.get(), 0));
+            dbs.push_back(queueDb);
+            configDb.reset(new Db(dbenv.get(), 0));
+            dbs.push_back(configDb);
+            exchangeDb.reset(new Db(dbenv.get(), 0));
+            dbs.push_back(exchangeDb);
+            mappingDb.reset(new Db(dbenv.get(), 0));
+            dbs.push_back(mappingDb);
+            bindingDb.reset(new Db(dbenv.get(), 0));
+            dbs.push_back(bindingDb);
+            generalDb.reset(new Db(dbenv.get(), 0));
+            dbs.push_back(generalDb);
 
-        txn.begin(dbenv.get(), false);
-        open(queueDb, txn.get(), "queues.db", false);
-        open(configDb, txn.get(), "config.db", false);
-        open(exchangeDb, txn.get(), "exchanges.db", false);
-        open(mappingDb, txn.get(), "mappings.db", true);
-        open(bindingDb, txn.get(), "bindings.db", true);
-        open(generalDb, txn.get(), "general.db",  false);
-        tplStorePtr.reset(new TplJournalImpl(timer, "TplStore", getTplBaseDir(), "tpl", defJournalGetEventsTimeout, defJournalFlushTimeout, agent));
-        txn.commit();
-    } catch (const journal::jexception& e) {
-        QPID_LOG(error, "Journal Exception occurred while initializing store: " << e);
-        txn.abort();
-        THROW_STORE_EXCEPTION_2("Error opening tplStore instance", e.what());
-    } catch (const DbException& e) {
-        QPID_LOG(error, "BDB exception occurred while initializing store: " << e.what());
-        txn.abort();
-        THROW_STORE_EXCEPTION_2("Error opening databases", e);
-    } catch (...) {
-        QPID_LOG(error, "Unknown exception occurred while initializing store.");
-        txn.abort();
-        throw;
-    }
+            TxnCtxt txn;
+            txn.begin(dbenv.get(), false);
+            try {
+                open(queueDb, txn.get(), "queues.db", false);
+                open(configDb, txn.get(), "config.db", false);
+                open(exchangeDb, txn.get(), "exchanges.db", false);
+                open(mappingDb, txn.get(), "mappings.db", true);
+                open(bindingDb, txn.get(), "bindings.db", true);
+                open(generalDb, txn.get(), "general.db",  false);
+                txn.commit();
+            } catch (...) { txn.abort(); throw; }
 
-    isInit = true;
+            tplStorePtr.reset(new TplJournalImpl(timer, "TplStore", getTplBaseDir(), "tpl", defJournalGetEventsTimeout, defJournalFlushTimeout, agent));
+            isInit = true;
+        } catch (const DbException& e) {
+            if (e.get_errno() == DB_VERSION_MISMATCH)
+            {
+                QPID_LOG(error, "Database environment mismatch: This version of db4 does not match that which created the store database.: " << e.what());
+                THROW_STORE_EXCEPTION_2("Database environment mismatch: This version of db4 does not match that which created the store database. "
+                                        "(If recovery is not important, delete the contents of the store directory. Otherwise, try upgrading the database using "
+                                        "db_upgrade or using db_recover - but the db4-utils package must also be installed to use these utilities.)", e);
+            }
+            QPID_LOG(error, "BDB exception occurred while initializing store: " << e.what());
+                THROW_STORE_EXCEPTION_2("BDB exception occurred while initializing store", e);
+        } catch (const journal::jexception& e) {
+            QPID_LOG(error, "Journal Exception occurred while initializing store: " << e);
+            THROW_STORE_EXCEPTION_2("Journal Exception occurred while initializing store", e.what());
+        } catch (...) {
+            QPID_LOG(error, "Unknown exception occurred while initializing store.");
+            throw;
+        }
 }
 
 void MessageStoreImpl::finalize()
@@ -389,20 +393,19 @@
                 THROW_STORE_EXCEPTION(oss.str());
             }
         }
-        for (std::list<db_ptr >::iterator i = dbs.begin(); i != dbs.end(); i++) {
-            (*i)->close(0);
-        }
+        closeDbs();
         dbs.clear();
         if (tplStorePtr->is_ready()) tplStorePtr->stop(true);
         dbenv->close(0);
+        isInit = false;
     }
     std::ostringstream oss;
     oss << storeDir << "/" << storeTopLevelDir;
     if (pushDownStoreFiles) {
         QPID_LOG(notice, "Store directory " << oss.str() << " was pushed down into directory " << mrg::journal::jdir::push_down(storeDir, storeTopLevelDir, "cluster") << ".");
     } else {
+        mrg::journal::jdir::delete_dir(oss.str().c_str());
         QPID_LOG(notice, "Store directory " << oss.str() << " was truncated.");
-        mrg::journal::jdir::delete_dir(oss.str().c_str());
     }
     init();
 }
@@ -425,16 +428,21 @@
 {
     if(dupKey) db->set_flags(DB_DUPSORT);
     db->open(txn, file, 0, DB_BTREE, DB_CREATE | DB_THREAD, 0);
-    dbs.push_back(db);
 }
 
+void MessageStoreImpl::closeDbs()
+{
+    for (std::list<db_ptr >::iterator i = dbs.begin(); i != dbs.end(); i++) {
+        (*i)->close(0);
+    }
+    dbs.clear();
+}
+
 MessageStoreImpl::~MessageStoreImpl()
 {
     finalize();
     try {
-        for (std::list<db_ptr >::iterator i = dbs.begin(); i != dbs.end(); i++) {
-            (*i)->close(0);
-        }
+        closeDbs();
     } catch (const DbException& e) {
         QPID_LOG(error, "Error closing BDB databases: " <<  e.what());
     } catch (const journal::jexception& e) {

Modified: store/trunk/cpp/lib/MessageStoreImpl.h
===================================================================
--- store/trunk/cpp/lib/MessageStoreImpl.h	2010-07-20 16:51:16 UTC (rev 4132)
+++ store/trunk/cpp/lib/MessageStoreImpl.h	2010-07-20 17:07:24 UTC (rev 4133)
@@ -240,6 +240,7 @@
               DbTxn* txn,
               const char* file,
               bool dupKey);
+    void closeDbs();
 
     // journal functions
     void createJrnlQueue(const qpid::broker::PersistableQueue& queue);



More information about the rhmessaging-commits mailing list