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 |