Skip to content

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
Edited by Sergio Durigan Junior

Merge request reports

Loading