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", | |
Alexei Svitkine (slow)
2014/08/05 13:18:16
Nit: Each histogram macro adds a lot of machine co
hashimoto
2014/08/06 03:52:20
Done.
| |
949 CHECK_VALIDITY_FAILURE_INVALID_HEADER, | |
950 CHECK_VALIDITY_FAILURE_MAX_VALUE); | |
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 CHECK_VALIDITY_FAILURE_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 CHECK_VALIDITY_FAILURE_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 CHECK_VALIDITY_FAILURE_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 CHECK_VALIDITY_FAILURE_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 CHECK_VALIDITY_FAILURE_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 CHECK_VALIDITY_FAILURE_MAX_VALUE); | |
1042 return false; | |
1043 } | |
1044 if (num_child_entries != num_entries_with_parent) { | |
1045 DLOG(ERROR) << "Child entry count mismatch"; | |
1046 UMA_HISTOGRAM_ENUMERATION("Drive.MetadataDBValidityCheckFailureReason", | |
1047 CHECK_VALIDITY_FAILURE_CHILD_ENTRY_COUNT_MISMATCH, | |
1048 CHECK_VALIDITY_FAILURE_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 |