xref: /OK3568_Linux_fs/kernel/Documentation/admin-guide/laptops/laptop-mode.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun===============================================
2*4882a593SmuzhiyunHow to conserve battery power using laptop-mode
3*4882a593Smuzhiyun===============================================
4*4882a593Smuzhiyun
5*4882a593SmuzhiyunDocument Author: Bart Samwel (bart@samwel.tk)
6*4882a593Smuzhiyun
7*4882a593SmuzhiyunDate created: January 2, 2004
8*4882a593Smuzhiyun
9*4882a593SmuzhiyunLast modified: December 06, 2004
10*4882a593Smuzhiyun
11*4882a593SmuzhiyunIntroduction
12*4882a593Smuzhiyun------------
13*4882a593Smuzhiyun
14*4882a593SmuzhiyunLaptop mode is used to minimize the time that the hard disk needs to be spun up,
15*4882a593Smuzhiyunto conserve battery power on laptops. It has been reported to cause significant
16*4882a593Smuzhiyunpower savings.
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun.. Contents
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun   * Introduction
21*4882a593Smuzhiyun   * Installation
22*4882a593Smuzhiyun   * Caveats
23*4882a593Smuzhiyun   * The Details
24*4882a593Smuzhiyun   * Tips & Tricks
25*4882a593Smuzhiyun   * Control script
26*4882a593Smuzhiyun   * ACPI integration
27*4882a593Smuzhiyun   * Monitoring tool
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun
30*4882a593SmuzhiyunInstallation
31*4882a593Smuzhiyun------------
32*4882a593Smuzhiyun
33*4882a593SmuzhiyunTo use laptop mode, you don't need to set any kernel configuration options
34*4882a593Smuzhiyunor anything. Simply install all the files included in this document, and
35*4882a593Smuzhiyunlaptop mode will automatically be started when you're on battery. For
36*4882a593Smuzhiyunyour convenience, a tarball containing an installer can be downloaded at:
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun	http://www.samwel.tk/laptop_mode/laptop_mode/
39*4882a593Smuzhiyun
40*4882a593SmuzhiyunTo configure laptop mode, you need to edit the configuration file, which is
41*4882a593Smuzhiyunlocated in /etc/default/laptop-mode on Debian-based systems, or in
42*4882a593Smuzhiyun/etc/sysconfig/laptop-mode on other systems.
43*4882a593Smuzhiyun
44*4882a593SmuzhiyunUnfortunately, automatic enabling of laptop mode does not work for
45*4882a593Smuzhiyunlaptops that don't have ACPI. On those laptops, you need to start laptop
46*4882a593Smuzhiyunmode manually. To start laptop mode, run "laptop_mode start", and to
47*4882a593Smuzhiyunstop it, run "laptop_mode stop". (Note: The laptop mode tools package now
48*4882a593Smuzhiyunhas experimental support for APM, you might want to try that first.)
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun
51*4882a593SmuzhiyunCaveats
52*4882a593Smuzhiyun-------
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun* The downside of laptop mode is that you have a chance of losing up to 10
55*4882a593Smuzhiyun  minutes of work. If you cannot afford this, don't use it! The supplied ACPI
56*4882a593Smuzhiyun  scripts automatically turn off laptop mode when the battery almost runs out,
57*4882a593Smuzhiyun  so that you won't lose any data at the end of your battery life.
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun* Most desktop hard drives have a very limited lifetime measured in spindown
60*4882a593Smuzhiyun  cycles, typically about 50.000 times (it's usually listed on the spec sheet).
61*4882a593Smuzhiyun  Check your drive's rating, and don't wear down your drive's lifetime if you
62*4882a593Smuzhiyun  don't need to.
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun* If you mount some of your ext3/reiserfs filesystems with the -n option, then
65*4882a593Smuzhiyun  the control script will not be able to remount them correctly. You must set
66*4882a593Smuzhiyun  DO_REMOUNTS=0 in the control script, otherwise it will remount them with the
67*4882a593Smuzhiyun  wrong options -- or it will fail because it cannot write to /etc/mtab.
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun* If you have your filesystems listed as type "auto" in fstab, like I did, then
70*4882a593Smuzhiyun  the control script will not recognize them as filesystems that need remounting.
71*4882a593Smuzhiyun  You must list the filesystems with their true type instead.
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun* It has been reported that some versions of the mutt mail client use file access
74*4882a593Smuzhiyun  times to determine whether a folder contains new mail. If you use mutt and
75*4882a593Smuzhiyun  experience this, you must disable the noatime remounting by setting the option
76*4882a593Smuzhiyun  DO_REMOUNT_NOATIME to 0 in the configuration file.
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun
79*4882a593SmuzhiyunThe Details
80*4882a593Smuzhiyun-----------
81*4882a593Smuzhiyun
82*4882a593SmuzhiyunLaptop mode is controlled by the knob /proc/sys/vm/laptop_mode. This knob is
83*4882a593Smuzhiyunpresent for all kernels that have the laptop mode patch, regardless of any
84*4882a593Smuzhiyunconfiguration options. When the knob is set, any physical disk I/O (that might
85*4882a593Smuzhiyunhave caused the hard disk to spin up) causes Linux to flush all dirty blocks. The
86*4882a593Smuzhiyunresult of this is that after a disk has spun down, it will not be spun up
87*4882a593Smuzhiyunanymore to write dirty blocks, because those blocks had already been written
88*4882a593Smuzhiyunimmediately after the most recent read operation. The value of the laptop_mode
89*4882a593Smuzhiyunknob determines the time between the occurrence of disk I/O and when the flush
90*4882a593Smuzhiyunis triggered. A sensible value for the knob is 5 seconds. Setting the knob to
91*4882a593Smuzhiyun0 disables laptop mode.
92*4882a593Smuzhiyun
93*4882a593SmuzhiyunTo increase the effectiveness of the laptop_mode strategy, the laptop_mode
94*4882a593Smuzhiyuncontrol script increases dirty_expire_centisecs and dirty_writeback_centisecs in
95*4882a593Smuzhiyun/proc/sys/vm to about 10 minutes (by default), which means that pages that are
96*4882a593Smuzhiyundirtied are not forced to be written to disk as often. The control script also
97*4882a593Smuzhiyunchanges the dirty background ratio, so that background writeback of dirty pages
98*4882a593Smuzhiyunis not done anymore. Combined with a higher commit value (also 10 minutes) for
99*4882a593Smuzhiyunext3 or ReiserFS filesystems (also done automatically by the control script),
100*4882a593Smuzhiyunthis results in concentration of disk activity in a small time interval which
101*4882a593Smuzhiyunoccurs only once every 10 minutes, or whenever the disk is forced to spin up by
102*4882a593Smuzhiyuna cache miss. The disk can then be spun down in the periods of inactivity.
103*4882a593Smuzhiyun
104*4882a593SmuzhiyunIf you want to find out which process caused the disk to spin up, you can
105*4882a593Smuzhiyungather information by setting the flag /proc/sys/vm/block_dump. When this flag
106*4882a593Smuzhiyunis set, Linux reports all disk read and write operations that take place, and
107*4882a593Smuzhiyunall block dirtyings done to files. This makes it possible to debug why a disk
108*4882a593Smuzhiyunneeds to spin up, and to increase battery life even more. The output of
109*4882a593Smuzhiyunblock_dump is written to the kernel output, and it can be retrieved using
110*4882a593Smuzhiyun"dmesg". When you use block_dump and your kernel logging level also includes
111*4882a593Smuzhiyunkernel debugging messages, you probably want to turn off klogd, otherwise
112*4882a593Smuzhiyunthe output of block_dump will be logged, causing disk activity that is not
113*4882a593Smuzhiyunnormally there.
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun
116*4882a593SmuzhiyunConfiguration
117*4882a593Smuzhiyun-------------
118*4882a593Smuzhiyun
119*4882a593SmuzhiyunThe laptop mode configuration file is located in /etc/default/laptop-mode on
120*4882a593SmuzhiyunDebian-based systems, or in /etc/sysconfig/laptop-mode on other systems. It
121*4882a593Smuzhiyuncontains the following options:
122*4882a593Smuzhiyun
123*4882a593SmuzhiyunMAX_AGE:
124*4882a593Smuzhiyun
125*4882a593SmuzhiyunMaximum time, in seconds, of hard drive spindown time that you are
126*4882a593Smuzhiyuncomfortable with. Worst case, it's possible that you could lose this
127*4882a593Smuzhiyunamount of work if your battery fails while you're in laptop mode.
128*4882a593Smuzhiyun
129*4882a593SmuzhiyunMINIMUM_BATTERY_MINUTES:
130*4882a593Smuzhiyun
131*4882a593SmuzhiyunAutomatically disable laptop mode if the remaining number of minutes of
132*4882a593Smuzhiyunbattery power is less than this value. Default is 10 minutes.
133*4882a593Smuzhiyun
134*4882a593SmuzhiyunAC_HD/BATT_HD:
135*4882a593Smuzhiyun
136*4882a593SmuzhiyunThe idle timeout that should be set on your hard drive when laptop mode
137*4882a593Smuzhiyunis active (BATT_HD) and when it is not active (AC_HD). The defaults are
138*4882a593Smuzhiyun20 seconds (value 4) for BATT_HD  and 2 hours (value 244) for AC_HD. The
139*4882a593Smuzhiyunpossible values are those listed in the manual page for "hdparm" for the
140*4882a593Smuzhiyun"-S" option.
141*4882a593Smuzhiyun
142*4882a593SmuzhiyunHD:
143*4882a593Smuzhiyun
144*4882a593SmuzhiyunThe devices for which the spindown timeout should be adjusted by laptop mode.
145*4882a593SmuzhiyunDefault is /dev/hda. If you specify multiple devices, separate them by a space.
146*4882a593Smuzhiyun
147*4882a593SmuzhiyunREADAHEAD:
148*4882a593Smuzhiyun
149*4882a593SmuzhiyunDisk readahead, in 512-byte sectors, while laptop mode is active. A large
150*4882a593Smuzhiyunreadahead can prevent disk accesses for things like executable pages (which are
151*4882a593Smuzhiyunloaded on demand while the application executes) and sequentially accessed data
152*4882a593Smuzhiyun(MP3s).
153*4882a593Smuzhiyun
154*4882a593SmuzhiyunDO_REMOUNTS:
155*4882a593Smuzhiyun
156*4882a593SmuzhiyunThe control script automatically remounts any mounted journaled filesystems
157*4882a593Smuzhiyunwith appropriate commit interval options. When this option is set to 0, this
158*4882a593Smuzhiyunfeature is disabled.
159*4882a593Smuzhiyun
160*4882a593SmuzhiyunDO_REMOUNT_NOATIME:
161*4882a593Smuzhiyun
162*4882a593SmuzhiyunWhen remounting, should the filesystems be remounted with the noatime option?
163*4882a593SmuzhiyunNormally, this is set to "1" (enabled), but there may be programs that require
164*4882a593Smuzhiyunaccess time recording.
165*4882a593Smuzhiyun
166*4882a593SmuzhiyunDIRTY_RATIO:
167*4882a593Smuzhiyun
168*4882a593SmuzhiyunThe percentage of memory that is allowed to contain "dirty" or unsaved data
169*4882a593Smuzhiyunbefore a writeback is forced, while laptop mode is active. Corresponds to
170*4882a593Smuzhiyunthe /proc/sys/vm/dirty_ratio sysctl.
171*4882a593Smuzhiyun
172*4882a593SmuzhiyunDIRTY_BACKGROUND_RATIO:
173*4882a593Smuzhiyun
174*4882a593SmuzhiyunThe percentage of memory that is allowed to contain "dirty" or unsaved data
175*4882a593Smuzhiyunafter a forced writeback is done due to an exceeding of DIRTY_RATIO. Set
176*4882a593Smuzhiyunthis nice and low. This corresponds to the /proc/sys/vm/dirty_background_ratio
177*4882a593Smuzhiyunsysctl.
178*4882a593Smuzhiyun
179*4882a593SmuzhiyunNote that the behaviour of dirty_background_ratio is quite different
180*4882a593Smuzhiyunwhen laptop mode is active and when it isn't. When laptop mode is inactive,
181*4882a593Smuzhiyundirty_background_ratio is the threshold percentage at which background writeouts
182*4882a593Smuzhiyunstart taking place. When laptop mode is active, however, background writeouts
183*4882a593Smuzhiyunare disabled, and the dirty_background_ratio only determines how much writeback
184*4882a593Smuzhiyunis done when dirty_ratio is reached.
185*4882a593Smuzhiyun
186*4882a593SmuzhiyunDO_CPU:
187*4882a593Smuzhiyun
188*4882a593SmuzhiyunEnable CPU frequency scaling when in laptop mode. (Requires CPUFreq to be setup.
189*4882a593SmuzhiyunSee Documentation/admin-guide/pm/cpufreq.rst for more info. Disabled by default.)
190*4882a593Smuzhiyun
191*4882a593SmuzhiyunCPU_MAXFREQ:
192*4882a593Smuzhiyun
193*4882a593SmuzhiyunWhen on battery, what is the maximum CPU speed that the system should use? Legal
194*4882a593Smuzhiyunvalues are "slowest" for the slowest speed that your CPU is able to operate at,
195*4882a593Smuzhiyunor a value listed in /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies.
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun
198*4882a593SmuzhiyunTips & Tricks
199*4882a593Smuzhiyun-------------
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun* Bartek Kania reports getting up to 50 minutes of extra battery life (on top
202*4882a593Smuzhiyun  of his regular 3 to 3.5 hours) using a spindown time of 5 seconds (BATT_HD=1).
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun* You can spin down the disk while playing MP3, by setting disk readahead
205*4882a593Smuzhiyun  to 8MB (READAHEAD=16384). Effectively, the disk will read a complete MP3 at
206*4882a593Smuzhiyun  once, and will then spin down while the MP3 is playing. (Thanks to Bartek
207*4882a593Smuzhiyun  Kania.)
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun* Drew Scott Daniels observed: "I don't know why, but when I decrease the number
210*4882a593Smuzhiyun  of colours that my display uses it consumes less battery power. I've seen
211*4882a593Smuzhiyun  this on powerbooks too. I hope that this is a piece of information that
212*4882a593Smuzhiyun  might be useful to the Laptop Mode patch or its users."
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun* In syslog.conf, you can prefix entries with a dash `-` to omit syncing the
215*4882a593Smuzhiyun  file after every logging. When you're using laptop-mode and your disk doesn't
216*4882a593Smuzhiyun  spin down, this is a likely culprit.
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun* Richard Atterer observed that laptop mode does not work well with noflushd
219*4882a593Smuzhiyun  (http://noflushd.sourceforge.net/), it seems that noflushd prevents laptop-mode
220*4882a593Smuzhiyun  from doing its thing.
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun* If you're worried about your data, you might want to consider using a USB
223*4882a593Smuzhiyun  memory stick or something like that as a "working area". (Be aware though
224*4882a593Smuzhiyun  that flash memory can only handle a limited number of writes, and overuse
225*4882a593Smuzhiyun  may wear out your memory stick pretty quickly. Do _not_ use journalling
226*4882a593Smuzhiyun  filesystems on flash memory sticks.)
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun
229*4882a593SmuzhiyunConfiguration file for control and ACPI battery scripts
230*4882a593Smuzhiyun-------------------------------------------------------
231*4882a593Smuzhiyun
232*4882a593SmuzhiyunThis allows the tunables to be changed for the scripts via an external
233*4882a593Smuzhiyunconfiguration file
234*4882a593Smuzhiyun
235*4882a593SmuzhiyunIt should be installed as /etc/default/laptop-mode on Debian, and as
236*4882a593Smuzhiyun/etc/sysconfig/laptop-mode on Red Hat, SUSE, Mandrake, and other work-alikes.
237*4882a593Smuzhiyun
238*4882a593SmuzhiyunConfig file::
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun  # Maximum time, in seconds, of hard drive spindown time that you are
241*4882a593Smuzhiyun  # comfortable with. Worst case, it's possible that you could lose this
242*4882a593Smuzhiyun  # amount of work if your battery fails you while in laptop mode.
243*4882a593Smuzhiyun  #MAX_AGE=600
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun  # Automatically disable laptop mode when the number of minutes of battery
246*4882a593Smuzhiyun  # that you have left goes below this threshold.
247*4882a593Smuzhiyun  MINIMUM_BATTERY_MINUTES=10
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun  # Read-ahead, in 512-byte sectors. You can spin down the disk while playing MP3/OGG
250*4882a593Smuzhiyun  # by setting the disk readahead to 8MB (READAHEAD=16384). Effectively, the disk
251*4882a593Smuzhiyun  # will read a complete MP3 at once, and will then spin down while the MP3/OGG is
252*4882a593Smuzhiyun  # playing.
253*4882a593Smuzhiyun  #READAHEAD=4096
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun  # Shall we remount journaled fs. with appropriate commit interval? (1=yes)
256*4882a593Smuzhiyun  #DO_REMOUNTS=1
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun  # And shall we add the "noatime" option to that as well? (1=yes)
259*4882a593Smuzhiyun  #DO_REMOUNT_NOATIME=1
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun  # Dirty synchronous ratio.  At this percentage of dirty pages the process
262*4882a593Smuzhiyun  # which
263*4882a593Smuzhiyun  # calls write() does its own writeback
264*4882a593Smuzhiyun  #DIRTY_RATIO=40
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun  #
267*4882a593Smuzhiyun  # Allowed dirty background ratio, in percent.  Once DIRTY_RATIO has been
268*4882a593Smuzhiyun  # exceeded, the kernel will wake flusher threads which will then reduce the
269*4882a593Smuzhiyun  # amount of dirty memory to dirty_background_ratio.  Set this nice and low,
270*4882a593Smuzhiyun  # so once some writeout has commenced, we do a lot of it.
271*4882a593Smuzhiyun  #
272*4882a593Smuzhiyun  #DIRTY_BACKGROUND_RATIO=5
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun  # kernel default dirty buffer age
275*4882a593Smuzhiyun  #DEF_AGE=30
276*4882a593Smuzhiyun  #DEF_UPDATE=5
277*4882a593Smuzhiyun  #DEF_DIRTY_BACKGROUND_RATIO=10
278*4882a593Smuzhiyun  #DEF_DIRTY_RATIO=40
279*4882a593Smuzhiyun  #DEF_XFS_AGE_BUFFER=15
280*4882a593Smuzhiyun  #DEF_XFS_SYNC_INTERVAL=30
281*4882a593Smuzhiyun  #DEF_XFS_BUFD_INTERVAL=1
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun  # This must be adjusted manually to the value of HZ in the running kernel
284*4882a593Smuzhiyun  # on 2.4, until the XFS people change their 2.4 external interfaces to work in
285*4882a593Smuzhiyun  # centisecs. This can be automated, but it's a work in progress that still
286*4882a593Smuzhiyun  # needs# some fixes. On 2.6 kernels, XFS uses USER_HZ instead of HZ for
287*4882a593Smuzhiyun  # external interfaces, and that is currently always set to 100. So you don't
288*4882a593Smuzhiyun  # need to change this on 2.6.
289*4882a593Smuzhiyun  #XFS_HZ=100
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun  # Should the maximum CPU frequency be adjusted down while on battery?
292*4882a593Smuzhiyun  # Requires CPUFreq to be setup.
293*4882a593Smuzhiyun  # See Documentation/admin-guide/pm/cpufreq.rst for more info
294*4882a593Smuzhiyun  #DO_CPU=0
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun  # When on battery what is the maximum CPU speed that the system should
297*4882a593Smuzhiyun  # use? Legal values are "slowest" for the slowest speed that your
298*4882a593Smuzhiyun  # CPU is able to operate at, or a value listed in:
299*4882a593Smuzhiyun  # /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
300*4882a593Smuzhiyun  # Only applicable if DO_CPU=1.
301*4882a593Smuzhiyun  #CPU_MAXFREQ=slowest
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun  # Idle timeout for your hard drive (man hdparm for valid values, -S option)
304*4882a593Smuzhiyun  # Default is 2 hours on AC (AC_HD=244) and 20 seconds for battery (BATT_HD=4).
305*4882a593Smuzhiyun  #AC_HD=244
306*4882a593Smuzhiyun  #BATT_HD=4
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun  # The drives for which to adjust the idle timeout. Separate them by a space,
309*4882a593Smuzhiyun  # e.g. HD="/dev/hda /dev/hdb".
310*4882a593Smuzhiyun  #HD="/dev/hda"
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun  # Set the spindown timeout on a hard drive?
313*4882a593Smuzhiyun  #DO_HD=1
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun
316*4882a593SmuzhiyunControl script
317*4882a593Smuzhiyun--------------
318*4882a593Smuzhiyun
319*4882a593SmuzhiyunPlease note that this control script works for the Linux 2.4 and 2.6 series (thanks
320*4882a593Smuzhiyunto Kiko Piris).
321*4882a593Smuzhiyun
322*4882a593SmuzhiyunControl script::
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun  #!/bin/bash
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun  # start or stop laptop_mode, best run by a power management daemon when
327*4882a593Smuzhiyun  # ac gets connected/disconnected from a laptop
328*4882a593Smuzhiyun  #
329*4882a593Smuzhiyun  # install as /sbin/laptop_mode
330*4882a593Smuzhiyun  #
331*4882a593Smuzhiyun  # Contributors to this script:   Kiko Piris
332*4882a593Smuzhiyun  #				 Bart Samwel
333*4882a593Smuzhiyun  #				 Micha Feigin
334*4882a593Smuzhiyun  #				 Andrew Morton
335*4882a593Smuzhiyun  #				 Herve Eychenne
336*4882a593Smuzhiyun  #				 Dax Kelson
337*4882a593Smuzhiyun  #
338*4882a593Smuzhiyun  # Original Linux 2.4 version by: Jens Axboe
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun  #############################################################################
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun  # Source config
343*4882a593Smuzhiyun  if [ -f /etc/default/laptop-mode ] ; then
344*4882a593Smuzhiyun	# Debian
345*4882a593Smuzhiyun	. /etc/default/laptop-mode
346*4882a593Smuzhiyun  elif [ -f /etc/sysconfig/laptop-mode ] ; then
347*4882a593Smuzhiyun	# Others
348*4882a593Smuzhiyun          . /etc/sysconfig/laptop-mode
349*4882a593Smuzhiyun  fi
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun  # Don't raise an error if the config file is incomplete
352*4882a593Smuzhiyun  # set defaults instead:
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun  # Maximum time, in seconds, of hard drive spindown time that you are
355*4882a593Smuzhiyun  # comfortable with. Worst case, it's possible that you could lose this
356*4882a593Smuzhiyun  # amount of work if your battery fails you while in laptop mode.
357*4882a593Smuzhiyun  MAX_AGE=${MAX_AGE:-'600'}
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun  # Read-ahead, in kilobytes
360*4882a593Smuzhiyun  READAHEAD=${READAHEAD:-'4096'}
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun  # Shall we remount journaled fs. with appropriate commit interval? (1=yes)
363*4882a593Smuzhiyun  DO_REMOUNTS=${DO_REMOUNTS:-'1'}
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun  # And shall we add the "noatime" option to that as well? (1=yes)
366*4882a593Smuzhiyun  DO_REMOUNT_NOATIME=${DO_REMOUNT_NOATIME:-'1'}
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun  # Shall we adjust the idle timeout on a hard drive?
369*4882a593Smuzhiyun  DO_HD=${DO_HD:-'1'}
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun  # Adjust idle timeout on which hard drive?
372*4882a593Smuzhiyun  HD="${HD:-'/dev/hda'}"
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun  # spindown time for HD (hdparm -S values)
375*4882a593Smuzhiyun  AC_HD=${AC_HD:-'244'}
376*4882a593Smuzhiyun  BATT_HD=${BATT_HD:-'4'}
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun  # Dirty synchronous ratio.  At this percentage of dirty pages the process which
379*4882a593Smuzhiyun  # calls write() does its own writeback
380*4882a593Smuzhiyun  DIRTY_RATIO=${DIRTY_RATIO:-'40'}
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun  # cpu frequency scaling
383*4882a593Smuzhiyun  # See Documentation/admin-guide/pm/cpufreq.rst for more info
384*4882a593Smuzhiyun  DO_CPU=${CPU_MANAGE:-'0'}
385*4882a593Smuzhiyun  CPU_MAXFREQ=${CPU_MAXFREQ:-'slowest'}
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun  #
388*4882a593Smuzhiyun  # Allowed dirty background ratio, in percent.  Once DIRTY_RATIO has been
389*4882a593Smuzhiyun  # exceeded, the kernel will wake flusher threads which will then reduce the
390*4882a593Smuzhiyun  # amount of dirty memory to dirty_background_ratio.  Set this nice and low,
391*4882a593Smuzhiyun  # so once some writeout has commenced, we do a lot of it.
392*4882a593Smuzhiyun  #
393*4882a593Smuzhiyun  DIRTY_BACKGROUND_RATIO=${DIRTY_BACKGROUND_RATIO:-'5'}
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun  # kernel default dirty buffer age
396*4882a593Smuzhiyun  DEF_AGE=${DEF_AGE:-'30'}
397*4882a593Smuzhiyun  DEF_UPDATE=${DEF_UPDATE:-'5'}
398*4882a593Smuzhiyun  DEF_DIRTY_BACKGROUND_RATIO=${DEF_DIRTY_BACKGROUND_RATIO:-'10'}
399*4882a593Smuzhiyun  DEF_DIRTY_RATIO=${DEF_DIRTY_RATIO:-'40'}
400*4882a593Smuzhiyun  DEF_XFS_AGE_BUFFER=${DEF_XFS_AGE_BUFFER:-'15'}
401*4882a593Smuzhiyun  DEF_XFS_SYNC_INTERVAL=${DEF_XFS_SYNC_INTERVAL:-'30'}
402*4882a593Smuzhiyun  DEF_XFS_BUFD_INTERVAL=${DEF_XFS_BUFD_INTERVAL:-'1'}
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun  # This must be adjusted manually to the value of HZ in the running kernel
405*4882a593Smuzhiyun  # on 2.4, until the XFS people change their 2.4 external interfaces to work in
406*4882a593Smuzhiyun  # centisecs. This can be automated, but it's a work in progress that still needs
407*4882a593Smuzhiyun  # some fixes. On 2.6 kernels, XFS uses USER_HZ instead of HZ for external
408*4882a593Smuzhiyun  # interfaces, and that is currently always set to 100. So you don't need to
409*4882a593Smuzhiyun  # change this on 2.6.
410*4882a593Smuzhiyun  XFS_HZ=${XFS_HZ:-'100'}
411*4882a593Smuzhiyun
412*4882a593Smuzhiyun  #############################################################################
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun  KLEVEL="$(uname -r |
415*4882a593Smuzhiyun               {
416*4882a593Smuzhiyun	       IFS='.' read a b c
417*4882a593Smuzhiyun	       echo $a.$b
418*4882a593Smuzhiyun	     }
419*4882a593Smuzhiyun  )"
420*4882a593Smuzhiyun  case "$KLEVEL" in
421*4882a593Smuzhiyun	"2.4"|"2.6")
422*4882a593Smuzhiyun		;;
423*4882a593Smuzhiyun	*)
424*4882a593Smuzhiyun		echo "Unhandled kernel version: $KLEVEL ('uname -r' = '$(uname -r)')" >&2
425*4882a593Smuzhiyun		exit 1
426*4882a593Smuzhiyun		;;
427*4882a593Smuzhiyun  esac
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun  if [ ! -e /proc/sys/vm/laptop_mode ] ; then
430*4882a593Smuzhiyun	echo "Kernel is not patched with laptop_mode patch." >&2
431*4882a593Smuzhiyun	exit 1
432*4882a593Smuzhiyun  fi
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun  if [ ! -w /proc/sys/vm/laptop_mode ] ; then
435*4882a593Smuzhiyun	echo "You do not have enough privileges to enable laptop_mode." >&2
436*4882a593Smuzhiyun	exit 1
437*4882a593Smuzhiyun  fi
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun  # Remove an option (the first parameter) of the form option=<number> from
440*4882a593Smuzhiyun  # a mount options string (the rest of the parameters).
441*4882a593Smuzhiyun  parse_mount_opts () {
442*4882a593Smuzhiyun	OPT="$1"
443*4882a593Smuzhiyun	shift
444*4882a593Smuzhiyun	echo ",$*," | sed		\
445*4882a593Smuzhiyun	 -e 's/,'"$OPT"'=[0-9]*,/,/g'	\
446*4882a593Smuzhiyun	 -e 's/,,*/,/g'			\
447*4882a593Smuzhiyun	 -e 's/^,//'			\
448*4882a593Smuzhiyun	 -e 's/,$//'
449*4882a593Smuzhiyun  }
450*4882a593Smuzhiyun
451*4882a593Smuzhiyun  # Remove an option (the first parameter) without any arguments from
452*4882a593Smuzhiyun  # a mount option string (the rest of the parameters).
453*4882a593Smuzhiyun  parse_nonumber_mount_opts () {
454*4882a593Smuzhiyun	OPT="$1"
455*4882a593Smuzhiyun	shift
456*4882a593Smuzhiyun	echo ",$*," | sed		\
457*4882a593Smuzhiyun	 -e 's/,'"$OPT"',/,/g'		\
458*4882a593Smuzhiyun	 -e 's/,,*/,/g'			\
459*4882a593Smuzhiyun	 -e 's/^,//'			\
460*4882a593Smuzhiyun	 -e 's/,$//'
461*4882a593Smuzhiyun  }
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun  # Find out the state of a yes/no option (e.g. "atime"/"noatime") in
464*4882a593Smuzhiyun  # fstab for a given filesystem, and use this state to replace the
465*4882a593Smuzhiyun  # value of the option in another mount options string. The device
466*4882a593Smuzhiyun  # is the first argument, the option name the second, and the default
467*4882a593Smuzhiyun  # value the third. The remainder is the mount options string.
468*4882a593Smuzhiyun  #
469*4882a593Smuzhiyun  # Example:
470*4882a593Smuzhiyun  # parse_yesno_opts_wfstab /dev/hda1 atime atime defaults,noatime
471*4882a593Smuzhiyun  #
472*4882a593Smuzhiyun  # If fstab contains, say, "rw" for this filesystem, then the result
473*4882a593Smuzhiyun  # will be "defaults,atime".
474*4882a593Smuzhiyun  parse_yesno_opts_wfstab () {
475*4882a593Smuzhiyun	L_DEV="$1"
476*4882a593Smuzhiyun	OPT="$2"
477*4882a593Smuzhiyun	DEF_OPT="$3"
478*4882a593Smuzhiyun	shift 3
479*4882a593Smuzhiyun	L_OPTS="$*"
480*4882a593Smuzhiyun	PARSEDOPTS1="$(parse_nonumber_mount_opts $OPT $L_OPTS)"
481*4882a593Smuzhiyun	PARSEDOPTS1="$(parse_nonumber_mount_opts no$OPT $PARSEDOPTS1)"
482*4882a593Smuzhiyun	# Watch for a default atime in fstab
483*4882a593Smuzhiyun	FSTAB_OPTS="$(awk '$1 == "'$L_DEV'" { print $4 }' /etc/fstab)"
484*4882a593Smuzhiyun	if echo "$FSTAB_OPTS" | grep "$OPT" > /dev/null ; then
485*4882a593Smuzhiyun		# option specified in fstab: extract the value and use it
486*4882a593Smuzhiyun		if echo "$FSTAB_OPTS" | grep "no$OPT" > /dev/null ; then
487*4882a593Smuzhiyun			echo "$PARSEDOPTS1,no$OPT"
488*4882a593Smuzhiyun		else
489*4882a593Smuzhiyun			# no$OPT not found -- so we must have $OPT.
490*4882a593Smuzhiyun			echo "$PARSEDOPTS1,$OPT"
491*4882a593Smuzhiyun		fi
492*4882a593Smuzhiyun	else
493*4882a593Smuzhiyun		# option not specified in fstab -- choose the default.
494*4882a593Smuzhiyun		echo "$PARSEDOPTS1,$DEF_OPT"
495*4882a593Smuzhiyun	fi
496*4882a593Smuzhiyun  }
497*4882a593Smuzhiyun
498*4882a593Smuzhiyun  # Find out the state of a numbered option (e.g. "commit=NNN") in
499*4882a593Smuzhiyun  # fstab for a given filesystem, and use this state to replace the
500*4882a593Smuzhiyun  # value of the option in another mount options string. The device
501*4882a593Smuzhiyun  # is the first argument, and the option name the second. The
502*4882a593Smuzhiyun  # remainder is the mount options string in which the replacement
503*4882a593Smuzhiyun  # must be done.
504*4882a593Smuzhiyun  #
505*4882a593Smuzhiyun  # Example:
506*4882a593Smuzhiyun  # parse_mount_opts_wfstab /dev/hda1 commit defaults,commit=7
507*4882a593Smuzhiyun  #
508*4882a593Smuzhiyun  # If fstab contains, say, "commit=3,rw" for this filesystem, then the
509*4882a593Smuzhiyun  # result will be "rw,commit=3".
510*4882a593Smuzhiyun  parse_mount_opts_wfstab () {
511*4882a593Smuzhiyun	L_DEV="$1"
512*4882a593Smuzhiyun	OPT="$2"
513*4882a593Smuzhiyun	shift 2
514*4882a593Smuzhiyun	L_OPTS="$*"
515*4882a593Smuzhiyun	PARSEDOPTS1="$(parse_mount_opts $OPT $L_OPTS)"
516*4882a593Smuzhiyun	# Watch for a default commit in fstab
517*4882a593Smuzhiyun	FSTAB_OPTS="$(awk '$1 == "'$L_DEV'" { print $4 }' /etc/fstab)"
518*4882a593Smuzhiyun	if echo "$FSTAB_OPTS" | grep "$OPT=" > /dev/null ; then
519*4882a593Smuzhiyun		# option specified in fstab: extract the value, and use it
520*4882a593Smuzhiyun		echo -n "$PARSEDOPTS1,$OPT="
521*4882a593Smuzhiyun		echo ",$FSTAB_OPTS," | sed \
522*4882a593Smuzhiyun		 -e 's/.*,'"$OPT"'=//'	\
523*4882a593Smuzhiyun		 -e 's/,.*//'
524*4882a593Smuzhiyun	else
525*4882a593Smuzhiyun		# option not specified in fstab: set it to 0
526*4882a593Smuzhiyun		echo "$PARSEDOPTS1,$OPT=0"
527*4882a593Smuzhiyun	fi
528*4882a593Smuzhiyun  }
529*4882a593Smuzhiyun
530*4882a593Smuzhiyun  deduce_fstype () {
531*4882a593Smuzhiyun	MP="$1"
532*4882a593Smuzhiyun	# My root filesystem unfortunately has
533*4882a593Smuzhiyun	# type "unknown" in /etc/mtab. If we encounter
534*4882a593Smuzhiyun	# "unknown", we try to get the type from fstab.
535*4882a593Smuzhiyun	cat /etc/fstab |
536*4882a593Smuzhiyun	grep -v '^#' |
537*4882a593Smuzhiyun	while read FSTAB_DEV FSTAB_MP FSTAB_FST FSTAB_OPTS FSTAB_DUMP FSTAB_DUMP ; do
538*4882a593Smuzhiyun		if [ "$FSTAB_MP" = "$MP" ]; then
539*4882a593Smuzhiyun			echo $FSTAB_FST
540*4882a593Smuzhiyun			exit 0
541*4882a593Smuzhiyun		fi
542*4882a593Smuzhiyun	done
543*4882a593Smuzhiyun  }
544*4882a593Smuzhiyun
545*4882a593Smuzhiyun  if [ $DO_REMOUNT_NOATIME -eq 1 ] ; then
546*4882a593Smuzhiyun	NOATIME_OPT=",noatime"
547*4882a593Smuzhiyun  fi
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun  case "$1" in
550*4882a593Smuzhiyun	start)
551*4882a593Smuzhiyun		AGE=$((100*$MAX_AGE))
552*4882a593Smuzhiyun		XFS_AGE=$(($XFS_HZ*$MAX_AGE))
553*4882a593Smuzhiyun		echo -n "Starting laptop_mode"
554*4882a593Smuzhiyun
555*4882a593Smuzhiyun		if [ -d /proc/sys/vm/pagebuf ] ; then
556*4882a593Smuzhiyun			# (For 2.4 and early 2.6.)
557*4882a593Smuzhiyun			# This only needs to be set, not reset -- it is only used when
558*4882a593Smuzhiyun			# laptop mode is enabled.
559*4882a593Smuzhiyun			echo $XFS_AGE > /proc/sys/vm/pagebuf/lm_flush_age
560*4882a593Smuzhiyun			echo $XFS_AGE > /proc/sys/fs/xfs/lm_sync_interval
561*4882a593Smuzhiyun		elif [ -f /proc/sys/fs/xfs/lm_age_buffer ] ; then
562*4882a593Smuzhiyun			# (A couple of early 2.6 laptop mode patches had these.)
563*4882a593Smuzhiyun			# The same goes for these.
564*4882a593Smuzhiyun			echo $XFS_AGE > /proc/sys/fs/xfs/lm_age_buffer
565*4882a593Smuzhiyun			echo $XFS_AGE > /proc/sys/fs/xfs/lm_sync_interval
566*4882a593Smuzhiyun		elif [ -f /proc/sys/fs/xfs/age_buffer ] ; then
567*4882a593Smuzhiyun			# (2.6.6)
568*4882a593Smuzhiyun			# But not for these -- they are also used in normal
569*4882a593Smuzhiyun			# operation.
570*4882a593Smuzhiyun			echo $XFS_AGE > /proc/sys/fs/xfs/age_buffer
571*4882a593Smuzhiyun			echo $XFS_AGE > /proc/sys/fs/xfs/sync_interval
572*4882a593Smuzhiyun		elif [ -f /proc/sys/fs/xfs/age_buffer_centisecs ] ; then
573*4882a593Smuzhiyun			# (2.6.7 upwards)
574*4882a593Smuzhiyun			# And not for these either. These are in centisecs,
575*4882a593Smuzhiyun			# not USER_HZ, so we have to use $AGE, not $XFS_AGE.
576*4882a593Smuzhiyun			echo $AGE > /proc/sys/fs/xfs/age_buffer_centisecs
577*4882a593Smuzhiyun			echo $AGE > /proc/sys/fs/xfs/xfssyncd_centisecs
578*4882a593Smuzhiyun			echo 3000 > /proc/sys/fs/xfs/xfsbufd_centisecs
579*4882a593Smuzhiyun		fi
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun		case "$KLEVEL" in
582*4882a593Smuzhiyun			"2.4")
583*4882a593Smuzhiyun				echo 1					> /proc/sys/vm/laptop_mode
584*4882a593Smuzhiyun				echo "30 500 0 0 $AGE $AGE 60 20 0"	> /proc/sys/vm/bdflush
585*4882a593Smuzhiyun				;;
586*4882a593Smuzhiyun			"2.6")
587*4882a593Smuzhiyun				echo 5					> /proc/sys/vm/laptop_mode
588*4882a593Smuzhiyun				echo "$AGE"				> /proc/sys/vm/dirty_writeback_centisecs
589*4882a593Smuzhiyun				echo "$AGE"				> /proc/sys/vm/dirty_expire_centisecs
590*4882a593Smuzhiyun				echo "$DIRTY_RATIO"			> /proc/sys/vm/dirty_ratio
591*4882a593Smuzhiyun				echo "$DIRTY_BACKGROUND_RATIO"		> /proc/sys/vm/dirty_background_ratio
592*4882a593Smuzhiyun				;;
593*4882a593Smuzhiyun		esac
594*4882a593Smuzhiyun		if [ $DO_REMOUNTS -eq 1 ]; then
595*4882a593Smuzhiyun			cat /etc/mtab | while read DEV MP FST OPTS DUMP PASS ; do
596*4882a593Smuzhiyun				PARSEDOPTS="$(parse_mount_opts "$OPTS")"
597*4882a593Smuzhiyun				if [ "$FST" = 'unknown' ]; then
598*4882a593Smuzhiyun					FST=$(deduce_fstype $MP)
599*4882a593Smuzhiyun				fi
600*4882a593Smuzhiyun				case "$FST" in
601*4882a593Smuzhiyun					"ext3"|"reiserfs")
602*4882a593Smuzhiyun						PARSEDOPTS="$(parse_mount_opts commit "$OPTS")"
603*4882a593Smuzhiyun						mount $DEV -t $FST $MP -o remount,$PARSEDOPTS,commit=$MAX_AGE$NOATIME_OPT
604*4882a593Smuzhiyun						;;
605*4882a593Smuzhiyun					"xfs")
606*4882a593Smuzhiyun						mount $DEV -t $FST $MP -o remount,$OPTS$NOATIME_OPT
607*4882a593Smuzhiyun						;;
608*4882a593Smuzhiyun				esac
609*4882a593Smuzhiyun				if [ -b $DEV ] ; then
610*4882a593Smuzhiyun					blockdev --setra $(($READAHEAD * 2)) $DEV
611*4882a593Smuzhiyun				fi
612*4882a593Smuzhiyun			done
613*4882a593Smuzhiyun		fi
614*4882a593Smuzhiyun		if [ $DO_HD -eq 1 ] ; then
615*4882a593Smuzhiyun			for THISHD in $HD ; do
616*4882a593Smuzhiyun				/sbin/hdparm -S $BATT_HD $THISHD > /dev/null 2>&1
617*4882a593Smuzhiyun				/sbin/hdparm -B 1 $THISHD > /dev/null 2>&1
618*4882a593Smuzhiyun			done
619*4882a593Smuzhiyun		fi
620*4882a593Smuzhiyun		if [ $DO_CPU -eq 1 -a -e /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq ]; then
621*4882a593Smuzhiyun			if [ $CPU_MAXFREQ = 'slowest' ]; then
622*4882a593Smuzhiyun				CPU_MAXFREQ=`cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq`
623*4882a593Smuzhiyun			fi
624*4882a593Smuzhiyun			echo $CPU_MAXFREQ > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
625*4882a593Smuzhiyun		fi
626*4882a593Smuzhiyun		echo "."
627*4882a593Smuzhiyun		;;
628*4882a593Smuzhiyun	stop)
629*4882a593Smuzhiyun		U_AGE=$((100*$DEF_UPDATE))
630*4882a593Smuzhiyun		B_AGE=$((100*$DEF_AGE))
631*4882a593Smuzhiyun		echo -n "Stopping laptop_mode"
632*4882a593Smuzhiyun		echo 0 > /proc/sys/vm/laptop_mode
633*4882a593Smuzhiyun		if [ -f /proc/sys/fs/xfs/age_buffer -a ! -f /proc/sys/fs/xfs/lm_age_buffer ] ; then
634*4882a593Smuzhiyun			# These need to be restored, if there are no lm_*.
635*4882a593Smuzhiyun			echo $(($XFS_HZ*$DEF_XFS_AGE_BUFFER))	 	> /proc/sys/fs/xfs/age_buffer
636*4882a593Smuzhiyun			echo $(($XFS_HZ*$DEF_XFS_SYNC_INTERVAL)) 	> /proc/sys/fs/xfs/sync_interval
637*4882a593Smuzhiyun		elif [ -f /proc/sys/fs/xfs/age_buffer_centisecs ] ; then
638*4882a593Smuzhiyun			# These need to be restored as well.
639*4882a593Smuzhiyun			echo $((100*$DEF_XFS_AGE_BUFFER))	> /proc/sys/fs/xfs/age_buffer_centisecs
640*4882a593Smuzhiyun			echo $((100*$DEF_XFS_SYNC_INTERVAL))	> /proc/sys/fs/xfs/xfssyncd_centisecs
641*4882a593Smuzhiyun			echo $((100*$DEF_XFS_BUFD_INTERVAL))	> /proc/sys/fs/xfs/xfsbufd_centisecs
642*4882a593Smuzhiyun		fi
643*4882a593Smuzhiyun		case "$KLEVEL" in
644*4882a593Smuzhiyun			"2.4")
645*4882a593Smuzhiyun				echo "30 500 0 0 $U_AGE $B_AGE 60 20 0"	> /proc/sys/vm/bdflush
646*4882a593Smuzhiyun				;;
647*4882a593Smuzhiyun			"2.6")
648*4882a593Smuzhiyun				echo "$U_AGE"				> /proc/sys/vm/dirty_writeback_centisecs
649*4882a593Smuzhiyun				echo "$B_AGE"				> /proc/sys/vm/dirty_expire_centisecs
650*4882a593Smuzhiyun				echo "$DEF_DIRTY_RATIO"			> /proc/sys/vm/dirty_ratio
651*4882a593Smuzhiyun				echo "$DEF_DIRTY_BACKGROUND_RATIO"	> /proc/sys/vm/dirty_background_ratio
652*4882a593Smuzhiyun				;;
653*4882a593Smuzhiyun		esac
654*4882a593Smuzhiyun		if [ $DO_REMOUNTS -eq 1 ] ; then
655*4882a593Smuzhiyun			cat /etc/mtab | while read DEV MP FST OPTS DUMP PASS ; do
656*4882a593Smuzhiyun				# Reset commit and atime options to defaults.
657*4882a593Smuzhiyun				if [ "$FST" = 'unknown' ]; then
658*4882a593Smuzhiyun					FST=$(deduce_fstype $MP)
659*4882a593Smuzhiyun				fi
660*4882a593Smuzhiyun				case "$FST" in
661*4882a593Smuzhiyun					"ext3"|"reiserfs")
662*4882a593Smuzhiyun						PARSEDOPTS="$(parse_mount_opts_wfstab $DEV commit $OPTS)"
663*4882a593Smuzhiyun						PARSEDOPTS="$(parse_yesno_opts_wfstab $DEV atime atime $PARSEDOPTS)"
664*4882a593Smuzhiyun						mount $DEV -t $FST $MP -o remount,$PARSEDOPTS
665*4882a593Smuzhiyun						;;
666*4882a593Smuzhiyun					"xfs")
667*4882a593Smuzhiyun						PARSEDOPTS="$(parse_yesno_opts_wfstab $DEV atime atime $OPTS)"
668*4882a593Smuzhiyun						mount $DEV -t $FST $MP -o remount,$PARSEDOPTS
669*4882a593Smuzhiyun						;;
670*4882a593Smuzhiyun				esac
671*4882a593Smuzhiyun				if [ -b $DEV ] ; then
672*4882a593Smuzhiyun					blockdev --setra 256 $DEV
673*4882a593Smuzhiyun				fi
674*4882a593Smuzhiyun			done
675*4882a593Smuzhiyun		fi
676*4882a593Smuzhiyun		if [ $DO_HD -eq 1 ] ; then
677*4882a593Smuzhiyun			for THISHD in $HD ; do
678*4882a593Smuzhiyun				/sbin/hdparm -S $AC_HD $THISHD > /dev/null 2>&1
679*4882a593Smuzhiyun				/sbin/hdparm -B 255 $THISHD > /dev/null 2>&1
680*4882a593Smuzhiyun			done
681*4882a593Smuzhiyun		fi
682*4882a593Smuzhiyun		if [ $DO_CPU -eq 1 -a -e /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq ]; then
683*4882a593Smuzhiyun			echo `cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq` > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
684*4882a593Smuzhiyun		fi
685*4882a593Smuzhiyun		echo "."
686*4882a593Smuzhiyun		;;
687*4882a593Smuzhiyun	*)
688*4882a593Smuzhiyun		echo "Usage: $0 {start|stop}" 2>&1
689*4882a593Smuzhiyun		exit 1
690*4882a593Smuzhiyun		;;
691*4882a593Smuzhiyun
692*4882a593Smuzhiyun  esac
693*4882a593Smuzhiyun
694*4882a593Smuzhiyun  exit 0
695*4882a593Smuzhiyun
696*4882a593Smuzhiyun
697*4882a593SmuzhiyunACPI integration
698*4882a593Smuzhiyun----------------
699*4882a593Smuzhiyun
700*4882a593SmuzhiyunDax Kelson submitted this so that the ACPI acpid daemon will
701*4882a593Smuzhiyunkick off the laptop_mode script and run hdparm. The part that
702*4882a593Smuzhiyunautomatically disables laptop mode when the battery is low was
703*4882a593Smuzhiyunwritten by Jan Topinski.
704*4882a593Smuzhiyun
705*4882a593Smuzhiyun/etc/acpi/events/ac_adapter::
706*4882a593Smuzhiyun
707*4882a593Smuzhiyun	event=ac_adapter
708*4882a593Smuzhiyun	action=/etc/acpi/actions/ac.sh %e
709*4882a593Smuzhiyun
710*4882a593Smuzhiyun/etc/acpi/events/battery::
711*4882a593Smuzhiyun
712*4882a593Smuzhiyun	event=battery.*
713*4882a593Smuzhiyun	action=/etc/acpi/actions/battery.sh %e
714*4882a593Smuzhiyun
715*4882a593Smuzhiyun/etc/acpi/actions/ac.sh::
716*4882a593Smuzhiyun
717*4882a593Smuzhiyun  #!/bin/bash
718*4882a593Smuzhiyun
719*4882a593Smuzhiyun  # ac on/offline event handler
720*4882a593Smuzhiyun
721*4882a593Smuzhiyun  status=`awk '/^state: / { print $2 }' /proc/acpi/ac_adapter/$2/state`
722*4882a593Smuzhiyun
723*4882a593Smuzhiyun  case $status in
724*4882a593Smuzhiyun          "on-line")
725*4882a593Smuzhiyun                  /sbin/laptop_mode stop
726*4882a593Smuzhiyun                  exit 0
727*4882a593Smuzhiyun          ;;
728*4882a593Smuzhiyun          "off-line")
729*4882a593Smuzhiyun                  /sbin/laptop_mode start
730*4882a593Smuzhiyun                  exit 0
731*4882a593Smuzhiyun          ;;
732*4882a593Smuzhiyun  esac
733*4882a593Smuzhiyun
734*4882a593Smuzhiyun
735*4882a593Smuzhiyun/etc/acpi/actions/battery.sh::
736*4882a593Smuzhiyun
737*4882a593Smuzhiyun  #! /bin/bash
738*4882a593Smuzhiyun
739*4882a593Smuzhiyun  # Automatically disable laptop mode when the battery almost runs out.
740*4882a593Smuzhiyun
741*4882a593Smuzhiyun  BATT_INFO=/proc/acpi/battery/$2/state
742*4882a593Smuzhiyun
743*4882a593Smuzhiyun  if [[ -f /proc/sys/vm/laptop_mode ]]
744*4882a593Smuzhiyun  then
745*4882a593Smuzhiyun     LM=`cat /proc/sys/vm/laptop_mode`
746*4882a593Smuzhiyun     if [[ $LM -gt 0 ]]
747*4882a593Smuzhiyun     then
748*4882a593Smuzhiyun       if [[ -f $BATT_INFO ]]
749*4882a593Smuzhiyun       then
750*4882a593Smuzhiyun          # Source the config file only now that we know we need
751*4882a593Smuzhiyun          if [ -f /etc/default/laptop-mode ] ; then
752*4882a593Smuzhiyun                  # Debian
753*4882a593Smuzhiyun                  . /etc/default/laptop-mode
754*4882a593Smuzhiyun          elif [ -f /etc/sysconfig/laptop-mode ] ; then
755*4882a593Smuzhiyun                  # Others
756*4882a593Smuzhiyun                  . /etc/sysconfig/laptop-mode
757*4882a593Smuzhiyun          fi
758*4882a593Smuzhiyun          MINIMUM_BATTERY_MINUTES=${MINIMUM_BATTERY_MINUTES:-'10'}
759*4882a593Smuzhiyun
760*4882a593Smuzhiyun          ACTION="`cat $BATT_INFO | grep charging | cut -c 26-`"
761*4882a593Smuzhiyun          if [[ ACTION -eq "discharging" ]]
762*4882a593Smuzhiyun          then
763*4882a593Smuzhiyun             PRESENT_RATE=`cat $BATT_INFO | grep "present rate:" | sed  "s/.* \([0-9][0-9]* \).*/\1/" `
764*4882a593Smuzhiyun             REMAINING=`cat $BATT_INFO | grep "remaining capacity:" | sed  "s/.* \([0-9][0-9]* \).*/\1/" `
765*4882a593Smuzhiyun          fi
766*4882a593Smuzhiyun          if (($REMAINING * 60 / $PRESENT_RATE < $MINIMUM_BATTERY_MINUTES))
767*4882a593Smuzhiyun          then
768*4882a593Smuzhiyun             /sbin/laptop_mode stop
769*4882a593Smuzhiyun          fi
770*4882a593Smuzhiyun       else
771*4882a593Smuzhiyun         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."
772*4882a593Smuzhiyun       fi
773*4882a593Smuzhiyun     fi
774*4882a593Smuzhiyun  fi
775*4882a593Smuzhiyun
776*4882a593Smuzhiyun
777*4882a593SmuzhiyunMonitoring tool
778*4882a593Smuzhiyun---------------
779*4882a593Smuzhiyun
780*4882a593SmuzhiyunBartek Kania submitted this, it can be used to measure how much time your disk
781*4882a593Smuzhiyunspends spun up/down.  See tools/laptop/dslm/dslm.c
782