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 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
319 if (make_backup_ && file_type_ == kTable) | 320 if (make_backup_ && file_type_ == kTable) |
320 uma_logger_->RecordBackupResult(ChromiumEnv::MakeBackup(filename_)); | 321 uma_logger_->RecordBackupResult(ChromiumEnv::MakeBackup(filename_)); |
321 | 322 |
322 return Status::OK(); | 323 return Status::OK(); |
323 } | 324 } |
324 | 325 |
325 class IDBEnv : public ChromiumEnv { | 326 class IDBEnv : public ChromiumEnv { |
326 public: | 327 public: |
327 IDBEnv() : ChromiumEnv() { | 328 IDBEnv() : ChromiumEnv() { |
328 name_ = "LevelDBEnv.IDB"; | 329 name_ = "LevelDBEnv.IDB"; |
330 uma_ioerror_base_name_ = name_ + ".IOError.BFE"; | |
329 make_backup_ = true; | 331 make_backup_ = true; |
330 } | 332 } |
331 }; | 333 }; |
332 | 334 |
333 base::LazyInstance<IDBEnv>::Leaky idb_env = LAZY_INSTANCE_INITIALIZER; | 335 base::LazyInstance<IDBEnv>::Leaky idb_env = LAZY_INSTANCE_INITIALIZER; |
334 | 336 |
335 base::LazyInstance<ChromiumEnv>::Leaky default_env = LAZY_INSTANCE_INITIALIZER; | 337 base::LazyInstance<ChromiumEnv>::Leaky default_env = LAZY_INSTANCE_INITIALIZER; |
336 | 338 |
337 } // unnamed namespace | 339 } // unnamed namespace |
338 | 340 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
389 NOTREACHED(); | 391 NOTREACHED(); |
390 return "Unknown"; | 392 return "Unknown"; |
391 } | 393 } |
392 | 394 |
393 Status MakeIOError(Slice filename, | 395 Status MakeIOError(Slice filename, |
394 const std::string& message, | 396 const std::string& message, |
395 MethodID method, | 397 MethodID method, |
396 base::File::Error error) { | 398 base::File::Error error) { |
397 DCHECK_LT(error, 0); | 399 DCHECK_LT(error, 0); |
398 char buf[512]; | 400 char buf[512]; |
399 snprintf(buf, sizeof(buf), "%s (ChromeMethodPFE: %d::%s::%d)", | 401 snprintf(buf, sizeof(buf), "%s (ChromeMethodBFE: %d::%s::%d)", |
400 message.c_str(), method, MethodIDToString(method), -error); | 402 message.c_str(), method, MethodIDToString(method), -error); |
401 return Status::IOError(filename, buf); | 403 return Status::IOError(filename, buf); |
402 } | 404 } |
403 | 405 |
404 Status MakeIOError(Slice filename, | 406 Status MakeIOError(Slice filename, |
405 const std::string& message, | 407 const std::string& message, |
406 MethodID method) { | 408 MethodID method) { |
407 char buf[512]; | 409 char buf[512]; |
408 snprintf(buf, sizeof(buf), "%s (ChromeMethodOnly: %d::%s)", message.c_str(), | 410 snprintf(buf, sizeof(buf), "%s (ChromeMethodOnly: %d::%s)", message.c_str(), |
409 method, MethodIDToString(method)); | 411 method, MethodIDToString(method)); |
410 return Status::IOError(filename, buf); | 412 return Status::IOError(filename, buf); |
411 } | 413 } |
412 | 414 |
413 ErrorParsingResult ParseMethodAndError(const leveldb::Status& status, | 415 ErrorParsingResult ParseMethodAndError(const leveldb::Status& status, |
414 MethodID* method_param, | 416 MethodID* method_param, |
415 base::File::Error* error) { | 417 base::File::Error* error) { |
416 const std::string status_string = status.ToString(); | 418 const std::string status_string = status.ToString(); |
417 int method; | 419 int method; |
418 if (RE2::PartialMatch(status_string.c_str(), "ChromeMethodOnly: (\\d+)", | 420 if (RE2::PartialMatch(status_string.c_str(), "ChromeMethodOnly: (\\d+)", |
419 &method)) { | 421 &method)) { |
420 *method_param = static_cast<MethodID>(method); | 422 *method_param = static_cast<MethodID>(method); |
421 return METHOD_ONLY; | 423 return METHOD_ONLY; |
422 } | 424 } |
423 int parsed_error; | 425 int parsed_error; |
424 if (RE2::PartialMatch(status_string.c_str(), | 426 if (RE2::PartialMatch(status_string.c_str(), |
425 "ChromeMethodPFE: (\\d+)::.*::(\\d+)", &method, | 427 "ChromeMethodBFE: (\\d+)::.*::(\\d+)", &method, |
426 &parsed_error)) { | 428 &parsed_error)) { |
427 *method_param = static_cast<MethodID>(method); | 429 *method_param = static_cast<MethodID>(method); |
428 *error = static_cast<base::File::Error>(-parsed_error); | 430 *error = static_cast<base::File::Error>(-parsed_error); |
429 DCHECK_LT(*error, base::File::FILE_OK); | 431 DCHECK_LT(*error, base::File::FILE_OK); |
430 DCHECK_GT(*error, base::File::FILE_ERROR_MAX); | 432 DCHECK_GT(*error, base::File::FILE_ERROR_MAX); |
431 return METHOD_AND_PFE; | 433 return METHOD_AND_BFE; |
432 } | 434 } |
433 return NONE; | 435 return NONE; |
434 } | 436 } |
435 | 437 |
436 // Keep in sync with LevelDBCorruptionTypes in histograms.xml. Also, don't | 438 // Keep in sync with LevelDBCorruptionTypes in histograms.xml. Also, don't |
437 // change the order because indices into this array have been recorded in uma | 439 // change the order because indices into this array have been recorded in uma |
438 // histograms. | 440 // histograms. |
439 const char* patterns[] = { | 441 const char* patterns[] = { |
440 "missing files", | 442 "missing files", |
441 "log record too small", | 443 "log record too small", |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
500 return patterns[code - 1]; | 502 return patterns[code - 1]; |
501 } | 503 } |
502 | 504 |
503 bool IndicatesDiskFull(const leveldb::Status& status) { | 505 bool IndicatesDiskFull(const leveldb::Status& status) { |
504 if (status.ok()) | 506 if (status.ok()) |
505 return false; | 507 return false; |
506 leveldb_env::MethodID method; | 508 leveldb_env::MethodID method; |
507 base::File::Error error = base::File::FILE_OK; | 509 base::File::Error error = base::File::FILE_OK; |
508 leveldb_env::ErrorParsingResult result = | 510 leveldb_env::ErrorParsingResult result = |
509 leveldb_env::ParseMethodAndError(status, &method, &error); | 511 leveldb_env::ParseMethodAndError(status, &method, &error); |
510 return (result == leveldb_env::METHOD_AND_PFE && | 512 return (result == leveldb_env::METHOD_AND_BFE && |
511 static_cast<base::File::Error>(error) == | 513 static_cast<base::File::Error>(error) == |
512 base::File::FILE_ERROR_NO_SPACE); | 514 base::File::FILE_ERROR_NO_SPACE); |
513 } | 515 } |
514 | 516 |
515 bool ChromiumEnv::MakeBackup(const std::string& fname) { | 517 bool ChromiumEnv::MakeBackup(const std::string& fname) { |
516 FilePath original_table_name = FilePath::FromUTF8Unsafe(fname); | 518 FilePath original_table_name = FilePath::FromUTF8Unsafe(fname); |
517 FilePath backup_table_name = | 519 FilePath backup_table_name = |
518 original_table_name.ReplaceExtension(backup_table_extension); | 520 original_table_name.ReplaceExtension(backup_table_extension); |
519 return base::CopyFile(original_table_name, backup_table_name); | 521 return base::CopyFile(original_table_name, backup_table_name); |
520 } | 522 } |
521 | 523 |
522 ChromiumEnv::ChromiumEnv() | 524 ChromiumEnv::ChromiumEnv() |
523 : name_("LevelDBEnv"), | 525 : name_("LevelDBEnv"), |
524 make_backup_(false), | 526 make_backup_(false), |
525 bgsignal_(&mu_), | 527 bgsignal_(&mu_), |
526 started_bgthread_(false), | 528 started_bgthread_(false), |
527 kMaxRetryTimeMillis(1000) { | 529 kMaxRetryTimeMillis(1000) { |
530 uma_ioerror_base_name_ = name_ + ".IOError.BFE"; | |
528 } | 531 } |
529 | 532 |
530 ChromiumEnv::~ChromiumEnv() { | 533 ChromiumEnv::~ChromiumEnv() { |
531 // In chromium, ChromiumEnv is leaked. It'd be nice to add NOTREACHED here to | 534 // In chromium, ChromiumEnv is leaked. It'd be nice to add NOTREACHED here to |
532 // ensure that behavior isn't accidentally changed, but there's an instance in | 535 // ensure that behavior isn't accidentally changed, but there's an instance in |
533 // a unit test that is deleted. | 536 // a unit test that is deleted. |
534 } | 537 } |
535 | 538 |
536 bool ChromiumEnv::FileExists(const std::string& fname) { | 539 bool ChromiumEnv::FileExists(const std::string& fname) { |
537 return base::PathExists(FilePath::FromUTF8Unsafe(fname)); | 540 return base::PathExists(FilePath::FromUTF8Unsafe(fname)); |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
944 | 947 |
945 void ChromiumEnv::RecordBackupResult(bool result) const { | 948 void ChromiumEnv::RecordBackupResult(bool result) const { |
946 std::string uma_name(name_); | 949 std::string uma_name(name_); |
947 uma_name.append(".TableBackup"); | 950 uma_name.append(".TableBackup"); |
948 base::BooleanHistogram::FactoryGet( | 951 base::BooleanHistogram::FactoryGet( |
949 uma_name, base::Histogram::kUmaTargetedHistogramFlag)->AddBoolean(result); | 952 uma_name, base::Histogram::kUmaTargetedHistogramFlag)->AddBoolean(result); |
950 } | 953 } |
951 | 954 |
952 base::HistogramBase* ChromiumEnv::GetOSErrorHistogram(MethodID method, | 955 base::HistogramBase* ChromiumEnv::GetOSErrorHistogram(MethodID method, |
953 int limit) const { | 956 int limit) const { |
954 std::string uma_name(name_); | 957 std::string uma_name; |
955 // TODO(dgrogan): This is probably not the best way to concatenate strings. | 958 base::StringAppendF(&uma_name, "%s.%s", uma_ioerror_base_name_.c_str(), |
956 uma_name.append(".IOError.").append(MethodIDToString(method)); | 959 MethodIDToString(method)); |
957 return base::LinearHistogram::FactoryGet(uma_name, 1, limit, limit + 1, | 960 return base::LinearHistogram::FactoryGet(uma_name, 1, limit, limit + 1, |
958 base::Histogram::kUmaTargetedHistogramFlag); | 961 base::Histogram::kUmaTargetedHistogramFlag); |
959 } | 962 } |
960 | 963 |
961 base::HistogramBase* ChromiumEnv::GetMethodIOErrorHistogram() const { | 964 base::HistogramBase* ChromiumEnv::GetMethodIOErrorHistogram() const { |
dgrogan
2015/03/14 05:57:37
It looks like this one didn't need to change. It j
cmumford
2015/03/17 21:25:52
Yes, I see your point - and agree.
| |
962 std::string uma_name(name_); | 965 return base::LinearHistogram::FactoryGet( |
963 uma_name.append(".IOError"); | 966 uma_ioerror_base_name_, 1, kNumEntries, kNumEntries + 1, |
964 return base::LinearHistogram::FactoryGet(uma_name, 1, kNumEntries, | 967 base::Histogram::kUmaTargetedHistogramFlag); |
965 kNumEntries + 1, base::Histogram::kUmaTargetedHistogramFlag); | |
966 } | 968 } |
967 | 969 |
968 base::HistogramBase* ChromiumEnv::GetMaxFDHistogram( | 970 base::HistogramBase* ChromiumEnv::GetMaxFDHistogram( |
969 const std::string& type) const { | 971 const std::string& type) const { |
970 std::string uma_name(name_); | 972 std::string uma_name(name_); |
971 uma_name.append(".MaxFDs.").append(type); | 973 uma_name.append(".MaxFDs.").append(type); |
972 // These numbers make each bucket twice as large as the previous bucket. | 974 // These numbers make each bucket twice as large as the previous bucket. |
973 const int kFirstEntry = 1; | 975 const int kFirstEntry = 1; |
974 const int kLastEntry = 65536; | 976 const int kLastEntry = 65536; |
975 const int kNumBuckets = 18; | 977 const int kNumBuckets = 18; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1104 | 1106 |
1105 Env* IDBEnv() { | 1107 Env* IDBEnv() { |
1106 return leveldb_env::idb_env.Pointer(); | 1108 return leveldb_env::idb_env.Pointer(); |
1107 } | 1109 } |
1108 | 1110 |
1109 Env* Env::Default() { | 1111 Env* Env::Default() { |
1110 return leveldb_env::default_env.Pointer(); | 1112 return leveldb_env::default_env.Pointer(); |
1111 } | 1113 } |
1112 | 1114 |
1113 } // namespace leveldb | 1115 } // namespace leveldb |
OLD | NEW |