Servidor NAS casero: Refrescando la Odroid XU-4

Continuando con la serie de artículos dedicados a la Odroid XU-4 y a mi aventura de intentar convertirla en un servidor NAS sin pasar por instalarme sistemas con todo ya integrado, ahora quería compartir una particularidad (o truco) que puede ayudar a que los componentes de la placa funcionen algo mejor.

En una configuración ideal, la placa estará siempre encendida. Si solamente consume 20 vatios (como potencia máxima), es muy barato mantenerla operando todo el tiempo y es mucho más fácil, de cara a la gente que vaya a utilizar el servidor. De otro modo, habría qué encenderla cuando se necesite utilizar, pero teniendo en cuenta que una de las tareas que quería que la placa pudiera hacer es actualizar un respaldo de mis ficheros más importantes en un Bucket de backblaze, y que esto lo hiciera a determinadas horas en el día, mantenerla encendida es la mejor idea.

Pero antes de dejar todo esto así, he notado que la placa se calienta un poco más de lo que me gustaría, hasta el punto de hacerlo bastante notable al tocar la parte inferior de la misma. No llega a ser peligroso tenerla así, pero he pensado que, ya que estará encendida por muchos días sin ver descanso, sería bueno mitigar ese problema.

El ventilador de la Odroid XU-4

La gente de HardKernel, los fabricantes de la placa, ha pensado en esto al diseñar las especificaciones hardware de este pequeño gigante. La potencia extra que viene con el hardware también hace que la temperatura se eleve más rápidamente. Para compensar este problema, la Odroid XU-4 lleva un pequeño ventilador integrado en la parte superior del dispositivo. Este ventilador se enciende cuando el sistema determina que la temperatura de los 8 CPU'S o la GPU es demasiado alta para un nivel deseable, y necesita refrigerarse un poco. El Ventilador, con su configuración por defecto, cuenta con 3 velocidades de rotación: Apagado, rotación suave, intermedia y máxima potencia.

La configuración del sistema funciona utilizando un umbral de temperatura de 3 que hay disponibles. Si la temperatura en promedio de los 5 sensores (la GPU se cuenta por separado) está dentro de un umbral predeterminado, se aplica la velocidad del ventilador que corresponde al mismo. Todo esto sucede de forma completamente automática, aunque también es posible controlar la rotación del ventilador manualmente o desactivar su encendido, aunque no entendería por qué se debería hacer esto último.

Por defecto, el sistema se comportará así:

Desde la terminal en Linux, se puede consultar la temperatura de los sensores para los 4 procesadores A15 (los "big") y la GPU. Para consultarlos, se llama simplemente a 5 archivos creados de forma especial durante el arranque por el kernel. Estas son las ubicaciones de los archivos:

Los primeros 4 ficheros (desde termal_zone0 hasta 3) corresponden a los núcleos de la CPU, y el último es para la GPU. En la práctica, todos los sensores marcan la misma temperatura (un grado más, un grado menos) porque se encuentran juntos en la misma placa, así que si se calienta una parte de la CPU inmediatamente transfiere ese calor al resto de componentes. Quiero decir que no es necesario consultar los 5 sensores para determinar la temperatura, con revisar la zona 0 será suficiente y los valores serán prácticamente los mismos para el resto de zonas. Aquí se puede ver un ejemplo de cómo se consulta esto desde la sesión SSH. La línea donde he escrito el comando es la que empieza por el signo dólar, y la respuesta del comando empieza sin ese signo. De ahora en adelante, ese será el modo en el que mostraré los comandos: Todos los que lleven un símbolo de dólar delante son comandos, y los que no lo lleven son respuestas a los comandos:

$ cat /sys/devices/virtual/thermal/thermal_zone0/temp
58000

Este comando indica que en mi caso, la placa se encuentra a unos 58 grados. El número que devuelve este sensor únicamente se divide entre 1000 para obtener la temperatura en grados.

Ajustando los umbrales de temperatura

Yo vivo en una ciudad bastante calurosa, y esta configuración por defecto de los umbrales de temperatura no es muy ventajosa para mis condiciones actuales, ya que con el tiempo teniendo la Odroid XU-4 corriendo (sin nada ejecutando, simplemente mientras funcionaba sin casi nada instalado), pasaba algo así:

  1. El sistema encendido eventualmente alcanzaba los 60 grados.
  2. El ventilador encendía un par de minutos.
  3. La temperatura bajaba a los 58 grados o algo más.
  4. Vuelta al paso 1.

El problema era que no se podía tocar la placa por un espacio relativamente largo de tiempo sin sentir que eso estaba muy caliente. Y el otro problema era que 60 grados me parecían una temperatura algo menos que ideal para una cosa que se presuponía durar todo el tiempo encendida. Así que terminé por modificar los umbrales de temperatura y hacerlos un poco más bajos.

Como esto es Linux, y todo es prácticamente un fichero, podemos consultar los 3 umbrales de temperatura para cada uno de los sensores que vienen en este procesador. Para esto utilizaremos un fichero que se encuentra en el mismo directorio que en el ejemplo para consultar la temperatura. En inglés, los umbrales de temperatura se llaman trip points, así que podemos utilizar este comando para mostrar los 3 trip points asociados a cada zona:

$ cat /sys/devices/virtual/thermal/thermal_zone{0,1,2,3}/trip_point_{0,1,2}_temp
# resultados
60000
70000
80000
60000
70000
80000
60000
70000
80000
60000
70000
80000

Este comando es una versión de una línea, pero lo que realmente se hace es consultar los ficheros trip_point0_temp, cambiando el 0 por 1 y 2 en ejecuciones subsecuentes del comando, y este proceso se repite para las 5 zonas de temperatura disponibles. Esto quiere decir que por cada uno de los sensores de temperatura que hay instalados en la Odroid, existen 3 trip_points. Cada trip_point se encuentra asociado a una velocidad del ventilador y por defecto el menor de ellos, el que está marcado con el número 0, tiene la velocidad menor del ventilador. Si la temperatura actual es menor que todos estos trip_points, entonces el ventilador se mantiene apagado. En el ejemplo de mi propia placa, la temperatura que marcaba era de 58 grados, así que no había ninguno de estos puntos activo en el momento de medirla.

Los trip_point solo son ficheros de texto sobre los que se puede escribir con normalidad. Aunque la documentación hable de un promedio, la realidad es que si, por poner el ejemplo, se escribe que el trip_point0 de la zona 0 sea activado a los 30 grados, eso es exactamente lo que ocurrirá aunque el promedio del resto de sensores pueda indicar algo distinto. Los valores de temperaturas en todo esto siempre deben expresarse de la misma forma (multiplicando los grados por 1000). Por ejemplo, para hacer que el ventilador active el primer trip_point al momento de llegar a 30 grados, lo que hará que empiece a girar, se debe escribir el siguiente comando:

$ echo 30000 | sudo tee /sys/devices/virtual/thermal/thermal_zone{0,1,2,3}/trip_point_0_temp
$ cat /sys/devices/virtual/thermal/thermal_zone{0,1,2,3}/trip_point_0_temp
# resultados.
30000
30000
30000
30000

Ten en cuenta que por lo general, al cambiar un trip_point se debe hacer con esta sintaxis, o cambiar manualmente el mismo trip_point para thermal_zone0, thermal_zone1, thermal_zone2 y así sucesivamente. El segundo comando ejecutado simplemente comprueba que los cambios se han escrito correctamente. Es una práctica bastante común al tocar algún parámetro del hardware de esta clase de dispositivos.

Al paso de un par de segundos, si la temperatura reportada en ese momento es mayor a 30 grados, el ventilador comenzará a girar y eso hará que la placa tenga algo más de disipación de calor y en general pueda bajar, en mi ejemplo, algunos 18 grados luego de varios minutos de actividad, lo que es bastante bien recibido.

$ cat /sys/devices/virtual/thermal/thermal_zone0/temp
40000

Bien, ¡ahora se ve mucho mejor!

Aplicar los cambios permanentemente

Un dato importante de modificar el hardware de este modo es que el cambio se mantiene activo siempre que la placa no sea reiniciada o apagada. Si alguna de estas dos cosas ocurre, los valores regresarán a los 60 grados para el primer trip_point. Afortunadamente, podemos llegar a un efecto global de esto estableciendo el cambio en el fichero /etc/rc.local. Este fichero se ejecuta cuando termina el inicio normal del sistema, justo antes de ejecutar la sesión de cualquier usuario y, de forma ideal, debería contener la mayoría de las veces comandos que sirvan para modificar algún parámetro en un fichero de configuración del sistema. Es decir, líneas simples que no sean tan complejas como para necesitar de una unidad de Systemd o algo similar para ser iniciadas.

Editar este fichero tiene un truco bastante simple, pero que es importante tener en cuenta. Una vez abierto, verás muchas líneas de comentario (se identifican por empezar con un signo de número (#)). El truco es ir hacia el final del fichero, pero escribir los comandos que necesites justo antes de la única línea que no lleva comentarios, "exit 0". Esta línea es siempre la última que se lee de este fichero y lo que sea colocado debajo de ella no se interpretará. Estas son las líneas del fichero /etc/rc.local "nuevo", sin modificar:

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.



if [ -f /aafirstboot ]; then /aafirstboot start ; fi

exit 0

Ahora que ya se ve claro cómo editar este fichero (solo añadir las líneas que sean antes de la última), continuamos con la historia. Para cambiar los puntos de temperatura a unos valores algo más recomendables, y mantener el cambio, yo he establecido el primer trip_point a 30 grados, el segundo a 50 y el tercero a 70. Esto lo he pegado antes del "exit 0", justo así:

# Activar los trip_points a las siguientes temperaturas: 30°C, 50°C, 70°C
# Estas variables se usarán por comodidad en el resto del script.
# Para cambiar las temperaturas solo hay qué editarlas.
TRIP_POINT_0=30000
TRIP_POINT_1=50000
TRIP_POINT_2=70000

# aquí se escribe el texto a los ficheros correspondientes.
# Primer trip_point
echo $TRIP_POINT_0 > /sys/devices/virtual/thermal/thermal_zone0/trip_point_0_temp
echo $TRIP_POINT_0 > /sys/devices/virtual/thermal/thermal_zone1/trip_point_0_temp
echo $TRIP_POINT_0 > /sys/devices/virtual/thermal/thermal_zone2/trip_point_0_temp
echo $TRIP_POINT_0 > /sys/devices/virtual/thermal/thermal_zone3/trip_point_0_temp

# segundo trip_point
echo $TRIP_POINT_1 > /sys/devices/virtual/thermal/thermal_zone0/trip_point_1_temp
echo $TRIP_POINT_1 > /sys/devices/virtual/thermal/thermal_zone1/trip_point_1_temp
echo $TRIP_POINT_1 > /sys/devices/virtual/thermal/thermal_zone2/trip_point_1_temp
echo $TRIP_POINT_1 > /sys/devices/virtual/thermal/thermal_zone3/trip_point_1_temp

# tercer trip_point
echo $TRIP_POINT_2 > /sys/devices/virtual/thermal/thermal_zone0/trip_point_2_temp
echo $TRIP_POINT_2 > /sys/devices/virtual/thermal/thermal_zone1/trip_point_2_temp
echo $TRIP_POINT_2 > /sys/devices/virtual/thermal/thermal_zone2/trip_point_2_temp
echo $TRIP_POINT_2 > /sys/devices/virtual/thermal/thermal_zone3/trip_point_2_temp

exit 0

Para comprobar si ha funcionado, es posible reiniciar el sistema operativo con el comando sudo reboot.

emular temperaturas

Una última cosa que me gustaría describir sobre este tema es que se puede emular la temperatura de la placa. Así no será necesario llevarla a un punto de uso intensivo para notar si el ventilador responde correctamente a los cambios que se le realizan. Esta técnica puede ser de utilidad para probar cambios en los umbrales de temperatura, o en la escala de velocidad del ventilador. Y simplemente consiste en escribir a otro fichero, como ya es costumbre. Se hace de la siguiente forma, por ejemplo, para hacer que la Odroid crea que estamos a 85 grados:

$ echo 85000 | sudo tee /sys/devices/virtual/thermal/thermal_zone{0,1,2,3}/emul_temp
# resultados.
85000

ahora, puedes comprobar la temperatura y ver si el cambio ha surtido efecto:

$ cat /sys/devices/virtual/thermal/thermal_zone{0,1,2,3}/temp
# resultados.
85000
85000
85000
85000

Este fichero pasará como válido todo lo que se le ponga aquí y remplazará la temperatura del sistema. Es decir, si esto tiene un valor diferente de 0, que significa desactivado, el sensor de temperatura es ignorado y el valor de este archivo es usado en su lugar. Ahora, para regresar la placa a su estado normal, que tampoco es muy bueno tener el ventilador a toda potencia todo el tiempo, supongo yo, se establece este fichero a 0 y ya está:

$ echo 0 | sudo tee /sys/devices/virtual/thermal/thermal_zone{0,1,2,3}/emul_temp
# resultados
0 
$ cat /sys/devices/virtual/thermal/thermal_zone{0,1,2,3}/temp
# resultados
42000
41000
45000
41000

conclusión

Luego de haber repasado la mayoría de configuraciones para el ventilador integrado, he dejado los trip_points modificados y gracias al fichero rc.local, este cambio se aplica durante el arranque del sistema. Ahora la placa se siente mejor en el uso diario ininterrumpido, y ha estado funcionando así por unos 14 días sin problema alguno.

Se puede encontrar más información sobre la configuración de este tema en la placa en la Wiki de Odroid Xu-4 (en inglés)

Add Comment

Share

Share in Facebook
Share in Twitter

Change language