summaryrefslogtreecommitdiffstats
path: root/sys-utils/dmesg.c
diff options
context:
space:
mode:
authorSami Kerola2013-06-30 20:11:22 +0200
committerKarel Zak2013-07-01 14:30:20 +0200
commit3c5384d05d3283cf93b5dbd8a4bb4fe245c4c19d (patch)
tree595d168a7c280c2dc30e312240084145de605a65 /sys-utils/dmesg.c
parentsfdisk: fix typo (diff)
downloadkernel-qcow2-util-linux-3c5384d05d3283cf93b5dbd8a4bb4fe245c4c19d.tar.gz
kernel-qcow2-util-linux-3c5384d05d3283cf93b5dbd8a4bb4fe245c4c19d.tar.xz
kernel-qcow2-util-linux-3c5384d05d3283cf93b5dbd8a4bb4fe245c4c19d.zip
dmesg: make time stamps to be printed consistently
Earlier uptime determination, which was done with sysinfo(2), had one second resolution, which made time stamps to be rounded unstable way depending on when a dmesg command was executed. In practical terms; the command below was supposed not to differ but it did. $ diff -q <(dmesg --ctime) <(sleep 0.5 ; dmesg --ctime) [kzak@redhat.com: - add -lrt to Makemodule.am, - fallback to sysinfo() based boot time - use #ifdef] CC: Kay Sievers <kay@vrfy.org> References: https://lkml.org/lkml/2013/6/30/37 Buglink: https://github.com/karelzak/util-linux/issues/24 Signed-off-by: Sami Kerola <kerolasa@iki.fi> Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'sys-utils/dmesg.c')
-rw-r--r--sys-utils/dmesg.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/sys-utils/dmesg.c b/sys-utils/dmesg.c
index c098323c2..e6819308c 100644
--- a/sys-utils/dmesg.c
+++ b/sys-utils/dmesg.c
@@ -145,7 +145,7 @@ struct dmesg_control {
struct timeval lasttime; /* last printed timestamp */
struct tm lasttm; /* last localtime */
- time_t boot_time; /* system boot time */
+ struct timeval boot_time; /* system boot time */
int action; /* SYSLOG_ACTION_* */
int method; /* DMESG_METHOD_* */
@@ -472,17 +472,30 @@ static int get_syslog_buffer_size(void)
return n > 0 ? n : 0;
}
-static time_t get_boot_time(void)
+static int get_boot_time(struct timeval *boot_time)
{
+ struct timespec hires_uptime;
+ struct timeval lores_uptime, now;
struct sysinfo info;
- struct timeval tv;
+ if (gettimeofday(&now, NULL) != 0) {
+ warn(_("gettimeofday failed"));
+ return -errno;
+ }
+
+#ifdef CLOCK_BOOTTIME
+ if (clock_gettime(CLOCK_BOOTTIME, &hires_uptime) == 0) {
+ TIMESPEC_TO_TIMEVAL(&lores_uptime, &hires_uptime);
+ timersub(&now, &lores_uptime, boot_time);
+ return 0;
+ }
+#endif
+ /* fallback */
if (sysinfo(&info) != 0)
warn(_("sysinfo failed"));
- else if (gettimeofday(&tv, NULL) != 0)
- warn(_("gettimeofday failed"));
- else
- return tv.tv_sec -= info.uptime;
+
+ boot_time->tv_sec = now.tv_sec - info.uptime;
+ boot_time->tv_usec = 0;
return 0;
}
@@ -771,7 +784,7 @@ static struct tm *record_localtime(struct dmesg_control *ctl,
struct dmesg_record *rec,
struct tm *tm)
{
- time_t t = ctl->boot_time + rec->tv.tv_sec;
+ time_t t = ctl->boot_time.tv_sec + rec->tv.tv_sec;
return localtime_r(&t, tm);
}
@@ -1339,8 +1352,7 @@ int main(int argc, char *argv[])
is_timefmt(&ctl, CTIME) ||
is_timefmt(&ctl, ISO8601)) {
- ctl.boot_time = get_boot_time();
- if (!ctl.boot_time)
+ if (get_boot_time(&ctl.boot_time) != 0)
ctl.time_fmt = DMESG_TIMEFTM_NONE;
}