歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Ubuntu中Load/Unload Cycle Count問題及解決

Ubuntu中Load/Unload Cycle Count問題及解決

日期:2017/2/28 16:14:01   编辑:Linux教程

說明:本文所描述的問題只在筆記本硬盤中才會出現。

1. 問題描述

幾周前收到soldiers童鞋的短信說,Ubuntu傷硬盤?我說沒事,好多人都用呢。過了一周,soldiers童鞋又問,Ubuntu傷硬盤?我說我查查看….

# 安裝smart參數查看工具,由此可以查看硬盤的smart信息
$ sudo apt-get install smartmontools

# 查看/dev/sda這塊硬盤的smart參數, 你可能需要把/dev/sda這部分修改成你的硬盤設備地址
# grep 193是只查看 Load Cycle Count這項
$ sudo smartctl -a /dev/sda | grep 193
193 Load_Cycle_Count 0×0012 090 090 000 Old_age Always - 109989

這樣就可以看到Load/Unload Cycle Count數目了。用Windows的童鞋可以借助Everest工具,查看存儲器->SMART信息,也可以找到相應項的數據。

不看不知道,一看嚇一跳,我的是華麗的11W!!! T.T 據說到了60W,就離掛掉不遠了。我才用了4個月,算下來照這個速度用下去的話,只能用4*60/10/12=2年…. 同寢的Acrest童鞋的也過了10W大關哈哈哈。

$ while true; do sudo smartctl -a /dev/sda | grep 193; sleep 300; done;

這樣可以每隔5分鐘查詢一下LCC,一般來說每小時增長在15上下應該是正常的。這樣的話即便你每天24小時開著本子,硬盤也可以堅持4年(當然是從理論上來講)。

1.1 這個Load/Unload Cycle Count到底是什麼?

Load/Unload Cycle Count(以下簡稱為LCC)就是Load/Unload的次數,那麼什麼叫做Load/Unload呢,下面是一段非常羅嗦的解釋,建議不感興趣的同學出門右轉,直接看下一節吧。

大家都知道,硬盤的數據傳輸是通過磁頭讀寫磁盤上的數據來完成的。在工作過程中,磁頭並不與磁盤的盤面直接接觸,兩者之間有一層很薄的空氣薄膜,這層空氣薄膜是由於磁盤的高速旋轉產生的。如果磁盤停止旋轉,空氣薄膜消失,磁頭則會直接接觸到盤片,更詳細一點說,會接觸到盤片的landing zone,或者叫做start/stop zone,這無疑對盤片的壽命以及對存儲在這塊區域的數據造成不好的影響。因此在早期階段,硬盤制造商一般會在對盤片的表面或landing zone部分做特殊的處理,並盡量避免在landing zone存儲數據。

但是隨著人們對於硬盤傳輸速度和硬盤容量需求的不斷增加,制造商需要不斷提高硬盤的面密度,同時要求盤片表面盡可能地平滑,這無疑與之前采用的技術產生了沖突,再加上其他的一些因素,硬盤制造商迫切地需要一種新的方式來替代之前采用的磁頭直接接觸盤面的行為。這時IBM的工程師們提出了一種叫做Load/Unload的技術。簡單來說,Load/Unload技術有點像老式的點唱機,當盤片轉速降低無法再產生空氣薄膜的時候,就將磁臂以及磁頭旋轉一下,停靠到磁盤旁邊的一個小斜坡上。這樣就完全避免了磁頭與盤片的直接接觸。

總體來說,Load/Unload技術是有利的,比如可以提高硬盤的可靠性:硬盤遭到撞擊的時候磁頭不會劃傷盤面;可以提高硬盤的面密度:不再需要對盤片表面做特殊的處理,可以提供平滑的盤面;以及可以有效地降低功耗:低功耗的程序可以通過多次請求Load/Unload來減少盤片的旋轉時間,或者設置旋轉超時時間(spin down timeout)來讓磁頭定期的做Load/Unload等等。

1.2 這個參數值高了有啥危害?

雖然Load/Unload技術有很多優點,但毫無疑問頻繁的Load/Unload操作會造成磁頭的磨損,嚴重的話會造成數據讀寫失效,也就說,硬盤掛了。

那麼到底Load/Unload多少次會掛呢?最流行的說法是到60W次,西部數據的一份產品規格說明書上也明確標示出了這一數字。

但也有人指出SMART參數根本就是扯淡,好多壞掉的硬盤SMART值很低好的硬盤SMART值超標,因此根本不能成為評判標准以至於現在好多新機器都直接屏掉。但無論如何,頻繁地卸載/掛載總不是什麼好事。尤其是當你已經了解到Load/Unload次數過多有可能造成硬盤掛掉的時候,我想無論再有人辟謠,你也不會高枕無憂了。畢竟相對於硬盤本身來說,上面的數據可是要重要的多。

1.3 LCC為啥會那麼高?

簡單來說,可能有下面幾個原因:

1) 硬盤廠商在固件中制定的節能策略過於苛刻,以至於為了節能,硬盤頻繁地Load/Unload
2) 操作系統的電源策略過於苛刻。

1.4 其他的發行版有沒有這個問題?Windows呢,MAC OS呢?

各大linux發行版好像就Ubuntu被報告有這個問題,但這實際上並不是Ubuntu的電源策略太變態,恰恰相反,默認情況下Ubuntu會直接沿用硬件固件裡面的設定。其他的發行版中SUSE也有類似的電源管理的BUG,初次之外的發行版似乎默認會忽略硬盤的這個節能功能,所以不會有類似的問題。

至於Windows,也會出現類似的現象,比如說我宿捨的Acrest童鞋,但我的沒有。
MAC OS也有報告出現類似的問題。

總體來說這個並不是個別現象,也並不應該算是操作系統的問題。感覺由於Windows下硬盤幾乎會一直不停地運作,所以硬件廠商不太重視硬盤固件中的初始設定,比如說我的日立硬盤,電源管理級別被設置為128,結果由於Linux並不像Windows那樣頻繁讀盤,磁頭為了節能會頻繁地做Load/Unload操作。

2. 如何修復這個問題?

2.1 硬件修改法 (***推薦使用***)

正如上面所說,如果你的硬盤在Ubuntu下有這個問題,那麼有可能是硬件本身的節能策略太激進了。最簡單也是最根本的方法,就是用廠商提供的固件修改工具對出廠的默認設置進行修改,比如說日立的Feature Tools。

在Feature Tools中,有一項"Change Advanced Power Mode",默認是128,可以選擇從1到254不同的數值。

簡單來說,數字越小越節能,數字越大性能越好。Feature Tools中將1-254分成三段並分別做了簡單的說明,一般來說,設置到192-254則表示不允許Load/Unload操作,而255則表示禁用APM(Advanced Power Management)。這個數字也就是後文提到的APM級別。

2.2 軟件修改法

修改硬盤固件是最根本的解決方案,除此之外,關於在Ubuntu中修改相關策略,網上有很多種不同的解法,有興趣的童鞋可以看關於這個Bug的討論, Ubuntu Wiki上關於這個Bug的介紹起因分析以及解決方案的總結等。基本上流傳的方法有這麼兩種:

2.2.1 啟用laptop-mode,通過修改laptop-mode.conf中的相關設置達到控制Load/Unload的目的

2.2.2 直接在/etc/acpi/start.d, resume.d等目錄下放置腳本,通過hdparm命令修改APM級別和spin down time.

具體內容見文後附注。歸根結底,這兩種方法都是利用hdparm工具,通過-B參數修改高級電源管理(APM)級別,通過-S參數修改旋轉超時時間(Spin Down Timeout),從而控制硬盤的Load/Unload次數。所謂APM級別就是我們上面介紹過的1~255,而Spin-down Timeout就是指硬盤空閒(或者旋轉?這個拿不准)多久後才會Spin Down,也就是停轉,做Unload操作。相對應的,有一個Spin up Time,這是指硬盤重新啟動到正常運轉所需要的時間。

Windows下也有一款HDDScan軟件可以很方便地做到這一點。這樣的軟件改法確實有效,但由於hdparm不會將設置寫入固件,因此在關機、休眠以及待機之後,由於硬盤掉電,這些通過軟件的設置會失效,需要重新啟用一次。目前這兩種方法在我的機器上的測試結果是待機喚醒之後參數不會重新啟用。實際上,laptop-mode只會在開機的時候才會應用我們設定的參數,而acpi的resume.d目錄下放置的腳本並不會被執行,不知道這是不是個別現象。 所以如果大家非要用軟件的修改方法時,推薦下面這一種。

2.2.3 pm.utils大法 (推薦使用)

除了這兩種修改方法之外,還有另外一種通過pm.utils來調用hdparm的方法。這實際上是Suse的一個解決方案。pm.utils全稱是Power Management Utilities,與acpi類似,它可以通過加入Hook腳本的方法在待機、休眠和喚醒的時候修復一些待機/休眠方面的Bug或者實現某些特定的功能。pm.utils很有可能會在8.10中就取代acpi,所以從這個意義上來講這個方案也會有更長的效用。具體步驟如下:

1) 首先做一些配置,主要就是設置省電模式開啟和關閉的模式下hdparm的參數,具體的內容腳本中有注釋。

你可能需要將“/dev/sda"修改成你的硬件設備,比如你有兩個硬盤,可以修改為"/dev/sda /dev/sdb"。

$ sudo vi /etc/pm/config.d/disk

# Configure disk power management settings to ensure both
# long disk life and good power management.
#
# Space delimited list of disk devices this affects.
#
DEVICES_DISK_PM_NAMES="/dev/sda"
#
#
# Power management modes
#
# Powersave mode off
# Set APM as 192
# Set spin-down for 30 minutes
#
DEVICES_DISK_PM_POWERSAVE_OFF="hdparm -q -B 192 -q -S 241 -q -M 128"
#
# Powersave mode on
# Enable APM to conservative 192 and set spin-down for 21 minutes
#
DEVICES_DISK_PM_POWERSAVE_ON="hdparm -q -B 192 -q -S 252 -q -M 128"

2) 在power.d中加入Hook腳本,作用是在使用電池和AC電源的時候可以自動切換省電模式。

$ cd /etc/pm/power.d
$ sudo vi disk

#!/bin/bash
. /usr/lib/pm-utils/functions
. /etc/pm/config.d/disk

if test -z "${DEVICES_DISK_PM_NAMES}"; then
exit 1
fi

case "$1" in
true)
echo "**enabled pm for harddisk"
for DISK_NAME in `echo ${DEVICES_DISK_PM_NAMES}`; do
${DEVICES_DISK_PM_POWERSAVE_ON} ${DISK_NAME}
done ;;
false)
echo "**disabled pm for harddisk"
for DISK_NAME in `echo ${DEVICES_DISK_PM_NAMES}`; do
${DEVICES_DISK_PM_POWERSAVE_OFF} ${DISK_NAME}
done ;;
esac

$ sudo chmod +x disk

3) 在sleep.d中加入腳本,目的是在休眠/待機之後喚醒的時候重新設定hdparm的參數:

$ cd /etc/pm/sleep.d/
$ sudo vi disk

#!/bin/bash
. /usr/lib/pm-utils/functions
. /etc/pm/config.d/disk

if test -z ${DEVICES_DISK_PM_NAMES}; then
exit 1
fi

case "$1" in
thaw|resume)
/usr/bin/on_ac_power;
if [ "$?" -eq 0 ]; then
echo "**disabled PM for harddisk"
for DISK_NAME in `echo ${DEVICES_DISK_PM_NAMES}`; do
${DEVICES_DISK_PM_POWERSAVE_OFF} ${DISK_NAME}
done
elif [ "$?" -eq 1 ]; then
echo "**enabled PM for harddisk"
for DISK_NAME in `echo ${DEVICES_DISK_PM_NAMES}`; do
${DEVICES_DISK_PM_POWERSAVE_ON} ${DISK_NAME}
done
fi
;;
esac

$ sudo chmod +x disk

***注意最後一定要為disk腳本添加執行權限。否則pm.tuils不會自動執行這段腳本

4) 如果你沒有啟用laptop mode (默認是不啟用的),可以跳過這部分了。

由於Ubuntu中acpi和pm.utils是共存的,所以如果你啟用了laptop mode,那麼在改變電源狀態(指電池->AC電源或者反之)的時候,acpi會在啟用/停用laptop mode的同時設置hdparm參數,會覆蓋掉pm-utils所做的設置。

所以如果你啟用了laptop mode的話,需要做如下修改:

1′ $ sudo vi /etc/default/acpi-support

將最後的

SPINDOWN_TIME=12

修改為

SPINDOWN_TIME=241

2′ $ sudo vi /etc/acpi/power.sh

將function laptop_mode_enable部分的

$HDPARM -B 1 /dev/$drive 2>/dev/null

修改成

$HDPARM -B 192 /dev/$drive 2>/dev/null

上述的解決方案在Dell Inspiron 700m + Ubuntu 8.04.1上測試通過。在待機喚醒之後參數會重新被設置,但是由於我的機器上休眠有問題,所以沒有辦法測試休眠。但理論上來也是可以的。

3. 我想定期檢測Load_Cycle_Count,怎麼辦?

好辦,這裡是一個腳本,具體用法在注釋裡面粗體標明了。(不好意思…注釋好像比代碼都長)

#!/bin/bash
#
# @Description:
#
# check_lcc v0.2
#
# Check Load_Cycle_Count from S.M.A.R.T info of your hard drive
# when power on and off and Save them to $FILE in following format:
#
# LCC TIME
# ON 110044 18:05:00 2008-09-08
# OFF 110044 18:10:03 2008-09-08
#
# "ON" indicates POWER ON while "OFF" indicates POWER OFF, LCC is
# exactly Load_Cycle_Count of your hard drive at TIME.
#
# @Usages:
#
# 1. sudo vi /etc/init.d/check_lcc
# 2. copy all the contents of this script to it
# *** Note that u need to modify "FILE" as what u want.
# save and quit.
# 3. sudo chmod +x /etc/init.d/check_lcc
# 4. sudo update-rc.d check_lcc start 1 2 . stop 99 0 6 .
# 5. Have fun.
#
# This script was tested under Ubuntu 8.04.1.
#
# @Author:
#
# [email protected]
# 2008/09/07

FILE="/home/bread/lcc_report.txt"
STAT=`smartctl -a /dev/sda | grep 193 | sed -nr "s/.*[[:space:]]([[:digit:]]{1,})$/\1/p"`"\t "`date +’%T %F’`

case "$1" in
start)
STAT="ON \t"$STAT
;;
stop)
STAT="OFF\t"$STAT
;;
*)
echo "Usages: $0 {start|stop}" >&2
exit 2
;;
esac

echo -e $STAT >> $FILE

按照上面的說明操作之後,LCC的結果就會存在你定義的log文件裡面了。可以定期打開查看。

4. 最後附上之前的兩種方法,啟用laptop mode和添加acpi腳本。

4.1. 加入acpi腳本

1) 為使用電源和電池的時候定制不同的hdparm參數。你可能需要把/dev/sda修改成你的硬盤設備。

$sudo vi 99-hdd-ugly-fix.sh

#!/bin/bash
if on_ac_power; then
# on AC so don’t do any head parking
hdparm -B 254 /dev/sda # you might need 255 or a different value
else
# either on battery or power status could not be determined
# so quickly park the head to protect the disk
hdparm -B 192 /dev/sda
fi

2) 將如上腳本安裝到如下4個地方

$sudo install 99-hdd-ugly-fix.sh /etc/acpi/resume.d/
$sudo install 99-hdd-ugly-fix.sh /etc/acpi/start.d/
$sudo install 99-hdd-ugly-fix.sh /etc/acpi/ac.d/
$sudo install 99-hdd-ugly-fix.sh /etc/acpi/battery.d/

這個方案比開啟laptop簡單且方便。因此如果你實在是不想用pm.utils的時候,推薦使用這種方法。

4.2. 啟用laptop mode

Ubuntu 8.04測試有效,但是待機/休眠喚醒之後設置會丟失。laptop mode 模塊在Ubuntu 8.04中是默認包含的,只是沒有啟用。下面是具體的設置方法。

1) /etc/default/acpi-support中修改

# 啟用laptop模式
ENABLE_LAPTOP_MODE=true

# 將spin down 時間改成 (241-240)*30min = 30min
# spin down time決定硬盤閒置多久以後關閉主軸電動機以節省功耗,0表示永遠不關閉
# 具體的解釋看 man hdparm的-S部分
SPINDOWN_TIME=241

2) /etc/laptop-mode/laptop-mode.conf中修改

# 即便是接上電源也用laptop mode
ENABLE_LAPTOP_MODE_ON_AC=1

# 顯示器關閉的時候也用laptop mode
ENABLE_LAPTOP_MODE_WHEN_LID_CLOSED=1

# 讓laptop mode控制硬盤閒置多長時間才卸載
CONTROL_HD_IDLE_TIMEOUT=1

# 改成半小時
LM_AC_HD_IDLE_TIMEOUT_SECONDS=1800
LM_BATT_HD_IDLE_TIMEOUT_SECONDS=1800
NOLM_HD_IDLE_TIMEOUT_SECONDS=7200

# 讓laptop mode來控制硬盤的電源管理
CONTROL_HD_POWERMGMT=1

# 192表示不關閉,從128-254都表示不關閉,越大能耗越大
# 具體可以 man hdparm 看-B
BATT_HD_POWERMGMT=192
LM_AC_HD_POWERMGMT=254
NOLM_AC_HD_POWERMGMT=254

3) /etc/acpi/power.sh中

把 "$HDPARM -B 1 /dev/$drive 2>/dev/null"
修改為 "$HDPARM -B 192 /dev/$drive 2>/dev/null"

4) 禁用pm.utils的部分功能

$ sudo chmod -x /usr/lib/pm-utils/power.d/laptop-tools

否則laptop-mode不會隨機啟動。

5) 重啟後,cat /proc/sys/vm/laptop_mode

結果是2表示laptop-mode已經啟動,是0表示還未啟動,請仔細檢查上面的設置是否有遺漏。

###############我是很郁悶的分割線###############

附:關於為啥要禁用pm.utils,具體的解釋如下:

我從網上找到了laptop mode的解決方案之後,按照說明一步步操作,但是重新啟動之後,查看cat /proc/sys/vm/laptop_mode,發現仍然是0.(是2才表示已經啟動)。查看/etc/rc2.d/目錄下確實有S99laptop-mode,這說明系統確實會加載這個服務(這個目錄下的文件都是個符號鏈接,會鏈接到/etc/init.d目錄下的同名腳本)。後來Google了一下發現這樣的解釋:

首先來說/proc/sys/vm/laptop_mode這個變量和初始化進程laptop-mode並不是一個意思。前者是個內核控制的變量,作用是將磁盤寫操作聚簇,後者是一個腳本。

其次,Hardy加入了pm-utils,會覆蓋或忽略一部分根據linux傳統的配置。為了解決這個問題,可以修改/usr/lib/pm-utils/power.d/laptop-tools中相關的內容或者運行下述命令:

$ sudo chmod -x /usr/lib/pm-utils/power.d/laptop-tools

這條命令會禁用pm-utils的部分功能,從而修復你所遇到的問題(指laptop-mode不會隨機啟動)。注意得重啟以後設置才會生效。

實際上pm-utils盲目地覆蓋掉laptop-mode或者是/etc/sysctl.conf中的配置,所以chmod -x禁用相關腳本後, 在從AC POWER轉到電池供電的時候,pm-utils就不會執行相關的腳本(laptop-tools),從而也就不會覆蓋相關的設置。這種做法改動最小,如果之後你想重新啟用pm-utils的這部分功能,只需要chmod +x就可以了。

###############很郁悶的分割線又來啦###############

5. 最後

折騰這個問題費了我一整天(實際上是半天,不過那天我中午才起…),總結這些破爛方法,再加上反復試驗確定某個方法是否有效,硬著頭皮分析腳本的功能,零零碎碎加起來也有一整天的時間,再加上寫這篇總結,又花去一整天加上兩節入學教育的時間(罪過啊罪過啊)。到此為止距離開始解決這個問題就已經過去整整一周了。就這還沒總結全,好多東西都還沒有寫上來。不過倒是學到了不少東西,硬盤的原理是確確實實復習了一遍了又,另外學了些寫Shell腳本的技巧以及ACPI和pm.utils的機制。感覺系統裡面同時有倆搞電源管理的東西實在是太FT了,因為會有沖突的部分,好在據說Intrepid要搞掉acpi只用pm.utils,也許會清淨一些。

無論如何總算是寫完了。一邊實驗一邊記錄,一度想放棄了(實在是太費時間,感覺也沒太大的意義),但一個是為了我的寶貝硬盤考慮(錢啊錢啊!),又覺得折騰了那麼多不記錄下來,功夫不就都白費了。正好今天有兩節入學教育,於是就勇敢地抱本過去,寫完最後一段哈哈哈。

貼到這裡,希望會對遇到這個問題的人有所幫助。

Copyright © Linux教程網 All Rights Reserved