]>
Commit | Line | Data |
---|---|---|
e2851fe7 AR |
1 | /* |
2 | * $Id$ | |
3 | * | |
4 | * DEBUG: section 79 Disk IO Routines | |
5 | */ | |
6 | ||
7 | #include "fs/rock/RockRebuild.h" | |
8 | #include "fs/rock/RockSwapDir.h" | |
9 | ||
10 | CBDATA_NAMESPACED_CLASS_INIT(Rock, Rebuild); | |
11 | ||
12 | Rock::Rebuild::Rebuild(SwapDir *dir): | |
13 | sd(dir), | |
14 | dbSize(0), | |
15 | dbEntrySize(0), | |
16 | dbEntryLimit(0), | |
17 | fd(-1), | |
18 | dbOffset(0), | |
19 | fileno(0) | |
20 | { | |
21 | assert(sd); | |
22 | memset(&counts, 0, sizeof(counts)); | |
23 | dbSize = sd->diskOffsetLimit(); // we do not care about the trailer waste | |
24 | dbEntrySize = sd->max_objsize; | |
25 | dbEntryLimit = sd->entryLimit(); | |
26 | } | |
27 | ||
28 | Rock::Rebuild::~Rebuild() | |
29 | { | |
30 | if (fd >= 0) | |
31 | file_close(fd); | |
32 | } | |
33 | ||
34 | /// prepares and initiates entry loading sequence | |
35 | void | |
36 | Rock::Rebuild::start() { | |
37 | debugs(47,2, HERE << sd->index); | |
38 | ||
39 | fd = file_open(sd->filePath, O_RDONLY | O_BINARY); | |
40 | if (fd < 0) | |
41 | failure("cannot open db", errno); | |
42 | ||
43 | char buf[SwapDir::HeaderSize]; | |
44 | if (read(fd, buf, sizeof(buf)) != SwapDir::HeaderSize) | |
45 | failure("cannot read db header", errno); | |
46 | ||
47 | dbOffset = SwapDir::HeaderSize; | |
48 | fileno = 0; | |
49 | ||
50 | checkpoint(); | |
51 | } | |
52 | ||
53 | /// quits if done; otherwise continues after a pause | |
54 | void | |
55 | Rock::Rebuild::checkpoint() | |
56 | { | |
57 | if (dbOffset < dbSize) | |
58 | eventAdd("Rock::Rebuild", Rock::Rebuild::Steps, this, 0.01, 1, true); | |
59 | else | |
60 | complete(); | |
61 | } | |
62 | ||
63 | void | |
64 | Rock::Rebuild::Steps(void *data) | |
65 | { | |
66 | static_cast<Rebuild*>(data)->steps(); | |
67 | } | |
68 | ||
69 | void | |
70 | Rock::Rebuild::steps() { | |
71 | debugs(47,5, HERE << sd->index << " fileno " << fileno << " at " << | |
72 | dbOffset << " <= " << dbSize); | |
73 | ||
74 | const int maxCount = dbEntryLimit; | |
75 | const int wantedCount = opt_foreground_rebuild ? maxCount : 50; | |
76 | const int stepCount = min(wantedCount, maxCount); | |
77 | for (int i = 0; i < stepCount && dbOffset < dbSize; ++i, ++fileno) { | |
78 | doOneEntry(); | |
79 | dbOffset += dbEntrySize; | |
80 | ||
81 | if (counts.scancount % 1000 == 0) | |
82 | storeRebuildProgress(sd->index, maxCount, counts.scancount); | |
83 | } | |
84 | ||
85 | checkpoint(); | |
86 | } | |
87 | ||
88 | void | |
89 | Rock::Rebuild::doOneEntry() { | |
90 | debugs(47,5, HERE << sd->index << " fileno " << fileno << " at " << | |
91 | dbOffset << " <= " << dbSize); | |
92 | ||
93 | if (lseek(fd, dbOffset, SEEK_SET) < 0) | |
94 | failure("cannot seek to db entry", errno); | |
95 | ||
96 | cache_key key[SQUID_MD5_DIGEST_LENGTH]; | |
97 | StoreEntry loadedE; | |
98 | if (!storeRebuildLoadEntry(fd, loadedE, key, counts, 0)) { | |
99 | // skip empty slots | |
100 | if (loadedE.swap_filen > 0 || loadedE.swap_file_sz > 0) { | |
101 | counts.invalid++; | |
102 | sd->unlink(fileno); | |
103 | } | |
104 | return; | |
105 | } | |
106 | ||
107 | assert(loadedE.swap_filen < dbEntryLimit); | |
108 | if (!storeRebuildKeepEntry(loadedE, key, counts)) | |
109 | return; | |
110 | ||
111 | counts.objcount++; | |
112 | // loadedE->dump(5); | |
113 | ||
114 | //StoreEntry *e = | |
115 | sd->addEntry(fileno, loadedE); | |
116 | //storeDirSwapLog(e, SWAP_LOG_ADD); | |
117 | } | |
118 | ||
119 | void | |
120 | Rock::Rebuild::complete() { | |
121 | debugs(47,3, HERE << sd->index); | |
122 | close(fd); | |
123 | StoreController::store_dirs_rebuilding--; | |
124 | storeRebuildComplete(&counts); | |
125 | delete this; // same as cbdataFree | |
126 | } | |
127 | ||
128 | void | |
129 | Rock::Rebuild::failure(const char *msg, int errNo) { | |
130 | debugs(47,5, HERE << sd->index << " fileno " << fileno << " at " << | |
131 | dbOffset << " <= " << dbSize); | |
132 | ||
133 | if (errNo) | |
134 | debugs(47,0, "Rock cache_dir rebuild failure: " << xstrerr(errNo)); | |
135 | debugs(47,0, "Do you need to run 'squid -z' to initialize storage?"); | |
136 | ||
137 | assert(sd); | |
138 | fatalf("Rock cache_dir[%d] rebuild of %s failed: %s.", | |
139 | sd->index, sd->filePath, msg); | |
140 | } |