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