| OLD | NEW |
| 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2008 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 // Performs basic inspection of the disk cache files with minimal disruption | 5 // Performs basic inspection of the disk cache files with minimal disruption |
| 6 // to the actual files (they still may change if an error is detected on the | 6 // to the actual files (they still may change if an error is detected on the |
| 7 // files). | 7 // files). |
| 8 | 8 |
| 9 #include <stdio.h> | 9 #include <stdio.h> |
| 10 #include <string> | 10 #include <string> |
| 11 | 11 |
| 12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
| 13 #include "base/message_loop.h" | 13 #include "base/message_loop.h" |
| 14 #include "net/base/file_stream.h" | 14 #include "net/base/file_stream.h" |
| 15 #include "net/disk_cache/block_files.h" | 15 #include "net/disk_cache/block_files.h" |
| 16 #include "net/disk_cache/disk_format.h" | 16 #include "net/disk_cache/disk_format.h" |
| 17 #include "net/disk_cache/mapped_file.h" | 17 #include "net/disk_cache/mapped_file.h" |
| 18 #include "net/disk_cache/storage_block.h" | 18 #include "net/disk_cache/storage_block.h" |
| 19 | 19 |
| 20 namespace { | 20 namespace { |
| 21 | 21 |
| 22 const wchar_t kIndexName[] = L"index"; | 22 const wchar_t kIndexName[] = L"index"; |
| 23 const wchar_t kDataPrefix[] = L"data_"; | 23 const wchar_t kDataPrefix[] = L"data_"; |
| 24 | 24 |
| 25 // Reads the |header_size| bytes from the beginning of file |name|. | 25 // Reads the |header_size| bytes from the beginning of file |name|. |
| 26 bool ReadHeader(const std::wstring name, char* header, int header_size) { | 26 bool ReadHeader(const std::wstring& name, char* header, int header_size) { |
| 27 net::FileStream file; | 27 net::FileStream file; |
| 28 file.Open(FilePath::FromWStringHack(name), | 28 file.Open(FilePath::FromWStringHack(name), |
| 29 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ); | 29 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ); |
| 30 if (!file.IsOpen()) { | 30 if (!file.IsOpen()) { |
| 31 printf("Unable to open file %ls\n", name.c_str()); | 31 printf("Unable to open file %ls\n", name.c_str()); |
| 32 return false; | 32 return false; |
| 33 } | 33 } |
| 34 | 34 |
| 35 int read = file.Read(header, header_size, NULL); | 35 int read = file.Read(header, header_size, NULL); |
| 36 if (read != header_size) { | 36 if (read != header_size) { |
| 37 printf("Unable to read file %ls\n", name.c_str()); | 37 printf("Unable to read file %ls\n", name.c_str()); |
| 38 return false; | 38 return false; |
| 39 } | 39 } |
| 40 return true; | 40 return true; |
| 41 } | 41 } |
| 42 | 42 |
| 43 int GetMajorVersionFromFile(const std::wstring name) { | 43 int GetMajorVersionFromFile(const std::wstring& name) { |
| 44 disk_cache::IndexHeader header; | 44 disk_cache::IndexHeader header; |
| 45 if (!ReadHeader(name, reinterpret_cast<char*>(&header), sizeof(header))) | 45 if (!ReadHeader(name, reinterpret_cast<char*>(&header), sizeof(header))) |
| 46 return 0; | 46 return 0; |
| 47 | 47 |
| 48 return header.version >> 16; | 48 return header.version >> 16; |
| 49 } | 49 } |
| 50 | 50 |
| 51 // Dumps the contents of the Index-file header. | 51 // Dumps the contents of the Index-file header. |
| 52 void DumpIndexHeader(const std::wstring name) { | 52 void DumpIndexHeader(const std::wstring& name) { |
| 53 disk_cache::IndexHeader header; | 53 disk_cache::IndexHeader header; |
| 54 if (!ReadHeader(name, reinterpret_cast<char*>(&header), sizeof(header))) | 54 if (!ReadHeader(name, reinterpret_cast<char*>(&header), sizeof(header))) |
| 55 return; | 55 return; |
| 56 | 56 |
| 57 printf("Index file:\n"); | 57 printf("Index file:\n"); |
| 58 printf("magic: %x\n", header.magic); | 58 printf("magic: %x\n", header.magic); |
| 59 printf("version: %d.%d\n", header.version >> 16, header.version & 0xffff); | 59 printf("version: %d.%d\n", header.version >> 16, header.version & 0xffff); |
| 60 printf("entries: %d\n", header.num_entries); | 60 printf("entries: %d\n", header.num_entries); |
| 61 printf("total bytes: %d\n", header.num_bytes); | 61 printf("total bytes: %d\n", header.num_bytes); |
| 62 printf("last file number: %d\n", header.last_file); | 62 printf("last file number: %d\n", header.last_file); |
| 63 printf("current id: %d\n", header.this_id); | 63 printf("current id: %d\n", header.this_id); |
| 64 printf("table length: %d\n", header.table_len); | 64 printf("table length: %d\n", header.table_len); |
| 65 printf("last crash: %d\n", header.crash); | 65 printf("last crash: %d\n", header.crash); |
| 66 printf("experiment: %d\n", header.experiment); | 66 printf("experiment: %d\n", header.experiment); |
| 67 for (int i = 0; i < 5; i++) { | 67 for (int i = 0; i < 5; i++) { |
| 68 printf("head %d: 0x%x\n", i, header.lru.heads[i]); | 68 printf("head %d: 0x%x\n", i, header.lru.heads[i]); |
| 69 printf("tail %d: 0x%x\n", i, header.lru.tails[i]); | 69 printf("tail %d: 0x%x\n", i, header.lru.tails[i]); |
| 70 } | 70 } |
| 71 printf("transaction: 0x%x\n", header.lru.transaction); | 71 printf("transaction: 0x%x\n", header.lru.transaction); |
| 72 printf("operation: %d\n", header.lru.operation); | 72 printf("operation: %d\n", header.lru.operation); |
| 73 printf("operation list: %d\n", header.lru.operation_list); | 73 printf("operation list: %d\n", header.lru.operation_list); |
| 74 printf("-------------------------\n\n"); | 74 printf("-------------------------\n\n"); |
| 75 } | 75 } |
| 76 | 76 |
| 77 // Dumps the contents of a block-file header. | 77 // Dumps the contents of a block-file header. |
| 78 void DumpBlockHeader(const std::wstring name) { | 78 void DumpBlockHeader(const std::wstring& name) { |
| 79 disk_cache::BlockFileHeader header; | 79 disk_cache::BlockFileHeader header; |
| 80 if (!ReadHeader(name, reinterpret_cast<char*>(&header), sizeof(header))) | 80 if (!ReadHeader(name, reinterpret_cast<char*>(&header), sizeof(header))) |
| 81 return; | 81 return; |
| 82 | 82 |
| 83 std::wstring file_name = file_util::GetFilenameFromPath(name); | 83 std::wstring file_name = file_util::GetFilenameFromPath(name); |
| 84 | 84 |
| 85 printf("Block file: %ls\n", file_name.c_str()); | 85 printf("Block file: %ls\n", file_name.c_str()); |
| 86 printf("magic: %x\n", header.magic); | 86 printf("magic: %x\n", header.magic); |
| 87 printf("version: %d.%d\n", header.version >> 16, header.version & 0xffff); | 87 printf("version: %d.%d\n", header.version >> 16, header.version & 0xffff); |
| 88 printf("file id: %d\n", header.this_file); | 88 printf("file id: %d\n", header.this_file); |
| 89 printf("next file id: %d\n", header.next_file); | 89 printf("next file id: %d\n", header.next_file); |
| 90 printf("entry size: %d\n", header.entry_size); | 90 printf("entry size: %d\n", header.entry_size); |
| 91 printf("current entries: %d\n", header.num_entries); | 91 printf("current entries: %d\n", header.num_entries); |
| 92 printf("max entries: %d\n", header.max_entries); | 92 printf("max entries: %d\n", header.max_entries); |
| 93 printf("updating: %d\n", header.updating); | 93 printf("updating: %d\n", header.updating); |
| 94 printf("empty sz 1: %d\n", header.empty[0]); | 94 printf("empty sz 1: %d\n", header.empty[0]); |
| 95 printf("empty sz 2: %d\n", header.empty[1]); | 95 printf("empty sz 2: %d\n", header.empty[1]); |
| 96 printf("empty sz 3: %d\n", header.empty[2]); | 96 printf("empty sz 3: %d\n", header.empty[2]); |
| 97 printf("empty sz 4: %d\n", header.empty[3]); | 97 printf("empty sz 4: %d\n", header.empty[3]); |
| 98 printf("user 0: 0x%x\n", header.user[0]); | 98 printf("user 0: 0x%x\n", header.user[0]); |
| 99 printf("user 1: 0x%x\n", header.user[1]); | 99 printf("user 1: 0x%x\n", header.user[1]); |
| 100 printf("user 2: 0x%x\n", header.user[2]); | 100 printf("user 2: 0x%x\n", header.user[2]); |
| 101 printf("user 3: 0x%x\n", header.user[3]); | 101 printf("user 3: 0x%x\n", header.user[3]); |
| 102 printf("-------------------------\n\n"); | 102 printf("-------------------------\n\n"); |
| 103 } | 103 } |
| 104 | 104 |
| 105 // Simple class that interacts with the set of cache files. | 105 // Simple class that interacts with the set of cache files. |
| 106 class CacheDumper { | 106 class CacheDumper { |
| 107 public: | 107 public: |
| 108 explicit CacheDumper(const std::wstring path) | 108 explicit CacheDumper(const std::wstring& path) |
| 109 : path_(path), block_files_(path), index_(NULL) {} | 109 : path_(path), block_files_(path), index_(NULL) {} |
| 110 | 110 |
| 111 bool Init(); | 111 bool Init(); |
| 112 | 112 |
| 113 // Reads an entry from disk. Return false when all entries have been already | 113 // Reads an entry from disk. Return false when all entries have been already |
| 114 // returned. | 114 // returned. |
| 115 bool GetEntry(disk_cache::EntryStore* entry); | 115 bool GetEntry(disk_cache::EntryStore* entry); |
| 116 | 116 |
| 117 // Loads a specific block from the block files. | 117 // Loads a specific block from the block files. |
| 118 bool LoadEntry(disk_cache::CacheAddr addr, disk_cache::EntryStore* entry); | 118 bool LoadEntry(disk_cache::CacheAddr addr, disk_cache::EntryStore* entry); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 printf("entry: 0x%x\n", rankings.contents); | 244 printf("entry: 0x%x\n", rankings.contents); |
| 245 printf("dirty: %d\n", rankings.dirty); | 245 printf("dirty: %d\n", rankings.dirty); |
| 246 printf("pointer: 0x%x\n", rankings.pointer); | 246 printf("pointer: 0x%x\n", rankings.pointer); |
| 247 printf("----------\n\n"); | 247 printf("----------\n\n"); |
| 248 } | 248 } |
| 249 | 249 |
| 250 } // namespace. | 250 } // namespace. |
| 251 | 251 |
| 252 // ----------------------------------------------------------------------- | 252 // ----------------------------------------------------------------------- |
| 253 | 253 |
| 254 int GetMajorVersion(const std::wstring input_path) { | 254 int GetMajorVersion(const std::wstring& input_path) { |
| 255 std::wstring index_name(input_path); | 255 std::wstring index_name(input_path); |
| 256 file_util::AppendToPath(&index_name, kIndexName); | 256 file_util::AppendToPath(&index_name, kIndexName); |
| 257 | 257 |
| 258 int version = GetMajorVersionFromFile(index_name); | 258 int version = GetMajorVersionFromFile(index_name); |
| 259 if (!version) | 259 if (!version) |
| 260 return 0; | 260 return 0; |
| 261 | 261 |
| 262 std::wstring data_name(input_path); | 262 std::wstring data_name(input_path); |
| 263 file_util::AppendToPath(&data_name, L"data_0"); | 263 file_util::AppendToPath(&data_name, L"data_0"); |
| 264 if (version != GetMajorVersionFromFile(data_name)) | 264 if (version != GetMajorVersionFromFile(data_name)) |
| 265 return 0; | 265 return 0; |
| 266 | 266 |
| 267 data_name = input_path; | 267 data_name = input_path; |
| 268 file_util::AppendToPath(&data_name, L"data_1"); | 268 file_util::AppendToPath(&data_name, L"data_1"); |
| 269 if (version != GetMajorVersionFromFile(data_name)) | 269 if (version != GetMajorVersionFromFile(data_name)) |
| 270 return 0; | 270 return 0; |
| 271 | 271 |
| 272 return version; | 272 return version; |
| 273 } | 273 } |
| 274 | 274 |
| 275 // Dumps the headers of all files. | 275 // Dumps the headers of all files. |
| 276 int DumpHeaders(const std::wstring input_path) { | 276 int DumpHeaders(const std::wstring& input_path) { |
| 277 std::wstring index_name(input_path); | 277 std::wstring index_name(input_path); |
| 278 file_util::AppendToPath(&index_name, kIndexName); | 278 file_util::AppendToPath(&index_name, kIndexName); |
| 279 DumpIndexHeader(index_name); | 279 DumpIndexHeader(index_name); |
| 280 | 280 |
| 281 std::wstring pattern(kDataPrefix); | 281 std::wstring pattern(kDataPrefix); |
| 282 pattern.append(L"*"); | 282 pattern.append(L"*"); |
| 283 file_util::FileEnumerator iter(FilePath::FromWStringHack(input_path), false, | 283 file_util::FileEnumerator iter(FilePath::FromWStringHack(input_path), false, |
| 284 file_util::FileEnumerator::FILES, pattern); | 284 file_util::FileEnumerator::FILES, pattern); |
| 285 for (std::wstring file = iter.Next().ToWStringHack(); !file.empty(); | 285 for (std::wstring file = iter.Next().ToWStringHack(); !file.empty(); |
| 286 file = iter.Next().ToWStringHack()) { | 286 file = iter.Next().ToWStringHack()) { |
| 287 DumpBlockHeader(file); | 287 DumpBlockHeader(file); |
| 288 } | 288 } |
| 289 | 289 |
| 290 return 0; | 290 return 0; |
| 291 } | 291 } |
| 292 | 292 |
| 293 // Dumps all entries from the cache. | 293 // Dumps all entries from the cache. |
| 294 int DumpContents(const std::wstring input_path) { | 294 int DumpContents(const std::wstring& input_path) { |
| 295 DumpHeaders(input_path); | 295 DumpHeaders(input_path); |
| 296 | 296 |
| 297 // We need a message loop, although we really don't run any task. | 297 // We need a message loop, although we really don't run any task. |
| 298 MessageLoop loop(MessageLoop::TYPE_IO); | 298 MessageLoop loop(MessageLoop::TYPE_IO); |
| 299 CacheDumper dumper(input_path); | 299 CacheDumper dumper(input_path); |
| 300 if (!dumper.Init()) | 300 if (!dumper.Init()) |
| 301 return -1; | 301 return -1; |
| 302 | 302 |
| 303 disk_cache::EntryStore entry; | 303 disk_cache::EntryStore entry; |
| 304 while (dumper.GetEntry(&entry)) { | 304 while (dumper.GetEntry(&entry)) { |
| 305 DumpEntry(entry); | 305 DumpEntry(entry); |
| 306 disk_cache::RankingsNode rankings; | 306 disk_cache::RankingsNode rankings; |
| 307 if (dumper.LoadRankings(entry.rankings_node, &rankings)) | 307 if (dumper.LoadRankings(entry.rankings_node, &rankings)) |
| 308 DumpRankings(rankings); | 308 DumpRankings(rankings); |
| 309 } | 309 } |
| 310 | 310 |
| 311 printf("Done.\n"); | 311 printf("Done.\n"); |
| 312 | 312 |
| 313 return 0; | 313 return 0; |
| 314 } | 314 } |
| OLD | NEW |