[systemd-devel] How to Listen for SessionRemoved Signal
Kurt von Laven
kurt at endlessm.com
Fri Jul 11 10:57:05 PDT 2014
Thank you Mantas and Djalal for improving my mental model.
On Fri, Jul 11, 2014 at 1:14 AM, Mantas Mikulėnas <grawity at gmail.com> wrote:
> On Fri, Jul 11, 2014 at 7:18 AM, Kurt von Laven <kurt at endlessm.com> wrote:
>
>> Hello folks,
>>
>> Apologies if anybody is getting this message twice; I originally posted
>> on dbus at lists.freedesktop.org and was directed here.
>>
>> I am attempting to listen to the SessionRemoved signal from the login
>> manager <http://www.freedesktop.org/wiki/Software/systemd/logind/>. I
>> have no trouble in the case where the user logs out and waits for ~15
>> seconds before shutting down, but when the user shuts down the system
>> without first logging out I don't hear the SessionRemoved signal in time. I
>> would've thought that inhibiting shutdown (by calling the Inhibit method
>> of the login manager
>> <http://www.freedesktop.org/wiki/Software/systemd/inhibit/>) would be
>> the appropriate way to keep my process alive long enough to record the
>> SessionRemoved signal before my process gets killed. Apparently that is not
>> the case though. I am fairly certain that I am actually inhibiting
>> shutdown, because my process shows up when I call ListInhibitors in
>> D-Feet <https://wiki.gnome.org/action/show/Apps/DFeet>.
>>
>> In case it's relevant, I'm using the delay mode of the inhibit method,
>> and my process runs as root.
>>
>
> Inhibitors do not make any sense here. You're inhibiting not just the
> final power-off of the machine, but the *entire* shutdown process, *including
> the stopping of login sessions*, so you would not see SessionRemoved
> until after you release the inhibitor anyway.
>
>
Doh. Makes perfect sense. I got rid of the inhibition logic entirely to no
avail though, so I suspect this was only one of my problems.
> To test whether my process was running in the user session, I called getsid
>> (0) <http://linux.about.com/library/cmd/blcmdl2_getsid.htm>. It returned
>> the PID of my process, which does not match the session ID of the
>> SessionRemoved signals I was able to record. Is this a legitimate way to
>> verify that my process isn't running in the user session? My original
>> assumption was that my process couldn't possibly be in the user session
>> because I am able to hear the SessionRemoved signal when the user logs out
>> and waits for ~15 seconds. Is that a bad assumption to make?
>>
>
> No, this is the wrong method. logind's sessions have nothing to do with
> getsid() and POSIX sessions (which are limited to the point of being
> completely useless).
>
> To see if you're running within a logind session, the preferred way is *sd_pid_get_session(0,
> &session_id)*. Alternatively, you can:
>
> I confirmed that my process is not running in a session
(sd_pid_get_session_id returned a negative number). This makes sense
because it is launched by a .service file in /lib/systemd/system.
> a) check the $XDG_SESSION_ID variable, which will contain the session ID
> if you're inside one,
> b) check the cgroups of your process (e.g. in /proc/self/cgroup), which
> will show you as being in "/user.slice/user-%s.slice/session-%d.scope".
>
> Note that there is no supported way for escaping a user session. But if
> you run your program as a system service (from a .service unit), then it
> won't be put in a session in the first place.
>
>
>> I was advised that some shutdown commands bypass logind, so I tried
>> shutting down several different ways (systemctl shutdown, shutdown now,
>> sudo shutdown now, calling Shutdown method on org.gnome.SessionManager from
>> D-Feet, and the typical GUI way). In all cases I got the same result: I
>> didn't hear the SessionRemoved signal.
>>
>
> logind is just a "proxy" for purposes of polkit authorization (which
> cannot be done in pid 1); it only forwards the shutdown request to systemd
> (PID 1). Even tools that use the old SysVinit "/dev/initctl" method still
> result in the same request, and systemd performs the same shutdown process.
>
>
>> If anyone has any suggestions on how to debug this or knows what I am
>> missing here, that would be greatly appreciated. Please let me know if any
>> additional details would be helpful.
>>
>
> If I remember correctly the details of systemd boot process, the best
> approach would be to run your monitor-thingy in a system service (a
> .service unit), and *order the service
> "Before=systemd-user-sessions.service"*. That way, during boot, it will
> be started *before* any session gets created, and the opposite happens
> during shutdown – your service will be stopped *after* all sessions are
> removed.
>
> I added systemd-user-sessions.service to the "Before" line of my .service
file, also to no avail. Here is the relevant excerpt of my .service file in
case I managed to screw anything else up.
Requires=dbus.service
After=dbus.service
Before=dbus-org.freedesktop.login1.service systemd-logind.service
systemd-user-sessions.service
[Install]
WantedBy=multi-user.target
In response to Djalal's suggestion that I treat the "PrepareForShutdown"
signal as an indicator that the user logged out: unfortunately it's already
too late at that point. (This is a property of my own particular situation,
not anything to do with DBus or systemd in general.)
--
> Mantas Mikulėnas <grawity at gmail.com>
>
--
Kurt von Laven | Endless Mobile | 732.784.7356 | EndlessM.com
<http://endlessm.com/>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/systemd-devel/attachments/20140711/ad054566/attachment.html>
More information about the systemd-devel
mailing list