Tengo varias máquinas Ubuntu con un SSD y un disco duro tradicional, donde el disco duro se usa sólo ocasionalmente.
Para reducir el ruido, el calor y el consumo de energía, y para extender la vida útil del disco duro, me gustaría apagarlo en cada arranque y activarlo solo cuando sea necesario.
hdparm -y
(o -Y
) funciona bastante bien en la línea de comando y hace exactamente lo que quiero.
Pero escribir un servicio systemd para ejecutar hdparm
no funciona. Para ser más precisos: funciona y el disco realmente entra en modo de suspensión (como muestra la depuración), pero se reactiva inmediatamente (y permanece despierto), porque hay algo en el sistema que accede a los discos duros (y por lo tanto activa it) al final del proceso de arranque de systemd.
Entonces, ¿cómo puedo poner un hdparm -y
proceso de arranque lo suficientemente tarde como para que ya no sea seguido por ningún otro proceso?
Mi última suposición sería cambiar el objetivo predeterminado de systemd de gráfico a uno nuevo (sleepydisks), que luego depende del objetivo gráfico anterior.
¿Pero no existe una forma más sencilla y sencilla de apagar los discos?
Saludos
Respuesta1
Abra la utilidad de discos y configure la unidad para que deje de girar automáticamente después de 10 minutos de inactividad.
Respuesta2
Utilice la opción -S de hdparm. Esto establece el tiempo de espera de inactividad, que se supone que debe mantener la unidad.
$ hdparm --help
-S Set standby (spindown) timeout
$ hdparm -S 60 /dev/sdd
/dev/sdd:
setting standby to 60 (5 minutes)
Tenga en cuenta que se trata de una 'S' mayúscula.
Respuesta3
Utilizo el siguiente script para "forzar" el giro de los discos inactivos, donde por fuerza me refiero a una instrucción directa al disco, ya que muchos discos WD son problemáticos con el giro automático. Quizás puedas ampliar esto a tus necesidades. El script está bien comentado por lo que deberías poder modificarlo con bastante facilidad. Lo llamo cron
cada 20 minutos, ajusto según sea necesario:
spindown.sh
#!/usr/bin/env bash
logger "[SPINDOWN] Checking disk activity and spinning down idles..."
# Exit during maintenance
if pgrep snapraid > /dev/null; then
logger "[SPINDOWN] Detected snapRAID maintenance. Exiting.";
exit 0
fi
# Specify any drives you want to ignore; separate multiple drives by spaces; e.g. "sda sdb"
IGNORE_DRIVES=""
PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
# Check for idle disks and spin them down unless smartd is running tests
# Create a file on the ramdisk and cycle it to test for disk activity
( if [ ! -f /dev/shm/diskstats_1 ]; then
logger "[SPINDOWN] Creating initial state file on ramdisk";
touch /dev/shm/diskstats_1;
fi ;
logger "[SPINDOWN] Updating state files on ramdisk";
mv /dev/shm/diskstats_1 /dev/shm/diskstats_2;
cat /proc/diskstats > /dev/shm/diskstats_1 ) > /dev/null 2>&1
# Find all removable USB drives, so we can ignore them later,
# see http://superuser.com/a/465953
REMOVABLE_DRIVES=""
for _device in /sys/block/*/device; do
if echo $(readlink -f "$_device")|egrep -q "usb"; then
_disk=$(echo "$_device" | cut -f4 -d/)
REMOVABLE_DRIVES="$REMOVABLE_DRIVES $_disk"
fi
done
# Append detected removable drives to manually ignored drives
IGNORE_DRIVES="$IGNORE_DRIVES $REMOVABLE_DRIVES"
# Loop through all the array disks and spin down the idle disks. Will find all drives sda > sdz AND sdaa > sdaz...
logger "[SPINDOWN] Looping through drives to detect idle state"
for disk in `find /dev/ -regex '/dev/sd[a-z]+' | cut -d/ -f3`
do
# Skip removable USB drives and those the user wants to ignore
if [[ $IGNORE_DRIVES =~ $disk ]]; then
continue
fi
# Skip SSDs
if [[ $(cat /sys/block/$disk/queue/rotational) -eq 0 ]]; then
continue
fi
# Check if drive exists
if [ -e /dev/$disk ]; then
logger "[SPINDOWN] Checking drive $disk"
# Check if drive is currently spinning
if [ "$(smartctl -i -n standby /dev/$disk | grep "ACTIVE or IDLE")" ]; then
logger "[SPINDOWN] Disk $disk is ACTIVE or IDLE. Checking for selftest"
# Check if smartctl is currently not running a self test
if [ $(smartctl -a /dev/$disk | grep -c "Self-test routine in progress") = 0 ]; then
logger "[SPINDOWN] Disk $disk is not running a self test. Checking activity."
# Check if drive has been non idle since last run
if [ "$(diff /dev/shm/diskstats_1 /dev/shm/diskstats_2 | grep $disk )" = "" ]; then
logger "[SPINDOWN] Spinning down /dev/$disk `df -h | grep /dev/$disk | rev | cut -d ' ' -f 1 | rev`"
hdparm -y /dev/$disk
fi
else
logger "[SPINDOWN] /dev/$disk is running Self-test routine. Skipping."
fi
fi
fi
done
Según la pregunta específica, ¿cómo hacerlo con systemd? ... cree un archivo de temporizador que llame a este script (Ref:https://wiki.archlinux.org/index.php/Systemd/Timers)