1 // Copyright (c) 2013 The LevelDB Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. See the AUTHORS file for names of contributors.
5 #ifndef THIRD_PARTY_LEVELDATABASE_ENV_CHROMIUM_H_
6 #define THIRD_PARTY_LEVELDATABASE_ENV_CHROMIUM_H_
13 #include "base/files/file.h"
14 #include "base/files/file_path.h"
15 #include "base/metrics/histogram.h"
16 #include "leveldb/env.h"
17 #include "port/port_chromium.h"
18 #include "util/mutexlock.h"
20 namespace leveldb_env
{
22 // These entries map to values in tools/metrics/histograms/histograms.xml. New
23 // values should be appended at the end.
27 kRandomAccessFileRead
,
50 // leveldb::Status::Code values are mapped to these values for UMA logging.
51 // Do not change/delete these values as you will break reporting for older
52 // copies of Chrome. Only add new values to the end.
53 enum LevelDBStatusValue
{
54 LEVELDB_STATUS_OK
= 0,
55 LEVELDB_STATUS_NOT_FOUND
,
56 LEVELDB_STATUS_CORRUPTION
,
57 LEVELDB_STATUS_NOT_SUPPORTED
,
58 LEVELDB_STATUS_INVALID_ARGUMENT
,
59 LEVELDB_STATUS_IO_ERROR
,
63 LevelDBStatusValue
GetLevelDBStatusUMAValue(const leveldb::Status
& s
);
65 // The default value for leveldb::Options::reuse_logs. Currently log reuse is an
66 // experimental feature in leveldb. More info at:
67 // https://github.com/google/leveldb/commit/251ebf5dc70129ad3
68 #if defined(OS_CHROMEOS)
69 // Reusing logs on Chrome OS resulted in an unacceptably high leveldb corruption
70 // rate (at least for Indexed DB). More info at https://crbug.com/460568
71 const bool kDefaultLogReuseOptionValue
= false;
73 const bool kDefaultLogReuseOptionValue
= true;
76 const char* MethodIDToString(MethodID method
);
78 leveldb::Status
MakeIOError(leveldb::Slice filename
,
79 const std::string
& message
,
81 base::File::Error error
);
82 leveldb::Status
MakeIOError(leveldb::Slice filename
,
83 const std::string
& message
,
86 enum ErrorParsingResult
{
92 ErrorParsingResult
ParseMethodAndError(const leveldb::Status
& status
,
94 base::File::Error
* error
);
95 int GetCorruptionCode(const leveldb::Status
& status
);
96 int GetNumCorruptionCodes();
97 std::string
GetCorruptionMessage(const leveldb::Status
& status
);
98 bool IndicatesDiskFull(const leveldb::Status
& status
);
102 virtual void RecordErrorAt(MethodID method
) const = 0;
103 virtual void RecordOSError(MethodID method
,
104 base::File::Error error
) const = 0;
105 virtual void RecordBackupResult(bool success
) const = 0;
108 class RetrierProvider
{
110 virtual int MaxRetryTimeMillis() const = 0;
111 virtual base::HistogramBase
* GetRetryTimeHistogram(MethodID method
) const = 0;
112 virtual base::HistogramBase
* GetRecoveredFromErrorHistogram(
113 MethodID method
) const = 0;
116 class ChromiumEnv
: public leveldb::Env
,
118 public RetrierProvider
{
122 typedef void(ScheduleFunc
)(void*);
124 static bool MakeBackup(const std::string
& fname
);
125 virtual ~ChromiumEnv();
127 virtual bool FileExists(const std::string
& fname
);
128 virtual leveldb::Status
GetChildren(const std::string
& dir
,
129 std::vector
<std::string
>* result
);
130 virtual leveldb::Status
DeleteFile(const std::string
& fname
);
131 virtual leveldb::Status
CreateDir(const std::string
& name
);
132 virtual leveldb::Status
DeleteDir(const std::string
& name
);
133 virtual leveldb::Status
GetFileSize(const std::string
& fname
, uint64_t* size
);
134 virtual leveldb::Status
RenameFile(const std::string
& src
,
135 const std::string
& dst
);
136 virtual leveldb::Status
LockFile(const std::string
& fname
,
137 leveldb::FileLock
** lock
);
138 virtual leveldb::Status
UnlockFile(leveldb::FileLock
* lock
);
139 virtual void Schedule(ScheduleFunc
*, void* arg
);
140 virtual void StartThread(void (*function
)(void* arg
), void* arg
);
141 virtual leveldb::Status
GetTestDirectory(std::string
* path
);
142 virtual uint64_t NowMicros();
143 virtual void SleepForMicroseconds(int micros
);
144 virtual leveldb::Status
NewSequentialFile(const std::string
& fname
,
145 leveldb::SequentialFile
** result
);
146 virtual leveldb::Status
NewRandomAccessFile(
147 const std::string
& fname
,
148 leveldb::RandomAccessFile
** result
);
149 virtual leveldb::Status
NewWritableFile(const std::string
& fname
,
150 leveldb::WritableFile
** result
);
151 virtual leveldb::Status
NewAppendableFile(const std::string
& fname
,
152 leveldb::WritableFile
** result
);
153 virtual leveldb::Status
NewLogger(const std::string
& fname
,
154 leveldb::Logger
** result
);
157 ChromiumEnv(const std::string
& name
, bool make_backup
);
160 static const char* FileErrorString(base::File::Error error
);
162 virtual void RecordErrorAt(MethodID method
) const;
163 virtual void RecordOSError(MethodID method
,
164 base::File::Error error
) const;
165 void RecordOpenFilesLimit(const std::string
& type
);
166 base::HistogramBase
* GetMaxFDHistogram(const std::string
& type
) const;
167 base::HistogramBase
* GetOSErrorHistogram(MethodID method
, int limit
) const;
169 // File locks may not be exclusive within a process (e.g. on POSIX). Track
170 // locks held by the ChromiumEnv to prevent access within the process.
173 bool Insert(const std::string
& fname
) {
174 leveldb::MutexLock
l(&mu_
);
175 return locked_files_
.insert(fname
).second
;
177 bool Remove(const std::string
& fname
) {
178 leveldb::MutexLock
l(&mu_
);
179 return locked_files_
.erase(fname
) == 1;
182 leveldb::port::Mutex mu_
;
183 std::set
<std::string
> locked_files_
;
186 const int kMaxRetryTimeMillis
;
187 // BGThread() is the body of the background thread
189 static void BGThreadWrapper(void* arg
) {
190 reinterpret_cast<ChromiumEnv
*>(arg
)->BGThread();
193 virtual void RecordBackupResult(bool result
) const;
194 void RestoreIfNecessary(const std::string
& dir
,
195 std::vector
<std::string
>* children
);
196 base::FilePath
RestoreFromBackup(const base::FilePath
& base_name
);
197 void RecordLockFileAncestors(int num_missing_ancestors
) const;
198 base::HistogramBase
* GetMethodIOErrorHistogram() const;
199 base::HistogramBase
* GetLockFileAncestorHistogram() const;
201 // RetrierProvider implementation.
202 virtual int MaxRetryTimeMillis() const { return kMaxRetryTimeMillis
; }
203 virtual base::HistogramBase
* GetRetryTimeHistogram(MethodID method
) const;
204 virtual base::HistogramBase
* GetRecoveredFromErrorHistogram(
205 MethodID method
) const;
207 base::FilePath test_directory_
;
210 std::string uma_ioerror_base_name_
;
214 base::ConditionVariable bgsignal_
;
215 bool started_bgthread_
;
217 // Entry per Schedule() call
220 void (*function
)(void*);
222 typedef std::deque
<BGItem
> BGQueue
;
227 } // namespace leveldb_env
229 #endif // THIRD_PARTY_LEVELDATABASE_ENV_CHROMIUM_H_