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
.