Thank you Mantas and Djalal for improving my mental model.
On Fri, Jul 11, 2014 at 1:14 AM, Mantas Mikulėnas <graw...@gmail.com> wrote: > On Fri, Jul 11, 2014 at 7:18 AM, Kurt von Laven <k...@endlessm.com> wrote: > >> Hello folks, >> >> Apologies if anybody is getting this message twice; I originally posted >> on d...@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 <graw...@gmail.com> > -- Kurt von Laven | Endless Mobile | 732.784.7356 | EndlessM.com <http://endlessm.com/>
_______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel