[Devel] [PATCH RH7 2/9] Port: diff-fence-watchdog-add-support-of-crash
Pavel Tikhomirov
ptikhomirov at virtuozzo.com
Tue Oct 13 07:52:52 PDT 2015
Author: Dmitry Guryanov
Email: dguryanov at parallels.com
Subject: watchdog: add support of crash
Date: Thu, 10 Jan 2013 15:25:07 +0400
* [fence-watchdog] The ability to choose, which action to perform
in case of timeout: crash, reboot or poweroff.
The configuration is done via sysfs files:
/sys/kernel/watchdog_available_actions
/sys/kernel/watchdog_action. (PSBM-13631)
Add ability to choose, which action to perform in case
of timeout and add support of crash: crash, reboot or poweroff.
Two sysfs files added:
/sys/kernel/watchdog_available_actions and /sys/kernel/watchdog_action.
https://jira.sw.ru/browse/PSBM-13631
Signed-off-by: Dmitry Guryanov <dguryanov at parallels.com>
Acked-by: Pavel Emelyanov <xemul at parallels.com>
Changes in v4:
* add poweroff action
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
kernel/fence-watchdog.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 82 insertions(+), 3 deletions(-)
diff --git a/kernel/fence-watchdog.c b/kernel/fence-watchdog.c
index e25140f..ca07da5 100644
--- a/kernel/fence-watchdog.c
+++ b/kernel/fence-watchdog.c
@@ -14,17 +14,49 @@
#include <linux/jiffies.h>
#include <linux/reboot.h>
#include <linux/fence-watchdog.h>
+#include <linux/device.h>
+#include <linux/kmsg_dump.h>
#define MAX_U64 (~(u64)0)
#define MAX_JIFFIES_DELTA (10 * 365UL * 24UL * 3600UL * HZ)
+#define ACTION_NAME_LEN 16
+
+enum {
+ FENCE_WDOG_CRASH = 0,
+ FENCE_WDOG_REBOOT = 1,
+ FENCE_WDOG_POWEROFF = 2,
+};
+
+const char *action_names[] = {"crash", "reboot", "poweroff", NULL};
+
DEFINE_VVAR(volatile unsigned long, fence_wdog_jiffies64) = MAX_U64;
+static int fence_wdog_action = FENCE_WDOG_CRASH;
void fence_wdog_do_fence(void)
{
- lockdep_off();
- local_irq_enable();
- emergency_restart();
+ char *killer = NULL;
+
+ switch (fence_wdog_action) {
+ case FENCE_WDOG_CRASH:
+ panic_on_oops = 1;
+ wmb();
+ *killer = 1;
+ break;
+ case FENCE_WDOG_REBOOT:
+ lockdep_off();
+ local_irq_enable();
+ emergency_restart();
+ break;
+ case FENCE_WDOG_POWEROFF:
+ lockdep_off();
+ local_irq_enable();
+ sysdev_shutdown();
+ printk(KERN_EMERG "System halted.\n");
+ kmsg_dump(KMSG_DUMP_HALT);
+ machine_halt();
+ break;
+ }
}
inline void fence_wdog_check_timer(void)
@@ -77,12 +109,59 @@ static ssize_t fence_wdog_timer_store(struct kobject *kobj,
return count;
}
+static ssize_t fence_wdog_action_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%s\n", action_names[fence_wdog_action]);
+}
+
+static ssize_t fence_wdog_action_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ char str_action[ACTION_NAME_LEN];
+ int i = 0;
+
+ if (sscanf(buf, "%15s", str_action) != 1)
+ return -EINVAL;
+
+ for (i = 0; action_names[i]; i++) {
+ if ((!strnicmp(str_action, action_names[i], ACTION_NAME_LEN))) {
+ fence_wdog_action = i;
+ return count;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static ssize_t fence_wdog_available_actions_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ int i, ret = 0;
+
+ for (i = 0; action_names[i] != NULL; i++)
+ ret += sprintf(&buf[ret], "%s ", action_names[i]);
+
+ ret += sprintf(&buf[ret], "\n");
+ return ret;
+}
+
static struct kobj_attribute fence_wdog_timer_attr =
__ATTR(watchdog_timer, 0644,
fence_wdog_timer_show, fence_wdog_timer_store);
+static struct kobj_attribute fence_wdog_action_attr =
+ __ATTR(watchdog_action, 0644,
+ fence_wdog_action_show, fence_wdog_action_store);
+
+static struct kobj_attribute fence_wdog_available_actions_attr =
+ __ATTR(watchdog_available_actions, 0644,
+ fence_wdog_available_actions_show, NULL);
+
static struct attribute *fence_wdog_attrs[] = {
&fence_wdog_timer_attr.attr,
+ &fence_wdog_action_attr.attr,
+ &fence_wdog_available_actions_attr.attr,
NULL,
};
--
1.9.3
More information about the Devel
mailing list