ab0e4d
From 4e1d7a423253d4e3476b003fc2e17c2ac44bd8ca Mon Sep 17 00:00:00 2001
ab0e4d
From: Kairui Song <kasong@redhat.com>
ab0e4d
Date: Thu, 10 Sep 2020 02:18:02 +0800
ab0e4d
Subject: [PATCH] 04watchdog: split the watchdog module install
ab0e4d
ab0e4d
In some cases, user only want to include the watchdog module, not the
ab0e4d
wdctl or any other userspace helper. For example, systemd have a
ab0e4d
RebootWatchdogSec option that use watchdog to prevent reboot hangs. And
ab0e4d
it can help prevent machines hangs when reboot directly within the
ab0e4d
initramfs stage. So split the module installation to a standlone module.
ab0e4d
ab0e4d
Also when watchdog-module get included, install driver for all loaded
ab0e4d
watchdog instaed of only install driver for active watchdog. Both
ab0e4d
watchdog and watchdog-module return 255 in check(), so it's enabled only
ab0e4d
when manually included, the watchdog may get configured/activated later.
ab0e4d
ab0e4d
Signed-off-by: Kairui Song <kasong@redhat.com>
ab0e4d
(cherry picked from commit 39d90012a652fa4d9d2534d0168ddad8cacec248)
ab0e4d
ab0e4d
Resolves: #1890039
ab0e4d
---
ab0e4d
 modules.d/04watchdog-modules/module-setup.sh | 61 ++++++++++++++++++++++++++++
ab0e4d
 modules.d/04watchdog/module-setup.sh         | 50 +----------------------
ab0e4d
 2 files changed, 63 insertions(+), 48 deletions(-)
ab0e4d
ab0e4d
diff --git a/modules.d/04watchdog-modules/module-setup.sh b/modules.d/04watchdog-modules/module-setup.sh
ab0e4d
new file mode 100755
ab0e4d
index 00000000..5fbd769b
ab0e4d
--- /dev/null
ab0e4d
+++ b/modules.d/04watchdog-modules/module-setup.sh
ab0e4d
@@ -0,0 +1,61 @@
ab0e4d
+#!/bin/bash
ab0e4d
+
ab0e4d
+# called by dracut
ab0e4d
+check() {
ab0e4d
+    return 255
ab0e4d
+}
ab0e4d
+
ab0e4d
+# called by dracut
ab0e4d
+depends() {
ab0e4d
+    return 0
ab0e4d
+}
ab0e4d
+
ab0e4d
+# called by dracut
ab0e4d
+install() {
ab0e4d
+    return 0
ab0e4d
+}
ab0e4d
+
ab0e4d
+installkernel() {
ab0e4d
+    local -A _drivers
ab0e4d
+    local _alldrivers _wdtdrv _wdtppath _dir
ab0e4d
+    [[ -d /sys/class/watchdog/ ]] || return
ab0e4d
+    for _dir in /sys/class/watchdog/*; do
ab0e4d
+        [[ -d "$_dir" ]] || continue
ab0e4d
+        [[ -f "$_dir/state" ]] || continue
ab0e4d
+        # device/modalias will return driver of this device
ab0e4d
+        _wdtdrv=$(< "$_dir/device/modalias")
ab0e4d
+        # There can be more than one module represented by same
ab0e4d
+        # modalias. Currently load all of them.
ab0e4d
+        # TODO: Need to find a way to avoid any unwanted module
ab0e4d
+        # represented by modalias
ab0e4d
+        _wdtdrv=$(modprobe --set-version "$kernel" -R $_wdtdrv 2>/dev/null)
ab0e4d
+        if [[ $_wdtdrv ]]; then
ab0e4d
+            instmods $_wdtdrv
ab0e4d
+            for i in $_wdtdrv; do
ab0e4d
+                _drivers[$i]=1
ab0e4d
+            done
ab0e4d
+        fi
ab0e4d
+        # however in some cases, we also need to check that if there is
ab0e4d
+        # a specific driver for the parent bus/device.  In such cases
ab0e4d
+        # we also need to enable driver for parent bus/device.
ab0e4d
+        _wdtppath=$(readlink -f "$_dir/device")
ab0e4d
+        while [[ -d "$_wdtppath" ]] && [[ "$_wdtppath" != "/sys" ]]; do
ab0e4d
+            _wdtppath=$(readlink -f "$_wdtppath/..")
ab0e4d
+            [[ -f "$_wdtppath/modalias" ]] || continue
ab0e4d
+
ab0e4d
+            _wdtdrv=$(< "$_wdtppath/modalias")
ab0e4d
+            _wdtdrv=$(modprobe --set-version "$kernel" -R $_wdtdrv 2>/dev/null)
ab0e4d
+            if [[ $_wdtdrv ]]; then
ab0e4d
+                instmods $_wdtdrv
ab0e4d
+                for i in $_wdtdrv; do
ab0e4d
+                    _drivers[$i]=1
ab0e4d
+                done
ab0e4d
+            fi
ab0e4d
+        done
ab0e4d
+    done
ab0e4d
+    # ensure that watchdog module is loaded as early as possible
ab0e4d
+    _alldrivers="${!_drivers[*]}"
ab0e4d
+    [[ $_alldrivers ]] && echo "rd.driver.pre=${_alldrivers// /,}" > ${initdir}/etc/cmdline.d/00-watchdog.conf
ab0e4d
+
ab0e4d
+    return 0
ab0e4d
+}
ab0e4d
diff --git a/modules.d/04watchdog/module-setup.sh b/modules.d/04watchdog/module-setup.sh
ab0e4d
index 7566d651..15bcd897 100755
ab0e4d
--- a/modules.d/04watchdog/module-setup.sh
ab0e4d
+++ b/modules.d/04watchdog/module-setup.sh
ab0e4d
@@ -7,7 +7,7 @@ check() {
ab0e4d
 
ab0e4d
 # called by dracut
ab0e4d
 depends() {
ab0e4d
-    return 0
ab0e4d
+    return "watchdog-modules"
ab0e4d
 }
ab0e4d
 
ab0e4d
 # called by dracut
ab0e4d
@@ -27,53 +27,7 @@ install() {
ab0e4d
         inst_hook cleanup   00 "$moddir/watchdog.sh"
ab0e4d
         inst_hook cleanup   99 "$moddir/watchdog.sh"
ab0e4d
     fi
ab0e4d
+
ab0e4d
     inst_hook emergency 02 "$moddir/watchdog-stop.sh"
ab0e4d
     inst_multiple -o wdctl
ab0e4d
 }
ab0e4d
-
ab0e4d
-installkernel() {
ab0e4d
-    local -A _drivers
ab0e4d
-    local _alldrivers _active _wdtdrv _wdtppath _dir
ab0e4d
-    [[ -d /sys/class/watchdog/ ]] || return
ab0e4d
-    for _dir in /sys/class/watchdog/*; do
ab0e4d
-        [[ -d "$_dir" ]] || continue
ab0e4d
-        [[ -f "$_dir/state" ]] || continue
ab0e4d
-        _active=$(< "$_dir/state")
ab0e4d
-        ! [[ $hostonly ]] || [[ "$_active" =  "active" ]] || continue
ab0e4d
-        # device/modalias will return driver of this device
ab0e4d
-        _wdtdrv=$(< "$_dir/device/modalias")
ab0e4d
-        # There can be more than one module represented by same
ab0e4d
-        # modalias. Currently load all of them.
ab0e4d
-        # TODO: Need to find a way to avoid any unwanted module
ab0e4d
-        # represented by modalias
ab0e4d
-        _wdtdrv=$(modprobe --set-version "$kernel" -R $_wdtdrv 2>/dev/null)
ab0e4d
-        if [[ $_wdtdrv ]]; then
ab0e4d
-            instmods $_wdtdrv
ab0e4d
-            for i in $_wdtdrv; do
ab0e4d
-                _drivers[$i]=1
ab0e4d
-            done
ab0e4d
-        fi
ab0e4d
-        # however in some cases, we also need to check that if there is
ab0e4d
-        # a specific driver for the parent bus/device.  In such cases
ab0e4d
-        # we also need to enable driver for parent bus/device.
ab0e4d
-        _wdtppath=$(readlink -f "$_dir/device")
ab0e4d
-        while [[ -d "$_wdtppath" ]] && [[ "$_wdtppath" != "/sys" ]]; do
ab0e4d
-            _wdtppath=$(readlink -f "$_wdtppath/..")
ab0e4d
-            [[ -f "$_wdtppath/modalias" ]] || continue
ab0e4d
-
ab0e4d
-            _wdtdrv=$(< "$_wdtppath/modalias")
ab0e4d
-            _wdtdrv=$(modprobe --set-version "$kernel" -R $_wdtdrv 2>/dev/null)
ab0e4d
-            if [[ $_wdtdrv ]]; then
ab0e4d
-                instmods $_wdtdrv
ab0e4d
-                for i in $_wdtdrv; do
ab0e4d
-                    _drivers[$i]=1
ab0e4d
-                done
ab0e4d
-            fi
ab0e4d
-        done
ab0e4d
-    done
ab0e4d
-    # ensure that watchdog module is loaded as early as possible
ab0e4d
-    _alldrivers="${!_drivers[*]}"
ab0e4d
-    [[ $_alldrivers ]] && echo "rd.driver.pre=${_alldrivers// /,}" > ${initdir}/etc/cmdline.d/00-watchdog.conf
ab0e4d
-
ab0e4d
-    return 0
ab0e4d
-}
ab0e4d