19e1cbedeSMauro Carvalho Chehab===============================================
29e1cbedeSMauro Carvalho ChehabHow to conserve battery power using laptop-mode
39e1cbedeSMauro Carvalho Chehab===============================================
49e1cbedeSMauro Carvalho Chehab
59e1cbedeSMauro Carvalho ChehabDocument Author: Bart Samwel (bart@samwel.tk)
69e1cbedeSMauro Carvalho Chehab
79e1cbedeSMauro Carvalho ChehabDate created: January 2, 2004
89e1cbedeSMauro Carvalho Chehab
99e1cbedeSMauro Carvalho ChehabLast modified: December 06, 2004
109e1cbedeSMauro Carvalho Chehab
119e1cbedeSMauro Carvalho ChehabIntroduction
129e1cbedeSMauro Carvalho Chehab------------
139e1cbedeSMauro Carvalho Chehab
149e1cbedeSMauro Carvalho ChehabLaptop mode is used to minimize the time that the hard disk needs to be spun up,
159e1cbedeSMauro Carvalho Chehabto conserve battery power on laptops. It has been reported to cause significant
169e1cbedeSMauro Carvalho Chehabpower savings.
179e1cbedeSMauro Carvalho Chehab
189e1cbedeSMauro Carvalho Chehab.. Contents
199e1cbedeSMauro Carvalho Chehab
209e1cbedeSMauro Carvalho Chehab   * Introduction
219e1cbedeSMauro Carvalho Chehab   * Installation
229e1cbedeSMauro Carvalho Chehab   * Caveats
239e1cbedeSMauro Carvalho Chehab   * The Details
249e1cbedeSMauro Carvalho Chehab   * Tips & Tricks
259e1cbedeSMauro Carvalho Chehab   * Control script
269e1cbedeSMauro Carvalho Chehab   * ACPI integration
279e1cbedeSMauro Carvalho Chehab   * Monitoring tool
289e1cbedeSMauro Carvalho Chehab
299e1cbedeSMauro Carvalho Chehab
309e1cbedeSMauro Carvalho ChehabInstallation
319e1cbedeSMauro Carvalho Chehab------------
329e1cbedeSMauro Carvalho Chehab
339e1cbedeSMauro Carvalho ChehabTo use laptop mode, you don't need to set any kernel configuration options
349e1cbedeSMauro Carvalho Chehabor anything. Simply install all the files included in this document, and
359e1cbedeSMauro Carvalho Chehablaptop mode will automatically be started when you're on battery. For
369e1cbedeSMauro Carvalho Chehabyour convenience, a tarball containing an installer can be downloaded at:
379e1cbedeSMauro Carvalho Chehab
389e1cbedeSMauro Carvalho Chehab	http://www.samwel.tk/laptop_mode/laptop_mode/
399e1cbedeSMauro Carvalho Chehab
409e1cbedeSMauro Carvalho ChehabTo configure laptop mode, you need to edit the configuration file, which is
419e1cbedeSMauro Carvalho Chehablocated in /etc/default/laptop-mode on Debian-based systems, or in
429e1cbedeSMauro Carvalho Chehab/etc/sysconfig/laptop-mode on other systems.
439e1cbedeSMauro Carvalho Chehab
449e1cbedeSMauro Carvalho ChehabUnfortunately, automatic enabling of laptop mode does not work for
459e1cbedeSMauro Carvalho Chehablaptops that don't have ACPI. On those laptops, you need to start laptop
469e1cbedeSMauro Carvalho Chehabmode manually. To start laptop mode, run "laptop_mode start", and to
479e1cbedeSMauro Carvalho Chehabstop it, run "laptop_mode stop". (Note: The laptop mode tools package now
489e1cbedeSMauro Carvalho Chehabhas experimental support for APM, you might want to try that first.)
499e1cbedeSMauro Carvalho Chehab
509e1cbedeSMauro Carvalho Chehab
519e1cbedeSMauro Carvalho ChehabCaveats
529e1cbedeSMauro Carvalho Chehab-------
539e1cbedeSMauro Carvalho Chehab
549e1cbedeSMauro Carvalho Chehab* The downside of laptop mode is that you have a chance of losing up to 10
559e1cbedeSMauro Carvalho Chehab  minutes of work. If you cannot afford this, don't use it! The supplied ACPI
569e1cbedeSMauro Carvalho Chehab  scripts automatically turn off laptop mode when the battery almost runs out,
579e1cbedeSMauro Carvalho Chehab  so that you won't lose any data at the end of your battery life.
589e1cbedeSMauro Carvalho Chehab
599e1cbedeSMauro Carvalho Chehab* Most desktop hard drives have a very limited lifetime measured in spindown
609e1cbedeSMauro Carvalho Chehab  cycles, typically about 50.000 times (it's usually listed on the spec sheet).
619e1cbedeSMauro Carvalho Chehab  Check your drive's rating, and don't wear down your drive's lifetime if you
629e1cbedeSMauro Carvalho Chehab  don't need to.
639e1cbedeSMauro Carvalho Chehab
649e1cbedeSMauro Carvalho Chehab* If you mount some of your ext3/reiserfs filesystems with the -n option, then
659e1cbedeSMauro Carvalho Chehab  the control script will not be able to remount them correctly. You must set
669e1cbedeSMauro Carvalho Chehab  DO_REMOUNTS=0 in the control script, otherwise it will remount them with the
679e1cbedeSMauro Carvalho Chehab  wrong options -- or it will fail because it cannot write to /etc/mtab.
689e1cbedeSMauro Carvalho Chehab
699e1cbedeSMauro Carvalho Chehab* If you have your filesystems listed as type "auto" in fstab, like I did, then
709e1cbedeSMauro Carvalho Chehab  the control script will not recognize them as filesystems that need remounting.
719e1cbedeSMauro Carvalho Chehab  You must list the filesystems with their true type instead.
729e1cbedeSMauro Carvalho Chehab
739e1cbedeSMauro Carvalho Chehab* It has been reported that some versions of the mutt mail client use file access
749e1cbedeSMauro Carvalho Chehab  times to determine whether a folder contains new mail. If you use mutt and
759e1cbedeSMauro Carvalho Chehab  experience this, you must disable the noatime remounting by setting the option
769e1cbedeSMauro Carvalho Chehab  DO_REMOUNT_NOATIME to 0 in the configuration file.
779e1cbedeSMauro Carvalho Chehab
789e1cbedeSMauro Carvalho Chehab
799e1cbedeSMauro Carvalho ChehabThe Details
809e1cbedeSMauro Carvalho Chehab-----------
819e1cbedeSMauro Carvalho Chehab
829e1cbedeSMauro Carvalho ChehabLaptop mode is controlled by the knob /proc/sys/vm/laptop_mode. This knob is
839e1cbedeSMauro Carvalho Chehabpresent for all kernels that have the laptop mode patch, regardless of any
849e1cbedeSMauro Carvalho Chehabconfiguration options. When the knob is set, any physical disk I/O (that might
859e1cbedeSMauro Carvalho Chehabhave caused the hard disk to spin up) causes Linux to flush all dirty blocks. The
869e1cbedeSMauro Carvalho Chehabresult of this is that after a disk has spun down, it will not be spun up
879e1cbedeSMauro Carvalho Chehabanymore to write dirty blocks, because those blocks had already been written
889e1cbedeSMauro Carvalho Chehabimmediately after the most recent read operation. The value of the laptop_mode
899e1cbedeSMauro Carvalho Chehabknob determines the time between the occurrence of disk I/O and when the flush
909e1cbedeSMauro Carvalho Chehabis triggered. A sensible value for the knob is 5 seconds. Setting the knob to
919e1cbedeSMauro Carvalho Chehab0 disables laptop mode.
929e1cbedeSMauro Carvalho Chehab
939e1cbedeSMauro Carvalho ChehabTo increase the effectiveness of the laptop_mode strategy, the laptop_mode
949e1cbedeSMauro Carvalho Chehabcontrol script increases dirty_expire_centisecs and dirty_writeback_centisecs in
959e1cbedeSMauro Carvalho Chehab/proc/sys/vm to about 10 minutes (by default), which means that pages that are
969e1cbedeSMauro Carvalho Chehabdirtied are not forced to be written to disk as often. The control script also
979e1cbedeSMauro Carvalho Chehabchanges the dirty background ratio, so that background writeback of dirty pages
989e1cbedeSMauro Carvalho Chehabis not done anymore. Combined with a higher commit value (also 10 minutes) for
999e1cbedeSMauro Carvalho Chehabext3 or ReiserFS filesystems (also done automatically by the control script),
1009e1cbedeSMauro Carvalho Chehabthis results in concentration of disk activity in a small time interval which
1019e1cbedeSMauro Carvalho Chehaboccurs only once every 10 minutes, or whenever the disk is forced to spin up by
1029e1cbedeSMauro Carvalho Chehaba cache miss. The disk can then be spun down in the periods of inactivity.
1039e1cbedeSMauro Carvalho Chehab
1049e1cbedeSMauro Carvalho Chehab
1059e1cbedeSMauro Carvalho ChehabConfiguration
1069e1cbedeSMauro Carvalho Chehab-------------
1079e1cbedeSMauro Carvalho Chehab
1089e1cbedeSMauro Carvalho ChehabThe laptop mode configuration file is located in /etc/default/laptop-mode on
1099e1cbedeSMauro Carvalho ChehabDebian-based systems, or in /etc/sysconfig/laptop-mode on other systems. It
1109e1cbedeSMauro Carvalho Chehabcontains the following options:
1119e1cbedeSMauro Carvalho Chehab
1129e1cbedeSMauro Carvalho ChehabMAX_AGE:
1139e1cbedeSMauro Carvalho Chehab
1149e1cbedeSMauro Carvalho ChehabMaximum time, in seconds, of hard drive spindown time that you are
1159e1cbedeSMauro Carvalho Chehabcomfortable with. Worst case, it's possible that you could lose this
1169e1cbedeSMauro Carvalho Chehabamount of work if your battery fails while you're in laptop mode.
1179e1cbedeSMauro Carvalho Chehab
1189e1cbedeSMauro Carvalho ChehabMINIMUM_BATTERY_MINUTES:
1199e1cbedeSMauro Carvalho Chehab
1209e1cbedeSMauro Carvalho ChehabAutomatically disable laptop mode if the remaining number of minutes of
1219e1cbedeSMauro Carvalho Chehabbattery power is less than this value. Default is 10 minutes.
1229e1cbedeSMauro Carvalho Chehab
1239e1cbedeSMauro Carvalho ChehabAC_HD/BATT_HD:
1249e1cbedeSMauro Carvalho Chehab
1259e1cbedeSMauro Carvalho ChehabThe idle timeout that should be set on your hard drive when laptop mode
1269e1cbedeSMauro Carvalho Chehabis active (BATT_HD) and when it is not active (AC_HD). The defaults are
1279e1cbedeSMauro Carvalho Chehab20 seconds (value 4) for BATT_HD  and 2 hours (value 244) for AC_HD. The
1289e1cbedeSMauro Carvalho Chehabpossible values are those listed in the manual page for "hdparm" for the
1299e1cbedeSMauro Carvalho Chehab"-S" option.
1309e1cbedeSMauro Carvalho Chehab
1319e1cbedeSMauro Carvalho ChehabHD:
1329e1cbedeSMauro Carvalho Chehab
1339e1cbedeSMauro Carvalho ChehabThe devices for which the spindown timeout should be adjusted by laptop mode.
1349e1cbedeSMauro Carvalho ChehabDefault is /dev/hda. If you specify multiple devices, separate them by a space.
1359e1cbedeSMauro Carvalho Chehab
1369e1cbedeSMauro Carvalho ChehabREADAHEAD:
1379e1cbedeSMauro Carvalho Chehab
1389e1cbedeSMauro Carvalho ChehabDisk readahead, in 512-byte sectors, while laptop mode is active. A large
1399e1cbedeSMauro Carvalho Chehabreadahead can prevent disk accesses for things like executable pages (which are
1409e1cbedeSMauro Carvalho Chehabloaded on demand while the application executes) and sequentially accessed data
1419e1cbedeSMauro Carvalho Chehab(MP3s).
1429e1cbedeSMauro Carvalho Chehab
1439e1cbedeSMauro Carvalho ChehabDO_REMOUNTS:
1449e1cbedeSMauro Carvalho Chehab
1459e1cbedeSMauro Carvalho ChehabThe control script automatically remounts any mounted journaled filesystems
1469e1cbedeSMauro Carvalho Chehabwith appropriate commit interval options. When this option is set to 0, this
1479e1cbedeSMauro Carvalho Chehabfeature is disabled.
1489e1cbedeSMauro Carvalho Chehab
1499e1cbedeSMauro Carvalho ChehabDO_REMOUNT_NOATIME:
1509e1cbedeSMauro Carvalho Chehab
1519e1cbedeSMauro Carvalho ChehabWhen remounting, should the filesystems be remounted with the noatime option?
1529e1cbedeSMauro Carvalho ChehabNormally, this is set to "1" (enabled), but there may be programs that require
1539e1cbedeSMauro Carvalho Chehabaccess time recording.
1549e1cbedeSMauro Carvalho Chehab
1559e1cbedeSMauro Carvalho ChehabDIRTY_RATIO:
1569e1cbedeSMauro Carvalho Chehab
1579e1cbedeSMauro Carvalho ChehabThe percentage of memory that is allowed to contain "dirty" or unsaved data
1589e1cbedeSMauro Carvalho Chehabbefore a writeback is forced, while laptop mode is active. Corresponds to
1599e1cbedeSMauro Carvalho Chehabthe /proc/sys/vm/dirty_ratio sysctl.
1609e1cbedeSMauro Carvalho Chehab
1619e1cbedeSMauro Carvalho ChehabDIRTY_BACKGROUND_RATIO:
1629e1cbedeSMauro Carvalho Chehab
1639e1cbedeSMauro Carvalho ChehabThe percentage of memory that is allowed to contain "dirty" or unsaved data
1649e1cbedeSMauro Carvalho Chehabafter a forced writeback is done due to an exceeding of DIRTY_RATIO. Set
1659e1cbedeSMauro Carvalho Chehabthis nice and low. This corresponds to the /proc/sys/vm/dirty_background_ratio
1669e1cbedeSMauro Carvalho Chehabsysctl.
1679e1cbedeSMauro Carvalho Chehab
1689e1cbedeSMauro Carvalho ChehabNote that the behaviour of dirty_background_ratio is quite different
1699e1cbedeSMauro Carvalho Chehabwhen laptop mode is active and when it isn't. When laptop mode is inactive,
1709e1cbedeSMauro Carvalho Chehabdirty_background_ratio is the threshold percentage at which background writeouts
1719e1cbedeSMauro Carvalho Chehabstart taking place. When laptop mode is active, however, background writeouts
1729e1cbedeSMauro Carvalho Chehabare disabled, and the dirty_background_ratio only determines how much writeback
1739e1cbedeSMauro Carvalho Chehabis done when dirty_ratio is reached.
1749e1cbedeSMauro Carvalho Chehab
1759e1cbedeSMauro Carvalho ChehabDO_CPU:
1769e1cbedeSMauro Carvalho Chehab
1779e1cbedeSMauro Carvalho ChehabEnable CPU frequency scaling when in laptop mode. (Requires CPUFreq to be setup.
1789e1cbedeSMauro Carvalho ChehabSee Documentation/admin-guide/pm/cpufreq.rst for more info. Disabled by default.)
1799e1cbedeSMauro Carvalho Chehab
1809e1cbedeSMauro Carvalho ChehabCPU_MAXFREQ:
1819e1cbedeSMauro Carvalho Chehab
1829e1cbedeSMauro Carvalho ChehabWhen on battery, what is the maximum CPU speed that the system should use? Legal
1839e1cbedeSMauro Carvalho Chehabvalues are "slowest" for the slowest speed that your CPU is able to operate at,
1849e1cbedeSMauro Carvalho Chehabor a value listed in /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies.
1859e1cbedeSMauro Carvalho Chehab
1869e1cbedeSMauro Carvalho Chehab
1879e1cbedeSMauro Carvalho ChehabTips & Tricks
1889e1cbedeSMauro Carvalho Chehab-------------
1899e1cbedeSMauro Carvalho Chehab
1909e1cbedeSMauro Carvalho Chehab* Bartek Kania reports getting up to 50 minutes of extra battery life (on top
1919e1cbedeSMauro Carvalho Chehab  of his regular 3 to 3.5 hours) using a spindown time of 5 seconds (BATT_HD=1).
1929e1cbedeSMauro Carvalho Chehab
1939e1cbedeSMauro Carvalho Chehab* You can spin down the disk while playing MP3, by setting disk readahead
1949e1cbedeSMauro Carvalho Chehab  to 8MB (READAHEAD=16384). Effectively, the disk will read a complete MP3 at
1959e1cbedeSMauro Carvalho Chehab  once, and will then spin down while the MP3 is playing. (Thanks to Bartek
1969e1cbedeSMauro Carvalho Chehab  Kania.)
1979e1cbedeSMauro Carvalho Chehab
1989e1cbedeSMauro Carvalho Chehab* Drew Scott Daniels observed: "I don't know why, but when I decrease the number
1999e1cbedeSMauro Carvalho Chehab  of colours that my display uses it consumes less battery power. I've seen
2009e1cbedeSMauro Carvalho Chehab  this on powerbooks too. I hope that this is a piece of information that
2019e1cbedeSMauro Carvalho Chehab  might be useful to the Laptop Mode patch or its users."
2029e1cbedeSMauro Carvalho Chehab
2039e1cbedeSMauro Carvalho Chehab* In syslog.conf, you can prefix entries with a dash `-` to omit syncing the
2049e1cbedeSMauro Carvalho Chehab  file after every logging. When you're using laptop-mode and your disk doesn't
2059e1cbedeSMauro Carvalho Chehab  spin down, this is a likely culprit.
2069e1cbedeSMauro Carvalho Chehab
2079e1cbedeSMauro Carvalho Chehab* Richard Atterer observed that laptop mode does not work well with noflushd
2089e1cbedeSMauro Carvalho Chehab  (http://noflushd.sourceforge.net/), it seems that noflushd prevents laptop-mode
2099e1cbedeSMauro Carvalho Chehab  from doing its thing.
2109e1cbedeSMauro Carvalho Chehab
2119e1cbedeSMauro Carvalho Chehab* If you're worried about your data, you might want to consider using a USB
2129e1cbedeSMauro Carvalho Chehab  memory stick or something like that as a "working area". (Be aware though
2139e1cbedeSMauro Carvalho Chehab  that flash memory can only handle a limited number of writes, and overuse
2149e1cbedeSMauro Carvalho Chehab  may wear out your memory stick pretty quickly. Do _not_ use journalling
2159e1cbedeSMauro Carvalho Chehab  filesystems on flash memory sticks.)
2169e1cbedeSMauro Carvalho Chehab
2179e1cbedeSMauro Carvalho Chehab
2189e1cbedeSMauro Carvalho ChehabConfiguration file for control and ACPI battery scripts
2199e1cbedeSMauro Carvalho Chehab-------------------------------------------------------
2209e1cbedeSMauro Carvalho Chehab
2219e1cbedeSMauro Carvalho ChehabThis allows the tunables to be changed for the scripts via an external
2229e1cbedeSMauro Carvalho Chehabconfiguration file
2239e1cbedeSMauro Carvalho Chehab
2249e1cbedeSMauro Carvalho ChehabIt should be installed as /etc/default/laptop-mode on Debian, and as
2259e1cbedeSMauro Carvalho Chehab/etc/sysconfig/laptop-mode on Red Hat, SUSE, Mandrake, and other work-alikes.
2269e1cbedeSMauro Carvalho Chehab
2279e1cbedeSMauro Carvalho ChehabConfig file::
2289e1cbedeSMauro Carvalho Chehab
2299e1cbedeSMauro Carvalho Chehab  # Maximum time, in seconds, of hard drive spindown time that you are
2309e1cbedeSMauro Carvalho Chehab  # comfortable with. Worst case, it's possible that you could lose this
2319e1cbedeSMauro Carvalho Chehab  # amount of work if your battery fails you while in laptop mode.
2329e1cbedeSMauro Carvalho Chehab  #MAX_AGE=600
2339e1cbedeSMauro Carvalho Chehab
2349e1cbedeSMauro Carvalho Chehab  # Automatically disable laptop mode when the number of minutes of battery
2359e1cbedeSMauro Carvalho Chehab  # that you have left goes below this threshold.
2369e1cbedeSMauro Carvalho Chehab  MINIMUM_BATTERY_MINUTES=10
2379e1cbedeSMauro Carvalho Chehab
2389e1cbedeSMauro Carvalho Chehab  # Read-ahead, in 512-byte sectors. You can spin down the disk while playing MP3/OGG
2399e1cbedeSMauro Carvalho Chehab  # by setting the disk readahead to 8MB (READAHEAD=16384). Effectively, the disk
2409e1cbedeSMauro Carvalho Chehab  # will read a complete MP3 at once, and will then spin down while the MP3/OGG is
2419e1cbedeSMauro Carvalho Chehab  # playing.
2429e1cbedeSMauro Carvalho Chehab  #READAHEAD=4096
2439e1cbedeSMauro Carvalho Chehab
2449e1cbedeSMauro Carvalho Chehab  # Shall we remount journaled fs. with appropriate commit interval? (1=yes)
2459e1cbedeSMauro Carvalho Chehab  #DO_REMOUNTS=1
2469e1cbedeSMauro Carvalho Chehab
2479e1cbedeSMauro Carvalho Chehab  # And shall we add the "noatime" option to that as well? (1=yes)
2489e1cbedeSMauro Carvalho Chehab  #DO_REMOUNT_NOATIME=1
2499e1cbedeSMauro Carvalho Chehab
2509e1cbedeSMauro Carvalho Chehab  # Dirty synchronous ratio.  At this percentage of dirty pages the process
2519e1cbedeSMauro Carvalho Chehab  # which
2529e1cbedeSMauro Carvalho Chehab  # calls write() does its own writeback
2539e1cbedeSMauro Carvalho Chehab  #DIRTY_RATIO=40
2549e1cbedeSMauro Carvalho Chehab
2559e1cbedeSMauro Carvalho Chehab  #
2569e1cbedeSMauro Carvalho Chehab  # Allowed dirty background ratio, in percent.  Once DIRTY_RATIO has been
2579e1cbedeSMauro Carvalho Chehab  # exceeded, the kernel will wake flusher threads which will then reduce the
2589e1cbedeSMauro Carvalho Chehab  # amount of dirty memory to dirty_background_ratio.  Set this nice and low,
2599e1cbedeSMauro Carvalho Chehab  # so once some writeout has commenced, we do a lot of it.
2609e1cbedeSMauro Carvalho Chehab  #
2619e1cbedeSMauro Carvalho Chehab  #DIRTY_BACKGROUND_RATIO=5
2629e1cbedeSMauro Carvalho Chehab
2639e1cbedeSMauro Carvalho Chehab  # kernel default dirty buffer age
2649e1cbedeSMauro Carvalho Chehab  #DEF_AGE=30
2659e1cbedeSMauro Carvalho Chehab  #DEF_UPDATE=5
2669e1cbedeSMauro Carvalho Chehab  #DEF_DIRTY_BACKGROUND_RATIO=10
2679e1cbedeSMauro Carvalho Chehab  #DEF_DIRTY_RATIO=40
2689e1cbedeSMauro Carvalho Chehab  #DEF_XFS_AGE_BUFFER=15
2699e1cbedeSMauro Carvalho Chehab  #DEF_XFS_SYNC_INTERVAL=30
2709e1cbedeSMauro Carvalho Chehab  #DEF_XFS_BUFD_INTERVAL=1
2719e1cbedeSMauro Carvalho Chehab
2729e1cbedeSMauro Carvalho Chehab  # This must be adjusted manually to the value of HZ in the running kernel
2739e1cbedeSMauro Carvalho Chehab  # on 2.4, until the XFS people change their 2.4 external interfaces to work in
2749e1cbedeSMauro Carvalho Chehab  # centisecs. This can be automated, but it's a work in progress that still
2759e1cbedeSMauro Carvalho Chehab  # needs# some fixes. On 2.6 kernels, XFS uses USER_HZ instead of HZ for
2769e1cbedeSMauro Carvalho Chehab  # external interfaces, and that is currently always set to 100. So you don't
2779e1cbedeSMauro Carvalho Chehab  # need to change this on 2.6.
2789e1cbedeSMauro Carvalho Chehab  #XFS_HZ=100
2799e1cbedeSMauro Carvalho Chehab
2809e1cbedeSMauro Carvalho Chehab  # Should the maximum CPU frequency be adjusted down while on battery?
2819e1cbedeSMauro Carvalho Chehab  # Requires CPUFreq to be setup.
2829e1cbedeSMauro Carvalho Chehab  # See Documentation/admin-guide/pm/cpufreq.rst for more info
2839e1cbedeSMauro Carvalho Chehab  #DO_CPU=0
2849e1cbedeSMauro Carvalho Chehab
2859e1cbedeSMauro Carvalho Chehab  # When on battery what is the maximum CPU speed that the system should
2869e1cbedeSMauro Carvalho Chehab  # use? Legal values are "slowest" for the slowest speed that your
2879e1cbedeSMauro Carvalho Chehab  # CPU is able to operate at, or a value listed in:
2889e1cbedeSMauro Carvalho Chehab  # /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
2899e1cbedeSMauro Carvalho Chehab  # Only applicable if DO_CPU=1.
2909e1cbedeSMauro Carvalho Chehab  #CPU_MAXFREQ=slowest
2919e1cbedeSMauro Carvalho Chehab
2929e1cbedeSMauro Carvalho Chehab  # Idle timeout for your hard drive (man hdparm for valid values, -S option)
2939e1cbedeSMauro Carvalho Chehab  # Default is 2 hours on AC (AC_HD=244) and 20 seconds for battery (BATT_HD=4).
2949e1cbedeSMauro Carvalho Chehab  #AC_HD=244
2959e1cbedeSMauro Carvalho Chehab  #BATT_HD=4
2969e1cbedeSMauro Carvalho Chehab
2979e1cbedeSMauro Carvalho Chehab  # The drives for which to adjust the idle timeout. Separate them by a space,
2989e1cbedeSMauro Carvalho Chehab  # e.g. HD="/dev/hda /dev/hdb".
2999e1cbedeSMauro Carvalho Chehab  #HD="/dev/hda"
3009e1cbedeSMauro Carvalho Chehab
3019e1cbedeSMauro Carvalho Chehab  # Set the spindown timeout on a hard drive?
3029e1cbedeSMauro Carvalho Chehab  #DO_HD=1
3039e1cbedeSMauro Carvalho Chehab
3049e1cbedeSMauro Carvalho Chehab
3059e1cbedeSMauro Carvalho ChehabControl script
3069e1cbedeSMauro Carvalho Chehab--------------
3079e1cbedeSMauro Carvalho Chehab
3089e1cbedeSMauro Carvalho ChehabPlease note that this control script works for the Linux 2.4 and 2.6 series (thanks
3099e1cbedeSMauro Carvalho Chehabto Kiko Piris).
3109e1cbedeSMauro Carvalho Chehab
3119e1cbedeSMauro Carvalho ChehabControl script::
3129e1cbedeSMauro Carvalho Chehab
3139e1cbedeSMauro Carvalho Chehab  #!/bin/bash
3149e1cbedeSMauro Carvalho Chehab
3159e1cbedeSMauro Carvalho Chehab  # start or stop laptop_mode, best run by a power management daemon when
3169e1cbedeSMauro Carvalho Chehab  # ac gets connected/disconnected from a laptop
3179e1cbedeSMauro Carvalho Chehab  #
3189e1cbedeSMauro Carvalho Chehab  # install as /sbin/laptop_mode
3199e1cbedeSMauro Carvalho Chehab  #
3209e1cbedeSMauro Carvalho Chehab  # Contributors to this script:   Kiko Piris
3219e1cbedeSMauro Carvalho Chehab  #				 Bart Samwel
3229e1cbedeSMauro Carvalho Chehab  #				 Micha Feigin
3239e1cbedeSMauro Carvalho Chehab  #				 Andrew Morton
3249e1cbedeSMauro Carvalho Chehab  #				 Herve Eychenne
3259e1cbedeSMauro Carvalho Chehab  #				 Dax Kelson
3269e1cbedeSMauro Carvalho Chehab  #
3279e1cbedeSMauro Carvalho Chehab  # Original Linux 2.4 version by: Jens Axboe
3289e1cbedeSMauro Carvalho Chehab
3299e1cbedeSMauro Carvalho Chehab  #############################################################################
3309e1cbedeSMauro Carvalho Chehab
3319e1cbedeSMauro Carvalho Chehab  # Source config
3329e1cbedeSMauro Carvalho Chehab  if [ -f /etc/default/laptop-mode ] ; then
3339e1cbedeSMauro Carvalho Chehab	# Debian
3349e1cbedeSMauro Carvalho Chehab	. /etc/default/laptop-mode
3359e1cbedeSMauro Carvalho Chehab  elif [ -f /etc/sysconfig/laptop-mode ] ; then
3369e1cbedeSMauro Carvalho Chehab	# Others
3379e1cbedeSMauro Carvalho Chehab          . /etc/sysconfig/laptop-mode
3389e1cbedeSMauro Carvalho Chehab  fi
3399e1cbedeSMauro Carvalho Chehab
3409e1cbedeSMauro Carvalho Chehab  # Don't raise an error if the config file is incomplete
3419e1cbedeSMauro Carvalho Chehab  # set defaults instead:
3429e1cbedeSMauro Carvalho Chehab
3439e1cbedeSMauro Carvalho Chehab  # Maximum time, in seconds, of hard drive spindown time that you are
3449e1cbedeSMauro Carvalho Chehab  # comfortable with. Worst case, it's possible that you could lose this
3459e1cbedeSMauro Carvalho Chehab  # amount of work if your battery fails you while in laptop mode.
3469e1cbedeSMauro Carvalho Chehab  MAX_AGE=${MAX_AGE:-'600'}
3479e1cbedeSMauro Carvalho Chehab
3489e1cbedeSMauro Carvalho Chehab  # Read-ahead, in kilobytes
3499e1cbedeSMauro Carvalho Chehab  READAHEAD=${READAHEAD:-'4096'}
3509e1cbedeSMauro Carvalho Chehab
3519e1cbedeSMauro Carvalho Chehab  # Shall we remount journaled fs. with appropriate commit interval? (1=yes)
3529e1cbedeSMauro Carvalho Chehab  DO_REMOUNTS=${DO_REMOUNTS:-'1'}
3539e1cbedeSMauro Carvalho Chehab
3549e1cbedeSMauro Carvalho Chehab  # And shall we add the "noatime" option to that as well? (1=yes)
3559e1cbedeSMauro Carvalho Chehab  DO_REMOUNT_NOATIME=${DO_REMOUNT_NOATIME:-'1'}
3569e1cbedeSMauro Carvalho Chehab
3579e1cbedeSMauro Carvalho Chehab  # Shall we adjust the idle timeout on a hard drive?
3589e1cbedeSMauro Carvalho Chehab  DO_HD=${DO_HD:-'1'}
3599e1cbedeSMauro Carvalho Chehab
3609e1cbedeSMauro Carvalho Chehab  # Adjust idle timeout on which hard drive?
3619e1cbedeSMauro Carvalho Chehab  HD="${HD:-'/dev/hda'}"
3629e1cbedeSMauro Carvalho Chehab
3639e1cbedeSMauro Carvalho Chehab  # spindown time for HD (hdparm -S values)
3649e1cbedeSMauro Carvalho Chehab  AC_HD=${AC_HD:-'244'}
3659e1cbedeSMauro Carvalho Chehab  BATT_HD=${BATT_HD:-'4'}
3669e1cbedeSMauro Carvalho Chehab
3679e1cbedeSMauro Carvalho Chehab  # Dirty synchronous ratio.  At this percentage of dirty pages the process which
3689e1cbedeSMauro Carvalho Chehab  # calls write() does its own writeback
3699e1cbedeSMauro Carvalho Chehab  DIRTY_RATIO=${DIRTY_RATIO:-'40'}
3709e1cbedeSMauro Carvalho Chehab
3719e1cbedeSMauro Carvalho Chehab  # cpu frequency scaling
3729e1cbedeSMauro Carvalho Chehab  # See Documentation/admin-guide/pm/cpufreq.rst for more info
3739e1cbedeSMauro Carvalho Chehab  DO_CPU=${CPU_MANAGE:-'0'}
3749e1cbedeSMauro Carvalho Chehab  CPU_MAXFREQ=${CPU_MAXFREQ:-'slowest'}
3759e1cbedeSMauro Carvalho Chehab
3769e1cbedeSMauro Carvalho Chehab  #
3779e1cbedeSMauro Carvalho Chehab  # Allowed dirty background ratio, in percent.  Once DIRTY_RATIO has been
3789e1cbedeSMauro Carvalho Chehab  # exceeded, the kernel will wake flusher threads which will then reduce the
3799e1cbedeSMauro Carvalho Chehab  # amount of dirty memory to dirty_background_ratio.  Set this nice and low,
3809e1cbedeSMauro Carvalho Chehab  # so once some writeout has commenced, we do a lot of it.
3819e1cbedeSMauro Carvalho Chehab  #
3829e1cbedeSMauro Carvalho Chehab  DIRTY_BACKGROUND_RATIO=${DIRTY_BACKGROUND_RATIO:-'5'}
3839e1cbedeSMauro Carvalho Chehab
3849e1cbedeSMauro Carvalho Chehab  # kernel default dirty buffer age
3859e1cbedeSMauro Carvalho Chehab  DEF_AGE=${DEF_AGE:-'30'}
3869e1cbedeSMauro Carvalho Chehab  DEF_UPDATE=${DEF_UPDATE:-'5'}
3879e1cbedeSMauro Carvalho Chehab  DEF_DIRTY_BACKGROUND_RATIO=${DEF_DIRTY_BACKGROUND_RATIO:-'10'}
3889e1cbedeSMauro Carvalho Chehab  DEF_DIRTY_RATIO=${DEF_DIRTY_RATIO:-'40'}
3899e1cbedeSMauro Carvalho Chehab  DEF_XFS_AGE_BUFFER=${DEF_XFS_AGE_BUFFER:-'15'}
3909e1cbedeSMauro Carvalho Chehab  DEF_XFS_SYNC_INTERVAL=${DEF_XFS_SYNC_INTERVAL:-'30'}
3919e1cbedeSMauro Carvalho Chehab  DEF_XFS_BUFD_INTERVAL=${DEF_XFS_BUFD_INTERVAL:-'1'}
3929e1cbedeSMauro Carvalho Chehab
3939e1cbedeSMauro Carvalho Chehab  # This must be adjusted manually to the value of HZ in the running kernel
3949e1cbedeSMauro Carvalho Chehab  # on 2.4, until the XFS people change their 2.4 external interfaces to work in
3959e1cbedeSMauro Carvalho Chehab  # centisecs. This can be automated, but it's a work in progress that still needs
3969e1cbedeSMauro Carvalho Chehab  # some fixes. On 2.6 kernels, XFS uses USER_HZ instead of HZ for external
3979e1cbedeSMauro Carvalho Chehab  # interfaces, and that is currently always set to 100. So you don't need to
3989e1cbedeSMauro Carvalho Chehab  # change this on 2.6.
3999e1cbedeSMauro Carvalho Chehab  XFS_HZ=${XFS_HZ:-'100'}
4009e1cbedeSMauro Carvalho Chehab
4019e1cbedeSMauro Carvalho Chehab  #############################################################################
4029e1cbedeSMauro Carvalho Chehab
4039e1cbedeSMauro Carvalho Chehab  KLEVEL="$(uname -r |
4049e1cbedeSMauro Carvalho Chehab               {
4059e1cbedeSMauro Carvalho Chehab	       IFS='.' read a b c
4069e1cbedeSMauro Carvalho Chehab	       echo $a.$b
4079e1cbedeSMauro Carvalho Chehab	     }
4089e1cbedeSMauro Carvalho Chehab  )"
4099e1cbedeSMauro Carvalho Chehab  case "$KLEVEL" in
4109e1cbedeSMauro Carvalho Chehab	"2.4"|"2.6")
4119e1cbedeSMauro Carvalho Chehab		;;
4129e1cbedeSMauro Carvalho Chehab	*)
4139e1cbedeSMauro Carvalho Chehab		echo "Unhandled kernel version: $KLEVEL ('uname -r' = '$(uname -r)')" >&2
4149e1cbedeSMauro Carvalho Chehab		exit 1
4159e1cbedeSMauro Carvalho Chehab		;;
4169e1cbedeSMauro Carvalho Chehab  esac
4179e1cbedeSMauro Carvalho Chehab
4189e1cbedeSMauro Carvalho Chehab  if [ ! -e /proc/sys/vm/laptop_mode ] ; then
4199e1cbedeSMauro Carvalho Chehab	echo "Kernel is not patched with laptop_mode patch." >&2
4209e1cbedeSMauro Carvalho Chehab	exit 1
4219e1cbedeSMauro Carvalho Chehab  fi
4229e1cbedeSMauro Carvalho Chehab
4239e1cbedeSMauro Carvalho Chehab  if [ ! -w /proc/sys/vm/laptop_mode ] ; then
4249e1cbedeSMauro Carvalho Chehab	echo "You do not have enough privileges to enable laptop_mode." >&2
4259e1cbedeSMauro Carvalho Chehab	exit 1
4269e1cbedeSMauro Carvalho Chehab  fi
4279e1cbedeSMauro Carvalho Chehab
4289e1cbedeSMauro Carvalho Chehab  # Remove an option (the first parameter) of the form option=<number> from
4299e1cbedeSMauro Carvalho Chehab  # a mount options string (the rest of the parameters).
4309e1cbedeSMauro Carvalho Chehab  parse_mount_opts () {
4319e1cbedeSMauro Carvalho Chehab	OPT="$1"
4329e1cbedeSMauro Carvalho Chehab	shift
4339e1cbedeSMauro Carvalho Chehab	echo ",$*," | sed		\
4349e1cbedeSMauro Carvalho Chehab	 -e 's/,'"$OPT"'=[0-9]*,/,/g'	\
4359e1cbedeSMauro Carvalho Chehab	 -e 's/,,*/,/g'			\
4369e1cbedeSMauro Carvalho Chehab	 -e 's/^,//'			\
4379e1cbedeSMauro Carvalho Chehab	 -e 's/,$//'
4389e1cbedeSMauro Carvalho Chehab  }
4399e1cbedeSMauro Carvalho Chehab
4409e1cbedeSMauro Carvalho Chehab  # Remove an option (the first parameter) without any arguments from
4419e1cbedeSMauro Carvalho Chehab  # a mount option string (the rest of the parameters).
4429e1cbedeSMauro Carvalho Chehab  parse_nonumber_mount_opts () {
4439e1cbedeSMauro Carvalho Chehab	OPT="$1"
4449e1cbedeSMauro Carvalho Chehab	shift
4459e1cbedeSMauro Carvalho Chehab	echo ",$*," | sed		\
4469e1cbedeSMauro Carvalho Chehab	 -e 's/,'"$OPT"',/,/g'		\
4479e1cbedeSMauro Carvalho Chehab	 -e 's/,,*/,/g'			\
4489e1cbedeSMauro Carvalho Chehab	 -e 's/^,//'			\
4499e1cbedeSMauro Carvalho Chehab	 -e 's/,$//'
4509e1cbedeSMauro Carvalho Chehab  }
4519e1cbedeSMauro Carvalho Chehab
4529e1cbedeSMauro Carvalho Chehab  # Find out the state of a yes/no option (e.g. "atime"/"noatime") in
4539e1cbedeSMauro Carvalho Chehab  # fstab for a given filesystem, and use this state to replace the
4549e1cbedeSMauro Carvalho Chehab  # value of the option in another mount options string. The device
4559e1cbedeSMauro Carvalho Chehab  # is the first argument, the option name the second, and the default
4569e1cbedeSMauro Carvalho Chehab  # value the third. The remainder is the mount options string.
4579e1cbedeSMauro Carvalho Chehab  #
4589e1cbedeSMauro Carvalho Chehab  # Example:
4599e1cbedeSMauro Carvalho Chehab  # parse_yesno_opts_wfstab /dev/hda1 atime atime defaults,noatime
4609e1cbedeSMauro Carvalho Chehab  #
4619e1cbedeSMauro Carvalho Chehab  # If fstab contains, say, "rw" for this filesystem, then the result
4629e1cbedeSMauro Carvalho Chehab  # will be "defaults,atime".
4639e1cbedeSMauro Carvalho Chehab  parse_yesno_opts_wfstab () {
4649e1cbedeSMauro Carvalho Chehab	L_DEV="$1"
4659e1cbedeSMauro Carvalho Chehab	OPT="$2"
4669e1cbedeSMauro Carvalho Chehab	DEF_OPT="$3"
4679e1cbedeSMauro Carvalho Chehab	shift 3
4689e1cbedeSMauro Carvalho Chehab	L_OPTS="$*"
4699e1cbedeSMauro Carvalho Chehab	PARSEDOPTS1="$(parse_nonumber_mount_opts $OPT $L_OPTS)"
4709e1cbedeSMauro Carvalho Chehab	PARSEDOPTS1="$(parse_nonumber_mount_opts no$OPT $PARSEDOPTS1)"
4719e1cbedeSMauro Carvalho Chehab	# Watch for a default atime in fstab
4729e1cbedeSMauro Carvalho Chehab	FSTAB_OPTS="$(awk '$1 == "'$L_DEV'" { print $4 }' /etc/fstab)"
4739e1cbedeSMauro Carvalho Chehab	if echo "$FSTAB_OPTS" | grep "$OPT" > /dev/null ; then
4749e1cbedeSMauro Carvalho Chehab		# option specified in fstab: extract the value and use it
4759e1cbedeSMauro Carvalho Chehab		if echo "$FSTAB_OPTS" | grep "no$OPT" > /dev/null ; then
4769e1cbedeSMauro Carvalho Chehab			echo "$PARSEDOPTS1,no$OPT"
4779e1cbedeSMauro Carvalho Chehab		else
4789e1cbedeSMauro Carvalho Chehab			# no$OPT not found -- so we must have $OPT.
4799e1cbedeSMauro Carvalho Chehab			echo "$PARSEDOPTS1,$OPT"
4809e1cbedeSMauro Carvalho Chehab		fi
4819e1cbedeSMauro Carvalho Chehab	else
4829e1cbedeSMauro Carvalho Chehab		# option not specified in fstab -- choose the default.
4839e1cbedeSMauro Carvalho Chehab		echo "$PARSEDOPTS1,$DEF_OPT"
4849e1cbedeSMauro Carvalho Chehab	fi
4859e1cbedeSMauro Carvalho Chehab  }
4869e1cbedeSMauro Carvalho Chehab
4879e1cbedeSMauro Carvalho Chehab  # Find out the state of a numbered option (e.g. "commit=NNN") in
4889e1cbedeSMauro Carvalho Chehab  # fstab for a given filesystem, and use this state to replace the
4899e1cbedeSMauro Carvalho Chehab  # value of the option in another mount options string. The device
4909e1cbedeSMauro Carvalho Chehab  # is the first argument, and the option name the second. The
4919e1cbedeSMauro Carvalho Chehab  # remainder is the mount options string in which the replacement
4929e1cbedeSMauro Carvalho Chehab  # must be done.
4939e1cbedeSMauro Carvalho Chehab  #
4949e1cbedeSMauro Carvalho Chehab  # Example:
4959e1cbedeSMauro Carvalho Chehab  # parse_mount_opts_wfstab /dev/hda1 commit defaults,commit=7
4969e1cbedeSMauro Carvalho Chehab  #
4979e1cbedeSMauro Carvalho Chehab  # If fstab contains, say, "commit=3,rw" for this filesystem, then the
4989e1cbedeSMauro Carvalho Chehab  # result will be "rw,commit=3".
4999e1cbedeSMauro Carvalho Chehab  parse_mount_opts_wfstab () {
5009e1cbedeSMauro Carvalho Chehab	L_DEV="$1"
5019e1cbedeSMauro Carvalho Chehab	OPT="$2"
5029e1cbedeSMauro Carvalho Chehab	shift 2
5039e1cbedeSMauro Carvalho Chehab	L_OPTS="$*"
5049e1cbedeSMauro Carvalho Chehab	PARSEDOPTS1="$(parse_mount_opts $OPT $L_OPTS)"
5059e1cbedeSMauro Carvalho Chehab	# Watch for a default commit in fstab
5069e1cbedeSMauro Carvalho Chehab	FSTAB_OPTS="$(awk '$1 == "'$L_DEV'" { print $4 }' /etc/fstab)"
5079e1cbedeSMauro Carvalho Chehab	if echo "$FSTAB_OPTS" | grep "$OPT=" > /dev/null ; then
5089e1cbedeSMauro Carvalho Chehab		# option specified in fstab: extract the value, and use it
5099e1cbedeSMauro Carvalho Chehab		echo -n "$PARSEDOPTS1,$OPT="
5109e1cbedeSMauro Carvalho Chehab		echo ",$FSTAB_OPTS," | sed \
5119e1cbedeSMauro Carvalho Chehab		 -e 's/.*,'"$OPT"'=//'	\
5129e1cbedeSMauro Carvalho Chehab		 -e 's/,.*//'
5139e1cbedeSMauro Carvalho Chehab	else
5149e1cbedeSMauro Carvalho Chehab		# option not specified in fstab: set it to 0
5159e1cbedeSMauro Carvalho Chehab		echo "$PARSEDOPTS1,$OPT=0"
5169e1cbedeSMauro Carvalho Chehab	fi
5179e1cbedeSMauro Carvalho Chehab  }
5189e1cbedeSMauro Carvalho Chehab
5199e1cbedeSMauro Carvalho Chehab  deduce_fstype () {
5209e1cbedeSMauro Carvalho Chehab	MP="$1"
5219e1cbedeSMauro Carvalho Chehab	# My root filesystem unfortunately has
5229e1cbedeSMauro Carvalho Chehab	# type "unknown" in /etc/mtab. If we encounter
5239e1cbedeSMauro Carvalho Chehab	# "unknown", we try to get the type from fstab.
5249e1cbedeSMauro Carvalho Chehab	cat /etc/fstab |
5259e1cbedeSMauro Carvalho Chehab	grep -v '^#' |
5269e1cbedeSMauro Carvalho Chehab	while read FSTAB_DEV FSTAB_MP FSTAB_FST FSTAB_OPTS FSTAB_DUMP FSTAB_DUMP ; do
5279e1cbedeSMauro Carvalho Chehab		if [ "$FSTAB_MP" = "$MP" ]; then
5289e1cbedeSMauro Carvalho Chehab			echo $FSTAB_FST
5299e1cbedeSMauro Carvalho Chehab			exit 0
5309e1cbedeSMauro Carvalho Chehab		fi
5319e1cbedeSMauro Carvalho Chehab	done
5329e1cbedeSMauro Carvalho Chehab  }
5339e1cbedeSMauro Carvalho Chehab
5349e1cbedeSMauro Carvalho Chehab  if [ $DO_REMOUNT_NOATIME -eq 1 ] ; then
5359e1cbedeSMauro Carvalho Chehab	NOATIME_OPT=",noatime"
5369e1cbedeSMauro Carvalho Chehab  fi
5379e1cbedeSMauro Carvalho Chehab
5389e1cbedeSMauro Carvalho Chehab  case "$1" in
5399e1cbedeSMauro Carvalho Chehab	start)
5409e1cbedeSMauro Carvalho Chehab		AGE=$((100*$MAX_AGE))
5419e1cbedeSMauro Carvalho Chehab		XFS_AGE=$(($XFS_HZ*$MAX_AGE))
5429e1cbedeSMauro Carvalho Chehab		echo -n "Starting laptop_mode"
5439e1cbedeSMauro Carvalho Chehab
5449e1cbedeSMauro Carvalho Chehab		if [ -d /proc/sys/vm/pagebuf ] ; then
5459e1cbedeSMauro Carvalho Chehab			# (For 2.4 and early 2.6.)
5469e1cbedeSMauro Carvalho Chehab			# This only needs to be set, not reset -- it is only used when
5479e1cbedeSMauro Carvalho Chehab			# laptop mode is enabled.
5489e1cbedeSMauro Carvalho Chehab			echo $XFS_AGE > /proc/sys/vm/pagebuf/lm_flush_age
5499e1cbedeSMauro Carvalho Chehab			echo $XFS_AGE > /proc/sys/fs/xfs/lm_sync_interval
5509e1cbedeSMauro Carvalho Chehab		elif [ -f /proc/sys/fs/xfs/lm_age_buffer ] ; then
5519e1cbedeSMauro Carvalho Chehab			# (A couple of early 2.6 laptop mode patches had these.)
5529e1cbedeSMauro Carvalho Chehab			# The same goes for these.
5539e1cbedeSMauro Carvalho Chehab			echo $XFS_AGE > /proc/sys/fs/xfs/lm_age_buffer
5549e1cbedeSMauro Carvalho Chehab			echo $XFS_AGE > /proc/sys/fs/xfs/lm_sync_interval
5559e1cbedeSMauro Carvalho Chehab		elif [ -f /proc/sys/fs/xfs/age_buffer ] ; then
5569e1cbedeSMauro Carvalho Chehab			# (2.6.6)
5579e1cbedeSMauro Carvalho Chehab			# But not for these -- they are also used in normal
5589e1cbedeSMauro Carvalho Chehab			# operation.
5599e1cbedeSMauro Carvalho Chehab			echo $XFS_AGE > /proc/sys/fs/xfs/age_buffer
5609e1cbedeSMauro Carvalho Chehab			echo $XFS_AGE > /proc/sys/fs/xfs/sync_interval
5619e1cbedeSMauro Carvalho Chehab		elif [ -f /proc/sys/fs/xfs/age_buffer_centisecs ] ; then
5629e1cbedeSMauro Carvalho Chehab			# (2.6.7 upwards)
5639e1cbedeSMauro Carvalho Chehab			# And not for these either. These are in centisecs,
5649e1cbedeSMauro Carvalho Chehab			# not USER_HZ, so we have to use $AGE, not $XFS_AGE.
5659e1cbedeSMauro Carvalho Chehab			echo $AGE > /proc/sys/fs/xfs/age_buffer_centisecs
5669e1cbedeSMauro Carvalho Chehab			echo $AGE > /proc/sys/fs/xfs/xfssyncd_centisecs
5679e1cbedeSMauro Carvalho Chehab			echo 3000 > /proc/sys/fs/xfs/xfsbufd_centisecs
5689e1cbedeSMauro Carvalho Chehab		fi
5699e1cbedeSMauro Carvalho Chehab
5709e1cbedeSMauro Carvalho Chehab		case "$KLEVEL" in
5719e1cbedeSMauro Carvalho Chehab			"2.4")
5729e1cbedeSMauro Carvalho Chehab				echo 1					> /proc/sys/vm/laptop_mode
5739e1cbedeSMauro Carvalho Chehab				echo "30 500 0 0 $AGE $AGE 60 20 0"	> /proc/sys/vm/bdflush
5749e1cbedeSMauro Carvalho Chehab				;;
5759e1cbedeSMauro Carvalho Chehab			"2.6")
5769e1cbedeSMauro Carvalho Chehab				echo 5					> /proc/sys/vm/laptop_mode
5779e1cbedeSMauro Carvalho Chehab				echo "$AGE"				> /proc/sys/vm/dirty_writeback_centisecs
5789e1cbedeSMauro Carvalho Chehab				echo "$AGE"				> /proc/sys/vm/dirty_expire_centisecs
5799e1cbedeSMauro Carvalho Chehab				echo "$DIRTY_RATIO"			> /proc/sys/vm/dirty_ratio
5809e1cbedeSMauro Carvalho Chehab				echo "$DIRTY_BACKGROUND_RATIO"		> /proc/sys/vm/dirty_background_ratio
5819e1cbedeSMauro Carvalho Chehab				;;
5829e1cbedeSMauro Carvalho Chehab		esac
5839e1cbedeSMauro Carvalho Chehab		if [ $DO_REMOUNTS -eq 1 ]; then
5849e1cbedeSMauro Carvalho Chehab			cat /etc/mtab | while read DEV MP FST OPTS DUMP PASS ; do
5859e1cbedeSMauro Carvalho Chehab				PARSEDOPTS="$(parse_mount_opts "$OPTS")"
5869e1cbedeSMauro Carvalho Chehab				if [ "$FST" = 'unknown' ]; then
5879e1cbedeSMauro Carvalho Chehab					FST=$(deduce_fstype $MP)
5889e1cbedeSMauro Carvalho Chehab				fi
5899e1cbedeSMauro Carvalho Chehab				case "$FST" in
5909e1cbedeSMauro Carvalho Chehab					"ext3"|"reiserfs")
5919e1cbedeSMauro Carvalho Chehab						PARSEDOPTS="$(parse_mount_opts commit "$OPTS")"
5929e1cbedeSMauro Carvalho Chehab						mount $DEV -t $FST $MP -o remount,$PARSEDOPTS,commit=$MAX_AGE$NOATIME_OPT
5939e1cbedeSMauro Carvalho Chehab						;;
5949e1cbedeSMauro Carvalho Chehab					"xfs")
5959e1cbedeSMauro Carvalho Chehab						mount $DEV -t $FST $MP -o remount,$OPTS$NOATIME_OPT
5969e1cbedeSMauro Carvalho Chehab						;;
5979e1cbedeSMauro Carvalho Chehab				esac
5989e1cbedeSMauro Carvalho Chehab				if [ -b $DEV ] ; then
5999e1cbedeSMauro Carvalho Chehab					blockdev --setra $(($READAHEAD * 2)) $DEV
6009e1cbedeSMauro Carvalho Chehab				fi
6019e1cbedeSMauro Carvalho Chehab			done
6029e1cbedeSMauro Carvalho Chehab		fi
6039e1cbedeSMauro Carvalho Chehab		if [ $DO_HD -eq 1 ] ; then
6049e1cbedeSMauro Carvalho Chehab			for THISHD in $HD ; do
6059e1cbedeSMauro Carvalho Chehab				/sbin/hdparm -S $BATT_HD $THISHD > /dev/null 2>&1
6069e1cbedeSMauro Carvalho Chehab				/sbin/hdparm -B 1 $THISHD > /dev/null 2>&1
6079e1cbedeSMauro Carvalho Chehab			done
6089e1cbedeSMauro Carvalho Chehab		fi
6099e1cbedeSMauro Carvalho Chehab		if [ $DO_CPU -eq 1 -a -e /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq ]; then
6109e1cbedeSMauro Carvalho Chehab			if [ $CPU_MAXFREQ = 'slowest' ]; then
6119e1cbedeSMauro Carvalho Chehab				CPU_MAXFREQ=`cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq`
6129e1cbedeSMauro Carvalho Chehab			fi
6139e1cbedeSMauro Carvalho Chehab			echo $CPU_MAXFREQ > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
6149e1cbedeSMauro Carvalho Chehab		fi
6159e1cbedeSMauro Carvalho Chehab		echo "."
6169e1cbedeSMauro Carvalho Chehab		;;
6179e1cbedeSMauro Carvalho Chehab	stop)
6189e1cbedeSMauro Carvalho Chehab		U_AGE=$((100*$DEF_UPDATE))
6199e1cbedeSMauro Carvalho Chehab		B_AGE=$((100*$DEF_AGE))
6209e1cbedeSMauro Carvalho Chehab		echo -n "Stopping laptop_mode"
6219e1cbedeSMauro Carvalho Chehab		echo 0 > /proc/sys/vm/laptop_mode
6229e1cbedeSMauro Carvalho Chehab		if [ -f /proc/sys/fs/xfs/age_buffer -a ! -f /proc/sys/fs/xfs/lm_age_buffer ] ; then
6239e1cbedeSMauro Carvalho Chehab			# These need to be restored, if there are no lm_*.
6249e1cbedeSMauro Carvalho Chehab			echo $(($XFS_HZ*$DEF_XFS_AGE_BUFFER))	 	> /proc/sys/fs/xfs/age_buffer
6259e1cbedeSMauro Carvalho Chehab			echo $(($XFS_HZ*$DEF_XFS_SYNC_INTERVAL)) 	> /proc/sys/fs/xfs/sync_interval
6269e1cbedeSMauro Carvalho Chehab		elif [ -f /proc/sys/fs/xfs/age_buffer_centisecs ] ; then
6279e1cbedeSMauro Carvalho Chehab			# These need to be restored as well.
6289e1cbedeSMauro Carvalho Chehab			echo $((100*$DEF_XFS_AGE_BUFFER))	> /proc/sys/fs/xfs/age_buffer_centisecs
6299e1cbedeSMauro Carvalho Chehab			echo $((100*$DEF_XFS_SYNC_INTERVAL))	> /proc/sys/fs/xfs/xfssyncd_centisecs
6309e1cbedeSMauro Carvalho Chehab			echo $((100*$DEF_XFS_BUFD_INTERVAL))	> /proc/sys/fs/xfs/xfsbufd_centisecs
6319e1cbedeSMauro Carvalho Chehab		fi
6329e1cbedeSMauro Carvalho Chehab		case "$KLEVEL" in
6339e1cbedeSMauro Carvalho Chehab			"2.4")
6349e1cbedeSMauro Carvalho Chehab				echo "30 500 0 0 $U_AGE $B_AGE 60 20 0"	> /proc/sys/vm/bdflush
6359e1cbedeSMauro Carvalho Chehab				;;
6369e1cbedeSMauro Carvalho Chehab			"2.6")
6379e1cbedeSMauro Carvalho Chehab				echo "$U_AGE"				> /proc/sys/vm/dirty_writeback_centisecs
6389e1cbedeSMauro Carvalho Chehab				echo "$B_AGE"				> /proc/sys/vm/dirty_expire_centisecs
6399e1cbedeSMauro Carvalho Chehab				echo "$DEF_DIRTY_RATIO"			> /proc/sys/vm/dirty_ratio
6409e1cbedeSMauro Carvalho Chehab				echo "$DEF_DIRTY_BACKGROUND_RATIO"	> /proc/sys/vm/dirty_background_ratio
6419e1cbedeSMauro Carvalho Chehab				;;
6429e1cbedeSMauro Carvalho Chehab		esac
6439e1cbedeSMauro Carvalho Chehab		if [ $DO_REMOUNTS -eq 1 ] ; then
6449e1cbedeSMauro Carvalho Chehab			cat /etc/mtab | while read DEV MP FST OPTS DUMP PASS ; do
6459e1cbedeSMauro Carvalho Chehab				# Reset commit and atime options to defaults.
6469e1cbedeSMauro Carvalho Chehab				if [ "$FST" = 'unknown' ]; then
6479e1cbedeSMauro Carvalho Chehab					FST=$(deduce_fstype $MP)
6489e1cbedeSMauro Carvalho Chehab				fi
6499e1cbedeSMauro Carvalho Chehab				case "$FST" in
6509e1cbedeSMauro Carvalho Chehab					"ext3"|"reiserfs")
6519e1cbedeSMauro Carvalho Chehab						PARSEDOPTS="$(parse_mount_opts_wfstab $DEV commit $OPTS)"
6529e1cbedeSMauro Carvalho Chehab						PARSEDOPTS="$(parse_yesno_opts_wfstab $DEV atime atime $PARSEDOPTS)"
6539e1cbedeSMauro Carvalho Chehab						mount $DEV -t $FST $MP -o remount,$PARSEDOPTS
6549e1cbedeSMauro Carvalho Chehab						;;
6559e1cbedeSMauro Carvalho Chehab					"xfs")
6569e1cbedeSMauro Carvalho Chehab						PARSEDOPTS="$(parse_yesno_opts_wfstab $DEV atime atime $OPTS)"
6579e1cbedeSMauro Carvalho Chehab						mount $DEV -t $FST $MP -o remount,$PARSEDOPTS
6589e1cbedeSMauro Carvalho Chehab						;;
6599e1cbedeSMauro Carvalho Chehab				esac
6609e1cbedeSMauro Carvalho Chehab				if [ -b $DEV ] ; then
6619e1cbedeSMauro Carvalho Chehab					blockdev --setra 256 $DEV
6629e1cbedeSMauro Carvalho Chehab				fi
6639e1cbedeSMauro Carvalho Chehab			done
6649e1cbedeSMauro Carvalho Chehab		fi
6659e1cbedeSMauro Carvalho Chehab		if [ $DO_HD -eq 1 ] ; then
6669e1cbedeSMauro Carvalho Chehab			for THISHD in $HD ; do
6679e1cbedeSMauro Carvalho Chehab				/sbin/hdparm -S $AC_HD $THISHD > /dev/null 2>&1
6689e1cbedeSMauro Carvalho Chehab				/sbin/hdparm -B 255 $THISHD > /dev/null 2>&1
6699e1cbedeSMauro Carvalho Chehab			done
6709e1cbedeSMauro Carvalho Chehab		fi
6719e1cbedeSMauro Carvalho Chehab		if [ $DO_CPU -eq 1 -a -e /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq ]; then
6729e1cbedeSMauro Carvalho Chehab			echo `cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq` > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
6739e1cbedeSMauro Carvalho Chehab		fi
6749e1cbedeSMauro Carvalho Chehab		echo "."
6759e1cbedeSMauro Carvalho Chehab		;;
6769e1cbedeSMauro Carvalho Chehab	*)
6779e1cbedeSMauro Carvalho Chehab		echo "Usage: $0 {start|stop}" 2>&1
6789e1cbedeSMauro Carvalho Chehab		exit 1
6799e1cbedeSMauro Carvalho Chehab		;;
6809e1cbedeSMauro Carvalho Chehab
6819e1cbedeSMauro Carvalho Chehab  esac
6829e1cbedeSMauro Carvalho Chehab
6839e1cbedeSMauro Carvalho Chehab  exit 0
6849e1cbedeSMauro Carvalho Chehab
6859e1cbedeSMauro Carvalho Chehab
6869e1cbedeSMauro Carvalho ChehabACPI integration
6879e1cbedeSMauro Carvalho Chehab----------------
6889e1cbedeSMauro Carvalho Chehab
6899e1cbedeSMauro Carvalho ChehabDax Kelson submitted this so that the ACPI acpid daemon will
6909e1cbedeSMauro Carvalho Chehabkick off the laptop_mode script and run hdparm. The part that
6919e1cbedeSMauro Carvalho Chehabautomatically disables laptop mode when the battery is low was
6929e1cbedeSMauro Carvalho Chehabwritten by Jan Topinski.
6939e1cbedeSMauro Carvalho Chehab
6949e1cbedeSMauro Carvalho Chehab/etc/acpi/events/ac_adapter::
6959e1cbedeSMauro Carvalho Chehab
6969e1cbedeSMauro Carvalho Chehab	event=ac_adapter
6979e1cbedeSMauro Carvalho Chehab	action=/etc/acpi/actions/ac.sh %e
6989e1cbedeSMauro Carvalho Chehab
6999e1cbedeSMauro Carvalho Chehab/etc/acpi/events/battery::
7009e1cbedeSMauro Carvalho Chehab
7019e1cbedeSMauro Carvalho Chehab	event=battery.*
7029e1cbedeSMauro Carvalho Chehab	action=/etc/acpi/actions/battery.sh %e
7039e1cbedeSMauro Carvalho Chehab
7049e1cbedeSMauro Carvalho Chehab/etc/acpi/actions/ac.sh::
7059e1cbedeSMauro Carvalho Chehab
7069e1cbedeSMauro Carvalho Chehab  #!/bin/bash
7079e1cbedeSMauro Carvalho Chehab
7089e1cbedeSMauro Carvalho Chehab  # ac on/offline event handler
7099e1cbedeSMauro Carvalho Chehab
7109e1cbedeSMauro Carvalho Chehab  status=`awk '/^state: / { print $2 }' /proc/acpi/ac_adapter/$2/state`
7119e1cbedeSMauro Carvalho Chehab
7129e1cbedeSMauro Carvalho Chehab  case $status in
7139e1cbedeSMauro Carvalho Chehab          "on-line")
7149e1cbedeSMauro Carvalho Chehab                  /sbin/laptop_mode stop
7159e1cbedeSMauro Carvalho Chehab                  exit 0
7169e1cbedeSMauro Carvalho Chehab          ;;
7179e1cbedeSMauro Carvalho Chehab          "off-line")
7189e1cbedeSMauro Carvalho Chehab                  /sbin/laptop_mode start
7199e1cbedeSMauro Carvalho Chehab                  exit 0
7209e1cbedeSMauro Carvalho Chehab          ;;
7219e1cbedeSMauro Carvalho Chehab  esac
7229e1cbedeSMauro Carvalho Chehab
7239e1cbedeSMauro Carvalho Chehab
7249e1cbedeSMauro Carvalho Chehab/etc/acpi/actions/battery.sh::
7259e1cbedeSMauro Carvalho Chehab
7269e1cbedeSMauro Carvalho Chehab  #! /bin/bash
7279e1cbedeSMauro Carvalho Chehab
7289e1cbedeSMauro Carvalho Chehab  # Automatically disable laptop mode when the battery almost runs out.
7299e1cbedeSMauro Carvalho Chehab
7309e1cbedeSMauro Carvalho Chehab  BATT_INFO=/proc/acpi/battery/$2/state
7319e1cbedeSMauro Carvalho Chehab
7329e1cbedeSMauro Carvalho Chehab  if [[ -f /proc/sys/vm/laptop_mode ]]
7339e1cbedeSMauro Carvalho Chehab  then
7349e1cbedeSMauro Carvalho Chehab     LM=`cat /proc/sys/vm/laptop_mode`
7359e1cbedeSMauro Carvalho Chehab     if [[ $LM -gt 0 ]]
7369e1cbedeSMauro Carvalho Chehab     then
7379e1cbedeSMauro Carvalho Chehab       if [[ -f $BATT_INFO ]]
7389e1cbedeSMauro Carvalho Chehab       then
7399e1cbedeSMauro Carvalho Chehab          # Source the config file only now that we know we need
7409e1cbedeSMauro Carvalho Chehab          if [ -f /etc/default/laptop-mode ] ; then
7419e1cbedeSMauro Carvalho Chehab                  # Debian
7429e1cbedeSMauro Carvalho Chehab                  . /etc/default/laptop-mode
7439e1cbedeSMauro Carvalho Chehab          elif [ -f /etc/sysconfig/laptop-mode ] ; then
7449e1cbedeSMauro Carvalho Chehab                  # Others
7459e1cbedeSMauro Carvalho Chehab                  . /etc/sysconfig/laptop-mode
7469e1cbedeSMauro Carvalho Chehab          fi
7479e1cbedeSMauro Carvalho Chehab          MINIMUM_BATTERY_MINUTES=${MINIMUM_BATTERY_MINUTES:-'10'}
7489e1cbedeSMauro Carvalho Chehab
7499e1cbedeSMauro Carvalho Chehab          ACTION="`cat $BATT_INFO | grep charging | cut -c 26-`"
7509e1cbedeSMauro Carvalho Chehab          if [[ ACTION -eq "discharging" ]]
7519e1cbedeSMauro Carvalho Chehab          then
7529e1cbedeSMauro Carvalho Chehab             PRESENT_RATE=`cat $BATT_INFO | grep "present rate:" | sed  "s/.* \([0-9][0-9]* \).*/\1/" `
7539e1cbedeSMauro Carvalho Chehab             REMAINING=`cat $BATT_INFO | grep "remaining capacity:" | sed  "s/.* \([0-9][0-9]* \).*/\1/" `
7549e1cbedeSMauro Carvalho Chehab          fi
7559e1cbedeSMauro Carvalho Chehab          if (($REMAINING * 60 / $PRESENT_RATE < $MINIMUM_BATTERY_MINUTES))
7569e1cbedeSMauro Carvalho Chehab          then
7579e1cbedeSMauro Carvalho Chehab             /sbin/laptop_mode stop
7589e1cbedeSMauro Carvalho Chehab          fi
7599e1cbedeSMauro Carvalho Chehab       else
7609e1cbedeSMauro 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."
7619e1cbedeSMauro Carvalho Chehab       fi
7629e1cbedeSMauro Carvalho Chehab     fi
7639e1cbedeSMauro Carvalho Chehab  fi
7649e1cbedeSMauro Carvalho Chehab
7659e1cbedeSMauro Carvalho Chehab
7669e1cbedeSMauro Carvalho ChehabMonitoring tool
7679e1cbedeSMauro Carvalho Chehab---------------
7689e1cbedeSMauro Carvalho Chehab
7699e1cbedeSMauro Carvalho ChehabBartek Kania submitted this, it can be used to measure how much time your disk
7709e1cbedeSMauro Carvalho Chehabspends spun up/down.  See tools/laptop/dslm/dslm.c
771