Title: [87490] trunk/Source/WebCore
Revision
87490
Author
h...@chromium.org
Date
2011-05-27 03:37:23 -0700 (Fri, 27 May 2011)

Log Message

2011-05-26  Hans Wennborg  <h...@chromium.org>

        Reviewed by Tony Gentilcore.

        LevelDB: turn on paranoid checks and verify checksums, log errors
        https://bugs.webkit.org/show_bug.cgi?id=61516

        This allows for detection of corrupted databases.
        Even if we can't recover from a corrupted database, discovering the
        problem is a step in the right direction.

        No new functionality, no new tests.

        * platform/leveldb/LevelDBDatabase.cpp:
        (WebCore::LevelDBDatabase::open):
        (WebCore::LevelDBDatabase::put):
        (WebCore::LevelDBDatabase::remove):
        (WebCore::LevelDBDatabase::get):
        (WebCore::LevelDBDatabase::write):
        (WebCore::IteratorImpl::checkStatus):
        (WebCore::IteratorImpl::seekToLast):
        (WebCore::IteratorImpl::seek):
        (WebCore::IteratorImpl::next):
        (WebCore::IteratorImpl::prev):
        (WebCore::LevelDBDatabase::createIterator):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (87489 => 87490)


--- trunk/Source/WebCore/ChangeLog	2011-05-27 10:16:40 UTC (rev 87489)
+++ trunk/Source/WebCore/ChangeLog	2011-05-27 10:37:23 UTC (rev 87490)
@@ -1,3 +1,29 @@
+2011-05-26  Hans Wennborg  <h...@chromium.org>
+
+        Reviewed by Tony Gentilcore.
+
+        LevelDB: turn on paranoid checks and verify checksums, log errors
+        https://bugs.webkit.org/show_bug.cgi?id=61516
+
+        This allows for detection of corrupted databases.
+        Even if we can't recover from a corrupted database, discovering the
+        problem is a step in the right direction.
+
+        No new functionality, no new tests.
+
+        * platform/leveldb/LevelDBDatabase.cpp:
+        (WebCore::LevelDBDatabase::open):
+        (WebCore::LevelDBDatabase::put):
+        (WebCore::LevelDBDatabase::remove):
+        (WebCore::LevelDBDatabase::get):
+        (WebCore::LevelDBDatabase::write):
+        (WebCore::IteratorImpl::checkStatus):
+        (WebCore::IteratorImpl::seekToLast):
+        (WebCore::IteratorImpl::seek):
+        (WebCore::IteratorImpl::next):
+        (WebCore::IteratorImpl::prev):
+        (WebCore::LevelDBDatabase::createIterator):
+
 2011-05-27  James Robinson  <jam...@chromium.org>
 
         Reviewed by Adam Barth.

Modified: trunk/Source/WebCore/platform/leveldb/LevelDBDatabase.cpp (87489 => 87490)


--- trunk/Source/WebCore/platform/leveldb/LevelDBDatabase.cpp	2011-05-27 10:16:40 UTC (rev 87489)
+++ trunk/Source/WebCore/platform/leveldb/LevelDBDatabase.cpp	2011-05-27 10:37:23 UTC (rev 87490)
@@ -32,6 +32,7 @@
 #include "LevelDBIterator.h"
 #include "LevelDBSlice.h"
 #include "LevelDBWriteBatch.h"
+#include "Logging.h"
 #include <leveldb/comparator.h>
 #include <leveldb/db.h>
 #include <leveldb/slice.h>
@@ -98,17 +99,19 @@
 {
     OwnPtr<ComparatorAdapter> comparatorAdapter = adoptPtr(new ComparatorAdapter(comparator));
 
-    OwnPtr<LevelDBDatabase> result = adoptPtr(new LevelDBDatabase);
-
     leveldb::Options options;
     options.comparator = comparatorAdapter.get();
     options.create_if_missing = true;
+    options.paranoid_checks = true;
     leveldb::DB* db;
-    leveldb::Status s = leveldb::DB::Open(options, fileName.utf8().data(), &db);
+    const leveldb::Status s = leveldb::DB::Open(options, fileName.utf8().data(), &db);
 
-    if (!s.ok())
+    if (!s.ok()) {
+        LOG_ERROR("Failed to open LevelDB database from %s: %s", fileName.ascii().data(), s.ToString().c_str());
         return nullptr;
+    }
 
+    OwnPtr<LevelDBDatabase> result = adoptPtr(new LevelDBDatabase);
     result->m_db = adoptPtr(db);
     result->m_comparatorAdapter = comparatorAdapter.release();
     result->m_comparator = comparator;
@@ -121,7 +124,11 @@
     leveldb::WriteOptions writeOptions;
     writeOptions.sync = true;
 
-    return m_db->Put(writeOptions, makeSlice(key), makeSlice(value)).ok();
+    const leveldb::Status s = m_db->Put(writeOptions, makeSlice(key), makeSlice(value));
+    if (s.ok())
+        return true;
+    LOG_ERROR("LevelDB put failed: %s", s.ToString().c_str());
+    return false;
 }
 
 bool LevelDBDatabase::remove(const LevelDBSlice& key)
@@ -129,17 +136,30 @@
     leveldb::WriteOptions writeOptions;
     writeOptions.sync = true;
 
-    return m_db->Delete(writeOptions, makeSlice(key)).ok();
+    const leveldb::Status s = m_db->Delete(writeOptions, makeSlice(key));
+    if (s.ok())
+        return true;
+    if (s.IsNotFound())
+        return false;
+    LOG_ERROR("LevelDB remove failed: %s", s.ToString().c_str());
+    return false;
 }
 
 bool LevelDBDatabase::get(const LevelDBSlice& key, Vector<char>& value)
 {
     std::string result;
-    if (!m_db->Get(leveldb::ReadOptions(), makeSlice(key), &result).ok())
+    leveldb::ReadOptions readOptions;
+    readOptions.verify_checksums = true; // FIXME: Disable this if the performance impact is too great.
+
+    const leveldb::Status s = m_db->Get(readOptions, makeSlice(key), &result);
+    if (s.ok()) {
+        value = makeVector(result);
+        return true;
+    }
+    if (s.IsNotFound())
         return false;
-
-    value = makeVector(result);
-    return true;
+    LOG_ERROR("LevelDB get failed: %s", s.ToString().c_str());
+    return false;
 }
 
 bool LevelDBDatabase::write(LevelDBWriteBatch& writeBatch)
@@ -147,7 +167,11 @@
     leveldb::WriteOptions writeOptions;
     writeOptions.sync = true;
 
-    return m_db->Write(writeOptions, writeBatch.m_writeBatch.get()).ok();
+    const leveldb::Status s = m_db->Write(writeOptions, writeBatch.m_writeBatch.get());
+    if (s.ok())
+        return true;
+    LOG_ERROR("LevelDB write failed: %s", s.ToString().c_str());
+    return false;
 }
 
 namespace {
@@ -166,6 +190,7 @@
 private:
     friend class WebCore::LevelDBDatabase;
     IteratorImpl(PassOwnPtr<leveldb::Iterator>);
+    void checkStatus();
 
     OwnPtr<leveldb::Iterator> m_iterator;
 };
@@ -176,6 +201,13 @@
 {
 }
 
+void IteratorImpl::checkStatus()
+{
+    const leveldb::Status s = m_iterator->status();
+    if (!s.ok())
+        LOG_ERROR("LevelDB iterator error: %s", s.ToString().c_str());
+}
+
 bool IteratorImpl::isValid() const
 {
     return m_iterator->Valid();
@@ -184,23 +216,27 @@
 void IteratorImpl::seekToLast()
 {
     m_iterator->SeekToLast();
+    checkStatus();
 }
 
 void IteratorImpl::seek(const LevelDBSlice& target)
 {
     m_iterator->Seek(makeSlice(target));
+    checkStatus();
 }
 
 void IteratorImpl::next()
 {
     ASSERT(isValid());
     m_iterator->Next();
+    checkStatus();
 }
 
 void IteratorImpl::prev()
 {
     ASSERT(isValid());
     m_iterator->Prev();
+    checkStatus();
 }
 
 LevelDBSlice IteratorImpl::key() const
@@ -217,7 +253,9 @@
 
 PassOwnPtr<LevelDBIterator> LevelDBDatabase::createIterator()
 {
-    OwnPtr<leveldb::Iterator> i = adoptPtr(m_db->NewIterator(leveldb::ReadOptions()));
+    leveldb::ReadOptions readOptions;
+    readOptions.verify_checksums = true; // FIXME: Disable this if the performance impact is too great.
+    OwnPtr<leveldb::Iterator> i = adoptPtr(m_db->NewIterator(readOptions));
     if (!i) // FIXME: Double check if we actually need to check this.
         return nullptr;
     return adoptPtr(new IteratorImpl(i.release()));
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to