]> git.ipfire.org Git - thirdparty/squid.git/blame - src/fs/rock/RockRebuild.cc
When searching for a hit, ask each cache_dir after checking in store_table.
[thirdparty/squid.git] / src / fs / rock / RockRebuild.cc
CommitLineData
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
10CBDATA_NAMESPACED_CLASS_INIT(Rock, Rebuild);
11
12Rock::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
28Rock::Rebuild::~Rebuild()
29{
30 if (fd >= 0)
31 file_close(fd);
32}
33
34/// prepares and initiates entry loading sequence
35void
36Rock::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
54void
55Rock::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
63void
64Rock::Rebuild::Steps(void *data)
65{
66 static_cast<Rebuild*>(data)->steps();
67}
68
69void
70Rock::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
88void
89Rock::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
119void
120Rock::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
128void
129Rock::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}