[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