summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authoralbertb@chromium.org <albertb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-27 17:17:05 +0000
committeralbertb@chromium.org <albertb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-27 17:17:05 +0000
commit62e0dbdec1c30c929d7c6148372b153e9b1c1792 (patch)
tree5be4d32baa5d183554a3b1d6bf2e43afc1734f43 /chrome/browser
parent17a9a971303d65afcd32ab0921e1beb8dd27329c (diff)
downloadchromium_src-62e0dbdec1c30c929d7c6148372b153e9b1c1792.zip
chromium_src-62e0dbdec1c30c929d7c6148372b153e9b1c1792.tar.gz
chromium_src-62e0dbdec1c30c929d7c6148372b153e9b1c1792.tar.bz2
Delete and recreate the sync database if it is corrupt.
BUG=40020 TEST=DirectoryBackingStoreTest.Corruption Review URL: http://codereview.chromium.org/1733008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45712 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/sync/syncable/directory_backing_store.cc18
-rw-r--r--chrome/browser/sync/syncable/directory_backing_store.h3
-rw-r--r--chrome/browser/sync/syncable/directory_backing_store_unittest.cc24
3 files changed, 41 insertions, 4 deletions
diff --git a/chrome/browser/sync/syncable/directory_backing_store.cc b/chrome/browser/sync/syncable/directory_backing_store.cc
index 2635def..9c86ea7 100644
--- a/chrome/browser/sync/syncable/directory_backing_store.cc
+++ b/chrome/browser/sync/syncable/directory_backing_store.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -12,6 +12,7 @@
#include <limits>
+#include "base/file_util.h"
#include "base/hash_tables.h"
#include "base/logging.h"
#include "chrome/browser/sync/protocol/bookmark_specifics.pb.h"
@@ -179,19 +180,22 @@ DirectoryBackingStore::~DirectoryBackingStore() {
bool DirectoryBackingStore::OpenAndConfigureHandleHelper(
sqlite3** handle) const {
if (SQLITE_OK == OpenSqliteDb(backing_filepath_, handle)) {
+ sqlite_utils::scoped_sqlite_db_ptr scoped_handle(*handle);
sqlite3_busy_timeout(*handle, std::numeric_limits<int>::max());
{
SQLStatement statement;
statement.prepare(*handle, "PRAGMA fullfsync = 1");
if (SQLITE_DONE != statement.step()) {
- LOG(FATAL) << sqlite3_errmsg(*handle);
+ LOG(ERROR) << sqlite3_errmsg(*handle);
+ return false;
}
}
{
SQLStatement statement;
statement.prepare(*handle, "PRAGMA synchronous = 2");
if (SQLITE_DONE != statement.step()) {
- LOG(FATAL) << sqlite3_errmsg(*handle);
+ LOG(ERROR) << sqlite3_errmsg(*handle);
+ return false;
}
}
sqlite3_busy_timeout(*handle, kDirectoryBackingStoreBusyTimeoutMs);
@@ -204,6 +208,7 @@ bool DirectoryBackingStore::OpenAndConfigureHandleHelper(
attrs | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);
#endif
+ scoped_handle.release();
return true;
}
return false;
@@ -230,6 +235,13 @@ DirOpenResult DirectoryBackingStore::Load(MetahandlesIndex* entry_bucket,
bool DirectoryBackingStore::BeginLoad() {
DCHECK(load_dbhandle_ == NULL);
+ bool ret = OpenAndConfigureHandleHelper(&load_dbhandle_);
+ if (ret)
+ return ret;
+ // Something's gone wrong. Nuke the database and try again.
+ LOG(ERROR) << "Sync database " << backing_filepath_.value()
+ << " corrupt. Deleting and recreating.";
+ file_util::Delete(backing_filepath_, false);
return OpenAndConfigureHandleHelper(&load_dbhandle_);
}
diff --git a/chrome/browser/sync/syncable/directory_backing_store.h b/chrome/browser/sync/syncable/directory_backing_store.h
index 34cb3ac..d1e7d7d 100644
--- a/chrome/browser/sync/syncable/directory_backing_store.h
+++ b/chrome/browser/sync/syncable/directory_backing_store.h
@@ -81,6 +81,7 @@ class DirectoryBackingStore {
FRIEND_TEST(DirectoryBackingStoreTest, MigrateVersion69To70);
FRIEND_TEST(DirectoryBackingStoreTest, MigrateVersion70To71);
FRIEND_TEST(DirectoryBackingStoreTest, ModelTypeIds);
+ FRIEND_TEST(DirectoryBackingStoreTest, Corruption);
FRIEND_TEST(MigrationTest, ToCurrentVersion);
// General Directory initialization and load helpers.
@@ -148,7 +149,7 @@ class DirectoryBackingStore {
int GetVersion();
bool MigrateToSpecifics(const char* old_columns,
const char* specifics_column,
- void (*handler_function)(
+ void (*handler_function) (
SQLStatement* old_value_query,
int old_value_column,
sync_pb::EntitySpecifics* mutable_new_value));
diff --git a/chrome/browser/sync/syncable/directory_backing_store_unittest.cc b/chrome/browser/sync/syncable/directory_backing_store_unittest.cc
index bf5dfde..777a163 100644
--- a/chrome/browser/sync/syncable/directory_backing_store_unittest.cc
+++ b/chrome/browser/sync/syncable/directory_backing_store_unittest.cc
@@ -10,6 +10,7 @@
#include "app/sql/statement.h"
#include "app/sql/transaction.h"
#include "base/file_path.h"
+#include "base/file_util.h"
#include "base/scoped_ptr.h"
#include "base/scoped_temp_dir.h"
#include "base/stl_util-inl.h"
@@ -870,4 +871,27 @@ TEST_F(DirectoryBackingStoreTest, ModelTypeIds) {
}
}
+TEST_F(DirectoryBackingStoreTest, Corruption) {
+ {
+ scoped_ptr<DirectoryBackingStore> dbs(
+ new DirectoryBackingStore(GetUsername(), GetDatabasePath()));
+ EXPECT_TRUE(dbs->BeginLoad());
+ }
+ std::string bad_data("BAD DATA");
+ EXPECT_TRUE(file_util::WriteFile(GetDatabasePath(), bad_data.data(),
+ bad_data.size()));
+ {
+ scoped_ptr<DirectoryBackingStore> dbs(
+ new DirectoryBackingStore(GetUsername(), GetDatabasePath()));
+
+ // In release mode, we expect the sync database to nuke itself and start
+ // over if it detects invalid/corrupted data.
+#if defined(NDEBUG)
+ EXPECT_TRUE(dbs->BeginLoad());
+#else
+ EXPECT_DEATH(dbs->BeginLoad(), "sqlite error");
+#endif
+ }
+}
+
} // namespace syncable