[launchd-dev] launchctl unload not working

James Bucanek subscriber at gloaming.com
Thu Nov 29 11:36:39 PST 2007


Hello again,

I've documented a little more of my problem. I think I might 
have a solution, but I'm still trying to understand what's going 
on and why. (Skip to the summary of the problem at the end if 
you want the short version.)

- A launchd.plist configuration file is stored it in 
/Library/LaunchDaemons/. The configuration includes the 
UserName=james property.  I made sure everything was unloaded 
before starting.

- Wrote a little script so I can see what's going on
     echo 'per-user'; launchctl list | fgrep -i qre
     echo 'per-user namespace'; launchctl bslist | fgrep -i qre
     echo 'root'; sudo launchctl list | fgrep -i qre
     echo 'root namespace'; sudo launchctl bslist | fgrep -i qre

- Load the daemon using the per-user launchd

crocodile:~ james$ launchctl load  /Library/LaunchDaemons/QRecallScheduler501.plist

crocodile:~ james$ ~/Desktop/seedaemons.sh
per-user
789 -   [0x0-0x4d04d].com.qrecall.client
115 -   [0x0-0x16016].com.qrecall.monitor
1251    -   0x1109d0.QRecallScheduler
1250    -   com.qrecall.scheduler.501
per-user namespace
A  QRecallMonitor
root
root namespace

(Ignore the extra child instance of QRecallScheduler; the daemon 
spawns a copy of itself to generate notifications -- a solution 
that I'm going to replace with another mechanism.)

I can see that the scheduler is running in the context of the 
per-user launchd. When it starts up its helper process, that too 
appears in the context of the user session:

crocodile:~ james$ ~/Desktop/seedaemons.sh
per-user
789 -   [0x0-0x4d04d].com.qrecall.client
115 -   [0x0-0x16016].com.qrecall.monitor
1263    -   0x1112c0.QRecallHelper
1251    -   0x1109d0.QRecallScheduler
1250    -   com.qrecall.scheduler.501
per-user namespace
A  QRecallMonitor
root
root namespace

After starting the helper tool, the scheduler connects with the 
helper and does its thing. So far, so good.

Now, I try to install the scheduler process as a system-wide daemon.

crocodile:~ james$ launchctl unload /Library/LaunchDaemons/QRecallScheduler501.plist

crocodile:~ james$ ~/Desktop/seedaemons.sh
per-user
789 -   [0x0-0x4d04d].com.qrecall.client
115 -   [0x0-0x16016].com.qrecall.monitor
per-user namespace
A  QRecallMonitor
root
root namespace

(All traces of the scheduler are gone.)

crocodile:~ james$ sudo launchctl load /Library/LaunchDaemons/QRecallScheduler501.plist

crocodile:~ james$ ~/Desktop/seedaemons.sh
per-user
789 -   [0x0-0x4d04d].com.qrecall.client
115 -   [0x0-0x16016].com.qrecall.monitor
1170    -   0x10dcc0.QRecallScheduler
1167    -   0x1109d0.QRecallScheduler
per-user namespace
A  QRecallMonitor
root
1170    -   0x10be90.QRecallScheduler
1167    -   com.qrecall.scheduler.501
root namespace
A  QRecallScheduler.501

It looks OK. The scheduler appears in the bootstrap launchd and 
also in the context of the per-user launchd (since I assume that 
the per-user launchd inherits everything from its parent). The 
"QRecallScheduler.501" is its registered Mach communications port.

Now when the scheduler starts the helper tool:

crocodile:~ james$ ~/Desktop/seedaemons.sh
per-user
789 -   [0x0-0x4d04d].com.qrecall.client
115 -   [0x0-0x16016].com.qrecall.monitor
1182    -   0x10df80.QRecallHelper
1170    -   0x10dcc0.QRecallScheduler
1167    -   0x1109d0.QRecallScheduler
per-user namespace
A  QRecallMonitor
root
1182    -   0x10b0b0.QRecallHelper
1170    -   0x10be90.QRecallScheduler
1167    -   com.qrecall.scheduler.501
root namespace
A  QRecallScheduler.501

The helper process appears in both contexts, but its 
communications port doesn't appear in the bootstrap namespace. 
The helper successfully registers its distribute objects 
connection port, but when the scheduler process attempt to 
connect with that port it fails.

It appears that the problem is this: The scheduler is started by 
the bootstrap launchd. It creates and registers a Mach port for 
communications. That works. The scheduler then launches a child 
process (the helper, using NSTask), but when it tries to connect 
with the Mach port created by the helper that doesn't work. No 
process can see the port and it doesn't appear in the boostrap 
namespace according to launchctl, even though the helper is told 
that the port was successfully created and registered.

-- 
James Bucanek



More information about the launchd-dev mailing list