Skip to content

Commit

Permalink
fix(iscsi): make sure services are shut down when switching root
Browse files Browse the repository at this point in the history
When systemd prepares switching root, it starts 'initrd-cleanup.service',
which runs 'systemctl --no-block isolate initrd-switch-root.target'.
This will stop all units on which initrd-switch-root.target does not
depend, including iscsid.service and iscsiuio.service. But systemd
doesn't guarantee a time ordering in this case. It can happen that
systemd switches root (i.e. restarts itself on the new root) before
iscsiuio is actually stopped, or at least before PID 1 receives
the notification that it has stopped. In this case, it considers
iscsiuio still running, and will not start it later in the boot
sequence when iscsid is coming up.

A typical log excerpt with systemd.log_level=debug looks like this:

[   36.470761] worker2 systemd[1]: initrd-cleanup.service: Trying to enqueue job initrd-cleanup.service/start/replace
[   36.765241] worker2 systemd[1]: initrd-switch-root.target: Trying to enqueue job initrd-switch-root.target/start/isolate
[   36.765337] worker2 systemd[1]: iscsid.service: Installed new job iscsid.service/stop as 139
[   36.765535] worker2 systemd[1]: iscsiuio.service: Installed new job iscsiuio.service/stop as 138
[   36.824789] worker2 systemd[1]: iscsid.socket: stopping held back, waiting for: iscsid.service
[   36.824813] worker2 systemd[1]: iscsiuio.socket: stopping held back, waiting for: iscsiuio.service
[   36.888759] worker2 systemd[1]: iscsid.service: Thawing unit.
[   36.888882] worker2 systemd[1]: iscsid.service: Changed running -> stop-sigterm
[   36.889355] worker2 systemd[1]: Stopping Open-iSCSI...
[   36.889413] worker2 systemd[1]: iscsiuio.service: stopping held back, waiting for: iscsid.service
[   37.512072] worker2 systemd[1]: Reached target Switch Root.
[   37.549512] worker2 @ystemctl[1614]: Switching root - root: /sysroot; init: n/a
[   37.577264] worker2 systemd[1]: Switching root.

When iscsid is started later on in the real root, it resets all existing iSCSI
connections, causing the root FS to come offline. In iSCSI offload scenarios
if iscsiuio is already running, it will re-establish the session after a few
seconds. But if iscsiuio has not been started at this point in time, it can't
be loaded any more from the root FS, and booting fails.

To avoid this problem, add "Conflicts" and a "Before" dependencies against
initrd-cleanup.service to the iSCSI service units.

See also systemd/systemd#3436

Signed-off-by: Martin Wilck <mwilck@suse.com>
  • Loading branch information
mwilck committed Feb 26, 2025
1 parent 2da7fec commit 0666da2
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions modules.d/95iscsi/module-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,8 @@ install() {
{
echo "[Unit]"
echo "DefaultDependencies=no"
echo "Conflicts=shutdown.target"
echo "Before=shutdown.target"
echo "Conflicts=shutdown.target initrd-cleanup.service"
echo "Before=shutdown.target initrd-cleanup.service"
} > "${initdir}/$systemdsystemunitdir/iscsid.service.d/dracut.conf"

mkdir -p "${initdir}/$systemdsystemunitdir/iscsid.socket.d"
Expand All @@ -258,8 +258,8 @@ install() {
{
echo "[Unit]"
echo "DefaultDependencies=no"
echo "Conflicts=shutdown.target"
echo "Before=shutdown.target"
echo "Conflicts=shutdown.target initrd-cleanup.service"
echo "Before=shutdown.target initrd-cleanup.service"
} > "${initdir}/$systemdsystemunitdir/iscsiuio.service.d/dracut.conf"

mkdir -p "${initdir}/$systemdsystemunitdir/iscsiuio.socket.d"
Expand Down

0 comments on commit 0666da2

Please sign in to comment.