Currently we take care to load only iTCO_wdt if this module was loaded in
primary kernel. This new approach is capitalizing on recent changes
proposed in the kernel which are following:
http://www.spinics.net/lists/linux-watchdog/msg07282.html
http://www.spinics.net/lists/linux-watchdog/msg07359.html
Above kernel patches fixes/adds two major aspects:
1) It fixes parent of watchdog_device so that
/sys/class/watchdog/watchdogn/device is populated.
2) Adds some sysfs device attributes so that we can read different watchdog
status.
With the above support, now we can find out whether a watchdog is active or
not. If it is active, we can also find out the driver/module responsible
for that watchdog device.
Proposed patch uses above kernel support and then loads relevant wdt
modules in kdump initramfs only for the active device.
Testing:
It has been tested with FC22.
- Added ShutdownWatchdogSec=40s in /etc/systemd/system.conf
- Modified cmdline for crashkernel=256M
- systemctl enable kdump
- [temporarily changed /etc/kdump.conf to stop at dracut shell]
- restart
- echo c > /proc/sysrq-trigger
On dracut shell I can see
kdump:/# cat /sys/class/watchdog/watchdog0/identity
iTCO_wdt
Tested also with correct /etc/kdump.conf and it was able to save the
vmcore.
Assumption: Both watchdog and kdump daemon are managed by systemd.
Limitations: This patch will be able to recognize an active wdt, only if
its driver has been written in watchdog-core framework and registered with
watchdog_class.
If watchdog daemon is started after kdump daemon or kdump daemon has
already prepared initramfs before watchdog is active, then this solution
will not work.
We will be working on these limitations in coming days.
Signed-off-by: Pratyush Anand <panand(a)redhat.com>
---
Hi All,
I am sending this patch as RFC, because all kernel patches are yet to ACKed
and merged into mainline. I am seeking your feedback in advance by sending
RFC, as the implementation has some assumption and limitations. Also, I am
not so good at shell scripting ;). So your feedback will help me to shape
it further by the time kernel patches goes to mainline.
~Pratyush
dracut-module-setup.sh | 36 ++++++++++++++++++++++++++++++------
1 file changed, 30 insertions(+), 6 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh
index 9b398ebced1a..6b7e097ba4ea 100755
--- a/dracut-module-setup.sh
+++ b/dracut-module-setup.sh
@@ -706,10 +706,34 @@ install() {
}
installkernel() {
- wdt=$(lsmod|cut -f1 -d' '|grep "wdt$")
- if [ -n "$wdt" ]; then
- [ "$wdt" = "iTCO_wdt" ] && instmods lpc_ich
&&
- echo "rd.driver.pre=lpc_ich,iTCO_wdt " >>
${initdir}/etc/cmdline.d/00-wdt.conf
- instmods $wdt
- fi
+ wdtcls=/sys/class/watchdog
+ cd $wdtcls
+ for dir in */; do
+ cd $dir
+ active=`cat state`
+ if [ $active = "active" ]
+ then
+ # device/modalias will return driver of this device
+ wdtdrv=`cat device/modalias`
+ wdtdrv=`modprobe -R $wdtdrv`
+ instmods $wdtdrv
+ wdtcmdline="rd.driver.pre=$wdtdrv"
+ # however in some cases, we also need to check that if
+ # there is a specific driver for the parent bus/device.
+ # In such cases we also need to enable driver for parent
+ # bus/device.
+ wdtppath="device/..";
+ while [ -f "$wdtppath/modalias" ]
+ do
+ wdtpdrv=`cat $wdtppath/modalias`
+ wdtpdrv=`modprobe -R $wdtpdrv`
+ instmods $wdtpdrv
+ wdtcmdline="$wdtcmdline,$wdtpdrv"
+ wdtppath="$wdtppath/.."
+ done
+ echo $wdtcmdline >> ${initdir}/etc/cmdline.d/00-wdt.conf
+ break
+ fi
+ cd ..
+ done
}
--
2.4.3