Resolución de Problemas de Arranque de Systemd: Problemas Comunes y Soluciones

Diagnostique problemas de arranque de systemd con journalctl, comprobaciones de unidades fallidas, objetivos de rescate, correcciones de fstab, revisión de dependencias y depuración de initramfs.

Resolución de Problemas de Arranque de Systemd: Problemas Comunes y Soluciones

Los problemas de arranque en Linux se sienten urgentes porque a menudo pierdes primero las herramientas cómodas. SSH puede estar caído, el inicio de sesión gráfico puede no aparecer nunca, y la consola puede dejarte en modo de emergencia con un mensaje que parece peor de lo que es. Con los problemas de arranque de systemd, el mejor primer movimiento no es adivinar. Encuentra el punto donde el arranque se detuvo, luego trabaja hacia atrás a través de los registros de unidades, fallos de montaje, errores de dependencia o mensajes tempranos del kernel.

Esta guía se centra en fallos que ocurren una vez que el kernel ha iniciado systemd como PID 1, más algunos problemas cercanos que parecen fallos de systemd desde la consola: entradas incorrectas en /etc/fstab, problemas con initramfs y errores del gestor de arranque.

Entendiendo el Proceso de Arranque de Systemd

Systemd gestiona el proceso de arranque de Linux a través de un sistema de "unidades". Estas unidades describen varios recursos y servicios del sistema, como servicios (.service), puntos de montaje (.mount), dispositivos (.device) y objetivos (.target). Los objetivos son unidades especiales que agrupan otras unidades y representan puntos de sincronización o estados específicos durante el proceso de arranque, como multi-user.target (el runlevel 3 tradicional) o graphical.target (runlevel 5).

El proceso de arranque típicamente incluye:

  1. Inicialización del Kernel: El kernel carga e inicializa el hardware.
  2. Etapa de Initramfs: Se carga un sistema de archivos RAM inicial, que incluye controladores y herramientas esenciales para montar el sistema de archivos raíz.
  3. Inicio de Systemd: Systemd toma el control como PID 1, iniciando el default.target (que a menudo enlaza simbólicamente a multi-user.target o graphical.target).
  4. Activación de Unidades: Systemd lee los archivos de unidad, resuelve dependencias e inicia servicios y montajes de manera altamente paralela.

Los problemas de arranque pueden ocurrir en cualquiera de estas etapas, pero esta guía se centra principalmente en problemas que se manifiestan una vez que systemd ha iniciado.

Triaje Inicial: Accediendo a los Registros de Arranque

Cuando tu sistema falla al arrancar correctamente, el primer y más crítico paso es acceder a los registros de arranque. Estos registros proporcionan pistas sobre lo que salió mal. Si tu sistema no arranca en un entorno gráfico o incluso en una TTY estándar, necesitarás usar métodos alternativos.

1. Usando journalctl (Desde Modo de Rescate/Emergencia o Medios en Vivo)

journalctl es la utilidad para consultar el diario de systemd. Si tu sistema puede arrancar en modo de rescate o modo de emergencia, o si estás usando un USB/CD en vivo para acceder a tu disco, journalctl es tu herramienta principal.

Para ver los registros del arranque anterior:

journalctl -b -1

Para ver todos los mensajes desde que el sistema arrancó:

journalctl -b

Para ver registros relacionados con unidades fallidas:

journalctl -b -p err..emerg # Muestra errores, críticos, alertas, mensajes de emergencia
journalctl -b --since "-5min" # Muestra registros de los últimos 5 minutos del arranque actual

Si estás usando un entorno en vivo, no siempre necesitas un chroot completo solo para leer registros. Monta el sistema instalado y apunta journalctl a él:

mount /dev/mapper/vg0-root /mnt
journalctl --directory=/mnt/var/log/journal -b -1

En sistemas sin diarios persistentes, los registros de arranque más antiguos pueden no existir bajo /var/log/journal. En ese caso, verifica los registros específicos de la distribución bajo /var/log, o reproduce el arranque después de habilitar el diario persistente cuando el sistema esté lo suficientemente sano para hacerlo.

2. Usando dmesg

dmesg muestra el búfer de anillo del kernel, que contiene mensajes del kernel durante el arranque. Esto es especialmente útil para problemas que ocurren muy temprano en el proceso de arranque, antes de que systemd haya tomado el control por completo.

dmesg

3. Examinando el Estado de las Unidades

Una vez en un shell utilizable (modo de rescate, modo de emergencia o entorno en vivo con chroot), puedes verificar el estado de todas las unidades de systemd.

systemctl --failed

Este comando lista todas las unidades que fallaron al iniciar. Para obtener información detallada sobre una unidad fallida específica, usa:

systemctl status <nombre_unidad>.service

Y para ver sus entradas de diario específicas:

journalctl -u <nombre_unidad>.service -b

Problemas Comunes de Arranque de Systemd y Soluciones

1. Servicios Fallidos y Fallos de Unidades

Problema: Un servicio crítico falla al iniciar, impidiendo que el sistema alcance el objetivo deseado (por ejemplo, multi-user.target). Esto a menudo se manifiesta como el sistema entrando en modo de emergencia.

Síntomas: systemctl --failed muestra una o más unidades con un estado "failed". journalctl -u <nombre_unidad>.service revela mensajes de error que indican por qué el servicio no pudo iniciar.

Causas Comunes:

  • Configuración Incorrecta: Error tipográfico en un archivo de configuración, rutas incorrectas, dependencias faltantes.
  • Archivos/Dependencias Faltantes: Un servicio intenta acceder a un archivo o directorio que no existe o es inaccesible.
  • Agotamiento de Recursos: El servicio intenta asignar demasiada memoria u otros recursos.
  • Problemas de Permisos: El servicio no tiene los permisos necesarios para leer/escribir archivos o ejecutar comandos.

Soluciones:

  1. Identifica la Unidad Fallida: Usa systemctl --failed.
  2. Inspecciona los Registros: Ejecuta journalctl -u <nombre_unidad>.service -b para mensajes de error detallados.
  3. Corrige la Configuración: Edita el archivo de configuración del servicio (por ejemplo, /etc/systemd/system/<nombre_unidad>.service o archivos en /etc/). Presta atención a las directivas ExecStart, WorkingDirectory, User, Group, Environment.
  4. Verifica las Dependencias: Asegúrate de que todas las directivas Wants=, Requires=, After=, Before= estén especificadas correctamente y que los servicios requeridos estén habilitados.
  5. Reinicia y Rehabilita: Después de hacer cambios, ejecuta systemctl daemon-reload, luego intenta systemctl start <nombre_unidad>.service y systemctl enable <nombre_unidad>.service.

Ejemplo: Un servicio web personalizado mywebapp.service falla porque su base de datos no está disponible.

# Verificar estado
systemctl status mywebapp.service

# Verificar registros en busca de pistas
journalctl -u mywebapp.service -b

# Editar archivo de unidad (por ejemplo, en /etc/systemd/system/mywebapp.service)
# Agregar/modificar la directiva After= para asegurar que la base de datos se inicie primero
# por ejemplo, After=postgresql.service mysql.service

# Recargar systemd e intentar de nuevo
systemctl daemon-reload
systemctl start mywebapp.service
systemctl enable mywebapp.service # Asegurar que se inicie en el próximo arranque

2. Problemas del Sistema de Archivos

Problema: Sistemas de archivos corruptos o entradas incorrectas en /etc/fstab pueden impedir que el sistema monte particiones críticas, llevando al modo de emergencia.

Síntomas: Mensajes de error sobre fallos de fsck, errores de mount, o el sistema entrando en modo de emergencia con un mensaje como "Give root password for maintenance (or type Control-D to continue)".

Causas Comunes:

  • Sistema de Archivos Sucio: Apagado inadecuado, pérdida de energía.
  • /etc/fstab Incorrecto: Error tipográfico en UUID/ruta de dispositivo, tipo de sistema de archivos incorrecto, falta noauto para montajes no críticos.
  • Fallo de Hardware: Corrupción del disco.

Soluciones:

  1. Accede al Modo de Emergencia: Si se solicita, ingresa la contraseña de root.
  2. Verifica /etc/fstab: Revisa cuidadosamente /etc/fstab en busca de errores. Comenta líneas sospechosas con # temporalmente.
  3. Ejecuta fsck con cuidado: Verifica y repara manualmente los sistemas de archivos solo cuando estén desmontados, o montados como solo lectura en un contexto de mantenimiento donde tu distribución lo documente como seguro. Para una partición que no sea raíz:
    umount /dev/sdb1
    fsck -f /dev/sdb1
    
    Si el sistema de archivos raíz necesita reparación, arranca desde medios en vivo o un entorno de rescate y ejecuta fsck desde allí. Evita fsck -y como primer movimiento en discos importantes; revisa las indicaciones a menos que ya tengas una copia de seguridad o entiendas el daño.
  4. Reinicia: Después de hacer cambios o ejecutar fsck, intenta reiniciar.

3. Conflictos de Dependencia y Orden de Unidades

Problema: Los servicios se inician en el orden incorrecto, o las unidades tienen dependencias conflictivas, lo que lleva a interbloqueos o fallos.

Síntomas: Servicios que se agotan, servicios que fallan porque sus dependencias no están listas, systemd-analyze plot mostrando cadenas largas o ciclos.

Causas Comunes:

  • Directivas Wants=, Requires=, After=, Before= mal configuradas en archivos de unidad.
  • Unidades que esperan recursos que aún no están disponibles.

Soluciones:

  1. Analiza la Secuencia de Arranque: Usa systemd-analyze para visualizar el proceso de arranque.

    • systemd-analyze blame: Muestra los servicios ordenados por su tiempo de inicio, destacando unidades lentas.
    • systemd-analyze critical-chain: Muestra la ruta crítica de unidades que impactan directamente el tiempo total de arranque.
    • systemd-analyze plot > boot.svg: Genera una imagen SVG de todo el gráfico de dependencias de arranque, invaluable para problemas complejos.
  2. Inspecciona las Dependencias de la Unidad: Usa systemctl list-dependencies <nombre_unidad> para ver qué requiere una unidad y qué depende de ella.

  3. Ajusta las Directivas del Archivo de Unidad:

    • After=, Before=: Controlan el orden de las unidades. Si A.service tiene After=B.service, A se iniciará después de B (si B se inicia en absoluto). Usa After= para la mayoría de las necesidades de orden.
    • Wants=: Expresa una dependencia débil. Si A.service Wants=B.service, B se iniciará cuando A se inicie, pero A continuará incluso si B falla.
    • Requires=: Expresa una dependencia fuerte. Si A.service Requires=B.service, B se incluye cuando A se inicia, y A falla si B no puede iniciarse. Si B se detiene explícitamente, A también se detiene.
    • Conflicts=: Asegura que una unidad específica se detenga si la unidad actual se inicia, y viceversa.
    • PartOf=: Vincula el ciclo de vida de una unidad a otra (por ejemplo, si un slice se detiene, todas las unidades PartOf también se detienen).

    Consejo: Siempre prefiere After= y Wants= para la mayoría de las dependencias para evitar crear un acoplamiento fuerte que podría llevar a interbloqueos o cascadas de fallos.

4. Pánicos del Kernel / Problemas de Initramfs

Problema: El sistema falla al arrancar muy temprano, a menudo antes de que systemd tome el control por completo, mostrando mensajes como "Kernel panic - not syncing" o relacionados con dracut o initramfs.

Síntomas: Falla de arranque temprana, a menudo con un muro de texto mostrando trazas de pila o mensajes sobre dispositivo raíz faltante, /dev/root no encontrado, etc.

Causas Comunes:

  • Módulos del Kernel Faltantes: Initramfs no contiene los controladores necesarios para el sistema de archivos raíz (por ejemplo, LVM, RAID, controladores de disco específicos).
  • Kernel/Initramfs Corrupto: Los archivos están dañados.
  • Parámetros del Kernel Incorrectos: El parámetro root= en GRUB apunta al dispositivo incorrecto.

Soluciones:

  1. Reconstruye Initramfs: Esta es una solución común. Arranca en un entorno en vivo o con otro kernel, haz chroot a tu sistema y reconstruye el initramfs.
    # Ejemplo para Dracut (Fedora/RHEL/CentOS)
    dracut -f -v /boot/initramfs-$(uname -r).img $(uname -r)
    
    # Ejemplo para mkinitcpio (Arch Linux)
    mkinitcpio -P
    
    # Ejemplo para update-initramfs (Debian/Ubuntu)
    update-initramfs -u -k all
    
  2. Verifica la Configuración de GRUB: Revisa /boot/grub/grub.cfg (o /etc/default/grub si lo regeneras) para el parámetro root= correcto y la ruta initrd.
  3. Parámetros del Kernel: Si sospechas que un módulo específico falta o causa problemas, puedes intentar agregar parámetros del kernel en GRUB (por ejemplo, rd.break para entrar en el shell de initramfs para depuración).

5. Problemas de GRUB/Gestor de Arranque

Problema: El sistema ni siquiera llega al punto donde el kernel se carga, o se queda atascado en el menú de GRUB.

Síntomas: "No boot device found", indicador de rescate de GRUB, o GRUB falla al cargar el kernel.

Causas Comunes:

  • Gestor de arranque corrupto.
  • Configuración incorrecta de GRUB que apunta a un kernel/initramfs inexistente.
  • Configuración de BIOS/UEFI que impide el orden de arranque correcto.

Soluciones:

  1. Reinstala GRUB: Arranca desde un USB en vivo, haz chroot a tu sistema y reinstala GRUB en el MBR/partición EFI.
    # Ejemplo
    mount /dev/sdaX /mnt # Montar partición raíz
    
    mount /dev/sdaY /mnt/boot/efi # Si es una partición EFI separada
    
    for i in /dev /dev/pts /proc /sys /run; do mount --bind $i /mnt$i; done
    chroot /mnt
    
    grub-install /dev/sda # Instalar en el disco principal
    
    grub-mkconfig -o /boot/grub/grub.cfg # Regenerar configuración de GRUB
    
    exit
    umount -R /mnt
    reboot
    
  2. Verifica la Configuración de BIOS/UEFI: Asegúrate de que la unidad de arranque correcta esté priorizada.

Técnicas Avanzadas de Solución de Problemas

Arrancar en Modo de Rescate/Emergencia

Estos modos proporcionan un entorno mínimo para solucionar problemas. Para ingresar a ellos:

  1. Durante GRUB: Presiona e para editar la línea de comandos del kernel.
  2. Localiza la línea linux: Encuentra la línea que comienza con linux (o linuxefi).
  3. Agrega systemd.unit=rescue.target para el modo de rescate (la mayoría de los servicios están apagados, shell de un solo usuario).
  4. Agrega systemd.unit=emergency.target para el modo de emergencia (servicios mínimos, raíz a menudo de solo lectura).
  5. Presiona Ctrl+X o F10 para arrancar.

Usando rd.break para Depuración de Initramfs

Agregar rd.break a la línea de comandos del kernel en GRUB te llevará a un shell dentro del initramfs antes de que se monte el sistema de archivos raíz real. Esto es extremadamente útil para depurar problemas de initramfs, como controladores faltantes o problemas con la configuración de LVM/RAID.

Una vez en el shell de initramfs, puedes:

  • Inspeccionar lsblk, mount.
  • Verificar archivos faltantes en /sysroot.
  • Intentar montar manualmente el sistema de archivos raíz.

Analizando el Rendimiento del Arranque

Aunque no es estrictamente un "fallo", los tiempos de arranque lentos pueden indicar problemas subyacentes o configuraciones de servicio ineficientes.

  • systemd-analyze blame: Identifica los servicios que tardan más en iniciarse.
  • systemd-analyze critical-chain: Comprende la ruta crítica de dependencias que impactan el tiempo total de arranque.

Una Secuencia de Recuperación Segura

Cuando estás en la consola y la máquina está medio arrancada, mantén la secuencia de recuperación aburrida:

  1. Captura el error exacto en la pantalla si puedes.
  2. Ejecuta systemctl --failed.
  3. Lee journalctl -b -p err..alert --no-pager.
  4. Si una unidad falló, lee journalctl -u nombre-unidad -b.
  5. Si un montaje falló, inspecciona /etc/fstab, verifica los UUIDs con blkid, y comenta solo el montaje no crítico sospechoso.
  6. Si el sistema de archivos raíz o initramfs está involucrado, cambia a medios en vivo o modo de rescate antes de hacer reparaciones invasivas.
  7. Después de editar archivos de unidad, ejecuta systemctl daemon-reload y reinicia solo la unidad afectada cuando sea posible.

La mayoría de los problemas de arranque de systemd no se solucionan cambiando muchas cosas a la vez. Una línea de montaje incorrecta, un disco faltante, un servicio con un ExecStart= roto o un error de orden dejan un rastro bastante directo. Sigue ese rastro, haz una pequeña reparación y reinicia solo cuando el shell actual no pueda probar la solución.

Usa estas herramientas para identificar cuellos de botella y optimizar el inicio de unidades ajustando las directivas After=, Requires=, TimeoutStartSec= o Type=.

Prevención y Mejores Prácticas

  • Prueba los Cambios: Antes de implementar modificaciones en archivos de unidad en producción, pruébalos en un entorno de prueba.
  • Respaldar la Configuración: Realiza copias de seguridad regulares de /etc/ o al menos de los archivos críticos de /etc/systemd/system/.
  • Comprende las Directivas de Unidad: Una comprensión sólida de las páginas de manual systemd.service(5) y systemd.unit(5) es invaluable.
  • Usa Archivos Drop-in: En lugar de modificar directamente los archivos de unidad de /lib/systemd/system/ (que pueden sobrescribirse con actualizaciones), usa archivos drop-in (/etc/systemd/system/<nombre_unidad>.service.d/*.conf) para configuraciones personalizadas.
  • Mantén Kernels: Siempre mantén al menos un kernel antiguo conocido como bueno en tu sistema para arrancar si un nuevo kernel causa problemas.

Conclusión

Resolver problemas de arranque de systemd requiere un enfoque sistemático, comenzando con un análisis efectivo de registros. Al comprender la arquitectura basada en unidades de systemd y aprovechar herramientas como journalctl, systemctl y systemd-analyze, puedes identificar eficientemente la causa raíz de los fallos de arranque, ya sea un servicio mal configurado, un problema del sistema de archivos o un conflicto de dependencia complejo. La capacidad de arrancar en modos de rescate o emergencia, junto con técnicas avanzadas de depuración, te permite recuperar el control de tu sistema incluso cuando parece completamente sin respuesta. Con estas estrategias y mejores prácticas, estarás bien equipado para enfrentar la mayoría de los desafíos de arranque de systemd y mantener operaciones Linux estables y confiables.