I run a web proxy server for folks in the office; we use it as a longterm testbed for Solaris.
But, in the insanity leading up to the release of Solaris 10, I’ve had little time to work
on it. Recently I got a new server to host the cache; and so I’ve been busy putting it together.
We’ve always used Squid as our proxy software.
Personally, I have some qualms about Squid’s design, but with five years of experience using it,
I think we’ll probably stick with it for now. It’s a curious thing that there doesn’t appear
to be a significant competitive open source alternative to Squid (the forthcoming Apache 2.1 is
moving mod_cache out of “experimental” support so perhaps that will be worth considering?).
Setting aside design complaints, being able to effectively administer Squid is a big priority,
so recently I worked on getting it properly under the control of the Service Management Facility (SMF).
It’s also a good example of how to improve a program’s administrative controls with SMF.
The first task was to look through Squid’s existing start/stop/restart capabilities. There’s
a RunCache script, which I had always thought was the supported way to start the daemon.
Looking at the documentation, RunCache is now aparently obsolete, but still installed along with
squid anyway (sigh). RunCache has many problems which I won’t detail here.
In the same neighborhood, there is the squid binary, which has a number of relevant
command line options:
Usage: squid [-dhsvzCDFNRVYX] [-f config-file] [-[au] port] [-k signal] ... -f file Use given config-file instead of /aux0/squid/etc/squid.conf ... -k reconfigure|rotate|shutdown|interrupt|kill|debug|check|parse Parse configuration file, then send signal to running copy (except -k parse) and exit. -s Enable logging to syslog. ... -z Create swap directories ... -N No daemon mode. ...
To add to the complexity, squid has its own restarter directly built into itself. This is
somewhat suboptimal, as SMF tends to trump these facilities, and allows monitoring software
to have visibility into restart events. Anyway, we can make use of the -k option to control
the daemon to some degree, and give the administrator the power to create multiple
service instances if we use the -f option. In my testing, I found the -k reconfigure
option to be somewhat useless, so I decided not to implement an SMF ‘refresh’ method. Perhaps
I missed something?
Another problem we’d like to solve is that Squid doesn’t operate properly “out of the box.”
First, one must run the daemon with the -z option in order to create the cache
metadata. I’m not sure why the squid team made this decision; I certainly don’t think it’s
a good one. Our startup scripting can simply take care of cache creation for the administrator.
After working out the right set of dependencies for the cache as I’d set it up
(./configure --disable-internal-dns --enable-ssl --prefix=/aux0/squid --enable-storeio='ufs aufs'),
I prepared a service manifest file which captured those dependencies; the dependencies
look like this:
$ svcs -d squid STATE STIME FMRI online Jan_26 svc:/milestone/network:default online Jan_26 svc:/system/filesystem/local:default online Jan_26 svc:/network/dns/client:default online Jan_26 svc:/milestone/sysconfig:default
The network milestone is the stable way to depend on “networking being up on the box.”
A buglet in some of the S10 FCS manifests (notably, Apache) is that some of them have finer
grained, and less stable dependencies (for example, on network/physical). When stable
dependencies in the form of milestones are available, please use them.
Note that the default mode for squid is to use it’s own internal DNS library (ugh), so
you may or may not need the DNS dependency. This is (double ugh) a compile time setting.
Regardless, you’ll want to have an /etc/resolv.conf file present, and the
network/dns/client manifest checks for that.
Next, I worked on revising the startup script to be much more intelligent. To start
up the cache, it uses squid’s -k parse option to decide whether the configuration file
has a valid syntax. If not, it exits with the $SMF_ERR_CONFIG error code,
which indicates a configuration problem. Next, it populates the cache directory using
squid -z as needed. Finally, it starts up the cache. Every failure logs a
clear and detailed log message.
I also added a couple of service properties, which the script uses to set its behavior.
Ideally, this will be automatically and correctly generated from the configure
script in the future. Just tweak the manifest before importing it. In the example
manifest, squid has been configured to be installed into /aux0/squid. You will
want to search the file and alter all of the places which reference /aux0/squid,
adjusting them for your installation (you can also use svccfg after you import the manifest
to make corrections).
Here is a draft of the
network/http-proxy:squid service manifest;
and a draft of the svc-squid
startup script. To install:
- Tweak squid.xml to reflect the Squid installation directory.
- Copy the svc-squid script to the location reflected by squid.xml.
- svccfg import /path/to/squid.xml
- svcadm enable squid
I hope this is helpful! I’d be happy to take suggestions for improvement, and please
let me know if you wind up using this successfully.
[Sigh. Sometimes I feel like I’m just too slow to post.
Since I started this post a month ago,
some of the work Trevor posted obviates mine. While I’m not happy about having multiple
similar solutions to a single problem I think this represents a substantial improvement, and
it did take quite a while to refine into the current state. It has also been checked
and nitpicked by the SMF team, so I’m optimistic that it is roughly correct. One interesting
result is that my dependencies are different than the set which Trevor worked out.
Determining the right set of dependencies is, at present, a bit of a black art.]