1. 程式人生 > >一個軟體實現的Linux看門狗—soft_wdt

一個軟體實現的Linux看門狗—soft_wdt

    soft_wdt(以下簡稱本軟體)是一個軟體實現的Linux看門狗。

    本軟體是一款開源、免費軟體。

    下載地址:

    本軟體和/drivers/watchdog/softdog.c實現的軟體看門狗幾乎一樣。
    主要的不同點是,前者支援一個看門狗,本軟體則支援大量的看門狗。


    soft_wdt程式碼編譯後,生成一個核心模組soft_wdt.ko。


    模組載入後,將建立一個裝置檔案/dev/soft_wdt


    使用者態程式,通過系統呼叫open每開啟一次/dev/soft_wdt,就得到一個新的看門狗,
    此看門狗的使用方法就和普通的看門狗一樣。


    例如:
    1) 向fd寫入任何資料,就等於是喂狗。
    2) 使用者可以通過ioctl對看門狗進行各種操作。
    3) 如果模擬載入時,模組引數nowayout的值為0,
       那麼當用戶向fd寫入一次含有字元V(注意,是大寫)的資料時,
       就將此看門狗設定成了可關閉的。


下面介紹一下此軟體的使用方法

(一)模組編譯


方法一、單獨編譯


    在soft_wdt原始碼目錄下,執行如下命令即可
    make -C /path/to/kernel/source/dir M=`pwd` modules


方法二、在Linux核心編譯體系中編譯


    1. 拷貝soft_wdt.c到drivers/watchdog/目錄下。
    
    2. 將下面這行程式碼,追加到核心原始碼的drivers/watchdog/Makefile中(在Architecture Independant部分)
    obj-$(CONFIG_SOFT_WDT) += soft_wdt.o
    
    3. 將下面的內容追加到核心原始碼的drivers/watchdog/Kconfig中(在Architecture Independant部分)


config SOFT_WDT
tristate "software watchdog timer (multiple dogs)"
default m
help
 A software watchdog driver, supporting multiple dogs.
 Each time, user opens the device file(/dev/soft_wdt),
 a new dog was created, associated with the fd returned
 by the open system call. The usage of each dog is just
 the same as ordinary watchdog, including MAGIC CLOSE.
 Currently the driver supports a maximum of 128 dogs.


 To compile this driver as a module, choose M here: the
 module will be called soft_wdt.


    4. 執行make menuconfig進入watchdog驅動程式的選擇介面,然後直接退出,並儲存配置。
    
    5. 執行make modules,然後在drivers/watchdog/目錄下,就會生成模組檔案soft_wdt.ko


(二)模組載入


    本軟體提供的模組引數如下。使用者可根據需要進行指定。


    nowayout           - 一旦啟動看門狗,不可以停止 (0,no;1,yes。default=0)
    timeout            - 看門狗超時時間,單位:秒。 (0 ~ 65536, default=5)
    no_reboot          - 看門狗超時,不重啟系統 。(0,no; 1,yes  default=0)
    core_dump_ill_task - 看門狗超時時,core dump異常任務,(0,no; 1,yes  default=1)


注意,core dump是通過向異常執行緒傳送SIGABRT訊號實現的。
因此,如果使用看門狗的程式,想自己記錄異常資訊,可以通過捕獲SIGABRT訊號來實現。




    下面是載入命令的示例。


    1. 使用預設引數載入(預設值如上面所列)
    insmod soft_wdt.ko


    2. 指定引數載入(12秒超時,看門狗可關閉,超時不重啟機器)
    insmod soft_wdt.ko timeout=12 nowayout=0 no_reboot=1


(三)使用者態程式使用看門狗

下面是示例程式碼

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/watchdog.h>

#define    SOFT_WDT_DEV    "/dev/soft_wdt"

int feed_dog_cnt;
int feed_dog_gap;

int main(int argc, char *argv[])
{
    int i;
    int  timeout;
    struct watchdog_info ident;
    
    int fd;

    if (argc<3)
    {
        printf("usage:\n %s  <feed_gap(in seconds)>  <feed_cnt>\n", argv[0]);
        return 0;
    }
    
    fd=open("/dev/soft_wdt", O_WRONLY);

    if (fd < 0)
    {
        printf("open %s failed\n", SOFT_WDT_DEV);
        exit(1);
    }


    printf("open %s succeed\n", SOFT_WDT_DEV);
    
    timeout = 7;
    printf("set timeout to %d\n", timeout);
    ioctl(fd, WDIOC_SETTIMEOUT, &timeout);

    timeout = 0;
    ioctl(fd, WDIOC_GETTIMEOUT, &timeout);
    printf("get timeout returns %d\n", timeout);

    ioctl(fd, WDIOC_GETSUPPORT, &ident);
    printf("dog name is %s\n", ident.identity);

    printf("make the dog closable\n");
    write(fd, "V", 1);

    feed_dog_gap = atoi(argv[1]);
    feed_dog_cnt = atoi(argv[2]);
    for (i=0; i<feed_dog_cnt; i++)
    {
        printf("feed dog\n");
        write(fd, "1234", 4);
        usleep(feed_dog_gap*1000000);
    }

    printf("stop feeding dog\n");
    while (1)
    {
        usleep(1000000);
    }
    
    return 0;
}