My Launch Agent is Persisting Beyond Logout
Hi, I have a custom process that is invoked when a user logs in via having a launchd config file located in /Library/Launch Agents. The config file looks something like this: <key>KeepAlive</key> <true/> <key>Label</key> <string>com.company.mylaunchagent</string> <key>OnDemand</key> <false/> <key>ProgramArguments</key> <array> <string>/mylaunchagent</string> </array> <key>RunAtLoad</key> <true/> The mylaunchagent is invoked just fine. If I do a fast user switch to login another user then a second instance is invoked for the second user. All seems good. However, when the second user logs out the second instance of mylaunchagent continues to stay running even though the user logs out! The Apple Multiple User Environments document [1] makes two statements regarding this. First, "If a user process daemonizes itself prior to logout, it can live past the end of the user logout and prolong the existence of the login session." And Second, "Per-user services are shut down automatically and are not given the chance to abort the logout procedure." The mylaunchagent process is always a background process just invoked by launchd, so given the first statement I guess that is why it is persisting logout. However, given the second statement, since this is a per-user service as launchagents are by definition, I don't understand why it isn't shut down automatically on logout. Frankly, those two statements seem contradictory. [1] Apple Multiple User Environments http://developer.apple.com/documentation/MacOSX/Conceptual/BPMultipleUsers/C... Can anyone point me towards how to make sure my launch agent processes get properly killed when a user logs out? I appreciate any tips. Thanks!
On Tue, Mar 11, 2008 at 8:41 PM, Mac QA <macqaguy@gmail.com> wrote:
The Apple Multiple User Environments document [1] makes two statements regarding this. First, "If a user process daemonizes itself prior to logout, it can live past the end of the user logout and prolong the existence of the login session." And Second, "Per-user services are shut down automatically and are not given the chance to abort the logout procedure." The mylaunchagent process is always a background process just invoked by launchd, so given the first statement I guess that is why it is persisting logout. However, given the second statement, since this is a per-user service as launchagents are by definition, I don't understand why it isn't shut down automatically on logout. Frankly, those two statements seem contradictory.
I take the second statement to mean "We send a SIGKILL to the agent". If the agent has daemonized, the child will have been re-parented, hence the first statement. In short: the mylaunchagent process must not daemonize, i.e., must not fork and exit. If it has a '-f' (run in foreground) option or similar, use that. Hamish
"Mac QA", Does your agent catch Unix signals? Can you please do a "launchctl list com.company.mylaunchagent" and email us the results? Thanks! davez On Mar 11, 2008, at 1:41 PM, Mac QA wrote:
Hi,
I have a custom process that is invoked when a user logs in via having a launchd config file located in /Library/Launch Agents. The config file looks something like this:
<key>KeepAlive</key> <true/> <key>Label</key> <string>com.company.mylaunchagent</string> <key>OnDemand</key> <false/> <key>ProgramArguments</key> <array> <string>/mylaunchagent</string> </array> <key>RunAtLoad</key> <true/>
The mylaunchagent is invoked just fine. If I do a fast user switch to login another user then a second instance is invoked for the second user. All seems good. However, when the second user logs out the second instance of mylaunchagent continues to stay running even though the user logs out!
The Apple Multiple User Environments document [1] makes two statements regarding this. First, "If a user process daemonizes itself prior to logout, it can live past the end of the user logout and prolong the existence of the login session." And Second, "Per-user services are shut down automatically and are not given the chance to abort the logout procedure." The mylaunchagent process is always a background process just invoked by launchd, so given the first statement I guess that is why it is persisting logout. However, given the second statement, since this is a per-user service as launchagents are by definition, I don't understand why it isn't shut down automatically on logout. Frankly, those two statements seem contradictory.
[1] Apple Multiple User Environments http://developer.apple.com/documentation/MacOSX/Conceptual/BPMultipleUsers/C... /apple_ref/doc/uid/20002208-106206
Can anyone point me towards how to make sure my launch agent processes get properly killed when a user logs out? I appreciate any tips. Thanks! _______________________________________________ launchd-dev mailing list launchd-dev@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/launchd-dev
On Tue, Mar 11, 2008 at 4:55 PM, Hamish Allan <hamish@gmail.com> wrote:
In short: the mylaunchagent process must not daemonize, i.e., must not fork and exit. If it has a '-f' (run in foreground) option or similar, use that.
Hamish, Thanks for the clarification. I think I understand the situation now. The mylaunchagent process is a Cocoa tool that I wrote myself, and I have no call to fork or exit in it. Yet it is meant to be a background process invoked with launchd, so I guess that is the same thing. On Tue, Mar 11, 2008 at 11:11 PM, Dave Zarzycki <zarzycki@apple.com> wrote:
Does your agent catch Unix signals? Can you please do a "launchctl list com.company.mylaunchagent" and email us the results?
Dave, No I don't catch Unix signals, my launch agent is written in Cocoa. I've never been aquatinted with unix signals before. Shouldn't there be a Cocoa notification to tell my lunch agent daemon that the user is logging out to allowing me to clean-up and terminate the program? All I can find is NSWorkspaceSessionDidResignActiveNotification, but this is for if a fast user switch is performed not an actual logout. In response to your inquiry about launchctl it only prints the name I put in. So, I logged in 3 users via fast user switch, logded out two of them, then Activity Monitor shows 3 instances of my launch agent still running. And launchctl shows: $ launchctl list com.company.mylaunchagentd com.company.mylaunchagentd Thank you both for your responses.
On Tue, Mar 11, 2008 at 11:11 PM, Dave Zarzycki <zarzycki@apple.com> wrote:
Does your agent catch Unix signals?
Quick clarifying question about this Unix signal business. Currently, if I log in 3 users via fast user switching, log out two of them, then Activity Monitor shows 3 instances of my launch agent running. Yet even if I try to force quit one of the launch agents running from one of the now logged out users from Activity Monitor (and authenticate as an administrator to do so) the process still gets re-launched by launchd. Doesn't it seem wrong for launchd to be RE-launching an app for a user that is no longer logged in. If I do whatever is necessary to catch this Unix signal business and exit the daemon that way, will it still keep getting relaunched by launchd after the user logs out?
On Thu, Mar 13, 2008 at 4:32 PM, Nathan Duran <launchd@khiltd.com> wrote:
On Mar 13, 2008, at 1:03 PM, Mac QA wrote:
Doesn't it seem wrong for launchd to be RE-launching an app for a user that is no longer logged in.
Fast User Switching does not log anybody out. That's why it's "fast."
Right. The second and third users were logged in with fast user switching. And then logged out by selecting logout from the Apple menu. Leaving only one user logged in. Yet the launch agent processes for users two and three were still running as viewed from the Activity Monitor in user one. And when using the Activity Monitor to force quit the launch agents from user two and three launchd automatically relaunches them even though user two and three are no longer logged in. I realize its MY fault that my launch agent doesn't get terminated on logout, and that I need to respond to this Unix signal thing. But it would also seem that there is a problem with launchd if it is re-launching user agents for users that are not logged in to the system.
Mac QA <mailto:macqaguy@gmail.com> wrote (Tuesday, March 11, 2008 1:41 PM -0400):
The mylaunchagent is invoked just fine. If I do a fast user switch to login another user then a second instance is invoked for the second user. All seems good. However, when the second user logs out the second instance of mylaunchagent continues to stay running even though the user logs out!
There are several levels of "logged in/out". A launchd Aqua session is created when the user logs into the GUI. When the user logs out again, the Aqua session ends. Restrict your user agent to the Aqua session and it should behave the way you are expecting. <key>LimitLoadToSessionType</key> <string>Aqua</string> In contrast, the Background session for a user gets created whenever a process for that user is created. This also gets created when the user logs into the GUI but can just as easily be created by starting a remote terminal session via ssh. The Background session does not end when the user logs out of the GUI. My product actually uses this fact to provide services for users after they log out. -- James Bucanek
participants (5)
-
Dave Zarzycki
-
Hamish Allan
-
James Bucanek
-
Mac QA
-
Nathan Duran