[Pkg-xfce-devel] Bug#762218: lightdm: maintainer scripts not idempotent: reinstalling does not fix half-working package

Santiago Vila sanvila at unex.es
Fri Sep 19 17:52:07 UTC 2014

Package: lightdm
Version: 1.10.2-1
Severity: serious

On a system where lightdm is installed, then purged and then
reinstalled again, the /var/lib/lightdm directory *might* not exist,
leading to a system where lightdm does not start and the user is
*greatly* confused.

In my case, these are the symptoms:

# systemctl status lightdm
lightdm.service - Light Display Manager
   Loaded: loaded (/lib/systemd/system/lightdm.service; enabled)
   Active: failed (Result: start-limit) since vie 2014-09-19 18:40:41 CEST; 25min ago
     Docs: man:lightdm(1)
  Process: 1933 ExecStart=/usr/sbin/lightdm (code=exited, status=1/FAILURE)
  Process: 1930 ExecStartPre=/bin/sh -c [ "$(cat /etc/X11/default-display-manager 2>/dev/null)" = "/usr/sbin/lightdm" ] (code=exited, status=0/SUCCESS)
 Main PID: 1933 (code=exited, status=1/FAILURE)
   CGroup: /system.slice/lightdm.service

sep 19 18:40:41 mymachine systemd[1]: lightdm.service: main process exited, code=exited, status=1/FAILURE
sep 19 18:40:41 mymachine systemd[1]: Unit lightdm.service entered failed state.
sep 19 18:40:41 mymachine systemd[1]: lightdm.service holdoff time over, scheduling restart.
sep 19 18:40:41 mymachine systemd[1]: Stopping Light Display Manager...
sep 19 18:40:41 mymachine systemd[1]: Starting Light Display Manager...
sep 19 18:40:41 mymachine systemd[1]: lightdm.service start request repeated too quickly, refusing to start.
sep 19 18:40:41 mymachine systemd[1]: Failed to start Light Display Manager.
sep 19 18:40:41 mymachine systemd[1]: Unit lightdm.service entered failed state.

After investigation, it seems the root of the problem is that /var/lib/lightdm
did not exist. But before I discovered that, one might thing that

dpkg --purge lightdm
apt-get install lightdm

would fix the problem.

Well, it does not because the /var/lib/lightdm directory is created
*only* if the lightdm user does not exist:

# creating lightdm user if he isn't already there
if ! getent passwd lightdm >/dev/null; then
        adduser --system --ingroup lightdm --home /var/lib/lightdm lightdm
        usermod -c "Light Display Manager" lightdm
        usermod -d "/var/lib/lightdm"      lightdm
        usermod -g "lightdm"               lightdm
        usermod -s "/bin/false"            lightdm

# The following code does only work if /var/lib/lightdm *already* exist:
if [ -d /var/lib/lightdm ]; then
  chown -R lightdm:lightdm /var/lib/lightdm
  chmod 0750 /var/lib/lightdm

So this is how you can reproduce the disaster I have just experienced:

* Take a jessie system with minimal packages installed.

* Install lightdm:

apt-get install lightdm

* Do something that makes the purge not to work 100% as expected, like, for example

rm /usr/sbin/deluser

In my case, I believe having lightdm still working is what actually
happened for deluser to fail.

* Purge lightdm:

dpkg --purge lightdm

What postrm does (or does not do) is part of the problem. let's see:

if [ "$1" = "purge" ] ; then
        update-rc.d lightdm remove >/dev/null
        if [ -d /var/lib/lightdm ]; then
                rm -r /var/lib/lightdm
# Ok, we see here that /var/lib/lightdm is removed *unconditionally*.

        if [ -d /var/log/lightdm ]; then
                rm -r /var/log/lightdm
        if getent passwd lightdm >/dev/null; then
                if [ -x /usr/sbin/deluser ]; then
                        deluser --system lightdm ||echo " Could not remove lightdm user, please make sure lightdm is not running before attempting to purge lightdm" 
# But if deluser fails, for whatever reason, postrm still ends with an exit status of 0
# and the lightdm user will already exist if the user decides to reinstall lightdm.

So, it seems that postinst and postrm do not play by the same rules,
because postinst blindly assumes that this implication holds:

user lightdm exists   ==>   the directory /var/lib/lightdm does not need to be created

while, at the same time, postrm makes such assumption not to be true,
as it unconditionally removes /var/lib/lightdm and then forgives any
error from deluser.


1) In postinst, please add code to ensure that /var/lib/lightdm exist
*regardless* of the user lightdm already existing or not.

2) In postrm, please do not ignore error from deluser. Quoting policy:

  The package management system looks at the exit status from these
  scripts. It is important that they exit with a non-zero status if
  there is an error, so that the package management system can stop its

3) In postrm, please change the order in which things are done: If
deluser does not work because I'm still using lightdm, there is no
point in removing /var/lib/lightdm because then it is when things
start to go really wrong. In fact, postrm should abort the purge as
soon as possible if lightdm is still working in the system.

Either I can purge the package or I can't, but if I purge it and the
postm script "forgives" some of the errors, the system should not be
left with a lightdm package which appears as being "installed" but
does not work.


More information about the Pkg-xfce-devel mailing list