Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium 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. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/drive/resource_metadata_storage.h" | 5 #include "chrome/browser/chromeos/drive/resource_metadata_storage.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 30 DB_INIT_IO_ERROR, | 30 DB_INIT_IO_ERROR, |
| 31 DB_INIT_FAILED, | 31 DB_INIT_FAILED, |
| 32 DB_INIT_INCOMPATIBLE, | 32 DB_INIT_INCOMPATIBLE, |
| 33 DB_INIT_BROKEN, | 33 DB_INIT_BROKEN, |
| 34 DB_INIT_OPENED_EXISTING_DB, | 34 DB_INIT_OPENED_EXISTING_DB, |
| 35 DB_INIT_CREATED_NEW_DB, | 35 DB_INIT_CREATED_NEW_DB, |
| 36 DB_INIT_REPLACED_EXISTING_DB_WITH_NEW_DB, | 36 DB_INIT_REPLACED_EXISTING_DB_WITH_NEW_DB, |
| 37 DB_INIT_MAX_VALUE, | 37 DB_INIT_MAX_VALUE, |
| 38 }; | 38 }; |
| 39 | 39 |
| 40 // Enum to describe DB validity check failure reason. | |
| 41 enum CheckValidityFailureReason { | |
| 42 CHECK_VALIDITY_FAILURE_INVALID_HEADER, | |
| 43 CHECK_VALIDITY_FAILURE_BROKEN_ID_ENTRY, | |
| 44 CHECK_VALIDITY_FAILURE_BROKEN_ENTRY, | |
| 45 CHECK_VALIDITY_FAILURE_INVALID_LOCAL_ID, | |
| 46 CHECK_VALIDITY_FAILURE_INVALID_PARENT_ID, | |
| 47 CHECK_VALIDITY_FAILURE_BROKEN_CHILD_MAP, | |
| 48 CHECK_VALIDITY_FAILURE_CHILD_ENTRY_COUNT_MISMATCH, | |
| 49 CHECK_VALIDITY_FAILURE_ITERATOR_ERROR, | |
| 50 CHECK_VALIDITY_FAILURE_MAX_VALUE, | |
| 51 }; | |
| 52 | |
| 40 // The name of the DB which stores the metadata. | 53 // The name of the DB which stores the metadata. |
| 41 const base::FilePath::CharType kResourceMapDBName[] = | 54 const base::FilePath::CharType kResourceMapDBName[] = |
| 42 FILE_PATH_LITERAL("resource_metadata_resource_map.db"); | 55 FILE_PATH_LITERAL("resource_metadata_resource_map.db"); |
| 43 | 56 |
| 44 // The name of the DB which couldn't be opened, but is preserved just in case. | 57 // The name of the DB which couldn't be opened, but is preserved just in case. |
| 45 const base::FilePath::CharType kPreservedResourceMapDBName[] = | 58 const base::FilePath::CharType kPreservedResourceMapDBName[] = |
| 46 FILE_PATH_LITERAL("resource_metadata_preserved_resource_map.db"); | 59 FILE_PATH_LITERAL("resource_metadata_preserved_resource_map.db"); |
| 47 | 60 |
| 48 // The name of the DB which couldn't be opened, and was replaced with a new one. | 61 // The name of the DB which couldn't be opened, and was replaced with a new one. |
| 49 const base::FilePath::CharType kTrashedResourceMapDBName[] = | 62 const base::FilePath::CharType kTrashedResourceMapDBName[] = |
| (...skipping 875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 925 // "|ID of B|" : ResourceEntry for entry B. | 938 // "|ID of B|" : ResourceEntry for entry B. |
| 926 // ... | 939 // ... |
| 927 | 940 |
| 928 // Check the header. | 941 // Check the header. |
| 929 ResourceMetadataHeader header; | 942 ResourceMetadataHeader header; |
| 930 if (!it->Valid() || | 943 if (!it->Valid() || |
| 931 it->key() != GetHeaderDBKey() || // Header entry must come first. | 944 it->key() != GetHeaderDBKey() || // Header entry must come first. |
| 932 !header.ParseFromArray(it->value().data(), it->value().size()) || | 945 !header.ParseFromArray(it->value().data(), it->value().size()) || |
| 933 header.version() != kDBVersion) { | 946 header.version() != kDBVersion) { |
| 934 DLOG(ERROR) << "Invalid header detected. version = " << header.version(); | 947 DLOG(ERROR) << "Invalid header detected. version = " << header.version(); |
| 948 UMA_HISTOGRAM_ENUMERATION("Drive.MetadataDBValidityCheckFailureReason", | |
| 949 CHECK_VALIDITY_FAILURE_INVALID_HEADER, | |
| 950 DB_INIT_MAX_VALUE); | |
|
kinaba
2014/08/05 06:00:14
CHECK_VALIDITY_FAILURE_MAX_VALUE? (ditto for every
hashimoto
2014/08/05 06:08:09
Ugh, done.
| |
| 935 return false; | 951 return false; |
| 936 } | 952 } |
| 937 | 953 |
| 938 // Check all entries. | 954 // Check all entries. |
| 939 size_t num_entries_with_parent = 0; | 955 size_t num_entries_with_parent = 0; |
| 940 size_t num_child_entries = 0; | 956 size_t num_child_entries = 0; |
| 941 ResourceEntry entry; | 957 ResourceEntry entry; |
| 942 std::string serialized_entry; | 958 std::string serialized_entry; |
| 943 std::string child_id; | 959 std::string child_id; |
| 944 for (it->Next(); it->Valid(); it->Next()) { | 960 for (it->Next(); it->Valid(); it->Next()) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 955 // Resource-ID-to-local-ID mapping without entry for the local ID is ok. | 971 // Resource-ID-to-local-ID mapping without entry for the local ID is ok. |
| 956 if (status.IsNotFound()) | 972 if (status.IsNotFound()) |
| 957 continue; | 973 continue; |
| 958 // When the entry exists, its resource ID must be consistent. | 974 // When the entry exists, its resource ID must be consistent. |
| 959 const bool ok = status.ok() && | 975 const bool ok = status.ok() && |
| 960 entry.ParseFromString(serialized_entry) && | 976 entry.ParseFromString(serialized_entry) && |
| 961 !entry.resource_id().empty() && | 977 !entry.resource_id().empty() && |
| 962 leveldb::Slice(GetIdEntryKey(entry.resource_id())) == it->key(); | 978 leveldb::Slice(GetIdEntryKey(entry.resource_id())) == it->key(); |
| 963 if (!ok) { | 979 if (!ok) { |
| 964 DLOG(ERROR) << "Broken ID entry. status = " << status.ToString(); | 980 DLOG(ERROR) << "Broken ID entry. status = " << status.ToString(); |
| 981 UMA_HISTOGRAM_ENUMERATION("Drive.MetadataDBValidityCheckFailureReason", | |
| 982 CHECK_VALIDITY_FAILURE_BROKEN_ID_ENTRY, | |
| 983 DB_INIT_MAX_VALUE); | |
| 965 return false; | 984 return false; |
| 966 } | 985 } |
| 967 continue; | 986 continue; |
| 968 } | 987 } |
| 969 | 988 |
| 970 // Check if stored data is broken. | 989 // Check if stored data is broken. |
| 971 if (!entry.ParseFromArray(it->value().data(), it->value().size())) { | 990 if (!entry.ParseFromArray(it->value().data(), it->value().size())) { |
| 972 DLOG(ERROR) << "Broken entry detected"; | 991 DLOG(ERROR) << "Broken entry detected"; |
| 992 UMA_HISTOGRAM_ENUMERATION("Drive.MetadataDBValidityCheckFailureReason", | |
| 993 CHECK_VALIDITY_FAILURE_BROKEN_ENTRY, | |
| 994 DB_INIT_MAX_VALUE); | |
| 973 return false; | 995 return false; |
| 974 } | 996 } |
| 975 | 997 |
| 976 if (leveldb::Slice(entry.local_id()) != it->key()) { | 998 if (leveldb::Slice(entry.local_id()) != it->key()) { |
| 977 DLOG(ERROR) << "Wrong local ID."; | 999 DLOG(ERROR) << "Wrong local ID."; |
| 1000 UMA_HISTOGRAM_ENUMERATION("Drive.MetadataDBValidityCheckFailureReason", | |
| 1001 CHECK_VALIDITY_FAILURE_INVALID_LOCAL_ID, | |
| 1002 DB_INIT_MAX_VALUE); | |
| 978 return false; | 1003 return false; |
| 979 } | 1004 } |
| 980 | 1005 |
| 981 if (!entry.parent_local_id().empty()) { | 1006 if (!entry.parent_local_id().empty()) { |
| 982 // Check if the parent entry is stored. | 1007 // Check if the parent entry is stored. |
| 983 leveldb::Status status = resource_map_->Get( | 1008 leveldb::Status status = resource_map_->Get( |
| 984 options, | 1009 options, |
| 985 leveldb::Slice(entry.parent_local_id()), | 1010 leveldb::Slice(entry.parent_local_id()), |
| 986 &serialized_entry); | 1011 &serialized_entry); |
| 987 if (!status.ok()) { | 1012 if (!status.ok()) { |
| 988 DLOG(ERROR) << "Can't get parent entry. status = " << status.ToString(); | 1013 DLOG(ERROR) << "Can't get parent entry. status = " << status.ToString(); |
| 1014 UMA_HISTOGRAM_ENUMERATION("Drive.MetadataDBValidityCheckFailureReason", | |
| 1015 CHECK_VALIDITY_FAILURE_INVALID_PARENT_ID, | |
| 1016 DB_INIT_MAX_VALUE); | |
| 989 return false; | 1017 return false; |
| 990 } | 1018 } |
| 991 | 1019 |
| 992 // Check if parent-child relationship is stored correctly. | 1020 // Check if parent-child relationship is stored correctly. |
| 993 status = resource_map_->Get( | 1021 status = resource_map_->Get( |
| 994 options, | 1022 options, |
| 995 leveldb::Slice(GetChildEntryKey(entry.parent_local_id(), | 1023 leveldb::Slice(GetChildEntryKey(entry.parent_local_id(), |
| 996 entry.base_name())), | 1024 entry.base_name())), |
| 997 &child_id); | 1025 &child_id); |
| 998 if (!status.ok() || leveldb::Slice(child_id) != it->key()) { | 1026 if (!status.ok() || leveldb::Slice(child_id) != it->key()) { |
| 999 DLOG(ERROR) << "Child map is broken. status = " << status.ToString(); | 1027 DLOG(ERROR) << "Child map is broken. status = " << status.ToString(); |
| 1028 UMA_HISTOGRAM_ENUMERATION("Drive.MetadataDBValidityCheckFailureReason", | |
| 1029 CHECK_VALIDITY_FAILURE_BROKEN_CHILD_MAP, | |
| 1030 DB_INIT_MAX_VALUE); | |
| 1000 return false; | 1031 return false; |
| 1001 } | 1032 } |
| 1002 ++num_entries_with_parent; | 1033 ++num_entries_with_parent; |
| 1003 } | 1034 } |
| 1004 } | 1035 } |
| 1005 if (!it->status().ok() || num_child_entries != num_entries_with_parent) { | 1036 if (!it->status().ok()) { |
| 1006 DLOG(ERROR) << "Error during checking resource map. status = " | 1037 DLOG(ERROR) << "Error during checking resource map. status = " |
| 1007 << it->status().ToString(); | 1038 << it->status().ToString(); |
| 1039 UMA_HISTOGRAM_ENUMERATION("Drive.MetadataDBValidityCheckFailureReason", | |
| 1040 CHECK_VALIDITY_FAILURE_ITERATOR_ERROR, | |
| 1041 DB_INIT_MAX_VALUE); | |
| 1042 return false; | |
| 1043 } | |
| 1044 if (num_child_entries != num_entries_with_parent) { | |
| 1045 DLOG(ERROR) << "Child entry count mismatch" << it->status().ToString(); | |
| 1046 UMA_HISTOGRAM_ENUMERATION("Drive.MetadataDBValidityCheckFailureReason", | |
| 1047 CHECK_VALIDITY_FAILURE_CHILD_ENTRY_COUNT_MISMATCH, | |
| 1048 DB_INIT_MAX_VALUE); | |
| 1008 return false; | 1049 return false; |
| 1009 } | 1050 } |
| 1010 return true; | 1051 return true; |
| 1011 } | 1052 } |
| 1012 | 1053 |
| 1013 } // namespace internal | 1054 } // namespace internal |
| 1014 } // namespace drive | 1055 } // namespace drive |
| OLD | NEW |