[launchd-dev] launchctl unload not working

James Bucanek subscriber at gloaming.com
Wed Nov 28 22:28:25 PST 2007


Greetings,

I'm having a number of issues with launchd, particularly under 
Leopard. (Most, if not all, of this works just fine under 
Tiger.) My current, and most pressing issue, is trying to 
replace a daemon when the user upgrades their software.

Here's what I've got running

- A daemon is installed in 
/Library/LaunchDaemons/QRecallScheduler501.plist. I install the 
file by writing the plist then executing 'launchctl load 
/path-to-plist' as root. The .plist file has the UserName 
property set to an individual user.

This has been working (mostly) until I need to upgrade the 
user's software. I've tried various techniques, but the one I'm 
using now which I think should work doesn't.

Setup (if this makes any difference): The path to the daemon is 
a symbolic link to the actual binary in my application bundle. 
When the application is upgraded (via Sparkle), the application 
bundle is replaced with the new application bundle containing an 
updated daemon.

Step #1: Run 'launchctl unload -w /path-to-plist' as root. I 
wait for launchctl to return and then wait for the daemon to terminate.

Step #2: Delete the .plist at /Library/LaunchDaemons/QRecallScheduler501.plist.

Step #3: Write a new .plist at /Library/LaunchDaemons/QRecallScheduler501.plist

Step #4: Run 'launchctl load /path-to-plist' as root. Wait for 
launchctl to finish.

Here's what happens:

In step #1, launchctl returns with a status of 0. The daemon 
receives a SIGTERM and shuts down (2-3 seconds).

IMMEDIATELY, launchd starts the new deamon. I can only assume 
because the location of the updated binary is the same as the 
old one that was just terminated.

Steps #2 and #3 delete and rewrite the .plist.

Step #4 runs 'launchctl load' which returns with a status of 0. 
What I get in the console log is

11/28/07 4:09:44 PM [0x0-0x1e01e].com.qrecall.client[145] 
launchctl: Error unloading: com.qrecall.scheduler
11/28/07 4:09:56 PM com.apple.launchd[62] 
(com.qrecall.scheduler.501) Ignored this key: UserName

Contrary to the second error, the daemon is run with a UID of 
501 (which is correct -- the daemon will terminate if it's 
started as root).

The new daemon is then repeatedly restarted. (The daemon checks 
for a duplicate running instance of itself and terminates 
immediately if it's already running.)

11/28/07 4:09:57 PM com.apple.launchd[62] 
(com.qrecall.scheduler.501) Throttling respawn: Will start in 10 seconds
11/28/07 4:10:07 PM com.apple.launchd[62] 
(com.qrecall.scheduler.501) Throttling respawn: Will start in 10 seconds
11/28/07 4:10:17 PM com.apple.launchd[62] 
(com.qrecall.scheduler.501) Throttling respawn: Will start in 10 seconds
11/28/07 4:10:27 PM com.apple.launchd[62] 
(com.qrecall.scheduler.501) Throttling respawn: Will start in 10 seconds

The really bad part is the instance of the daemon that is 
running does not seem to be running in the correct 
environment/namespace. When it launches a sub-process it 
attempts to connect with it using Mach ports; The connection 
fails. Restarting the OS doesn't fix the problem.

I think the problem is that (in Leopard) there seems to be two 
instances of launchd running: One as root and one as user 501. 
But I'm getting very confused as to which one I should be trying 
to deal with.

I changed the code to call launchctl while running as user 501. 
That sometimes works and sometimes doesn't. If I can get the 
daemon to stop and issue 'launchctl load /...' as user 501, the 
daemon starts working: specifically, it can communication with 
the sub-processes that it starts. Once started using 'launchctl' 
as user 501 it can be stopped again using launchctl as 501. But 
after a restart, it's running in the wrong namespace again and I 
have to perform a 'sudo launchctl unload' to get it to stop.

So after an entire day, I'm really confused as to what launchctl 
commands I should be issuing to replace a running deamon, in 
what order, and using what UID.

James
-- 
James Bucanek



More information about the launchd-dev mailing list