[Devel] [PATCH RH7 1/2] fence-watchdog: log wdog actions directly to special file
Pavel Tikhomirov
ptikhomirov at virtuozzo.com
Wed Jul 19 12:04:41 MSK 2017
Kirill, please review.
On 07/19/2017 12:03 PM, Pavel Tikhomirov wrote:
> If watchdog was triggered, that means that userspace is unreliable
> and we can't expect kernel messages are logged by userspace logger,
> thus we need ourselfs write info about watchdog triggered to special
> file configured through sysfs /sys/kernel/watchdog_log_path, so that
> users can see that watchdog was triggered but not some other event.
>
> https://jira.sw.ru/browse/PSBM-54747
> Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
> ---
> kernel/fence-watchdog.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 73 insertions(+)
>
> diff --git a/kernel/fence-watchdog.c b/kernel/fence-watchdog.c
> index f5c2347f..607045a 100644
> --- a/kernel/fence-watchdog.c
> +++ b/kernel/fence-watchdog.c
> @@ -23,6 +23,8 @@
> #include <linux/fence-watchdog.h>
> #include <linux/device.h>
> #include <linux/kmsg_dump.h>
> +#include <linux/fs.h>
> +#include <linux/string.h>
>
> #define MAX_U64 (~(u64)0)
> #define MAX_JIFFIES_DELTA (10 * 365UL * 24UL * 3600UL * HZ)
> @@ -41,11 +43,63 @@ const char *action_names[] = {"crash", "reboot", "halt", "netfilter", NULL};
> DEFINE_VVAR(volatile unsigned long, fence_wdog_jiffies64) = MAX_U64;
> static int fence_wdog_action = FENCE_WDOG_CRASH;
> static atomic_t not_fenced = ATOMIC_INIT(-1);
> +static char fence_wdog_log_path[PATH_MAX] = "/fence_wdog.log";
> +
> +#define MSG_LEN 32
> +
> +void fence_wdog_log(void)
> +{
> + char msg[MSG_LEN] = "fence-watchdog: ";
> + struct file *file;
> + int ret;
> +
> + ret = sprintf(msg+strlen(msg), "%s\n", action_names[fence_wdog_action]);
> + if (ret != strlen(action_names[fence_wdog_action]) + 1) {
> + printk(KERN_EMERG"fence-watchdog: Failed to sprintf msg\n");
> + return;
> + }
> +
> + file = filp_open(fence_wdog_log_path,
> + O_CREAT | O_WRONLY | O_APPEND | O_NOFOLLOW | O_LARGEFILE,
> + 0600);
> + if (IS_ERR(file)) {
> + printk(KERN_EMERG"fence-watchdog: Failed to open log path\n");
> + return;
> + }
> +
> + if (!S_ISREG(file_inode(file)->i_mode)) {
> + printk(KERN_EMERG"fence-watchdog: Wrong type of log file\n");
> + goto close;
> + }
> +
> + if (!file->f_op->write) {
> + printk(KERN_EMERG"fence-watchdog: No write op for log file\n");
> + goto close;
> + }
> +
> + ret = file->f_op->write(file, msg, strlen(msg), &file->f_pos);
> + if (ret != strlen(msg))
> + printk(KERN_EMERG"fence-watchdog: Failed to write msg, ret=%d\n", ret);
> +
> + ret = vfs_fsync(file, 0);
> + if (ret < 0)
> + printk(KERN_EMERG"fence-watchdog: Failed to fsync log file ret=%d\n", ret);
> +
> +close:
> + ret = filp_close(file, NULL);
> + if (ret < 0)
> + printk(KERN_EMERG"fence-watchdog: Failed to close log file ret=%d\n", ret);
> +
> + return;
> +}
>
> static void do_halt_or_reboot(struct work_struct *dummy)
> {
> printk(KERN_EMERG"fence-watchdog: %s\n",
> action_names[fence_wdog_action]);
> +
> + fence_wdog_log();
> +
> switch (fence_wdog_action) {
> case FENCE_WDOG_REBOOT:
> emergency_restart();
> @@ -166,6 +220,20 @@ static ssize_t fence_wdog_available_actions_show(struct kobject *kobj,
> return ret;
> }
>
> +static ssize_t fence_wdog_log_path_show(struct kobject *kobj,
> + struct kobj_attribute *attr, char *buf)
> +{
> + return sprintf(buf, "%s\n", fence_wdog_log_path);
> +}
> +
> +static ssize_t fence_wdog_log_path_store(struct kobject *kobj,
> + struct kobj_attribute *attr, const char *buf, size_t count)
> +{
> + if (sscanf(buf, "%s", fence_wdog_log_path) != 1)
> + return -EINVAL;
> + return 0;
> +}
> +
> static struct kobj_attribute fence_wdog_timer_attr =
> __ATTR(watchdog_timer, 0644,
> fence_wdog_timer_show, fence_wdog_timer_store);
> @@ -178,10 +246,15 @@ static struct kobj_attribute fence_wdog_available_actions_attr =
> __ATTR(watchdog_available_actions, 0644,
> fence_wdog_available_actions_show, NULL);
>
> +static struct kobj_attribute fence_wdog_log_path_attr =
> + __ATTR(watchdog_log_path, 0644,
> + fence_wdog_log_path_show, fence_wdog_log_path_store);
> +
> static struct attribute *fence_wdog_attrs[] = {
> &fence_wdog_timer_attr.attr,
> &fence_wdog_action_attr.attr,
> &fence_wdog_available_actions_attr.attr,
> + &fence_wdog_log_path_attr.attr,
> NULL,
> };
>
>
--
Best regards, Tikhomirov Pavel
Software Developer, Virtuozzo.
More information about the Devel
mailing list