Skip to content. | Skip to navigation

Sections
Personal tools
What is this?
Hi, my name is Tom Lazar and I'm a Plone and Zope developer based in Berlin, Germany and this is my personal and professional (no big difference, really...) website.
 

Launchd in a nutshell

Filed Under:

Apple's solution for startup items works well but seems over-engineered.

Today I needed to make a fetchmail process automatically start on a Mac OS X Server instance.

Now, ever since Version 10.4 this is the domain of launchd. But compared to what I'm used to in FreeBSD, Apple's own introduction to launchd seemed rather daunting.

My reasong was something along the lines of "If I can't use something as straightforward as rc I might as well get out the big guns and use daemontools" (which already e.g. takes care of my IMAP Server and, of course, my name servers.)

Well, to make a long story short, once I got over the fact, that I need to write XML to configure startup items everything else went rather smoothly. In the end, to have fetchmail launched automatically at startup I needed the following markup in /Library/LaunchDaemons/fetchmail.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Disabled</key>
    <false/>
    <key>GroupName</key>
    <string>staff</string>
    <key>KeepAlive</key>
    <true/>
    <key>Label</key>
    <string>fetchmail</string>
    <key>Program</key>
    <string>/usr/bin/fetchmail</string>
    <key>ProgramArguments</key>
    <array>
        <string>--fetchmailrc=/Users/diradmin/.fetchmailrc</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>Umask</key>
    <integer>7</integer>
    <key>UserName</key>
    <string>diradmin</string>
    <key>WorkingDirectory</key>
    <string>/Users/diradmin/</string>
</dict>
</plist>

(Since the fetchmail process won't be launched via a logged in user, I needed to point it explicitly to the config file I developed for it using the ProgramArguments key.)

Next, I needed to make sure that the abovementioned file had the right ownership and permissions:

sudo chown root:wheel /Library/LaunchDaemons/fetchmail.plist
sudo chmod 644 /Library/LaunchDaemons/fetchmail.plist

Unlike with rc or daemontools, however, just because I now had a perfectly fine config file sitting in its proper place didn't mean anything would happen next time the machine booted. No, I still needed to explicitly tell launchd to use this item using its companion launchctl command:

sudo launchctl load fetchmail.plist

To test the item I then proceeded to manually start it:

sudo launchctl start fetchmail

Note, that this time I didn't state fetchmail.plist as above but rather fetchmail, which refers to the Label key in the XML.

And sure enough, fetchmail was now up and running and was doing its thing. Since I had set KeepAlive to <true/> I could kill it and not even a second later, it was back up and running (with a new PID, of course). Nice. Just like daemontools.

While I'm glad that this all went rather smoothly for me I must say that I much prefer rc and daemontools, though. launchd seems over-engineered. I find that snippet above positively ugly. Even for XML. I mean, come on, what's this supposed to be: <key>RunAtLoad</key><true/>?

But to be fair, Apple specifically designed launchd to handle more than just start up items but to replace "init, rc, the init.d and rc.d scripts, SystemStarter (Mac OS X), inetd and xinetd, atd, crond and watchdogd", to quote its Wikipedia entry.

Anyway, from now on I'm probably just going to use the snippet above as boilerplate and get over with it ;-)

Oh, and Tim? Sorry about the XML bashing. I got nothing against XML per se. In fact I wouldn't know what to do without it. I just don't think it's a good choice for configuration files that are created and read by humans. (And perhaps, neither do you.) Even Zope is moving away from ZCML ;-)