Squid startup: Extreme Makeover with SMF
By user12618941 on Feb 28, 2005
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:defaultThe 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
[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.]