Páginas

Buscar este blog

viernes, 16 de octubre de 2026

Restaurar red tras resume ACPI en FreeBSD

Objetivo

Ejecutar automáticamente un script al despertar el equipo de suspensión (S3) para restaurar:

  • Ethernet con IP fija
  • Reglas de pf
  • Ratón USB
  • Cliente NFS

Piezas necesarias

Pieza Ruta
Script de restauración /usr/local/sbin/resume-network.sh
Regla de devd /etc/devd/resume-network.conf
Log del script /var/log/resume-network.log
Syslog (logger) /var/log/messages

1️⃣ Crear el script

doas vim /usr/local/sbin/resume-network.sh

Puntos clave:

  • Shebang: #!/bin/sh
  • PATH completo al inicio (devd lo ejecuta con PATH mínimo):
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
export PATH

Redirigir toda la salida a un log para depurar:

exec >> /var/log/resume-network.log 2>&1
  • Función log() que escribe a archivo y a syslog
log() {
    echo "[$(date '+%F %T')] $*"
    logger -t resume-network "$*"
}
  • Usar rutas absolutas en comandos críticos (/sbin/pfctl, /usr/local/bin/wg-quick, etc.).
  • Esperar a que el enlace esté active antes de reasignar IP.
  • Al reasignar IP fija: borrar primero la IP previa y borrar la ruta por defecto antes de volver a añadirla.

Dar permisos:

doas chmod +x /usr/local/sbin/resume-network.sh

2️⃣ Script completo

#!/bin/sh
# =========================================================
# /usr/local/sbin/resume-network.sh
# Restaura Ethernet (em0, IP fija), ratón USB y NFS
# tras un resume ACPI.
# (WireGuard y qBittorrent excluidos)
# =========================================================

# PATH completo: devd ejecuta los scripts con un PATH mínimo
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
export PATH

LOG="/var/log/resume-network.log"
exec >> "$LOG" 2>&1

# Función para loguear en archivo y en syslog
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
    logger -t resume-network "$*"
}

log "=== $(date) - Resume detectado ==="

# ---------------------------------------------------------
# 1. Ethernet: reactivar em0 y aplicar IP fija
# ---------------------------------------------------------
sleep 3

ifconfig em0 down
sleep 1
ifconfig em0 up

# Esperar a que el enlace esté activo (hasta 15s)
i=0
status=""
while [ $i -lt 15 ]; do
    status=$(ifconfig em0 | awk '/status:/ {print $2}')
    [ "$status" = "active" ] && break
    sleep 1
    i=$((i + 1))
done

log "em0 status=$status tras ${i}s"

if [ "$status" != "active" ]; then
    log "ERROR - em0 sin enlace tras ${i}s"
    exit 1
fi

# Eliminar IP previa (si existe) y reaplicar IP fija y ruta
ifconfig em0 inet 192.168.88.50 delete 2>/dev/null
ifconfig em0 inet 192.168.88.50 netmask 255.255.255.0
route delete default 2>/dev/null
route add default 192.168.88.1

log "Ethernet OK (IP fija y ruta activas)"

# ---------------------------------------------------------
# 2. Recargar pf para limpiar estados obsoletos
# ---------------------------------------------------------
/sbin/pfctl -f /etc/pf.conf 2>/dev/null
log "pf recargado"

# ---------------------------------------------------------
# 3. Verificar conectividad con reintentos
# ---------------------------------------------------------
connected=0
for attempt in 1 2 3; do
    if ping -c 1 -t 3 192.168.88.1 >/dev/null 2>&1; then
        connected=1
        break
    fi
    sleep 2
done

if [ "$connected" != "1" ]; then
    log "ERROR - sin conectividad a la puerta de enlace"
    exit 1
fi
log "Conectividad verificada tras ${attempt} intento(s)"

# ---------------------------------------------------------
# 4. Reactivar ratón USB
# ---------------------------------------------------------
if kldstat -q -m ums 2>/dev/null; then
    kldunload ums 2>/dev/null
    sleep 1
    kldload ums
    log "módulo ums recargado"
elif kldstat -q -m uhid 2>/dev/null; then
    kldunload uhid 2>/dev/null
    sleep 1
    kldload uhid
    log "módulo uhid recargado"
else
    log "ni ums ni uhid cargados, ratón sin cambios"
fi

# Reiniciar moused si está corriendo
if pgrep -q moused; then
    service moused restart 2>/dev/null || {
        pkill -f moused 2>/dev/null
        sleep 1
        service moused start 2>/dev/null
    }
    log "moused reiniciado"
fi

# ---------------------------------------------------------
# 5. Reiniciar el cliente NFS
# ---------------------------------------------------------
service nfsclient restart
log "nfsclient reiniciado"

# Opcional: remontar sistemas NFS si se quedan colgados
# mount -a -t nfs
# log "sistemas NFS remontados"

log "=== $(date) - Resume completado ==="
exit 0

3️⃣ Crear la regla de devd

# cat /etc/devd/resume-network.conf 
notify 100 {
    match "system"      "ACPI";
    match "subsystem"   "Resume";
    action "/usr/local/sbin/resume-network.sh";
};

Aplicar cambios

doas service devd restart

Comprobar que devd ve el evento

Verifica que el subsystem sea exactamente el correcto. Algunos equipos emiten Resume y otros resume. Para ver qué llega:

doas devd -d

Suspende y despierta el equipo. Si no aparece el evento ACPI/Resume, ajusta la regla con el subsystem que realmente emita tu hardware (puedes verlo también en /var/log/messages).

4️⃣ Probar sin suspender

Ejecuta el script manualmente como root:

doas sh -x /usr/local/sbin/resume-network.sh

Y revisa el log:

tail -f /var/log/resume-network.log

5️⃣ Depurar tras un resume real

Log propio del script:

tail -n 50 /var/log/resume-network.log
add net default: gateway 192.168.88.1
[2026-10-16 15:02:49] Ethernet OK (IP fija y ruta activas)
[2026-10-16 15:02:49] pf recargado
[2026-10-16 15:02:51] Conectividad verificada tras 1 intento(s)
[2026-10-16 15:02:51] ni ums ni uhid cargados, ratón sin cambios
Starting default moused.
[2026-10-16 15:02:51] moused reiniciado
NFS access cache time=60
[2026-10-16 15:02:51] nfsclient reiniciado
[2026-10-16 15:02:51] === Fri Oct 16 15:02:51 CEST 2026 - Resume completado ===
[2026-10-16 15:03:28] === Fri Oct 16 15:03:28 CEST 2026 - Resume detectado ===
[2026-10-16 15:03:36] em0 status=active tras 2s

add net default: gateway 192.168.88.1
[2026-10-16 15:03:37] Ethernet OK (IP fija y ruta activas)
[2026-10-16 15:03:37] pf recargado
[2026-10-16 15:03:42] Conectividad verificada tras 2 intento(s)
[2026-10-16 15:03:42] ni ums ni uhid cargados, ratón sin cambios
Starting default moused.
[2026-10-16 15:03:42] moused reiniciado
NFS access cache time=60
[2026-10-16 15:03:42] nfsclient reiniciado
[2026-10-16 15:03:42] === Fri Oct 16 15:03:42 CEST 2026 - Resume completado ===
[2026-10-16 18:34:14] === Fri Oct 16 18:34:14 CEST 2026 - Resume detectado ===
[2026-10-16 18:34:23] em0 status=active tras 2s

add net default: gateway 192.168.88.1
[2026-10-16 18:34:23] Ethernet OK (IP fija y ruta activas)
[2026-10-16 18:34:23] pf recargado
[2026-10-16 18:34:26] Conectividad verificada tras 1 intento(s)
[2026-10-16 18:34:26] ni ums ni uhid cargados, ratón sin cambios
Starting default moused.
[2026-10-16 18:34:26] moused reiniciado
NFS access cache time=60
[2026-10-16 18:34:26] nfsclient reiniciado
[2026-10-16 18:34:26] === Fri Oct 16 18:34:26 CEST 2026 - Resume completado ===
[2026-10-16 21:58:08] === Fri Oct 16 21:58:08 CEST 2026 - Resume detectado ===
[2026-10-16 21:58:16] em0 status=active tras 2s

add net default: gateway 192.168.88.1
[2026-10-16 21:58:17] Ethernet OK (IP fija y ruta activas)
[2026-10-16 21:58:17] pf recargado
[2026-10-16 21:58:22] Conectividad verificada tras 2 intento(s)
[2026-10-16 21:58:22] ni ums ni uhid cargados, ratón sin cambios
Starting default moused.
[2026-10-16 21:58:22] moused reiniciado
NFS access cache time=60
[2026-10-16 21:58:22] nfsclient reiniciado
[2026-10-16 21:58:22] === Fri Oct 16 21:58:22 CEST 2026 - Resume completado ===

Mensajes que ha escrito devd y el script vía logger:

grep resume /var/log/messages
Oct 16 21:58:08 solaris resume-network[18841]: === Fri Oct 16 21:58:08 CEST 2026 - Resume detectado ===
Oct 16 21:58:16 solaris resume-network[18862]: em0 status=active tras 2s
Oct 16 21:58:17 solaris resume-network[18871]: Ethernet OK (IP fija y ruta activas)
Oct 16 21:58:17 solaris resume-network[18877]: pf recargado
Oct 16 21:58:22 solaris resume-network[18891]: Conectividad verificada tras 2 intento(s)
Oct 16 21:58:22 solaris resume-network[18898]: ni ums ni uhid cargados, ratón sin cambios
Oct 16 21:58:22 solaris resume-network[18929]: moused reiniciado
Oct 16 21:58:22 solaris resume-network[18945]: nfsclient reiniciado
Oct 16 21:58:22 solaris resume-network[18951]: === Fri Oct 16 21:58:22 CEST 2026 - Resume completado ===

Errores frecuentes

Síntoma Causa Solución
Nada ocurre al despertar & al final del action Quitarlo
Nada ocurre al despertar subsystem distinto (resume vs Resume) Ajustar en el .conf
Script falla silenciosamente Comando no encontrado (logger, route, …) Añadir PATH completo
IP fija no se aplica La IP ya estaba asignada ifconfig em0 inet X delete antes
Ratón no vuelve Módulo incorrecto cargado Probar ums, uhid, usbhid
NFS colgado service nfsclient restart no remonta Añadir umount -f + mount -a

Comandos útiles de referencia

service devd restart            # recargar reglas
devd -d                         # ver eventos en directo
ifconfig em0                    # ver estado del enlace
netstat -rn                     # ver rutas
pfctl -s info                   # estado de pf
kldstat                         # módulos cargados
mount | grep nfs                # montajes NFS activos

Todo el flujo en un solo vistazo: script → regla devd → restart → log → depuración.

FreeBSD es genial!.

No hay comentarios:

Publicar un comentario