Disks.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 /* DEBUG: section 47 Store Directory Routines */
10 
11 #include "squid.h"
12 #include "Debug.h"
13 #include "globals.h"
14 #include "profiler/Profiler.h"
15 #include "SquidConfig.h"
16 #include "Store.h"
17 #include "store/Disk.h"
18 #include "store/Disks.h"
19 #include "swap_log_op.h"
20 #include "util.h" // for tvSubDsec() which should be in SquidTime.h
21 
29 
32 static int64_t
34 {
35  // entry.objectLen() is negative here when we are still STORE_PENDING
36  int64_t minSize = entry.mem_obj->expectedReplySize();
37 
38  // If entry size is unknown, use already accumulated bytes as an estimate.
39  // Controller::accumulateMore() guarantees that there are enough of them.
40  if (minSize < 0)
41  minSize = entry.mem_obj->endOffset();
42 
43  assert(minSize >= 0);
44  minSize += entry.mem_obj->swap_hdr_sz;
45  return minSize;
46 }
47 
53 static int
55 {
56  const int64_t objsize = objectSizeForDirSelection(*e);
57 
58  // Increment the first candidate once per selection (not once per
59  // iteration) to reduce bias when some disk(s) attract more entries.
60  static int firstCandidate = 0;
61  if (++firstCandidate >= Config.cacheSwap.n_configured)
62  firstCandidate = 0;
63 
64  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
65  const int dirn = (firstCandidate + i) % Config.cacheSwap.n_configured;
66  const SwapDir *sd = dynamic_cast<SwapDir*>(INDEXSD(dirn));
67 
68  int load = 0;
69  if (!sd->canStore(*e, objsize, load))
70  continue;
71 
72  if (load < 0 || load > 1000) {
73  continue;
74  }
75 
76  return dirn;
77  }
78 
79  return -1;
80 }
81 
95 static int
97 {
98  int64_t most_free = 0;
99  int64_t best_objsize = -1;
100  int least_load = INT_MAX;
101  int load;
102  int dirn = -1;
103  int i;
105 
106  const int64_t objsize = objectSizeForDirSelection(*e);
107 
108  for (i = 0; i < Config.cacheSwap.n_configured; ++i) {
109  SD = dynamic_cast<SwapDir *>(INDEXSD(i));
110  SD->flags.selected = false;
111 
112  if (!SD->canStore(*e, objsize, load))
113  continue;
114 
115  if (load < 0 || load > 1000)
116  continue;
117 
118  if (load > least_load)
119  continue;
120 
121  const int64_t cur_free = SD->maxSize() - SD->currentSize();
122 
123  /* If the load is equal, then look in more details */
124  if (load == least_load) {
125  /* best max-size fit */
126  if (best_objsize != -1) {
127  // cache_dir with the smallest max-size gets the known-size object
128  // cache_dir with the largest max-size gets the unknown-size object
129  if ((objsize != -1 && SD->maxObjectSize() > best_objsize) ||
130  (objsize == -1 && SD->maxObjectSize() < best_objsize))
131  continue;
132  }
133 
134  /* most free */
135  if (cur_free < most_free)
136  continue;
137  }
138 
139  least_load = load;
140  best_objsize = SD->maxObjectSize();
141  most_free = cur_free;
142  dirn = i;
143  }
144 
145  if (dirn >= 0)
146  dynamic_cast<SwapDir *>(INDEXSD(dirn))->flags.selected = true;
147 
148  return dirn;
149 }
150 
152  largestMinimumObjectSize(-1),
153  largestMaximumObjectSize(-1),
154  secondLargestMaximumObjectSize(-1)
155 {
156 }
157 
158 SwapDir *
159 Store::Disks::store(int const x) const
160 {
161  return INDEXSD(x);
162 }
163 
164 SwapDir &
165 Store::Disks::dir(const int i) const
166 {
167  SwapDir *sd = INDEXSD(i);
168  assert(sd);
169  return *sd;
170 }
171 
172 int
174 {
175  int result = 0;
176  int j;
177  static int ndir = 0;
178 
179  do {
180  j = 0;
181 
182  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
183  if (ndir >= Config.cacheSwap.n_configured)
184  ndir = ndir % Config.cacheSwap.n_configured;
185 
186  int temp_result = store(ndir)->callback();
187 
188  ++ndir;
189 
190  j += temp_result;
191 
192  result += temp_result;
193 
194  if (j > 100)
195  fatal ("too much io\n");
196  }
197  } while (j > 0);
198 
199  ++ndir;
200 
201  return result;
202 }
203 
204 void
206 {
207  if (Config.cacheSwap.n_configured == 0) {
208  debugs(0, DBG_PARSE_NOTE(DBG_CRITICAL), "No cache_dir stores are configured.");
209  }
210 
211  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
212  if (dir(i).active())
213  store(i)->create();
214  }
215 }
216 
217 StoreEntry *
219 {
220  if (const int cacheDirs = Config.cacheSwap.n_configured) {
221  // ask each cache_dir until the entry is found; use static starting
222  // point to avoid asking the same subset of disks more often
223  // TODO: coordinate with put() to be able to guess the right disk often
224  static int idx = 0;
225  for (int n = 0; n < cacheDirs; ++n) {
226  idx = (idx + 1) % cacheDirs;
227  SwapDir *sd = dynamic_cast<SwapDir*>(INDEXSD(idx));
228  if (!sd->active())
229  continue;
230 
231  if (StoreEntry *e = sd->get(key)) {
232  debugs(20, 7, "cache_dir " << idx << " has: " << *e);
233  return e;
234  }
235  }
236  }
237 
238  debugs(20, 6, "none of " << Config.cacheSwap.n_configured <<
239  " cache_dirs have " << storeKeyText(key));
240  return nullptr;
241 }
242 
243 void
245 {
246  if (Config.Store.objectsPerBucket <= 0)
247  fatal("'store_objects_per_bucket' should be larger than 0.");
248 
249  if (Config.Store.avgObjectSize <= 0)
250  fatal("'store_avg_object_size' should be larger than 0.");
251 
252  /* Calculate size of hash table (maximum currently 64k buckets). */
253  /* this is very bogus, its specific to the any Store maintaining an
254  * in-core index, not global */
256  debugs(20, DBG_IMPORTANT, "Swap maxSize " << (Store::Root().maxSize() >> 10) <<
257  " + " << ( Config.memMaxSize >> 10) << " KB, estimated " << buckets << " objects");
258  buckets /= Config.Store.objectsPerBucket;
259  debugs(20, DBG_IMPORTANT, "Target number of buckets: " << buckets);
260  /* ideally the full scan period should be configurable, for the
261  * moment it remains at approximately 24 hours. */
263  debugs(20, DBG_IMPORTANT, "Using " << store_hash_buckets << " Store buckets");
264  debugs(20, DBG_IMPORTANT, "Max Mem size: " << ( Config.memMaxSize >> 10) << " KB" <<
265  (Config.memShared ? " [shared]" : ""));
266  debugs(20, DBG_IMPORTANT, "Max Swap size: " << (Store::Root().maxSize() >> 10) << " KB");
267 
270 
271  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
272  /* this starts a search of the store dirs, loading their
273  * index. under the new Store api this should be
274  * driven by the StoreHashIndex, not by each store.
275  *
276  * That is, the HashIndex should perform a search of each dir it is
277  * indexing to do the hash insertions. The search is then able to
278  * decide 'from-memory', or 'from-clean-log' or 'from-dirty-log' or
279  * 'from-no-log'.
280  *
281  * Step 1: make the store rebuilds use a search internally
282  * Step 2: change the search logic to use the four modes described
283  * above
284  * Step 3: have the hash index walk the searches itself.
285  */
286  if (dir(i).active())
287  store(i)->init();
288  }
289 
290  if (strcasecmp(Config.store_dir_select_algorithm, "round-robin") == 0) {
292  debugs(47, DBG_IMPORTANT, "Using Round Robin store dir selection");
293  } else {
295  debugs(47, DBG_IMPORTANT, "Using Least Load store dir selection");
296  }
297 }
298 
299 uint64_t
301 {
302  uint64_t result = 0;
303 
304  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
305  if (dir(i).doReportStat())
306  result += store(i)->maxSize();
307  }
308 
309  return result;
310 }
311 
312 uint64_t
314 {
315  uint64_t result = 0;
316 
317  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
318  if (dir(i).doReportStat())
319  result += store(i)->minSize();
320  }
321 
322  return result;
323 }
324 
325 uint64_t
327 {
328  uint64_t result = 0;
329 
330  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
331  if (dir(i).doReportStat())
332  result += store(i)->currentSize();
333  }
334 
335  return result;
336 }
337 
338 uint64_t
340 {
341  uint64_t result = 0;
342 
343  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
344  if (dir(i).doReportStat())
345  result += store(i)->currentCount();
346  }
347 
348  return result;
349 }
350 
351 int64_t
353 {
354  return largestMaximumObjectSize;
355 }
356 
357 void
359 {
360  largestMinimumObjectSize = -1;
361  largestMaximumObjectSize = -1;
362  secondLargestMaximumObjectSize = -1;
363 
364  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
365  const auto &disk = dir(i);
366  if (!disk.active())
367  continue;
368 
369  if (disk.minObjectSize() > largestMinimumObjectSize)
370  largestMinimumObjectSize = disk.minObjectSize();
371 
372  const auto diskMaxObjectSize = disk.maxObjectSize();
373  if (diskMaxObjectSize > largestMaximumObjectSize) {
374  if (largestMaximumObjectSize >= 0) // was set
375  secondLargestMaximumObjectSize = largestMaximumObjectSize;
376  largestMaximumObjectSize = diskMaxObjectSize;
377  }
378  }
379 }
380 
381 int64_t
383 {
384  const auto accumulated = entry.mem_obj->availableForSwapOut();
385 
386  /*
387  * Keep accumulating more bytes until the set of disks eligible to accept
388  * the entry becomes stable, and, hence, accumulating more is not going to
389  * affect the cache_dir selection. A stable set is usually reached
390  * immediately (or soon) because most configurations either do not use
391  * cache_dirs with explicit min-size/max-size limits or use the same
392  * max-size limit for all cache_dirs (and low min-size limits).
393  */
394 
395  // Can the set of min-size cache_dirs accepting this entry change?
396  if (accumulated < largestMinimumObjectSize)
397  return largestMinimumObjectSize - accumulated;
398 
399  // Can the set of max-size cache_dirs accepting this entry change
400  // (other than when the entry exceeds the largest maximum; see below)?
401  if (accumulated <= secondLargestMaximumObjectSize)
402  return secondLargestMaximumObjectSize - accumulated + 1;
403 
404  /*
405  * Checking largestMaximumObjectSize instead eliminates the risk of starting
406  * to swap out an entry that later grows too big, but also implies huge
407  * accumulation in most environments. Accumulating huge entries not only
408  * consumes lots of RAM but also creates a burst of doPages() write requests
409  * that overwhelm the disk. To avoid these problems, we take the risk and
410  * allow swap out now. The disk will quit swapping out if the entry
411  * eventually grows too big for its selected cache_dir.
412  */
413  debugs(20, 3, "no: " << accumulated << '>' <<
414  secondLargestMaximumObjectSize << ',' << largestMinimumObjectSize);
415  return 0;
416 }
417 
418 void
420 {
421  // accumulate per-disk cache stats
422  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
423  StoreInfoStats dirStats;
424  store(i)->getStats(dirStats);
425  stats += dirStats;
426  }
427 
428  // common to all disks
430 
431  // memory cache stats are collected in StoreController::getStats(), for now
432 }
433 
434 void
436 {
437  int i;
438 
439  /* Now go through each store, calling its stat routine */
440 
441  for (i = 0; i < Config.cacheSwap.n_configured; ++i) {
442  storeAppendPrintf(&output, "\n");
443  store(i)->stat(output);
444  }
445 }
446 
447 void
449 {
450  e.disk().reference(e);
451 }
452 
453 bool
455 {
456  return e.disk().dereference(e);
457 }
458 
459 void
461 {
462  Must(e);
463  return e->disk().updateHeaders(e);
464 }
465 
466 void
468 {
469  int i;
470  /* walk each fs */
471 
472  for (i = 0; i < Config.cacheSwap.n_configured; ++i) {
473  /* XXX FixMe: This should be done "in parallell" on the different
474  * cache_dirs, not one at a time.
475  */
476  /* call the maintain function .. */
477  store(i)->maintain();
478  }
479 }
480 
481 void
483 {
484  for (int i = 0; i < Config.cacheSwap.n_configured; ++i)
485  store(i)->sync();
486 }
487 
488 void
490  if (e.swap_filen >= 0)
491  store(e.swap_dirn)->markForUnlink(e);
492 }
493 
494 void
496  if (e.swap_filen >= 0)
497  store(e.swap_dirn)->unlink(e);
498 }
499 
500 bool
501 Store::Disks::anchorCollapsed(StoreEntry &collapsed, bool &inSync)
502 {
503  if (const int cacheDirs = Config.cacheSwap.n_configured) {
504  // ask each cache_dir until the entry is found; use static starting
505  // point to avoid asking the same subset of disks more often
506  // TODO: coordinate with put() to be able to guess the right disk often
507  static int idx = 0;
508  for (int n = 0; n < cacheDirs; ++n) {
509  idx = (idx + 1) % cacheDirs;
510  SwapDir &sd = dir(idx);
511  if (!sd.active())
512  continue;
513 
514  if (sd.anchorCollapsed(collapsed, inSync)) {
515  debugs(20, 3, "cache_dir " << idx << " anchors " << collapsed);
516  return true;
517  }
518  }
519  }
520 
521  debugs(20, 4, "none of " << Config.cacheSwap.n_configured <<
522  " cache_dirs have " << collapsed);
523  return false;
524 }
525 
526 bool
528 {
529  return collapsed.swap_filen >= 0 &&
530  dir(collapsed.swap_dirn).updateCollapsed(collapsed);
531 }
532 
533 bool
535 {
536  for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
537  // A mix is not supported, but we conservatively check every
538  // dir because features like collapsed revalidation should
539  // currently be disabled if any dir is SMP-aware
540  if (dir(i).smpAware())
541  return true;
542  }
543  return false;
544 }
545 
546 /* Store::Disks globals that should be converted to use RegisteredRunner */
547 
548 void
550 {
551  for (int dirn = 0; dirn < Config.cacheSwap.n_configured; ++dirn)
552  INDEXSD(dirn)->openLog();
553 }
554 
555 void
557 {
558  for (int dirn = 0; dirn < Config.cacheSwap.n_configured; ++dirn)
559  INDEXSD(dirn)->closeLog();
560 }
561 
571 int
573 {
574  const StoreEntry *e = NULL;
575  int n = 0;
576 
577  struct timeval start;
578  double dt;
580  int dirn;
581  int notdone = 1;
582 
583  // Check for store_dirs_rebuilding because fatal() often calls us in early
584  // initialization phases, before store log is initialized and ready. Also,
585  // some stores do not support log cleanup during Store rebuilding.
587  debugs(20, DBG_IMPORTANT, "Not currently OK to rewrite swap log.");
588  debugs(20, DBG_IMPORTANT, "storeDirWriteCleanLogs: Operation aborted.");
589  return 0;
590  }
591 
592  debugs(20, DBG_IMPORTANT, "storeDirWriteCleanLogs: Starting...");
593  getCurrentTime();
594  start = current_time;
595 
596  for (dirn = 0; dirn < Config.cacheSwap.n_configured; ++dirn) {
597  sd = dynamic_cast<SwapDir *>(INDEXSD(dirn));
598 
599  if (sd->writeCleanStart() < 0) {
600  debugs(20, DBG_IMPORTANT, "log.clean.start() failed for dir #" << sd->index);
601  continue;
602  }
603  }
604 
605  /*
606  * This may look inefficient as CPU wise it is more efficient to do this
607  * sequentially, but I/O wise the parallellism helps as it allows more
608  * hdd spindles to be active.
609  */
610  while (notdone) {
611  notdone = 0;
612 
613  for (dirn = 0; dirn < Config.cacheSwap.n_configured; ++dirn) {
614  sd = dynamic_cast<SwapDir *>(INDEXSD(dirn));
615 
616  if (NULL == sd->cleanLog)
617  continue;
618 
619  e = sd->cleanLog->nextEntry();
620 
621  if (!e)
622  continue;
623 
624  notdone = 1;
625 
626  if (!sd->canLog(*e))
627  continue;
628 
629  sd->cleanLog->write(*e);
630 
631  if ((++n & 0xFFFF) == 0) {
632  getCurrentTime();
633  debugs(20, DBG_IMPORTANT, " " << std::setw(7) << n <<
634  " entries written so far.");
635  }
636  }
637  }
638 
639  /* Flush */
640  for (dirn = 0; dirn < Config.cacheSwap.n_configured; ++dirn)
641  dynamic_cast<SwapDir *>(INDEXSD(dirn))->writeCleanDone();
642 
643  if (reopen)
645 
646  getCurrentTime();
647 
648  dt = tvSubDsec(start, current_time);
649 
650  debugs(20, DBG_IMPORTANT, " Finished. Wrote " << n << " entries.");
651  debugs(20, DBG_IMPORTANT, " Took "<< std::setw(3)<< std::setprecision(2) << dt <<
652  " seconds ("<< std::setw(6) << ((double) n / (dt > 0.0 ? dt : 1.0)) << " entries/sec).");
653 
654  return n;
655 }
656 
657 /* Globals that should be converted to static Store::Disks methods */
658 
659 void
661 {
662  if (swap->swapDirs == NULL) {
663  swap->n_allocated = 4;
664  swap->swapDirs = static_cast<SwapDir::Pointer *>(xcalloc(swap->n_allocated, sizeof(SwapDir::Pointer)));
665  }
666 
667  if (swap->n_allocated == swap->n_configured) {
668  swap->n_allocated <<= 1;
669  SwapDir::Pointer *const tmp = static_cast<SwapDir::Pointer *>(xcalloc(swap->n_allocated, sizeof(SwapDir::Pointer)));
670  memcpy(tmp, swap->swapDirs, swap->n_configured * sizeof(SwapDir *));
671  xfree(swap->swapDirs);
672  swap->swapDirs = tmp;
673  }
674 }
675 
676 void
678 {
679  int i;
680  /* DON'T FREE THESE FOR RECONFIGURE */
681 
682  if (reconfiguring)
683  return;
684 
685  for (i = 0; i < swap->n_configured; ++i) {
686  /* TODO XXX this lets the swapdir free resources asynchronously
687  * swap->swapDirs[i]->deactivate();
688  * but there may be such a means already.
689  * RBC 20041225
690  */
691  swap->swapDirs[i] = NULL;
692  }
693 
694  safe_free(swap->swapDirs);
695  swap->swapDirs = NULL;
696  swap->n_allocated = 0;
697  swap->n_configured = 0;
698 }
699 
700 /* Globals that should be moved to some Store::UFS-specific logging module */
701 
711 void
712 storeDirSwapLog(const StoreEntry * e, int op)
713 {
714  assert (e);
716  assert(e->swap_filen >= 0);
717  /*
718  * icons and such; don't write them to the swap log
719  */
720 
721  if (EBIT_TEST(e->flags, ENTRY_SPECIAL))
722  return;
723 
724  assert(op > SWAP_LOG_NOP && op < SWAP_LOG_MAX);
725 
726  debugs(20, 3, "storeDirSwapLog: " <<
727  swap_log_op_str[op] << " " <<
728  e->getMD5Text() << " " <<
729  e->swap_dirn << " " <<
730  std::hex << std::uppercase << std::setfill('0') << std::setw(8) << e->swap_filen);
731 
732  dynamic_cast<SwapDir *>(INDEXSD(e->swap_dirn))->logEntry(*e, op);
733 }
734 
virtual void stat(StoreEntry &) const override
Definition: Disks.cc:435
CleanLog * cleanLog
Definition: Disk.h:134
sdirno swap_dirn
Definition: Store.h:179
virtual int64_t maxObjectSize() const override
the maximum size of a storable object; -1 if unlimited
Definition: Disk.cc:103
virtual void unlink(StoreEntry &) override
remove the entry from the store
Definition: Disks.cc:495
static int store_dirs_rebuilding
the number of cache_dirs being rebuilt; TODO: move to Disks::Rebuilding
Definition: Controller.h:90
hash_table * store_table
virtual bool active() const
Definition: Disk.cc:236
virtual void sync() override
prepare for shutdown
Definition: Disks.cc:482
#define assert(EX)
Definition: assert.h:17
virtual bool dereference(StoreEntry &e) override
Definition: Disks.cc:454
void updateLimits()
slowly calculate (and cache) hi/lo watermarks and similar limits
Definition: Disks.cc:358
size_t swap_hdr_sz
Definition: MemObject.h:170
double open_disk_fd
number of opened disk files
Definition: StoreStats.h:35
void storeDirSwapLog(const StoreEntry *e, int op)
Definition: Disks.cc:712
virtual uint64_t currentCount() const override
the total number of objects stored right now
Definition: Disks.cc:339
virtual uint64_t minSize() const override
the minimum size the store will shrink to via normal housekeeping
Definition: Disks.cc:313
unsigned char cache_key
Store key.
Definition: forward.h:29
#define xcalloc
Definition: membanger.c:57
virtual void updateHeaders(StoreEntry *)
make stored metadata and HTTP headers the same as in the given entry
Definition: Controlled.h:29
int i
Definition: membanger.c:49
int64_t endOffset() const
Definition: MemObject.cc:232
HASHHASH storeKeyHashHash
#define safe_free(x)
Definition: xalloc.h:73
const char * storeKeyText(const cache_key *key)
YesNoNone memShared
whether the memory cache is shared among workers
Definition: SquidConfig.h:79
virtual void markForUnlink(StoreEntry &) override
expect an unlink() call after the entry becomes idle
Definition: Disks.cc:489
class Ping::pingStats_ stats
struct Store::Disk::Flags flags
virtual void reference(StoreEntry &) override
somebody needs this entry (many cache replacement policies need to know)
Definition: Disks.cc:448
bool canLog(StoreEntry const &e) const
Definition: Disk.cc:188
int64_t accumulateMore(const StoreEntry &) const
Definition: Disks.cc:382
struct SquidConfig::@110 Store
sfileno swap_filen
unique ID inside a cache_dir for swapped out entries; -1 for others
Definition: Store.h:177
#define DBG_CRITICAL
Definition: Debug.h:44
#define DBG_PARSE_NOTE(x)
Definition: Debug.h:49
Controller & Root()
safely access controller singleton
Definition: Controller.cc:619
virtual uint64_t currentSize() const =0
current size
High-level store statistics used by mgr:info action. Used inside PODs!
Definition: StoreStats.h:13
virtual bool dereference(StoreEntry &e) override
Definition: Disk.cc:139
struct timeval current_time
Definition: stub_time.cc:15
static int64_t objectSizeForDirSelection(const StoreEntry &entry)
Definition: Disks.cc:33
int store_hash_buckets
void storeDirOpenSwapLogs()
Definition: Disks.cc:549
virtual void reference(StoreEntry &e) override
somebody needs this entry (many cache replacement policies need to know)
Definition: Disk.cc:136
SwapDir & dir(int const idx) const
Definition: Disks.cc:165
virtual uint64_t maxSize() const override
Definition: Controller.cc:153
virtual void getStats(StoreInfoStats &stats) const override
collect statistics
Definition: Disks.cc:419
int64_t avgObjectSize
Definition: SquidConfig.h:261
virtual uint64_t maxSize() const override
Definition: Disks.cc:300
STDIRSELECT * storeDirSelectSwapDir
Definition: Disks.cc:28
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:123
#define DBG_IMPORTANT
Definition: Debug.h:45
HASHCMP storeKeyHashCmp
virtual void maintain() override
perform regular periodic maintenance; TODO: move to UFSSwapDir::Maintain
Definition: Disks.cc:467
void fatal(const char *message)
Definition: fatal.cc:39
virtual void write(StoreEntry const &)=0
uint16_t flags
Definition: Store.h:173
SQUIDCEXTERN hash_table * hash_create(HASHCMP *, int, HASHHASH *)
Definition: hash.cc:109
virtual bool updateCollapsed(StoreEntry &e) override
Definition: Disks.cc:527
int storeDirWriteCleanLogs(int reopen)
Definition: Disks.cc:572
void free_cachedir(Store::DiskConfig *swap)
Definition: Disks.cc:677
MemObject * mem_obj
Definition: Store.h:162
int objectsPerBucket
Definition: SquidConfig.h:260
virtual uint64_t maxSize() const override
Definition: Disk.h:48
void allocate_new_swapdir(Store::DiskConfig *swap)
Definition: Disks.cc:660
#define INDEXSD(i)
Definition: SquidConfig.h:64
int STDIRSELECT(const StoreEntry *e)
Definition: Disks.h:75
const char * swap_log_op_str[]
#define Must(cond)
Definition: TextException.h:89
int index
Definition: Disk.h:97
time_t getCurrentTime(void)
Get current time.
virtual const char * getMD5Text() const
Definition: store.cc:181
RefCount< SwapDir > * swapDirs
Definition: SquidConfig.h:58
Store::Disk & disk() const
the disk this entry is [being] cached on; asserts for entries w/o a disk
Definition: store.cc:2055
virtual void init() override
Definition: Disks.cc:244
Store::DiskConfig cacheSwap
Definition: SquidConfig.h:418
int store_open_disk_fd
virtual uint64_t currentSize() const override
current size
Definition: Disks.cc:326
virtual bool anchorCollapsed(StoreEntry &, bool &)
Definition: Controlled.h:34
size_t memMaxSize
Definition: SquidConfig.h:81
virtual bool anchorCollapsed(StoreEntry &e, bool &inSync) override
Definition: Disks.cc:501
SwapDir * store(int const x) const
Definition: Disks.cc:159
void const cache_key * key
int storeKeyHashBuckets(int nbuckets)
static struct tok * buckets[HASHSIZE]
Definition: parse.c:219
static STDIRSELECT storeDirSelectSwapDirRoundRobin
Definition: Disks.cc:22
#define INT_MAX
Definition: types.h:76
virtual int writeCleanStart()
Definition: Disk.cc:218
virtual bool smpAware() const override
Definition: Disks.cc:534
virtual void create() override
create system resources needed for this store to operate in the future
Definition: Disks.cc:205
virtual int callback() override
called once every main loop iteration; TODO: Move to UFS code.
Definition: Disks.cc:173
static STDIRSELECT storeDirSelectSwapDirLeastLoad
Definition: Disks.cc:23
virtual bool canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const =0
check whether we can store the entry; if we can, report current load
Definition: Disk.cc:164
#define xfree
virtual int64_t maxObjectSize() const override
the maximum size of a storable object; -1 if unlimited
Definition: Disks.cc:352
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)
Definition: store.cc:904
int64_t availableForSwapOut() const
buffered bytes we have not swapped out yet
Definition: MemObject.cc:499
#define EBIT_TEST(flag, bit)
Definition: defines.h:107
virtual StoreEntry * get(const cache_key *) override
Retrieve a store entry from the store (blocking)
Definition: Disks.cc:218
class SquidConfig Config
Definition: SquidConfig.cc:12
#define NULL
Definition: types.h:166
char * store_dir_select_algorithm
Definition: SquidConfig.h:503
virtual const StoreEntry * nextEntry()=0
int64_t expectedReplySize() const
Definition: MemObject.cc:256
int reconfiguring
SQUIDCEXTERN double tvSubDsec(struct timeval, struct timeval)
Definition: util.c:46
Swap swap
cache_mem stats
Definition: StoreStats.h:48
virtual StoreEntry * get(const cache_key *) override
Retrieve a store entry from the store (blocking)
Definition: Disk.cc:393
virtual void updateHeaders(StoreEntry *) override
make stored metadata and HTTP headers the same as in the given entry
Definition: Disks.cc:460
manages a single cache_dir
Definition: Disk.h:21
void storeDirCloseSwapLogs()
Definition: Disks.cc:556

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors