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

63

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

  • Este é um computador muito recente que me foi fornecido pela TI corporativa. Possui um CPU Intel recente (geração Skylake).
  • O computador executa o Ubuntu 16.04.
  • O computador foi inicializado corretamente pela última vez em março. O problema provavelmente se deve a uma atualização de software ou a um erro de hardware.
  • Eu tenho outro computador executando o 16.04 com praticamente o mesmo software instalado (eu usei apt-clone) e funciona muito bem. Possui 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, a senha do meu volume dm-crypt é solicitada e a última coisa que vejo é que ele foi montado com sucesso.
  • O travamento ocorre antes que eu receba um prompt de logon. Quando o computador trava, é difícil. Mesmo Alt+ SysRqnão responde. A CPU está evidentemente fixada em 100%, já que os ventiladores são ativados a todo vapor.
  • Eu ainda tenho o kernel que estava executando antes de reiniciar. Quando seleciono este kernel no menu Grub, recebo o mesmo bloqueio. Portanto, parece que este é um bug do kernel pré-existente que é acionado por outra coisa - mas o que?
  • Se eu desligar a tela inicial (remover splashda linuxlinha de comando no Grub), vejo vários serviços sendo iniciados, e ela trava.
  • Eu posso obter um shell raiz adicionando init=/bin/shà linuxlinha de comando no Grub. Eu posso ir mais longe adicionando

    systemd.unit=basic.target systemd.shell
    

    Isso inicia vários serviços e executa um shell raiz no tty9.

  • Se eu executar a systemctl start multi-user.targetpartir desse shell raiz, o computador trava. Portanto, presumivelmente, o problema é desencadeado por um desses serviços.
  • Corri systemctl list-dependencies multi-user.targetpara ver quais serviços são iniciados. Comecei manualmente as dependências listadas uma a uma e tudo começou bem.

Portanto, 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 trava com tanta força, não consigo obter nenhum registro. Nem consigo obter nenhuma saída útil do console.


Técnicas úteis de depuração:

  • Alt+ SysRq: tecla mágica SysRq , que permite fazer coisas como uma reinicialização de emergência. Ele acessa o kernel em um nível muito baixo, portanto funciona em todas as falhas, exceto as piores. No meu caso, o Alt+ SysRqnão responde, o que mostra a profundidade da falha.
  • Para modificar os parâmetros de inicialização, pressione e segure Shiftalguns segundos após ligar a energia. Você precisa pressioná-lo depois que o BIOS inicializar o teclado, mas antes que o sistema operacional seja inicializado. Isso faz o menu Grub aparecer.
  • No menu Grub, pressione epara editar a linha de comando para 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+ xpara inicializar. Qualquer alteração feita aqui é apenas para esta inicialização, não é salva no disco.
  • Algumas opções úteis na linuxlinha de comando:
    • quiet nosplashoculta quase todas as mensagens de inicialização. Remova-os para obter mensagens no console durante a inicialização, o que é necessário para ter alguma chance de diagnosticar problemas.
    • recoveryfornece um shell raiz com quase nenhum serviço. Você precisará saber a senha root. A entrada do menu "modo de recuperação" usa isso.
    • init=/bin/shfornece um shell raiz sem serviços. Para retomar a inicialização normal, execute exec init. Você pode passar as opções systemd neste momento, por exemplo, exec init --unit=basic.targetpara iniciar o init e alguns serviços (observe que isso não inicia nenhuma maneira de efetuar login, portanto é melhor ter um shell em execução em outro console). Observe que o sistema de arquivos raiz é montado como somente leitura; executar mount -o remount,rw /para poder escrever nele.
    • systemd.unit=basic.targetinicia um conjunto muito básico de serviços. Observe que isso não inclui nenhuma maneira de fazer login! Você pode tornar isso o padrão executando systemctl set-default basic.targetem um prompt raiz. Para restaurar o destino padrão original, execute systemctl set-default graphical.target(ou systemctl set-default multi-user.targetpara um servidor sem GUI).
    • systemd.debug-shellinicia um shell raiz no tty9. Você pode habilitar isso para cada inicialização executando systemctl enable debug-shellem um prompt raiz. Não se esqueça de desativar isso depois de resolver o problema systemctl disable debug-shell. Pressione Alt+ F9para alternar para tty9.
    • Veja também dicas do sistema Fedora , dicas sobre problemas de inicialização do Arch Linux .
Gilles 'SO- parar de ser mau'
fonte

Respostas:

71

O problema

Acontece que meu problema é um problema conhecido entre o mais recente microcódigo da Intel em (alguns?) CPUs Skylake e os kernels recentes do Linux, que são principalmente acionados pelo sssd . Veja o bug do Ubuntu # 1759920 “intel-microcode 3.20180312.0 causa travamento na tela de login (w / linux-image-4.13.0-37-generic)” e também vários outros erros que acabam sendo o mesmo problema , como o bug do Ubuntu # 1746806 “o sssd parece travar as instâncias do AWS c5 e m5, causa 100% de CPU” e o 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. Até onde eu sei, esse bug surge apenas nas 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ó executava esse kernel com um microcódigo anterior.
  • Seu computador está conectado a uma rede corporativa (normalmente LDAP ou Active Directory) para autenticação do usuário. Embora existam outras maneiras de acionar o bug, a execução do sssd parece ser o culpado mais comum. Há também relatos de falhas no Xorg .

O bug se deve a atenuações do problema de segurança Spectre, publicado em janeiro de 2018. Há uma incompatibilidade entre algum código do kernel e algum microcódigo do processador que causa um bloqueio em determinadas 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 raiz.
  2. Uma solução alternativa para esse bug específico é adicionar o noibpbparâmetro à linha de comando do kernel ( 1746418/14 , 1759920/56 ). Isso deve permitir que você inicialize normalmente e faça alguns reparos.
    Isso desativa a atenuação da vulnerabilidade que causa o problema, o que significa que seu computador agora está vulnerável a alguns ataques. São ataques locais, ou seja, o invasor precisa executar o código em sua máquina, mas esses ataques podem ser realizados, por exemplo, por meio de JavaScript em um navegador da web.
    Se você não tem outra maneira, você pode tornar isso permanente adicionando noibpbà linha de comando do kernel até conseguir um kernel fixo.
  3. No Ubuntu, a correção é esperada na semana de 23 de abril de 2018 , no que presumivelmente será o kernel 4.4.0-117 e 4.13.0-39. Enquanto isso, Tyler Hicks publicou kernels de teste para 4.4 e 4.13 .

Como diagnosticei o problema

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

Eu executei systemctl list-dependencies multi-user.targete iniciei manualmente as dependências listadas uma a uma. Isso não acionou a falha.

Nem todos os serviços são gerenciados diretamente pelo systemd . Alguns são gerenciados como serviços Upstart e outros como scripts SysVinit . O script de shell abaixo executa todos eles. Nota: Eu o testei apenas uma vez e ele travou 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 após iniciar sssd. A partir daí, uma pesquisa na Web sobre "sssd linux kernel hang" me levou a https://bugs.launchpad.net/cloud-images/+bug/1746806 e ao diagnóstico e solução.

Gilles 'SO- parar de ser mau'
fonte
Eu encontrei este também. Eu removi o pacote intel-microcode e o coloquei na lista negra no apt para evitar que ele seja reinstalado. O microcódigo que causa os problemas não é adicionado permanentemente à CPU. É recarregado sempre. Portanto, não carregá-lo também funcionará como uma solução alternativa. O noipbp não é necessário nesse caso e você ainda obterá as atenuações. No meu caso, uma necessidade, pois esse sistema geralmente fica diretamente na Internet, sem a proteção adicional dos servidores proxy corporativos.
Tonny
3
@ Tonny O microcódigo corrige outros erros, como este , bem como problemas que a Intel não divulga. Embora seja de fato uma solução, não me preocupo em não aplicar atualizações de microcódigo - exceto que o Spectre / Meltdown parece ter sido um pouco acelerado. Estou propondo noipbpprincipalmente como uma maneira de inicializar o sistema afetado. Eu acho que a melhor solução aqui é atualizar o kernel.
Gilles 'SO- stop be evil'
Eu sei e concordo. Mas os novos kernels ainda não estão aqui e, por enquanto, prefiro um sistema de trabalho com a maioria das mitigações (exceto o microcódigo) a um sistema com microcódigo, mas nenhuma mitigação de software (que cobre mais do que o microcódigo). Com relação às atualizações de microcódigo: para esses novos Skylakes, parece que as correções Spectre / Meltdown são as únicas atualizações de microcódigo até agora, para que não pareçamos perder muito sem elas. Para CPUs mais antigas, é outra questão. Existem muitas erratas da CPU corrigidas com atualizações de microcódigo. E eu realmente seria relutante em ir sem isso.
Tonny