From e43405778454cbe8cdaeabed519e81ee749a64ee Mon Sep 17 00:00:00 2001 From: Nikos Dragazis Date: Mon, 2 Feb 2026 20:34:32 +0200 Subject: [PATCH] scylla_swap_setup: Remove Before=swap.target dependency from swap unit When a Scylla node starts, the scylla-image-setup.service invokes the `scylla_swap_setup` script to provision swap. This script allocates a swap file and creates a swap systemd unit to delegate control to systemd. By default, systemd injects a Before=swap.target dependency into every swap unit, allowing other services to use swap.target to wait for swap to be enabled. On Azure, this doesn't work so well because we store the swap file on the ephemeral disk [1] which has network dependencies (`_netdev` mount option, configured by cloud-init [2]). This makes the swap.target indirectly depend on the network, leading to dependency cycles such as: swap.target -> mnt-swapfile.swap -> mnt.mount -> network-online.target -> network.target -> systemd-resolved.service -> tmp.mount -> swap.target This patch breaks the cycle by removing the swap unit from swap.target using DefaultDependencies=no. The swap unit will still be activated via WantedBy=multi-user.target, just not during early boot. Although this problem is specific to Azure, this patch applies the fix to all clouds to keep the code simple. Fixes #26519. Fixes SCYLLADB-1257 [1] https://github.com/scylladb/scylla-machine-image/pull/426 [2] https://github.com/canonical/cloud-init/pull/1213#issuecomment-1026065501 Signed-off-by: Nikos Dragazis Closes scylladb/scylladb#28504 (cherry picked from commit 6d50e67bd2af7bbab1fd336b40106da5c15396bf) Closes scylladb/scylladb#29339 Closes scylladb/scylladb#29354 (cherry picked from commit 7ed772866e39ebd2944f5bc0776ebe1708fd1183) Closes scylladb/scylladb#29517 --- dist/common/scripts/scylla_swap_setup | 28 ++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/dist/common/scripts/scylla_swap_setup b/dist/common/scripts/scylla_swap_setup index b45f830853..261e33c7b5 100755 --- a/dist/common/scripts/scylla_swap_setup +++ b/dist/common/scripts/scylla_swap_setup @@ -9,6 +9,7 @@ import os import sys +import shlex import argparse import psutil from pathlib import Path @@ -103,16 +104,41 @@ if __name__ == '__main__': run('dd if=/dev/zero of={} bs=1M count={}'.format(swapfile, swapsize_mb), shell=True, check=True) swapfile.chmod(0o600) run('mkswap -f {}'.format(swapfile), shell=True, check=True) + + mount_point = find_mount_point(swap_directory) + mount_unit = out(f'systemd-escape -p --suffix=mount {shlex.quote(str(mount_point))}') + + # Add DefaultDependencies=no to the swap unit to avoid getting the default + # Before=swap.target dependency. We apply this to all clouds, but the + # requirement came from Azure: + # + # On Azure, the swap directory is on the Azure ephemeral disk (mounted on /mnt). + # However, cloud-init makes this mount (i.e., the mnt.mount unit) depend on + # the network (After=network-online.target). By extension, this means that + # the swap unit depends on the network. If we didn't use DefaultDependencies=no, + # then the swap unit would be part of the swap.target which other services + # assume to be a local boot target, so we would end up with dependency cycles + # such as: + # + # swap.target -> mnt-swapfile.swap -> mnt.mount -> network-online.target -> network.target -> systemd-resolved.service -> tmp.mount -> swap.target + # + # By removing the automatic Before=swap.target, the swap unit is no longer + # part of swap.target, avoiding such cycles. The swap will still be + # activated via WantedBy=multi-user.target. unit_data = ''' [Unit] Description=swapfile +DefaultDependencies=no +After={} +Conflicts=umount.target +Before=umount.target [Swap] What={} [Install] WantedBy=multi-user.target -'''[1:-1].format(swapfile) +'''[1:-1].format(mount_unit, swapfile) with swapunit.open('w') as f: f.write(unit_data) systemd_unit.reload()