[launchd-dev] launchctl unload not working
Kevin Van Vechten
kvv at apple.com
Wed Nov 28 23:08:49 PST 2007
I recommend reading the "Daemonomicon" <http://developer.apple.com/technotes/tn2005/tn2083.html#SECDAEMONOMICON
>.
Short summary pertinent to your symptoms:
- Root (uid 0) launchd loads jobs from LaunchDameons directories. Use
`sudo launchctl` to communicate with it.
- Per-user (uid 501) launchd loads jobs from LaunchAgents
directories. Use `launchctl` to communicate with it.
- Per-user launchd ignores the UserName key because it does not have
the privilege to execute as any other user than the current user.
- Per-user mach bootstrap is a sub-bootstrap of the root mach
bootstrap: agents can lookup daemons, but daemons cannot lookup agents.
- Kevin
On Nov 28, 2007, at 10:28 PM, James Bucanek wrote:
> 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
>
> _______________________________________________
> launchd-dev mailing list
> launchd-dev at lists.macosforge.org
> http://lists.macosforge.org/mailman/listinfo/launchd-dev
More information about the launchd-dev
mailing list