f4d4e0
From 8877bffec31185b58ffa867d59ae0da213fae080 Mon Sep 17 00:00:00 2001
f4d4e0
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
f4d4e0
Date: Wed, 24 Jul 2019 23:54:48 -0400
f4d4e0
Subject: [PATCH] swap: finish the secondary swap units' jobs if deactivation
f4d4e0
 of the primary swap unit fails
f4d4e0
f4d4e0
Currently, if deactivation of the primary swap unit fails:
f4d4e0
f4d4e0
    # LANG=C systemctl --no-pager stop dev-mapper-fedora\\x2dswap.swap
f4d4e0
    Job for dev-mapper-fedora\x2dswap.swap failed.
f4d4e0
    See "systemctl status "dev-mapper-fedora\\x2dswap.swap"" and "journalctl -xe" for details.
f4d4e0
f4d4e0
then there are still the running stop jobs for all the secondary swap units
f4d4e0
that follow the primary one:
f4d4e0
f4d4e0
    # systemctl list-jobs
f4d4e0
     JOB UNIT                                                                                                         TYPE STATE
f4d4e0
     3233 dev-disk-by\x2duuid-2dc8b9b1\x2da0a5\x2d44d8\x2d89c4\x2d6cdd26cd5ce0.swap                                    stop running
f4d4e0
     3232 dev-dm\x2d1.swap                                                                                             stop running
f4d4e0
     3231 dev-disk-by\x2did-dm\x2duuid\x2dLVM\x2dyuXWpCCIurGzz2nkGCVnUFSi7GH6E3ZcQjkKLnF0Fil0RJmhoLN8fcOnDybWCMTj.swap stop running
f4d4e0
     3230 dev-disk-by\x2did-dm\x2dname\x2dfedora\x2dswap.swap                                                          stop running
f4d4e0
     3234 dev-fedora-swap.swap                                                                                         stop running
f4d4e0
f4d4e0
    5 jobs listed.
f4d4e0
f4d4e0
This remains endlessly because their JobTimeoutUSec is infinity:
f4d4e0
f4d4e0
    # LANG=C systemctl show -p JobTimeoutUSec dev-fedora-swap.swap
f4d4e0
    JobTimeoutUSec=infinity
f4d4e0
f4d4e0
If this issue happens during system shutdown, the system shutdown appears to
f4d4e0
get hang and the system will be forcibly shutdown or rebooted 30 minutes later
f4d4e0
by the following configuration:
f4d4e0
f4d4e0
    # grep -E "^JobTimeout" /usr/lib/systemd/system/reboot.target
f4d4e0
    JobTimeoutSec=30min
f4d4e0
    JobTimeoutAction=reboot-force
f4d4e0
f4d4e0
The scenario in the real world seems that there is some service unit with
f4d4e0
KillMode=none, processes whose memory is being swapped out are not killed
f4d4e0
during stop operation in the service unit and then swapoff command fails.
f4d4e0
f4d4e0
On the other hand, it works well in successful case of swapoff command because
f4d4e0
the secondary jobs monitor /proc/swaps file and can detect deletion of the
f4d4e0
corresponding swap file.
f4d4e0
f4d4e0
This commit fixes the issue by finishing the secondary swap units' jobs if
f4d4e0
deactivation of the primary swap unit fails.
f4d4e0
f4d4e0
Fixes: #11577
f4d4e0
(cherry picked from commit 9c1f969d40f84d5cc98d810bab8b24148b2d8928)
f4d4e0
(cherry picked from commit 1e5b6b9930db88c3a5fb464bad13853885ea82f1)
f4d4e0
f4d4e0
Resolves: #1821261
f4d4e0
---
f4d4e0
 src/core/swap.c | 10 ++++++++--
f4d4e0
 1 file changed, 8 insertions(+), 2 deletions(-)
f4d4e0
f4d4e0
diff --git a/src/core/swap.c b/src/core/swap.c
f4d4e0
index c9cce3d945..ff27936142 100644
f4d4e0
--- a/src/core/swap.c
f4d4e0
+++ b/src/core/swap.c
f4d4e0
@@ -679,9 +679,15 @@ static void swap_enter_active(Swap *s, SwapResult f) {
f4d4e0
 static void swap_enter_dead_or_active(Swap *s, SwapResult f) {
f4d4e0
         assert(s);
f4d4e0
 
f4d4e0
-        if (s->from_proc_swaps)
f4d4e0
+        if (s->from_proc_swaps) {
f4d4e0
+                Swap *other;
f4d4e0
+
f4d4e0
                 swap_enter_active(s, f);
f4d4e0
-        else
f4d4e0
+
f4d4e0
+                LIST_FOREACH_OTHERS(same_devnode, other, s)
f4d4e0
+                        if (UNIT(other)->job)
f4d4e0
+                                swap_enter_dead_or_active(other, f);
f4d4e0
+        } else
f4d4e0
                 swap_enter_dead(s, f);
f4d4e0
 }
f4d4e0