]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/env/env.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / rocksdb / env / env.cc
CommitLineData
7c673cae 1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
11fdf7f2
TL
2// This source code is licensed under both the GPLv2 (found in the
3// COPYING file in the root directory) and Apache 2.0 License
4// (found in the LICENSE.Apache file in the root directory).
7c673cae
FG
5//
6// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
7// Use of this source code is governed by a BSD-style license that can be
8// found in the LICENSE file. See the AUTHORS file for names of contributors.
9
10#include "rocksdb/env.h"
11
12#include <thread>
f67539c2
TL
13#include "env/composite_env_wrapper.h"
14#include "logging/env_logger.h"
15#include "memory/arena.h"
7c673cae
FG
16#include "options/db_options.h"
17#include "port/port.h"
18#include "port/sys_time.h"
19#include "rocksdb/options.h"
f67539c2 20#include "rocksdb/utilities/object_registry.h"
7c673cae
FG
21#include "util/autovector.h"
22
f67539c2 23namespace ROCKSDB_NAMESPACE {
7c673cae
FG
24
25Env::~Env() {
26}
27
f67539c2
TL
28Status Env::NewLogger(const std::string& fname,
29 std::shared_ptr<Logger>* result) {
30 return NewEnvLogger(fname, this, result);
31}
32
33Status Env::LoadEnv(const std::string& value, Env** result) {
34 Env* env = *result;
35 Status s;
36#ifndef ROCKSDB_LITE
37 s = ObjectRegistry::NewInstance()->NewStaticObject<Env>(value, &env);
38#else
39 s = Status::NotSupported("Cannot load environment in LITE mode: ", value);
40#endif
41 if (s.ok()) {
42 *result = env;
43 }
44 return s;
45}
46
47Status Env::LoadEnv(const std::string& value, Env** result,
48 std::shared_ptr<Env>* guard) {
49 assert(result);
50 Status s;
51#ifndef ROCKSDB_LITE
52 Env* env = nullptr;
53 std::unique_ptr<Env> uniq_guard;
54 std::string err_msg;
55 assert(guard != nullptr);
56 env = ObjectRegistry::NewInstance()->NewObject<Env>(value, &uniq_guard,
57 &err_msg);
58 if (!env) {
59 s = Status::NotFound(std::string("Cannot load ") + Env::Type() + ": " +
60 value);
61 env = Env::Default();
62 }
63 if (s.ok() && uniq_guard) {
64 guard->reset(uniq_guard.release());
65 *result = guard->get();
66 } else {
67 *result = env;
68 }
69#else
70 (void)result;
71 (void)guard;
72 s = Status::NotSupported("Cannot load environment in LITE mode: ", value);
73#endif
74 return s;
75}
76
11fdf7f2
TL
77std::string Env::PriorityToString(Env::Priority priority) {
78 switch (priority) {
79 case Env::Priority::BOTTOM:
80 return "Bottom";
81 case Env::Priority::LOW:
82 return "Low";
83 case Env::Priority::HIGH:
84 return "High";
494da23a
TL
85 case Env::Priority::USER:
86 return "User";
11fdf7f2
TL
87 case Env::Priority::TOTAL:
88 assert(false);
89 }
90 return "Invalid";
91}
92
7c673cae
FG
93uint64_t Env::GetThreadID() const {
94 std::hash<std::thread::id> hasher;
95 return hasher(std::this_thread::get_id());
96}
97
98Status Env::ReuseWritableFile(const std::string& fname,
99 const std::string& old_fname,
494da23a 100 std::unique_ptr<WritableFile>* result,
7c673cae
FG
101 const EnvOptions& options) {
102 Status s = RenameFile(old_fname, fname);
103 if (!s.ok()) {
104 return s;
105 }
106 return NewWritableFile(fname, result, options);
107}
108
109Status Env::GetChildrenFileAttributes(const std::string& dir,
110 std::vector<FileAttributes>* result) {
111 assert(result != nullptr);
112 std::vector<std::string> child_fnames;
113 Status s = GetChildren(dir, &child_fnames);
114 if (!s.ok()) {
115 return s;
116 }
117 result->resize(child_fnames.size());
118 size_t result_size = 0;
119 for (size_t i = 0; i < child_fnames.size(); ++i) {
120 const std::string path = dir + "/" + child_fnames[i];
121 if (!(s = GetFileSize(path, &(*result)[result_size].size_bytes)).ok()) {
122 if (FileExists(path).IsNotFound()) {
123 // The file may have been deleted since we listed the directory
124 continue;
125 }
126 return s;
127 }
128 (*result)[result_size].name = std::move(child_fnames[i]);
129 result_size++;
130 }
131 result->resize(result_size);
132 return Status::OK();
133}
134
135SequentialFile::~SequentialFile() {
136}
137
138RandomAccessFile::~RandomAccessFile() {
139}
140
141WritableFile::~WritableFile() {
142}
143
11fdf7f2
TL
144MemoryMappedFileBuffer::~MemoryMappedFileBuffer() {}
145
146Logger::~Logger() {}
147
148Status Logger::Close() {
149 if (!closed_) {
150 closed_ = true;
151 return CloseImpl();
152 } else {
153 return Status::OK();
154 }
7c673cae
FG
155}
156
11fdf7f2
TL
157Status Logger::CloseImpl() { return Status::NotSupported(); }
158
7c673cae
FG
159FileLock::~FileLock() {
160}
161
162void LogFlush(Logger *info_log) {
163 if (info_log) {
164 info_log->Flush();
165 }
166}
167
11fdf7f2 168static void Logv(Logger *info_log, const char* format, va_list ap) {
7c673cae 169 if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::INFO_LEVEL) {
7c673cae 170 info_log->Logv(InfoLogLevel::INFO_LEVEL, format, ap);
7c673cae
FG
171 }
172}
173
11fdf7f2
TL
174void Log(Logger* info_log, const char* format, ...) {
175 va_list ap;
176 va_start(ap, format);
177 Logv(info_log, format, ap);
178 va_end(ap);
179}
180
7c673cae
FG
181void Logger::Logv(const InfoLogLevel log_level, const char* format, va_list ap) {
182 static const char* kInfoLogLevelNames[5] = { "DEBUG", "INFO", "WARN",
183 "ERROR", "FATAL" };
184 if (log_level < log_level_) {
185 return;
186 }
187
188 if (log_level == InfoLogLevel::INFO_LEVEL) {
189 // Doesn't print log level if it is INFO level.
190 // This is to avoid unexpected performance regression after we add
191 // the feature of log level. All the logs before we add the feature
192 // are INFO level. We don't want to add extra costs to those existing
193 // logging.
194 Logv(format, ap);
494da23a
TL
195 } else if (log_level == InfoLogLevel::HEADER_LEVEL) {
196 LogHeader(format, ap);
7c673cae
FG
197 } else {
198 char new_format[500];
199 snprintf(new_format, sizeof(new_format) - 1, "[%s] %s",
200 kInfoLogLevelNames[log_level], format);
201 Logv(new_format, ap);
202 }
203}
204
11fdf7f2 205static void Logv(const InfoLogLevel log_level, Logger *info_log, const char *format, va_list ap) {
7c673cae 206 if (info_log && info_log->GetInfoLogLevel() <= log_level) {
7c673cae
FG
207 if (log_level == InfoLogLevel::HEADER_LEVEL) {
208 info_log->LogHeader(format, ap);
209 } else {
210 info_log->Logv(log_level, format, ap);
211 }
7c673cae
FG
212 }
213}
214
11fdf7f2
TL
215void Log(const InfoLogLevel log_level, Logger* info_log, const char* format,
216 ...) {
217 va_list ap;
218 va_start(ap, format);
219 Logv(log_level, info_log, format, ap);
220 va_end(ap);
221}
222
223static void Headerv(Logger *info_log, const char *format, va_list ap) {
7c673cae 224 if (info_log) {
7c673cae 225 info_log->LogHeader(format, ap);
7c673cae
FG
226 }
227}
228
11fdf7f2
TL
229void Header(Logger* info_log, const char* format, ...) {
230 va_list ap;
231 va_start(ap, format);
232 Headerv(info_log, format, ap);
233 va_end(ap);
234}
235
236static void Debugv(Logger* info_log, const char* format, va_list ap) {
7c673cae 237 if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::DEBUG_LEVEL) {
7c673cae 238 info_log->Logv(InfoLogLevel::DEBUG_LEVEL, format, ap);
7c673cae
FG
239 }
240}
241
11fdf7f2
TL
242void Debug(Logger* info_log, const char* format, ...) {
243 va_list ap;
244 va_start(ap, format);
245 Debugv(info_log, format, ap);
246 va_end(ap);
247}
248
249static void Infov(Logger* info_log, const char* format, va_list ap) {
7c673cae 250 if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::INFO_LEVEL) {
7c673cae 251 info_log->Logv(InfoLogLevel::INFO_LEVEL, format, ap);
7c673cae
FG
252 }
253}
254
11fdf7f2
TL
255void Info(Logger* info_log, const char* format, ...) {
256 va_list ap;
257 va_start(ap, format);
258 Infov(info_log, format, ap);
259 va_end(ap);
260}
261
262static void Warnv(Logger* info_log, const char* format, va_list ap) {
7c673cae 263 if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::WARN_LEVEL) {
7c673cae 264 info_log->Logv(InfoLogLevel::WARN_LEVEL, format, ap);
7c673cae
FG
265 }
266}
11fdf7f2
TL
267
268void Warn(Logger* info_log, const char* format, ...) {
269 va_list ap;
270 va_start(ap, format);
271 Warnv(info_log, format, ap);
272 va_end(ap);
273}
274
275static void Errorv(Logger* info_log, const char* format, va_list ap) {
7c673cae 276 if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::ERROR_LEVEL) {
7c673cae 277 info_log->Logv(InfoLogLevel::ERROR_LEVEL, format, ap);
7c673cae
FG
278 }
279}
11fdf7f2
TL
280
281void Error(Logger* info_log, const char* format, ...) {
282 va_list ap;
283 va_start(ap, format);
284 Errorv(info_log, format, ap);
285 va_end(ap);
286}
287
288static void Fatalv(Logger* info_log, const char* format, va_list ap) {
7c673cae 289 if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::FATAL_LEVEL) {
7c673cae 290 info_log->Logv(InfoLogLevel::FATAL_LEVEL, format, ap);
7c673cae
FG
291 }
292}
293
11fdf7f2
TL
294void Fatal(Logger* info_log, const char* format, ...) {
295 va_list ap;
296 va_start(ap, format);
297 Fatalv(info_log, format, ap);
298 va_end(ap);
299}
300
494da23a 301void LogFlush(const std::shared_ptr<Logger>& info_log) {
11fdf7f2 302 LogFlush(info_log.get());
7c673cae
FG
303}
304
494da23a 305void Log(const InfoLogLevel log_level, const std::shared_ptr<Logger>& info_log,
7c673cae 306 const char* format, ...) {
11fdf7f2
TL
307 va_list ap;
308 va_start(ap, format);
309 Logv(log_level, info_log.get(), format, ap);
310 va_end(ap);
7c673cae
FG
311}
312
494da23a 313void Header(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
11fdf7f2
TL
314 va_list ap;
315 va_start(ap, format);
316 Headerv(info_log.get(), format, ap);
317 va_end(ap);
7c673cae
FG
318}
319
494da23a 320void Debug(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
11fdf7f2
TL
321 va_list ap;
322 va_start(ap, format);
323 Debugv(info_log.get(), format, ap);
324 va_end(ap);
7c673cae
FG
325}
326
494da23a 327void Info(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
11fdf7f2
TL
328 va_list ap;
329 va_start(ap, format);
330 Infov(info_log.get(), format, ap);
331 va_end(ap);
7c673cae
FG
332}
333
494da23a 334void Warn(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
11fdf7f2
TL
335 va_list ap;
336 va_start(ap, format);
337 Warnv(info_log.get(), format, ap);
338 va_end(ap);
7c673cae
FG
339}
340
494da23a 341void Error(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
11fdf7f2
TL
342 va_list ap;
343 va_start(ap, format);
344 Errorv(info_log.get(), format, ap);
345 va_end(ap);
7c673cae
FG
346}
347
494da23a 348void Fatal(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
11fdf7f2
TL
349 va_list ap;
350 va_start(ap, format);
351 Fatalv(info_log.get(), format, ap);
352 va_end(ap);
7c673cae
FG
353}
354
494da23a 355void Log(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
11fdf7f2
TL
356 va_list ap;
357 va_start(ap, format);
358 Logv(info_log.get(), format, ap);
359 va_end(ap);
7c673cae
FG
360}
361
362Status WriteStringToFile(Env* env, const Slice& data, const std::string& fname,
363 bool should_sync) {
494da23a 364 std::unique_ptr<WritableFile> file;
7c673cae
FG
365 EnvOptions soptions;
366 Status s = env->NewWritableFile(fname, &file, soptions);
367 if (!s.ok()) {
368 return s;
369 }
370 s = file->Append(data);
371 if (s.ok() && should_sync) {
372 s = file->Sync();
373 }
374 if (!s.ok()) {
375 env->DeleteFile(fname);
376 }
377 return s;
378}
379
380Status ReadFileToString(Env* env, const std::string& fname, std::string* data) {
f67539c2
TL
381 LegacyFileSystemWrapper lfsw(env);
382 return ReadFileToString(&lfsw, fname, data);
7c673cae
FG
383}
384
385EnvWrapper::~EnvWrapper() {
386}
387
388namespace { // anonymous namespace
389
390void AssignEnvOptions(EnvOptions* env_options, const DBOptions& options) {
391 env_options->use_mmap_reads = options.allow_mmap_reads;
392 env_options->use_mmap_writes = options.allow_mmap_writes;
393 env_options->use_direct_reads = options.use_direct_reads;
394 env_options->set_fd_cloexec = options.is_fd_close_on_exec;
395 env_options->bytes_per_sync = options.bytes_per_sync;
396 env_options->compaction_readahead_size = options.compaction_readahead_size;
397 env_options->random_access_max_buffer_size =
398 options.random_access_max_buffer_size;
399 env_options->rate_limiter = options.rate_limiter.get();
400 env_options->writable_file_max_buffer_size =
401 options.writable_file_max_buffer_size;
402 env_options->allow_fallocate = options.allow_fallocate;
f67539c2
TL
403 env_options->strict_bytes_per_sync = options.strict_bytes_per_sync;
404 options.env->SanitizeEnvOptions(env_options);
7c673cae
FG
405}
406
407}
408
409EnvOptions Env::OptimizeForLogWrite(const EnvOptions& env_options,
410 const DBOptions& db_options) const {
411 EnvOptions optimized_env_options(env_options);
412 optimized_env_options.bytes_per_sync = db_options.wal_bytes_per_sync;
11fdf7f2
TL
413 optimized_env_options.writable_file_max_buffer_size =
414 db_options.writable_file_max_buffer_size;
7c673cae
FG
415 return optimized_env_options;
416}
417
418EnvOptions Env::OptimizeForManifestWrite(const EnvOptions& env_options) const {
419 return env_options;
420}
421
11fdf7f2
TL
422EnvOptions Env::OptimizeForLogRead(const EnvOptions& env_options) const {
423 EnvOptions optimized_env_options(env_options);
424 optimized_env_options.use_direct_reads = false;
425 return optimized_env_options;
426}
427
428EnvOptions Env::OptimizeForManifestRead(const EnvOptions& env_options) const {
429 EnvOptions optimized_env_options(env_options);
430 optimized_env_options.use_direct_reads = false;
431 return optimized_env_options;
432}
433
7c673cae
FG
434EnvOptions Env::OptimizeForCompactionTableWrite(
435 const EnvOptions& env_options, const ImmutableDBOptions& db_options) const {
436 EnvOptions optimized_env_options(env_options);
437 optimized_env_options.use_direct_writes =
438 db_options.use_direct_io_for_flush_and_compaction;
439 return optimized_env_options;
440}
441
442EnvOptions Env::OptimizeForCompactionTableRead(
443 const EnvOptions& env_options, const ImmutableDBOptions& db_options) const {
444 EnvOptions optimized_env_options(env_options);
11fdf7f2 445 optimized_env_options.use_direct_reads = db_options.use_direct_reads;
7c673cae
FG
446 return optimized_env_options;
447}
448
449EnvOptions::EnvOptions(const DBOptions& options) {
450 AssignEnvOptions(this, options);
451}
452
453EnvOptions::EnvOptions() {
454 DBOptions options;
455 AssignEnvOptions(this, options);
456}
457
f67539c2
TL
458Status NewEnvLogger(const std::string& fname, Env* env,
459 std::shared_ptr<Logger>* result) {
460 EnvOptions options;
461 // TODO: Tune the buffer size.
462 options.writable_file_max_buffer_size = 1024 * 1024;
463 std::unique_ptr<WritableFile> writable_file;
464 const auto status = env->NewWritableFile(fname, &writable_file, options);
465 if (!status.ok()) {
466 return status;
467 }
468
469 *result = std::make_shared<EnvLogger>(
470 NewLegacyWritableFileWrapper(std::move(writable_file)), fname, options,
471 env);
472 return Status::OK();
473}
7c673cae 474
f67539c2 475} // namespace ROCKSDB_NAMESPACE