diff options
author | Sami Kerola | 2013-06-30 20:11:22 +0200 |
---|---|---|
committer | Karel Zak | 2013-07-01 14:30:20 +0200 |
commit | 3c5384d05d3283cf93b5dbd8a4bb4fe245c4c19d (patch) | |
tree | 595d168a7c280c2dc30e312240084145de605a65 /sys-utils | |
parent | sfdisk: fix typo (diff) | |
download | kernel-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')
-rw-r--r-- | sys-utils/Makemodule.am | 2 | ||||
-rw-r--r-- | sys-utils/dmesg.c | 32 |
2 files changed, 23 insertions, 11 deletions
diff --git a/sys-utils/Makemodule.am b/sys-utils/Makemodule.am index 977be5aff..658b203c6 100644 --- a/sys-utils/Makemodule.am +++ b/sys-utils/Makemodule.am @@ -55,7 +55,7 @@ if LINUX bin_PROGRAMS += dmesg dist_man_MANS += sys-utils/dmesg.1 dmesg_SOURCES = sys-utils/dmesg.c -dmesg_LDADD = $(LDADD) libcommon.la +dmesg_LDADD = $(LDADD) libcommon.la -lrt sbin_PROGRAMS += ctrlaltdel dist_man_MANS += sys-utils/ctrlaltdel.8 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; } |