Author: kpvdr
Date: Mon Jun  2 15:38:56 2014
New Revision: 1599243

URL: http://svn.apache.org/r1599243
Log:
QPID-5767: [linearstore] broker segfaults when recovering journal file with 
damaged header

Modified:
    qpid/trunk/qpid/cpp/src/qpid/linearstore/ISSUES
    qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/RecoveryManager.cpp
    qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/RecoveryManager.h
    qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/jcfg.h
    qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/utils/file_hdr.c
    qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/utils/file_hdr.h
    qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/utils/rec_hdr.c

Modified: qpid/trunk/qpid/cpp/src/qpid/linearstore/ISSUES
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/linearstore/ISSUES?rev=1599243&r1=1599242&r2=1599243&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/linearstore/ISSUES (original)
+++ qpid/trunk/qpid/cpp/src/qpid/linearstore/ISSUES Mon Jun  2 15:38:56 2014
@@ -47,6 +47,7 @@ Current/pending:
    5464 -        [linearstore] Incompletely created journal files accumulate 
in EFP
    -    1088944  [Linearstore] store does not return all files to EFP after 
purging big queue
    -    1078937  [linearstore] Installation and tests for new store analysis 
tool qpid-qls-analyze
+                   svn r.1596633 2014-05-21: Modified to run from installed 
location
 
 Fixed/closed (in commit order):
 ===============================
@@ -157,6 +158,7 @@ no.   svn r  Q-JIRA     RHBZ       Date 
 26. 1584379    5661        - 2014-04-03
 27. 1594215    5750  1078142 2014-05-13
 28. 1596509    5767  1098118 2014-05-21 (pmoravec)
+29. 1596633  NO-JIRA 1078937 2014-05-21
 
 See above sections for details on these checkins.
 

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=1599243&r1=1599242&r2=1599243&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/RecoveryManager.cpp 
(original)
+++ qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/RecoveryManager.cpp Mon 
Jun  2 15:38:56 2014
@@ -399,10 +399,10 @@ void RecoveryManager::analyzeJournalFile
     stringList_t directoryList;
     jdir::read_dir(journalDirectory_, directoryList, false, true, false, true);
     for (stringListConstItr_t i = directoryList.begin(); i != 
directoryList.end(); ++i) {
-        readJournalFileHeader(*i, fileHeader, headerQueueName);
-        if (headerQueueName.empty()) {
+        bool hdrOk = readJournalFileHeader(*i, fileHeader, headerQueueName);
+        if (!hdrOk || headerQueueName.empty()) {
             std::ostringstream oss;
-            oss << "Journal file " << (*i) << " is uninitialized";
+            oss << "Journal file " << (*i) << " is uninitialized or corrupted";
             journalLogRef_.log(JournalLog::LOG_WARN, queueName_, oss.str());
             uninitFileList_.push_back(*i);
         } else if (headerQueueName.compare(queueName_) != 0) {
@@ -893,7 +893,7 @@ bool RecoveryManager::readFileHeader() {
     file_hdr_t fhdr;
     inFileStream_.read((char*)&fhdr, sizeof(fhdr));
     checkFileStreamOk(true);
-    if (::file_hdr_check(&fhdr, QLS_FILE_MAGIC, QLS_JRNL_VERSION, 
efpFileSize_kib_) != 0) {
+    if (::file_hdr_check(&fhdr, QLS_FILE_MAGIC, QLS_JRNL_VERSION, 
efpFileSize_kib_, QLS_MAX_QUEUE_NAME_LEN) != 0) {
         firstRecordOffset_ = fhdr._fro;
         currentSerial_ = fhdr._rhdr._serial;
     } else {
@@ -907,7 +907,7 @@ bool RecoveryManager::readFileHeader() {
 }
 
 // static private
-void RecoveryManager::readJournalFileHeader(const std::string& journalFileName,
+bool RecoveryManager::readJournalFileHeader(const std::string& journalFileName,
                                             ::file_hdr_t& fileHeaderRef,
                                             std::string& queueName) {
     const std::size_t headerBlockSize = QLS_JRNL_FHDR_RES_SIZE_SBLKS * 
QLS_SBLK_SIZE_KIB * 1024;
@@ -928,8 +928,9 @@ void RecoveryManager::readJournalFileHea
     }
     ifs.close();
     ::memcpy(&fileHeaderRef, buffer, sizeof(::file_hdr_t));
+    if (::file_hdr_check(&fileHeaderRef, QLS_FILE_MAGIC, QLS_JRNL_VERSION, 0, 
QLS_MAX_QUEUE_NAME_LEN)) return false;
     queueName.assign(buffer + sizeof(::file_hdr_t), 
fileHeaderRef._queue_name_len);
-
+    return true;
 }
 
 void RecoveryManager::removeEmptyFiles(EmptyFilePool* emptyFilePoolPtr) {

Modified: qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/RecoveryManager.h
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/RecoveryManager.h?rev=1599243&r1=1599242&r2=1599243&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/RecoveryManager.h 
(original)
+++ qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/RecoveryManager.h Mon Jun  
2 15:38:56 2014
@@ -147,7 +147,7 @@ protected:
     void readJournalData(char* target, const std::streamsize size);
     void removeEmptyFiles(EmptyFilePool* emptyFilePoolPtr);
 
-    static void readJournalFileHeader(const std::string& journalFileName,
+    static bool readJournalFileHeader(const std::string& journalFileName,
                                       ::file_hdr_t& fileHeaderRef,
                                       std::string& queueName);
 };

Modified: qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/jcfg.h
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/jcfg.h?rev=1599243&r1=1599242&r2=1599243&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/jcfg.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/jcfg.h Mon Jun  2 15:38:56 
2014
@@ -54,6 +54,7 @@
 #define QLS_EMPTY_MAGIC                 0x78534c51  /**< ("QLSx" in little 
endian) Magic for empty dblk */
 #define QLS_JRNL_VERSION                2           /**< Version (of file 
layout) */
 #define QLS_JRNL_FHDR_RES_SIZE_SBLKS    1           /**< Journal file header 
reserved size in sblks (as defined by QLS_SBLK_SIZE_BYTES) */
+#define QLS_MAX_QUEUE_NAME_LEN          (QLS_JRNL_FHDR_RES_SIZE_SBLKS * 
QLS_SBLK_SIZE_BYTES) - sizeof(file_hdr_t)
 
 #define QLS_CLEAN                                   /**< If defined, writes 
QLS_CLEAN_CHAR to all filled areas on disk */
 #define QLS_CLEAN_CHAR                  0xff        /**< Char used to clear 
empty space on disk */

Modified: qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/utils/file_hdr.c
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/utils/file_hdr.c?rev=1599243&r1=1599242&r2=1599243&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/utils/file_hdr.c (original)
+++ qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/utils/file_hdr.c Mon Jun  
2 15:38:56 2014
@@ -55,11 +55,11 @@ int file_hdr_init(void* dest, const uint
     return set_time_now(dest);
 }
 
-int file_hdr_check(file_hdr_t* hdr, const uint32_t magic, const uint16_t 
version, const uint64_t data_size_kib) {
-    int res = rec_hdr_check_base(&hdr->_rhdr, magic, version);
-    if (res != 0) return res;
-    if (hdr->_data_size_kib != data_size_kib) return 3;
-    return 0;
+int file_hdr_check(file_hdr_t* hdr, const uint32_t magic, const uint16_t 
version, const uint64_t data_size_kib, const uint16_t max_queue_name_len) {
+    int err = rec_hdr_check_base(&hdr->_rhdr, magic, version);
+    if (data_size_kib && hdr->_data_size_kib != data_size_kib) err |= 0x1000;
+    if (hdr->_queue_name_len > max_queue_name_len) err |= 0x10000;
+    return err;
 }
 
 void file_hdr_copy(file_hdr_t* dest, const file_hdr_t* src) {

Modified: qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/utils/file_hdr.h
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/utils/file_hdr.h?rev=1599243&r1=1599242&r2=1599243&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/utils/file_hdr.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/utils/file_hdr.h Mon Jun  
2 15:38:56 2014
@@ -92,8 +92,10 @@ typedef struct file_hdr_t {
 void file_hdr_create(file_hdr_t* dest, const uint32_t magic, const uint16_t 
version,
                      const uint16_t fhdr_size_sblks, const uint16_t 
efp_partition, const uint64_t file_size);
 int file_hdr_init(void* dest, const uint64_t dest_len, const uint16_t uflag, 
const uint64_t serial, const uint64_t rid,
-                  const uint64_t fro, const uint64_t file_number, const 
uint16_t queue_name_len, const char* queue_name);
-int file_hdr_check(file_hdr_t* hdr, const uint32_t magic, const uint16_t 
version, const uint64_t data_size_kib);
+                  const uint64_t fro, const uint64_t file_number, const 
uint16_t queue_name_len,
+                  const char* queue_name);
+int file_hdr_check(file_hdr_t* hdr, const uint32_t magic, const uint16_t 
version, const uint64_t data_size_kib,
+                   const uint16_t max_queue_name_len);
 void file_hdr_reset(file_hdr_t* target);
 int is_file_hdr_reset(file_hdr_t* target);
 void file_hdr_copy(file_hdr_t* dest, const file_hdr_t* src);

Modified: qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/utils/rec_hdr.c
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/utils/rec_hdr.c?rev=1599243&r1=1599242&r2=1599243&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/utils/rec_hdr.c (original)
+++ qpid/trunk/qpid/cpp/src/qpid/linearstore/journal/utils/rec_hdr.c Mon Jun  2 
15:38:56 2014
@@ -38,14 +38,14 @@ void rec_hdr_copy(rec_hdr_t* dest, const
 }
 
 int rec_hdr_check_base(rec_hdr_t* header, const uint32_t magic, const uint16_t 
version) {
-    if (header->_magic != magic) return 1;
-    if (header->_version != version) return 2;
-    return 0;
+    int err = 0;
+    if (header->_magic != magic) err |= 0x1;
+    if (header->_version != version) err |= 0x10;
+    return err;
 }
 
 int rec_hdr_check(rec_hdr_t* header, const uint32_t magic, const uint16_t 
version, const uint64_t serial) {
-    int res = rec_hdr_check_base(header, magic, version);
-    if (res != 0) return res;
-    if (header->_serial != serial) return 3;
-    return 0;
+    int err = rec_hdr_check_base(header, magic, version);
+    if (header->_serial != serial) err |= 0x100;
+    return err;
 }



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

Reply via email to