Subject: [dtn-users] More work on transaction problem in oasys

From: Elwyn Davies <[email-masked]>
Date: Fri, 11 Nov 2011 17:07:04 +0000

Hi.

Darren Long reported that yesterday's 'fix' to the oasys storage 
routines resulted in a crash during database initialization.

I was able to reproduce the crash on a 32 bit machine running Berkeley 
DB 4.7.  For some reason Alex could not do so on a 64 bit machine.

However, inspection of the code indicates that there is a problem, at 
least during full database initialization, due to an apparent unmatched 
endTransaction in DTNServer::init_datastore.  This feeds a NULL pointer 
to the Berkeley commit routine as there is no transaction open at the 
time.  Closer inspection reveals that there is some more work to be done 
to properly integrate the new transaction control with the legacy 
storage mechanisms (BerkeleyDB, memorydb, filedb) so I have implemented 
a temporary workaround that turns the BerkeleyDB begin/endTransaction 
routines into no-ops, and added some debugging statements to allow us to 
track what is going on in case of further disaster.

I have checked this out to a limited extent with BerkeleyDB and it 
appears to work correctly so far.  If anybody (notably Darren) has any 
further problems - and has any feedback - please let me know.

The patch is attached and it is now in the repository on Sourcefourge 
(Change 2283).

Keith Scott is away until next week.  I'll liaise with him when he gets 
back to get a fully functional and unhacked system back up.

Regards,
Elwyn

diff -r 8941bd3e6dfb -r ee5bc0d3f40d storage/BerkeleyDBStore.cc
--- a/storage/BerkeleyDBStore.cc	Thu Nov 10 17:24:03 2011 +0000
+++ b/storage/BerkeleyDBStore.cc	Fri Nov 11 15:54:29 2011 +0000
@@ -222,6 +222,7 @@
 
     log_debug("BerkeleyDBStore::beginTransaction.");
 
+#if 0
     ret = dbenv_->txn_begin(dbenv_, NULL, &txid_local, flags);
     if ( ret!=0 ) {
         if ( ret==DB_RUNRECOVERY ) {
@@ -232,6 +233,13 @@
     if ( txid != NULL ) {
         *txid = (void *)txid_local;
     }
+#else
+    if ( txid != NULL) {
+        txid_local = (DB_TXN *)(*txid);
+	flags = 0x0;
+	ret = 0;
+    }
+#endif
 
     return 0;
 }
@@ -244,15 +252,21 @@
     u_int32_t flags = 0x0;
     DB_TXN *txp = (DB_TXN *) txid;
 
-    log_debug("BerkeleyDBStore::endTransaction");
+    log_debug("BerkeleyDBStore::endTransaction: txid = %p", txid);
 
     if ( be_durable ) {
     	log_debug("BerkeleyDBStore::endTransaction called with be_durable TRUE");
     }
 
+#if 0
     ret = txp->commit(txp, flags);
+#else
+    flags = 0x0;
+    txp = (DB_TXN *) txid;
+    ret = 0;
+#endif
 
-    return 0;
+    return ret;
 }
 
 //----------------------------------------------------------------------------
diff -r 8941bd3e6dfb -r ee5bc0d3f40d storage/DurableStore.cc
--- a/storage/DurableStore.cc	Thu Nov 10 17:24:03 2011 +0000
+++ b/storage/DurableStore.cc	Fri Nov 11 15:54:29 2011 +0000
@@ -171,6 +171,8 @@
 //         transaction_lock_.lock("beginTransaction");
 //     }
 
+     log_debug("DurableStore::beginTransaction entered");
+
      if (impl_!=NULL) {
         if ( open_txid_ ) {
             log_debug("DurableStore::beginTransaction called with Tx already open.");
@@ -179,6 +181,8 @@
             }
             return(0);
         } else {
+	    tx_counter_++;
+	    log_info("DurableStore::beginTransaction calling implementation beginTransaction for transaction %u", tx_counter_);
             ret = impl_->beginTransaction(&open_txid_);
             if ( ret==DS_ERR ) {
                 log_warn("error in beginTransaction; releasing lock and DS_ERR");
@@ -212,6 +216,7 @@
     }
 
     if (impl_!=NULL) {
+	log_info("DurableStore::endTransaction calling implementation endTransaction for transaction %u", tx_counter_);
         ret = impl_->endTransaction(open_txid_, durably_close_next_transaction_);
         open_txid_ = NULL;
         log_debug("DurableStore::endTransaction - releasing transaction lock.");
diff -r 8941bd3e6dfb -r ee5bc0d3f40d storage/DurableStore.h
--- a/storage/DurableStore.h	Thu Nov 10 17:24:03 2011 +0000
+++ b/storage/DurableStore.h	Fri Nov 11 15:54:29 2011 +0000
@@ -107,7 +107,7 @@
      */
     DurableStore(const char* logpath)
         : Logger("DurableStore", "%s", logpath), open_txid_(NULL),
-          haveSeenTransaction(false), impl_(0)
+          haveSeenTransaction(false), tx_counter_(0), impl_(0)
     { 
         log_debug("DurableStore instantiated (%p)", this);
         set_instance(this);
@@ -246,6 +246,7 @@
     void *open_txid_;
     pthread_t transactionThread;
     bool haveSeenTransaction;
+    unsigned int tx_counter_;		  // Counter for transactions executed
 
     bool durably_close_next_transaction_; // Durably save state at next
                                           // transaction close.