Tempo de força para ficar parado

4

O tempo na minha máquina Linux não vai ficar parado. Eu preciso testar um problema com o nosso servidor que só ocorre aos sábados.

  • CentOS 6.5 de 64 bits
  • Eu tenho o NTPD desativado. ( service ntpd stop e chkconfig ntpd off )
  • Eu tenho o relógio BIOS / HW virtual definido para 2 de maio de 2015
  • Alterar a hora para o futuro ou o passado tem o mesmo efeito.
  • Eu defino a data na linha de comando com date --set "02 May 2015 11:00:00"
  • date responde corretamente e mostra que a data é 2 de maio de 2015
  • Nada relacionado ao tempo / ntp em cron.d , cron.daily , cron.hourly , etc.

Após alguns minutos, o tempo será forçado a voltar à data apropriada.

O que mais poderia estar sendo executado para alterar continuamente o tempo de volta? Onde está ficando sua informação!?

    
por Justin Edmands 28.04.2015 / 22:08

2 respostas

4

Para essa resposta, presumo que pode haver vários elementos trabalhando muito para definir seu tempo. Como eu realmente não quero adivinhar que qual deles está funcionando contra você, vou tentar e dar uma resposta que o ajude a encontrar você mesmo.

Em um sistema UNIX, o relógio normalmente pode ser definido usando a chamada do sistema stime . Conforme as coisas evoluíram, também foi possível definir os relógios com mais precisão usando a chamada clock_settime . Você também pode vir em settimeofday . Ao executar date --set em uma máquina do CentOS, strace revelou que usava clock_settime .

Sabendo disso, uma solução seria rastrear essas chamadas do sistema. O bom é que o Linux tem um mecanismo para isso: debugfs. No meu sistema, chamando mount , posso ver que isso está disponível em /sys/kernel/debug :

$ mount
none on /sys/kernel/debug type debugfs (rw)
...

No entanto, em alguns sistemas (incluindo RedHat e provavelmente CentOS), não está montado no momento da inicialização . Você precisará, portanto, executar ...

# mount -t debugfs nodev /sys/kernel/debug

Observe também que, se você estivesse nesse diretório antes da montagem, talvez tenha que sair e voltar antes que os arquivos comecem a aparecer nele.

Agora estamos prontos para ir. Vamos habilitar o rastreamento para nossas chamadas de sistemas. Estou rastreando todos eles porque não quero realmente verificar qual deles está realmente sendo usado. O rastreamento para chamadas do sistema pode ser definido em /sys/kernel/debug/tracing/events/syscalls . Neste diretório, você deve encontrar ...

  • sys_enter_stime
  • sys_enter_clock_settime
  • sys_enter_settimeofday

... dependendo do que está disponível no seu sistema.

Estes correspondem aos eventos de entrar em nossas chamadas de sistema, que é o que queremos rastrear (você também encontrará sys_exit_* diretórios). Dentro de cada diretório, você encontrará um arquivo chamado enable , cujo conteúdo deve aparecer como 0. Para rastrear essas chamadas, defina isso como 1:

# echo 1 > /sys/kernel/debug/tracing/events/syscalls/sys_enter_stime/enable
# echo 1 > /sys/kernel/debug/tracing/events/syscalls/sys_enter_clock_settime/enable
# echo 1 > /sys/kernel/debug/tracing/events/syscalls/sys_enter_settimeofday/enable

Agora que configuramos nossa armadilha, aguarde até que algo defina seu tempo com o valor correto. Uma vez que isso aconteceu, corra para os logs de rastreamento em ...

# cat /sys/kernel/debug/tracing/trace 

Agora, a menos que algo de errado ocorra, você deverá ver uma das seguintes linhas:

stime-xxxxx [xxx] .... x.x: sys_stime(...)
clock_settime-xxxxx [xxx] .... x.x: sys_clock_settime(...)
settimeofday-xxxxx [xxx] .... x.x: sys_settimeofday(...)

O número logo após stime- (ou o nome de outra chamada) é o PID do processo que fez a chamada do sistema. Agora vá em frente:

# ps -fp xxxxx
UID        PID  PPID  C STIME TTY          TIME CMD
root     XXXXX XXXXX  0 hh:mm ?        hh:mm:ss time_warrior

Agora você deve ter tudo de que precisa para garantir que seu sistema pare de acertar o tempo. A coisa mais simples provavelmente seria matar o processo e garantir que ele não seja gerado durante a inicialização; É claro que você terá que garantir que ele não atenda a um propósito mais importante antes de fazê-lo: você não quer estragar completamente seu sistema ...

Lembre-se também de desativar o rastreamento quando terminar, escrevendo 0 nos arquivos que editamos anteriormente. Um atalho pode ser:

# echo 0 > /sys/kernel/debug/tracing/events/syscalls/enable

(este arquivo atua como um switch mestre para todos os outros; ele permite que você desligue todas as chamadas do sistema)

Nota: como Mark Plotnick disse em um comentário systemtap poderia ser uma maneira um pouco mais fácil de alcançar resultados semelhantes. Vou deixá-lo escrever uma resposta stap se ele quiser, já que eu não sou fluente com scripts stap .

    
por 28.04.2015 / 23:44
1

Se você tiver systemtap instalado, o que provavelmente é o caso de um sistema CentOS, é fácil rastrear qualquer chamada de sistema em todo o sistema .

# cat clock.stp
probe nd_syscall.stime, nd_syscall.settimeofday, nd_syscall.clock_settime {
    printf("process %d (%s) called %s(%s) at %d\n", pid(), execname(), name, argstr,
           gettimeofday_us());
}

# stap clock.stp

Para testar isso, em outra janela, execute

# date 04301056
Thu Apr 30 10:56:00 EDT 2015

e a saída do stap será

process 7520 (date) called clock_settime(CLOCK_REALTIME, [1430405760.000000000]) at 1430405782997282
    
por 30.04.2015 / 16:59