Slaying Daemons!

Typical story, my MacBook has become progressively slower since it was last re-installed over 18 months ago.  Having run disk permissions repair, disk warrior and all the other “cleaning” tools, there was very little improvement.

After giving it some thought (while staring at yet another beachball cursor icon) I thought I’d look at Activity Monitor to see what is running in the background.  In addition to the standard software set, part of my job involves constantly evaluating new and exciting bits of software.
As many of you will have seen, a lot of application installers seem to add startup items to keep extra services running in the background. This is particularly true of techie utilities.  After looking at Activity Monitor, I noticed a large chunk of processing power and RAM being consumed by these background services.
You may think that you can simply remove the application or uninstall (if there was an uninstaller provided) but I rarely see this process remove background Daemons.
LaunchD
Since Mac OS X v10.4, Apple have passed responsibility for starting background processes (normally called “Daemons”) to a master process called LaunchD.  More information about the inner workings of LaunchD in our earlier podcast.
LaunchD finds which processes to start by reading XML files in specific locations.   These are divided into three categories: Apple processes, third party processes & user processes.  These XML files are stored in one of the following locations:
Apple’s system processes
/System/Library/LaunchDaemons
/System/Library/LaunchAgents
Third party processes
/Library/LaunchDaemons
/Library/LaunchAgents
User processes
~/Library/LaunchAgents
If you are unfamiliar with LaunchD, you may be wondering why there are LaunchDaemons and LaunchAgents folders.  Simply put, items in the LaunchDaemons folders will generally load on startup (and are normally owned by root).  Items in the LaunchAgents folders are normally loaded when a user actually logs in to the machine.  This helps to explain why the users home folder (the ~ symbol) does not have a LaunchDaemons folder.  Mac OS X would not know which Daemons to load on startup as a user is not logged in.
Slaying the Daemons
It is important for me to note that although the process for stopping Daemons and preventing them from launching is relatively simple.  Unfortunately, choosing which Daemons to slay does require a fair amount of background Mac technical knowledge.  Here are a few basic guidelines before you start on your quest:
Don’t touch anything in /System/Library.  This will end in tears.
If you can’t identify an XML file, your better off leaving it alone.
The first step is to identify which Daemons you want to kill.  Using the Terminal, navigate to your target directory.  E.g:
MacBook:~ dave$ cd /Library/LaunchDaemons/ 
Then list the Daemons:
MacBook:LaunchDaemons dave$ ls
at.obdev.littlesnitchd.plist
com.apple.remotepairtool.plist
com.bjango.istatlocaldaemon.plist
com.googlecode.munki.logouthelper.plist
com.googlecode.munki.managedsoftwareupdate-check.plist
com.googlecode.munki.managedsoftwareupdate-install.plist
com.googlecode.munki.managedsoftwareupdate-manualcheck.plist
com.sophos.autoupdate.plist
com.sophos.intercheck.plist
com.sophos.notification.plist
For the purposes of this example, I will target the istatlocaldaemon.  To help identify what the Daemon is doing, you can use the “cat” command (you may need to use “sudo” to read the file):
MacBook:LaunchDaemons dave$ sudo cat com.bjango.istatlocaldaemon.plist
Password:
<?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>wheel</string>
<key>KeepAlive</key>
<true/>
<key>Label</key>
<string>com.bjango.istatlocaldaemon</string>
<key>OnDemand</key>
<false/>
<key>Program</key>
<string>/Library/Application Support/iStat local/iStatLocalDaemon</string>
<key>RunAtLoad</key>
<true/>
<key>StartOnMount</key>
<false/>
<key>UserName</key>
<string>root</string>
</dict>
</plist>
 
The section I am interested in here is the program that is being launched by the XML file, highlighted in blue, it is /Library/Application Support/iStat local/iStatLocalDaemon.
To check if the process is running in the Terminal:
MacBook:LaunchDaemons dave$ ps aux | grep “istatlocal”
dave           44638   0.1  0.0  2434892    540 s000  S+    6:07pm   0:00.00 grep istatlocal
Or alternatively:
MacBook:LaunchDaemons dave$ launchctl list | grep “istatlocal”
231 – com.bjango.istatlocal
To stop the process:
MacBook:LaunchDaemons dave$ sudo launchctl unload com.bjango.istatlocaldaemon.plist
And finally, to prevent the Daemon from re-launching, simply remove it from the enclosing folder (I recommend moving rather than deleting, in case you want to put it back later):
MacBook:LaunchDaemons dave$ mv com.bjango.istatlocaldaemon.plist ~/Desktop/
(In this example, I am moving the XML file to my Desktop).
I can now restart, safe in the knowledge that the istatlocaldaemon process is not going to try and fire up.
On my own MacBook, I cleared out over 10 processes left behind by previously removed applications.  My machine is now running nice and fast once more.