]> git.ipfire.org Git - thirdparty/squid.git/blob - src/SwapDir.cc
Moved some prototypes to tools.h
[thirdparty/squid.git] / src / SwapDir.cc
1 /*
2 * DEBUG: section 20 Swap Dir base object
3 * AUTHOR: Robert Collins
4 *
5 * SQUID Web Proxy Cache http://www.squid-cache.org/
6 * ----------------------------------------------------------
7 *
8 * Squid is the result of efforts by numerous individuals from
9 * the Internet community; see the CONTRIBUTORS file for full
10 * details. Many organizations have provided support for Squid's
11 * development; see the SPONSORS file for full details. Squid is
12 * Copyrighted (C) 2001 by the Regents of the University of
13 * California; see the COPYRIGHT file for full details. Squid
14 * incorporates software developed and/or copyrighted by other
15 * sources; see the CREDITS file for full details.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
30 *
31 */
32
33 #include "squid.h"
34 #include "cache_cf.h"
35 #include "compat/strtoll.h"
36 #include "ConfigOption.h"
37 #include "Parsing.h"
38 #include "protos.h"
39 #include "StoreFileSystem.h"
40 #include "SwapDir.h"
41 #include "tools.h"
42
43 SwapDir::SwapDir(char const *aType): theType(aType),
44 max_size(0),
45 path(NULL), index(-1), disker(-1), min_objsize(0), max_objsize (-1),
46 repl(NULL), removals(0), scanned(0),
47 cleanLog(NULL)
48 {
49 fs.blksize = 1024;
50 }
51
52 SwapDir::~SwapDir()
53 {
54 // TODO: should we delete repl?
55 xfree(path);
56 }
57
58 void
59 SwapDir::create() {}
60
61 void
62 SwapDir::dump(StoreEntry &)const {}
63
64 bool
65 SwapDir::doubleCheck(StoreEntry &)
66 {
67 return false;
68 }
69
70 void
71 SwapDir::unlink(StoreEntry &) {}
72
73 void
74 SwapDir::getStats(StoreInfoStats &stats) const
75 {
76 if (!doReportStat())
77 return;
78
79 stats.swap.size = currentSize();
80 stats.swap.capacity = maxSize();
81 stats.swap.count = currentCount();
82 }
83
84 void
85 SwapDir::stat(StoreEntry &output) const
86 {
87 if (!doReportStat())
88 return;
89
90 storeAppendPrintf(&output, "Store Directory #%d (%s): %s\n", index, type(),
91 path);
92 storeAppendPrintf(&output, "FS Block Size %d Bytes\n",
93 fs.blksize);
94 statfs(output);
95
96 if (repl) {
97 storeAppendPrintf(&output, "Removal policy: %s\n", repl->_type);
98
99 if (repl->Stats)
100 repl->Stats(repl, &output);
101 }
102 }
103
104 void
105 SwapDir::statfs(StoreEntry &)const {}
106
107 void
108 SwapDir::maintain() {}
109
110 uint64_t
111 SwapDir::minSize() const
112 {
113 return ((maxSize() * Config.Swap.lowWaterMark) / 100);
114 }
115
116 void
117 SwapDir::reference(StoreEntry &) {}
118
119 bool
120 SwapDir::dereference(StoreEntry &)
121 {
122 return true; // keep in global store_table
123 }
124
125 int
126 SwapDir::callback()
127 {
128 return 0;
129 }
130
131 bool
132 SwapDir::canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const
133 {
134 debugs(47,8, HERE << "cache_dir[" << index << "]: needs " <<
135 diskSpaceNeeded << " <? " << max_objsize);
136
137 if (EBIT_TEST(e.flags, ENTRY_SPECIAL))
138 return false; // we do not store Squid-generated entries
139
140 if (!objectSizeIsAcceptable(diskSpaceNeeded))
141 return false; // does not satisfy size limits
142
143 if (flags.read_only)
144 return false; // cannot write at all
145
146 if (currentSize() > maxSize())
147 return false; // already overflowing
148
149 /* Return 999 (99.9%) constant load; TODO: add a named constant for this */
150 load = 999;
151 return true; // kids may provide more tests and should report true load
152 }
153
154 void
155 SwapDir::sync() {}
156
157 /* Move to StoreEntry ? */
158 bool
159 SwapDir::canLog(StoreEntry const &e)const
160 {
161 if (e.swap_filen < 0)
162 return false;
163
164 if (e.swap_status != SWAPOUT_DONE)
165 return false;
166
167 if (e.swap_file_sz <= 0)
168 return false;
169
170 if (EBIT_TEST(e.flags, RELEASE_REQUEST))
171 return false;
172
173 if (EBIT_TEST(e.flags, KEY_PRIVATE))
174 return false;
175
176 if (EBIT_TEST(e.flags, ENTRY_SPECIAL))
177 return false;
178
179 return true;
180 }
181
182 void
183 SwapDir::openLog() {}
184
185 void
186 SwapDir::closeLog() {}
187
188 int
189 SwapDir::writeCleanStart()
190 {
191 return 0;
192 }
193
194 void
195 SwapDir::writeCleanDone() {}
196
197 void
198 SwapDir::logEntry(const StoreEntry & e, int op) const {}
199
200 char const *
201 SwapDir::type() const
202 {
203 return theType;
204 }
205
206 bool
207 SwapDir::active() const
208 {
209 if (IamWorkerProcess())
210 return true;
211
212 // we are inside a disker dedicated to this disk
213 if (KidIdentifier == disker)
214 return true;
215
216 return false; // Coordinator, wrong disker, etc.
217 }
218
219 bool
220 SwapDir::needsDiskStrand() const
221 {
222 return false;
223 }
224
225 /* NOT performance critical. Really. Don't bother optimising for speed
226 * - RBC 20030718
227 */
228 ConfigOption *
229 SwapDir::getOptionTree() const
230 {
231 ConfigOptionVector *result = new ConfigOptionVector;
232 result->options.push_back(new ConfigOptionAdapter<SwapDir>(*const_cast<SwapDir *>(this), &SwapDir::optionReadOnlyParse, &SwapDir::optionReadOnlyDump));
233 result->options.push_back(new ConfigOptionAdapter<SwapDir>(*const_cast<SwapDir *>(this), &SwapDir::optionObjectSizeParse, &SwapDir::optionObjectSizeDump));
234 return result;
235 }
236
237 void
238 SwapDir::parseOptions(int isaReconfig)
239 {
240 unsigned int old_read_only = flags.read_only;
241 char *name, *value;
242
243 ConfigOption *newOption = getOptionTree();
244
245 while ((name = strtok(NULL, w_space)) != NULL) {
246 value = strchr(name, '=');
247
248 if (value) {
249 *value = '\0'; /* cut on = */
250 ++value;
251 }
252
253 debugs(3,2, "SwapDir::parseOptions: parsing store option '" << name << "'='" << (value ? value : "") << "'");
254
255 if (newOption)
256 if (!newOption->parse(name, value, isaReconfig))
257 self_destruct();
258 }
259
260 delete newOption;
261
262 /*
263 * Handle notifications about reconfigured single-options with no value
264 * where the removal of the option cannot be easily detected in the
265 * parsing...
266 */
267
268 if (isaReconfig) {
269 if (old_read_only != flags.read_only) {
270 debugs(3, DBG_IMPORTANT, "Cache dir '" << path << "' now " << (flags.read_only ? "No-Store" : "Read-Write"));
271 }
272 }
273 }
274
275 void
276 SwapDir::dumpOptions(StoreEntry * entry) const
277 {
278 ConfigOption *newOption = getOptionTree();
279
280 if (newOption)
281 newOption->dump(entry);
282
283 delete newOption;
284 }
285
286 bool
287 SwapDir::optionReadOnlyParse(char const *option, const char *value, int isaReconfig)
288 {
289 if (strcmp(option, "no-store") != 0 && strcmp(option, "read-only") != 0)
290 return false;
291
292 int read_only = 0;
293
294 if (value)
295 read_only = xatoi(value);
296 else
297 read_only = 1;
298
299 flags.read_only = read_only;
300
301 return true;
302 }
303
304 void
305 SwapDir::optionReadOnlyDump(StoreEntry * e) const
306 {
307 if (flags.read_only)
308 storeAppendPrintf(e, " no-store");
309 }
310
311 bool
312 SwapDir::optionObjectSizeParse(char const *option, const char *value, int isaReconfig)
313 {
314 int64_t *val;
315 if (strcmp(option, "max-size") == 0) {
316 val = &max_objsize;
317 } else if (strcmp(option, "min-size") == 0) {
318 val = &min_objsize;
319 } else
320 return false;
321
322 if (!value)
323 self_destruct();
324
325 int64_t size = strtoll(value, NULL, 10);
326
327 if (isaReconfig && *val != size) {
328 if (allowOptionReconfigure(option)) {
329 debugs(3, DBG_IMPORTANT, "cache_dir '" << path << "' object " <<
330 option << " now " << size << " Bytes");
331 } else {
332 debugs(3, DBG_IMPORTANT, "WARNING: cache_dir '" << path << "' "
333 "object " << option << " cannot be changed dynamically, " <<
334 "value left unchanged (" << *val << " Bytes)");
335 return true;
336 }
337 }
338
339 *val = size;
340
341 return true;
342 }
343
344 void
345 SwapDir::optionObjectSizeDump(StoreEntry * e) const
346 {
347 if (min_objsize != 0)
348 storeAppendPrintf(e, " min-size=%" PRId64, min_objsize);
349
350 if (max_objsize != -1)
351 storeAppendPrintf(e, " max-size=%" PRId64, max_objsize);
352 }
353
354 // some SwapDirs may maintain their indexes and be able to lookup an entry key
355 StoreEntry *
356 SwapDir::get(const cache_key *key)
357 {
358 return NULL;
359 }
360
361 void
362 SwapDir::get(String const key, STOREGETCLIENT aCallback, void *aCallbackData)
363 {
364 fatal("not implemented");
365 }