*NOTA: se o seu servidor ainda tiver problemas devido a kernels confusos e você não puder reinicializar - a solução mais simples proposta com o gnu date instalado em seu sistema é: date -s now. Isso redefinirá a variável interna "time_was_set" do kernel e corrigirá os loops futex da CPU em java e outras ferramentas de espaço do usuário. Eu tracei este comando no meu próprio sistema e confirmei que ele está fazendo o que diz na lata *
PÓS-MORTEM
Anticlímax: a única coisa que morreu foi meu link VPN (openvpn) para o cluster, então houve alguns segundos emocionantes enquanto ele era restabelecido. Tudo o resto estava bem, e a inicialização do ntp foi limpa após o segundo bissexto ter passado.
Eu escrevi minha experiência completa do dia em http://blog.fastmail.fm/2012/07/03/a-story-of-leaping-seconds/
Se você olhar para o blog de Marco em http://my.opera.com/marcomarongiu/blog/2012/06/01/an-humble-attempt-to-work-around-the-leap-second - ele tem uma solução para faseando a mudança de horário em 24 horas usando ntpd -x para evitar o salto de 1 segundo. Este é um método de mancha alternativo para executar sua própria infraestrutura ntp.
Apenas hoje, sábado 30 de junho de 2012 - começando logo após o início do dia GMT. Tivemos um punhado de servidores em diferentes datacenters, gerenciados por equipes diferentes, todos apagados - sem responder a pings, tela em branco.
Eles estão todos rodando o Debian Squeeze - com tudo, desde kernel padrão até builds 3.2.21 customizados. A maioria são blades Dell M610, mas também acabei de perder um Dell R510 e outros departamentos também perderam máquinas de outros fornecedores. Houve também um IBM x3550 mais antigo que travou e que eu pensei que poderia não estar relacionado, mas agora estou me perguntando.
A única falha da qual recebi um despejo de tela disse:
[3161000.864001] BUG: spinlock lockup on CPU#1, ntpd/3358
[3161000.864001] lock: ffff88083fc0d740, .magic: dead4ead, .owner: imapd/24737, .owner_cpu: 0
Infelizmente, todos os blades supostamente tinham o kdump configurado, mas morreram com tanta força que o kdump não foi acionado - e eles tinham o apagamento do console ativado. Eu desativei o apagamento do console agora, então dedos cruzados terei mais informações após a próxima falha.
Só quero saber se é um fio comum ou "só nós". É realmente estranho que sejam unidades diferentes em datacenters diferentes, compradas em momentos diferentes e administradas por administradores diferentes (eu corro os FastMail.FM)... e agora até hardware de fornecedores diferentes. A maioria das máquinas que travaram estavam funcionando por semanas/meses e estavam rodando kernels da série 3.1 ou 3.2.
A falha mais recente foi uma máquina que estava funcionando apenas cerca de 6 horas executando o 3.2.21.
A SOLUÇÃO
Ok pessoal, aqui está como eu trabalhei em torno disso.
- ntp desativado:
/etc/init.d/ntp stop
- criado http://linux.brong.fastmail.fm/2012-06-30/fixtime.pl (código roubado de Marco, veja as postagens do blog nos comentários)
- correu
fixtime.pl
sem um argumento para ver que havia um segundo bissexto definido - correu
fixtime.pl
com um argumento para remover o segundo bissexto
NOTA: depende de adjtimex
. Eu coloquei uma cópia do adjtimex
binário squeeze em http://linux.brong.fastmail.fm/2012-06-30/adjtimex — ele será executado sem dependências em um sistema squeeze de 64 bits. Se você colocá-lo no mesmo diretório que fixtime.pl
, ele será usado se o do sistema não estiver presente. Obviamente, se você não tiver o squeeze de 64 bits… encontre o seu próprio.
Vou recomeçar ntp
amanhã.
Como um usuário anônimo sugeriu - uma alternativa à execução adjtimex
é apenas definir a hora, o que presumivelmente também limpará o contador de segundos bissextos.
Isso é causado por um livelock quando o ntpd chama o adjtimex(2) para dizer ao kernel para inserir um segundo bissexto. Veja a postagem do lkml http://lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.html
A Red Hat também deve atualizar seu artigo da base de conhecimento. https://access.redhat.com/knowledge/articles/15145
ATUALIZAÇÃO: Red Hat tem um segundo artigo KB apenas para este problema aqui: https://access.redhat.com/knowledge/solutions/154713 - o artigo anterior é para um problema anterior não relacionado
A solução alternativa é apenas desligar o ntpd. Se o ntpd já emitiu a chamada adjtimex(2), pode ser necessário desabilitar o ntpd e reiniciar para ficar 100% seguro.
Isso afeta o RHEL 6 e outras distribuições que executam kernels mais recentes (mais recentes que aproximadamente 2.6.26), mas não o RHEL 5.
A razão pela qual isso está ocorrendo antes que o segundo bissexto esteja realmente programado para ocorrer é que o ntpd permite que o kernel lide com o segundo bissexto à meia-noite, mas precisa alertar o kernel para inserir o segundo bissexto antes da meia-noite. O ntpd, portanto, chama adjtimex(2) em algum momento durante o dia do segundo bissexto, momento em que esse bug é acionado.
Se você tiver o adjtimex(8) instalado, poderá usar este script para determinar se o sinalizador 16 está definido. O sinalizador 16 está "inserindo segundo bissexto":
ATUALIZAR:
A Red Hat atualizou seu artigo da base de conhecimento para observar: "Os clientes do RHEL 6 podem ser afetados por um problema conhecido que faz com que o NMI Watchdog detecte um travamento ao receber o anúncio de segundo bissexto do NTP. Este problema está sendo resolvido em tempo hábil. Se seus sistemas receberam o anúncio do segundo bissexto e não tiveram esse problema, eles não serão mais afetados."
ATUALIZAÇÃO: O idioma acima foi removido do artigo da Red Hat; e uma segunda solução KB foi adicionada detalhando o problema de falha do adjtimex(2): https://access.redhat.com/knowledge/solutions/154713
No entanto, a alteração de código na postagem LKML pelo engenheiro da IBM John Stultz observa que também pode haver um impasse quando o segundo bissexto é realmente aplicado, então você pode querer desabilitar o segundo bissexto reinicializando ou usando adjtimex(8) após desabilitar o ntpd.
ATUALIZAÇÃO FINAL:
Bem, eu não sou nenhum desenvolvedor do kernel, mas revisei o patch de John Stultz novamente aqui: https://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h =6b43ae8a619d17c4935c3320d2ef9e92bdeed05d
Se eu estou lendo certo desta vez, eu estava errado sobre haver outro impasse quando o segundo bissexto é aplicado. Essa também parece ser a opinião da Red Hat, com base em sua entrada na KB. No entanto, se você desativou o ntpd, mantenha-o desativado por mais 10 minutos, para que você não atinja o impasse quando o ntpd chamar o adjtimex(2).
Vamos descobrir se há mais bugs em breve :)
SEGUNDA ATUALIZAÇÃO PÓS-SALTO:
Passei as últimas horas lendo o código do kernel ntpd e pré-patch (com bugs) e, embora possa estar muito errado aqui, tentarei explicar o que acho que estava acontecendo:
Primeiro, o ntpd chama adjtimex(2) o tempo todo. Ele faz isso como parte de seu "filtro de loop de relógio", definido em local_clock em ntp_loopfilter.c. Você pode ver esse código aqui: http://www.opensource.apple.com/source/ntp/ntp-70/ntpd/ntp_loopfilter.c (do ntp versão 4.2.6).
O filtro de loop de relógio é executado com bastante frequência - ele é executado toda vez que o ntpd pesquisa seus servidores upstream, que por padrão é a cada 17 minutos ou mais. O bit relevante do filtro de loop de clock é:
E depois:
Em outras palavras, nos dias em que há um segundo bissexto, o ntpd define o sinalizador "STA_INS" e chama adjtimex(2) (através de seu wrapper de portabilidade).
Essa chamada de sistema chega ao kernel. Aqui está o código do kernel relevante: https://github.com/mirrors/linux/blob/a078c6d0e6288fad6d83fb6d5edd91ddb7b6ab33/kernel/time/ntp.c
O caminho de código do kernel é aproximadamente este:
Há algumas coisas interessantes aqui.
Primeiro, a linha 691 cancela o cronômetro existente toda vez que adjtimex(2) é chamado. Em seguida, 554 recria esse temporizador. Isso significa que cada vez que o ntpd executou seu filtro de loop de clock, o código com bugs foi invocado.
Portanto, acredito que a Red Hat estava errada quando disse que uma vez que o ntpd tivesse definido o sinalizador de segundo bissexto, o sistema não travaria. Acredito que cada sistema executando o ntpd tinha o potencial de travar a cada 17 minutos (ou mais) pelo período de 24 horas antes do segundo bissexto. Acredito que isso também possa explicar por que tantos sistemas travaram; uma chance única de bater seria muito menos provável de acertar em comparação com 3 chances por hora.
ATUALIZAÇÃO: Na solução KB da Red Hat em https://access.redhat.com/knowledge/solutions/154713 , os engenheiros da Red Hat chegaram à mesma conclusão (que a execução do ntpd atingiria continuamente o código com erros). E, de fato, eles fizeram isso várias horas antes de mim. Esta solução não estava vinculada ao artigo principal em https://access.redhat.com/knowledge/articles/15145 , então não percebi até agora.
Em segundo lugar, isso explica por que os sistemas carregados eram mais propensos a travar. Sistemas carregados lidarão com mais interrupções, fazendo com que a função do kernel "do_tick" seja chamada com mais frequência, dando mais chance para esse código ser executado e pegar o ntp_lock enquanto o temporizador estava sendo criado.
Terceiro, há uma chance de o sistema travar quando o segundo bissexto realmente ocorrer? Eu não sei ao certo, mas possivelmente sim, porque o temporizador que dispara e realmente executa o ajuste do segundo bissexto (ntp_leap_second, na linha 388) também pega o spinlock ntp_lock e tem uma chamada para hrtimer_add_expires_ns. Não sei se essa chamada também pode causar um livelock, mas não parece impossível.
Finalmente, o que faz com que o sinalizador de segundo bissexto seja desabilitado após a execução do segundo bissexto? A resposta é que o ntpd para de definir o sinalizador de segundo bissexto em algum ponto após a meia-noite quando chama adjtimex(2). Como o sinalizador não está definido, a verificação na linha 554 não será verdadeira e nenhum temporizador será criado, e a linha 598 redefinirá a variável global time_state para TIME_OK. Isso explica por que se você verificar o sinalizador com adjtimex(8) logo após o segundo bissexto, você ainda verá o sinalizador de segundo bissexto definido.
Resumindo, o melhor conselho para hoje parece ser o primeiro que dei afinal: desabilite o ntpd e desabilite o sinalizador de segundo bissexto.
E algumas considerações finais:
Atualização de 02/06 de John Stultz:
https://lkml.org/lkml/2012/7/1/203
A postagem continha um passo a passo de por que o segundo bissexto fazia com que os cronômetros futex expirassem prematuramente e continuamente, aumentando a carga da CPU.
Isso nos atingiu em cheio. Depois de reiniciar muitos de nossos hosts, o seguinte acabou sendo embaraçosamente simples e totalmente eficaz sem a reinicialização do host:
Tudo o que é necessário é redefinir o relógio do sistema. Sheesh. O que eu dei para saber disso seis horas atrás.
Um programa em C simples que limpa o segundo bit bissexto no campo de status de tempo do kernel:
Salve como
lsec.c
, compile comgcc -Wall -Wextra -o lsec lsec.c
e execute como root.Você provavelmente desejará parar o ntpd antes de executá-lo e reiniciar o ntpd após o segundo bissexto.
Postmortem parece que ./lsec não tem efeito.
O que estamos vendo são muitos processos softirqd consumindo CPU (geralmente lineares à carga de processos Java)
O que funciona para corrigir POSTMORTEM com segundos bissextos já aplicados pelo ntp é o seguinte:
Parece ser suficiente apenas emitir:
Isso deve reduzir a carga sem reiniciar ou reinicializar o ntpd. Alternativamente, você pode emitir:
http://my.opera.com/marcomarongiu/blog/2012/03/12/no-step-back parece indicar que o kernel squeeze do Debian não vai lidar com o segundo bissexto.
Este tópico em comp.protocols.tim.ntp também é interessante: https://groups.google.com/forum/?fromgroups#!topic/comp.protocols.time.ntp/KSflIgjUdPE
Dito isto, o segundo bissexto ainda não aconteceu: 23:59:60 UTC
Finalmente, https://access.redhat.com/knowledge/articles/15145 tem o seguinte a dizer: "Quando ocorre o segundo bissexto, o kernel imprime uma mensagem no log do sistema. Há uma chance de que a impressão desta mensagem pode fazer com que o kernel falhe no Red Hat Enterprise Linux."