]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/SwapDir.cc
2 * DEBUG: section 20 Swap Dir base object
3 * AUTHOR: Robert Collins
5 * SQUID Web Proxy Cache http://www.squid-cache.org/
6 * ----------------------------------------------------------
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.
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.
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.
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.
35 #include "compat/strtoll.h"
36 #include "ConfigOption.h"
37 #include "ConfigParser.h"
40 #include "SquidConfig.h"
41 #include "StoreFileSystem.h"
45 SwapDir::SwapDir(char const *aType
): theType(aType
),
46 max_size(0), min_objsize(0), max_objsize (-1),
47 path(NULL
), index(-1), disker(-1),
48 repl(NULL
), removals(0), scanned(0),
56 // TODO: should we delete repl?
64 SwapDir::dump(StoreEntry
&)const {}
67 SwapDir::doubleCheck(StoreEntry
&)
73 SwapDir::unlink(StoreEntry
&) {}
76 SwapDir::getStats(StoreInfoStats
&stats
) const
81 stats
.swap
.size
= currentSize();
82 stats
.swap
.capacity
= maxSize();
83 stats
.swap
.count
= currentCount();
87 SwapDir::stat(StoreEntry
&output
) const
92 storeAppendPrintf(&output
, "Store Directory #%d (%s): %s\n", index
, type(),
94 storeAppendPrintf(&output
, "FS Block Size %d Bytes\n",
99 storeAppendPrintf(&output
, "Removal policy: %s\n", repl
->_type
);
102 repl
->Stats(repl
, &output
);
107 SwapDir::statfs(StoreEntry
&)const {}
110 SwapDir::maintain() {}
113 SwapDir::minSize() const
115 return ((maxSize() * Config
.Swap
.lowWaterMark
) / 100);
119 SwapDir::maxObjectSize() const
121 // per-store max-size=N value is authoritative
122 if (max_objsize
> -1)
125 // store with no individual max limit is limited by configured maximum_object_size
126 // or the total store size, whichever is smaller
127 return min(static_cast<int64_t>(maxSize()), Config
.Store
.maxObjectSize
);
131 SwapDir::maxObjectSize(int64_t newMax
)
133 // negative values mean no limit (-1)
135 max_objsize
= -1; // set explicitly in case it had a non-default value previously
139 // prohibit values greater than total storage area size
140 // but set max_objsize to the maximum allowed to override maximum_object_size global config
141 if (static_cast<uint64_t>(newMax
) > maxSize()) {
142 debugs(47, DBG_PARSE_NOTE(2), "WARNING: Ignoring 'max-size' option for " << path
<<
143 " which is larger than total cache_dir size of " << maxSize() << " bytes.");
144 max_objsize
= maxSize();
148 max_objsize
= newMax
;
152 SwapDir::reference(StoreEntry
&) {}
155 SwapDir::dereference(StoreEntry
&, bool)
157 return true; // keep in global store_table
167 SwapDir::canStore(const StoreEntry
&e
, int64_t diskSpaceNeeded
, int &load
) const
169 debugs(47,8, HERE
<< "cache_dir[" << index
<< "]: needs " <<
170 diskSpaceNeeded
<< " <? " << max_objsize
);
172 if (EBIT_TEST(e
.flags
, ENTRY_SPECIAL
))
173 return false; // we do not store Squid-generated entries
175 if (!objectSizeIsAcceptable(diskSpaceNeeded
))
176 return false; // does not satisfy size limits
179 return false; // cannot write at all
181 if (currentSize() > maxSize())
182 return false; // already overflowing
184 /* Return 999 (99.9%) constant load; TODO: add a named constant for this */
186 return true; // kids may provide more tests and should report true load
192 /* Move to StoreEntry ? */
194 SwapDir::canLog(StoreEntry
const &e
)const
196 if (e
.swap_filen
< 0)
199 if (e
.swap_status
!= SWAPOUT_DONE
)
202 if (e
.swap_file_sz
<= 0)
205 if (EBIT_TEST(e
.flags
, RELEASE_REQUEST
))
208 if (EBIT_TEST(e
.flags
, KEY_PRIVATE
))
211 if (EBIT_TEST(e
.flags
, ENTRY_SPECIAL
))
218 SwapDir::openLog() {}
221 SwapDir::closeLog() {}
224 SwapDir::writeCleanStart()
230 SwapDir::writeCleanDone() {}
233 SwapDir::logEntry(const StoreEntry
& e
, int op
) const {}
236 SwapDir::type() const
242 SwapDir::active() const
244 if (IamWorkerProcess())
247 // we are inside a disker dedicated to this disk
248 if (KidIdentifier
== disker
)
251 return false; // Coordinator, wrong disker, etc.
255 SwapDir::needsDiskStrand() const
260 /* NOT performance critical. Really. Don't bother optimising for speed
264 SwapDir::getOptionTree() const
266 ConfigOptionVector
*result
= new ConfigOptionVector
;
267 result
->options
.push_back(new ConfigOptionAdapter
<SwapDir
>(*const_cast<SwapDir
*>(this), &SwapDir::optionReadOnlyParse
, &SwapDir::optionReadOnlyDump
));
268 result
->options
.push_back(new ConfigOptionAdapter
<SwapDir
>(*const_cast<SwapDir
*>(this), &SwapDir::optionObjectSizeParse
, &SwapDir::optionObjectSizeDump
));
273 SwapDir::parseOptions(int isaReconfig
)
275 const bool old_read_only
= flags
.read_only
;
278 ConfigOption
*newOption
= getOptionTree();
280 while ((name
= ConfigParser::NextToken()) != NULL
) {
281 value
= strchr(name
, '=');
284 *value
= '\0'; /* cut on = */
288 debugs(3,2, "SwapDir::parseOptions: parsing store option '" << name
<< "'='" << (value
? value
: "") << "'");
291 if (!newOption
->parse(name
, value
, isaReconfig
))
298 * Handle notifications about reconfigured single-options with no value
299 * where the removal of the option cannot be easily detected in the
304 if (old_read_only
!= flags
.read_only
) {
305 debugs(3, DBG_IMPORTANT
, "Cache dir '" << path
<< "' now " << (flags
.read_only
? "No-Store" : "Read-Write"));
311 SwapDir::dumpOptions(StoreEntry
* entry
) const
313 ConfigOption
*newOption
= getOptionTree();
316 newOption
->dump(entry
);
322 SwapDir::optionReadOnlyParse(char const *option
, const char *value
, int isaReconfig
)
324 if (strcmp(option
, "no-store") != 0 && strcmp(option
, "read-only") != 0)
327 if (strcmp(option
, "read-only") == 0) {
328 debugs(3, DBG_PARSE_NOTE(3), "UPGRADE WARNING: Replace cache_dir option 'read-only' with 'no-store'.");
334 read_only
= (xatoi(value
) != 0);
338 flags
.read_only
= read_only
;
344 SwapDir::optionReadOnlyDump(StoreEntry
* e
) const
347 storeAppendPrintf(e
, " no-store");
351 SwapDir::optionObjectSizeParse(char const *option
, const char *value
, int isaReconfig
)
354 if (strcmp(option
, "max-size") == 0) {
356 } else if (strcmp(option
, "min-size") == 0) {
364 int64_t size
= strtoll(value
, NULL
, 10);
366 if (isaReconfig
&& *val
!= size
) {
367 if (allowOptionReconfigure(option
)) {
368 debugs(3, DBG_IMPORTANT
, "cache_dir '" << path
<< "' object " <<
369 option
<< " now " << size
<< " Bytes");
371 debugs(3, DBG_IMPORTANT
, "WARNING: cache_dir '" << path
<< "' "
372 "object " << option
<< " cannot be changed dynamically, " <<
373 "value left unchanged (" << *val
<< " Bytes)");
384 SwapDir::optionObjectSizeDump(StoreEntry
* e
) const
386 if (min_objsize
!= 0)
387 storeAppendPrintf(e
, " min-size=%" PRId64
, min_objsize
);
389 if (max_objsize
!= -1)
390 storeAppendPrintf(e
, " max-size=%" PRId64
, max_objsize
);
393 // some SwapDirs may maintain their indexes and be able to lookup an entry key
395 SwapDir::get(const cache_key
*key
)
401 SwapDir::get(String
const key
, STOREGETCLIENT aCallback
, void *aCallbackData
)
403 fatal("not implemented");