Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: sync/syncable/on_disk_directory_backing_store.cc

Issue 10821121: sync: Attempt to recover from directory corruption (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix other win compile warning Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "sync/syncable/on_disk_directory_backing_store.h" 5 #include "sync/syncable/on_disk_directory_backing_store.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/metrics/histogram.h"
9 #include "sync/syncable/syncable-inl.h"
8 10
9 namespace syncer { 11 namespace syncer {
10 namespace syncable { 12 namespace syncable {
11 13
14 namespace {
15
16 enum HistogramResultEnum {
17 FIRST_TRY_SUCCESS,
18 SECOND_TRY_SUCCESS,
19 SECOND_TRY_FAILURE,
20 RESULT_COUNT
21 };
22
23 } // namespace
24
12 OnDiskDirectoryBackingStore::OnDiskDirectoryBackingStore( 25 OnDiskDirectoryBackingStore::OnDiskDirectoryBackingStore(
13 const std::string& dir_name, const FilePath& backing_filepath) 26 const std::string& dir_name, const FilePath& backing_filepath)
14 : DirectoryBackingStore(dir_name), 27 : DirectoryBackingStore(dir_name),
28 allow_failure_for_test_(false),
15 backing_filepath_(backing_filepath) { 29 backing_filepath_(backing_filepath) {
16 db_->set_exclusive_locking(); 30 db_->set_exclusive_locking();
17 db_->set_page_size(4096); 31 db_->set_page_size(4096);
18 } 32 }
19 33
20 DirOpenResult OnDiskDirectoryBackingStore::Load( 34 OnDiskDirectoryBackingStore::~OnDiskDirectoryBackingStore() { }
35
36 DirOpenResult OnDiskDirectoryBackingStore::TryLoad(
21 MetahandlesIndex* entry_bucket, 37 MetahandlesIndex* entry_bucket,
22 Directory::KernelLoadInfo* kernel_load_info) { 38 Directory::KernelLoadInfo* kernel_load_info) {
23 DCHECK(CalledOnValidThread()); 39 DCHECK(CalledOnValidThread());
24 if (!db_->is_open()) { 40 if (!db_->is_open()) {
25 if (!db_->Open(backing_filepath_)) 41 if (!db_->Open(backing_filepath_))
26 return FAILED_OPEN_DATABASE; 42 return FAILED_OPEN_DATABASE;
27 } 43 }
28 44
29 if (!InitializeTables()) 45 if (!InitializeTables())
30 return FAILED_OPEN_DATABASE; 46 return FAILED_OPEN_DATABASE;
31 47
32 if (!DropDeletedEntries()) 48 if (!DropDeletedEntries())
33 return FAILED_DATABASE_CORRUPT; 49 return FAILED_DATABASE_CORRUPT;
34 if (!LoadEntries(entry_bucket)) 50 if (!LoadEntries(entry_bucket))
35 return FAILED_DATABASE_CORRUPT; 51 return FAILED_DATABASE_CORRUPT;
36 if (!LoadInfo(kernel_load_info)) 52 if (!LoadInfo(kernel_load_info))
37 return FAILED_DATABASE_CORRUPT; 53 return FAILED_DATABASE_CORRUPT;
54 if (!VerifyReferenceIntegrity(*entry_bucket))
55 return FAILED_DATABASE_CORRUPT;
38 56
39 return OPENED; 57 return OPENED;
58
59 }
60
61 DirOpenResult OnDiskDirectoryBackingStore::Load(
62 MetahandlesIndex* entry_bucket,
63 Directory::KernelLoadInfo* kernel_load_info) {
64 DirOpenResult result = TryLoad(entry_bucket, kernel_load_info);
65 if (result == OPENED) {
66 HISTOGRAM_ENUMERATION(
67 "Sync.DirectoryOpenResult", FIRST_TRY_SUCCESS, RESULT_COUNT);
68 return OPENED;
69 }
70
71 ReportFirstTryOpenFailure();
72
73 // The fallback: delete the current database and return a fresh one. We can
74 // fetch the user's data from the could.
75 entry_bucket->clear();
76 db_.reset(new sql::Connection);
77 file_util::Delete(backing_filepath_, false);
78
79 result = TryLoad(entry_bucket, kernel_load_info);
80 if (result == OPENED) {
81 HISTOGRAM_ENUMERATION(
82 "Sync.DirectoryOpenResult", SECOND_TRY_SUCCESS, RESULT_COUNT);
83 } else {
84 HISTOGRAM_ENUMERATION(
85 "Sync.DirectoryOpenResult", SECOND_TRY_FAILURE, RESULT_COUNT);
86 }
87
88 return result;
89 }
90
91 void OnDiskDirectoryBackingStore::ReportFirstTryOpenFailure() {
92 // In debug builds, the last thing we want is to silently clear the database.
93 // It's full of evidence that might help us determine what went wrong. It
94 // might be sqlite's fault, but it could also be a bug in sync. We crash
95 // immediately so a developer can investigate.
96 //
97 // Developers: If you're not interested in debugging this right now, just move
98 // aside the 'Sync Data' directory in your profile. This is similar to what
99 // the code would do if this DCHECK were disabled.
100 NOTREACHED() << "Crashing to preserve corrupt sync database";
40 } 101 }
41 102
42 } // namespace syncable 103 } // namespace syncable
43 } // namespace syncer 104 } // namespace syncer
OLDNEW
« no previous file with comments | « sync/syncable/on_disk_directory_backing_store.h ('k') | sync/test/test_directory_backing_store.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698