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://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id...
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id...
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id...
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 kernel-4.5.0-0.rc1.git2.1.fc24 and fc23 user space.
- Added RuntimeWatchdogSec=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
kdump:/# cat /sys/class/watchdog/watchdog0/state
active
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.systemd
starts watchdog daemon before kdump. If an user changes the watchdog status
afterwards then he/she will have to execute `kdumpctrl restart`.
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.
Signed-off-by: Pratyush Anand <panand(a)redhat.com>
---
dracut-module-setup.sh | 19 +++++++++++++------
kdump-lib.sh | 39 +++++++++++++++++++++++++++++++++++++++
2 files changed, 52 insertions(+), 6 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh
index 4cd7107c4a35..32032304476e 100755
--- a/dracut-module-setup.sh
+++ b/dracut-module-setup.sh
@@ -706,10 +706,17 @@ 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
+ wdtcmdline=$(get_wdt_cmdline)
+
+ if [ "$?" = "0" ]; then
+ echo $wdtcmdline >> ${initdir}/etc/cmdline.d/00-wdt.conf
+ IFS='=,' read -ra modarr <<< "$wdtcmdline"
+ count='1'
+ while [ "$count" -lt ${#modarr[@]} ]
+ do
+ instmods ${modarr[$count]}
+ count=`expr $count + 1`
+ done
+ fi
+ return 0
}
diff --git a/kdump-lib.sh b/kdump-lib.sh
index 4d3420652b2f..f60909bca047 100755
--- a/kdump-lib.sh
+++ b/kdump-lib.sh
@@ -230,3 +230,42 @@ is_hostname()
fi
echo $1 | grep -q "[a-zA-Z]"
}
+
+get_wdt_cmdline()
+{
+ local wdtcmdline=""
+ wdtcls=/sys/class/watchdog
+ cd $wdtcls
+ for dir in */; do
+ cd $dir
+ active=`[ -f state ] && cat state`
+ if [ "$active" = "active" ]; then
+ # device/modalias will return driver of this device
+ wdtdrv=`cat device/modalias`
+ # There can be more than one module represnted by same
+ # modalias. Currently load all of them.
+ # TODO: Need to find a way to avoid any unwanted module
+ # represented by modalias
+ wdtdrv=`modprobe -R $wdtdrv | tr "\n" "," | sed 's/.$//'`
+ 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 | tr "\n" "," | sed
's/.$//'`
+ wdtcmdline="$wdtcmdline,$wdtpdrv"
+ wdtppath="$wdtppath/.."
+ done
+ echo "$wdtcmdline"
+ return 0
+ fi
+ cd ..
+ done
+
+ echo "$wdtcmdline"
+ return 1
+}
--
2.5.0