We met a problem that the kdump emergency service failed to
start when the target dump timeout(we passed "rd.timeout=30"
to kdump), it reported "Transaction is destructive" messages:
[ TIME ] Timed out waiting for device dev-mapper-fedora\x2droot.device.
[DEPEND] Dependency failed for Initrd Root Device.
[ SKIP ] Ordering cycle found, skipping System Initialization
[DEPEND] Dependency failed for /sysroot.
[DEPEND] Dependency failed for Initrd Root File System.
[DEPEND] Dependency failed for Reload Configuration from the Real Root.
[ SKIP ] Ordering cycle found, skipping System Initialization
[ SKIP ] Ordering cycle found, skipping Initrd Default Target
[DEPEND] Dependency failed for File System Check on /dev/mapper/fedora-root.
[ OK ] Reached target Initrd File Systems.
[ OK ] Stopped dracut pre-udev hook.
[ OK ] Stopped dracut cmdline hook.
Starting Setup Virtual Console...
Starting Kdump Emergency...
[ OK ] Reached target Initrd Default Target.
[ OK ] Stopped dracut initqueue hook.
Failed to start kdump-error-handler.service: Transaction is destructive.
See system logs and 'systemctl status kdump-error-handler.service' for details.
[FAILED] Failed to start Kdump Emergency.
See 'systemctl status emergency.service' for details.
[DEPEND] Dependency failed for Emergency Mode.
This is because in case of root failure, initrd-root-fs.target
will trigger systemd emergency target which requires the systemd
emergency service actually is kdump-emergency.service, then our
kdump-emergency.service starts kdump-error-handler.service with
"systemctl isolate"(see 99kdumpbase/kdump-emergency.service, we
replace systemd's with this one under kdump).
This will lead to systemd two contradictable jobs queued as an
atomic transaction:
job 1) the emergency service gets started by initrd-root-fs.target
job 2) the emergency service gets stopped due to "systemctl isolate"
thereby throwing "Transaction is destructive".
In order to solve it, we can utilize "IgnoreOnIsolate=yes" for
both kdump-emergency.service and kdump-emergency.target to avoid
being isolated, then they can keep going on as expected in case
of failures.
We add kdump-emergency.target dedicated to kdump the similar way
as did for kdump-emergency.service(i.e. will replace systemd's
emergency.target with kdump-emergency.target under kdump), and
adds "IgnoreOnIsolate=yes" into both of them.
Signed-off-by: Xunlei Pang <xlpang(a)redhat.com>
---
dracut-kdump-emergency.service | 1 +
dracut-kdump-emergency.target | 14 ++++++++++++++
dracut-module-setup.sh | 3 ++-
kexec-tools.spec | 2 ++
4 files changed, 19 insertions(+), 1 deletion(-)
create mode 100644 dracut-kdump-emergency.target
diff --git a/dracut-kdump-emergency.service b/dracut-kdump-emergency.service
index fb764f2..e023284 100644
--- a/dracut-kdump-emergency.service
+++ b/dracut-kdump-emergency.service
@@ -12,6 +12,7 @@
[Unit]
Description=Kdump Emergency
DefaultDependencies=no
+IgnoreOnIsolate=yes
[Service]
ExecStart=/usr/bin/systemctl --no-block isolate kdump-error-handler.service
diff --git a/dracut-kdump-emergency.target b/dracut-kdump-emergency.target
new file mode 100644
index 0000000..a1bb493
--- /dev/null
+++ b/dracut-kdump-emergency.target
@@ -0,0 +1,14 @@
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=Emergency Mode
+Documentation=man:systemd.special(7)
+Requires=emergency.service
+After=emergency.service
+AllowIsolate=yes
+IgnoreOnIsolate=yes
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh
index 1f96bb8..fa4fa2a 100755
--- a/dracut-module-setup.sh
+++ b/dracut-module-setup.sh
@@ -734,8 +734,9 @@ install() {
ln_r "$systemdsystemunitdir/kdump-capture.service"
"$systemdsystemunitdir/initrd.target.wants/kdump-capture.service"
inst "$moddir/kdump-error-handler.sh"
"/usr/bin/kdump-error-handler.sh"
inst "$moddir/kdump-error-handler.service"
"$systemdsystemunitdir/kdump-error-handler.service"
- # Replace existing emergency service
+ # Replace existing emergency service and emergency target
cp "$moddir/kdump-emergency.service"
"$initdir/$systemdsystemunitdir/emergency.service"
+ cp "$moddir/kdump-emergency.target"
"$initdir/$systemdsystemunitdir/emergency.target"
# Also redirect dracut-emergency to kdump error handler
ln_r "$systemdsystemunitdir/emergency.service"
"$systemdsystemunitdir/dracut-emergency.service"
diff --git a/kexec-tools.spec b/kexec-tools.spec
index 2a176f3..c3359fb 100644
--- a/kexec-tools.spec
+++ b/kexec-tools.spec
@@ -41,6 +41,7 @@ Source103: dracut-kdump-error-handler.sh
Source104: dracut-kdump-emergency.service
Source105: dracut-kdump-error-handler.service
Source106: dracut-kdump-capture.service
+Source107: dracut-kdump-emergency.target
Requires(post): systemd-units
Requires(preun): systemd-units
@@ -197,6 +198,7 @@ cp %{SOURCE103}
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpb
cp %{SOURCE104}
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix
%{SOURCE104}}
cp %{SOURCE105}
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix
%{SOURCE105}}
cp %{SOURCE106}
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix
%{SOURCE106}}
+cp %{SOURCE107}
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix
%{SOURCE107}}
chmod 755
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix
%{SOURCE100}}
chmod 755
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix
%{SOURCE101}}
--
1.8.3.1