對查詢一款硬體伺服器電源狀態問題的探究

來源:互聯網
上載者:User

發現自己寫的文章有點像是科技小品文,沒有太多的技術含量,讀起來也沒太大難度,甚至可能像清水煮白菜,沒什麼味道。但是文章中的這些問題確實是在工作中碰到的,經過無數的google,或者向同事請教才解決的。自己經曆的痛苦可能還會有人遇到,所以,為了”中國夢“的早日實現,無論如何,也要把這些問題還是記錄下來,希望對他人能有所協助。不積跬步無以至千裡,相信總有一天豬也會飛起來的
這個問題我曾經在ChinaUnix上求助過,可能發的版面不對,幾個月也沒有人解答,後來老大幫忙求助了驅動部門的人,問題很快有了答案。
問題很簡單:我們需要監控x86-64 Linux伺服器的電源狀態,看看兩個電源是否都正常工作,如果有一個壞了,要發警示上來。
記得開始的時候自己查遍了Linux的操作文檔,想找到一個命令或者從一個檔案中能夠直接把電源狀態讀出來,甚至把拔插電源前後的linux目錄也比較了一遍,可是找了半天也沒點線索,憑什麼查CPU、記憶體都有命令,查個電源就沒命令呢?後來發現這個可能真沒有!

自己不懂驅動,更不懂硬體,拿到別人寫的指令碼,不能稀裡糊塗地用,試圖能搞得明白點。後面是自己的理解,錯誤之處還請海涵。

首先明白的一點是,這個方案也不是通用的,電源狀態因硬體而異,不同伺服器會有不同的方式。
我們用的硬體使用的是I2C匯流排... 什嗎?I2C是什麼也不知道?那太好了,跟我一樣,下面翻譯點海外資料。
資訊來源:http://www.esacademy.com/en/library/technical-articles-and-documents/miscellaneous/i2c-bus.html
I2C匯流排協議
I2C匯流排物理上由兩根活性線和一根地線組成。活性線,分別叫做SDA和SCL,都是雙向工作的。SDA是串列資料線,SCL是串列時鐘線。
每一個串連到匯流排的裝置都有它自己的地址,不管它是MCU,LCD驅動,記憶體,或者ASIC。每一個晶片既可以作為接受方,也可以作為發送方,或者二者兼具,這取決於它們的功能。很明顯,LCD驅動只是一個接收方,而記憶體或者I/O晶片可以同時做發送方或者接收方。
I2C匯流排是一個multi-master的匯流排,也就是說不止一個能夠發起資料轉送命令的IC可以串連到它上面。I2C規範說,發起資料轉送的IC就可以認為是匯流排的Master,其它的所有IC就被看作是匯流排的Slave。
由於bus master通常是微控制器,讓我們來看一下一個常見的“IC間的對話”。考慮下面的設定,假設MCU想發送資料給一個slave。


首先,MCU發送一個START狀態。這像是給所有串連的裝置發送了一個“立正”的命令,匯流排上所有IC將監聽即將到來的資料。
接著,MCU發送了一個它想訪問的ADDRESS命令,同時帶有是讀還是寫的資訊(假設是寫)。收到這個地址後,所有IC都會將之與自己的地址比對,如果不匹配的話,它們只是簡單地等待直到發送STOP狀態後匯流排被釋放;然而如果是匹配的話,這個晶片就要發送一個ACKNOWLEDGE的訊號來回應。
一旦MCU收到了ACKNOWLEDGE就開始收發資料。在我們的例子中,MCU將發送資料。這都做完以後,MCU發送一個STOP狀態。這個訊號表示匯流排被釋放了,IC們可以等待下一個傳輸請求了。
我們的例子中包括了好幾個指令:START,ADDRESS,ACKNOWLEDGE,DATA,STOP。這些在匯流排上都是獨一無二的狀態。在我們想進一步探究匯流排狀態之前,我們需要瞭解一點物理結構和匯流排的硬體知識。

==============華麗麗的分割線==================
Linux的I2C工具以前是作為lm-sensors的一部分,現在已經拆分為獨立的軟體包。原因是並非所有硬體監控晶片都是I2C裝置,I2C裝置也不都是硬體監控晶片,所以把所有東西放在一起有些不太合理。因為I2C工具是在核心實現的,所以所有Linux版本都會支援。
我們的伺服器可能有多條I2C匯流排,電源控制器串連在其中一條上。電源熱拔插後,狀態資訊會在儲存在電源控制器中,我們要做的就是通過I2C匯流排找到電源控制器的地址然後把資料讀出來,這個工作由i2cget命令完成。
i2cget [-y] i2cbus chip-address [data-address [mode]]
-y去使能互動模式,使用指令碼時需要加這個參數,避免確認資訊。參數i2cbus表示需要掃描的I2C匯流排號,這個號必須在i2cdetect -l的列表當中; chip-address指定匯流排上那個晶片的地址,範圍是0x03到0x77;data-address指定晶片上要讀取資料的地址,範圍是0x00到0xFF;mode如果指定的話表示讀寫入模式,不帶這個參數預設情況是唯讀模式。

指令碼片段:

# Check for i2c-toolsif [ ! -f /usr/sbin/i2cget ] ; then   echo -e "\nError: i2c-tools are required for this monitoring tool."   exitfi# Check for lm_sensors# Load i2c_dev modules if not loadedif [ "`lsmod | grep -c i2c_dev`" == 0 ] ; then        modprobe i2c_dev 2> /dev/nullfi# Query for PS modules, 250w PS registered at i2c address 0x20ps_status=`i2cget -y 0 0x20 0x00 2> /dev/null`if [ "$ps_status" == "" ] ; then      echo -e "\nError: PS module not responding, check i2c/lm_sensors setup."      exitfiecho -e "\nSystem Power Supply Status:"echo -e "---------------------------\n"# Parse PS1 Bottom power supply module status# Bit 0 = PS1 FAN status (0 = normal, 1 = fail)let "ps_fan=$ps_status&1"# Bit 1 = PS1 OTP (0 = normal, 1 = Over 55C, shuts off at 65C)let "ps_otp=$ps_status&2"# Bit 2 = PS1 PG (1 = Power good, 0 = Power good failed)let "ps_pg=$ps_status&4"# Bit 3 = PS1 Present (0 = PS detected on backplane, 1 = PS not present)let "ps_present=$ps_status&8"# Print PS1 resultsif [ "$ps_present" == "0" ] ; then        echo -en "PS1 BTM MODULE:\tPRESENT\nPS1 FAN STATUS:\t"        if [ "$ps_fan" == "0" ] ; then echo "GOOD"        else echo "FAILED"        fi        if [ "$ps_otp" == "0" ] ; then echo -e "PS1 OTP:\tGOOD (<55C)"        else echo -e "PS1 OTP:\tFAILED (>55C)"        fi        if [ "$ps_pg" == "0" ] ; then echo -e "PS1 POWER:\tFAILED"        else echo -e "PS1 POWER:\tGOOD"        fielse        echo -e "PS1 BTM MODULE:\tNOT DETECTED"fi# Parse PS2 Top power supply module status# Bit 4 = PS2 FAN status (0 = normal, 1 = fail)let "ps_fan=$ps_status&16"# Bit 5 = PS2 OTP (0 = normal, 1 = Over 55C, shuts off at 65C)let "ps_otp=$ps_status&32"# Bit 6 = PS2 PG (1 = Power good, 0 = Power good failed)let "ps_pg=$ps_status&64"# Bit 7 = PS2 Present (0 = PS detected on backplane, 1 = PS not present)let "ps_present=$ps_status&128"# Print PS2 resultsif [ "$ps_present" == "0" ] ; then        echo -en "\nPS2 TOP MODULE:\tPRESENT\nPS2 FAN STATUS:\t"        if [ "$ps_fan" == "0" ] ; then echo "GOOD"        else echo "FAILED"        fi        if [ "$ps_otp" == "0" ] ; then echo -e "PS2 OTP:\tGOOD (<55C)"        else echo -e "PS2 OTP:\tFAILED (>55C)"        fi        if [ "$ps_pg" == "0" ] ; then echo -e "PS2 POWER:\tFAILED"        else echo -e "PS2 POWER:\tGOOD"        fielse        echo -e "\nPS2 TOP MODULE:\tNOT DETECTED"fi

電源狀態取出來了發個警示就簡單了,不再贅述。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.