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