Bloqueo durante el inicio en una computadora corporativa reciente

63

Después de algunas actualizaciones recientes, ¡mi computadora ya no arranca! Esto es lo que podría determinar:

  • Esta es una computadora muy reciente que me fue proporcionada por TI corporativa. Tiene una CPU Intel reciente (generación Skylake).
  • La computadora ejecuta Ubuntu 16.04.
  • La computadora se inició correctamente por última vez en marzo. El problema probablemente se deba a una actualización de software o un error de hardware.
  • Tengo otra computadora con 16.04 con casi el mismo software instalado (que usé apt-clone), y funciona bien. Tiene hardware diferente (también amd64, pero CPU diferente, GPU diferente, etc.).
  • El núcleo se inicia, el initrd funciona correctamente. Cuando inicio con una pantalla de presentación en modo gráfico, se me solicita la contraseña para mi volumen dm-crypt, y lo último que veo es que se ha montado correctamente.
  • El bloqueo se produce antes de recibir un mensaje de inicio de sesión. Cuando la computadora se cuelga, es difícil. Incluso Alt+ SysRqno responde. La CPU está evidentemente vinculada al 100% ya que los ventiladores se encienden a toda potencia.
  • Todavía tengo el kernel que estaba ejecutando antes de reiniciar. Cuando selecciono este kernel en el menú Grub, obtengo el mismo bloqueo. Parece que este es un error del kernel preexistente que se activa por otra cosa, pero ¿qué?
  • Si apago la pantalla de inicio (eliminar splashde la linuxlínea de comando en Grub), veo que se inician varios servicios y luego se bloquea.
  • Puedo obtener un shell raíz agregando init=/bin/sha la linuxlínea de comando en Grub. Incluso puedo llegar más lejos agregando

    systemd.unit=basic.target systemd.shell
    

    Esto inicia una serie de servicios y ejecuta un shell raíz en tty9.

  • Si corro systemctl start multi-user.targetdesde ese shell raíz, la computadora se bloquea. Entonces, presumiblemente, el problema se desencadena por uno de estos servicios.
  • Corrí systemctl list-dependencies multi-user.targetpara ver qué servicios empezar. Inicié manualmente las dependencias enumeradas una por una, y todo comenzó bien.

Así que esto parece un error de hardware (ya que ocurre en una computadora pero no en la otra) que se activa por algún software. ¿Pero qué software? Como la computadora se bloquea tan fuerte, no puedo obtener ningún registro. Ni siquiera puedo obtener ninguna salida de consola útil.


Técnicas de depuración útiles:

  • Alt+ SysRq: tecla mágica SysRq , que te permite hacer cosas como un reinicio de emergencia. Accede al kernel a un nivel muy bajo, por lo que funciona en todos los accidentes, excepto en los peores. En mi caso, Alt+ SysRqno responde, lo que muestra qué tan profundo es el choque.
  • Para modificar los parámetros de arranque, presione y mantenga presionados Shiftunos segundos después de encenderlo. Debe presionarlo después de que el BIOS haya inicializado el teclado, pero antes de que se inicie el sistema operativo. Esto hace que aparezca el menú Grub .
  • En el menú Grub, presione epara editar la línea de comando para una entrada de menú. Para cambiar los parámetros de arranque de Linux, navegue hasta la línea que comienza con linux. En un Ubuntu moderno, encontrará núcleos antiguos en "Opciones avanzadas para Ubuntu". Una vez que haya realizado los cambios deseados en la línea de comando, presione Ctrl+ xpara iniciar. Cualquier cambio que realice aquí es solo para este arranque, no se guardan en el disco.
  • Algunas opciones útiles en la linuxlínea de comando:
    • quiet nosplashoculta casi todos los mensajes de arranque. Elimínelos para obtener mensajes en la consola durante el arranque, lo cual es necesario para tener alguna posibilidad de diagnosticar problemas.
    • recoveryle ofrece un shell de raíz casi sin servicios. Necesitará saber la contraseña de root. La entrada del menú "modo de recuperación" usa esto.
    • init=/bin/shle ofrece un shell raíz sin ningún tipo de servicio. Para reanudar el arranque normal, ejecute exec init. Puede pasar las opciones de systemd en este punto, por ejemplo, exec init --unit=basic.targetpara iniciar init y algunos servicios (tenga en cuenta que esto no inicia ninguna forma de iniciar sesión, por lo que será mejor que tenga un shell ejecutándose en otra consola). Tenga en cuenta que el sistema de archivos raíz está montado de solo lectura; corre mount -o remount,rw /para poder escribirle.
    • systemd.unit=basic.targetinicia un conjunto muy básico de servicios. ¡Tenga en cuenta que esto no incluye ninguna forma de iniciar sesión! Puede hacer que esto sea el predeterminado ejecutando systemctl set-default basic.targeten un indicador raíz. Para restaurar el objetivo predeterminado original, ejecute systemctl set-default graphical.target(o systemctl set-default multi-user.targetpara un servidor sin GUI).
    • systemd.debug-shellinicia un shell de raíz en tty9. Puede habilitar esto para cada arranque ejecutando systemctl enable debug-shellen un indicador raíz. No olvide deshabilitar esto después de que haya resuelto el problema systemctl disable debug-shell. Presione Alt+ F9para cambiar a tty9.
    • Véanse también las sugerencias systemd de Fedora , las sugerencias de problemas de arranque de Arch Linux .
Gilles 'SO- deja de ser malvado'
fuente

Respuestas:

71

El problema

Resulta que mi problema es un problema conocido entre el último microcódigo de Intel en las CPU Skylake (¿algunas?) Y los núcleos Linux recientes, que se activa principalmente por sssd . Consulte el error de Ubuntu # 1759920 "intel-microcode 3.20180312.0 causa el bloqueo en la pantalla de inicio de sesión (w / linux-image-4.13.0-37-generic)" , y también una serie de otros errores que resultan ser sobre el mismo problema , como el error de Ubuntu # 1746806 "sssd parece bloquear las instancias de AWS c5 y m5, causa el 100% de CPU" y el error de Ubuntu # 1746418 "El sistema se congela al iniciar Xorg después de instalar linux-image-4.13.0-32-generic" . Es probable que encuentre este error si:

  • Tienes una CPU Intel muy reciente. Por lo que puedo decir, este error solo surge en las CPU Skylake .
  • Tiene instalado el paquete intel-microcode . Volver a un kernel probado anteriormente no funcionó para mí porque solo había ejecutado ese kernel con un microcódigo anterior.
  • Su computadora está conectada a una red corporativa (generalmente LDAP o Active Directory) para la autenticación del usuario. Aunque hay otras formas de activar el error, ejecutar sssd parece ser el culpable más común. También hay informes de la caída de Xorg .

El error se debe a mitigaciones para el problema de seguridad de Spectre que se publicó en enero de 2018. Existe una incompatibilidad entre el código del kernel y el microcódigo del procesador que causa un bloqueo en ciertas circunstancias.

Como reparar

  1. Si no puede arrancar normalmente, deberá editar la línea de comando del núcleo en el indicador de Grub. Consulte la pregunta para obtener explicaciones y posibles formas de obtener un shell raíz.
  2. Una solución para este error específico es agregar el noibpbparámetro a la línea de comando del núcleo ( 1746418/14 , 1759920/56 ). Esto debería permitirle arrancar normalmente y realizar algunas reparaciones.
    Esto deshabilita la mitigación de la vulnerabilidad que causa el problema, lo que significa que su computadora ahora es vulnerable a algunos ataques. Son ataques locales, es decir, el atacante necesita ejecutar código en su máquina, pero estos ataques pueden llevarse a cabo, por ejemplo, a través de JavaScript en un navegador web.
    Si no tiene otra forma, puede hacer esto permanente agregando noibpba la línea de comando del núcleo hasta que pueda obtener un núcleo fijo.
  3. En Ubuntu, la solución se espera para la semana del 23 de abril de 2018 , en lo que presumiblemente será el kernel 4.4.0-117 y 4.13.0-39. Mientras tanto, Tyler Hicks ha publicado núcleos de prueba para 4.4 y 4.13 .

Cómo diagnostiqué el problema

Intenté varias cosas (vea la pregunta) y determiné que el error se activó en algún lugar entre alcanzar basic.targety alcanzar multi-user.target. Así que configuré el objetivo predeterminado de systemd en basic.target( systemctl set-default basic.target) y habilité el debug-shellservicio ( systemctl enable debug-shell) para obtener un shell raíz.

Ejecuté systemctl list-dependencies multi-user.targety comencé manualmente las dependencias enumeradas una por una. Esto no desencadenó el accidente.

No todos los servicios son administrados directamente por systemd . Algunos se administran como servicios Upstart y otros se administran como scripts SysVinit . El script de shell a continuación los ejecuta a todos. Nota: solo lo probé una vez y se bloqueó por diseño.

#!/bin/sh
wants=$(systemctl show -p Wants multi-user.target | sed 's/^Wants=//' | tr ' ' '\n' | sort)
log=/var/tmp/multi-user-steps-$(date +%Y%m%d-%H%M%S)

log () {
  echo "$* ..." | tee -a "$log"
  sync
  "$@"
  ret=$?
  echo "$* -> $ret" | tee -a "$log"
  sync
  return $ret
}

# systemd services
for service in $wants; do
  log systemctl start $service
  sleep 2
done

# upstart services
for conf in /etc/init/*.conf; do
  service=${conf##*/}; service=${service%.conf}
  log service ${service} start
  sleep 2
done

# sysvinit services
for service in /etc/rc3.d/S*; do
  log ${service} start
  sleep 2
done

Mi computadora se bloqueó después de comenzar sssd. A partir de ahí, una búsqueda web en "sssd linux kernel hang" me llevó a https://bugs.launchpad.net/cloud-images/+bug/1746806 y al diagnóstico y la solución.

Gilles 'SO- deja de ser malvado'
fuente
Me encontré con este también. Eliminé el paquete intel-microcode y lo incluí en la lista negra para evitar que se vuelva a instalar. El microcódigo que causa los problemas no se agrega permanentemente a la CPU. Se vuelve a cargar cada vez. Por lo tanto, no cargarlo también actuará como una solución alternativa. El noipbp no es necesario en ese caso y aún obtendrá las mitigaciones. En mi caso, es una necesidad, ya que este sistema se enfrenta directamente a Internet sin la protección adicional de los servidores proxy corporativos.
Tonny
3
@Tonny El microcódigo corrige otros errores, como este , así como problemas que Intel no revela. Si bien es una solución, no estoy seguro de no aplicar actualizaciones de microcódigo, excepto que el espectro / Meltdown parece haber sido eliminado un poco. Lo propongo noipbpprincipalmente como una forma de iniciar el sistema afectado. Creo que la mejor solución aquí es actualizar el kernel.
Gilles 'SO- deja de ser malvado'
Lo sé y estoy de acuerdo. Pero los nuevos núcleos aún no están aquí y, por el momento, prefiero un sistema que funcione con la mayoría de las mitigaciones (excepto el microcódigo) a un sistema con microcódigo, pero sin mitigaciones de software (que cubren más que el microcódigo). Con respecto a las actualizaciones de microcódigo: para estos nuevos Skylakes parece que las correcciones de Spectre / Meltdown son las únicas actualizaciones de microcódigo hasta ahora, por lo que no parece que nos perdamos mucho sin ellas. Para las CPU más antiguas es otra cuestión. Hay muchas erratas de CPU arregladas con actualizaciones de microcódigo. Y realmente sería reacio a ir sin esos.
Tonny