[launchd-dev] Cause of "Service cannot load in requested session"?

Damien Sorresso dsorresso at apple.com
Thu Nov 5 16:41:17 PST 2015


On 5 Nov, 2015, at 15:54, James Bucanek <subscriber at gloaming.com> wrote:
> 
>> Damien Sorresso <mailto:dsorresso at apple.com> November 5, 2015 at 3:43 PM
>> On 5 Nov, 2015, at 14:23, James Bucanek <subscriber at gloaming.com <mailto:subscriber at gloaming.com>> wrote:
>>> I understand. This is exactly the session I want. My product has an option ("Start and run actions when logged out") that allows you install the scheduler agent the "Background" session so that backups and other maintenance can be performed even when logged out (or because you've logged out).
>> 
>> Okay, just as long as you understand the implications.
> I'm trying. :)
> 
> 
>>> I'm surprised that you say that the home folder might not be available when the Background session is created. How is that possible? The user agent configuration file (~/Library/LaunchAgents/com.qrecall.scheduler.plist) is _inside_ the home folder. How would launchd load an agent service *before* the configuration file that defines that service is readable?
>> 
>> This gets complicated. First off, Background agents cannot rely on the presence of the user's home directory because there is code that executes only in the GUI login path which may be responsible for making that home directory available. Think NFS home directories or OG FileVault, which both require the user to enter her password at the login window to mount/decrypt the home directory. In either of those scenarios, without the user's secret, the home directory is inaccessible.
> Honestly, I had always assumed that any authentication/login/mounting/decrypting would have been handled in login's Aqua session, not the user's Aqua session. But if that's where it's happening, I can see some of the chicken-and-egg problems.

The login window's session gets morphed into the user's Aqua session. It's a very weird and complex dance.

>> For this reason, launchd cannot actually support loading Background agents from the user's home directory. This is what you're hitting.
>> 
>> To give you a little more background on what's happening, launchd has to use a helper (otherbsd) to sniff out agents from the user's home directory because it itself cannot actually safely resolve a user's home directory location. The calls to do this (getpwnam(3) and friends) might wind up doing IPC to opendirectoryd, which launchd is responsible for launching, which would create a layering inversion.
>> 
>> So what it does instead is spawn its little otherbsd helper to go off, find the user's home directory, and snarf the agents  contained therein. But this agent is there specifically to load stuff into the Aqua session. So when it gives launchd a plist that has its loads limited to the Background session, launchd says "No you're in the wrong session", hence that error message.
> Thanks, that makes (a lot more) sense now.
> 
> OK, one last question: Is it ever the case that the home directory/mountpoint might disappear *after* a user's Background and Aqua session is created, say when they log out?

Yes, network home directories or OG FileVault homes will probably get unmounted after logout.

>> Something ugly you could do:
>> 
>> Have another plist inside ~/Library/LaunchAgents that does not have the LimitLoadToSession key set which runs a script which does
>> 
>> launchctl load -S Background ~/Library/LaunchAgents/com.qrecall.scheduler.plist
>> 
>> That will target the load to the background session upon the user's GUI login, and the agent will continue to be available after logout, but it will not be available until the user logs in at least once on the GUI.
> There's a possibility I don't have to get that ugly, but I might look into implementing something like that ... but only if the answer to the earlier question is "never."

Perhaps the best way to answer would be the statement that the only time a home directory guaranteed to be available is when the user is logged in at the GUI console. Once that GUI login session goes away, there is no guarantee of home directory availability.

> The principle purpose of my app is backups. If the user's home directory is going to unmount again when they log out, trying to perform a backup at that point is pretty useless, so worrying about how to keep the scheduler running int the background session under those circumstance would be moot.

In that case, I would say that your agent could potentially listen for a notification for when that user actually logs in. I don't know what that notification is called, but I'm pretty sure it exists. ;)

At that point, it could start a backup at a low priority QoS. (See the dispatch(3) man pages for explanations of the quality-of-service APIs and how you can run work at a background priority.)
-damien

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/launchd-dev/attachments/20151105/8c64c36e/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 3327 bytes
Desc: not available
URL: <https://lists.macosforge.org/pipermail/launchd-dev/attachments/20151105/8c64c36e/attachment-0001.p7s>


More information about the launchd-dev mailing list