| OLD | NEW |
| 1 // Copyright (c) 2011 The LevelDB Authors. All rights reserved. | 1 // Copyright (c) 2011 The LevelDB 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. See the AUTHORS file for names of contributors. | 3 // found in the LICENSE file. See the AUTHORS file for names of contributors. |
| 4 | 4 |
| 5 #include "third_party/leveldatabase/env_chromium.h" | 5 #include "third_party/leveldatabase/env_chromium.h" |
| 6 | 6 |
| 7 #if defined(OS_POSIX) | 7 #if defined(OS_POSIX) |
| 8 #include <dirent.h> | 8 #include <dirent.h> |
| 9 #include <sys/types.h> | 9 #include <sys/types.h> |
| 10 #endif | 10 #endif |
| 11 | 11 |
| 12 #include "base/files/file_util.h" | 12 #include "base/files/file_util.h" |
| 13 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
| 14 #include "base/memory/shared_memory.h" | 14 #include "base/memory/shared_memory.h" |
| 15 #include "base/metrics/histogram.h" | 15 #include "base/metrics/histogram.h" |
| 16 #include "base/process/process_metrics.h" | 16 #include "base/process/process_metrics.h" |
| 17 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
| 18 #include "base/strings/stringprintf.h" |
| 18 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
| 19 #include "base/trace_event/trace_event.h" | 20 #include "base/trace_event/trace_event.h" |
| 20 #include "third_party/leveldatabase/chromium_logger.h" | 21 #include "third_party/leveldatabase/chromium_logger.h" |
| 21 #include "third_party/re2/re2/re2.h" | 22 #include "third_party/re2/re2/re2.h" |
| 22 | 23 |
| 23 using base::FilePath; | 24 using base::FilePath; |
| 24 using leveldb::FileLock; | 25 using leveldb::FileLock; |
| 25 using leveldb::Slice; | 26 using leveldb::Slice; |
| 26 using leveldb::Status; | 27 using leveldb::Status; |
| 27 | 28 |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 if (file_type_ == kManifest) | 313 if (file_type_ == kManifest) |
| 313 return SyncParent(); | 314 return SyncParent(); |
| 314 | 315 |
| 315 return Status::OK(); | 316 return Status::OK(); |
| 316 } | 317 } |
| 317 | 318 |
| 318 class IDBEnv : public ChromiumEnv { | 319 class IDBEnv : public ChromiumEnv { |
| 319 public: | 320 public: |
| 320 IDBEnv() : ChromiumEnv() { | 321 IDBEnv() : ChromiumEnv() { |
| 321 name_ = "LevelDBEnv.IDB"; | 322 name_ = "LevelDBEnv.IDB"; |
| 323 uma_ioerror_base_name_ = name_ + ".IOError.BFE"; |
| 322 make_backup_ = true; | 324 make_backup_ = true; |
| 323 } | 325 } |
| 324 }; | 326 }; |
| 325 | 327 |
| 326 base::LazyInstance<IDBEnv>::Leaky idb_env = LAZY_INSTANCE_INITIALIZER; | 328 base::LazyInstance<IDBEnv>::Leaky idb_env = LAZY_INSTANCE_INITIALIZER; |
| 327 | 329 |
| 328 base::LazyInstance<ChromiumEnv>::Leaky default_env = LAZY_INSTANCE_INITIALIZER; | 330 base::LazyInstance<ChromiumEnv>::Leaky default_env = LAZY_INSTANCE_INITIALIZER; |
| 329 | 331 |
| 330 } // unnamed namespace | 332 } // unnamed namespace |
| 331 | 333 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 NOTREACHED(); | 384 NOTREACHED(); |
| 383 return "Unknown"; | 385 return "Unknown"; |
| 384 } | 386 } |
| 385 | 387 |
| 386 Status MakeIOError(Slice filename, | 388 Status MakeIOError(Slice filename, |
| 387 const std::string& message, | 389 const std::string& message, |
| 388 MethodID method, | 390 MethodID method, |
| 389 base::File::Error error) { | 391 base::File::Error error) { |
| 390 DCHECK_LT(error, 0); | 392 DCHECK_LT(error, 0); |
| 391 char buf[512]; | 393 char buf[512]; |
| 392 snprintf(buf, sizeof(buf), "%s (ChromeMethodPFE: %d::%s::%d)", | 394 snprintf(buf, sizeof(buf), "%s (ChromeMethodBFE: %d::%s::%d)", |
| 393 message.c_str(), method, MethodIDToString(method), -error); | 395 message.c_str(), method, MethodIDToString(method), -error); |
| 394 return Status::IOError(filename, buf); | 396 return Status::IOError(filename, buf); |
| 395 } | 397 } |
| 396 | 398 |
| 397 Status MakeIOError(Slice filename, | 399 Status MakeIOError(Slice filename, |
| 398 const std::string& message, | 400 const std::string& message, |
| 399 MethodID method) { | 401 MethodID method) { |
| 400 char buf[512]; | 402 char buf[512]; |
| 401 snprintf(buf, sizeof(buf), "%s (ChromeMethodOnly: %d::%s)", message.c_str(), | 403 snprintf(buf, sizeof(buf), "%s (ChromeMethodOnly: %d::%s)", message.c_str(), |
| 402 method, MethodIDToString(method)); | 404 method, MethodIDToString(method)); |
| 403 return Status::IOError(filename, buf); | 405 return Status::IOError(filename, buf); |
| 404 } | 406 } |
| 405 | 407 |
| 406 ErrorParsingResult ParseMethodAndError(const leveldb::Status& status, | 408 ErrorParsingResult ParseMethodAndError(const leveldb::Status& status, |
| 407 MethodID* method_param, | 409 MethodID* method_param, |
| 408 base::File::Error* error) { | 410 base::File::Error* error) { |
| 409 const std::string status_string = status.ToString(); | 411 const std::string status_string = status.ToString(); |
| 410 int method; | 412 int method; |
| 411 if (RE2::PartialMatch(status_string.c_str(), "ChromeMethodOnly: (\\d+)", | 413 if (RE2::PartialMatch(status_string.c_str(), "ChromeMethodOnly: (\\d+)", |
| 412 &method)) { | 414 &method)) { |
| 413 *method_param = static_cast<MethodID>(method); | 415 *method_param = static_cast<MethodID>(method); |
| 414 return METHOD_ONLY; | 416 return METHOD_ONLY; |
| 415 } | 417 } |
| 416 int parsed_error; | 418 int parsed_error; |
| 417 if (RE2::PartialMatch(status_string.c_str(), | 419 if (RE2::PartialMatch(status_string.c_str(), |
| 418 "ChromeMethodPFE: (\\d+)::.*::(\\d+)", &method, | 420 "ChromeMethodBFE: (\\d+)::.*::(\\d+)", &method, |
| 419 &parsed_error)) { | 421 &parsed_error)) { |
| 420 *method_param = static_cast<MethodID>(method); | 422 *method_param = static_cast<MethodID>(method); |
| 421 *error = static_cast<base::File::Error>(-parsed_error); | 423 *error = static_cast<base::File::Error>(-parsed_error); |
| 422 DCHECK_LT(*error, base::File::FILE_OK); | 424 DCHECK_LT(*error, base::File::FILE_OK); |
| 423 DCHECK_GT(*error, base::File::FILE_ERROR_MAX); | 425 DCHECK_GT(*error, base::File::FILE_ERROR_MAX); |
| 424 return METHOD_AND_PFE; | 426 return METHOD_AND_BFE; |
| 425 } | 427 } |
| 426 return NONE; | 428 return NONE; |
| 427 } | 429 } |
| 428 | 430 |
| 429 // Keep in sync with LevelDBCorruptionTypes in histograms.xml. Also, don't | 431 // Keep in sync with LevelDBCorruptionTypes in histograms.xml. Also, don't |
| 430 // change the order because indices into this array have been recorded in uma | 432 // change the order because indices into this array have been recorded in uma |
| 431 // histograms. | 433 // histograms. |
| 432 const char* patterns[] = { | 434 const char* patterns[] = { |
| 433 "missing files", | 435 "missing files", |
| 434 "log record too small", | 436 "log record too small", |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 return patterns[code - 1]; | 495 return patterns[code - 1]; |
| 494 } | 496 } |
| 495 | 497 |
| 496 bool IndicatesDiskFull(const leveldb::Status& status) { | 498 bool IndicatesDiskFull(const leveldb::Status& status) { |
| 497 if (status.ok()) | 499 if (status.ok()) |
| 498 return false; | 500 return false; |
| 499 leveldb_env::MethodID method; | 501 leveldb_env::MethodID method; |
| 500 base::File::Error error = base::File::FILE_OK; | 502 base::File::Error error = base::File::FILE_OK; |
| 501 leveldb_env::ErrorParsingResult result = | 503 leveldb_env::ErrorParsingResult result = |
| 502 leveldb_env::ParseMethodAndError(status, &method, &error); | 504 leveldb_env::ParseMethodAndError(status, &method, &error); |
| 503 return (result == leveldb_env::METHOD_AND_PFE && | 505 return (result == leveldb_env::METHOD_AND_BFE && |
| 504 static_cast<base::File::Error>(error) == | 506 static_cast<base::File::Error>(error) == |
| 505 base::File::FILE_ERROR_NO_SPACE); | 507 base::File::FILE_ERROR_NO_SPACE); |
| 506 } | 508 } |
| 507 | 509 |
| 508 bool ChromiumEnv::MakeBackup(const std::string& fname) { | 510 bool ChromiumEnv::MakeBackup(const std::string& fname) { |
| 509 FilePath original_table_name = FilePath::FromUTF8Unsafe(fname); | 511 FilePath original_table_name = FilePath::FromUTF8Unsafe(fname); |
| 510 FilePath backup_table_name = | 512 FilePath backup_table_name = |
| 511 original_table_name.ReplaceExtension(backup_table_extension); | 513 original_table_name.ReplaceExtension(backup_table_extension); |
| 512 return base::CopyFile(original_table_name, backup_table_name); | 514 return base::CopyFile(original_table_name, backup_table_name); |
| 513 } | 515 } |
| 514 | 516 |
| 515 ChromiumEnv::ChromiumEnv() | 517 ChromiumEnv::ChromiumEnv() |
| 516 : name_("LevelDBEnv"), | 518 : name_("LevelDBEnv"), |
| 517 make_backup_(false), | 519 make_backup_(false), |
| 518 bgsignal_(&mu_), | 520 bgsignal_(&mu_), |
| 519 started_bgthread_(false), | 521 started_bgthread_(false), |
| 520 kMaxRetryTimeMillis(1000) { | 522 kMaxRetryTimeMillis(1000) { |
| 523 uma_ioerror_base_name_ = name_ + ".IOError.BFE"; |
| 521 } | 524 } |
| 522 | 525 |
| 523 ChromiumEnv::~ChromiumEnv() { | 526 ChromiumEnv::~ChromiumEnv() { |
| 524 // In chromium, ChromiumEnv is leaked. It'd be nice to add NOTREACHED here to | 527 // In chromium, ChromiumEnv is leaked. It'd be nice to add NOTREACHED here to |
| 525 // ensure that behavior isn't accidentally changed, but there's an instance in | 528 // ensure that behavior isn't accidentally changed, but there's an instance in |
| 526 // a unit test that is deleted. | 529 // a unit test that is deleted. |
| 527 } | 530 } |
| 528 | 531 |
| 529 bool ChromiumEnv::FileExists(const std::string& fname) { | 532 bool ChromiumEnv::FileExists(const std::string& fname) { |
| 530 return base::PathExists(FilePath::FromUTF8Unsafe(fname)); | 533 return base::PathExists(FilePath::FromUTF8Unsafe(fname)); |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 927 | 930 |
| 928 void ChromiumEnv::RecordBackupResult(bool result) const { | 931 void ChromiumEnv::RecordBackupResult(bool result) const { |
| 929 std::string uma_name(name_); | 932 std::string uma_name(name_); |
| 930 uma_name.append(".TableBackup"); | 933 uma_name.append(".TableBackup"); |
| 931 base::BooleanHistogram::FactoryGet( | 934 base::BooleanHistogram::FactoryGet( |
| 932 uma_name, base::Histogram::kUmaTargetedHistogramFlag)->AddBoolean(result); | 935 uma_name, base::Histogram::kUmaTargetedHistogramFlag)->AddBoolean(result); |
| 933 } | 936 } |
| 934 | 937 |
| 935 base::HistogramBase* ChromiumEnv::GetOSErrorHistogram(MethodID method, | 938 base::HistogramBase* ChromiumEnv::GetOSErrorHistogram(MethodID method, |
| 936 int limit) const { | 939 int limit) const { |
| 937 std::string uma_name(name_); | 940 std::string uma_name; |
| 938 // TODO(dgrogan): This is probably not the best way to concatenate strings. | 941 base::StringAppendF(&uma_name, "%s.%s", uma_ioerror_base_name_.c_str(), |
| 939 uma_name.append(".IOError.").append(MethodIDToString(method)); | 942 MethodIDToString(method)); |
| 940 return base::LinearHistogram::FactoryGet(uma_name, 1, limit, limit + 1, | 943 return base::LinearHistogram::FactoryGet(uma_name, 1, limit, limit + 1, |
| 941 base::Histogram::kUmaTargetedHistogramFlag); | 944 base::Histogram::kUmaTargetedHistogramFlag); |
| 942 } | 945 } |
| 943 | 946 |
| 944 base::HistogramBase* ChromiumEnv::GetMethodIOErrorHistogram() const { | 947 base::HistogramBase* ChromiumEnv::GetMethodIOErrorHistogram() const { |
| 945 std::string uma_name(name_); | 948 std::string uma_name(name_); |
| 946 uma_name.append(".IOError"); | 949 uma_name.append(".IOError"); |
| 947 return base::LinearHistogram::FactoryGet(uma_name, 1, kNumEntries, | 950 return base::LinearHistogram::FactoryGet(uma_name, 1, kNumEntries, |
| 948 kNumEntries + 1, base::Histogram::kUmaTargetedHistogramFlag); | 951 kNumEntries + 1, base::Histogram::kUmaTargetedHistogramFlag); |
| 949 } | 952 } |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1068 | 1071 |
| 1069 Env* IDBEnv() { | 1072 Env* IDBEnv() { |
| 1070 return leveldb_env::idb_env.Pointer(); | 1073 return leveldb_env::idb_env.Pointer(); |
| 1071 } | 1074 } |
| 1072 | 1075 |
| 1073 Env* Env::Default() { | 1076 Env* Env::Default() { |
| 1074 return leveldb_env::default_env.Pointer(); | 1077 return leveldb_env::default_env.Pointer(); |
| 1075 } | 1078 } |
| 1076 | 1079 |
| 1077 } // namespace leveldb | 1080 } // namespace leveldb |
| OLD | NEW |