Solucionando ventilador al 100% al volver de suspender el sistema

recoveryLlevo teniendo este problema con Ubuntu en un portátil desde… bueno, desde siempre, que yo recuerde, pero como normalmente suelo apagarlo no me había preocupado de buscar cómo arreglarlo.

Hoy me picó la curiosidad y me puse a investigar. Resulta que al parecer el problema viene de que el SO asume que al volver del estado suspendido los ventiladores estarán en el estado en que estaban antes de suspender, y esto dependiendo del hardware no tiene por qué ser así.

Parece que en algunos sistemas (no se cuales, pero en el mío definitivamente debe ser el caso) al volver de la suspensión los ventiladores se ponen automáticamente al 100%, y como el SO no los restaura a ningún estado se quedan ahí bufando sin razón.

De hecho si cuando están ahí a tope lanzas un proceso intensivo que normalmente aumentaría la frecuencia de los ventiladores, al terminar dicho proceso los ventiladores se ralentizan de vuelta a un estado normal, así que definitivamente parece confirmarse la hipótesis del estado inicial incorrecto.

La primera solución que encontré hablaba de crear un script en /etc/pm/sleep.d que pusiese a cero los ventiladores. Supuestamente los scripts en esta ruta se ejecutan al volver desde el estado suspendido, así que debería funcionar automáticamente.

Al script le llamaremos por ejemplo 10_fancontrol, y sería:


#!/bin/sh
case "$1" in
        resume|thaw)
                for i in $(seq 0 15) ; 
                do 
                        echo "0" > /sys/devices/virtual/thermal/cooling_device${i}/cur_state
                done
;;
esac

En la ruta /sys/devices/virtual/thermal/ hay una serie de directorios, comenzando por cooling_device0 y llegando hasta cooling_device10 o más, dependiendo del hardware (en mi portátil va hasta el 15).

Si haces un cat del archivo cur_state dentro de cada uno de esos directorios verás que hay o bien un 0 o un 1, correspondiendo el 1 al estado en que el ventilador está activo, así que lo que hacemos es poner todos a cero.

El problema: resulta que ahora con systemd esto ya no funciona, ya que no se ejecutan automáticamente los scripts de esa ruta.

La solución: crear un servicio de systemd.

Seguramente se podría hacer de forma más limpia, pero con esto funciona: vamos al directorio /etc/systemd/system/suspend.target.wants y creamos un nuevo archivo, por ejemplo root-suspend.service:


cd /etc/systemd/system/suspend.target.wants
sudo vi root-suspend.service

Dentro de este archivo ponemos lo siguiente:


[Unit]
Description=Local system resume actions
After=suspend.target

[Service]
Type=simple
ExecStart=-/etc/pm/sleep.d/10_fancontrol resume

[Install]
WantedBy=suspend.target

Lo que conseguimos con esto es crear un servicio dependiente de suspend.target (es decir, que se ejecutará cuando lo haga el servicio suspend) y que además lo hará después (de ahí lo de la línea con “After”).

En él lo que se hará será ejecutar el script que habíamos creado antes en /etc/pm/sleep.d

Una vez guardado le he dado permisos de lectura y ejecución para todos (no se si es imprescindible, pero los demás archivos de esa ruta parecen tenerlos):


chmod +rx root-suspend.service

Con esto ya no hace falta nada más. Probando a hacer un suspend ya no se quedan los ventiladores al 100%, si no que en un par de segundos se apagan. Además no parece tener efectos secundarios negativos ya que al hacer una prueba de stress de CPU el ventilador se activa normalmente como se esperaría, y una vez terminada la prueba se vuelve a apagar.

Tampoco es que le vaya a dar mucha utilidad a esto porque sigo apagando el portátil normalmente cuando no lo uso, pero mira, un misterio resuelto al menos.