The View from the Moon

20050301 Tuesday March 01, 2005

Squid startup: Extreme Makeover with SMF
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:

  1. Tweak squid.xml to reflect the Squid installation directory.
  2. Copy the svc-squid script to the location reflected by squid.xml.
  3. svccfg import /path/to/squid.xml
  4. 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.]
(2005-03-01 04:45:01.0) Permalink Comments [7]
Trackback: http://blogs.sun.com/dp/entry/squid_startup_extreme_makeover_with

 

Trackback URL: http://blogs.sun.com/dp/entry/squid_startup_extreme_makeover_with
Comments:

This looks good, Dan - you obviously spent considerably more time on it than I did.

I looked at the network stuff and noticed that some of the other manifests used the milestone, but I couldn't quite work out which way was best given the way the Apache manifest was laid out. However, I think I'll change to the way you've done it.

I would be interested in knowing why you specifically chose the DNS dependency rather than the name services milestone which I used - especially given your comment about using milestones where possible ? I totally agree with you on the dependency stuff being a black art though. I'll be off out to purchase my wizard's hat and wand before tampering with it much more :)

Posted by Trevor Watson on March 01, 2005 at 05:21 AM PST #

Ahh, the dependency on DNS is because Squid *always* uses DNS. It doesn't matter if your name service is NIS; it's going to use DNS (via either libresolv or its own custom (ugh) library).

Posted by Daniel Price on March 01, 2005 at 05:30 AM PST #

The reason squid uses its own DNS resolver is that gethostbyname, getadrinfo and friends are all synchronous functions, and since squid is a single-threaded process it can't afford to call them and risk blocking. If you add the --disable-internal-dns flag when configuring squid, it will fork some helper "dnsserver" processes (5 by default) that do call gethostbyname().

Posted by Dan Nelson on March 27, 2005 at 10:43 PM PST #

I was hoping to try out your squid startup scripts for svcs but the links to squid.xml.txt and the startup script seem to be dead. Is there any chance of you either fixing the links or sending me the files please? Thanks Sean

Posted by Sean Clarke on July 20, 2005 at 10:58 AM PDT #

Anyone has cookbook to reduce squid privilege by using the same method as this article http://www.sun.com/blueprints/0605/819-2887.pdf thanks

Posted by nawir on November 22, 2005 at 01:04 AM PST #

Your blog entry was very useful in helping me finish my setup, and it does basically work. Readers should understand that these instructions are incomplete, though. I've got a page describing the complete procedure and am working to get it posted in a public place.
A few particular comments on your entry:
(1) See pages 52-53 in Squid: The Definitive Guide for hints as to why dynamic reconfiguration is not reliable.
(2) Simply enabling squid did not work, because the <tt>svc:/network/dns/client</tt> service was disabled. It takes awhile for a neophyte to stumble around and figure out what might be wrong, where to look for error messages, etc., since the "<tt>svcadm enable squid</tt>" command itself doesn't emit any useful error messages for this failure. "<tt>svcs -d squid</tt>" comes in handy here.
(3) In my installation, I put the manifest and the control script in the standard places Sun uses for other services, with file edits to match. As part of this, the XML file is now named <tt>http-proxy-squid.xml</tt> .
(4) It's best to use "<tt>svccfg validate</tt>" before "<tt>svccfg import</tt>".
(5) It's important to point out the proper commands to use to stop and start the daemon if you ever need to do so manually: "<tt>svcadm disable -t squid</tt>" and "<tt>svcadm enable -t squid</tt>".

Posted by Glenn on December 19, 2005 at 03:34 AM PST #

How usefull are all this Manifests guys.I am sorry to ask,but i am kind of naive about the whole discussion.I have seen quite a lot of SMF manifests being written and posted BUT i am just concerned about their usefulness.Please advice.

Posted by Maina Noa on June 17, 2007 at 01:26 AM PDT #

Post a Comment:

Name:
E-Mail:
URL:

Your Comment:

HTML Syntax: NOT allowed
Dan Price's Weblog
[about me]