Changeset 87490 in webkit


Ignore:
Timestamp:
May 27, 2011 3:37:23 AM (13 years ago)
Author:
hans@chromium.org
Message:

2011-05-26 Hans Wennborg <hans@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):
Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r87485 r87490  
     12011-05-26  Hans Wennborg  <hans@chromium.org>
     2
     3        Reviewed by Tony Gentilcore.
     4
     5        LevelDB: turn on paranoid checks and verify checksums, log errors
     6        https://bugs.webkit.org/show_bug.cgi?id=61516
     7
     8        This allows for detection of corrupted databases.
     9        Even if we can't recover from a corrupted database, discovering the
     10        problem is a step in the right direction.
     11
     12        No new functionality, no new tests.
     13
     14        * platform/leveldb/LevelDBDatabase.cpp:
     15        (WebCore::LevelDBDatabase::open):
     16        (WebCore::LevelDBDatabase::put):
     17        (WebCore::LevelDBDatabase::remove):
     18        (WebCore::LevelDBDatabase::get):
     19        (WebCore::LevelDBDatabase::write):
     20        (WebCore::IteratorImpl::checkStatus):
     21        (WebCore::IteratorImpl::seekToLast):
     22        (WebCore::IteratorImpl::seek):
     23        (WebCore::IteratorImpl::next):
     24        (WebCore::IteratorImpl::prev):
     25        (WebCore::LevelDBDatabase::createIterator):
     26
    1272011-05-27  James Robinson  <jamesr@chromium.org>
    228
  • trunk/Source/WebCore/platform/leveldb/LevelDBDatabase.cpp

    r87370 r87490  
    3333#include "LevelDBSlice.h"
    3434#include "LevelDBWriteBatch.h"
     35#include "Logging.h"
    3536#include <leveldb/comparator.h>
    3637#include <leveldb/db.h>
     
    99100    OwnPtr<ComparatorAdapter> comparatorAdapter = adoptPtr(new ComparatorAdapter(comparator));
    100101
    101     OwnPtr<LevelDBDatabase> result = adoptPtr(new LevelDBDatabase);
    102 
    103102    leveldb::Options options;
    104103    options.comparator = comparatorAdapter.get();
    105104    options.create_if_missing = true;
     105    options.paranoid_checks = true;
    106106    leveldb::DB* db;
    107     leveldb::Status s = leveldb::DB::Open(options, fileName.utf8().data(), &db);
    108 
    109     if (!s.ok())
     107    const leveldb::Status s = leveldb::DB::Open(options, fileName.utf8().data(), &db);
     108
     109    if (!s.ok()) {
     110        LOG_ERROR("Failed to open LevelDB database from %s: %s", fileName.ascii().data(), s.ToString().c_str());
    110111        return nullptr;
    111 
     112    }
     113
     114    OwnPtr<LevelDBDatabase> result = adoptPtr(new LevelDBDatabase);
    112115    result->m_db = adoptPtr(db);
    113116    result->m_comparatorAdapter = comparatorAdapter.release();
     
    122125    writeOptions.sync = true;
    123126
    124     return m_db->Put(writeOptions, makeSlice(key), makeSlice(value)).ok();
     127    const leveldb::Status s = m_db->Put(writeOptions, makeSlice(key), makeSlice(value));
     128    if (s.ok())
     129        return true;
     130    LOG_ERROR("LevelDB put failed: %s", s.ToString().c_str());
     131    return false;
    125132}
    126133
     
    130137    writeOptions.sync = true;
    131138
    132     return m_db->Delete(writeOptions, makeSlice(key)).ok();
     139    const leveldb::Status s = m_db->Delete(writeOptions, makeSlice(key));
     140    if (s.ok())
     141        return true;
     142    if (s.IsNotFound())
     143        return false;
     144    LOG_ERROR("LevelDB remove failed: %s", s.ToString().c_str());
     145    return false;
    133146}
    134147
     
    136149{
    137150    std::string result;
    138     if (!m_db->Get(leveldb::ReadOptions(), makeSlice(key), &result).ok())
     151    leveldb::ReadOptions readOptions;
     152    readOptions.verify_checksums = true; // FIXME: Disable this if the performance impact is too great.
     153
     154    const leveldb::Status s = m_db->Get(readOptions, makeSlice(key), &result);
     155    if (s.ok()) {
     156        value = makeVector(result);
     157        return true;
     158    }
     159    if (s.IsNotFound())
    139160        return false;
    140 
    141     value = makeVector(result);
    142     return true;
     161    LOG_ERROR("LevelDB get failed: %s", s.ToString().c_str());
     162    return false;
    143163}
    144164
     
    148168    writeOptions.sync = true;
    149169
    150     return m_db->Write(writeOptions, writeBatch.m_writeBatch.get()).ok();
     170    const leveldb::Status s = m_db->Write(writeOptions, writeBatch.m_writeBatch.get());
     171    if (s.ok())
     172        return true;
     173    LOG_ERROR("LevelDB write failed: %s", s.ToString().c_str());
     174    return false;
    151175}
    152176
     
    167191    friend class WebCore::LevelDBDatabase;
    168192    IteratorImpl(PassOwnPtr<leveldb::Iterator>);
     193    void checkStatus();
    169194
    170195    OwnPtr<leveldb::Iterator> m_iterator;
     
    177202}
    178203
     204void IteratorImpl::checkStatus()
     205{
     206    const leveldb::Status s = m_iterator->status();
     207    if (!s.ok())
     208        LOG_ERROR("LevelDB iterator error: %s", s.ToString().c_str());
     209}
     210
    179211bool IteratorImpl::isValid() const
    180212{
     
    185217{
    186218    m_iterator->SeekToLast();
     219    checkStatus();
    187220}
    188221
     
    190223{
    191224    m_iterator->Seek(makeSlice(target));
     225    checkStatus();
    192226}
    193227
     
    196230    ASSERT(isValid());
    197231    m_iterator->Next();
     232    checkStatus();
    198233}
    199234
     
    202237    ASSERT(isValid());
    203238    m_iterator->Prev();
     239    checkStatus();
    204240}
    205241
     
    218254PassOwnPtr<LevelDBIterator> LevelDBDatabase::createIterator()
    219255{
    220     OwnPtr<leveldb::Iterator> i = adoptPtr(m_db->NewIterator(leveldb::ReadOptions()));
     256    leveldb::ReadOptions readOptions;
     257    readOptions.verify_checksums = true; // FIXME: Disable this if the performance impact is too great.
     258    OwnPtr<leveldb::Iterator> i = adoptPtr(m_db->NewIterator(readOptions));
    221259    if (!i) // FIXME: Double check if we actually need to check this.
    222260        return nullptr;
Note: See TracChangeset for help on using the changeset viewer.