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]