From d47384e5eaa55bb2789ee7e8e2dcc6d7a7415a02 Mon Sep 17 00:00:00 2001
From: Pratyush Anand <panand@redhat.com>
Date: Wed, 16 Mar 2016 09:09:10 +0530
Subject: [PATCH] watchdog: install module for active watchdog

Recently following patches have been added in upstream Linux kernel, which
(1) fixes parent of watchdog_device so that
/sys/class/watchdog/watchdogn/device is populated. (2) adds some sysfs
device attributes so that different watchdog status can be read.

http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=6551881c86c791237a3bebf11eb3bd70b60ea782
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=906d7a5cfeda508e7361f021605579a00cd82815
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=33b711269ade3f6bc9d9d15e4343e6fa922d999b

With the above support, now we can find out whether a watchdog is active or
not. We can also find out the driver/module responsible for that watchdog
device.

Proposed patch uses above support and then adds module of active watchdog
in initramfs generated by dracut for hostonly mode. Kernel module for
inactive watchdog will be added as well for none hostonly mode.

When an user does not want to add kernel module, then one should exclude
complete dracut watchdog module with --omit.

Testing:
-- When watchdog is active watchdog modules were added
	# cat /sys/class/watchdog/watchdog0/identity
	iTCO_wdt
	# cat /sys/class/watchdog/watchdog0/state
	active
	# dracut --hostonly initramfs-test.img -a watchdog
	# lsinitrd initramfs-test.img | grep iTCO
	-rw-r--r--   1 root     root         9100 Feb 24 09:19 usr/lib/modules/.../kernel/drivers/watchdog/iTCO_vendor_support.ko
	-rw-r--r--   1 root     root        19252 Feb 24 09:19 usr/lib/modules/.../kernel/drivers/watchdog/iTCO_wdt.ko

-- When watchdog is inactive then watchdog modules were not added
	# cat /sys/class/watchdog/watchdog0/state
	inactive
	# dracut --hostonly initramfs-test.img -a watchdog
	# lsinitrd initramfs-test.img | grep iTCO

-- When watchdog is inactive, but no hostonly mode, watchdog modules were added
	# cat /sys/class/watchdog/watchdog0/state
	inactive
	# dracut --no-hostonly initramfs-test.img -a watchdog
	# lsinitrd initramfs-test.img | grep iTCO
	-rw-r--r--   1 root     root         9100 Feb 24 09:19 usr/lib/modules/.../kernel/drivers/watchdog/iTCO_vendor_support.ko
	-rw-r--r--   1 root     root        19252 Feb 24 09:19 usr/lib/modules/.../kernel/drivers/watchdog/iTCO_wdt.ko

Signed-off-by: Pratyush Anand <panand@redhat.com>
Cc: Dave Young <dyoung@redhat.com>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Harald Hoyer <harald@redhat.com>
---
 modules.d/04watchdog/module-setup.sh | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/modules.d/04watchdog/module-setup.sh b/modules.d/04watchdog/module-setup.sh
index 7ec757ae..0ffaa965 100755
--- a/modules.d/04watchdog/module-setup.sh
+++ b/modules.d/04watchdog/module-setup.sh
@@ -32,3 +32,31 @@ install() {
     inst_multiple -o wdctl
 }
 
+installkernel() {
+    [[ -d /sys/class/watchdog/ ]] || return
+    for dir in /sys/class/watchdog/*; do
+	    [[ -d "$dir" ]] || continue
+	    [[ -f "$dir/state" ]] || continue
+	    active=$(< "$dir/state")
+	    ! [[ $hostonly ]] || [[ "$active" =  "active" ]] || continue
+	    # device/modalias will return driver of this device
+	    wdtdrv=$(< "$dir/device/modalias")
+	    # There can be more than one module represented 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)
+	    instmods $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=$(readlink -f "$dir/device/..")
+	    while [ -f "$wdtppath/modalias" ]
+	    do
+		    wdtpdrv=$(< "$wdtppath/modalias")
+		    wdtpdrv=$(modprobe -R $wdtpdrv)
+		    instmods $wdtpdrv
+		    wdtppath=$(readlink -f "$wdtppath/..")
+	    done
+    done
+}
