![dmesg 时间与系统时间的时间不正确](https://linux22.com/image/627060/dmesg%20%E6%97%B6%E9%97%B4%E4%B8%8E%E7%B3%BB%E7%BB%9F%E6%97%B6%E9%97%B4%E7%9A%84%E6%97%B6%E9%97%B4%E4%B8%8D%E6%AD%A3%E7%A1%AE.png)
我希望有人能帮助我解决这个奇怪的问题。
我想我知道为什么会发生这种情况,但我不知道如何解决它。可能是因为 BIOS 时间设置不正确或类似原因。但我不想更改大约 400 多台服务器的 BIOS 时间。(或更改 BIOS 电池)
root@spool:~# echo TEST > /dev/kmsg
root@spool:~# dmesg -T | tail -1
[Mon Feb 17 04:57:03 2014] TEST
root@spool:~# date
Mon Feb 17 11:45:17 CET 2014
服务器正在运行 ntp 进行时间同步。
这里有谁知道如何修复操作系统中的这个问题吗?
Linux spool 3.2.0-4-amd64 #1 SMP Debian 3.2.46-1+deb7u1 x86_64 GNU/Linux
为什么回显到 时/dev/kmsg
,我的消息的日期/时间dmesg
与系统日期/时间不同步?
答案1
为了验证你的理论(顺便说一句,这是正确的),请以 root 身份执行以下操作:
hwclock --show
这将显示您正在执行命令的服务器上的硬件时钟。
要将您的硬件时钟与系统时间(由 ntp 管理)同步,请运行以下命令:
hwclock --systohc --utc
最后一个参数(--utc)告诉 hwclock 以协调世界时的形式存储硬件时钟中的时间。
此外,请记住 dmesg(1) 的手册页内容如下,因此您所遇到的行为是有记录的且有效的:
-T, --ctime
Print human-readable timestamps.
Be aware that the timestamp could be inaccurate! The time
source used for the logs is not updated after system
SUSPEND/RESUME.
答案2
dmesg 仅打印内核环形缓冲区,该缓冲区以时间戳的形式记录启动时间(以秒为单位)的消息。
因此,如果您使用 -T 选项,所有这些正常运行时间值都只会添加到系统启动的日期。如果您在挂起或恢复时有睡眠时间,这些时间会丢失,因此在这种情况下 -T 选项没有用,因为日期/时间值不是当时的正确值,也不是过去的值。
答案3
解决方法是使用 journalctl 加上 -k、--dmesg。我使用 -k 因为它更短:
journalctl -k
它将只显示内核消息和正确的时间。
仅显示与短语匹配的内核行:
journalctl -kg phrase
答案4
为了获得“最近”条目的准确时间dmesg
,您可以对输出进行一些修改,将 dmesg 时间戳转换为实时时间。
我所说的“最近”是指上次挂起/恢复之后的时间,因为(正如其他人已经指出的)挂起时间不计入 dmesg 时间戳中。
但如果您经常需要它,例如在笔记本上,您可以将以下内容放入函数或别名中:
# write current time to kernel ring buffer so it appears in dmesg output
echo "timecheck: $(date +%s) = $(date +%F_%T)" | sudo tee /dev/kmsg
# use our "timecheck" entry to get the difference
# between the dmesg timestamp and real time
offset=$(dmesg | grep timecheck | tail -1 \
| perl -nle '($t1,$t2)=/^.(\d+)\S+ timecheck: (\d+)/; print $t2-$t1')
# pipe dmesg output through a Perl snippet to
# convert it's timestamp to correct readable times
dmesg | tail \
| perl -pe 'BEGIN{$offset=shift} s/^\[(\d+)\S+/localtime($1+$offset)/e' $offset
# or use this instead to keep dmesg colors
dmesg --color=always | tail \
| perl -pe 'BEGIN{$offset=shift} s/^(\x1b\[.*?m)?\[(\d+)\S+/$1.localtime($2+$offset)/e' $offset
示例输出:
...
Sat Jun 29 11:12:28 2019 wlp3s0: Limiting TX power to 30 (30 - 0) dBm as advertised by 10:5a:f7:53:1d:0f
Sat Jun 29 11:12:28 2019 IPv6: ADDRCONF(NETDEV_CHANGE): wlp3s0: link becomes ready
Sat Jun 29 11:34:16 2019 timecheck: 1561800856 = 2019-06-29_11:34:16
Sat Jun 29 12:10:11 2019 wlp3s0: cannot understand ECSA IE operating class, 5, ignoring
与原始输出相比dmesg
(相差 3 天):
$ dmesg | tail -4
[249424.746958] wlp3s0: Limiting TX power to 30 (30 - 0) dBm as advertised by 10:5a:f7:53:1d:0f
[249424.749662] IPv6: ADDRCONF(NETDEV_CHANGE): wlp3s0: link becomes ready
[250732.318826] timecheck: 1561800856 = 2019-06-29_11:34:16
[252887.828699] wlp3s0: cannot understand ECSA IE operating class, 5, ignoring
$ dmesg -T | tail -4
[Wed Jun 26 17:59:09 2019] wlp3s0: Limiting TX power to 30 (30 - 0) dBm as advertised by 10:5a:f7:53:1d:0f
[Wed Jun 26 17:59:09 2019] IPv6: ADDRCONF(NETDEV_CHANGE): wlp3s0: link becomes ready
[Wed Jun 26 18:20:57 2019] timecheck: 1561800856 = 2019-06-29_11:34:16
[Wed Jun 26 18:56:52 2019] wlp3s0: cannot understand ECSA IE operating class, 5, ignoring
更新:
如果你的系统使用“systemd” journalctl
,那么这个答案用户“16851556”让它变得更容易:
journalctl --dmesg