Mac OS X 10.4 Tiger introduced a new program called launchd.
Launchd: One Program to Rule them all (YouTube)
FreeBSD machines can have uptimes anywhere between months and years, and that makes it all the more critical when they go down (for maintenance of course). To where every second of downtime can be lost business, or lost time for a development team that uses a centralized server. By porting launchd(8) to FreeBSD 6-CURRENT, boot up times and job management can both be handled more effectively, and improve some aspects of the operating system itself.
This has the possibility, if merged into the source tree, of improving overall boot times for all FreeBSD users, from those desktop users, to firewalls, to critical servers. It also benefits the system, with it's simplicity, launchd(8) replaces: init, rc, the init.d and rc.d scripts, SystemStarter (Mac OS X specific), inetd and xinetd, atd, crond, and watchdog, into one centralized daemon.
20150629: The TrueOS fork of FreeBSD 10 has launchd running as init and a JSON-aware launchctl utility, along with notifyd, libdispatch and ASL integrated. This work has also been forward-ported to FreeBSD -CURRENT. FreeNAS 10, which is also based on FreeBSD 10.1, will be using launchd and a host of other tools ported from OS X / iOS. It has used the original, and latest, Apple sources and ported them along with MACH IPC.
20140910: Outback Dingo has made available an older port of pfSense's launchd_xml.
20080921: A FreeBSD port has been spotted on Github
20060906: Launchd Subversion Repository Available at MacOSForge.
- 20060807: Launchd Adopts Apache License, Version 2.0!
20051101: Recently merged code snapshot from zarzycki@Apple into perforce directory.
2005 GSoC Project Details
The launchd(8) project was originally released under the APSL (Apple Public Source License) by Apple Computers Inc., along with its release of Mac OS 10.4. It has helped dramatically improve boot times of Mac OS X, and would be very valuable to have elsewhere in the open source community. Politics may be a problem with its acceptance into the base system of FreeBSD, given that it is neither BSD licensed nor part of the necessary GNU code in the FreeBSD base system. Another problem that may present itself would be that launchd(8) uses an XML configuration file, depending on how things go, it may be simpler to go with a more "traditional" .conf configuration file. The main goal of the project is to port the program, to where it can plausibly replace ancient unix utilities, such as 'cron', xinetd/inetd, atd, and watchdog. Giving system administrators, and individual users alike a simple administration point to manage most of the system daemons that are "usually" run automatically.
- Speed up FreeBSD boot times noticeably. (to where there isn't a doubt that launchd(8) has made a definite effect on boot times)
- Create a script, or other method for converting rc.d scripts from ports that a user installs, for launchd(8)'s use.
Port launchd(8) first as a user-land daemon, replacing init as PID 1 to be done later (as in, not within the scope of this project) because of certain complexities involved.
- Reduce dependency on rc.d scripts as much as is feasibly possible, to where any rc.d scripts that still need to exist are started simultaneously along with the rest of the daemons that launchd(8) manages.
- Create a centralized management point for many of the duties that older unix daemons (cron, atd, watchdog, etc) formerly did.
2005 - End of Summer Synopsis
- Although I did not get as far as I had originally hoped (partially because I vastly underestimated the complexity of zarzycki@'s wonderful creation) for, I have made enough progress to where launchd can be used as a non-PID 1 daemon to manage other running processes.
In short, launchd can run perfectly fine on FreeBSD, and combined with launchctl, it can be used to manage daemons through the launchctl(1) interface. Jobs can be added and managed two ways as of yet from launchctl(1). Using zarzycki@'s experimental "submit" command within launchctl(1) or by using my lame/rudimentary/etc "launcher" format (launchd/launchers/*.launch) which uses property(3) to parse out three simple, and important details. The program label, path, and any program flags. Using the "load" command, one can load the data into launchctl(1) and then start the processes with the..."start" command. Jobs can be removed/stopped with the "remove" command. The "limit" command still throws launchctl(1) into an infinite loop, and yes, I plan on fixing this.
In the future
As it stands right now, the code is still somewhat, well, very, unpolished. I'll take the blame on that one. I still intend on writing a plist format (the non-XML one) parser to incorporate into the code base, which will give users full advantage of everything launchd(8) can do, while maintaining backwards compatibilty with launchd/MacOS. Work also is about 40% done on the init(8) replacement part of launchd(8), but since the FreeBSD organization isn't as anal retentive about daemon count as Apple Inc. apparently was, it's not _as_ necessary (but I still intend to port it over soon enough, the orig. launchd(8) incorporates a lot of mach_init oddness) In all honesty, I don't think launchd(8) will be anything to brag about until, maybe this winter, but the hardest part is definitely behind me, wrapping my little 19 year old brain around this code was quite a feat, but I think I have a good feel for how everything works, and why. (MANY thanks to zarzycki@apple in this regard, he held my hand through a lot of the tougher parts ;))
As mentioned in the "Updates" section, this has changed from APSL to Apache Version 2 license.
- [finished] Remove all of the dependencies on autoconf/automake (in favour of a BSD-styled build system)
[finished] Use launchctl as a test subject for removing the CoreFoundation hooks and API calls
[finished] Strip out CoreFoundation calls from the main launchd(8) code
- [finished] Be able to compile the core utilities of launchd(8) on any FreeBSD 6.xx system.
- [finished] Allow launchd(8) to assume a non-PID-1 role, i.e., as a regular daemon, not _the_ daemon
- [finished] Reach the point to where there is functional communication between launchd(8) and launchctl(1) via the unix socket.
- [finished] Start to start daemons via launchd(8) and my stupid "launcher" file format (probably need to change this to make it more robust)
- [work in progress] Start to make it _work_ as PID 1
[work in progress] document code? *gasp*