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