Package: hdparm Version: 6.1-2 Severity: normal Tags: patch The current behaviour of hdparm is that it will refuse to set options for any disks if one RAID array is in the process of resynchronisation. This is somewhat too conservative: As far as I know, the real problem with setting harddisk options while the RAID array is being resynchronised is that hdparm and the RAID system is competing with each other for the disk I/O, nothing else (nothing to do with the resynchronisation process itself).
It is possible to suspend the resynchronisation before setting the harddisk options, and resuming the resynchronisation afterwards (thus there will be no I/O on the disk while hdparm is performing its task). The benefit of this approach is that the sysadmin does not have to manually check harddisk options after an unclean boot, still hdparm can be run safely. Regarding the detection of resynchronisation, there's at least one more state of the RAID system which the current hdparm init script does not recognise as synchronisation, but it should. If one disk fails, and there's a spare disk assigned to the same array, the RAID system immediately takes this disk into use, and starts to synchronise the contents to this disk; but this state shows in the /proc/mdstat file as 'recover', not 'resync'. Just to be complete, I looked into the 2.6.16 kernel sources, and found two more states that can show up in /proc/mdstat: 'repair' and 'check'. To be honest, I don't know these two, but I think that hdparm should consider these the same as 'resync' and 'recover', to err on the safe side. Attached a patch that contains the above fixes. (Sorry, the patch is for the Sarge version of hdparm, and then for the installed scripts and not for the package source.) Bye, norbi -- System Information: Debian Release: 3.1 Architecture: i386 (i686) Kernel: Linux 2.6.16 Locale: LANG=C, LC_CTYPE=hu_HU (charmap=ISO-8859-2) Versions of packages hdparm depends on: ii libc6 2.3.2.ds1-22sarge3 GNU C Library: Shared libraries an -- no debconf information
--- /etc/init.d/hdparm 2005-04-18 20:40:03.000000000 +0200 +++ /etc/init.d/hdparm.fixed 2006-05-07 15:40:40.000000000 +0200 @@ -8,6 +8,12 @@ # #See /usr/share/doc/hdparm/README.Debian for more details. +# Defaults for configuration variables. +RAID_WORKAROUND=yes + +# Source the defaults file. +[ -e /etc/default/hdparm ] && . /etc/default/hdparm + case "$0" in *hdparm) FIRST=yes @@ -32,9 +38,38 @@ report_error_and_exit() { report_error "$*. Exiting." + + # Turn on RAID synchronisation if we turned it off. + if [ "$raidstat" != 'OK' ] && [ "$RAID_WORKAROUND" = "yes" ]; then + undo_slow_down_raid_sync + fi + exit 1 } +slow_down_raid_sync() +{ + if [ -f /proc/sys/dev/raid/speed_limit_min ]; then + raid_speed_limit_min=`cat /proc/sys/dev/raid/speed_limit_min` + echo 0 >/proc/sys/dev/raid/speed_limit_min + fi + if [ -f /proc/sys/dev/raid/speed_limit_max ]; then + raid_speed_limit_max=`cat /proc/sys/dev/raid/speed_limit_max` + echo 0 >/proc/sys/dev/raid/speed_limit_max + fi + sleep 2 +} + +undo_slow_down_raid_sync() +{ + if [ -f /proc/sys/dev/raid/speed_limit_min ] && [ "x$raid_speed_limit_min" != "x" ]; then + echo $raid_speed_limit_min >/proc/sys/dev/raid/speed_limit_min + fi + if [ -f /proc/sys/dev/raid/speed_limit_max ] && [ "x$raid_speed_limit_max" != "x" ]; then + echo $raid_speed_limit_max >/proc/sys/dev/raid/speed_limit_max + fi +} + case $1 in start|restart|reload|force-reload) ;; @@ -55,14 +90,14 @@ raidstat=OK if [ -e /proc/mdstat ]; then - if grep -iq resync /proc/mdstat; then + if egrep -iq "resync|repair|recover|check" /proc/mdstat; then raidstat=RESYNC fi elif [ -e /proc/rd/status ]; then raidstat=`cat /proc/rd/status` fi - if ! [ "$raidstat" = 'OK' ]; then + if [ "$raidstat" != 'OK' ] && [ "$RAID_WORKAROUND" != "yes" ]; then report_error "*** RAID status not OK. Exiting. ***" exit 0 fi @@ -126,12 +161,15 @@ ITEMS_ECHOED=no +# Turn off RAID synchronisation if needed and asked for. +if [ "$raidstat" != 'OK' ] && [ "$RAID_WORKAROUND" = "yes" ]; then + slow_down_raid_sync +fi + # Get blocks as far as the drive's write cache. /bin/sync # Set options for a group of disks in /etc/default/hdparm -[ -e /etc/default/hdparm ] && . /etc/default/hdparm - if [ -n "$harddisks" -a -n "$hdparm_opts" ]; then for drive in $harddisks; do /sbin/hdparm -q -f $drive @@ -302,3 +340,8 @@ echo " (none)." fi } + +# Turn back on RAID synchronisation if we turned it off. +if [ "$raidstat" != 'OK' ] && [ "$RAID_WORKAROUND" = "yes" ]; then + undo_slow_down_raid_sync +fi --- /etc/default/hdparm 2005-05-24 16:08:23.000000000 +0200 +++ /etc/default/hdparm.fixed 2006-05-07 15:35:13.000000000 +0200 @@ -9,3 +9,11 @@ # # harddisks="" # hdparm_opts="" + +# By default, hdparm will refuse to set harddisk options on any drive +# if the system has software RAID running, and one or more disk arrays +# are in the process of resynchronisation. +# With this variable set to 'yes', /etc/init.d/hdparm will suspend the +# RAID resynchronisation process before setting harddisk options, and +# will resume it after setting is done. +RAID_WORKAROUND=yes