歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> Linux教程

使用 watchdog 構建高可用性的 Linux 系統及應用

周 婷 ([email protected]), 軟件工程師, IBM 中國系統技術實驗室

周婷,軟件工程師,目前在 IBM 中國系統技術實驗室從事服務器管理固件的開發工作

簡介: Linux 在不同領域如電信、終端便攜設備等得到廣泛應用,不同領域的應用對 Linux系統也提出相應的需求。Carrier Grade Linux 是 OSDL(Open Source Development Lab)發布的電信級 Linux 的標准,在系統可用性這部分指出 Linux 必須支持 watchdog 機制。Linux 內核從 1.3.51 版本開使提供硬件、軟件 watchdog 驅動。隨著內核的發展,Linux 對不同類型的硬件 watchdog 卡提供了廣泛的支持。本文首先介紹 Linux 內核對硬件、軟件 watchdog 的支持;然後通過一個開源項目watchdog daemon介紹如何在一個系統監控應用中加入 watchdog 的使用以提高系統的可用性,以及如何在一個 Linux 服務應用中加入watchdog 模塊以提高應用的可用性。

1 Linux對Watchdog的支持

1.1 Linux下watchdog的工作原理

Watchdog在實現上可以是硬件電路也可以是軟件定時器,能夠在系統出現故障時自動重新啟動系統。在Linux 內核下, watchdog的基本工作原理是:當watchdog啟動後(即/dev/watchdog 設備被打開後),如果在某一設定的時間間隔內/dev/watchdog沒有被執行寫操作, 硬件watchdog電路或軟件定時器就會重新啟動系統。

/dev/watchdog 是一個主設備號為10, 從設備號130的字符設備節點。 Linux內核不僅為各種不同類型的watchdog硬件電路提供了驅動,還提供了一個基於定時器的純軟件watchdog驅動。 驅動源碼位於內核源碼樹drivers\char\watchdog\目錄下。

1.2 硬件與軟件watchdog的區別

  1. 硬件watchdog必須有硬件電路支持, 設備節點/dev/watchdog對應著真實的物理設備, 不同類型的硬件watchdog設備由相應的硬件驅動管理。軟件watchdog由一內核模塊softdog.ko 通過定時器機制實現,/dev/watchdog並不對應著真實的物理設備,只是為應用提供了一個與操作硬件watchdog相同的接口。
  2. 硬件watchdog比軟件watchdog有更好的可靠性。 軟件watchdog基於內核的定時器實現,當內核或中斷出現異常時,軟件watchdog將會失效。而硬件watchdog由自身的硬件電路控制, 獨立於內核。無論當前系統狀態如何,硬件watchdog在設定的時間間隔內沒有被執行寫操作,仍會重新啟動系統。
  3. 一些硬件watchdog卡如WDT501P 以及一些Berkshire卡還可以監測系統溫度,提供了 /dev/temperature接口。

對於應用程序而言, 操作軟件、硬件watchdog的方式基本相同:打開設備/dev/watchdog, 在重啟時間間隔內對/dev/watchdog執行寫操作。即軟件、硬件watchdog對應用程序而言基本是透明的。

在任一時刻, 只能有一個watchdog驅動模塊被加載,管理/dev/watchdog 設備節點。如果系統沒有硬件watchdog電路,可以加載軟件watchdog驅動softdog.ko。

1.3 Linux內核中關於watchdog的配置

在Linux下使用watchdog開發應用之前, 請確定內核已經正確地配置支持watchdog。內核源碼下的drivers/char/watchdog/Kconfig文件提供了各種watchdog配置選項的詳細介紹。特別指出關於‘CONFIG_WATCHDOG_NOWAYOUT’選項的配置,從清單1軟件watchdog的模塊信息可以看到,nowayout參數的缺省值等於‘CONFIG_WATCHDOG_NOWAYOUT’, 如果‘CONFIG_WATCHDOG_NOWAYOUT’選項在內核配置時設為‘Y’, 缺省情況下,watchdog啟動後(即/dev/watchdog被打開後),無論是執行close操作還是寫入字符‘V’都不能停止watchdog的運行。


清單 1. 軟件watchdog驅動softdog的模塊信息

                
linux-mach:~ # modinfo softdog
filename:       /lib/modules/2.6.16.21-0.8-smp/kernel/drivers/char/watchdog/softdog.ko
author:         Alan Cox
description:    Software Watchdog Device Driver
license:        GPL
alias:          char-major-10-130
vermagic:       2.6.16.21-0.8-smp SMP 586 REGPARM gcc-4.1
supported:      yes
depends:        
srcversion:     EAE9E5688843C073B0EF5BC
parm:           soft_noboot:Softdog action, set to 1 to ignore reboots, 0 to reboot 
                    (default depends on ONLY_TESTING) (int)
parm:           nowayout:Watchdog cannot be stopped once started 
                    (default=CONFIG_WATCHDOG_NOWAYOUT) (int)
parm:           soft_margin:Watchdog soft_margin in seconds. 
                    (0<soft_margin<65536, default=60) (int)      

1.4 watchdog重啟時間間隔設定

在開發應用之前,必須了解所用的watchdog驅動的重啟時間間隔。各種硬件以及軟件watchdog驅動都設有一個缺省的重啟時間間隔,此重啟時間間隔也可在加載驅動模塊時設置。

從清單1軟件watchdog的模塊信息可以看到,soft_margin參數代表了softdog.ko的重啟時間間隔,缺省值是60秒,可以在加載softdog.ko 時指定重啟時間間隔, 如 `modprobe softdog soft_margin=100`。

1.5 watchdog啟動

各種硬件以及軟件watchdog驅動都為應用提供了相同的操作方式。打開/dev/watchdog設備,watchdog將被啟動。如果在指定重啟時間間隔內沒有對/dev/watchdog執行寫操作,系統將重啟。


清單 2. 啟動watchdog的代碼段

                
int wdt_fd = -1;
wdt_fd = open("/dev/watchdog", O_WRONLY);
if (wdt_fd == -1)
{
    // fail to open watchdog device
}
  

1.6 watchdog停止

如果內核配置選項‘CONFIG_WATCHDOG_NOWAYOUT’設為‘Y’, 缺省情況下watchdog啟動後不能被停止。 如果模塊的nowayout參數設為0, 往/dev/watchdog 寫入字符`V’ 可以使watchdog停止工作。可以參考參考文獻二2.6內核源碼drivers\char\watchdog目錄下各種硬件及軟件watchdog驅動的write函數得到停止watchdog的邏輯, 譬如軟件watchdog驅動softdog.c 中的write函數。

參考文獻三watchdog daemon源碼 watchdog-5.4.tar.gz的 close_all函數提供了停止watchdog運行的范例。以下是一個簡單的停止watchdog的代碼段范例:


清單 3. 停止watchdog的代碼段

                
    if (wdt_fd != -1)
    {
        write(wdt_fd, "V", 1);
        close(wdt_fd);
        wdt_fd = -1;
    }  

1.7 watchdog運行

從1.6節中提到的softdog模塊的write函數可以看到,在watchdog重啟時間間隔內執行寫操作,softdog_keepalive將被調用,增加定時器定時時間。

所以應用在啟動watchdog後,必須在重啟時間間隔內,周期性地對/dev/watchdog執行寫操作才能使系統不被重啟。

參考文獻三watchdog daemon源碼 watchdog-5.4.tar.gz的keep_alive函數提供了保持watchdog運行的范例。以下是一個簡單的保持watchdog運行的代碼段范例:


清單 4. 保持watchdog運行的代碼段

                
    if (wdt_fd != -1)
        write(wdt_fd, "a", 1);
Copyright © Linux教程網 All Rights Reserved