		NOFLUSHD - An Idle Disk Daemon
               ================================
               (Version 2.4 - March, 13th 2001)


This is noflushd, a daemon that spins down disks that have not been 
read from after a certain amount of time, and then prevents disk
writes from spinning them back up. It's for use with kernel versions
2.2.11 and up, where the userland bdflush (update) daemon has been fully
integrated in the new kernel thread kupdate. Recent kernels renamed kupdate
to kupdated. I'll call it kupdate in the following anyway.

noflushd uses the sleep support logic from bdflush-1.6.2. bdflush was
originally written by Eric Youngdale <ericy@gnu.ai.mit.edu>, Pavel Machek
<pavel@atrey.karlin.mff.cuni.cz> added the sleep support.

INSTALLATION

1. Be aware that noflushd might have problems with a mixed IDE/SCSI setup
   or large numbers of disks. noflushd will inform you of any conflict.
   CAUTION: SCSI disks won't work out of the box. They require a kernel
   patch that gracefully handles spinup in the interrupt routine. See the
   file contrib/README in the source distribution for details. The binary
   distributions have SCSI disabled. If you are not able to grab the 
   source, edit src/spindown.c and recompile, you'd better not patch your
   kernel anyway.
   
2. Check if the init skript in the skripts/ directory goes fine with you.
   You might want to change the timeout value in skripts/noflushd.

[The next steps are described in more detail in the generic installation
 instructions found in INSTALLATION.]
 
3. Next run './configure' - it tries to autodetect your system's init layout
   and changes noflushd's installation paths accordingly. You can override
   the settings via the --with-scheme=<dist> option. Currently supported
   values for <dist> are 'debian', 'redhat', and 'suse'. Alternatively,
   you may specify the directory where your distribution keeps its init
   skripts via --with-initdir=<dir>, and the directory for package 
   documentation via --with-docdir=<dir>.

4. Compile the daemon by typing 'make'.

5. Install the package with 'make install'.

6. To automatically start noflushd, either manually set appropriate symlinks 
   from your system's rc-directories to the noflushd init skript like:

   ln -s /etc/rc.d/init.d/noflushd /etc/rc.d/rc2.d/S80noflushd
   ln -s /etc/rc.d/init.d/noflushd /etc/rc.d/rc0.d/K10noflushd

   or similar, according to your system's boot concept. Or use your 
   distribution-specific tools, e.g. chkconfig on RedHat, update-init.d on
   Debian.

THEORY of OPERATION

noflushd polls the disk i/o statistics reported in /proc/stat and keeps track
of when the last read to a disk occurred. If a configurable amount of time has
elapsed without read activity, the disk is sent to standby mode, ie. it is
spun down. Disk hardware will notice when the next command occurs and spin
up the disk again. So far nothing fancy - you could do this much cheaper
using hdparm. There's one nasty thing however, and that's the kernel's lazy
flushing of dirty buffers. When you write to a file, the data usually isn't
physically stored on disk immediately, it's kept in the buffer cache. Every
few seconds, a kernel thread (kupdate) wakes up and sends a few of these
buffers to disk. And mind you, quite a lot of data gets written out regularly.
Unless you mount your filesystems with the noatime option, each read access
to a file will update the last-access timestamp. Check your logfiles, and
you'll see a substantial amount of write traffic. Now suppose, all the files
and binaries you want to access in the next few hours have already been 
accessed before and are thus likely to be cached in memory. Using the hdparm
method, your hard disk probably will keep spinning most of the time. noflushd
however tries to be smarter: when a read-write mounted disk is spun
down, it stops the kupdate thread, thus blocking further writes to disk.[1] The
writes won't be lost of course, they stay cached in memory. noflushd doesn't
block any other disk access though, so the first attempt to read data that is
not yet cached in memory, or a forced write (via sync() or fsync()) gets
through to the hardware, which happily spins up the disk again. noflushd
notices that the disk is back up when the i/o numbers in /proc/stat start
spinning again, and makes sure writes are flushed to disk. 

[1] This is different from noflushd's behaviour in the 1.x series where 
    kupdate was left running until the last r/w mounted disk was spun down.
    Nowadays noflushd has its own dumb flushing algorithm that takes over
    kupdate's job of syncing written data to disk. You won't notice the
    difference if there is only a single hard disk in your system, but it
    improves spindown time in multidisk environments a lot. Still this is
    a dirty hack though. What you'd much rather like to do is to spin down
    idle disk A and tell kupdate: "Don't send any more buffers to A". 
    Unfortunately kupdate doesn't have a notion of individual disks and can
    only be configured globally. Changing that is on my TODO list but patches
    are welcome. :-) [You'll make the embedded folks happy as well with such a
    patch btw. Flash memory card can't take as many write cycles as hard disks,
    so they'd like to raise the update interval on their flash cards without
    affecting the disks.]

RANDOM BUBBLINGS for the UNDECIDED

* But what if someone pulls the plug while the disk is spun down?

You lose. That's the risk you have to take. It's entirely up to you to decide
between the risk and the noise. Take into account if you're about to install
noflushd on your notebook that's rather immune to power glitches and kernel
bugs, or on your kernel devel machine crashing twice a day, where you're about
to write your PhD thesis...

* Heck, I'm not within 50 yards of the machine but it keeps spinning up!?

Check for cron jobs running every few minutes. Make sure to tell syslogd not
to sync logfiles after each write. (Go to /etc/syslog.conf and prepend all the 
less important logfiles with a '-'.) Or are there by chance other disks still
spinning so noflushd can't stop kupdate? Well, I hope you checked it's not 
due to some folks accessing your machine via the net, didn't you?

* I just switched over to devfs. No noflushd BUGs about not finding the
  device directory!?

You did not pass the devfs=mount option to the kernel because you still want
access to your old-style /dev, right? But the kernel internally already thinks
the devfs-way, and also does in the information on disks it exports, e.g. in
/proc/partitions. As noflushd relies on kernel information, it needs to be
able to access disks via kernel-style (devfs) names. In other words, it needs
a devfs tree mounted somewhere in the filesystem. Just add something like the
following to /etc/fstab:

none	/devfs	devfs	defaults	0	0

* Why don't you monitor my laptop's power state and set up different timeouts
  if I'm running off AC or battery?

There is already a daemon that just gets the kicks from monitoring power 
states all day long, so why should noflushd bother? This daemon is called
apmd, it spits out events when the power state changes and it even lets
you configure what to do in this case. You might think of running 
'killall -HUP noflushd'. And guess what noflushd does when it receives the
signal? It switches to the next set of timeouts...

* Hey, that's cool! But when I boot off battery I need a different set of
  initial timeout than when booting while on AC!

Yepp. You'll have to modify the init skript a bit. Always start with e.g.
the AC defaults first and add a line 

if <running_off_battery>; then killall -HUP noflushd

right after the start command. Now the implementation of the 
<running_off_battery> part is left as an excercise to the reader, mainly 
because I don't possess a laptop.

* Aiee, me non-coder. Still can't figure out what to do...

Fine then. At your convenience, choose one or both of the following:

Hint A: 'man 1 apm'.
Hint B: Sponsor me a laptop.

* This $%&! noflushd is a piece of ignorant crap - it spins down nothing but
  my first disk!

You're using a kernel version of 2.3.99pre8 or later, correct? Don't take it
up with me. Some kernel folks decided that it was time for an improved scheme
to report disk statistics (they were right) and implemented a method that 
would consume 64k of kernel memory. That was assumed to be too much, so they
decided to only provide statistics for devices with major numbers up to 16. 
Bright move. If you liked to know how many cars drive through your street,
would you count only the red and blue ones? Your first IDE controller is a
red one fortunately, so are the first 16 SCSI disks. The rest is green and
loses. Now this really bothers you? Okay, go to your kernel source tree, cd
to include/linux, and change the DK_MAX_MAJOR define in kernel_stat.h from
16 to 255. And don't bill me for these extra 60k you waste!

* I still think noflushd is a piece of crap!

Uh-uh, someone's actually looked at the code. Damn, you're right...

* Rats! That blurb's not getting me any further at all. Where can I get more
  help with regard to noflushd?

Send mail to noflushd-devel@lists.sourceforge.net, or have a look at
http://noflushd.sourceforge.net for up-to-date information.

BUGS and LIMITATIONS

- Works only for IDE, SCSI requires a kernel patch.
- Doesn't work on kernel version 2.3.99pre8 to 2.4.0-test8 due to a format
  change in /proc/stat.
- noflushd, heavy swap activity, and APM suspend obviously don't go together
  too well. Upon resume, syslogd has a tendency to get stuck in 'D' state.
  Reportedly, noflushd and kupdate are up and running though, so I suspect
  this might be a kernel bug rather than a noflushd one. The best kludge I
  know of (thanks to Tom Holroyd) is to put a line with
    sync && sync && sync
  in the apmd suspend script.
- Calling sync with no dirty buffers pending will cause the disk to
  spin up but leave kupdate stopped (noflushd is still in spindown mode). 
  kupdate is restarted on the next read or write request though.
- Reiserfs journaling bypasses the kernel's delayed write mechanisms and writes
  straight to disk. Therefore noflushd is unable to postpone writing of
  journaling data. As a result, expect lousy spindown behaviour when working
  off reiserfs partitions.
- Remounting a partition from read-only to read-write while noflushd's internal
  syncer is active will go unnoticed, i.e. no sync will occur. (This should be
  extremely rare - it requires that not only were e.g. /dev/hda{1,2...} all
  read-only before, but also the full disk device /dev/hda. A filesystem on
  an unpartitioned disk is probably the only real-world case where this bug
  might trigger.)

TODO

- For saner handling of multiple disks a kernel patch is needed that allows 
  for separate bdflush parameters on each device. A second part - a saner 
  interface for getting disk statistics than the one currently available via
  /proc/stat - is contained in Stephen Tweedie's sard patch that seems about
  to make it into the kernel. 
- Add sard support (RedHat patch sard in their 7.0 default kernel).
- Put up a web page with FAQs and more information (work in progress, see
  http://noflushd.sourceforge.net).
- Come up with a better SCSI spinup patch for kernel 2.4.x.

THANKS

Pavel Machek <pavel@atrey.karlin.mff.cuni.cz> for the sleep code in bdflush-1.6,
	and the syncing code adapted in noflushd 2.0.
Peter Englmaier <ppe@pa.uky.edu> for lots of comments, fixes and improvements.
Ross Golder <rossigee@bigfoot.com> for not getting tired to test and report 
	the endless bugs in my alpha versions.
Dr. Tom Holroyd <tomh@po.crl.go.jp> for his extremely valuable suggestions and
	maltreating his laptop to work out weird suspend interactions.
Andreas Steinmetz <ast@domdv.de> suggested how to handle LVM volumes.
Osma Ahvenlampi <oa@iki.fi> made me aware of the devfs problems.
Matthias Andree <matthias.andree@gmx.de> suggested improvements to the RPM
	build process.
Andreas U. Trottmann <ftc@aart.ch> tracked down and fixed bugs in oldstyle 
	stat support.
Andrew Lenharth <adl@cs.washington.edu> spooted a bogus cast that made 64bit
	architectures freak out.
Honza Fikar <Jan.Fikar@epfl.ch> and Gerd Bavendiek <bav@esn.sbs.de> for
	testing and giving feedback on pre-releases. 
Joey Hess <joeyh@debian.org> adopted noflushd and adapted it to Debian's needs.
Bob Mathews <bobmathewsandspam@yahoo.com> tracked down a no-go bug in the
	spindown code.
Brent Roman <brent@mbari.org> sent in a pile of valuable patches with bug
	fixes and improvements.
Olivier Chapuis <olivier.chapuis@free.fr> debugged my multiple timeout
	braindeadness. 

and lots of others who sent in bug reports and suggestions...

Daniel Kobras <kobras@linux.de>.
