A user logs in, opens some applications, plays a game, launches a browser and visits a webpage. Processes process. The user logs out. What happens to application processes when a user logs out? Do the processes die? And if they do, do they do so willingly or unwillingly? Or perhaps they just lay dormant until next user session?
I don’t want to get overly poetic or philosophical, but the answer does have some relevance and is not always obvious. Usually we expect processes to just die (or otherwise ”become nonexistant”) when we log out from a computer system, and this is what typically happens (if you are interested: most often processes die willingly, if we allow some antropomorphism here). But some software may instead daemonize itself, meaning that they detach themselves from terminal sessions and keep running after a user has logged out. A user may intentionally, perhaps even maliciously, leave processes running in the background when he logs out to perform some tasks. Some programs may have bugs and will not always exit as a user logs out or a terminal connection is broken. Even worse, a program may end up using resources pointlessly, for example stay in an endless loop using most available CPU time, or keep trying to write to nonwritable filesystem mounts or doing something else nonsensical.
These may be problems and while they may appear elsewhere, they are probably most prevalent in server environments such as in LTSP systems, because badly behaving software spends resources that could be used by other software. With servers problems also persist long times, because servers are rebooted relatively infrequently.
In some environments, of course, it may be desirable that users can leave processes open to do some processing after a user has logged out. For example, this might be the case when servers are used for scientific calculations. But even in these cases it may be useful to have some limits to what particular programs should be left running after the actual desktop session is closed.
One possible solution is xexit, which may be used to trigger scripts as users log out or their session is abruptly broken by a network disconnection or some other such an event. See the xexit project website at https://code.launchpad.net/~sbalneav/ltsp/xexit. The xexit program is written by Scott Balneaves, an LTSP developer, and it is created primarily for LTSP environments even though it can be used in other settings.
For those who use Ubuntu (or perhaps Debian or some other of its derivatives), the easiest way to install xexit is from the launchpad ppa by Scott:
sudo add-apt-repository ppa:sbalneav/ppa
sudo apt-get update
sudo apt-get install xexit
Those who use some other Unix can compile the source and install the xexit binary in the following way. First install autoconf and bzr, and then do (this should work for version 0.2):
bzr branch lp:~sbalneav/ltsp/xexit
cd xexit
touch ChangeLog
sh autogen.sh
./configure
make
sudo install -o root -g root -m 755 src/xexit /usr/local/bin/xexit
Using xexit from the Ubuntu package is easy. The package installs a startup
snippet into /etc/X11/Xsession.d/90xexit
so that xexit is started with
parameter /usr/bin/EndXSession
when user logs in. The xexit binary
periodically pings the X display and if a connection to X server is broken or
does not answer to ping checks in some time, xexit runs the session exit script
it was given as a parameter. With thin clients, if a thin client is turned off
uncleanly from a power button or if a network cable is unplugged, xexit
normally waits about 20-30 seconds before the exit script is run on the server.
The default exit session script (/usr/bin/EndXSession
) runs all the scripts in
directory /etc/Xexit.d. With the default script the scripts under /etc/Xexit.d
must be bourne shell fragments. The default configuration kills
evolution-data-server (that daemonizes itself when started), pulseaudio,
requests gconfd to shut down and then kills all user processes forcibly with
KILL-signal. This should work quite well for many configurations.
One can change the script that is run at session exit by editing
/etc/X11/Xsession.d/90xexit
. This also allows to use some other language than
bourne shell. For example, we might want to trigger
/usr/local/bin/kill_desktop_session
instead of executing the scripts in
/etc/Xexit.d
.
Edit /etc/X11/Xsession.d/90xexit
:
xexit /usr/local/bin/kill_desktop_session || true
One possible problem with default configuration is that if a user has two
desktop sessions to the same LTSP server, exiting one session will end up
forcing an exit to the other one as well. To kill only the processes of the
session where X connection is lost, one can only kill processes that have the
same LTSP_CLIENT_HOSTNAME environment variable set that xexit has. This can be
done by having the following script at /usr/local/bin/kill_desktop_session
(do remember to set the executable bits for this script):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
This works, because for each desktop session an xexit process is started, and
it has the same environment variable LTSP_CLIENT_HOSTNAME as other processes in
that session. In function lookup_processes
we lookup the pids of those
processes that match this environment variable. Then we send them CONT
(continue) signal (in case some of them have been stopped), request them to
terminate (by sending TERM), and if they did not comply after three seconds, we
forcibly kill them. (In process termination, it is nice to ask politely before
making demands, in case some programs want to do some operations (such as
writing their internal state to files) before they are killed).
In a non-LTSP case we could replace the TERMINAL and lookup_processes() definitions with this:
1 2 3 4 5 |
|
This should work for laptops, workstations and other such cases, in case xexit is wanted or needed for those. Xexit also works properly with the ”change user” feature in GNOME session (and probably others), that is, it will not kill processes when user session is still open, even if it is not active.
Note that xexit is run with the privileges of the user that logs in. This means that if a user wants to bypass this mechanism and not have her processes killed when she logs out, she can do so by killing the xexit process when her desktop session is still open. While this may be an issue, on the other hand the choice to run xexit with user privileges makes xexit simple to implement, and it safeguards against some bad session exit scripts, because xexit only has the same limited privileges that the user has.
What is nice about xexit is that it is simple, effective and mostly desktop environment agnostic. The default configuration targets a typical Ubuntu installation, but it may be adapted with ease to other systems and configurations. Try it out, and keep your servers clean!