新聞中心
Linux看門狗是一個(gè)守護(hù)進(jìn)程,主要用于監(jiān)視系統(tǒng)運(yùn)行狀態(tài),并在系統(tǒng)遇到異常情況或死機(jī)時(shí)自動(dòng)重啟系統(tǒng)。該功能廣泛應(yīng)用于計(jì)算機(jī)、嵌入式設(shè)備等領(lǐng)域,對(duì)于保障系統(tǒng)的可靠性和穩(wěn)定性有著重要作用。

10多年的新城網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。網(wǎng)絡(luò)營(yíng)銷推廣的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整新城建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)從事“新城網(wǎng)站設(shè)計(jì)”,“新城網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
本文將以一個(gè)簡(jiǎn)單的看門狗代碼演示為例,介紹Linux看門狗的實(shí)現(xiàn)原理和使用方法。
1. 實(shí)現(xiàn)原理
Linux看門狗的實(shí)現(xiàn)原理非常簡(jiǎn)單,主要有以下幾個(gè)步驟:
1)設(shè)定看門狗定時(shí)器??撮T狗定時(shí)器的作用是定時(shí)檢查系統(tǒng)的運(yùn)行狀態(tài),如果系統(tǒng)正常運(yùn)行,則重置看門狗計(jì)時(shí)器;如果系統(tǒng)異常或死機(jī),則看門狗計(jì)時(shí)器超時(shí),觸發(fā)重啟系統(tǒng)的操作。
2)初始化看門狗設(shè)備。在Linux系統(tǒng)啟動(dòng)時(shí),需要通過驅(qū)動(dòng)程序初始化看門狗設(shè)備,并將看門狗定時(shí)器設(shè)置為一個(gè)合適的值,以便于檢測(cè)系統(tǒng)異常情況的發(fā)生。
3)啟動(dòng)看門狗守護(hù)進(jìn)程。看門狗守護(hù)進(jìn)程在后臺(tái)運(yùn)行,定期檢查系統(tǒng)運(yùn)行狀態(tài),并根據(jù)情況進(jìn)行系統(tǒng)重啟等操作。
2. 代碼演示
下面是一個(gè)簡(jiǎn)單的看門狗代碼演示,主要包括看門狗設(shè)備的初始化和看門狗守護(hù)進(jìn)程的實(shí)現(xiàn)。
(1)看門狗設(shè)備的初始化
#include
#include
#include
#include
#include
int mn()
{
int fd;
// 打開看門狗設(shè)備,獲取文件句柄
fd = open(“/dev/watchdog”, O_WRON);
if (fd
perror(“watchdog”);
return 1;
}
// 設(shè)置看門狗定時(shí)器為30s
ioctl(fd, WDIOC_SETTIMEOUT, 30);
// 關(guān)閉看門狗設(shè)備
close(fd);
return 0;
}
在上述代碼中,首先通過open()函數(shù)打開/dev/watchdog設(shè)備文件,獲取到該文件的文件句柄。然后使用ioctl()函數(shù)設(shè)置看門狗定時(shí)器為30秒。最后使用close()函數(shù)關(guān)閉看門狗設(shè)備。
(2)看門狗守護(hù)進(jìn)程的實(shí)現(xiàn)
#include
#include
#include
#include
#include
int mn()
{
int fd;
// 打開看門狗設(shè)備,獲取文件句柄
fd = open(“/dev/watchdog”, O_WRON);
if (fd
perror(“watchdog”);
return 1;
}
while (1) {
// 寫入看門狗喂狗指令
ioctl(fd, WDIOC_KEEPALIVE, 0);
// 等待一段時(shí)間,等待看門狗定時(shí)器的超時(shí)
sleep(1);
}
// 關(guān)閉看門狗設(shè)備
close(fd);
return 0;
}
在上述代碼中,首先通過open()函數(shù)打開/dev/watchdog設(shè)備文件,獲取到該文件的文件句柄。然后在while循環(huán)中使用ioctl()函數(shù)寫入喂狗指令,以保證看門狗定時(shí)器不會(huì)超時(shí)。最后使用close()函數(shù)關(guān)閉看門狗設(shè)備。
3. 使用方法
將上述兩個(gè)程序編譯成可執(zhí)行文件,然后在Linux系統(tǒng)啟動(dòng)時(shí),運(yùn)行看門狗守護(hù)進(jìn)程即可。例如,可以在/etc/rc.local文件中添加如下命令:
nohup /path/to/watchdog_daemon &
其中,/path/to/watchdog_daemon為看門狗守護(hù)進(jìn)程可執(zhí)行文件的路徑。
在運(yùn)行時(shí),可以通過ps -ef | grep watchdog命令查看看門狗守護(hù)進(jìn)程的運(yùn)行情況。如果看門狗守護(hù)進(jìn)程正常運(yùn)行,說明系統(tǒng)正常;如果看門狗守護(hù)進(jìn)程停止運(yùn)行,說明系統(tǒng)遇到了異常情況,此時(shí)看門狗定時(shí)器將在一定時(shí)間內(nèi)超時(shí),自動(dòng)觸發(fā)系統(tǒng)重啟的操作。
4.
成都網(wǎng)站建設(shè)公司-創(chuàng)新互聯(lián),建站經(jīng)驗(yàn)豐富以策略為先導(dǎo)10多年以來專注數(shù)字化網(wǎng)站建設(shè),提供企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計(jì),響應(yīng)式網(wǎng)站制作,設(shè)計(jì)師量身打造品牌風(fēng)格,熱線:028-86922220如何linux內(nèi)核報(bào)告問題
Linux Kernel BUG:soft lockup CPU#1 stuck分析
1.線上內(nèi)核bug日志
kernel: Deltaway too big!ts=write stamp =377
kernel:
kernel:WARNING: at kernel/trace/ring_buffer.c:1988 rb_reserve_next_event+0x2ce/巖衫0x370()(Not tainted)
kernel:Hardware name: ProLiant DL360 G7
kernel:Modules linked in: fuse ipv6 power_meter bnx2 sg microcode serio_raw iTCO_wdtiTCO_vendor_support hpilo hpwdt i7core_edac edac_core shpchp ext4 mbcache jbd2sd_mod crc_t10dif hpsa radeon ttm drm_kms_helper drm i2c_algo_bit i2c_coredm_mirror dm_region_hash dm_log dm_mod
kernel: Pid:5483, comm: master Not tainted 2.6.32-220.el6.x86_64 #1
kernel: CallTrace:
kernel: ? warn_slowpath_common+0x87/0xc0
kernel: ? warn_slowpath_null+0x1a/0x20
kernel: ? rb_reserve_next_event+0x2ce/0x370
kernel: ? ring_buffer_lock_reserve+0xa2/0x160
kernel: ? trace_buffer_lock_reserve+0x2c/0x70
kernel: ? trace_current_buffer_lock_reserve+0x16/0x20
kernel: ? ftrace_raw_event_hrtimer_cancel+0x4e/廳棗局0xb0
kernel: ? hrtimer_try_to_cancel+0xba/0xd0
kernel: ? do_setitimer+0xd4/0x220
kernel: ? alarm_setitimer+0x3a/0x60
kernel: ? sys_alarm+0xe/0x20
kernel: ? tracesys+0xd9/0xde
kernel: ——
abrt-dump-oops: Reported 1 kernel oopses to Abrt
kernel: BUG: softlockup – CPU#11 stuck fors!
kernel:Modules linked in: fuse ipv6 power_meter bnx2 sg microcode serio_raw iTCO_wdtiTCO_vendor_support hpilo hpwdt i7core_edac edac_core shpchp ext4 mbcache jbd2sd_mod crc_t10dif hpsa radeon ttm drm_kms_helper drm i2c_algo_bit i2c_coredm_mirror dm_region_hash dm_log dm_mod
kernel: CPU 11
kernel:Modules linked in: fuse ipv6 power_meter bnx2 sg microcode serio_raw iTCO_wdtiTCO_vendor_support hpilo hpwdt i7core_edac edac_core shpchp ext4 mbcache jbd2sd_mod crc_t10dif hpsa radeon ttm drm_kms_helper drm i2c_algo_bit i2c_coredm_mirror dm_region_hash dm_log dm_mod
kernel:
kernel: Pid:5492, comm: qmgr Tainted: G W— 2.6.32-220.el6.x86_64 #1 HPProLiant DL360 G7
kernel: RIP:0010: do_setitimer+0x1d0/0x220
kernel: RSP:0018:ffff88080a661ef8 EFLAGS:
kernel: RAX:ffff88080b175a08 RBX: ffff88080a661f18 RCX:000
kernel: RDX:00 RSI:082 RDI: ffff88080c8c4c40
kernel: RBP:ffffffff8100bc0e R08:000 R09: 0099d7270e01c3f1
kernel: R10:00 R11:246 R12: ffffffff810ef9a3
kernel: R13:ffff88080a661e88 R14:000 R15: ffff88080a65a544
kernel: FS:00007f10b245f7c0(0000) GS:ffff88083c4a0000(0000) knlGS:00
kernel: CS:0010 DS: 0000 ES: 0000 CR0:03b
kernel: CR2:00007ffCR3:a80b000 CR4:6e0
kernel: DR0:00 DR1:000 DR2:000
kernel: DR3:00 DR6:ffff0ff0 DR7:400
kernel:Process qmgr (pid: 5492, threadinfo ffff88080a660000, task ffff)
kernel: Stack:
kernel:00007f10b323deff10b248eadf10b26d0ff10b248ede0
kernel: ffff88080a661f68 ffffffff8106f88a000000
kernel:14cf423d000000
kernel: CallTrace:
kernel: ? alarm_setitimer+0x3a/0x60
kernel: ? sys_alarm+0xe/0x20
kernel: ? tracesys+0xd9/0xde
kernel: Code:89 ef e83 3db49 8bfffb 66 0f 1fc0 e9 64 fe ff ff49 8bc7 80 d
kernel: CallTrace:
kernel: ? do_setitimer+0x209/0x220
kernel: ? alarm_setitimer+0x3a/0x60
kernel: ? sys_alarm+0xe/0x20
kernel: ? tracesys+0xd9/0xde
abrt-dump-oops: Reported 1 kernel oopses to Abrt
2.內(nèi)核軟死鎖(soft lockup)bug原因分析
Soft lockup名稱解釋:所謂,soft lockup就是說,這個(gè)bug沒有讓系統(tǒng)徹底死機(jī),但是若干個(gè)進(jìn)程(或者kernel thread)被鎖死在了某個(gè)狀態(tài)(一般在內(nèi)核區(qū)域),很多情況下這個(gè)是由于內(nèi)核鎖的使用的問題。
Linux內(nèi)核對(duì)于每一個(gè)cpu都有一個(gè)監(jiān)控進(jìn)程,在技術(shù)界這個(gè)叫做watchdog(看門狗)。通過ps –ef | grep watchdog能夠看見,進(jìn)程名稱大概是watchdog/X(數(shù)字:cpu邏輯編號(hào)1/2/3/4之類的)。這個(gè)進(jìn)程或者線程每一秒鐘運(yùn)行一次,否則會(huì)睡眠和待機(jī)。這個(gè)進(jìn)程運(yùn)行會(huì)收集每一個(gè)cpu運(yùn)行時(shí)使用數(shù)據(jù)的時(shí)間并且存放到屬于每個(gè)cpu自己的內(nèi)核數(shù)據(jù)結(jié)構(gòu)。在內(nèi)核中有很多特定的中斷函數(shù)。這些中斷函數(shù)會(huì)調(diào)用soft lockup計(jì)數(shù),他會(huì)使用當(dāng)前的時(shí)間戳與特定(對(duì)應(yīng)的)cpu的內(nèi)核數(shù)據(jù)結(jié)構(gòu)中保存的時(shí)間對(duì)比,如果發(fā)現(xiàn)當(dāng)前的時(shí)間戳比對(duì)應(yīng)cpu保存的時(shí)間大于設(shè)定的閥值,他就假設(shè)監(jiān)測(cè)進(jìn)程或看門狗線程在一個(gè)相當(dāng)可觀的時(shí)間還沒有執(zhí)。Cpu軟鎖為什么會(huì)產(chǎn)生,是怎么產(chǎn)生的?如果linux內(nèi)核是經(jīng)過精心設(shè)計(jì)安排的CPU調(diào)度訪問,那么怎么會(huì)產(chǎn)生cpu軟死鎖?那么只能說由于用戶開發(fā)的或者第三方軟件引入,看我們服務(wù)器內(nèi)核panic的原因就是qmgr進(jìn)程引起。因?yàn)槊恳粋€(gè)無限的循環(huán)都會(huì)一直有一個(gè)cpu的執(zhí)行流程(qmgr進(jìn)程示一個(gè)后臺(tái)郵件的消息隊(duì)列服務(wù)進(jìn)程),并且擁有一定的優(yōu)先級(jí)。Cpu調(diào)度器調(diào)度一個(gè)驅(qū)動(dòng)程序來運(yùn)行,如果這個(gè)驅(qū)動(dòng)程序有問題并且沒有被檢測(cè)到,那么這個(gè)驅(qū)動(dòng)程序?qū)?huì)暫用cpu的很長(zhǎng)時(shí)間。根據(jù)前面的描述,看門狗進(jìn)程會(huì)抓?。╟atch)這一點(diǎn)并且拋出一個(gè)軟死鎖(soft lockup)錯(cuò)誤。軟死鎖會(huì)掛起cpu使你的系統(tǒng)不可用。
如果是用戶空間的進(jìn)程或線程引起的問題backtrace是不會(huì)有內(nèi)容的,如果內(nèi)核線程那么在soft lockup消息中會(huì)顯示出backtrace信息。
3.根據(jù)linux內(nèi)核源碼分析錯(cuò)誤
根據(jù)我們之一部分內(nèi)核拋出的錯(cuò)誤信息和call trace(linux內(nèi)核的跟蹤子系統(tǒng))來分析產(chǎn)生的具體原因。
首先根據(jù)我們的centos版本安裝相應(yīng)的linux內(nèi)核源碼,具體步驟如下:
(1)下載源碼的rpm包kernel-2.6.32-220.17.1.el6.src.rpm
(2)安裝相應(yīng)的依賴庫(kù),命令:yuminstall rpm-build redhat-rpm-config asciidoc newt-devel
(3)安裝源碼包:rpm -ikernel-2.6.32-220.17.1.el6.src.rpm
(4)進(jìn)入建立源碼的目錄:cd~/rpmbuild/SPECS
(5)建立生成源碼目錄:rpmbuild-bp –target=`uname -m` kernel.spec
下面開始真正的根據(jù)內(nèi)核bug日志分析源碼:
(1)之一階段內(nèi)核錯(cuò)誤日志分析(時(shí)間在Dec 4 14:03:34這個(gè)階段的日志輸出代碼分析,其實(shí)這部分代碼不會(huì)導(dǎo)致cpu軟死鎖,主要是第二階段錯(cuò)誤日志顯示導(dǎo)致cpu軟死鎖)
我們首先通過日志定位到相關(guān)源代碼:看下面日志:Dec 4 14:03:34 BP-YZH-1-xxxx kernel: WARNING: atkernel/trace/ring_buffer.c:1988 rb_reserve_next_event+0x2ce/0x370() (Not tainted)
根據(jù)日志內(nèi)容我們可以很容易的定位到kernel/trace/ring_buffer.c這個(gè)文件的1988行代碼如下:WARN_ON(1)。
先簡(jiǎn)單解釋一下WARN_ON的作用:WARN_ON只是打印出當(dāng)前棧信息,不會(huì)panic。所以會(huì)看到后面有一大堆的棧信息。這個(gè)宏定義如下:
#ifndef WARN_ON
#defineWARN_ON(condition) ({ \
int __ret_warn_on = !!(condition); \
if (unlikely(__ret_warn_on))\
__WARN();\
unlikely(__ret_warn_on); \
})
#endif
這個(gè)宏很簡(jiǎn)單保證傳遞進(jìn)來的條件值為0或者1(兩次邏輯非操作的結(jié)果),然后使用分支預(yù)測(cè)技術(shù)(保證執(zhí)行概率大的分支緊鄰上面的指令)判斷是否需要調(diào)用__WARN()宏定義。如果滿足條件執(zhí)行了__WARN()宏定義也接著執(zhí)行一條空指令;。上面調(diào)用WARN_ON宏是傳遞的1,所以會(huì)執(zhí)行__WARN()。下面繼續(xù)看一下__WARN()宏定義如下:
#define __WARN()warn_slowpath_null(__FILE__,__LINE__)
從接下來的call trace信息中我們也確實(shí)發(fā)現(xiàn)調(diào)用了warn_slowpath_null這個(gè)函數(shù)。通過在linux內(nèi)核源代碼中搜索這個(gè)函數(shù)的實(shí)現(xiàn),發(fā)現(xiàn)在panic.c(內(nèi)核恐慌時(shí)的相關(guān)功能實(shí)現(xiàn))中實(shí)現(xiàn)如下:
voidwarn_slowpath_null(const char *file, int line)
{
warn_slowpath_common(file, line,__builtin_return_address(0),
TAINT_WARN, NULL);
}
EXPORT_SYMBOL(warn_slowpath_null);//都出這個(gè)符號(hào),讓其他模塊可以使用這個(gè)函數(shù)
同樣的我們看到了warn_slowpath_common這個(gè)函數(shù),而在call trace當(dāng)中這個(gè)函數(shù)在warn_slowpath_null函數(shù)之前打印出來,再次印證了這個(gè)流程是正確的。同樣在panic.c這個(gè)文件中我發(fā)現(xiàn)了warn_slowpath_common這個(gè)函數(shù)的實(shí)現(xiàn)如下:
static voidwarn_slowpath_common(const char *file, int line, void *caller,
unsigned taint, struct slowpath_args *args)
{
const char *board;
printk(KERN_WARNING “\n”);
printk(KERN_WARNING “WARNING: at %s:%d %pS()(%s)\n”,
file, line, caller, print_tainted());
board = dmi_get_system_info(DMI_PRODUCT_NAME);//得到dmi系統(tǒng)信息
if (board)
printk(KERN_WARNING “Hardware name:%s\n”, board);//通過我們的日志信息可以發(fā)現(xiàn)我們硬件名稱是ProLiant DL360 G7
if (args)
vprintk(args->fmt, args->args);
print_modules();//打印系統(tǒng)模塊信息
dump_stack();//dump信息輸出(call trace開始)
print_oops_end_marker();//打印oops結(jié)束
add_taint(taint);
}
分析這個(gè)函數(shù)的實(shí)現(xiàn)不難發(fā)現(xiàn)我們的很多日志信息從這里開始輸出,包括打印一些系統(tǒng)信息,就不繼續(xù)深入分析了(請(qǐng)看代碼注釋,里面調(diào)用相關(guān)函數(shù)打印對(duì)應(yīng)信息,通過我分析這些函數(shù)的實(shí)現(xiàn)和我們的日志信息完全能夠?qū)?yīng),其中dump_stack是與cpu體系結(jié)構(gòu)相關(guān)的,我們的服務(wù)器應(yīng)該是屬于x86體系)。這里在繼續(xù)分析一下dump_stack函數(shù)的實(shí)現(xiàn),因?yàn)檫@個(gè)是與cpu體系結(jié)構(gòu)相關(guān)的,而且這個(gè)函數(shù)直接反應(yīng)出導(dǎo)致內(nèi)核panic的相關(guān)進(jìn)程。這個(gè)函數(shù)實(shí)現(xiàn)如下:
/*
* The architecture-independent dump_stackgenerator
*/
void dump_stack(void)
{
unsigned long stack;
printk(“Pid: %d, comm: %.20s %s %s %.*s\n”,
current->pid, current->comm,print_tainted(),
init_utsname()->release,
linux 看門狗代碼示例的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于linux 看門狗代碼示例,Linux實(shí)例:看門狗代碼演示,如何linux內(nèi)核報(bào)告問題的信息別忘了在本站進(jìn)行查找喔。
成都創(chuàng)新互聯(lián)科技公司主營(yíng):網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、小程序制作、成都軟件開發(fā)、網(wǎng)頁(yè)設(shè)計(jì)、微信開發(fā)、成都小程序開發(fā)、網(wǎng)站制作、網(wǎng)站開發(fā)等業(yè)務(wù),是專業(yè)的成都做小程序公司、成都網(wǎng)站建設(shè)公司、成都做網(wǎng)站的公司。創(chuàng)新互聯(lián)公司集小程序制作創(chuàng)意,網(wǎng)站制作策劃,畫冊(cè)、網(wǎng)頁(yè)、VI設(shè)計(jì),網(wǎng)站、軟件、微信、小程序開發(fā)于一體。
網(wǎng)站名稱:Linux實(shí)例:看門狗代碼演示(linux看門狗代碼示例)
文章網(wǎng)址:http://fisionsoft.com.cn/article/dhdiocd.html


咨詢
建站咨詢
