A couple of times recently the issue of ext's periodic fscks came up.
The first inspired me to write a script; in the latter I included it.
At that time some silliness in LVM and udev made it too noisy to run
from cron, these issues appear to be fixed in the version below.
(Apologies for the new thread; ICBF looking up the original.)
#!/bin/bash
## e2fsck is usually triggers after enough mounts, or enough time
## without a fsck. For always-on servers, the latter usually means
## that after an outage, you have to wait a few hours for the fscks to
## finish before normal operation resumes. This is especially
## annoying as it cannot be skipped on Ubuntu 10.04 servers.
##
## Instead we make an LVM snapshot of each ext LV, and if *that* fscks
## OK, we conclude that there were no errors and we set the snapshot's
## origin to indicate that a fsck has taken place.
set -eEu
set -o pipefail
trap 'echo >&2 "$0: unknown error"' ERR
# Silently succeed if the necessary tools aren't available, as that
# strongly indicates this script is not needed on this host.
{ which lvs && which tune2fs; } &>/dev/null || exit 0
# When run via vixie (ISC) cron, for some reason, fd 17 is open.
# LVM (stupidly) complains about this, and can't be silenced.
# The workaround is to close this fd.
exec 17<&-
# Output of e2fsck is desirable iff e2fsck had a genuine issue. It
# may be arbitrarily long, so a temporary file is more appropriate
# than a simple bash variable.
f="`mktemp -t avoid-fsck.XXXXXX`"
trap 'rm -f "$f"' EXIT
lvs --noheadings --separator , --options lv_name,vg_name,origin |
while IFS="$IFS," read lv vg origin
do
# Skip snapshots.
test -z "$origin" || continue
# Skip non-ext LVs.
tune2fs -l "/dev/$vg/$lv" &>/dev/null || continue
# Cleanup any mess left over from a previous run.
test ! -e "/dev/$vg/fsck_$lv" ||
/dev/null lvremove -f "/dev/$vg/fsck_$lv"
sleep 1 # wait a bit and hope udev catches up
# NB: 4G should be plenty of space for the COW, since we are only
# going to keep it around long enough to do a fsck.
/dev/null lvcreate --snapshot "/dev/$vg/$lv"
--name "fsck_$lv" --size 4G
sleep 1 # wait a
bit and hope udev catches up
if nice ionice -c3 e2fsck -p "/dev/$vg/fsck_$lv" >"$f" ||
test $? -eq 1 -o $? -eq 4 -o $? -eq 5 # Ignore "safe" statuses.
then
/dev/null tune2fs -C0 -Tnow "/dev/$vg/$lv"
else
&2 echo "e2fsck -p /dev/$vg/fsck_$lv
failed"
&2 cat "$f"
fi
sleep 1 # wait a bit and hope udev catches up
/dev/null lvremove -f "/dev/$vg/fsck_$lv"
done