Controller.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2018 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 20 Store Controller */
10 
11 #include "squid.h"
12 #include "mem_node.h"
13 #include "MemStore.h"
14 #include "profiler/Profiler.h"
15 #include "SquidConfig.h"
16 #include "SquidMath.h"
17 #include "store/Controller.h"
18 #include "store/Disks.h"
19 #include "store/LocalSearch.h"
20 #include "tools.h"
21 #include "Transients.h"
22 
23 #if HAVE_SYS_WAIT_H
24 #include <sys/wait.h>
25 #endif
26 
27 /*
28  * store_dirs_rebuilding is initialized to _1_ as a hack so that
29  * storeDirWriteCleanLogs() doesn't try to do anything unless _all_
30  * cache_dirs have been read. For example, without this hack, Squid
31  * will try to write clean log files if -kparse fails (becasue it
32  * calls fatal()).
33  */
35 
37  swapDir(new Disks),
38  memStore(NULL),
39  transients(NULL)
40 {
42 }
43 
45 {
46  delete memStore;
47  delete transients;
48  delete swapDir;
49 
50  if (store_table) {
53  store_table = nullptr;
54  }
55 }
56 
57 void
59 {
61  memStore = new MemStore;
62  memStore->init();
63  }
64 
65  swapDir->init();
66 
68  smpAware()) {
69  transients = new Transients;
70  transients->init();
71  }
72 }
73 
74 void
76 {
77  swapDir->create();
78 
79 #if !_SQUID_WINDOWS_
80  pid_t pid;
81  do {
82  PidStatus status;
83  pid = WaitForAnyPid(status, WNOHANG);
84  } while (pid > 0 || (pid < 0 && errno == EINTR));
85 #endif
86 }
87 
88 void
90 {
91  static time_t last_warn_time = 0;
92 
93  PROF_start(storeMaintainSwapSpace);
94  swapDir->maintain();
95 
96  /* this should be emitted by the oversize dir, not globally */
97 
98  if (Root().currentSize() > Store::Root().maxSize()) {
99  if (squid_curtime - last_warn_time > 10) {
100  debugs(20, DBG_CRITICAL, "WARNING: Disk space over limit: "
101  << Store::Root().currentSize() / 1024.0 << " KB > "
102  << (Store::Root().maxSize() >> 10) << " KB");
103  last_warn_time = squid_curtime;
104  }
105  }
106 
107  PROF_stop(storeMaintainSwapSpace);
108 }
109 
110 void
112 {
113  if (memStore)
114  memStore->getStats(stats);
115  else {
116  // move this code to a non-shared memory cache class when we have it
117  stats.mem.shared = false;
118  stats.mem.capacity = Config.memMaxSize;
119  stats.mem.size = mem_node::StoreMemSize();
120  stats.mem.count = hot_obj_count;
121  }
122 
123  swapDir->getStats(stats);
124 
125  // low-level info not specific to memory or disk cache
128 }
129 
130 void
132 {
133  storeAppendPrintf(&output, "Store Directory Statistics:\n");
134  storeAppendPrintf(&output, "Store Entries : %lu\n",
135  (unsigned long int)StoreEntry::inUseCount());
136  storeAppendPrintf(&output, "Maximum Swap Size : %" PRIu64 " KB\n",
137  maxSize() >> 10);
138  storeAppendPrintf(&output, "Current Store Swap Size: %.2f KB\n",
139  currentSize() / 1024.0);
140  storeAppendPrintf(&output, "Current Capacity : %.2f%% used, %.2f%% free\n",
141  Math::doublePercent(currentSize(), maxSize()),
142  Math::doublePercent((maxSize() - currentSize()), maxSize()));
143 
144  if (memStore)
145  memStore->stat(output);
146 
147  /* now the swapDir */
148  swapDir->stat(output);
149 }
150 
151 /* if needed, this could be taught to cache the result */
152 uint64_t
154 {
155  /* TODO: include memory cache ? */
156  return swapDir->maxSize();
157 }
158 
159 uint64_t
161 {
162  /* TODO: include memory cache ? */
163  return swapDir->minSize();
164 }
165 
166 uint64_t
168 {
169  /* TODO: include memory cache ? */
170  return swapDir->currentSize();
171 }
172 
173 uint64_t
175 {
176  /* TODO: include memory cache ? */
177  return swapDir->currentCount();
178 }
179 
180 int64_t
182 {
183  /* TODO: include memory cache ? */
184  return swapDir->maxObjectSize();
185 }
186 
187 void
189 {
190  swapDir->updateLimits();
191 
192  store_swap_high = (long) (((float) maxSize() *
193  (float) Config.Swap.highWaterMark) / (float) 100);
194  store_swap_low = (long) (((float) maxSize() *
195  (float) Config.Swap.lowWaterMark) / (float) 100);
197 
198  // TODO: move this into a memory cache class when we have one
199  const int64_t memMax = static_cast<int64_t>(min(Config.Store.maxInMemObjSize, Config.memMaxSize));
200  const int64_t disksMax = swapDir ? swapDir->maxObjectSize() : 0;
201  store_maxobjsize = std::max(disksMax, memMax);
202 }
203 
204 StoreSearch *
206 {
207  // this is the only kind of search we currently support
208  return NewLocalSearch();
209 }
210 
211 void
213 {
214  if (memStore)
215  memStore->sync();
216  swapDir->sync();
217 }
218 
219 /*
220  * handle callbacks all avaliable fs'es
221  */
222 int
224 {
225  /* This will likely double count. Thats ok. */
226  PROF_start(storeDirCallback);
227 
228  /* mem cache callbacks ? */
229  int result = swapDir->callback();
230 
231  PROF_stop(storeDirCallback);
232 
233  return result;
234 }
235 
237 void
239 {
240  // special entries do not belong to any specific Store, but are IN_MEMORY
241  if (EBIT_TEST(e.flags, ENTRY_SPECIAL))
242  return;
243 
244  /* Notify the fs that we're referencing this object again */
245 
246  if (e.hasDisk())
247  swapDir->reference(e);
248 
249  // Notify the memory cache that we're referencing this object again
250  if (memStore && e.mem_status == IN_MEMORY)
251  memStore->reference(e);
252 
253  // TODO: move this code to a non-shared memory cache class when we have it
254  if (e.mem_obj) {
255  if (mem_policy->Referenced)
257  }
258 }
259 
262 bool
264 {
265  // special entries do not belong to any specific Store, but are IN_MEMORY
266  if (EBIT_TEST(e.flags, ENTRY_SPECIAL))
267  return true;
268 
269  bool keepInStoreTable = false; // keep only if somebody needs it there
270 
271  /* Notify the fs that we're not referencing this object any more */
272 
273  if (e.hasDisk())
274  keepInStoreTable = swapDir->dereference(e) || keepInStoreTable;
275 
276  // Notify the memory cache that we're not referencing this object any more
277  if (memStore && e.mem_status == IN_MEMORY)
278  keepInStoreTable = memStore->dereference(e) || keepInStoreTable;
279 
280  // TODO: move this code to a non-shared memory cache class when we have it
281  if (e.mem_obj) {
284  // non-shared memory cache relies on store_table
285  if (!memStore)
286  keepInStoreTable = wantsLocalMemory || keepInStoreTable;
287  }
288 
289  return keepInStoreTable;
290 }
291 
292 bool
294 {
295  // assuming a public key, checking Transients should cover all cases.
296  return transients && transients->markedForDeletion(key);
297 }
298 
299 bool
301 {
302  // The opposite check order could miss a reader that has arrived after the
303  // !readers() and before the markedForDeletion() check.
304  return markedForDeletion(reinterpret_cast<const cache_key*>(e.key)) &&
305  transients && !transients->readers(e);
306 }
307 
308 bool
310 {
311  return swapDir->hasReadableEntry(e);
312 }
313 
314 StoreEntry *
316 {
317  if (const auto entry = peek(key)) {
318  try {
319  if (!entry->key)
320  allowSharing(*entry, key);
321  checkTransients(*entry);
322  entry->touch();
323  referenceBusy(*entry);
324  return entry;
325  } catch (const std::exception &ex) {
326  debugs(20, 2, "failed with " << *entry << ": " << ex.what());
327  entry->release(true);
328  // fall through
329  }
330  }
331  return NULL;
332 }
333 
335 void
337 {
338  // TODO: refactor to throw on anchorToCache() inSync errors!
339 
340  // anchorToCache() below and many find() callers expect a registered entry
341  addReading(&entry, key);
342 
343  if (entry.hasTransients()) {
344  bool inSync = false;
345  const bool found = anchorToCache(entry, inSync);
346  if (found && !inSync)
347  throw TexcHere("cannot sync");
348  }
349 }
350 
351 StoreEntry *
353 {
354  // We could check for mem_obj presence (and more), moving and merging some
355  // of the duplicated neighborsUdpAck() and neighborsHtcpReply() code here,
356  // but that would mean polluting Store with HTCP/ICP code. Instead, we
357  // should encapsulate callback-related data in a protocol-neutral MemObject
358  // member or use an HTCP/ICP-specific index rather than store_table.
359 
360  // cannot reuse peekAtLocal() because HTCP/ICP callbacks may use private keys
361  return static_cast<StoreEntry*>(hash_lookup(store_table, key));
362 }
363 
367 StoreEntry *
369 {
370  if (StoreEntry *e = static_cast<StoreEntry*>(hash_lookup(store_table, key))) {
371  // callers must only search for public entries
372  assert(!EBIT_TEST(e->flags, KEY_PRIVATE));
373  assert(e->publicKey());
374  checkTransients(*e);
375 
376  // TODO: ignore and maybe handleIdleEntry() unlocked intransit entries
377  // because their backing store slot may be gone already.
378  return e;
379  }
380  return nullptr;
381 }
382 
383 StoreEntry *
385 {
386  debugs(20, 3, storeKeyText(key));
387 
388  if (markedForDeletion(key)) {
389  debugs(20, 3, "ignoring marked in-transit " << storeKeyText(key));
390  return nullptr;
391  }
392 
393  if (StoreEntry *e = peekAtLocal(key)) {
394  debugs(20, 3, "got local in-transit entry: " << *e);
395  return e;
396  }
397 
398  // Must search transients before caches because we must sync those we find.
399  if (transients) {
400  if (StoreEntry *e = transients->get(key)) {
401  debugs(20, 3, "got shared in-transit entry: " << *e);
402  return e;
403  }
404  }
405 
406  if (memStore) {
407  if (StoreEntry *e = memStore->get(key)) {
408  debugs(20, 3, HERE << "got mem-cached entry: " << *e);
409  return e;
410  }
411  }
412 
413  if (swapDir) {
414  if (StoreEntry *e = swapDir->get(key)) {
415  debugs(20, 3, "got disk-cached entry: " << *e);
416  return e;
417  }
418  }
419 
420  debugs(20, 4, "cannot locate " << storeKeyText(key));
421  return nullptr;
422 }
423 
424 bool
426 {
427  return transients && e.hasTransients() && transients->isReader(e);
428 }
429 
430 bool
432 {
433  return transients && e.hasTransients() && transients->isWriter(e);
434 }
435 
436 int64_t
438 {
439  return swapDir ? swapDir->accumulateMore(entry) : 0;
440  // The memory cache should not influence for-swapout accumulation decision.
441 }
442 
443 // Must be called from StoreEntry::release() or releaseRequest() because
444 // those methods currently manage local indexing of StoreEntry objects.
445 // TODO: Replace StoreEntry::release*() with Root().evictCached().
446 void
448 {
449  debugs(20, 7, e);
450  if (transients)
451  transients->evictCached(e);
452  memoryEvictCached(e);
453  if (swapDir)
454  swapDir->evictCached(e);
455 }
456 
457 void
459 {
460  debugs(20, 7, storeKeyText(key));
461 
462  if (StoreEntry *entry = peekAtLocal(key)) {
463  debugs(20, 5, "marking local in-transit " << *entry);
464  entry->release(true);
465  return;
466  }
467 
468  if (memStore)
469  memStore->evictIfFound(key);
470  if (swapDir)
471  swapDir->evictIfFound(key);
472  if (transients)
473  transients->evictIfFound(key);
474 }
475 
477 bool
478 Store::Controller::memoryCacheHasSpaceFor(const int pagesRequired) const
479 {
480  // XXX: We count mem_nodes but may free shared memory pages instead.
481  const auto fits = mem_node::InUseCount() + pagesRequired <= store_pages_max;
482  debugs(20, 7, fits << ": " << mem_node::InUseCount() << '+' << pagesRequired << '?' << store_pages_max);
483  return fits;
484 }
485 
486 void
487 Store::Controller::freeMemorySpace(const int bytesRequired)
488 {
489  const auto pagesRequired = (bytesRequired + SM_PAGE_SIZE-1) / SM_PAGE_SIZE;
490 
491  if (memoryCacheHasSpaceFor(pagesRequired))
492  return;
493 
494  // XXX: When store_pages_max is smaller than pagesRequired, we should not
495  // look for more space (but we do because we want to abandon idle entries?).
496 
497  // limit our performance impact to one walk per second
498  static time_t lastWalk = 0;
499  if (lastWalk == squid_curtime)
500  return;
501  lastWalk = squid_curtime;
502 
503  debugs(20, 2, "need " << pagesRequired << " pages");
504 
505  // let abandon()/handleIdleEntry() know about the impeding memory shortage
506  memoryPagesDebt_ = pagesRequired;
507 
508  // XXX: SMP-unaware: Walkers should iterate memory cache, not store_table.
509  // XXX: Limit iterations by time, not arbitrary count.
510  const auto walker = mem_policy->PurgeInit(mem_policy, 100000);
511  int removed = 0;
512  while (const auto entry = walker->Next(walker)) {
513  // Abandoned memory cache entries are purged during memory shortage.
514  entry->abandon(__FUNCTION__); // may delete entry
515  ++removed;
516 
517  if (memoryCacheHasSpaceFor(pagesRequired))
518  break;
519  }
520  // TODO: Move to RemovalPolicyWalker::Done() that has more/better details.
521  debugs(20, 3, "removed " << removed << " out of " << hot_obj_count << " memory-cached entries");
522  walker->Done(walker);
523  memoryPagesDebt_ = 0;
524 }
525 
526 // move this into [non-shared] memory cache class when we have one
528 bool
530 {
531  if (!e.memoryCachable())
532  return false;
533 
534  // does the current and expected size obey memory caching limits?
535  assert(e.mem_obj);
536  const int64_t loadedSize = e.mem_obj->endOffset();
537  const int64_t expectedSize = e.mem_obj->expectedReplySize(); // may be < 0
538  const int64_t ramSize = max(loadedSize, expectedSize);
539  const int64_t ramLimit = min(
540  static_cast<int64_t>(Config.memMaxSize),
541  static_cast<int64_t>(Config.Store.maxInMemObjSize));
542  return ramSize <= ramLimit;
543 }
544 
545 void
546 Store::Controller::memoryOut(StoreEntry &e, const bool preserveSwappable)
547 {
548  bool keepInLocalMemory = false;
549  if (memStore)
550  memStore->write(e); // leave keepInLocalMemory false
551  else
552  keepInLocalMemory = keepForLocalMemoryCache(e);
553 
554  debugs(20, 7, HERE << "keepInLocalMemory: " << keepInLocalMemory);
555 
556  if (!keepInLocalMemory)
557  e.trimMemory(preserveSwappable);
558 }
559 
562 void
564 {
565  // TODO: Untangle memory caching from mem_obj.
566  if (memStore)
567  memStore->evictCached(e);
568  else // TODO: move into [non-shared] memory cache class when we have one
569  if (!e.locked())
570  e.destroyMemObject();
571 }
572 
573 void
575 {
576  if (memStore)
577  memStore->disconnect(e);
578  // else nothing to do for non-shared memory cache
579 }
580 
581 void
583 {
584  // Marking the transients entry is sufficient to prevent new readers from
585  // starting to wait for `e` updates and to inform the current readers (and,
586  // hence, Broadcast() recipients) about the underlying Store problems.
587  if (transients && e.hasTransients())
588  transients->evictCached(e);
589 }
590 
591 void
593 {
594  // transients->isWriter(e) is false if `e` is writing to its second store
595  // after finishing writing to its first store: At the end of the first swap
596  // out, the transients writer becomes a reader and (XXX) we never switch
597  // back to writing, even if we start swapping out again (to another store).
598  if (transients && e.hasTransients() && transients->isWriter(e))
599  transients->completeWriting(e);
600 }
601 
602 int
604 {
605  return (transients && e.hasTransients()) ?
606  transients->readers(e) : 0;
607 }
608 
609 void
611 {
612  if (transients)
613  transients->disconnect(e);
614 }
615 
616 void
618 {
619  bool keepInLocalMemory = false;
620 
621  if (EBIT_TEST(e.flags, ENTRY_SPECIAL)) {
622  // Icons (and cache digests?) should stay in store_table until we
623  // have a dedicated storage for them (that would not purge them).
624  // They are not managed [well] by any specific Store handled below.
625  keepInLocalMemory = true;
626  } else if (memStore) {
627  // leave keepInLocalMemory false; memStore maintains its own cache
628  } else {
629  keepInLocalMemory = keepForLocalMemoryCache(e) && // in good shape and
630  // the local memory cache is not overflowing
631  memoryCacheHasSpaceFor(memoryPagesDebt_);
632  }
633 
634  // An idle, unlocked entry that only belongs to a SwapDir which controls
635  // its own index, should not stay in the global store_table.
636  if (!dereferenceIdle(e, keepInLocalMemory)) {
637  debugs(20, 5, HERE << "destroying unlocked entry: " << &e << ' ' << e);
638  destroyStoreEntry(static_cast<hash_link*>(&e));
639  return;
640  }
641 
642  debugs(20, 5, HERE << "keepInLocalMemory: " << keepInLocalMemory);
643 
644  // TODO: move this into [non-shared] memory cache class when we have one
645  if (keepInLocalMemory) {
647  e.mem_obj->unlinkRequest();
648  return;
649  }
650 
651  // We know the in-memory data will be gone. Get rid of the entire entry if
652  // it has nothing worth preserving on disk either.
653  if (!e.swappedOut()) {
654  e.release(); // deletes e
655  return;
656  }
657 
658  memoryEvictCached(e); // may already be gone
659  // and keep the entry in store_table for its on-disk data
660 }
661 
662 void
664 {
665  /* update the old entry object */
666  Must(old);
667  HttpReply *oldReply = const_cast<HttpReply*>(old->getReply());
668  Must(oldReply);
669 
670  const bool modified = oldReply->updateOnNotModified(newer.getReply());
671  if (!old->timestampsSet() && !modified)
672  return;
673 
674  /* update stored image of the old entry */
675 
676  if (memStore && old->mem_status == IN_MEMORY && !EBIT_TEST(old->flags, ENTRY_SPECIAL))
677  memStore->updateHeaders(old);
678 
679  if (old->hasDisk())
680  swapDir->updateHeaders(old);
681 }
682 
683 bool
685  const HttpRequestMethod &reqMethod)
686 {
687  const KeyScope keyScope = reqFlags.refresh ? ksRevalidation : ksDefault;
688  if (e->makePublic(keyScope)) { // this is needed for both local and SMP collapsing
689  debugs(20, 3, "may " << (transients && e->hasTransients() ?
690  "SMP-" : "locally-") << "collapse " << *e);
691  return true;
692  }
693  return false;
694 }
695 
696 void
698 {
699  if (transients)
700  transients->monitorIo(e, key, Store::ioReading);
701  e->hashInsert(key);
702 }
703 
704 void
706 {
707  assert(e);
708  if (EBIT_TEST(e->flags, ENTRY_SPECIAL))
709  return; // constant memory-resident entries do not need transients
710 
711  if (transients)
712  transients->monitorIo(e, key, Store::ioWriting);
713  // else: non-SMP configurations do not need transients
714 }
715 
716 void
718 {
719  assert(transients);
720 
721  StoreEntry *collapsed = transients->findCollapsed(xitIndex);
722  if (!collapsed) { // the entry is no longer active, ignore update
723  debugs(20, 7, "not SMP-syncing not-transient " << xitIndex);
724  return;
725  }
726 
727  if (!collapsed->locked()) {
728  debugs(20, 3, "skipping (and may destroy) unlocked " << *collapsed);
729  handleIdleEntry(*collapsed);
730  return;
731  }
732 
733  assert(collapsed->mem_obj);
734 
735  if (EBIT_TEST(collapsed->flags, ENTRY_ABORTED)) {
736  debugs(20, 3, "skipping already aborted " << *collapsed);
737  return;
738  }
739 
740  debugs(20, 7, "syncing " << *collapsed);
741 
742  bool abortedByWriter = false;
743  bool waitingToBeFreed = false;
744  transients->status(*collapsed, abortedByWriter, waitingToBeFreed);
745 
746  if (waitingToBeFreed) {
747  debugs(20, 3, "will release " << *collapsed << " due to waitingToBeFreed");
748  collapsed->release(true); // may already be marked
749  }
750 
751  if (transients->isWriter(*collapsed))
752  return; // readers can only change our waitingToBeFreed flag
753 
754  assert(transients->isReader(*collapsed));
755 
756  if (abortedByWriter) {
757  debugs(20, 3, "aborting " << *collapsed << " because its writer has aborted");
758  collapsed->abort();
759  return;
760  }
761 
762  bool found = false;
763  bool inSync = false;
764  if (memStore && collapsed->mem_obj->memCache.io == MemObject::ioDone) {
765  found = true;
766  inSync = true;
767  debugs(20, 7, "fully mem-loaded " << *collapsed);
768  } else if (memStore && collapsed->hasMemStore()) {
769  found = true;
770  inSync = memStore->updateAnchored(*collapsed);
771  // TODO: handle entries attached to both memory and disk
772  } else if (swapDir && collapsed->hasDisk()) {
773  found = true;
774  inSync = swapDir->updateAnchored(*collapsed);
775  } else {
776  found = anchorToCache(*collapsed, inSync);
777  }
778 
779  if (waitingToBeFreed && !found) {
780  debugs(20, 3, "aborting unattached " << *collapsed <<
781  " because it was marked for deletion before we could attach it");
782  collapsed->abort();
783  return;
784  }
785 
786  if (inSync) {
787  debugs(20, 5, "synced " << *collapsed);
788  collapsed->invokeHandlers();
789  return;
790  }
791 
792  if (found) { // unrecoverable problem syncing this entry
793  debugs(20, 3, "aborting unsyncable " << *collapsed);
794  collapsed->abort();
795  return;
796  }
797 
798  // the entry is still not in one of the caches
799  debugs(20, 7, "waiting " << *collapsed);
800 }
801 
805 bool
807 {
808  assert(entry.hasTransients());
809  assert(transientsReader(entry));
810 
811  debugs(20, 7, "anchoring " << entry);
812 
813  bool found = false;
814  if (memStore)
815  found = memStore->anchorToCache(entry, inSync);
816  if (!found && swapDir)
817  found = swapDir->anchorToCache(entry, inSync);
818 
819  if (found) {
820  if (inSync)
821  debugs(20, 7, "anchored " << entry);
822  else
823  debugs(20, 5, "failed to anchor " << entry);
824  } else {
825  debugs(20, 7, "skipping not yet cached " << entry);
826  }
827 
828  return found;
829 }
830 
831 bool
833 {
834  return memStore || (swapDir && swapDir->smpAware());
835 }
836 
837 void
839 {
840  if (EBIT_TEST(e.flags, ENTRY_SPECIAL))
841  return;
842  assert(!transients || e.hasTransients());
843 }
844 
845 namespace Store {
847 }
848 
851 {
852  assert(TheRoot);
853  return *TheRoot;
854 }
855 
856 void
858 {
859  TheRoot = root ? root : new Controller;
860 }
861 
862 void
864 {
865  TheRoot = nullptr;
866 }
867 
bool memoryCacheHasSpaceFor(const int pagesRequired) const
whether the memory cache is allowed to store that many additional pages
Definition: Controller.cc:478
void Init(Controller *root=nullptr)
initialize the storage module; a custom root is used by unit tests only
Definition: Controller.cc:857
StoreSearch * search()
Definition: Controller.cc:205
static int store_dirs_rebuilding
the number of cache_dirs being rebuilt; TODO: move to Disks::Rebuilding
Definition: Controller.h:134
hash_table * store_table
int PidStatus
Definition: tools.h:94
#define assert(EX)
Definition: assert.h:17
RemovalPolicyNode repl
Definition: MemObject.h:171
size_t maxInMemObjSize
Definition: SquidConfig.h:264
virtual void init() override
Definition: Transients.cc:41
SQUIDCEXTERN void hashFreeMemory(hash_table *)
Definition: hash.cc:272
virtual void release(const bool shareable=false)
Definition: store.cc:1207
size_t store_pages_max
StoreEntry * find(const cache_key *)
Definition: Controller.cc:315
void unlinkRequest()
Definition: MemObject.h:56
double size
bytes currently in use
Definition: StoreStats.h:20
bool timestampsSet()
Definition: store.cc:1472
struct SquidConfig::@113 onoff
int collapsed_forwarding
Definition: SquidConfig.h:323
unsigned char cache_key
Store key.
Definition: forward.h:29
pid_t WaitForAnyPid(PidStatus &status, int flags)
Definition: tools.h:111
virtual void sync() override
prepare for shutdown
Definition: Controller.cc:212
int64_t endOffset() const
Definition: MemObject.cc:229
bool hasTransients() const
whether there is a corresponding locked transients table entry
Definition: Store.h:187
RemovalPolicy * mem_policy
Definition: MemObject.cc:45
void stopSharing(StoreEntry &)
stop any current (and prevent any future) SMP sharing of the given entry
Definition: Controller.cc:582
int64_t store_maxobjsize
static size_t inUseCount()
Definition: store.cc:175
virtual void init() override
Definition: MemStore.cc:176
const char * storeKeyText(const cache_key *key)
double mem_object_count
number of MemObject objects in existence
Definition: StoreStats.h:53
YesNoNone memShared
whether the memory cache is shared among workers
Definition: SquidConfig.h:79
bool hasDisk(const sdirno dirn=-1, const sfileno filen=-1) const
Definition: store.cc:2009
Io io
current I/O state
Definition: MemObject.h:155
void freeMemorySpace(const int spaceRequired)
Definition: Controller.cc:487
class Ping::pingStats_ stats
#define Must(condition)
Like assert() but throws an exception instead of aborting the process.
Definition: TextException.h:69
static size_t inUseCount()
Definition: MemObject.cc:48
bool dereferenceIdle(StoreEntry &, bool wantsLocalMemory)
Definition: Controller.cc:263
#define DBG_CRITICAL
Definition: Debug.h:45
static size_t StoreMemSize()
Definition: mem_node.cc:61
void referenceBusy(StoreEntry &e)
update reference counters of the recently touched entry
Definition: Controller.cc:238
Controller & Root()
safely access controller singleton
Definition: Controller.cc:850
High-level store statistics used by mgr:info action. Used inside PODs!
Definition: StoreStats.h:13
int lowWaterMark
Definition: SquidConfig.h:76
double store_entry_count
number of StoreEntry objects in existence
Definition: StoreStats.h:52
double count
number of cached objects
Definition: StoreStats.h:21
void destroyMemObject()
Definition: store.cc:371
A const & max(A const &lhs, A const &rhs)
MemCache memCache
current [shared] memory caching state for the entry
Definition: MemObject.h:157
bool IamWorkerProcess()
whether the current process handles HTTP transactions and such
Definition: stub_tools.cc:49
time_t squid_curtime
Definition: stub_time.cc:17
void updateLimits()
slowly calculate (and cache) hi/lo watermarks and similar limits
Definition: Controller.cc:188
void transientsDisconnect(StoreEntry &)
disassociates the entry from the intransit table
Definition: Controller.cc:610
virtual bool smpAware() const override
Definition: Controller.cc:832
double capacity
the size limit
Definition: StoreStats.h:22
virtual uint64_t maxSize() const override
Definition: Controller.cc:153
int transientReaders(const StoreEntry &) const
number of the transient entry readers some time ago
Definition: Controller.cc:603
double doublePercent(const double, const double)
Definition: SquidMath.cc:25
void invokeHandlers()
Mem mem
all cache_dirs stats
Definition: StoreStats.h:49
int locked() const
Definition: store.cc:1267
static RefCount< Controller > TheRoot
Definition: Controller.cc:846
void hashInsert(const cache_key *)
Definition: store.cc:414
virtual void maintain() override
perform regular periodic maintenance; TODO: move to UFSSwapDir::Maintain
Definition: Controller.cc:89
virtual ~Controller() override
Definition: Controller.cc:44
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:124
bool updateOnNotModified(HttpReply const *other)
Definition: HttpReply.cc:246
void abort()
Definition: store.cc:1125
int store_swap_high
virtual HttpReply const * getReply() const
Definition: store.cc:1688
void handleIdleEntry(StoreEntry &)
called when the entry is no longer needed by any transaction
Definition: Controller.cc:617
mem_status_t mem_status
Definition: Store.h:214
void(* Referenced)(RemovalPolicy *policy, const StoreEntry *entry, RemovalPolicyNode *node)
Definition: RemovalPolicy.h:48
SQUIDCEXTERN hash_link * hash_lookup(hash_table *, const void *)
Definition: hash.cc:147
void checkTransients(const StoreEntry &) const
Definition: Controller.cc:838
bool hasMemStore() const
whether there is a corresponding locked shared memory table entry
Definition: Store.h:189
void memoryEvictCached(StoreEntry &)
Definition: Controller.cc:563
static size_t InUseCount()
Definition: mem_node.cc:55
summary view of all disk caches (cache_dirs) combined
Definition: Disks.h:18
uint16_t flags
Definition: Store.h:206
SQUIDCEXTERN void hashFreeItems(hash_table *, HASHFREE *)
Definition: hash.cc:256
virtual void getStats(StoreInfoStats &stats) const override
collect statistics
Definition: Controller.cc:111
int64_t accumulateMore(StoreEntry &) const
Definition: Controller.cc:437
signed_int32_t sfileno
Definition: forward.h:22
MemObject * mem_obj
Definition: Store.h:195
void addReading(StoreEntry *, const cache_key *)
Definition: Controller.cc:697
void allowSharing(StoreEntry &, const cache_key *)
indexes and adds SMP-tracking for an ephemeral peek() result
Definition: Controller.cc:336
bool transientsWriter(const StoreEntry &) const
whether the entry is in "writing to Transients" I/O state
Definition: Controller.cc:431
bool markedForDeletionAndAbandoned(const StoreEntry &) const
Definition: Controller.cc:300
#define SM_PAGE_SIZE
Definition: defines.h:102
virtual int callback() override
called once every main loop iteration; TODO: Move to UFS code.
Definition: Controller.cc:223
::Transients Transients
Definition: forward.h:52
bool UsingSmp()
Whether there should be more than one worker process running.
Definition: tools.cc:658
std::ostream & HERE(std::ostream &s)
Definition: Debug.h:153
bool shared
whether memory cache is shared among workers
Definition: StoreStats.h:42
bool makePublic(const KeyScope keyScope=ksDefault)
Definition: store.cc:143
static pid_t pid
Definition: IcmpSquid.cc:35
void memoryDisconnect(StoreEntry &)
disassociates the entry from the memory cache, preserving cached data
Definition: Controller.cc:574
int highWaterMark
Definition: SquidConfig.h:75
#define PRIu64
Definition: types.h:120
void transientsCompleteWriting(StoreEntry &)
marks the entry completed for collapsed requests
Definition: Controller.cc:592
StoreEntry * findCallbackXXX(const cache_key *)
Definition: Controller.cc:352
bool markedForDeletion(const cache_key *key) const
Definition: Controller.cc:293
struct SquidConfig::@111 Store
virtual void create() override
create system resources needed for this store to operate in the future
Definition: Controller.cc:75
#define PROF_start(probename)
Definition: Profiler.h:62
void addWriting(StoreEntry *, const cache_key *)
Definition: Controller.cc:705
void FreeMemory()
undo Init()
Definition: Controller.cc:863
void(* Dereferenced)(RemovalPolicy *policy, const StoreEntry *entry, RemovalPolicyNode *node)
Definition: RemovalPolicy.h:49
virtual void evictCached(StoreEntry &) override
Definition: Controller.cc:447
bool memoryCachable()
checkCachable() and can be cached in memory
Definition: store.cc:1357
virtual void evictIfFound(const cache_key *) override
Definition: Controller.cc:458
KeyScope
Definition: store_key_md5.h:18
bool hasReadableDiskEntry(const StoreEntry &) const
whether there is a disk entry with e.key
Definition: Controller.cc:309
size_t memMaxSize
Definition: SquidConfig.h:81
#define TexcHere(msg)
legacy convenience macro; it is not difficult to type Here() now
Definition: TextException.h:55
struct SquidConfig::@97 Swap
virtual uint64_t minSize() const override
the minimum size the store will shrink to via normal housekeeping
Definition: Controller.cc:160
StoreEntry * peekAtLocal(const cache_key *)
Definition: Controller.cc:368
int hot_obj_count
virtual void init() override
Definition: Controller.cc:58
#define PROF_stop(probename)
Definition: Profiler.h:63
void memoryOut(StoreEntry &, const bool preserveSwappable)
called to get rid of no longer needed entry data in RAM, if any
Definition: Controller.cc:546
StoreEntry * peek(const cache_key *)
Definition: Controller.cc:384
virtual uint64_t currentCount() const override
the total number of objects stored right now
Definition: Controller.cc:174
int store_swap_low
static constexpr Io ioDone
Definition: MemObject.h:133
void updateOnNotModified(StoreEntry *old, const StoreEntry &newer)
update old entry metadata and HTTP headers using a newer entry
Definition: Controller.cc:663
bool keepForLocalMemoryCache(StoreEntry &e) const
whether e should be kept in local RAM for possible future caching
Definition: Controller.cc:529
bool transientsReader(const StoreEntry &) const
whether the entry is in "reading from Transients" I/O state
Definition: Controller.cc:425
RemovalPurgeWalker *(* PurgeInit)(RemovalPolicy *policy, int max_scan)
Definition: RemovalPolicy.h:51
FREE destroyStoreEntry
bool swappedOut() const
whether the entire entry is now on disk (possibly marked for deletion)
Definition: Store.h:121
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)
Definition: store.cc:893
#define EBIT_TEST(flag, bit)
Definition: defines.h:107
virtual void stat(StoreEntry &) const override
Definition: Controller.cc:131
virtual uint64_t currentSize() const override
current size
Definition: Controller.cc:167
class SquidConfig Config
Definition: SquidConfig.cc:12
#define NULL
Definition: types.h:166
virtual int64_t maxObjectSize() const override
the maximum size of a storable object; -1 if unlimited
Definition: Controller.cc:181
bool allowCollapsing(StoreEntry *, const RequestFlags &, const HttpRequestMethod &)
tries to make the entry available for collapsing future requests
Definition: Controller.cc:684
int64_t expectedReplySize() const
Definition: MemObject.cc:253
void syncCollapsed(const sfileno)
Update local intransit entry after changes made by appending worker.
Definition: Controller.cc:717
A const & min(A const &lhs, A const &rhs)
virtual void trimMemory(const bool preserveSwappable)
Definition: store.cc:1883
StoreSearch * NewLocalSearch()
Definition: LocalSearch.cc:44
bool anchorToCache(StoreEntry &e, bool &inSync)
Definition: Controller.cc:806
void setMemStatus(mem_status_t)
Definition: store.cc:1576

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors