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

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

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的支持

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);

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

不同的系統與應用有自己的監控需求,不同的被監控對象有相應的監控方法。下文第一部分介紹了一個Linux下的開源項目watchdog daemon。 這是一個系統監控的後臺應用,通過從配置文件中讀取監控對象以及監控參數等信息對系統進行內存、負載、進程、網絡等方面的監控, 同時將各種監測信息記入系統日誌,並能夠在系統重啓之前發email通知管理員。通過閱讀這個項目的源碼可以學習到:

  1. 如何在一個系統監控程序中使用watchdog,在系統出現故障時重新啓動系統,以提高系統的可用性
  2. 常用的被監控對象以及相應的監控方法

當Linux用於電信、 嵌入式領域, 一些基於Linux操作系統開發的服務應用在可用性上有較高的要求,下文第二部分介紹瞭如何在這種類型的應用中加入watchdog機制以提高應用的可用性。

2.1 在監控應用中加入watchdog以提高系統可用性

watchdog daemon是一個Linux下使用了watchdog的系統監控的後臺應用。開發人員可以下載最新的watchdog_5.4.tar.gz源碼。 參見參考資源下載源碼。

2.1.1 程序框架

Watchdog daemon主程序運行流程如下:

  1. 解析命令行輸入,從watchdog.conf 配置文件讀取配置信息,檢測各種配置參數的有效性。 這些配置信息包括:
    • 被監控的對象譬如網絡接口eth0, 被監控進程的pid文件如/var/run/syslogd.pid
    • 各種檢測參數的闕值
    • 用戶提供的修復程序路徑
    • 用戶提供的測試程序路徑
    ?

    如果沒有在配置文件中設置某些配置信息, 相應的檢測將不被執行。

  2. 進行一系列初始化:
    • 初始化用於檢測網絡狀態的套接口
    • 設置自身爲後臺進程
    • 打開日誌文件,往日誌中記入各種配置信息
    • 打開/dev/watchdog設備啓動watchdog
    • 打開proc/下各種狀態信息文件如/proc/meminfo、 /proc/loadavg
    • 禁止自身被swap出內存, 設置自身的調度優先級(在系統負載較高時, watchdog 後臺進程自身有可能被swap出內存,導致不能及時對/dev/watchdog 執行寫操作而使系統重啓)
    ?
  3. 進入while(1) 主循環, 依次執行: ?
    • 對/dev/watchdog執行寫操作,表明當前系統運行良好。如果超過一分鐘的時間間隔沒有對/dev/watchdog執行寫操作,系統將會被動重啓
    • 進行各種檢測,下節將介紹被各種檢測的對象以及相應的檢測方法
    • 睡眠一段時間,此睡眠時間在配置文件中設置。如果睡眠時間設置太長,則會出現不必要的重啓;設置太短,會導致檢測太頻繁,增加系統負載。
    ? ?

如果檢測返回錯誤, 檢測返回值顯示故障可以修復,同時配置文件中也設置了修復程序, 修復程序將會被調用。如果修復故障失敗,主程序將會嘗試執行一系列清理、記載日誌、email通知管理員的操作,然後重新啓動系統。必須注意的是,當檢測發現錯誤時,主程序並不是退出while(1)循環,使/dev/watchdog在1分鐘內沒被執行寫操作而導致系統被動重啓; 而是執行一系列操作後主動重啓系統,這樣既可以記錄下日誌信息,email通知管理員,也可以防止系統被動重啓導致文件系統損壞。

主程序在主動重啓之前, 會執行以下一系列操作:

  • 關閉所有打開的文件
  • 如果sendemail應用存在,配置文件中提供了管理員的email地址,將發封email給管理員通知系統重啓
  • 將重啓信息記入系統日誌
  • kill掉所有進程
  • 將重啓信息記入wtmp
  • 關閉accounting,quota,swap ?
  • 卸載所有非根文件系統
  • 以只讀方式重新裝載根文件系統
  • 關閉網絡接口
  • 重啓系統

?

從以上程序框架可以看到,監控應用檢測出系統故障時,在系統可控的狀態下,應用會嘗試主動重啓系統。但是通過啓動watchdog,能夠在系統不可控,或是監控應用自身不能正常運行時,由watchdog自動啓動系統。

2.1.2 監控對象及監控方法

watchdog daemon根據配置文件對系統進行以下類型的監控,並將每次檢測的結果記入系統日誌:

  1. 通過打開一個文件成功與否測試文件表是否已滿
  2. 通過讀取/proc/loadavg 以檢測1、5、15分鐘內系統平均負載是否超過設定值
  3. 通過讀取/proc/meminfo檢測系統是否還剩下足夠的空閒內存
  4. 如果一些硬件watchdog卡提供有溫度傳感器進行溫度監控,訪問/dev/temperature設備判斷溫度是否過高
  5. 通過調用kill (pid, 0)檢測某個進程是否仍在運行,如果kill調用返回爲0,則進程仍在運行, 通過從配置文件中讀取pid文件如/var/run/syslogd.pid來獲取被監控進程的pid
  6. 通過解析/proc/net/dev 的信息, 查看指定的網絡接口如eh0的收發包狀況
  7. 通過往一些IP地址發包檢測這些IP地址可否被ping通,或是ping廣播地址檢測子網中是否至少一臺機器可以被ping通
  8. 通過調用fork、execl執行用戶傳遞的測試程序

watchdog daemon提供了一些常用的很有參考價值的監控方法及源碼,開發人員也可自行設計開發更豐富的監控方法對系統進行更爲細緻、全面的監控。

2.2 在服務應用中增加watchdog模塊以提高應用的可用性


Linux因爲其強大的功能已成爲很多企業級應用的開發平臺。這些應用本身並不是一個監控程序而是一個管理或服務程序, 對可用性有較高的要求。通過在

這類應用中加watchdog模塊, 一方面監測系統狀態, 另一方面監測此應用中其它模塊的工作狀態。系統出現故障時能自動重啓,因爲應用已加在系統

的init.d啓動服務中, 應用會隨着系統的啓動而啓動,自動提供服務。

這類服務應用通常是多線程的,甚至是多進程的。 加入watchdog機制的通常作法是在應用中加入一個watchdog線程,此線程主循環的工作流程與上節介紹的

系統監控應用的守護進程的主循環工作流程大致相似。Watchdog線程在進入主循環之前的初始化階段打開/dev/watchdog 啓動watchdog, 然後執行上節中提到

的while(1)循環中的操作。

如果此應用是多進程的,子進程的fork可以放在watchdog線程的初始化階段執行。 Watchdog線程可以獲得這些子進程的pid,從而檢測這些子進程的工作狀態。

Watchdog線程除了可以參照上節watchdog daemon提供的方法對系統狀態進行監控, 還可以通過消息隊列或套接口與應用中的其它線程進行通信,

 獲得其它線程的工作狀態。不過這需要在其它子線程中加入與watchdog線程進行通信的接口。

轉自:https://www.ibm.com/developerworks/cn/linux/l-cn-watchdog/#icomments 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章