小言_互联网的博客

总结Linux内核中watchdog

466人阅读  评论(0)

在Linux内核中有三个watchdog(看门狗),它们都需要被悉心的喂养照料,分别是:

1. /dev/watchdog

2.softlockup检测机制

3.hardlockup检测机制

首先看 1./dev/watchdog,此看门狗该怎样喂养呢,linux内核中有一段样例代码:

samples/watchdog/watchdog-simple.c

   
  1. 1 // SPDX-License-Identifier: GPL-2.0
  2. 2#include <stdio.h>
  3. 3#include <stdlib.h>
  4. 4#include <unistd.h>
  5. 5#include <fcntl.h>
  6. 6
  7. 7int main(void)
  8. 8{
  9. 9         int fd = open( "/dev/watchdog", O_WRONLY);
  10. 10         int ret =  0;
  11. 11         if (fd ==  -1) {
  12. 12                perror( "watchdog");
  13. 13                exit(EXIT_FAILURE);
  14. 14        }   
  15. 15        while ( 1) {
  16. 16                ret = write(fd,  "\0"1); 
  17. 17                 if (ret !=  1) {
  18. 18                        ret =  -1
  19. 19                         break;
  20. 20                }   
  21. 21                sleep( 10);
  22. 22        }   
  23. 23         close(fd);
  24. 24         return ret;
  25. 25}

此例子中,每隔10秒钟就会向“/dev/watchdog" 文件写入0, 这就是喂狗过程,看到这个样例,好像不太能感受到这个看门狗大的用处,但是放在实际工程中,用处太大了,举个例子:

某国中央银行在一台有 内存4T, 320个cpu核 的Linux服务器上跑一个数据库程序,数据库上存有他本国所有人民的银行账号信息,当此数据库程序在运行过程中,发生了IO读写错误,或者程序bug, 一下卡住了,那么他本国人民就都不能存钱取钱转账了,整个国民经济瞬间瘫痪。

此时想想看,Linux系统有没有什么机制来解决这种问题了,这时候“/dev/watchdog" 来了,

这个时候只需要在数据库程序中加上类似上面的样例程序,每隔10s中就去喂狗一次,

只要数据库程序卡住,卡住之后就不能喂狗了,等到比如默认60s以后,这只狗就罢工了,立马会默认触发服务器重启。

服务器重启会重新加载数据库程序, 或者服务器在重启过程中,由于服务器与它所在的服务器集群失联,从而触发集群中的分脑检测,把数据库程序挪到集群中其它设备上跑, 此时就减少了很多损失. 所以这只狗/dev/watchdog 用处太大了。

再来看下它的实现原理:


   
  1. #ps -ef | grep watchdog
  2. root        104      2   0   2020 ?         00: 00: 00 [watchdogd]
  3. #ls -l /dev/watchdog*
  4. crw-------  1 root root   10130 Dec  30  20: 04 /dev/watchdog
  5. crw-------  1 root root  247,    0 Dec  30  20: 04 /dev/watchdog0

看到系统中有个内核线程watchdogd, 和两个字符文件:/dev/watchdog和/dev/watchdog0

其中watchdogd实时调度类线程负责具体执行喂狗,/dev/watchdog是内核提供给用户层的通用操作接口文件,用来开启这只狗,喂狗,查询状态等。/dev/watchdog0 是具体的狗子实现,可以基于具体的物理设备实现,或者是softdog内核模块以软件的方式(具体使用方法:modprobe softdog)模拟硬件实现。

来看下softdog内核模块怎样模拟硬件实现这个功能:


   
  1. 1static  int __init softdog_init(void)
  2. 2        hrtimer_init(&softdog_ticktock, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
  3. 3        softdog_ticktock.function = softdog_fire;
  4. 4
  5. 5static enum hrtimer_restart softdog_fire( struct hrtimer *timer)
  6. 6        emergency_restart();
  7. 7
  8. 8static  int softdog_ping( struct watchdog_device *w)
  9. 9        hrtimer_start(&softdog_ticktock, ktime_set(w->timeout,  0), ( 60s)
  10. 10                      HRTIMER_MODE_REL);

从代码实现来看,很好理解,在开启看门狗(open "/dev/watchdog")之后,默认60s以后就会触发系统重启,在60s倒计时过程中,只有喂狗(softdog_ping)一次,它就又会恢复到60s以后才会触发系统重启,所以只要一直喂狗,emergency_restart()就不会执行,系统就不会重启。

再来看下 2.softlockup检测机制  和 3.hardlockup检测机制。

softlockup检测机制的喂狗方式是,每cpu上的hrtimer会唤醒一个migration/N内核线程,migration/N每次被唤醒之后都会对某个时间戳进行重置。

hardlockup检测机制的喂狗方式是,hrtimer每次执行时都会对一个变量进行加一。

关于softlockup和hardlockup检测机制的具体原理实现和应用场景,我最近发布了一个视频“Linux常见锁和lockup检查机制" 包含了从实现原理(linux内核代码层)和原理验证(使用ftrace调试手段)、样例代码、动手模拟实验,可以全方位理解softlockup/hardlockup.  

视频发布在“传播有深度的IT技术内容”的阅码场平台,点击"阅读原文"即可报名查看。

---end---


转载:https://blog.csdn.net/xiehuan1997/article/details/112211331
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场