Bug#556610: Please do incremental checks every night instead of a full monthly one
Sergey Kirpichev
skirpichev at gmail.com
Tue Dec 6 15:18:42 UTC 2011
tag 556610 +patch
thanks
Just a more simple version of the
http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=32;filename=checkarray.diff;att=2;bug=556610
Rough idea is to
1) setup crontab on a regular basis, e.g. weekly:
---------->8-----------
57 0 * * 0 root [ -x /usr/share/mdadm/checkarray ] && /usr/share/mdadm/checkarray --cron --all --quiet
57 6 * * 0 root [ -x /usr/share/mdadm/checkarray ] && /usr/share/mdadm/checkarray --cron --all --quiet --cancel
----------------->8-----------
2) Save sync_completed info to sync_min on --cancel:
----------->8-----------------
--- /usr/share/mdadm/checkarray 2011-12-06 04:41:09.000000000 +0400
+++ ./checkarray 2011-12-06 18:45:41.000000000 +0400
@@ -165,8 +165,10 @@
case "$action" in
idle)
+ completed=$(awk -F/ '{ if ($1 == "none") {print 0} else {print $1}}' /sys/block/$array/md/sync_completed)
echo $action > $SYNC_ACTION_CTL
[ $quiet -lt 1 ] && echo "$PROGNAME: I: cancel request queued for array $array." >&2
+ echo $completed > /sys/block/$array/md/sync_min
;;
check)
----------------->8----------------
Of course, it's easy to dump sync_completed state in
temporary files somewhere in /var/lib/mdadm/ to survive
on reboot. I'm not sure if that is a good idea at all...
-------------- next part --------------
A non-text attachment was scrubbed...
Name: checkarray-v2.patch
Type: text/x-diff
Size: 499 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/pkg-mdadm-devel/attachments/20111206/05c4395e/attachment.patch>
-------------- next part --------------
#!/bin/sh
#
# checkarray -- initiates a check run of an MD array's redundancy information.
#
# Copyright © martin f. krafft <madduck at debian.org>
# distributed under the terms of the Artistic Licence 2.0
#
set -eu
PROGNAME=${0##*/}
about()
{
echo "$PROGNAME -- MD array (RAID) redundancy checker tool"
echo "Copyright © martin f. krafft <madduck at debian.org>"
echo "Released under the terms of the Artistic Licence 2.0"
}
usage()
{
about
echo
echo "Usage: $PROGNAME [options] [arrays]"
echo
echo "Valid options are:"
cat <<-_eof | column -s\& -t
-a|--all & check all assembled arrays (check /proc/mdstat).
-s|--status & print redundancy check status of devices.
-x|--cancel & queue a request to cancel a running redundancy check.
-i|--idle & perform check in a lowest I/O scheduling class (idle).
-l|--slow & perform check in a lower-than-standard I/O scheduling class.
-f|--fast & perform check in higher-than-standard I/O scheduling class.
--realtime & perform check in real-time I/O scheduling class (DANGEROUS!).
-c|--cron & honour AUTOCHECK setting in /etc/default/mdadm.
-q|--quiet & suppress informational messages.
-Q|--real-quiet & suppress all output messages, including warnings and errors.
-h|--help & show this output.
-V|--version & show version information.
_eof
echo
echo "Examples:"
echo " $PROGNAME --all --idle"
echo " $PROGNAME --quiet /dev/md[123]"
echo " $PROGNAME -sa"
echo " $PROGNAME -x --all"
echo
echo "Devices can be specified in almost any format. The following are"
echo "all equivalent:"
echo " /dev/md0, md0, /dev/md/0, /sys/block/md0"
echo
echo "The --all option overrides all arrays passed to the script."
echo
echo "You can also control the status of a check with /proc/mdstat ."
}
SHORTOPTS=achVqQsxilf
LONGOPTS=all,cron,help,version,quiet,real-quiet,status,cancel,idle,slow,fast,realtime
eval set -- $(getopt -o $SHORTOPTS -l $LONGOPTS -n $PROGNAME -- "$@")
arrays=''
cron=0
all=0
quiet=0
status=0
action=check
ionice=
for opt in $@; do
case "$opt" in
-a|--all) all=1;;
-s|--status) action=status;;
-x|--cancel) action=idle;;
-i|--idle) ionice=idle;;
-l|--slow) ionice=low;;
-f|--fast) ionice=high;;
--realtime) ionice=realtime;;
-c|--cron) cron=1;;
-q|--quiet) quiet=1;;
-Q|--real-quiet) quiet=2;;
-h|--help) usage; exit 0;;
-V|--version) about; exit 0;;
/dev/md/*|md/*) arrays="${arrays:+$arrays }md${opt#*md/}";;
/dev/md*|md*) arrays="${arrays:+$arrays }${opt#/dev/}";;
/sys/block/md*) arrays="${arrays:+$arrays }${opt#/sys/block/}";;
--) :;;
*) echo "$PROGNAME: E: invalid option: $opt" >&2; usage >&2; exit 0;;
esac
done
is_true()
{
case "${1:-}" in
[Yy]es|[Yy]|1|[Tt]rue|[Tt]) return 0;;
*) return 1;
esac
}
DEBIANCONFIG=/etc/default/mdadm
[ -r $DEBIANCONFIG ] && . $DEBIANCONFIG
if [ $cron = 1 ] && ! is_true ${AUTOCHECK:-false}; then
[ $quiet -lt 1 ] && echo "$PROGNAME: I: disabled in $DEBIANCONFIG ." >&2
exit 0
fi
if [ ! -f /proc/mdstat ]; then
[ $quiet -lt 2 ] && echo "$PROGNAME: E: MD subsystem not loaded, or /proc unavailable." >&2
exit 2
fi
if [ ! -d /sys/block ]; then
[ $quiet -lt 2 ] && echo "$PROGNAME: E: /sys filesystem not available." >&2
exit 7
fi
if [ -z "$(ls /sys/block/md* 2>/dev/null)" ]; then
if [ $quiet -lt 2 ] && [ $cron != 1 ]; then
echo "$PROGNAME: W: no active MD arrays found." >&2
echo "$PROGNAME: W: (maybe uninstall the mdadm package?)" >&2
fi
exit 0
fi
if [ -z "$(ls /sys/block/md*/md/level 2>/dev/null)" ]; then
[ $quiet -lt 2 ] && echo "$PROGNAME: E: kernel too old, no support for redundancy checks." >&2
exit 6
fi
if ! egrep -q '^raid([1456]|10)$' /sys/block/md*/md/level 2>/dev/null; then
[ $quiet -lt 1 ] && echo "$PROGNAME: I: no redundant arrays present; skipping checks..." >&2
exit 0
fi
if [ -z "$(ls /sys/block/md*/md/sync_action 2>/dev/null)" ]; then
[ $quiet -lt 2 ] && echo "$PROGNAME: E: no kernel support for redundancy checks." >&2
exit 3
fi
[ $all = 1 ] && arrays="$(ls -d1 /sys/block/md* | cut -d/ -f4)"
for array in $arrays; do
SYNC_ACTION_CTL=/sys/block/$array/md/sync_action
if [ ! -e $SYNC_ACTION_CTL ]; then
[ $quiet -lt 1 ] && echo "$PROGNAME: I: skipping non-redundant array $array." >&2
continue
fi
cur_status="$(cat $SYNC_ACTION_CTL)"
if [ $action = status ]; then
echo "$array: $cur_status"
continue
fi
if [ ! -w $SYNC_ACTION_CTL ]; then
[ $quiet -lt 2 ] && echo "$PROGNAME: E: $SYNC_ACTION_CTL not writeable." >&2
exit 4
fi
if [ "$(cat /sys/block/$array/md/array_state)" = 'read-auto' ]; then
echo "$PROGNAME: W: array $array in auto-read-only state, skipping..." >&2
continue
fi
case "$action" in
idle)
completed=$(awk -F/ '{ if ($1 == "none") {print 0} else {print $1}}' /sys/block/$array/md/sync_completed)
echo $action > $SYNC_ACTION_CTL
[ $quiet -lt 1 ] && echo "$PROGNAME: I: cancel request queued for array $array." >&2
echo $completed > /sys/block/$array/md/sync_min
;;
check)
if [ "$cur_status" != idle ]; then
[ $quiet -lt 2 ] && echo "$PROGNAME: W: array $array not idle, skipping..." >&2
continue
fi
# queue request for the array. The kernel will make sure that these requests
# are properly queued so as to not kill one of the array.
echo $action > $SYNC_ACTION_CTL
[ $quiet -lt 1 ] && echo "$PROGNAME: I: check queued for array $array." >&2
case "$ionice" in
idle) arg='-c3';;
low) arg='-c2 -n7';;
high) arg='-c2 -n0';;
realtime) arg='-c1 -n4';;
*) break;;
esac
resync_pid= wait=5
while [ $wait -gt 0 ]; do
wait=$((wait - 1))
resync_pid=$(ps -ef | awk -v dev=$array 'BEGIN { pattern = "^\\[" dev "_resync]$" } $8 ~ pattern { print $2 }')
if [ -n "$resync_pid" ]; then
[ $quiet -lt 1 ] && echo "$PROGNAME: I: selecting $ionice I/O scheduling class for resync of $array." >&2
ionice -p "$resync_pid" $arg
break
fi
sleep 1
done
;;
esac
done
exit 0
More information about the pkg-mdadm-devel
mailing list