如何使用筆記本模式節約電池電量¶
文件作者: Bart Samwel (bart@samwel.tk)
建立日期: 2004年1月2日
最後修改: 2004年12月6日
簡介¶
筆記本模式旨在最大限度地減少硬碟啟動所需的時間,以節約筆記型電腦的電池電量。據報道,它能顯著節約電量。
安裝¶
要使用筆記本模式,您無需設定任何核心配置選項。只需安裝本文件中包含的所有檔案,當您使用電池供電時,筆記本模式將自動啟動。為了您的方便,包含安裝程式的 tar 包可從以下地址下載:
要配置筆記本模式,您需要編輯配置檔案,該檔案在基於 Debian 的系統上位於 /etc/default/laptop-mode,在其他系統上位於 /etc/sysconfig/laptop-mode。
不幸的是,對於不具備 ACPI 的筆記型電腦,筆記本模式的自動啟用功能不起作用。在這些筆記型電腦上,您需要手動啟動筆記本模式。要啟動筆記本模式,執行“laptop_mode start”,要停止它,執行“laptop_mode stop”。(注意:筆記本模式工具包現在已實驗性支援 APM,您可能想先嚐試一下。)
注意事項¶
筆記本模式的缺點是您有可能丟失長達 10 分鐘的工作內容。如果您無法承受這種損失,請不要使用它!提供的 ACPI 指令碼在電池電量幾乎耗盡時會自動關閉筆記本模式,這樣您就不會在電池壽命結束時丟失任何資料。
大多數桌上型電腦硬碟的壽命(以主軸停轉週期衡量)非常有限,通常約為 50,000 次(這通常列在規格表中)。檢查您硬碟的額定值,如果您不需要,請不要縮短硬碟的壽命。
如果您使用 -n 選項掛載了部分 ext3/reiserfs 檔案系統,則控制指令碼將無法正確地重新掛載它們。您必須在控制指令碼中設定 DO_REMOUNTS=0,否則它將使用錯誤的選項重新掛載它們——或者因為它無法寫入 /etc/mtab 而失敗。
如果您的檔案系統在 fstab 中被列為“auto”型別(就像我曾經那樣),那麼控制指令碼將不會識別它們為需要重新掛載的檔案系統。您必須改為列出檔案系統的實際型別。
據報道,某些版本的 mutt 郵件客戶端會使用檔案訪問時間來判斷資料夾是否包含新郵件。如果您使用 mutt 並遇到此問題,則必須透過在配置檔案中將選項 DO_REMOUNT_NOATIME 設定為 0 來停用 noatime 重新掛載。
詳情¶
筆記本模式由 /proc/sys/vm/laptop_mode 旋鈕控制。所有打有筆記本模式補丁的核心都存在此旋鈕,無論任何配置選項如何。當此旋鈕設定後,任何物理磁碟 I/O(可能導致硬碟啟動)都會使 Linux 重新整理所有髒塊。其結果是,硬碟在停轉後將不再因為寫入髒塊而啟動,因為這些髒塊在最近的讀取操作之後就已經立即寫入了。laptop_mode 旋鈕的值決定了磁碟 I/O 發生與重新整理觸發之間的時間。該旋鈕的合理值為 5 秒。將此旋鈕設定為 0 會停用筆記本模式。
為了提高 laptop_mode 策略的效率,laptop_mode 控制指令碼會將 /proc/sys/vm 中的 dirty_expire_centisecs 和 dirty_writeback_centisecs 增加到大約 10 分鐘(預設),這意味著髒頁不會被迫頻繁地寫入磁碟。控制指令碼還會改變髒背景比率,這樣髒頁的後臺回寫就不再執行了。結合 ext3 或 ReiserFS 檔案系統的更高提交值(同樣是 10 分鐘,也由控制指令碼自動完成),這將導致磁碟活動集中在一個短時間間隔內,每 10 分鐘只發生一次,或者當磁碟因快取未命中而被強制啟動時發生。然後,磁碟可以在不活動期間停轉。
配置¶
筆記本模式配置檔案在基於 Debian 的系統上位於 /etc/default/laptop-mode,在其他系統上位於 /etc/sysconfig/laptop-mode。它包含以下選項:
MAX_AGE
您可接受的硬碟停轉最長時間(以秒為單位)。最壞的情況下,如果您的電池在筆記本模式下發生故障,您可能會丟失這段時間的工作內容。
MINIMUM_BATTERY_MINUTES
如果電池剩餘電量低於此值,則自動停用筆記本模式。預設值為 10 分鐘。
AC_HD/BATT_HD
在筆記本模式啟用時 (BATT_HD) 和非啟用時 (AC_HD) 應設定的硬碟空閒超時時間。BATT_HD 的預設值為 20 秒(值 4),AC_HD 的預設值為 2 小時(值 244)。可能的值是“hdparm”手冊頁中“ -S”選項所列出的值。
HD
筆記本模式應調整停轉超時時間的裝置。預設值為 /dev/hda。如果您指定多個裝置,請用空格分隔。
READAHEAD
筆記本模式啟用時,磁碟預讀量,以 512 位元組扇區為單位。較大的預讀量可以防止對可執行頁面(應用程式執行時按需載入)和順序訪問資料(如 MP3 檔案)進行磁碟訪問。
DO_REMOUNTS
控制指令碼會自動重新掛載所有已掛載的日誌檔案系統,並使用適當的提交間隔選項。當此選項設定為 0 時,此功能被停用。
DO_REMOUNT_NOATIME
重新掛載時,檔案系統是否應使用 noatime 選項重新掛載?通常,此選項設定為“1”(啟用),但有些程式可能需要記錄訪問時間。
DIRTY_RATIO
筆記本模式啟用時,在強制回寫之前允許包含“髒”或未儲存資料的記憶體百分比。對應於 /proc/sys/vm/dirty_ratio sysctl。
DIRTY_BACKGROUND_RATIO
由於超出 DIRTY_RATIO 而強制回寫之後,允許包含“髒”或未儲存資料的記憶體百分比。請將其設定得較低。這對應於 /proc/sys/vm/dirty_background_ratio sysctl。
請注意,當筆記本模式處於活動狀態和非活動狀態時,dirty_background_ratio 的行為會大相徑庭。當筆記本模式非活動時,dirty_background_ratio 是後臺寫入開始發生的閾值百分比。然而,當筆記本模式啟用時,後臺寫入被停用,dirty_background_ratio 只決定當達到 dirty_ratio 時完成多少回寫。
DO_CPU
在筆記本模式下啟用 CPU 頻率縮放。(需要設定 CPUFreq。有關更多資訊,請參閱CPU 效能縮放。預設停用。)
CPU_MAXFREQ
當使用電池供電時,系統應使用的最大 CPU 速度是多少?合法值為“slowest”(指 CPU 能夠執行的最低速度),或 /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies 中列出的值。
提示與技巧¶
Bartek Kania 報告稱,透過使用 5 秒的停轉時間 (BATT_HD=1),他額外獲得了長達 50 分鐘的電池續航時間(在他常規的 3 到 3.5 小時基礎上)。
您可以在播放 MP3 時讓磁碟停轉,方法是將磁碟預讀設定為 8MB (READAHEAD=16384)。實際上,磁碟將一次性讀取整個 MP3 檔案,然後在 MP3 播放時停轉。(鳴謝 Bartek Kania。)
Drew Scott Daniels 觀察到:“我不知道為什麼,但是當我減少顯示器使用的顏色數量時,它會消耗更少的電池電量。我在 Powerbook 上也見過這種情況。我希望這條資訊對筆記本模式補丁或其使用者有用。”
在 syslog.conf 中,您可以在條目前加上一個短劃線 -,以省略每次日誌記錄後同步檔案。當您使用筆記本模式且硬碟無法停轉時,這很可能就是原因。
Richard Atterer 觀察到筆記本模式與 noflushd (http://noflushd.sourceforge.net/) 配合不佳,似乎 noflushd 阻止了筆記本模式正常工作。
如果您擔心資料安全,您可能需要考慮使用 USB 儲存棒或類似裝置作為“工作區”。(但請注意,快閃記憶體只能處理有限次數的寫入,過度使用可能會很快耗盡您的儲存棒壽命。切勿在快閃記憶體棒上使用日誌檔案系統。)
控制指令碼和 ACPI 電池指令碼的配置檔案¶
這允許透過外部配置檔案更改指令碼的可調引數
在 Debian 上應將其安裝為 /etc/default/laptop-mode,在 Red Hat、SUSE、Mandrake 及其他類似系統上應安裝為 /etc/sysconfig/laptop-mode。
配置檔案
# Maximum time, in seconds, of hard drive spindown time that you are
# comfortable with. Worst case, it's possible that you could lose this
# amount of work if your battery fails you while in laptop mode.
#MAX_AGE=600
# Automatically disable laptop mode when the number of minutes of battery
# that you have left goes below this threshold.
MINIMUM_BATTERY_MINUTES=10
# Read-ahead, in 512-byte sectors. You can spin down the disk while playing MP3/OGG
# by setting the disk readahead to 8MB (READAHEAD=16384). Effectively, the disk
# will read a complete MP3 at once, and will then spin down while the MP3/OGG is
# playing.
#READAHEAD=4096
# Shall we remount journaled fs. with appropriate commit interval? (1=yes)
#DO_REMOUNTS=1
# And shall we add the "noatime" option to that as well? (1=yes)
#DO_REMOUNT_NOATIME=1
# Dirty synchronous ratio. At this percentage of dirty pages the process
# which
# calls write() does its own writeback
#DIRTY_RATIO=40
#
# Allowed dirty background ratio, in percent. Once DIRTY_RATIO has been
# exceeded, the kernel will wake flusher threads which will then reduce the
# amount of dirty memory to dirty_background_ratio. Set this nice and low,
# so once some writeout has commenced, we do a lot of it.
#
#DIRTY_BACKGROUND_RATIO=5
# kernel default dirty buffer age
#DEF_AGE=30
#DEF_UPDATE=5
#DEF_DIRTY_BACKGROUND_RATIO=10
#DEF_DIRTY_RATIO=40
#DEF_XFS_AGE_BUFFER=15
#DEF_XFS_SYNC_INTERVAL=30
#DEF_XFS_BUFD_INTERVAL=1
# This must be adjusted manually to the value of HZ in the running kernel
# on 2.4, until the XFS people change their 2.4 external interfaces to work in
# centisecs. This can be automated, but it's a work in progress that still
# needs# some fixes. On 2.6 kernels, XFS uses USER_HZ instead of HZ for
# external interfaces, and that is currently always set to 100. So you don't
# need to change this on 2.6.
#XFS_HZ=100
# Should the maximum CPU frequency be adjusted down while on battery?
# Requires CPUFreq to be setup.
# See Documentation/admin-guide/pm/cpufreq.rst for more info
#DO_CPU=0
# When on battery what is the maximum CPU speed that the system should
# use? Legal values are "slowest" for the slowest speed that your
# CPU is able to operate at, or a value listed in:
# /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
# Only applicable if DO_CPU=1.
#CPU_MAXFREQ=slowest
# Idle timeout for your hard drive (man hdparm for valid values, -S option)
# Default is 2 hours on AC (AC_HD=244) and 20 seconds for battery (BATT_HD=4).
#AC_HD=244
#BATT_HD=4
# The drives for which to adjust the idle timeout. Separate them by a space,
# e.g. HD="/dev/hda /dev/hdb".
#HD="/dev/hda"
# Set the spindown timeout on a hard drive?
#DO_HD=1
控制指令碼¶
請注意,此控制指令碼適用於 Linux 2.4 和 2.6 系列(鳴謝 Kiko Piris)。
控制指令碼
#!/bin/bash
# start or stop laptop_mode, best run by a power management daemon when
# ac gets connected/disconnected from a laptop
#
# install as /sbin/laptop_mode
#
# Contributors to this script: Kiko Piris
# Bart Samwel
# Micha Feigin
# Andrew Morton
# Herve Eychenne
# Dax Kelson
#
# Original Linux 2.4 version by: Jens Axboe
#############################################################################
# Source config
if [ -f /etc/default/laptop-mode ] ; then
# Debian
. /etc/default/laptop-mode
elif [ -f /etc/sysconfig/laptop-mode ] ; then
# Others
. /etc/sysconfig/laptop-mode
fi
# Don't raise an error if the config file is incomplete
# set defaults instead:
# Maximum time, in seconds, of hard drive spindown time that you are
# comfortable with. Worst case, it's possible that you could lose this
# amount of work if your battery fails you while in laptop mode.
MAX_AGE=${MAX_AGE:-'600'}
# Read-ahead, in kilobytes
READAHEAD=${READAHEAD:-'4096'}
# Shall we remount journaled fs. with appropriate commit interval? (1=yes)
DO_REMOUNTS=${DO_REMOUNTS:-'1'}
# And shall we add the "noatime" option to that as well? (1=yes)
DO_REMOUNT_NOATIME=${DO_REMOUNT_NOATIME:-'1'}
# Shall we adjust the idle timeout on a hard drive?
DO_HD=${DO_HD:-'1'}
# Adjust idle timeout on which hard drive?
HD="${HD:-'/dev/hda'}"
# spindown time for HD (hdparm -S values)
AC_HD=${AC_HD:-'244'}
BATT_HD=${BATT_HD:-'4'}
# Dirty synchronous ratio. At this percentage of dirty pages the process which
# calls write() does its own writeback
DIRTY_RATIO=${DIRTY_RATIO:-'40'}
# cpu frequency scaling
# See Documentation/admin-guide/pm/cpufreq.rst for more info
DO_CPU=${CPU_MANAGE:-'0'}
CPU_MAXFREQ=${CPU_MAXFREQ:-'slowest'}
#
# Allowed dirty background ratio, in percent. Once DIRTY_RATIO has been
# exceeded, the kernel will wake flusher threads which will then reduce the
# amount of dirty memory to dirty_background_ratio. Set this nice and low,
# so once some writeout has commenced, we do a lot of it.
#
DIRTY_BACKGROUND_RATIO=${DIRTY_BACKGROUND_RATIO:-'5'}
# kernel default dirty buffer age
DEF_AGE=${DEF_AGE:-'30'}
DEF_UPDATE=${DEF_UPDATE:-'5'}
DEF_DIRTY_BACKGROUND_RATIO=${DEF_DIRTY_BACKGROUND_RATIO:-'10'}
DEF_DIRTY_RATIO=${DEF_DIRTY_RATIO:-'40'}
DEF_XFS_AGE_BUFFER=${DEF_XFS_AGE_BUFFER:-'15'}
DEF_XFS_SYNC_INTERVAL=${DEF_XFS_SYNC_INTERVAL:-'30'}
DEF_XFS_BUFD_INTERVAL=${DEF_XFS_BUFD_INTERVAL:-'1'}
# This must be adjusted manually to the value of HZ in the running kernel
# on 2.4, until the XFS people change their 2.4 external interfaces to work in
# centisecs. This can be automated, but it's a work in progress that still needs
# some fixes. On 2.6 kernels, XFS uses USER_HZ instead of HZ for external
# interfaces, and that is currently always set to 100. So you don't need to
# change this on 2.6.
XFS_HZ=${XFS_HZ:-'100'}
#############################################################################
KLEVEL="$(uname -r |
{
IFS='.' read a b c
echo $a.$b
}
)"
case "$KLEVEL" in
"2.4"|"2.6")
;;
*)
echo "Unhandled kernel version: $KLEVEL ('uname -r' = '$(uname -r)')" >&2
exit 1
;;
esac
if [ ! -e /proc/sys/vm/laptop_mode ] ; then
echo "Kernel is not patched with laptop_mode patch." >&2
exit 1
fi
if [ ! -w /proc/sys/vm/laptop_mode ] ; then
echo "You do not have enough privileges to enable laptop_mode." >&2
exit 1
fi
# Remove an option (the first parameter) of the form option=<number> from
# a mount options string (the rest of the parameters).
parse_mount_opts () {
OPT="$1"
shift
echo ",$*," | sed \
-e 's/,'"$OPT"'=[0-9]*,/,/g' \
-e 's/,,*/,/g' \
-e 's/^,//' \
-e 's/,$//'
}
# Remove an option (the first parameter) without any arguments from
# a mount option string (the rest of the parameters).
parse_nonumber_mount_opts () {
OPT="$1"
shift
echo ",$*," | sed \
-e 's/,'"$OPT"',/,/g' \
-e 's/,,*/,/g' \
-e 's/^,//' \
-e 's/,$//'
}
# Find out the state of a yes/no option (e.g. "atime"/"noatime") in
# fstab for a given filesystem, and use this state to replace the
# value of the option in another mount options string. The device
# is the first argument, the option name the second, and the default
# value the third. The remainder is the mount options string.
#
# Example:
# parse_yesno_opts_wfstab /dev/hda1 atime atime defaults,noatime
#
# If fstab contains, say, "rw" for this filesystem, then the result
# will be "defaults,atime".
parse_yesno_opts_wfstab () {
L_DEV="$1"
OPT="$2"
DEF_OPT="$3"
shift 3
L_OPTS="$*"
PARSEDOPTS1="$(parse_nonumber_mount_opts $OPT $L_OPTS)"
PARSEDOPTS1="$(parse_nonumber_mount_opts no$OPT $PARSEDOPTS1)"
# Watch for a default atime in fstab
FSTAB_OPTS="$(awk '$1 == "'$L_DEV'" { print $4 }' /etc/fstab)"
if echo "$FSTAB_OPTS" | grep "$OPT" > /dev/null ; then
# option specified in fstab: extract the value and use it
if echo "$FSTAB_OPTS" | grep "no$OPT" > /dev/null ; then
echo "$PARSEDOPTS1,no$OPT"
else
# no$OPT not found -- so we must have $OPT.
echo "$PARSEDOPTS1,$OPT"
fi
else
# option not specified in fstab -- choose the default.
echo "$PARSEDOPTS1,$DEF_OPT"
fi
}
# Find out the state of a numbered option (e.g. "commit=NNN") in
# fstab for a given filesystem, and use this state to replace the
# value of the option in another mount options string. The device
# is the first argument, and the option name the second. The
# remainder is the mount options string in which the replacement
# must be done.
#
# Example:
# parse_mount_opts_wfstab /dev/hda1 commit defaults,commit=7
#
# If fstab contains, say, "commit=3,rw" for this filesystem, then the
# result will be "rw,commit=3".
parse_mount_opts_wfstab () {
L_DEV="$1"
OPT="$2"
shift 2
L_OPTS="$*"
PARSEDOPTS1="$(parse_mount_opts $OPT $L_OPTS)"
# Watch for a default commit in fstab
FSTAB_OPTS="$(awk '$1 == "'$L_DEV'" { print $4 }' /etc/fstab)"
if echo "$FSTAB_OPTS" | grep "$OPT=" > /dev/null ; then
# option specified in fstab: extract the value, and use it
echo -n "$PARSEDOPTS1,$OPT="
echo ",$FSTAB_OPTS," | sed \
-e 's/.*,'"$OPT"'=//' \
-e 's/,.*//'
else
# option not specified in fstab: set it to 0
echo "$PARSEDOPTS1,$OPT=0"
fi
}
deduce_fstype () {
MP="$1"
# My root filesystem unfortunately has
# type "unknown" in /etc/mtab. If we encounter
# "unknown", we try to get the type from fstab.
cat /etc/fstab |
grep -v '^#' |
while read FSTAB_DEV FSTAB_MP FSTAB_FST FSTAB_OPTS FSTAB_DUMP FSTAB_DUMP ; do
if [ "$FSTAB_MP" = "$MP" ]; then
echo $FSTAB_FST
exit 0
fi
done
}
if [ $DO_REMOUNT_NOATIME -eq 1 ] ; then
NOATIME_OPT=",noatime"
fi
case "$1" in
start)
AGE=$((100*$MAX_AGE))
XFS_AGE=$(($XFS_HZ*$MAX_AGE))
echo -n "Starting laptop_mode"
if [ -d /proc/sys/vm/pagebuf ] ; then
# (For 2.4 and early 2.6.)
# This only needs to be set, not reset -- it is only used when
# laptop mode is enabled.
echo $XFS_AGE > /proc/sys/vm/pagebuf/lm_flush_age
echo $XFS_AGE > /proc/sys/fs/xfs/lm_sync_interval
elif [ -f /proc/sys/fs/xfs/lm_age_buffer ] ; then
# (A couple of early 2.6 laptop mode patches had these.)
# The same goes for these.
echo $XFS_AGE > /proc/sys/fs/xfs/lm_age_buffer
echo $XFS_AGE > /proc/sys/fs/xfs/lm_sync_interval
elif [ -f /proc/sys/fs/xfs/age_buffer ] ; then
# (2.6.6)
# But not for these -- they are also used in normal
# operation.
echo $XFS_AGE > /proc/sys/fs/xfs/age_buffer
echo $XFS_AGE > /proc/sys/fs/xfs/sync_interval
elif [ -f /proc/sys/fs/xfs/age_buffer_centisecs ] ; then
# (2.6.7 upwards)
# And not for these either. These are in centisecs,
# not USER_HZ, so we have to use $AGE, not $XFS_AGE.
echo $AGE > /proc/sys/fs/xfs/age_buffer_centisecs
echo $AGE > /proc/sys/fs/xfs/xfssyncd_centisecs
echo 3000 > /proc/sys/fs/xfs/xfsbufd_centisecs
fi
case "$KLEVEL" in
"2.4")
echo 1 > /proc/sys/vm/laptop_mode
echo "30 500 0 0 $AGE $AGE 60 20 0" > /proc/sys/vm/bdflush
;;
"2.6")
echo 5 > /proc/sys/vm/laptop_mode
echo "$AGE" > /proc/sys/vm/dirty_writeback_centisecs
echo "$AGE" > /proc/sys/vm/dirty_expire_centisecs
echo "$DIRTY_RATIO" > /proc/sys/vm/dirty_ratio
echo "$DIRTY_BACKGROUND_RATIO" > /proc/sys/vm/dirty_background_ratio
;;
esac
if [ $DO_REMOUNTS -eq 1 ]; then
cat /etc/mtab | while read DEV MP FST OPTS DUMP PASS ; do
PARSEDOPTS="$(parse_mount_opts "$OPTS")"
if [ "$FST" = 'unknown' ]; then
FST=$(deduce_fstype $MP)
fi
case "$FST" in
"ext3"|"reiserfs")
PARSEDOPTS="$(parse_mount_opts commit "$OPTS")"
mount $DEV -t $FST $MP -o remount,$PARSEDOPTS,commit=$MAX_AGE$NOATIME_OPT
;;
"xfs")
mount $DEV -t $FST $MP -o remount,$OPTS$NOATIME_OPT
;;
esac
if [ -b $DEV ] ; then
blockdev --setra $(($READAHEAD * 2)) $DEV
fi
done
fi
if [ $DO_HD -eq 1 ] ; then
for THISHD in $HD ; do
/sbin/hdparm -S $BATT_HD $THISHD > /dev/null 2>&1
/sbin/hdparm -B 1 $THISHD > /dev/null 2>&1
done
fi
if [ $DO_CPU -eq 1 -a -e /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq ]; then
if [ $CPU_MAXFREQ = 'slowest' ]; then
CPU_MAXFREQ=`cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq`
fi
echo $CPU_MAXFREQ > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
fi
echo "."
;;
stop)
U_AGE=$((100*$DEF_UPDATE))
B_AGE=$((100*$DEF_AGE))
echo -n "Stopping laptop_mode"
echo 0 > /proc/sys/vm/laptop_mode
if [ -f /proc/sys/fs/xfs/age_buffer -a ! -f /proc/sys/fs/xfs/lm_age_buffer ] ; then
# These need to be restored, if there are no lm_*.
echo $(($XFS_HZ*$DEF_XFS_AGE_BUFFER)) > /proc/sys/fs/xfs/age_buffer
echo $(($XFS_HZ*$DEF_XFS_SYNC_INTERVAL)) > /proc/sys/fs/xfs/sync_interval
elif [ -f /proc/sys/fs/xfs/age_buffer_centisecs ] ; then
# These need to be restored as well.
echo $((100*$DEF_XFS_AGE_BUFFER)) > /proc/sys/fs/xfs/age_buffer_centisecs
echo $((100*$DEF_XFS_SYNC_INTERVAL)) > /proc/sys/fs/xfs/xfssyncd_centisecs
echo $((100*$DEF_XFS_BUFD_INTERVAL)) > /proc/sys/fs/xfs/xfsbufd_centisecs
fi
case "$KLEVEL" in
"2.4")
echo "30 500 0 0 $U_AGE $B_AGE 60 20 0" > /proc/sys/vm/bdflush
;;
"2.6")
echo "$U_AGE" > /proc/sys/vm/dirty_writeback_centisecs
echo "$B_AGE" > /proc/sys/vm/dirty_expire_centisecs
echo "$DEF_DIRTY_RATIO" > /proc/sys/vm/dirty_ratio
echo "$DEF_DIRTY_BACKGROUND_RATIO" > /proc/sys/vm/dirty_background_ratio
;;
esac
if [ $DO_REMOUNTS -eq 1 ] ; then
cat /etc/mtab | while read DEV MP FST OPTS DUMP PASS ; do
# Reset commit and atime options to defaults.
if [ "$FST" = 'unknown' ]; then
FST=$(deduce_fstype $MP)
fi
case "$FST" in
"ext3"|"reiserfs")
PARSEDOPTS="$(parse_mount_opts_wfstab $DEV commit $OPTS)"
PARSEDOPTS="$(parse_yesno_opts_wfstab $DEV atime atime $PARSEDOPTS)"
mount $DEV -t $FST $MP -o remount,$PARSEDOPTS
;;
"xfs")
PARSEDOPTS="$(parse_yesno_opts_wfstab $DEV atime atime $OPTS)"
mount $DEV -t $FST $MP -o remount,$PARSEDOPTS
;;
esac
if [ -b $DEV ] ; then
blockdev --setra 256 $DEV
fi
done
fi
if [ $DO_HD -eq 1 ] ; then
for THISHD in $HD ; do
/sbin/hdparm -S $AC_HD $THISHD > /dev/null 2>&1
/sbin/hdparm -B 255 $THISHD > /dev/null 2>&1
done
fi
if [ $DO_CPU -eq 1 -a -e /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq ]; then
echo `cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq` > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
fi
echo "."
;;
*)
echo "Usage: $0 {start|stop}" 2>&1
exit 1
;;
esac
exit 0
ACPI 整合¶
Dax Kelson 提交了此內容,以便 ACPI acpid 守護程式能夠啟動 laptop_mode 指令碼並執行 hdparm。電池電量低時自動停用筆記本模式的部分由 Jan Topinski 編寫。
/etc/acpi/events/ac_adapter
event=ac_adapter
action=/etc/acpi/actions/ac.sh %e
/etc/acpi/events/battery
event=battery.*
action=/etc/acpi/actions/battery.sh %e
/etc/acpi/actions/ac.sh
#!/bin/bash
# ac on/offline event handler
status=`awk '/^state: / { print $2 }' /proc/acpi/ac_adapter/$2/state`
case $status in
"on-line")
/sbin/laptop_mode stop
exit 0
;;
"off-line")
/sbin/laptop_mode start
exit 0
;;
esac
/etc/acpi/actions/battery.sh
#! /bin/bash
# Automatically disable laptop mode when the battery almost runs out.
BATT_INFO=/proc/acpi/battery/$2/state
if [[ -f /proc/sys/vm/laptop_mode ]]
then
LM=`cat /proc/sys/vm/laptop_mode`
if [[ $LM -gt 0 ]]
then
if [[ -f $BATT_INFO ]]
then
# Source the config file only now that we know we need
if [ -f /etc/default/laptop-mode ] ; then
# Debian
. /etc/default/laptop-mode
elif [ -f /etc/sysconfig/laptop-mode ] ; then
# Others
. /etc/sysconfig/laptop-mode
fi
MINIMUM_BATTERY_MINUTES=${MINIMUM_BATTERY_MINUTES:-'10'}
ACTION="`cat $BATT_INFO | grep charging | cut -c 26-`"
if [[ ACTION -eq "discharging" ]]
then
PRESENT_RATE=`cat $BATT_INFO | grep "present rate:" | sed "s/.* \([0-9][0-9]* \).*/\1/" `
REMAINING=`cat $BATT_INFO | grep "remaining capacity:" | sed "s/.* \([0-9][0-9]* \).*/\1/" `
fi
if (($REMAINING * 60 / $PRESENT_RATE < $MINIMUM_BATTERY_MINUTES))
then
/sbin/laptop_mode stop
fi
else
logger -p daemon.warning "You are using laptop mode and your battery interface $BATT_INFO is missing. This may lead to loss of data when the battery runs out. Check kernel ACPI support and /proc/acpi/battery folder, and edit /etc/acpi/battery.sh to set BATT_INFO to the correct path."
fi
fi
fi
監控工具¶
Bartek Kania 提交了此工具,可用於衡量您的磁碟啟動/停轉的時間。請參閱 tools/laptop/dslm/dslm.c