迫使时间保持原样

迫使时间保持原样

我的 Linux 机器上的时间不会停滞不前。我需要测试我们的服务器仅在周六发生的问题。

  • CentOS 6.5 64位
  • 我已经关闭了 NTPD。 (service ntpd stopchkconfig ntpd off
  • 我将虚拟 BIOS/硬件时钟设置为 2015 年 5 月 2 日
  • 将时间更改为未来或过去具有相同的效果。
  • 我在命令行上设置日期date --set "02 May 2015 11:00:00"
  • date正确回复并显示日期为 2015 年 5 月 2 日
  • cron.dcron.dailycron.hourly等中与时间/ntp 无关。

几分钟后,时间将自动回到正确的日期。

还有什么可以不断地改变时间呢?它从哪里获取信息!?

答案1

对于这个答案,我假设可能有几个因素在努力调整你的时间。因为我真的不想胡乱猜测哪一个对你不利,我会尽力给你一个答案,这应该可以帮助你自己找到它。

在 UNIX 系统上,通常可以使用系统调用来设置时钟stime。随着事情的发展,使用调用来更准确地设置时钟也成为可能clock_settime。你也可能会遇到settimeofday。在date --setCentOS 机器上运行时,strace显示它使用clock_settime.

知道这一点后,解决方案就是跟踪这些系统调用。好消息是,Linux 有一个机制:debugfs。在我的系统上,调用mount,我可以看到该功能可在以下位置找到/sys/kernel/debug

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

然而,在某些系统上(包括 RedHat 和可能的 CentOS),它没有在启动时安装。因此你需要运行...

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

另请注意,如果您在安装之前位于该目录中,则可能需要退出并返回才能在其中开始出现文件。

现在我们准备出发了。让我们启用系统调用的跟踪。我正在追踪所有这些,因为我真的不想检查哪一个正在被真正使用。可以在 中设置系统调用的跟踪/sys/kernel/debug/tracing/events/syscalls。在此目录中,您应该找到...

  • sys_enter_stime
  • sys_enter_clock_settime
  • sys_enter_settimeofday

...取决于您的系统上可用的内容。

这些对应的事件进入我们的系统调用,这就是我们想要跟踪的内容(您还将找到sys_exit_*目录)。在每个目录中,您将找到一个名为 的文件enable,其内容应显示为 0。要跟踪这些调用,请将其设置为 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

现在我们已经设置了陷阱,只需等待某些东西将您的时间设置为正确的值即可。一旦发生,请运行以下位置的跟踪日志:

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

现在,除非发生错误,否则您应该看到以下行之一:

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

紧随其后的数字stime-(或另一个调用的名称)是进行系统调用的进程的 PID。现在去获取它:

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

您现在应该拥有确保系统停止获得正确时间所需的一切。最简单的事情可能是终止该进程,并确保它不会在启动时生成;当然,您必须确保它不会提供更多服务重要的这样做之前的目的:你不想让你的系统完全崩溃......

还记得在完成后通过向我们之前编辑的文件写入 0 来禁用跟踪。捷径可能是:

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

(该文件充当主开关对于所有其他人;它允许您关闭所有系统调用跟踪)


笔记:正如马克·普洛特尼克(Mark Plotnick)在评论中所说,这systemtap可能是实现类似结果的稍微更容易的方法。stap如果他愿意的话,我会让他写一个答案,因为我stap根本不熟悉脚本。

答案2

如果你有系统水龙头安装后(这可能是 CentOS 系统上的情况),很容易跟踪系统范围内的任何系统调用。

# 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

要测试这一点,请在另一个窗口中运行

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

stap 的输出将是

process 7520 (date) called clock_settime(CLOCK_REALTIME, [1430405760.000000000]) at 1430405782997282

相关内容