About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Documentation / laptops / laptop-mode.txt


Based on kernel version 4.16.1. Page generated on 2018-04-09 11:53 EST.

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


About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog