Tech —

Mac OS X 10.4 Tiger

Apple's latest OS X release (10.4) is about to hit the streets. Tiger brings a …

Out to launch

Preface

The topic of this section may seem esoteric and not worthy of extensive coverage. I chose to write about it not so much because it is such a significant part of Tiger, but because I think it highlights some important aspects of Apple's development process.

It's going to get very Unix-y, very fast. I'll explain as much as I can, but this won't be a full-fledged Unix indoctrination starting from first principles. If this all sounds like greek to you, you can always skip to the next section.

Background

In Unix in general, and in Mac OS X in particular, there are a lot of ways to launch programs in response to external events, or on a timed schedule. Common events include system startup, shutdown, and restart, user login, and incoming or outgoing network connections.

In Unix, startup, shutdown, and restart events are handled by a series of interconnected shell scripts stored under /etc/rc.d/. The exact path and contents of that directory tree vary. Some Unix flavors use a different mechanism all together, but most bear the signs of their BSD or System V ancestry.

Timed execution is usually handled by the cron or at daemons. Login time events are triggered by shell-specific dot-files stored in the user's home directory. Network connections may be handled by individual daemons, or by one of many possible "super daemons" (e.g., inetd) that multiplex network connections, triggering other daemons as appropriate. Mac OS X does all of the above, plus it has its own XML-driven mechanisms for system startup and user login items that are independent of the Unix layer.

All of these systems suffer from limitations. The network super daemons in particular are limited by assumptions about their job. Most super daemons are IP-centric and assume one network connection handle per daemon. They're usually system-wide, making them unsuitable to, say, launch a daemon on behalf of a particular user. They also tend to pass the buck when it comes to the realities of modern desktop computing. A PowerBook may go to sleep in one location and then wake up somewhere else on an entirely different network.

As new program-launching needs have arisen in the Unix world, the reaction has always been to modify or piggy-back on one of the existing systems. For example, the ssh-agent daemon (think "keychain for ssh passwords") needs to launch once, and only once for each user login session. Shell startup files are read every time a shell is started. Multiple terminal windows means multiple shells, but still only one login session.

The Unix community's solution was to make runtime checks at shell startup time to see if the ssh-agent was already running, and launch it if it was not. This passed from clever hack into common idiom as ssh-agent became more popular. This is a good example of "The Unix Way."

Whenever Unix vendors have bucked the trend and tried to build something more than just incrementally better than the existing mechanisms, they've met with instinctive resistance. Just look at one Unix user's assessment of the new service management system in Solaris 10.

My concern about SMF [Service Management Framework] is that its not as transparent as a system like rc.d on NetBSD/FreeBSD or even the old sysV init. It is still fairly easy to understand, but there is a level of "magic" that wasn't there before.

As a heavy Unix user myself, I can see where this person is coming from. But honestly, only someone absolutely immersed in Unix culture could ever consider the rc.d or System V init systems "transparent." SMF uses shell scripts, but also XML. It's a new twist to old-school Unix hackers, and the initial reaction is predictably cautious.

Apple went down the same path as Solaris 10, adding its own XML-driven mechanisms for startup and login. The Unix community mostly ignored these efforts. They had their shell scripts, super daemons, and elaborate /etc/rc.d/ scaffolding.

But Apple is not your typical Unix vendor. While the new XML-based systems were nice, they represented two more systems in an already crowded field. In Tiger, Apple decided to tackle the program launching problem again, this time wiping the slate clean.

Launchd

For Tiger, Apple created launchd: one launch daemon to rule them all. Launchd does the job of all of the existing program launching mechanisms, and does it in a way that puts the least possible burden on the programs that it launches. Processes spawned by launchd don't have to worry about "daemonizing" themselves, checking for dependencies, or relaunching or keeping communication handles alive in the case of a crash.

Launchd can launch programs in response to any of the events listed earlier, and it can do so on behalf of the system or an individual user. It will discover dependencies on its own and launch programs in parallel when possible. This is essential for fast system startup. Mac OS X's older startup items system did the same thing, but it had to be explicitly told the dependencies.

Launchd supports a messaging protocol to answer questions like, "How many users are connected to this daemon?" and "Have you shut down yet?" Program shutdown is another example of an area where "The Unix Way" is usually deemed "good enough" despite obvious deficiencies. Traditionally, Unix services are shut down by sending a signal to the process, waiting a little while, and then sending a more harsh signal just in case the service refused to shut down. This is barbaric, but necessary because there's no standardized messaging system for Unix daemons. Launchd recognized the need and filled it.

Apple has developed launchd as an open source project that it hopes will be adopted by the wider Unix community. To the average Unix hacker, launchd probably looks like a reinvention of the wheel. I think it addresses a problem the Unix community doesn't even know that it has. In this way it's much like Mac OS X itself. There was "Unix on the desktop," and then there was Mac OS X. You'd think that alone would have been a big enough wake-up call.

If I were working on a Unix-based operating system, I'd be borrowing ideas and code from Apple like there's no tomorrow. Apple has certainly been smart enough to pull in the opposite direction, basing a huge part of its OS (particular its server OS) on open source Unix projects. Apple has returned the favor by contributing to many of those projects: FreeBSD, gcc, KHTML/KJS, etc. When Apple comes calling with their own open source Unix creations, I think it's foolish not to pay attention.

Anyway, enough preaching. What launchd means to Mac OS X is that all the preexisting program launch facilities will slowly be migrated to launchd. This won't happen overnight, or perhaps not even in the next few years, but the groundwork has been laid. There are also plans to extend launchd to handle device events (e.g., plugging in a camera) and to further standardize not just the protocol but the contents of service messages.

Like lookupd before it, launchd tackles a long-standing Unix problem head on. It's unashamedly ambitious, doing exactly what Apple wants it to do without undue regard for how it has been done in the past. Even the names "lookupd" and "launchd" reflect the straight-forward, can-do attitude that Apple brings to all of its Unix-related development. "Good enough" is never good enough for Apple's core OS team, and I'm glad.

Share this story

John Siracusa
John Siracusa has a B.S. in Computer Engineering from Boston University. He has been a Mac user since 1984, a Unix geek since 1993, and is a professional web developer and freelance technology writer. Emailsiracusa@arstechnica.com//Twitter@siracusa