What are Machine Check Exceptions (or MCE)?
A machine check exception is an error dedected by your system's processor. There are 2 major types of MCE errors, a notice or warning error, and a fatal execption. The warning will be logged by a "Machine Check Event logged" notice in your system logs, and can be later viewed via some Linux utilities. A fatal MCE will cause the machine to stop responding and the details of the MCE will be printed out to the system's console.
本文重點,主要看案例2,帶你很好的理解mcelog如何工作的?
- mcelog的干什么的?
- mcelog 是 x86 的 Linux 系統上用來 檢查硬件錯誤,特別是內存和CPU錯誤的工具.
- mcelog怎么運行的?這三種方式有什么優點?缺點?
- 有三種運行的方式,cron,daemon,trigger
- cron是最low的方式,會丟失,trigger是比較高級的方式,觸發的。一般我們在el6.el7上都是用daemon的方式
- 線上情況:el6,el7上怎么運行的?
- el6上默認應該是使用cron,每小時運行一次,也可以使用daemon守護進程的方式(需要手動執行mcelog --daemon),默認日志打到/var/log/mcelog,和/var/log/message.
- el7上默認使用mcelog.service啟動的,相當於daemon守護進程的方式,但是,默認日志只打到和/var/log/message,然而默認/var/log/mcelog文件不存在,這個需要在啟動命令種加上--logfile=/var/log/mcelog才可以。
- 如何模擬硬件錯誤驗證mcelog是否運行正常?
- 有一個工具叫:mceinject ,mcetest,參見下文的案例2
mcelog簡介
可糾正和不可糾正的硬件錯誤統稱為機器檢查異常 (MCE)。CPU 自身能夠糾正錯誤,並通知底層操作系統與 CPU 或緩存有關的問題。CPU 本身還能從某些錯誤中恢復。Oracle Linux 可將 mcelog 用作機器檢查的日志子系統。首先,必須使用以下命令在服務器上安裝軟件包。
yum install mcelog.x86_64 service mcelogd start chkconfig mcelogd on or mcelog --daemon or systemctl restart mcelog.service
mcelog 是 x86 的 Linux 系統上用來 檢查硬件錯誤,特別是內存和CPU錯誤的工具.
mcelog 軟件包有工作方式,有使用cron的,也有使用守護進程的,,這個取決於你的操作系統版本。
/etc/cron.hourly/mcelog.cron 中的 cron 作業每小時檢查 MCE 並將其保存到 /var/log/mcelog 中。由后台程序控制 mcelog 的方法更好一些,因為這樣可以更快速地檢測到硬件錯誤並立即記錄下來,而不必等待 cron 作業運行。使用 mcelog 能檢測到總線錯誤、內存錯誤和 CPU 緩存錯誤之類的錯誤,如果即將發生硬件故障,可以提前通知。
mcelog 能捕獲兩類錯誤:已糾正的 和未糾正的。已糾正的錯誤是由 CPU 處理的事件,可用來識別可能預測更大問題的趨勢。
未糾正的錯誤是關鍵異常,如果 CPU 無法恢復,往往會導致系統上的內核錯誤。這會導致應用程序重置和中斷。對於未糾正的錯誤,mcelog 捕獲錯誤的能力取決於錯誤導致熱重啟還是硬重啟。如果是熱重啟,信息會被 mcelog 捕獲,恢復后可看到。硬重啟會導致數據丟失,而且 mcelog 可能捕獲不到該事件。
如下示例顯示的 mcelog 錯誤消息顯示了 CPU 1 上一個已糾正的錯誤:
Hardware event. This is not a software error. MCE 0 CPU 1 BANK 2 ADDR 1234 TIME 1364535025 Fri Mar 29 01:30:25 2013 MCG status: MCi status: Corrected error Error enabled MCi_ADDR register valid MCA: No Error STATUS 9400000000000000 MCGSTATUS 0 MCGCAP c07 APICID 1 SOCKETID 0 CPUID Vendor Intel Family 6 Model 58
為了進行測試和故障排除,可以使用 mce-test 包生成假的硬件 MCE 事件並執行系統測試。
mce-test 軟件包含豐富的默認測試,能模擬真實硬件故障,甚至會導致內核錯誤。需要執行幾個配置步驟才能對系統進行此類測試。
首先,需要安裝幾個支持軟件包才能在測試系統上配置 mce-test。使用以下命令:
yum install gcc.x86_64 gcc-c++.x86_64 flex.x86_64 dialog.x86_64 ras-utils.x86_64 git.x86_64
mcelog相關
mcelog的啟動方式
- cron,最老的方式,有確定,定時任務,會丟失一些
- daemon,el7上用這種
- trigger,高級一點的方式,觸發的時候,看man mcelog
mcelog相關文件
/dev/mcelog 設備文件
/var/log/mcelog messages日志文件
/etc/mcelog/mcelog.conf配置文件
/var/run/mcelog.pid
默認故障日志只記錄在/var/log/mcelog,並不記錄到系統日志中。
如果需要在系統日志中也體現,需修改/etc/mcelog/mcelog.conf文件,將前面#去掉,並保存。
# log output options # Log decoded machine checks in syslog (default stdout or syslog for daemon) #syslog = yes # Log decoded machine checks in syslog with error level #syslog-error = yes # Never log anything to syslog #no-syslog = yes # Append log output to logfile instead of stdout. Only when no syslog logging is active #logfile = filename
el6的mcelog
el6運行mcelog的方式
在el6上mcelog使用cron來運行,安裝mcelog會自動產生如下文件:
/etc/cron.hourly/mcelog.cron
默認配置 /etc/cron.hourly/mcelog.cron 每小時執行一次。
這個定時腳本是軟件包 mcelog安裝的,這個工具mcelog目前仍在持續開發維護,可以從內核工具 或GitHub andikleen/mcelog 獲得。
#ps aux | grep mcelog root 4177 0.0 0.0 6756 616 ? Ss Aug18 0:00 /usr/sbin/mcelog --daemon
el6手動運行mcelog的方式
# mcelog --daemon
el6上查看mcelog日志
#tail /var/log/mcelog
什么也沒有說明,正常。
查看mcelog守護進程是否檢測到錯誤信息
# mcelog --client
沒有輸出,表示正常。
解析系統異常時的mcelog輸出:
# mcelog --ascii < file.log or # mcelog --ascii --file file.log
案例1:完全看不懂
mcelog --ascii --file /var/log/mcelog |tail 和sudo tail /var/log/mcelog看到的結果是一樣的。
[root@zxl /home/ahao.mah] $mcelog --ascii --file /var/log/mcelog |tail mcelog: Cannot open /dev/mem for DMI decoding: Permission denied MCA: MEMORY CONTROLLER MS_CHANNEL2_ERR Transaction: Memory scrubbing error STATUS cc000140000800c2 MCGSTATUS 0 MCGCAP 1000c19 APICID 0 SOCKETID 0 Hardware event. This is not a software error. CPU 0 BANK 0 MISC 0 ADDR 0 STATUS cc000140000800c2 MCGSTATUS 0 MCGCAP 1000c19 APICID 0 SOCKETID 0 (Fields were incomplete)
[root@zxl /home/ahao.mah] $sudo tail /var/log/mcelog MCi status: Error overflow Corrected error MCi_MISC register valid MCi_ADDR register valid MCA: MEMORY CONTROLLER MS_CHANNEL2_ERR Transaction: Memory scrubbing error STATUS cc000140000800c2 MCGSTATUS 0 MCGCAP 1000c19 APICID 0 SOCKETID 0 CPUID Vendor Intel Family 6 Model 62
[root@zxl /home/ahao.mah] $sudo mcelog --client Memory errors SOCKET 0 CHANNEL any DIMM any corrected memory errors: 13 total 0 in 24h uncorrected memory errors: 0 total 0 in 24h SOCKET 0 CHANNEL 2 DIMM any corrected memory errors: 4 total 4 in 24h uncorrected memory errors: 0 total 0 in 24h Per page corrected memory statistics: 198f0b2000: total 1 seen "1 in 24h" online 198f0b9000: total 1 seen "1 in 24h" online 1b8f0b5000: total 1 seen "1 in 24h" online 1b8f0be000: total 1 seen "1 in 24h" online
el7的mcelog
el7運行mcelog
- 默認開機啟動:mcelog.service
-
#systemctl is-enabled mcelog.service enabled - 在el7不是使用cron運行mcelog,用mcelog.service管理
-
#systemctl cat mcelog.service # /usr/lib/systemd/system/mcelog.service [Unit] Description=Machine Check Exception Logging Daemon After=syslog.target # FIXME - due to upstream kernel bug always start the mcelog process # twice using the following ExecStartPre hack. This needs fixing. # There is a bug filed against systemd for the ExecStartPre bit # since it is not possible to specify that the ExecStarPre bit # is allowed and expected to fail without aborting the daemon. [Service] Type=forking ExecStartPre=/etc/mcelog/mcelog.setup ExecStart=/usr/sbin/mcelog --ignorenodev --daemon --syslog StandardOutput=syslog [Install] WantedBy=multi-user.target
在RHEL 7.x平台,已經舍棄了使用cron方式運行mcelog程序的方法,而改為系統啟動時運行mcelog.service服務進程。使用ps命令可以檢查到系統運行了如下mcelog服務
-
/usr/sbin/mcelog --ignorenodev --daemon --syslog
--ignorenodev Exit silently when the device cannot be opened --daemon Run in background waiting for events (needs newer kernel) --syslog Log decoded machine checks in syslog (default stdout or syslog for daemon)
el7上查看mcelog日志
mcelog的相關配置
-
#grep MCE /boot/config-2.6.32-220.23.2.ali878.el6.x86_64 CONFIG_X86_MCE=y CONFIG_X86_MCE_INTEL=y CONFIG_X86_MCE_AMD=y CONFIG_X86_MCE_THRESHOLD=y CONFIG_X86_MCE_INJECT=m CONFIG_EDAC_DECODE_MCE=m # CONFIG_EDAC_MCE_INJ is not set CONFIG_EDAC_MCE=y
安全
__mcelog__需要使用root身份運行,因為它需要出發動作,如page-offlining,這要求CAP_SYS_ADMIN。並且它需要打開設備/dev/mcelog和一個用於支持客戶端的unix socket。
當mcelog運行在daemon模式,它會監聽在一個unix socket上並處理mcelog --client的請求。默認會檢查請求的uid/gid並且默認是0/0,可配置。客戶端處理和相應是由daemon的完整的特權處理的。
測試
mce-inject使用方法
mce-inject用於測試mcelog能否正確的獲取硬件錯誤信息,並進行正確解碼,mce-inject可以向內核注入指定的錯誤信息,因此,可以很方便的了解到mcelog的功能是否正常。
這里需要注意的是,當用戶利用mce-inject工具向內核注入不可恢復錯誤(如:fatal)時,會發生死機重新啟動等現象,當然,可以通過更改sys文件系統下的tolerate文件來避免此現象的發生。安裝mce-inject
-
#yum install -y ras-utils
tolerate文件配置
位置:/sys/devices/system/machinecheck/machinecheck*/
說明:其中machinecheck* 中的 *號由CPU的個數所決定的,如果是雙核的,則存在machinecheck0和machinecheck1兩個目錄,對應目錄里都有一個tolerate文件,tolerate中存放容忍程度值。
功能:向用戶提供一個可選擇的出現相應硬件錯誤時的容忍程度(tolerate),比如:當tolerate的值為1時,出現fatal錯誤時就會死機,重新啟動,並且該錯誤信息並不被記錄;當tolerate的值為3時(注意該值只用於測試),在出現fatal錯誤時,機器會容忍該錯誤不予響應,不會出現死機重新啟動現象,並且會記錄相關錯誤信息。查看tolerate
以root身份進入相應的目錄進行查看即可。如:
-
#cd /sys/devices/system/machinecheck/machinecheck0 #cat tolerate
查看CPU0的tolerate值。
設置tolerate
以root身份進入相應的目錄進行修改即可,設置tolerate的方法很多,如: -
#cd /sys/devices/system/machinecheck/machinecheck0 #echo 3 > tolerant
數值含義
-
tolerate的取值可以為0、1、2、3。 0: always panic on uncorrected errors, log corrected errors 1: panic or SIGBUS on uncorrected errors, log corrected errors 2: SIGBUS or log uncorrected errors (if possible), log corrected errors 3: never panic or SIGBUS, log all errors (for testing only)
案例2:mce-inject使用
-
mce-inject的使用方法也很簡單,不過在使用前要現將tolerate的值修改為3,以防止死機重啟事件發生,然后,在終端以root身份執行: mce-inject filename ... filename 存放要注入的具體錯誤類型
1. 安裝
-
yum install gcc.x86_64 gcc-c++.x86_64 flex.x86_64 dialog.x86_64 ras-utils.x86_64 git.x86_64
2. 捏造文件
例如,一個mce-filename文件correct的內容為:
-
#cat correct CPU 1 BANK 2 STATUS corrected RIP 0x12341234
3. 加載mce-inject模塊
-
# modprobe mce-inject#modprobe -l | grep mce-inject kernel/arch/x86/kernel/cpu/mcheck/mce-inject.ko
4. 在終端輸入
-
#mce-inject ./correct
即可成功注入,詳細的輸出結果可以查看/var/log/mcelog文件。
5. 查看/var/log/mcelog,/var/log/messages
-
#tail /var/log/mcelog CPU 1 BANK 2 TIME 1475065726 Wed Sep 28 20:28:46 2016 MCG status: MCi status: Corrected error Error enabled MCA: No Error STATUS 9000000000000000 MCGSTATUS 0 MCGCAP 1000c12 APICID 2 SOCKETID 0 CPUID Vendor Intel Family 6 Model 45
#cat /var/log/messages Sep 28 20:41:24 dnstest08.tbc kernel: : [16423350.358386] Starting machine check poll CPU 1 Sep 28 20:41:24 dnstest08.tbc kernel: : [16423350.371252] [Hardware Error]: Machine check events logged
6.同樣的方式,在el7上也可以看到
tail /var/log/messages 可以看到日志,但是,/var/log/mcelog文件默認在el7上,卻不存在!!
原因是,默認打到/var/log/messages ,不打到/var/log/mcelog。如果希望打到/var/log/mcelog,需要在mcelog 的service文件中,加入參數--logfile=/var/log/mcelog,然后重啟mcelog . -
ExecStart=/usr/sbin/mcelog --ignorenodev --daemon --syslog --logfile=/var/log/mcelog
#tail /var/log/messages -f Sep 28 20:57:53 jiangyi02 kernel: Starting machine check poll CPU 1 Sep 28 20:57:53 jiangyi02 kernel: Machine check poll done on CPU 1 Sep 28 20:57:53 jiangyi02 mcelog: Hardware event. This is not a software error. Sep 28 20:57:53 jiangyi02 mcelog: MCE 0 Sep 28 20:57:53 jiangyi02 mcelog: CPU 1 BANK 2 Sep 28 20:57:53 jiangyi02 mcelog: TIME 1475067473 Wed Sep 28 20:57:53 2016 Sep 28 20:57:53 jiangyi02 mcelog: MCG status: Sep 28 20:57:53 jiangyi02 mcelog: MCi status: Sep 28 20:57:53 jiangyi02 mcelog: Corrected error Sep 28 20:57:53 jiangyi02 mcelog: Error enabled Sep 28 20:57:53 jiangyi02 mcelog: MCA: No Error Sep 28 20:57:53 jiangyi02 mcelog: STATUS 9000000000000000 MCGSTATUS 0 Sep 28 20:57:53 jiangyi02 mcelog: MCGCAP 1000c12 APICID 2 SOCKETID 0 Sep 28 20:57:53 jiangyi02 mcelog: CPUID Vendor Intel Family 6 Model 45
可以通過文本文件提供輸入的方式直接使用 mce-inject 可執行程序,但對於在系統上進行測試,功能更強的方法是使用 mce-test 程序。
-
#git clone https://github.com/andikleen/mce-test.git Cloning into 'mce-test'... remote: Counting objects: 2197, done. remote: Total 2197 (delta 0), reused 0 (delta 0), pack-reused 2197 Receiving objects: 100% (2197/2197), 409.06 KiB | 57.00 KiB/s, done. Resolving deltas: 100% (1220/1220), done. Checking connectivity... done.
克隆 git 信息庫之后,您就可以轉到 mce-test 目錄執行 mcemenu,這會轉至 mce-test 工具主菜單
我們要做的第一件事是編譯測試套件,所以選擇 Compile 選項編譯該測試套件要用到的所有可執行文件。然后可以從 Execute 菜單中執行測試。測試運行后,可以使用 Results 菜單查看測試結果。mce-test/doc 目錄下的文檔包含了有關測試以及如何根據需要充分利用該套件的所有信息。
-
硬件排查
- 日志報錯查看/var/log/messages或/var/log/mcelog 有報錯,不知道有什么方法可以找出mc0: csrow6: CPU_SrcID#0_Ha#0_Channel#3是哪個內存DIMM,其中的chanel和csrow分別代表什么意思?
-
[30200989.742558] {1}[Hardware Error]: Hardware error from APEIGeneric Hardware Error Source: 65534 [30200989.742562] {1}[Hardware Error]: It has been corrected by h/wand requires no further action [30200989.742566] {1}[Hardware Error]: event severity: corrected [30200989.742568] {1}[Hardware Error]: Error 0, type: corrected [30200989.742571] {1}[Hardware Error]: section type: unknown,330f1140-72a5-11df-9690-0002a5d5c51b [30200989.742578] {2}[Hardware Error]: Hardware error from APEIGeneric Hardware Error Source: 0 [30200989.742580] {2}[Hardware Error]: It has been corrected by h/wand requires no further action [30200989.742608] {2}[Hardware Error]: event severity: corrected [30200989.742609] {2}[Hardware Error]: Error 0, type: corrected [30200989.742610] {2}[Hardware Error]: fru_text: A5 [30200989.742614] {2}[Hardware Error]: section_type: memory error [30200989.742615] {2}[Hardware Error]: error_status:0x0000000000000400 [30200989.742617] {2}[Hardware Error]: physical_address:0x0000000f98cf5fc0 [30200989.742619] {2}[Hardware Error]: node: 1 card: 1 module: 0rank: 1 bank: 1 row: 42861 column: 192 [30200989.742621] {2}[Hardware Error]: error_type: 13, scrubcorrected error [30200989.742623] {2}[Hardware Error]: DIMM location: not present.DMI handle: 0x0000 [30200989.742655] EDAC skx MC1: HANDLING MCE MEMORY ERROR [30200989.742661] EDAC skx MC1: CPU 0: Machine Check Event: 0 Bank1: 940000000000009f [30200989.742672] EDAC skx MC1: TSC 105192b3d65b124 [30200989.742674] EDAC skx MC1: ADDR f98cf5fc0 [30200989.742675] EDAC skx MC1: MISC 0 [30200989.742677] EDAC skx MC1: PROCESSOR 0:50654 TIME 1557145393SOCKET 0 APIC 0 [30200989.742694] EDAC MC1: 0 CE memory read error onCPU_SrcID#0_MC#1_Chan#1_DIMM#0 (channel:1 slot:0 page:0xf98cf5offset:0xfc0 grain:32 syndrome:0x0 - err_code:0000:009f socket:0imc:1 rank:1 bg:3 ba:1 row:a362 col:1a8) [30200989.744952] __get_any_page: 0xf98cf5 free huge page [30201088.985651] mce: [Hardware Error]: Machine check eventslogged
linux使用edac_util輸出確認故障硬件位置 mc1: csrow0: CPU_SrcID#1_Ha#0_Chan#0_DIMM#0: 1 Corrected Errors
-
[root@zxl]# edac-util -v mc0: 0 Uncorrected Errors with no DIMM info mc0: 0 Corrected Errors with no DIMM info mc0: csrow0: 0 Uncorrected Errors mc0: csrow0: CPU_SrcID#0_Ha#0_Chan#0_DIMM#0: 0 Corrected Errors mc0: csrow0: CPU_SrcID#0_Ha#0_Chan#1_DIMM#0: 0 Corrected Errors mc0: csrow0: CPU_SrcID#0_Ha#0_Chan#2_DIMM#0: 0 Corrected Errors mc0: csrow0: CPU_SrcID#0_Ha#0_Chan#3_DIMM#0: 0 Corrected Errors mc1: 0 Uncorrected Errors with no DIMM info mc1: 0 Corrected Errors with no DIMM info mc1: csrow0: 0 Uncorrected Errors mc1: csrow0: CPU_SrcID#1_Ha#0_Chan#0_DIMM#0: 1 Corrected Errors mc1: csrow0: CPU_SrcID#1_Ha#0_Chan#1_DIMM#0: 0 Corrected Errors mc1: csrow0: CPU_SrcID#1_Ha#0_Chan#2_DIMM#0: 0 Corrected Errors mc1: csrow0: CPU_SrcID#1_Ha#0_Chan#3_DIMM#0: 0 Corrected Errors
-
相關鏈接
