Некоторые жёсткие диски, не только ноутбучные 2.5″ но и например 3.5″ вполне серверные модели WDC WD2002FYPS-02W3B0, имеют отвратительную особенность парковать головы. Для ноутбучных дисков это вероятно оправдано и сделано чтобы исключить повреждение дисков при возможных ударах ноутбука, компьютер то мобильный. А вот для 3.5″ дисков это сделано вроде бы как для экономии электрической энергии. Но ресурс механизма парковок ограничен и через некоторое время это приводит к его износу и поломке диска. Чтобы предотвратить износ механизма принудительной парковкой головок нужно отключить APM диска.
Отключить APM в дисках можно с помощью утилиты hdparm.
hdparm -B 255 /dev/sda
Однако она не работает если диск подключён в RAID контроллер. В этом случае RAID контроллер отдаёт в систему блочное устройство без уточнения из каких дисков оно собрано. Тоесть система обращаясь к блочному устройству представленному RAID контроллером не обращается конкретно к какому-то диску. Поэтому функционал физического доступа к порту диска через имя блочного устройства ограничен.
В этом случае нужно воспользоваться утилитой smartctl которая может добраться до дисков следующим способом:
# пример для контроллера с 7-мю дисками. for i in `seq 0 7` ; do smartctl /dev/twa0 -d 3ware,$i --get=apm | sed -n '/^$/,//p' | sed -e '/^[ \t]*$/d' ; done
Для отключения APM
# пример для контроллера с 7-мю дисками. for i in `seq 0 7` ; do smartctl /dev/twa0 -d 3ware,$i --set=apm,off | sed -n '/^$/,//p' | sed -e '/^[ \t]*$/d' ; done
В этом примере использовался контроллер 3ware с подключёнными к нему 7-мью дисками вставленными без пропусков с 0 по 7. Более универсален следующий вариант, где проверяются все контроллеры и все диски установленные в контроллерах независимо от их количества.
#!/bin/bash # script displays APM info for all disks connected to RAID controller # multiply controllrs are supported TW_CLI="/root/tw_cli/x86_64/tw_cli" # от номера контроллера оставить только цифру и вывести количество подключённых дисков TW_SHOW=`${TW_CLI} show | grep '^c[0-9][ \t]\+' | awk '{print gensub(/^c/, "", "g", $1)" "$4}'` # if [ -z "${TW_SHOW}" ] ; then echo -e "No controllers were found." exit 1 fi while read TW_DEVICE TW_DISKS ; do if [ ${TW_DISKS} -eq 0 ] ; then echo "No disk present in the controller /c${TW_DEVICE}" continue fi while read i ; do echo -en "3ware /c${TW_DEVICE}/p${i} " smartctl /dev/twa0 -d 3ware,$i --get=apm | sed -n '/^$/,//p' | sed -e 's/[ \t]\+/ /g;/^ *$/d' done < <(${TW_CLI} /c${TW_DEVICE} show phy | awk '/^phy[0-9]/{if ($4 ~ /^\/c[0-9]+\/p[0-9]+$/)print $4}' | sed -e 's|^/c[0-9]\+/p||g') done < <(echo -e "${TW_SHOW}")
Для отключения APM на машинах без специализированного RAID контроллера я использую скрипт который читает все блочные устройства из /proc/partitions без цифр на конце, затем проверяет включён ли там APM и если да тогда выключает его.
cat /proc/partitions | awk '{if($4 ~ /^sd[a-z]$/){print $4}}' | while read DEV ; do hdparm -B /dev/${DEV} | grep APM_level | sed -e 's/[ \t]//g' | awk -v dev=${DEV} -F= '{if ($2~/^on$/) {print dev}}' | xargs -I{} hdparm -B 255 /dev/{} >/dev/null ; done
А чтобы он запускался автоматически при каждом старте компьютера прописываю его в /etc/rc.d/rc.local
Но при замене диска без перезагрузки например в fakeraid mdraid нужно будет выполнить скрипт вручную.
Про отключение парковки головок ноутбучных дисков с поддержкой sleep, hybernate и suspend можно прочесть здесь.