Author: pmoravec
Date: Wed May 21 08:31:35 2014
New Revision: 1596509

URL: http://svn.apache.org/r1596509
Log:
QPID-5767: [C++ broker][linearstore] broker segfaults when recovering journal 
file with damaged header (Kim's patch)

Modified:
    qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/EmptyFilePoolManager.cpp
    qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/LinearFileController.cpp
    qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/RecoveryManager.cpp
    qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/jcntl.cpp
    qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/jerrno.cpp
    qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/jerrno.h

Modified: 
qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/EmptyFilePoolManager.cpp
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/EmptyFilePoolManager.cpp?rev=1596509&r1=1596508&r2=1596509&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/EmptyFilePoolManager.cpp 
(original)
+++ qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/EmptyFilePoolManager.cpp 
Wed May 21 08:31:35 2014
@@ -184,9 +184,9 @@ EmptyFilePool* EmptyFilePoolManager::get
 
 EmptyFilePool* EmptyFilePoolManager::getEmptyFilePool(const 
efpPartitionNumber_t partitionNumber,
                                                       const efpDataSize_kib_t 
efpDataSize_kib) {
-    EmptyFilePoolPartition* efppp = getEfpPartition(partitionNumber);
+    EmptyFilePoolPartition* efppp = getEfpPartition(partitionNumber > 0 ? 
partitionNumber : defaultPartitionNumber_);
     if (efppp != 0)
-        return efppp->getEmptyFilePool(efpDataSize_kib);
+       return efppp->getEmptyFilePool(efpDataSize_kib > 0 ? efpDataSize_kib : 
defaultEfpDataSize_kib_);
     return 0;
 }
 

Modified: 
qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/LinearFileController.cpp
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/LinearFileController.cpp?rev=1596509&r1=1596508&r2=1596509&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/LinearFileController.cpp 
(original)
+++ qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/LinearFileController.cpp 
Wed May 21 08:31:35 2014
@@ -102,6 +102,7 @@ void LinearFileController::removeFileToE
 }
 
 void LinearFileController::restoreEmptyFile(const std::string& fileName) {
+    // TODO: Add checks that this file is of a valid size; if not, delete this 
and get one from the EFP
     addJournalFile(fileName, emptyFilePoolPtr_->getIdentity(), 
getNextFileSeqNum(), 0);
 }
 

Modified: qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/RecoveryManager.cpp
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/RecoveryManager.cpp?rev=1596509&r1=1596508&r2=1596509&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/RecoveryManager.cpp 
(original)
+++ qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/RecoveryManager.cpp Wed 
May 21 08:31:35 2014
@@ -99,10 +99,22 @@ void RecoveryManager::analyzeJournals(co
     // Analyze file headers of existing journal files
     efpIdentity_t efpIdentity;
     analyzeJournalFileHeaders(efpIdentity);
-    *emptyFilePoolPtrPtr = emptyFilePoolManager->getEmptyFilePool(efpIdentity);
-    efpFileSize_kib_ = (*emptyFilePoolPtrPtr)->fileSize_kib();
 
-    if (!journalEmptyFlag_) {
+    if (journalEmptyFlag_) {
+        *emptyFilePoolPtrPtr = emptyFilePoolManager->getEmptyFilePool(0, 0); 
// Use default EFP
+    } else {
+        *emptyFilePoolPtrPtr = 
emptyFilePoolManager->getEmptyFilePool(efpIdentity);
+        if (! *emptyFilePoolPtrPtr) {
+            // TODO: At a later time, this could be used to establish a new 
pool size provided the partition exists.
+            // If the partition does not exist, this is always an error. For 
now, throw an exception, as this should
+            // not occur in any practical application. Once multiple 
partitions and mixed EFPs are supported, this
+            // needs to be resolved. Note that EFP size is always a multiple 
of QLS_SBLK_SIZE_BYTES (currently 4096
+            // bytes, any other value cannot be used and should be rejected as 
an error.
+            std::ostringstream oss;
+            oss << "Invalid EFP identity: Partition=" << efpIdentity.pn_ << " 
Size=" << efpIdentity.ds_ << "k";
+            throw jexception(jerrno::JERR_RCVM_INVALIDEFPID, oss.str(), 
"RecoveryManager", "analyzeJournals");
+        }
+        efpFileSize_kib_ = (*emptyFilePoolPtrPtr)->fileSize_kib();
 
         // Read all records, establish remaining enqueued records
         if (inFileStream_.is_open()) {
@@ -409,15 +421,14 @@ void RecoveryManager::analyzeJournalFile
             if (fileHeader._file_number > highestFileNumber_) {
                 highestFileNumber_ = fileHeader._file_number;
             }
+            // TODO: Logic weak here for detecting error conditions in 
journal, specifically when no
+            // valid files exist, or files from mixed EFPs. Currently last 
read file header determines
+            // efpIdentity.
+            efpIdentity.pn_ = fileHeader._efp_partition;
+            efpIdentity.ds_ = fileHeader._data_size_kib;
         }
     }
 
-    // TODO: Logic weak here for detecting error conditions in journal, 
specifically when no
-    // valid files exist, or files from mixed EFPs. Currently last read file 
header determines
-    // efpIdentity.
-    efpIdentity.pn_ = fileHeader._efp_partition;
-    efpIdentity.ds_ = fileHeader._data_size_kib;
-
     if (fileNumberMap_.empty()) {
         journalEmptyFlag_ = true;
     } else {

Modified: qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/jcntl.cpp
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/jcntl.cpp?rev=1596509&r1=1596508&r2=1596509&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/jcntl.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/jcntl.cpp Wed May 21 
08:31:35 2014
@@ -116,6 +116,7 @@ jcntl::recover(EmptyFilePoolManager* efp
     // Verify journal dir and journal files
     _jdir.verify_dir();
     _recoveryManager.analyzeJournals(prep_txn_list_ptr, efpmp, 
&_emptyFilePoolPtr);
+    assert(_emptyFilePoolPtr != 0);
 
     highest_rid = _recoveryManager.getHighestRecordId();
     _jrnl_log.log(/*LOG_DEBUG*/JournalLog::LOG_INFO, _jid, 
_recoveryManager.toLog(_jid, 5));

Modified: qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/jerrno.cpp
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/jerrno.cpp?rev=1596509&r1=1596508&r2=1596509&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/jerrno.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/jerrno.cpp Wed May 21 
08:31:35 2014
@@ -95,6 +95,7 @@ const uint32_t jerrno::JERR_RCVM_WRITE  
 const uint32_t jerrno::JERR_RCVM_NULLXID         = 0x0904;
 const uint32_t jerrno::JERR_RCVM_NOTDBLKALIGNED  = 0x0905;
 const uint32_t jerrno::JERR_RCVM_NULLFID         = 0x0907;
+const uint32_t jerrno::JERR_RCVM_INVALIDEFPID    = 0x0908;
 
 // class data_tok
 const uint32_t jerrno::JERR_DTOK_ILLEGALSTATE    = 0x0a00;
@@ -188,6 +189,7 @@ jerrno::__init()
     _err_map[JERR_RCVM_NULLXID] = "JERR_RCVM_NULLXID: Null XID when XID length 
non-null in header";
     _err_map[JERR_RCVM_NOTDBLKALIGNED] = "JERR_RCVM_NOTDBLKALIGNED: Offset is 
not data block (dblk)-aligned";
     _err_map[JERR_RCVM_NULLFID] = "JERR_RCVM_NULLFID: Null file id (FID)";
+    _err_map[JERR_RCVM_INVALIDEFPID] = "JERR_RCVM_INVALIDEFPID: Invalid EFP 
identity (partition/size)";
 
     // class data_tok
     _err_map[JERR_DTOK_ILLEGALSTATE] = "JERR_MTOK_ILLEGALSTATE: Attempted to 
change to illegal state.";

Modified: qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/jerrno.h
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/jerrno.h?rev=1596509&r1=1596508&r2=1596509&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/jerrno.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/jerrno.h Wed May 21 
08:31:35 2014
@@ -113,6 +113,7 @@ namespace journal {
         static const uint32_t JERR_RCVM_NULLXID;        ///< Null XID when XID 
length non-null in header
         static const uint32_t JERR_RCVM_NOTDBLKALIGNED; ///< Offset is not 
data block (dblk)-aligned
         static const uint32_t JERR_RCVM_NULLFID;        ///< Null file ID (FID)
+        static const uint32_t JERR_RCVM_INVALIDEFPID;   ///< Invalid EFP 
identity (partition/size)
 
         // class data_tok
         static const uint32_t JERR_DTOK_ILLEGALSTATE;   ///< Attempted to 
change to illegal state



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to