En los capítulos anteriores explicamos cómo personalizar el WD My Cloud Gen 2, recuperar el botón Shutdown y ejecutar scripts automáticamente mediante Boot Scripts.
En esta quinta entrega abordaremos uno de los aspectos más interesantes del funcionamiento de un NAS: la actividad del disco duro y su capacidad para entrar en suspensión cuando no está siendo utilizado.
Nuestro objetivo fue desarrollar un sistema que permitiera medir cuánto tiempo permanece el HDD activo, inactivo o suspendido, identificar sus despertares y modificar determinadas tareas de mantenimiento para reducir los accesos innecesarios.
El procedimiento fue desarrollado y probado en un
WD My Cloud Gen 2 con firmware OS5 5.33.102,
utilizando Linux 4.14.22 y un disco identificado
como /dev/sda.
1. ¿Por qué monitorear la suspensión del disco?
En un NAS que permanece encendido las 24 horas, el disco duro puede continuar girando incluso cuando ningún usuario está accediendo a sus archivos.
Esto puede ocurrir porque el sistema operativo ejecuta procesos periódicos de mantenimiento, escribe registros o actualiza información administrativa.
Permitir que el disco entre en suspensión durante periodos prolongados puede reducir su consumo eléctrico y el ruido producido por el dispositivo.
Sin embargo, la suspensión también implica detener y volver a arrancar el motor del disco. Por tanto, no necesariamente conviene maximizar el número de suspensiones.
Nuestro objetivo no fue provocar ciclos frecuentes de apagado y encendido, sino reducir accesos innecesarios y permitir periodos de descanso más prolongados.
2. Estados de energía del disco duro
Linux permite consultar el estado de energía
de determinados discos ATA mediante
la herramienta hdparm.
El comando utilizado es:
hdparm -C /dev/sda
Durante nuestras pruebas encontramos respuestas como las siguientes:
/dev/sda:
drive state is: active/idle
/dev/sda:
drive state is: idle
/dev/sda:
drive state is: standby
Para nuestro sistema de monitoreo distinguimos cuatro estados:
| Estado | Interpretación |
|---|---|
| ACTIVE | Estado reportado como active o active/idle. El disco continúa girando. |
| IDLE | El disco permanece girando, aunque se encuentra en un estado de inactividad. |
| STANDBY | El disco ha entrado en suspensión y normalmente ha detenido su motor. |
| UNKNOWN | No fue posible interpretar el estado devuelto. |
Es importante señalar que hdparm -C
consulta el estado de energía, pero no mide
directamente las operaciones de lectura y escritura.
Por tanto, un resultado ACTIVE no demuestra, por sí mismo, que un proceso esté realizando operaciones intensivas de disco.
3. Objetivos del sistema de monitoreo
Diseñamos el monitor para cumplir los siguientes objetivos:
- Consultar el estado físico del disco cada cinco minutos.
- Registrar los cambios de estado con fecha y hora.
- Utilizar memoria RAM para reducir escrituras.
- Conservar un historial persistente.
- Calcular las horas acumuladas en cada estado.
- Estimar el número de despertares.
- Generar reportes estadísticos desde SSH.
- Reconstruir determinadas optimizaciones después de reiniciar.
El monitor fue implementado mediante scripts de shell, sin instalar una base de datos adicional.
4. Organización de archivos
El sistema está instalado en una carpeta oculta del volumen principal:
/mnt/HD/HD_a2/.disk-sleep-monitor
La estructura principal es:
.disk-sleep-monitor/
|
+-- bin/
| +-- disk-sleep-monitor.sh
| +-- disk-sleep-report.sh
| +-- sync-tm-safe.sh
|
+-- archive/
|
+-- history.log
El directorio bin contiene los scripts
y history.log conserva el historial
de estados registrado.
Para crear la estructura básica desde cero:
mkdir -p /mnt/HD/HD_a2/.disk-sleep-monitor/bin
mkdir -p /mnt/HD/HD_a2/.disk-sleep-monitor/archive
Durante la operación normal también se utilizan varios archivos temporales en RAM:
/tmp/disk-sleep-history.log
/tmp/disk-sleep-last-state
/tmp/disk-sleep-persist-merge.log
Esta separación permite mantener los archivos de trabajo en memoria y conservar solamente el historial necesario en el disco.
5. Script principal de monitoreo
El archivo principal se denomina:
disk-sleep-monitor.sh
Su ubicación completa es:
/mnt/HD/HD_a2/.disk-sleep-monitor/bin/disk-sleep-monitor.sh
El script original realiza dos funciones: monitorear el disco y mantener determinadas optimizaciones de cron.
A continuación se reproduce la implementación utilizada en nuestro dispositivo.
#!/bin/sh
DISK="/dev/sda"
LOG="/tmp/disk-sleep-history.log"
STATEFILE="/tmp/disk-sleep-last-state"
PERSIST="/mnt/HD/HD_a2/.disk-sleep-monitor/history.log"
MERGE="/tmp/disk-sleep-persist-merge.log"
SAFE_SYNC="/tmp/sync-tm-safe.sh"
# Recrear wrapper seguro en RAM si no existe
if [ ! -x "$SAFE_SYNC" ]; then
cat > "$SAFE_SYNC" <<'EOS'
#!/bin/sh
STATE=$(hdparm -C /dev/sda 2>/dev/null | awk '/drive state is:/ {print $4}')
case "$STATE" in
standby)
exit 0
;;
*)
/usr/sbin/sync_tm_to_hd.sh
;;
esac
EOS
chmod +x "$SAFE_SYNC"
fi
# Sustituir la tarea original si WD la restaura
if crontab -l 2>/dev/null | grep -q '^0 \*/4 \* \* \* sync_tm_to_hd.sh &$'; then
crontab -l 2>/dev/null \
| sed 's|^0 \*/4 \* \* \* sync_tm_to_hd.sh &$|0 */4 * * * /tmp/sync-tm-safe.sh \&|' \
| crontab -
fi
# Mover stime de 02:30 a 03:00
if crontab -l 2>/dev/null | grep -q '^30 2 \* \* \* /usr/sbin/stime&$'; then
crontab -l 2>/dev/null \
| sed 's|^30 2 \* \* \* /usr/sbin/stime&$|0 3 * * * /usr/sbin/stime\&|' \
| crontab -
fi
# Wrapper para quota_monitor
QUOTA_SAFE="/tmp/quota-monitor-safe.sh"
if [ ! -x "$QUOTA_SAFE" ]; then
cat > "$QUOTA_SAFE" <<'EOS'
#!/bin/sh
STATE=$(hdparm -C /dev/sda 2>/dev/null | awk '/drive state is:/ {print $4}')
case "$STATE" in
standby)
exit 0
;;
*)
/usr/sbin/quota_monitor
;;
esac
EOS
chmod +x "$QUOTA_SAFE"
fi
if crontab -l 2>/dev/null | grep -q '^\*/30 \* \* \* \* /usr/sbin/quota_monitor &$'; then
crontab -l 2>/dev/null \
| sed 's|^\*/30 \* \* \* \* /usr/sbin/quota_monitor &$|*/30 * * * * /tmp/quota-monitor-safe.sh \&|' \
| crontab -
fi
# Wrapper para rlog
RLOG_SAFE="/tmp/rlog-safe.sh"
if [ ! -x "$RLOG_SAFE" ]; then
cat > "$RLOG_SAFE" <<'EOS'
#!/bin/sh
STATE=$(hdparm -C /dev/sda 2>/dev/null | awk '/drive state is:/ {print $4}')
case "$STATE" in
standby)
exit 0
;;
*)
/usr/sbin/rlog -s /usr/local/modules/files/syslog_rotate.conf
;;
esac
EOS
chmod +x "$RLOG_SAFE"
fi
if crontab -l 2>/dev/null | grep -q '^0 \*/4 \* \* \* /usr/sbin/rlog -s /usr/local/modules/files/syslog_rotate.conf$'; then
crontab -l 2>/dev/null \
| sed 's|^0 \*/4 \* \* \* /usr/sbin/rlog -s /usr/local/modules/files/syslog_rotate.conf$|0 */4 * * * /tmp/rlog-safe.sh|' \
| crontab -
fi
# Corregir horario de actualizaciones
if crontab -l 2>/dev/null | grep -q '^0 4 \* \* \* auto_fw -a -c&$'; then
crontab -l 2>/dev/null \
| sed 's|^0 4 \* \* \* auto_fw -a -c&$|20 3 * * * auto_fw -a -c\&|' \
| crontab -
fi
if crontab -l 2>/dev/null | grep -q '^42 10 \* \* \* auto_fw -c 1 &$'; then
crontab -l 2>/dev/null \
| sed 's|^42 10 \* \* \* auto_fw -c 1 &$|25 3 * * * auto_fw -c 1 \&|' \
| crontab -
fi
# Corregir horario de PullWdlogConfig
PULL_LINE=$(crontab -l 2>/dev/null | grep '/usr/local/sbin/PullWdlogConfig.sh' | head -1)
if [ -n "$PULL_LINE" ] && [ "$PULL_LINE" != "5 3 * * * /usr/local/sbin/PullWdlogConfig.sh" ]; then
crontab -l 2>/dev/null \
| grep -v '/usr/local/sbin/PullWdlogConfig.sh' \
| { cat; echo '5 3 * * * /usr/local/sbin/PullWdlogConfig.sh'; } \
| crontab -
fi
# Consultar estado del disco
STATE=$(hdparm -C "$DISK" 2>/dev/null | awk '/drive state is:/ {print $4}')
case "$STATE" in
standby)
STATE="STANDBY"
;;
active/idle|active)
STATE="ACTIVE"
;;
idle)
STATE="IDLE"
;;
*)
STATE="UNKNOWN"
;;
esac
# Recuperar estado anterior
OLDSTATE=""
[ -f "$STATEFILE" ] && OLDSTATE=$(cat "$STATEFILE")
# Registrar solamente cambios
if [ "$STATE" != "$OLDSTATE" ]; then
NOW=$(date '+%Y-%m-%d %H:%M:%S')
echo "$NOW $STATE" >> "$LOG"
echo "$STATE" > "$STATEFILE"
fi
# Consolidar historial cuando el disco esta activo
if [ "$STATE" = "ACTIVE" ]; then
: > "$MERGE"
[ -f "$PERSIST" ] && cat "$PERSIST" >> "$MERGE"
[ -f "$LOG" ] && cat "$LOG" >> "$MERGE"
sort -u "$MERGE" > "${MERGE}.new"
cp "${MERGE}.new" "$PERSIST"
cp "${MERGE}.new" "$LOG"
rm -f "$MERGE" "${MERGE}.new"
fi
Para asignar permisos de ejecución:
chmod +x /mnt/HD/HD_a2/.disk-sleep-monitor/bin/disk-sleep-monitor.sh
6. Cómo funciona el registro de estados
El monitor consulta el estado físico mediante:
hdparm -C /dev/sda
Posteriormente normaliza la respuesta a uno de los siguientes estados:
- ACTIVE
- IDLE
- STANDBY
- UNKNOWN
El script conserva en RAM el último estado detectado:
/tmp/disk-sleep-last-state
Cuando encuentra un cambio, registra la fecha, la hora y el nuevo estado.
Por ejemplo:
2026-10-15 11:50:00 ACTIVE
2026-10-15 11:55:00 IDLE
2026-10-15 13:20:01 ACTIVE
2026-10-15 13:30:01 IDLE
El historial permanece temporalmente en memoria RAM y se consolida en el volumen persistente cuando el monitor detecta ACTIVE.
Este diseño evita realizar escrituras persistentes mientras el estado detectado es STANDBY.
7. Configurar la ejecución automática
El monitor fue configurado para ejecutarse cada cinco minutos.
La entrada de cron es:
*/5 * * * * /mnt/HD/HD_a2/.disk-sleep-monitor/bin/disk-sleep-monitor.sh
Para comprobar si está registrada:
crontab -l | grep disk-sleep-monitor
En nuestra instalación comprobamos que la tarea también estaba registrada en la configuración persistente del firmware:
/usr/local/config/config.xml
La sección correspondiente era:
<disk_sleep_monitor>
<count>1</count>
<item id="1">
<method>3</method>
<1>*/5</1>
<2>*</2>
<3>*</3>
<4>*</4>
<5>*</5>
<run>/mnt/HD/HD_a2/.disk-sleep-monitor/bin/disk-sleep-monitor.sh</run>
</item>
</disk_sleep_monitor>
La configuración permaneció disponible después de reiniciar el dispositivo.
También comprobamos que el sistema la reconocía mediante:
xmldbc -g /system_mgr/crond/disk_sleep_monitor/count
Resultado:
1
Sin embargo, el procedimiento para registrar una tarea nueva directamente en XMLDB no fue probado durante este proyecto.
Por ello, no recomiendo copiar una configuración XML completa de otro dispositivo.
En una instalación nueva puede utilizarse
temporalmente la programación mediante
crontab, verificando su ejecución.
Para garantizar persistencia debe configurarse
un mecanismo compatible con el firmware instalado.
8. Optimización de tareas programadas
Durante la investigación identificamos varias tareas que podían ejecutarse aunque el disco estuviera suspendido.
Para reducir estos accesos desarrollamos tres scripts auxiliares.
Su funcionamiento es similar:
- Consultar el estado del HDD.
- Si está en STANDBY, terminar sin ejecutar la tarea.
- Si está en otro estado, ejecutar el comando original.
Los scripts se crean automáticamente
en /tmp cuando el monitor
detecta que no existen.
8.1. Supervisión de cuotas
Archivo:
/tmp/quota-monitor-safe.sh
Contenido:
#!/bin/sh
STATE=$(hdparm -C /dev/sda 2>/dev/null | awk '/drive state is:/ {print $4}')
case "$STATE" in
standby)
exit 0
;;
*)
/usr/sbin/quota_monitor
;;
esac
La tarea se ejecuta cada 30 minutos, pero omite la supervisión de cuotas cuando detecta el disco suspendido.
8.2. Rotación de registros
Archivo:
/tmp/rlog-safe.sh
Contenido:
#!/bin/sh
STATE=$(hdparm -C /dev/sda 2>/dev/null | awk '/drive state is:/ {print $4}')
case "$STATE" in
standby)
exit 0
;;
*)
/usr/sbin/rlog -s /usr/local/modules/files/syslog_rotate.conf
;;
esac
Este script permite omitir la rotación programada cuando el disco se encuentra suspendido.
8.3. Sincronización de información de tiempo
Archivo:
/tmp/sync-tm-safe.sh
Contenido:
#!/bin/sh
STATE=$(hdparm -C /dev/sda 2>/dev/null | awk '/drive state is:/ {print $4}')
case "$STATE" in
standby)
exit 0
;;
*)
/usr/sbin/sync_tm_to_hd.sh
;;
esac
Este procedimiento permite evitar la ejecución de la sincronización cuando el disco está en STANDBY.
Los tres scripts utilizan una política conservadora respecto a la ejecución de las tareas originales: si el estado no se reconoce, la tarea se ejecuta.
9. Concentrar tareas de mantenimiento
Otra modificación consistió en concentrar determinadas operaciones de mantenimiento durante la madrugada.
El monitor reconoce ciertas entradas originales de cron y las sustituye por nuevos horarios.
| Proceso | Horario configurado |
|---|---|
| stime | 03:00 |
| PullWdlogConfig.sh | 03:05 |
| auto_fw -a -c | 03:20 |
| auto_fw -c 1 | 03:25 |
El objetivo fue evitar que varias operaciones programadas se distribuyeran a lo largo del día.
No obstante, esta concentración de tareas todavía no ha demostrado una mejora sostenida en el tiempo que el HDD permanece suspendido.
10. Generar estadísticas de suspensión
Para analizar las mediciones desarrollamos un segundo script:
/mnt/HD/HD_a2/.disk-sleep-monitor/bin/disk-sleep-report.sh
Este programa combina los registros temporales y persistentes, calcula el tiempo transcurrido entre cambios de estado y presenta estadísticas acumuladas.
El código completo utilizado fue:
#!/bin/sh
RAMLOG="/tmp/disk-sleep-history.log"
PERSIST="/mnt/HD/HD_a2/.disk-sleep-monitor/history.log"
MERGED="/tmp/disk-sleep-merged.log"
: > "$MERGED"
[ -f "$PERSIST" ] && cat "$PERSIST" >> "$MERGED"
[ -f "$RAMLOG" ] && cat "$RAMLOG" >> "$MERGED"
sort -u "$MERGED" -o "$MERGED"
if [ ! -s "$MERGED" ]; then
echo "No hay historial disponible."
exit 1
fi
awk '
function tosec(d,t, cmd,x) {
cmd = "date -d \"" d " " t "\" +%s"
cmd | getline x
close(cmd)
return x
}
NR==1 {
first_date=$1
first_clock=$2
prev_time=tosec($1,$2)
prev_state=$3
next
}
{
now=tosec($1,$2)
delta=now-prev_time
if (prev_state=="ACTIVE")
active+=delta
else if (prev_state=="IDLE")
idle+=delta
else if (prev_state=="STANDBY")
standby+=delta
else
unknown+=delta
if (prev_state=="STANDBY" && $3!="STANDBY")
wakeups++
prev_time=now
prev_state=$3
}
END {
cmd="date +%s"
cmd | getline now
close(cmd)
delta=now-prev_time
if (prev_state=="ACTIVE")
active+=delta
else if (prev_state=="IDLE")
idle+=delta
else if (prev_state=="STANDBY")
standby+=delta
else
unknown+=delta
total=active+idle+standby+unknown
printf "Desde %s %s:\n\n", first_date, first_clock
if (total>0) {
printf "Activo: %.2f h (%.1f%%)\n", active/3600, active*100/total
printf "Idle: %.2f h (%.1f%%)\n", idle/3600, idle*100/total
printf "Dormido: %.2f h (%.1f%%)\n", standby/3600, standby*100/total
printf "Desconocido: %.2f h (%.1f%%)\n", unknown/3600, unknown*100/total
printf "Total: %.2f h\n", total/3600
printf "Despertares: %d\n", wakeups
printf "Estado actual: %s\n", prev_state
}
}
' "$MERGED"
11. Ejecutar el reporte estadístico
Para generar un reporte utilizamos:
/mnt/HD/HD_a2/.disk-sleep-monitor/bin/disk-sleep-report.sh
Una de las mediciones obtenidas el 15 de octubre de 2026 fue:
Desde 2026-10-02 15:35:00:
Activo: 146.40 h (46.6%)
Idle: 136.39 h (43.4%)
Dormido: 31.26 h (10.0%)
Desconocido: 0.00 h (0.0%)
Total: 314.06 h
Despertares: 68
Estado actual: IDLE
Estas estadísticas representan el comportamiento acumulado desde el inicio del periodo de medición.
12. Cómo interpretar los resultados
En el reporte anterior encontramos:
| Indicador | Resultado |
|---|---|
| Tiempo monitoreado | 314.06 horas |
| ACTIVE | 46.6% |
| IDLE | 43.4% |
| STANDBY | 10.0% |
| Despertares detectados | 68 |
El disco permaneció suspendido 31.26 horas durante el periodo.
Sin embargo, encontramos un problema: durante los últimos días de medición, el tiempo acumulado en STANDBY dejó de aumentar.
El contador de despertares también permaneció en 68.
Esto no representa necesariamente una mejora, porque el disco no estaba entrando nuevamente en suspensión.
Las modificaciones realizadas no habían conseguido todavía restablecer periodos prolongados de STANDBY.
13. Cómo se calculan los despertares
El script considera que ocurrió un despertar cuando detecta una transición desde STANDBY hacia cualquier otro estado.
La condición utilizada es:
if (prev_state=="STANDBY" && $3!="STANDBY")
wakeups++
Esto permite estimar cuántas veces el disco abandona el estado de suspensión.
Sin embargo, la medición se realiza cada cinco minutos.
Por tanto, pueden existir ciclos de suspensión y reactivación que ocurran entre dos mediciones y no sean registrados.
El contador representa despertares detectados por el monitor, no necesariamente todos los despertares físicos del HDD.
14. Limitaciones del sistema
El monitor es útil para analizar tendencias de funcionamiento, pero presenta algunas limitaciones.
14.1. Precisión temporal
Los cambios de estado se detectan mediante consultas cada cinco minutos.
Por ello, la duración de cada estado se estima utilizando la hora en que se detectó la transición.
14.2. Reportes acumulados
El reporte calcula los indicadores desde el primer registro disponible.
Si modificamos la configuración del NAS durante el periodo, las estadísticas mezclan mediciones anteriores y posteriores al cambio.
Para evaluar una modificación concreta conviene analizar solamente el intervalo posterior a ella.
14.3. Persistencia del historial
Los cambios de estado se registran inicialmente en RAM.
El historial se consolida en disco cuando el monitor detecta ACTIVE.
Si el dispositivo reinicia antes de esa consolidación, pueden perderse registros temporales.
14.4. Estado actual del reporte
El script de reportes muestra el último estado registrado en el historial.
No consulta nuevamente el estado físico del disco.
Por tanto, para conocer el estado instantáneo conviene utilizar:
hdparm -C /dev/sda
14.5. Efecto de las escrituras del monitor
Aunque el diseño evita consolidar el historial cuando detecta STANDBY, sí puede realizar escrituras cuando el disco está ACTIVE.
Además, el script puede modificar crontab si encuentra tareas que deben corregirse.
Por tanto, no debemos considerar que el sistema de monitoreo está completamente libre de efectos sobre la actividad del NAS.
15. Verificación después de reiniciar
Después de reiniciar el WD My Cloud comprobamos que la tarea principal seguía registrada:
crontab -l | grep disk-sleep-monitor
También verificamos que los tres scripts auxiliares habían sido reconstruidos en RAM.
ls -l /tmp/*-safe.sh
Los archivos aparecieron con permisos de ejecución.
Esto confirmó que el monitor podía continuar funcionando después del reinicio.
La recuperación depende de que la tarea principal continúe registrada y pueda ejecutarse.
16. Diagnóstico rápido
Para consultar el estado del sistema podemos utilizar:
echo "=== ESTADO DEL DISCO ==="
hdparm -C /dev/sda
echo "=== TAREA PROGRAMADA ==="
crontab -l | grep disk-sleep-monitor
echo "=== SCRIPTS AUXILIARES ==="
ls -l /tmp/*-safe.sh
echo "=== ULTIMOS REGISTROS ==="
tail -10 /mnt/HD/HD_a2/.disk-sleep-monitor/history.log
echo "=== REPORTE ==="
/mnt/HD/HD_a2/.disk-sleep-monitor/bin/disk-sleep-report.sh
Este conjunto de comandos permite comprobar el estado físico del HDD, la programación del monitor, la existencia de los scripts auxiliares y las estadísticas acumuladas.
17. Cómo detener el monitoreo
Si necesitamos suspender temporalmente las mediciones, podemos eliminar la tarea correspondiente de cron, conservando los archivos del monitor.
Sin embargo, en nuestra instalación la tarea también está registrada en la configuración persistente del firmware.
Por tanto, eliminarla únicamente del crontab puede no impedir que vuelva a aparecer después de reiniciar.
Antes de desinstalar completamente el monitor, también deben revisarse las tareas de mantenimiento que utilizan sus scripts auxiliares.
No es recomendable eliminar
los archivos de /tmp
mientras existan tareas programadas
que dependan de ellos.
18. Resultados y conclusiones
El sistema desarrollado permitió medir el comportamiento del disco durante varios días y conservar un historial de sus estados.
Entre los resultados obtenidos destacan:
- Registro automático cada cinco minutos.
- Identificación de ACTIVE, IDLE y STANDBY.
- Estadísticas acumuladas de tiempo.
- Conteo de despertares detectados.
- Persistencia del historial.
- Reconstrucción de scripts auxiliares después de reiniciar.
- Optimización de determinadas tareas programadas.
También comprobamos que reducir algunas operaciones periódicas no garantiza por sí mismo que el disco entre en suspensión.
En la medición del 15 de octubre de 2026 el tiempo acumulado de STANDBY permanecía en 31.26 horas, sin incrementos recientes.
Esto indica que todavía existen factores que debemos investigar para conseguir periodos de suspensión más prolongados.
El principal resultado de este proyecto es disponer de una herramienta para medir objetivamente el comportamiento del HDD antes y después de realizar cambios.
Próximo capítulo
Capítulo 6. Optimización de servicios, procesos y tareas programadas en WD My Cloud OS5.
Analizaremos los servicios internos del firmware, las tareas que se ejecutan periódicamente y los procedimientos utilizados para reducir la actividad innecesaria del disco.
Documentación técnica basada en pruebas realizadas sobre WD My Cloud Gen 2 con My Cloud OS5 5.33.102, septiembre y octubre de 2026.
Comentarios
Publicar un comentario