I have a custom launchd job setup to run when a directory changes. It has been running for quite some time now, and up until recently (July 28, 2011) it has been working perfectly. I just realized however, that the job is no longer being triggered by modifications to the path.
Here's my launchd 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>Label</key> <string>com.mydomain.myscript</string> <key>LowPriorityIO</key> <true/> <key>Nice</key> <integer>20</integer> <key>Program</key> <string>/path/to/myscript.sh</string> <key>RunAtLoad</key> <false/> <key>StandardErrorPath</key> <string>/Library/Logs/myscript.log</string> <key>StandardOutPath</key> <string>/Library/Logs/myscript.log</string> <key>ThrottleInterval</key> <integer>60</integer> <key>UserName</key> <string>adminuser</string> <key>WatchPaths</key> <array> <string>/Volumes/MyDisk/Watch</string> </array> </dict> </plist>
I've double-checked everything I could think of:
There has been all kinds of activity in the watched directory recently (new files) which has always triggered the job in the past:
$ ls -ld /Volumes/MyDisk/Watch drwxrwxr-x 93 adminuser admingrp 3162 Aug 3 16:08 /Volumes/MyDisk/Watch
The job is active:
$ sudo launchctl list | grep mydomain - 0 com.mydomain.myscript
My script is in the correct location, is executable, and works perfectly when run manually as the correct user. The log file shows the last date my script was executed by launchd:
$ cat /Library/Logs/myscript.log <snip> [2011-07-27 08:04:27] running... [2011-07-27 08:06:33] running... [2011-07-27 08:07:33] running... [2011-07-27 20:58:15] running... [2011-07-28 21:10:18] running...
I did perform a software update on the machine recently, so I checked what changed there...
$ cat /Library/Logs/Software\ Update.log <snip> 2011-06-15 08:13:31 -0400: Installed "Java for Mac OS X 10.5 Update 9" (1.0) 2011-07-29 15:39:24 -0400: Installed "Java for Mac OS X 10.5 Update 10" (1.0) 2011-07-29 15:40:55 -0400: Installed "Safari" (5.0.6) 2011-07-29 15:45:46 -0400: Installed "Security Update 2011-004" (1.0) 2011-07-29 15:47:10 -0400: Installed "iTunes" (10.4)
"Security Update 2011-004" looks awfully suspicious, however the kb article doesn't mention anything about launchd.
System Version: Mac OS X Server 10.5.8 (9L30)
Ok, after some more messing around and research I discovered the problem. It occurs (launchd fails to monitor path changes) when the machine is rebooted (in this case due to the software update). While snooping in the rotated system logs, I found this launchd error which occured only seconds after the machine powered on:
Aug 1 07:37:12 localhost kernel: Darwin Kernel Version 9.8.0: ... <snip> Aug 1 07:37:17 localhost com.apple.launchd (com.mydomain.myscript): Path monitoring failed on "/Volumes/MyDisk/Watch": No such file or directory
The REAL problem here is the the path launchd is supposed to watch exists on an external (FireWire) volume, and the launchd job is loaded at startup before the volume gets mounted. I would personally consider this a launchd bug, because I would expect launchd to treat the path as "unmodified" if it doesn't exist and simply not run the job at that moment. Instead, launchd completely ignores the path from this point forward, and the job sits idle for eternity.
So my question now is: what is a good way to ensure the disk mounts before telling launchd to monitor the path?