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