Bug#903807: deb-systemd-helper purge breaks services duplicated between conflicting packages

Richard Laager rlaager at wiktel.com
Sun Jul 15 03:51:30 BST 2018


Package: init-system-helpers
Version: 1.51
Severity: important

If two packages ship the same unit, `deb-systemd-helper purge` is
problematic.  For example, the packages "ntp" and "ntpsec" both provide
a unit called "ntp.service". (I am the maintainer of ntpsec.)

dh_systemd_enable adds this to the postrm script of packages, where UNIT
is the relevant systemd unit:

if [ "$1" = "remove" ]; then
        if [ -x "/usr/bin/deb-systemd-helper" ]; then
                deb-systemd-helper mask UNIT >/dev/null
        fi
fi

if [ "$1" = "purge" ]; then
        if [ -x "/usr/bin/deb-systemd-helper" ]; then
                deb-systemd-helper purge UNIT >/dev/null
                deb-systemd-helper unmask UNIT >/dev/null
        fi
fi

Consider this series of steps:
1) apt install ntp
2) apt install ntpsec
3) apt purge ntp

Step 1 installs /usr/lib/systemd/system/ntp.service, and the postinst
(by way of the dh_systemd_enable postinst snippet) enables the service.

Step 2 results in the ntp package being removed, which (by way of the
dh_systemd_enable postrm snippet quoted above) masks ntp.service. Then,
as ntpsec is installed, it installs /usr/lib/systemd/system/ntp.service,
which is unmasked and again enabled by its postinst.

Step 3 results in ntp's postrm script calling
`deb-systemd-helper purge ntp.service`. This creates a problem.

Desired results:
ntp.service is left enabled.

Actual results:
ntp.service is disabled

Internally, deb-systemd-helper implements purge as a disable plus some
extra steps conditionalized on is_purge(). It is this disable that is
problematic.

There are a number of ways to address this. My first thought is that
disable and/or purge should be skipped if the unit file still exists.
This would be similar to the documented behavior of update-rc.d.
(Unfortunately, update-rc.d isn't doing that, which creates the same
problem for me on sysvinit, which I just commented about in #680293.)

Purging ntp after installing ntpsec seems to be fairly common with
users. Accordingly, I'm setting the severity of this bug to important. I
would mark it serious, but I can't currently point to an explicit policy
item being violated nor am I the maintainer of this package (nor a
release manager).

The same thing happens, for the exact same reasons, if you start with
ntpsec, install ntp, then purge ntpsec.

Here are the deb-systemd-helper DEBUG logs from step 3 (apt purge ntp):

Purging configuration files for ntp (1:4.2.8p11+dfsg-1) ...

(deb-systemd-helper DEBUG) is purge = yes

(deb-systemd-helper DEBUG) action = disable, scriptname = ntp.service, service_path = /lib/systemd/system/ntp.service

(deb-systemd-helper DEBUG) Reading state file /var/lib/systemd/deb-systemd-helper-enabled/ntp.service.dsh-also

(deb-systemd-helper DEBUG) Contents: $VAR1 = [

          '/etc/systemd/system/multi-user.target.wants/ntp.service'

        ];



(deb-systemd-helper DEBUG) rmdir_if_empty /var/lib/systemd/deb-systemd-helper-enabled

(deb-systemd-helper DEBUG) rmdir_if_empty /var/lib/systemd/deb-systemd-helper-enabled/graphical.target.wants

(deb-systemd-helper DEBUG) rmdir(/var/lib/systemd/deb-systemd-helper-enabled/graphical.target.wants) failed (Directory not empty)

(deb-systemd-helper DEBUG) rmdir_if_empty /var/lib/systemd/deb-systemd-helper-enabled/multi-user.target.wants

(deb-systemd-helper DEBUG) rmdir(/var/lib/systemd/deb-systemd-helper-enabled/multi-user.target.wants) failed (Directory not empty)

(deb-systemd-helper DEBUG) rmdir_if_empty /var/lib/systemd/deb-systemd-helper-enabled/network-online.target.wants

(deb-systemd-helper DEBUG) rmdir(/var/lib/systemd/deb-systemd-helper-enabled/network-online.target.wants) failed (Directory not empty)

(deb-systemd-helper DEBUG) rmdir_if_empty /var/lib/systemd/deb-systemd-helper-enabled/paths.target.wants

(deb-systemd-helper DEBUG) rmdir(/var/lib/systemd/deb-systemd-helper-enabled/paths.target.wants) failed (Directory not empty)

(deb-systemd-helper DEBUG) rmdir_if_empty /var/lib/systemd/deb-systemd-helper-enabled/remote-fs.target.wants

(deb-systemd-helper DEBUG) rmdir(/var/lib/systemd/deb-systemd-helper-enabled/remote-fs.target.wants) failed (Directory not empty)

(deb-systemd-helper DEBUG) rmdir_if_empty /var/lib/systemd/deb-systemd-helper-enabled/sockets.target.wants

(deb-systemd-helper DEBUG) rmdir(/var/lib/systemd/deb-systemd-helper-enabled/sockets.target.wants) failed (Directory not empty)

(deb-systemd-helper DEBUG) rmdir_if_empty /var/lib/systemd/deb-systemd-helper-enabled/sysinit.target.wants

(deb-systemd-helper DEBUG) rmdir(/var/lib/systemd/deb-systemd-helper-enabled/sysinit.target.wants) failed (Directory not empty)

(deb-systemd-helper DEBUG) rmdir_if_empty /var/lib/systemd/deb-systemd-helper-enabled/time-sync.target.wants

(deb-systemd-helper DEBUG) rmdir(/var/lib/systemd/deb-systemd-helper-enabled/time-sync.target.wants) failed (Directory not empty)

(deb-systemd-helper DEBUG) rmdir_if_empty /var/lib/systemd/deb-systemd-helper-enabled/timers.target.wants

(deb-systemd-helper DEBUG) rmdir(/var/lib/systemd/deb-systemd-helper-enabled/timers.target.wants) failed (Directory not empty)

(deb-systemd-helper DEBUG) rmdir(/var/lib/systemd/deb-systemd-helper-enabled) failed (Directory not empty)

(deb-systemd-helper DEBUG) rmdir_if_empty /etc/systemd/system/getty.target.wants

(deb-systemd-helper DEBUG) rmdir(/etc/systemd/system/getty.target.wants) failed (Directory not empty)

(deb-systemd-helper DEBUG) rmdir_if_empty /etc/systemd/system/graphical.target.wants

(deb-systemd-helper DEBUG) rmdir(/etc/systemd/system/graphical.target.wants) failed (Directory not empty)

(deb-systemd-helper DEBUG) rmdir_if_empty /etc/systemd/system/multi-user.target.wants

(deb-systemd-helper DEBUG) rmdir(/etc/systemd/system/multi-user.target.wants) failed (Directory not empty)

(deb-systemd-helper DEBUG) rmdir_if_empty /etc/systemd/system/network-online.target.wants

(deb-systemd-helper DEBUG) rmdir(/etc/systemd/system/network-online.target.wants) failed (Directory not empty)

(deb-systemd-helper DEBUG) rmdir_if_empty /etc/systemd/system/paths.target.wants

(deb-systemd-helper DEBUG) rmdir(/etc/systemd/system/paths.target.wants) failed (Directory not empty)

(deb-systemd-helper DEBUG) rmdir_if_empty /etc/systemd/system/remote-fs.target.wants

(deb-systemd-helper DEBUG) rmdir(/etc/systemd/system/remote-fs.target.wants) failed (Directory not empty)

(deb-systemd-helper DEBUG) rmdir_if_empty /etc/systemd/system/sockets.target.wants

(deb-systemd-helper DEBUG) rmdir(/etc/systemd/system/sockets.target.wants) failed (Directory not empty)

(deb-systemd-helper DEBUG) rmdir_if_empty /etc/systemd/system/sysinit.target.wants

(deb-systemd-helper DEBUG) rmdir(/etc/systemd/system/sysinit.target.wants) failed (Directory not empty)

(deb-systemd-helper DEBUG) rmdir_if_empty /etc/systemd/system/time-sync.target.wants

(deb-systemd-helper DEBUG) rmdir(/etc/systemd/system/time-sync.target.wants) failed (Directory not empty)

(deb-systemd-helper DEBUG) rmdir_if_empty /etc/systemd/system/timers.target.wants

(deb-systemd-helper DEBUG) rmdir(/etc/systemd/system/timers.target.wants) failed (Directory not empty)

(deb-systemd-helper DEBUG) is purge = no

(deb-systemd-helper DEBUG) action = unmask, scriptname = ntp.service, service_path = /lib/systemd/system/ntp.service

(deb-systemd-helper DEBUG) rmdir_if_empty /var/lib/systemd/deb-systemd-helper-masked

(deb-systemd-helper DEBUG) rmdir(/var/lib/systemd/deb-systemd-helper-masked) failed (No such file or directory)

-- 
Richard



More information about the Pkg-systemd-maintainers mailing list