Falha durante a inicialização em um computador corporativo recente

63

Após algumas atualizações recentes, meu computador não inicializa mais! Veja o que eu poderia determinar:

  • Este é um computador muito recente que me foi fornecido pela TI corporativa. Tem uma recente CPU Intel (geração Skylake).
  • O computador roda o Ubuntu 16.04.
  • O último computador foi inicializado corretamente em março. O problema é presumivelmente devido a uma atualização de software ou a um bug de hardware.
  • Eu tenho outro computador rodando 16.04 com praticamente o mesmo software instalado (usei apt-clone ), e funciona muito bem. Tem hardware diferente (também amd64, mas CPU diferente, GPU diferente, etc.).
  • O kernel inicia, o initrd funciona corretamente. Quando inicializo com uma tela inicial no modo gráfico, recebo a senha do meu volume dm-crypt e a última coisa que vejo é que ele é montado com sucesso.
  • O bloqueio ocorre antes de eu receber um prompt de login. Quando o computador trava, é um problema difícil. Mesmo Alt + SysRq não responde. A CPU está evidentemente marcada em 100% desde que os fãs ligam a todo vapor.
  • Ainda tenho o kernel em execução antes de reinicializar. Quando eu seleciono este kernel no menu do Grub, recebo o mesmo bloqueio. Então parece que esse é um bug do kernel preexistente que é acionado por outra coisa - mas o que?
  • Se eu desligar a tela inicial (remover splash da linha de comando linux no Grub), vejo vários serviços sendo iniciados e, em seguida, eles são bloqueados.
  • Eu posso obter um shell de root adicionando init=/bin/sh à linha de comando linux no Grub. Eu posso até mesmo continuar adicionando

    systemd.unit=basic.target systemd.shell
    

    Isso inicia um número de serviços e executa um shell de root no tty9.

  • Se eu executar systemctl start multi-user.target desse shell de raiz, o computador será bloqueado. Então, presumivelmente, o problema é desencadeado por um desses serviços.
  • Eu corri systemctl list-dependencies multi-user.target para ver quais serviços são iniciados. Eu iniciei manualmente as dependências listadas, uma a uma, e tudo começou bem.

Então, isso parece um bug de hardware (já que ocorre em um computador, mas não no outro) que é acionado por algum software. Mas qual software? Como o computador bloqueia muito, não consigo obter nenhum registro. Eu não posso nem obter qualquer saída de console útil.

Técnicas de depuração úteis:

  • Alt + SysRq : chave mágica do SysRq , que permite fazer coisas como uma reinicialização de emergência. Ele acessa o kernel em um nível muito baixo, então funciona em todos, menos nas piores falhas. No meu caso, o Alt + SysRq não responde, o que mostra a profundidade do travamento.
  • Para modificar os parâmetros de inicialização, pressione e segure Shift alguns segundos depois de ligar a energia. Você precisa pressioná-lo após o BIOS ter inicializado o teclado, mas antes do sistema operacional inicializar. Isso faz com que o menu Grub apareça.
  • No menu Grub, pressione e para editar a linha de comando de uma entrada de menu. Para alterar os parâmetros de inicialização do Linux, navegue até a linha que começa com linux . Em um Ubuntu moderno, você encontrará kernels antigos em "Opções avançadas para o Ubuntu". Depois de fazer as alterações desejadas na linha de comando, pressione Ctrl + x para inicializar. Qualquer alteração feita aqui é somente para essa inicialização, eles não são salvos no disco.
  • Algumas opções úteis na linha de comando linux :
    • quiet nosplash oculta quase todas as mensagens de inicialização. Remova-os para receber mensagens no console durante a inicialização, o que é necessário para ter alguma chance de diagnosticar problemas.
    • recovery fornece um shell de root com quase nenhum serviço. Você precisará saber a senha do root. A entrada do menu “modo de recuperação” usa isso.
    • init=/bin/sh fornece um shell root sem nenhum serviço. Para retomar a inicialização normal, execute exec init . Você pode passar opções de systemd neste momento, por exemplo exec init --unit=basic.target para iniciar o init e alguns serviços (note que isso não inicia nenhuma maneira de logar, então é melhor você ter um shell rodando em outro console). Observe que o sistema de arquivos raiz é montado somente leitura; execute mount -o remount,rw / para poder gravar nele.
    • systemd.unit=basic.target inicia um conjunto muito básico de serviços. Observe que isso não inclui nenhuma maneira de efetuar login! Você pode tornar isso padrão executando systemctl set-default basic.target em um prompt raiz. Para restaurar o destino padrão original, execute systemctl set-default graphical.target (ou systemctl set-default multi-user.target para um servidor sem GUI).
    • systemd.debug-shell inicia um shell de root no tty9. Você pode habilitar isso para cada inicialização executando systemctl enable debug-shell em um prompt de root. Não esqueça de desabilitar isso depois de ter resolvido o problema com systemctl disable debug-shell . Pressione Alt + F9 para mudar para tty9.
    • Veja também dicas do Fedora systemd , Dicas para problemas de inicialização do Arch Linux .
por Gilles 09.04.2018 / 01:17

1 resposta

71

O problema

Acontece que o meu problema é um problema conhecido entre o mais recente microcódigo da Intel (alguns?) CPUs Skylake e kernels recentes do Linux, que é principalmente desencadeada por sssd . Veja bug do Ubuntu # 1759920 “intel-microcode 3.20180312.0 provoca bloqueio na tela de login (w / linux-image-4.13.0-37-generic) ”, e também uma série de outros bugs que acabam se tornando o mesmo problema, como bug do Ubuntu # 1746806" o sssd parece travar as instâncias AWS c5 e m5, causando 100% de CPU " e Bug do Ubuntu # 1746418" O sistema congela ao iniciar o Xorg após a instalação do linux-image-4.13.0-32-generic ". É provável que você encontre esse bug se:

  • Você tem um CPU Intel muito recente. Tanto quanto eu posso dizer, este bug só surge em CPUs Skylake .
  • Você tem o pacote intel-microcode instalado. A reversão para um kernel testado anteriormente não funcionou para mim porque eu só executaria esse kernel com um microcódigo anterior.
  • Seu computador está conectado a uma rede corporativa (geralmente LDAP ou Active Directory) para autenticação do usuário. Embora existam outras maneiras de desencadear o bug, executar sssd parece ser o culpado mais comum. Também há relatos de travamento do Xorg .

O bug é devido a atenuações para o problema de segurança Spectre que foi publicado em janeiro de 2018. Há uma incompatibilidade entre algum código do kernel e algum microcódigo do processador que causa um travamento em certas circunstâncias.

Como reparar

  1. Se você não conseguir inicializar normalmente, precisará editar a linha de comando do kernel no prompt do Grub. Veja a pergunta para explicações e possíveis maneiras de obter um shell de root.
  2. Uma solução para esse bug específico é adicionar o parâmetro noibpb à linha de comando do kernel ( 1746418/14 , 1759920/56 ). Isso deve permitir que você inicialize normalmente e realize alguns reparos.
    Isso desativa a atenuação de vulnerabilidades que causa o problema, o que significa que seu computador agora está vulnerável a alguns ataques. Eles são ataques locais, ou seja, o invasor precisa executar o código em sua máquina, mas esses ataques podem ser realizados, e. através de JavaScript em um navegador da Web.
    Se você não tem outro jeito, você pode tornar isso permanente adicionando noibpb à linha de comando do kernel até que você possa obter um kernel fixo.
  3. No Ubuntu, espera-se que a correção na semana de 23 de abril 2018 , no que presumivelmente será o kernel 4.4.0-117 e 4.13.0-39. Enquanto isso, o Tyler Hicks publicou kernels de teste para < href="https://people.canonical.com/~tyhicks/lp1759920/xenial/"> 4.4 e 4.13 .

Como diagnostiquei o problema

Eu tentei várias coisas (veja a pergunta) e determinei que o bug foi acionado em algum lugar entre alcançar basic.target e alcançar multi-user.target . Então, configurei o destino systemd padrão como basic.target ( systemctl set-default basic.target ) e ativei o debug-shell service ( systemctl enable debug-shell ) para obter um shell raiz.

Eu corri systemctl list-dependencies multi-user.target e iniciei manualmente as dependências listadas uma a uma. Isso não acionou o acidente.

Nem todos os serviços são gerenciados diretamente por systemd . Alguns são gerenciados como serviços Upstart e alguns são gerenciados como SysVinit . O script de shell abaixo executa todos eles. Nota: Eu só testei uma vez, e caiu por design.

#!/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

Meu computador travou depois de iniciar sssd . A partir daí, uma pesquisa na web sobre “sssd linux kernel hang” levou-me ao link e ao diagnóstico e solução.

    
por 09.04.2018 / 01:17