Alex Rousskov [Sat, 26 Apr 2014 17:30:33 +0000 (11:30 -0600)]
Document counter-intuitive round-robin cache_dir selection bias; decrease it.
Many squid.confs have at least two groups of cache_dir lines. For example,
rare "large" objects go to larger/slower HDDs while popular "small" objects go
to smaller/fast SSDs:
# HDDs
cache_dir rock /hdd1 ... min-size=large
cache_dir rock /hdd2 ... min-size=large
cache_dir rock /hdd3 ... min-size=large
# SSDs
cache_dir rock /ssd1 ... max-size=large-1
cache_dir rock /ssd2 ... max-size=large-1
cache_dir rock /ssd3 ... max-size=large-1
# rock store does not support least-load yet
store_dir_select_algorithm round-robin
Since round-robin selects the first suitable disk during a sequential scan,
the probability of /hdd1 (/ssd1) selection is higher than other HDDs (SSDs).
Consider a large object that needs an HDD: /hdd1 is selected whenever scan
starts at /ssd1, /ssd2, /ssd3, and /hdd1 while /hdd2 is selected only when the
scan starts at /hdd2 itself! Documentation now warns against the above
cache_dir configuration approach and suggests to interleave cache_dirs:
cache_dir rock /hdd1 ... min-size=large
cache_dir rock /ssd1 ... max-size=large-1
cache_dir rock /hdd2 ... min-size=large
cache_dir rock /ssd2 ... max-size=large-1
cache_dir rock /hdd3 ... min-size=large
cache_dir rock /ssd3 ... max-size=large-1
store_dir_select_algorithm round-robin
Squid's historic implementation of round-robin made its natural bias even
worse because it made the starting point of the sequential scan to be the last
selected dir. In the first configuration example above, it boosted the
probability that the scan will start at one of the SSDs because smaller
objects are more popular and, hence, their dirs are selected more often. With
the starting point usually at an SSD, even more _large_ objects were sent to
/hdd1 compared to other HDDs! The code change avoids this artificial boost
(but the cache_dir lines should still be interleaved to avoid the natural
round-robin bias discussed earlier).
Alex Rousskov [Mon, 21 Apr 2014 18:09:06 +0000 (12:09 -0600)]
Stop wasting 96 RAM bytes per slot for high-offset slots in large shared caches
with more than 16777216 slots.
Ipc::StoreMap was using the same structure for all db slots. However, slots at
offsets exceeding SwapFilenMax (16777215) could not contain store entry
anchors and the anchor part of the structure was wasting RAM for those slots.
This change splits a single array of StoreMapSlots into two arrays, one
storing StoreMapAnchors and one storing StoreMapSlices. The anchors array is
shorter for caches with more than 16777216 slots.
For example, a StoreMap for a 1TB shared cache with default 16KB slot sizes
(67108864 slots) occupied about 6.5GB of RAM. After this change, the same
information is stored in about 2.0GB because unused anchors are not stored.
32-bit environments were wasting 72 (instead of 96) bytes per high-offset slot.
Also simplified Ipc::StoreMap API by removing its StoreMapWithExtras part.
The added complexity caused bugs and was not worth saving a few extra lines of
callers code. With the StoreMap storage array split in two, the extras may
belong to each part (although the current code only adds extras to slices),
further complicating the WithExtras part of the StoreMap API. These extras
are now stored in dedicated shared memory segments (*_ex.shm).
Added Ipc::Mem::Segment::Name() function to standardize segment name
formation. TODO: Attempt to convert shm_new/old API to use SBuf instead of
char* to simplify callers, most of which have to form Segment IDs by
concatenating strings.
Alex Rousskov [Sat, 19 Apr 2014 23:05:51 +0000 (17:05 -0600)]
Allow HITs on entries backed by a shared memory cache only.
A typo in r12501.1.59 "Do not become a store_client for entries that are not
backed by Store" prevented such entries from being used for HITs and possibly
even purged them from the memory cache.
Alex Rousskov [Fri, 18 Apr 2014 16:57:01 +0000 (10:57 -0600)]
Restored Squid ability to cache (in memory) when no disk caches are configured
which was lost during r12662 "Bug 3686: cache_dir max-size default fails"
The bug was hidden until the memory cache code started calling
StoreEntry::checkCachable() in branch r13315, exposing the entry size check to
a broken limit.
r12662 converted store_maxobjsize from a sometimes present disk-only limit to
an always set Squid-global limit. However, store_maxobjsize value was only
calculated when parsing cache_dirs. A config without cache_dirs would leave
store_maxobjsize at -1, triggering "StoreEntry::checkCachable: NO: too big"
prohibition for all responses.
This change moves store_maxobjsize calculation from parser to storeConfigure()
where some other Store globals are computed after squid.conf parsing.
Also honored memory cache size limit (just in case cache_mem is smaller than
maximum_object_size_in_memory) and removed leftover checks for
store_maxobjsize being set (it should always be set, at least to zero).
Alex Rousskov [Thu, 10 Apr 2014 04:56:25 +0000 (22:56 -0600)]
Significantly reduced Large Rock (and slightly shared memory) RAM requirements
by not allocating 40 (and 12) bytes of unused RAM per cache slot.
Rock: Stale code inherited from the Small Rock implementation allocated 40
bytes of unused memory per rock db slot (2.5GB of RAM for a 1TB disk with 16KB
db slots). The current (Large Rock) code stores the same kind of information
(and more) in a different location (Ipc::StoreMap).
Shared memory: Similarly, the Large Rock-based shared memory cache allocated
12 bytes of unused memory per shared memory cache slot (3.8MB of RAM for a
10GB shared RAM cache with 32KB slots).
Alex Rousskov [Sun, 6 Apr 2014 21:02:18 +0000 (15:02 -0600)]
Lifted 16777216 slot limit from rock cache_dirs and shared memory caches.
Also fixed rock disk space waste warning.
Rock store and shared memory cache code used entry and slot limit as if
the two were the same. In large caches, the number of entry slots may exceed
the number of entries supported by Squid (16777216 entries per store). This
is especially likely with large caches storing large entries (many slots
per entry with maximum number of entries) or large caches using small slot
sizes.
AFAICT, the bug led to the "tail" of cache storage being unused and cache
entries being purged even though there was still space to store them. Also,
Squid was allocating smaller shared memory tables (and temporary cache index
build tables) than actually needed for the configured cache sizes.
Note that this change does not remove the per-store 16777216 entry limit.
The old [small] rock warning about wasted disk space assumed that a cache
entry occupies exactly one slot. The updated warnings do not.
Also fixed and simplified db scanning condition during cache index build.
Alex Rousskov [Fri, 4 Apr 2014 16:10:40 +0000 (10:10 -0600)]
Report IpcIo file name with errors and warnings
to inform admin which cache_dir needs troubleshooting or tuning.
Some level-0/1 messages did not mention disker ID or file name at all while
others relied on disker process ID which is too low-level information from most
admins point of view.
Also improved error and warning messages consistency.
Alex Rousskov [Wed, 19 Mar 2014 04:04:52 +0000 (22:04 -0600)]
Avoid "FATAL: Squid has attempted to read data from memory that is not present"
crashes. Improve related code.
Shared memory caching code was not checking whether the response is generally
cachable and, hence, tried to store responses that Squid already refused to
cache (e.g., release-requested entries). The shared memory cache should also
check that the response is contiguous because the disk store may not check
that (e.g., when disk caching id disabled).
The problem was exacerbated by the broken entry dump code accompanying the
FATAL message. The Splay tree iterator is evidently not iterating a portion of
the tree. I added a visitor pattern code to work around that, but did not try
to fix the Splay iterator iterator itself because, in part, the whole iterator
design felt inappropriate (storing and flattening the tree before iterating
it?) for its intended purpose. I could not check quickly enough where the
broken iterator is used besides mem_hdr::debugDump() so more bugs like this
are possible.
Optimized StoreEntry::checkCachable() a little and removed wrong TODO comment:
Disk-only mayStartSwapOut() should not accumulate "general" cachability checks
which are used by RAM caches as well.
Added more mem_hdr debugging and polished method descriptions.
Fixed NullStoreEntry::mayStartSwapout() spelling/case. It should override
StoreEntry::mayStartSwapOut().
url_rewrite_extras and store_id_extras patch fixes
Fixes to patch "Add url_rewrite_extras and store_id_extras for redirector and store_id helpers",r13308:
- Fix cf_gen.cc:gen_conf(..) function to not escape quotes before write to
conf file
- The Format::Format name is used to inform the user about parsing problems.
Fix the names of related objects for the new redirecor_extras and
store_id_extras directives.
- cf.data.pre: The NAME tag take as argument only the name of directive. Fix
the new redirecor_extras and store_id_extras related tags.
Add url_rewrite_extras and store_id_extras for redirector and store_id helpers
The url_rewrite_extras/store_id_extras is a "quoted string" with logformat
%macro support. It is used to modify the request line for redirector and
storeId helpers.
The url rewrite and store_id helpers request format now is:
url [<SP> extras]
and the default value for extras is:
"%>a/%>A %un %>rm myip=%la myport=%lp"
Example usage:
url_rewrite_extras "Note1=%{Note1}note Note2=%{Note2}note"
Alex Rousskov [Sat, 8 Mar 2014 17:28:23 +0000 (10:28 -0700)]
Avoid assertions on Range requests that trigger Squid-generated errors.
Added HttpRequest::ignoreRange() to encapsulate range ignoring logic.
Currently the new method only contains the code common among all callers. More
work is needed to check whether further caller homogenization is possible.
Documented that ClientSocketContext::getNextRangeOffset() may sometimes be
called before it is ready to do its job.
Amos Jeffries [Fri, 7 Mar 2014 11:18:03 +0000 (04:18 -0700)]
Protect MemBlob::append() against raw-space writes
There is no guarantee that the 'unused' area of MemBlob is actually
unused. For example if a read buffer was being filled into the
rawSpace() of a SBuf or MemBlob it will overlap with this empty area
until a read call updates the related size state in MemBlob/SBuf.
For these cases we must use memmove() which guarantees no buffer
corruption will take place on memory overlaps.
Amos Jeffries [Thu, 6 Mar 2014 03:55:41 +0000 (20:55 -0700)]
Copyright: Relicense helpers by Treehouse Networks Ltd.
Update the license on helper code designed and authored by myself using
the BSD 2-clause license. This makes the example helper code and license
more legally acceptible for use as a basis of proprietary helpers while
remaining compatible with GPL for distribution with Squid.
Amos Jeffries [Wed, 5 Mar 2014 12:08:54 +0000 (01:08 +1300)]
Better fix for CMSG definitions
It turns out autoconf versions are not consistent with $ symbol escaping
which can cause incorrect definitions. Revert to AC_CHECK_TYPE instead.
Its a bit more verbose in configure.ac but works more often than not.
Amos Jeffries [Wed, 5 Mar 2014 06:32:34 +0000 (19:32 +1300)]
Portability: define CMSG related structures individually
Some OS provide the CMSG related definitions and others only partially
define them. Sometimes (Windows particularly) this varies between build
environments.
Checking for each symbol separately and providing only those needed
avoids problems we have been having with missing or redefined symbols
on Windows and elsewhere.
Amos Jeffries [Tue, 4 Mar 2014 10:33:08 +0000 (23:33 +1300)]
Fix helper ID number assignment
Since helpers are now dynamically started the old method of allocating
an ID number based on the current start sequence can result in many
helpers being assigned overlapping ID numbers.
Use InstanceID template instead to assure a unique incremental ID is
assigned to each helper no matter when it is started.
Alex Rousskov [Fri, 21 Feb 2014 16:14:05 +0000 (09:14 -0700)]
Migrated RegisteredRunners to a multi-action interface.
Old generic two-action RegisteredRunners were good for handling paired
create/destroy events, but not all main.cc events fit that model well. In
fact, even the old runners implemented the destruction action for one event
only (rrAfterConfig); all other runners implemented a single action.
The adjusted API better supports runners that are interested in any number
of the supported events. It also allows a single runner object to handle
multiple events, which simplifies current code and may help with better
[re]configuration handling in the future.
Added startShutdown() and finishShutdown() events. The former will be needed
for authentication module shutdown and more polished shutdown initiation code
in general (patch pending). The latter is needed for final cleanup code that
previously ran as the destruction action for rrAfterConfig. finishShutdown()
also destroys all runners.
Note that the master process in SMP mode does not run startShutdown because
that process lacks the main loop and startShutdown() promises at least one
main loop iteration (to help with clean connections closures, for example).
Added syncConfig() event that will be needed for the standby pool
implementation (patch pending) and future code that reacts to Squid
configuration changes caused by reconfiguration.
"after config" event is now called "use config" to better match verb+noun or
action+object naming scheme.
Amos Jeffries [Fri, 21 Feb 2014 10:46:19 +0000 (03:46 -0700)]
Cleanup: un-wrap C++ header includes
Coding guideline is now that standard C++ headers are not to be
wrapped in HAVE_ macros.
* Remove HAVE_ macros for currently wrapped C++ headers.
Includes removing autoconf checks.
* Replace C includes with C++ includes where possible
Also, <cstdio> / <stdio.h> has issues on 64-bit systems and a
portable fixed version is provided by libcompat via squid.h
It should not be included anywhere in the Squid sources.
Amos Jeffries [Thu, 20 Feb 2014 13:03:07 +0000 (06:03 -0700)]
squidclient: --ping mode module support
Module support:
Update squidclient support modules with different logics
and configuration option sets as a basis for multiple
protocol support.
A mechanism is added to allow each module to have its own
command line option set. Any option unknown to the current
module handler drops back to the main loop for processing.
--ping mode module:
Break the existing code "ping mode" operations and command
line processing out from the main squidclient.cc into Ping.*
Ping-specific short command line options are now only parsed
after a mode flag (--ping) is presented. This frees up the
-g and -I options for use by other non-ping modules in future.
Also, shuffle squidclient code into its own directory
tools/squidclient/ to keep the tool code files clearly
identifiable now that they are multiplying.
1) The dynamic_cert_mem_cache_size does not change on reconfigure
2) When dynamic_cert_mem_cache_size of http_port set to 0 then:
a) The dynamic certs cache is grow unlimited.
This patch just disables certificates caching when this option set to 0.
b) Huge amount of memory appeared as free cache memory in "Cached ssl
certificates statistic" page of cache manager.
This problem caused because of a signed to unsigned int conversion.
Amos Jeffries [Sun, 16 Feb 2014 05:15:45 +0000 (22:15 -0700)]
squidclient: support verbosity levels
This makes the -v option repeatable. By default no debug is displayed.
Each time -v is repeated the level of debug message verbosity is raised.
Three levels of verbosity are currently defined:
0 - no output except ERROR messages.
1 - display HTTP request sent
2 - display actions taken connecting to server
Amos Jeffries [Thu, 13 Feb 2014 07:02:35 +0000 (20:02 +1300)]
Bug 4001: remove use of strsep()
The strsep() function is not defined by POSIX. Additionally
auto-tools has been having some obscure issues detecting
or linking the provided implementation into libcompat on
Windows and Solaris respectively. Which are the two known
OS requiring it.
Investigation of its use in Squid revealed that it can be
replaced with strcspan() which is both portable and more
efficient since it also removes the need for several
strdup()/free() operations used to protect Squid from
strsep() memory fiddling.
Bug 3969: user credentials cache lookup for Digest authentication broken
Changes to the username credentials cache were made in Basic auth but
the matching changes were not duplicated to Digest auth. Since the
lookup is identical move it to generic Auth::Config.
Amos Jeffries [Sat, 8 Feb 2014 12:33:31 +0000 (05:33 -0700)]
Move compat/unsafe.h protections from libcompat to source maintenance
It is sufficient to run a code scan from source-maintenance.sh for the
unsafe functions being used in Squid-specific code instead of
hard-coding compiler breakage on users.
This also "fixes" reporting of errors when cstdio pulls in use of the
unsafe functions by stdlib.
Alex Rousskov [Wed, 5 Feb 2014 18:04:47 +0000 (19:04 +0100)]
Fix keepalive handling for non-ranged requests.
Internal keepalive flag was ignored by a mismatched interface between ClientSocketContext::socketState
and writeComplete in the case of non-ranged requests.