Implement real socket-activation of multipathd.service
Hi there,
As part of my job this cycle at Canonical, I've spent some time looking at multipath-tools and determining how to properly implement socket-activation of the service. Currently, after you install the package the service is enabled right away. This is usually not a big deal if you're using a beefy system, but because multipath-tools is part of the default ubuntu-server image we have received complaints from people who are running Ubuntu on resource-constrained systems and didn't like the fact that multipathd was consuming 25 MB of RAM to do nothing.
On top of all that, as far as I have investigated the service is ready to work in a socket-activated manner, so there's really no reason I could see that justifies keeping it always active.
My idea here was to use the work done on open-iscsi as a base, but
expand a bit on it, especially the part about invoking udevadm trigger
on new installations of the package.
I have tested these changes on many scenarios (new installations; upgrades; with and without multipath devices already present in the system; with hotplugged multipath devices). All of these tests have been done using a VM.
@zeha, I'd love to hear your opinion here. Thanks in advance!
As requested by @ahasenack, here's the postinst that's generated with the new changes:
#!/bin/sh
# postinst script for multipath-tools
set -ex
MULTIPATH_SERVICE="multipathd.service"
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
# Automatically added by dh_installtmpfiles/13.11.6
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
if [ -x "$(command -v systemd-tmpfiles)" ]; then
systemd-tmpfiles ${DPKG_ROOT:+--root="$DPKG_ROOT"} --create multipath.conf || true
fi
fi
# End automatically added section
# Automatically added by dh_installinit/13.11.6
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
if [ -z "${DPKG_ROOT:-}" ] && [ -x "/etc/init.d/multipath-tools" ]; then
update-rc.d multipath-tools defaults >/dev/null
if [ -n "$2" ]; then
_dh_action=restart
else
_dh_action=start
fi
invoke-rc.d --skip-systemd-native multipath-tools $_dh_action || exit 1
fi
fi
# End automatically added section
# Automatically added by dh_installsystemd/13.11.6
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
if deb-systemd-helper debian-installed 'multipathd.service'; then
# The following line should be removed in trixie or trixie+1
deb-systemd-helper unmask 'multipathd.service' >/dev/null || true
if deb-systemd-helper --quiet was-enabled 'multipathd.service'; then
# Create new symlinks, if any.
deb-systemd-helper enable 'multipathd.service' >/dev/null || true
fi
fi
# Update the statefile to add new symlinks (if any), which need to be cleaned
# up on purge. Also remove old symlinks.
deb-systemd-helper update-state 'multipathd.service' >/dev/null || true
fi
# End automatically added section
# Automatically added by dh_installsystemd/13.11.6
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
if [ -z "${DPKG_ROOT:-}" ] && [ -d /run/systemd/system ]; then
systemctl --system daemon-reload >/dev/null || true
deb-systemd-invoke start 'multipathd.service' >/dev/null || true
fi
fi
# End automatically added section
# Automatically added by dh_installsystemd/13.11.6
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
# The following line should be removed in trixie or trixie+1
deb-systemd-helper unmask 'multipathd.socket' >/dev/null || true
# was-enabled defaults to true, so new installations run enable.
if deb-systemd-helper --quiet was-enabled 'multipathd.socket'; then
# Enables the unit on first installation, creates new
# symlinks on upgrades if the unit file has changed.
deb-systemd-helper enable 'multipathd.socket' >/dev/null || true
else
# Update the statefile to add new symlinks (if any), which need to be
# cleaned up on purge. Also remove old symlinks.
deb-systemd-helper update-state 'multipathd.socket' >/dev/null || true
fi
fi
# End automatically added section
# Automatically added by dh_installsystemd/13.11.6
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
if [ -d /run/systemd/system ]; then
systemctl --system daemon-reload >/dev/null || true
if [ -n "$2" ]; then
_dh_action=restart
else
_dh_action=start
fi
deb-systemd-invoke $_dh_action 'multipathd.socket' >/dev/null || true
fi
fi
# End automatically added section
if [ "$1" = "configure" ] && [ -d /run/systemd/system ]; then
if [ -n "$2" ]; then
# We're upgrading to a new version of the package.
if systemctl --quiet is-active "${MULTIPATH_SERVICE}"; then
# If the service is active, we need to restart it manually.
deb-systemd-invoke restart "${MULTIPATH_SERVICE}"
fi
else
# This is a new installation.
# Trigger udev in case we have multipath devices already
# present in the system. If there's any, then
# multipathd.service will be started.
udevadm trigger --action change --type devices --subsystem-match block --settle
fi
fi
exit 0