Received: by 2002:a25:683:0:0:0:0:0 with SMTP id 125csp714392ybg; Mon, 1 Jun 2020 12:24:27 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxcZTRJCOUH35+32IKWf2FzJ41QBnpZ0nzwdfyUoQc5AWduhu48YFyZQGrfC9g2oAWyUNtP X-Received: by 2002:a50:f0c4:: with SMTP id a4mr1586739edm.125.1591039467534; Mon, 01 Jun 2020 12:24:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1591039467; cv=none; d=google.com; s=arc-20160816; b=o2nqTiCdF9ZYG0oKko+ULvXxEwQQQSYhuAyghrrzeFRgZYGeW6/pzkwPYbeaGCA3UD 7aaVdEbiz5SC+2p4YLuUVQ0TvmlUwhod6uF62roIbZI0heXp6v6PyVd/5EzQMFo8VFY0 /dIUwZbHw1H5hKW6iH1mn99ATWlb2MxARahhrCmYcyly+nNtuc7CX7x/c6mFVxg5ug1W ZayinRothLZNgt5mU59hgGE/5qF7VzMwVlUMDD3aa6ziPNld0BEUalj9n+DVfk66nXke l7WuXTv4u/LsEYZexV5RvJXlxg+jvSViRI0kjo5LfRVYic8BFiz6MDUwFympveYEvBKV e2VQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:message-id:date:cc:to:from:subject:dkim-signature; bh=9qIipJ1NHMYN+PK3lJcRt0JyyNTfeEEpJCKeCYNYrEw=; b=m/E7aoJ0tMfZlseoBE2lqSHzib4dyrr9AzUzvvXOc3x+KjRBzh3gtalSNNCySLrpst 3azTJDYDo8cwTcplje6ivfpyOQc19xC1hTyZ/YimEeSWZYrFvQQXZpfXtOcU/SMlCwNW MCym+bBuFthDIDqa+PUQjCbIPjRrFZXaGWYNGSp0D2MQ1b7t+V8UVw/nbcy5yDyiaqvr chTDmAk9Yi0ERvkh8Hdv+UqH1YjR8JUsM8E+N2eu9zCiuJIpdPjmQn+8eeAj0qbyhTn7 C2BvRy/vIi5lZtF7oiSMUiAZA7M6f+hom0kOQxOkpaYWflkDR9hteugK1gelFfZrIADr cJXg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@yandex-team.ru header.s=default header.b=KAUiQpEY; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=yandex-team.ru Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id dp4si278726ejc.258.2020.06.01.12.23.54; Mon, 01 Jun 2020 12:24:27 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@yandex-team.ru header.s=default header.b=KAUiQpEY; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=yandex-team.ru Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728205AbgFATVl (ORCPT + 99 others); Mon, 1 Jun 2020 15:21:41 -0400 Received: from forwardcorp1o.mail.yandex.net ([95.108.205.193]:58616 "EHLO forwardcorp1o.mail.yandex.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726751AbgFATVl (ORCPT ); Mon, 1 Jun 2020 15:21:41 -0400 Received: from mxbackcorp2j.mail.yandex.net (mxbackcorp2j.mail.yandex.net [IPv6:2a02:6b8:0:1619::119]) by forwardcorp1o.mail.yandex.net (Yandex) with ESMTP id 5A5792E157C; Mon, 1 Jun 2020 22:21:37 +0300 (MSK) Received: from myt5-70c90f7d6d7d.qloud-c.yandex.net (myt5-70c90f7d6d7d.qloud-c.yandex.net [2a02:6b8:c12:3e2c:0:640:70c9:f7d]) by mxbackcorp2j.mail.yandex.net (mxbackcorp/Yandex) with ESMTP id Iz970RYwJe-LafmlK9f; Mon, 01 Jun 2020 22:21:37 +0300 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1591039297; bh=9qIipJ1NHMYN+PK3lJcRt0JyyNTfeEEpJCKeCYNYrEw=; h=Message-ID:Date:To:From:Subject:Cc; b=KAUiQpEYqvpp+dMvJQOaqsPFGXX18uZIFDUyDlMRl6vFRJVJCoYFxvBW4USj+wIKB dEe5FJhrScjJxlLybS/r6t4k2CCUjfMwAZ77lrgoE7Vxn5UIjVKQafieFHTDDppnaG sGhldjGhzZZoYEJwxrlljFnZUtq/GCxRFU1M0pdY= Authentication-Results: mxbackcorp2j.mail.yandex.net; dkim=pass header.i=@yandex-team.ru Received: from dynamic-vpn.dhcp.yndx.net (dynamic-vpn.dhcp.yndx.net [2a02:6b8:b081:623::1:1]) by myt5-70c90f7d6d7d.qloud-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id YVOhHoRaIy-LaW45fjp; Mon, 01 Jun 2020 22:21:36 +0300 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (Client certificate not present) Subject: [PATCH util-linux] dmesg: adjust timestamps according to suspended time From: Konstantin Khlebnikov To: util-linux@vger.kernel.org Cc: linux-kernel@vger.kernel.org Date: Mon, 01 Jun 2020 22:21:34 +0300 Message-ID: <159103929487.199093.15757669576783156290.stgit@buzz> User-Agent: StGit/0.22-39-gd257 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Timestamps in kernel log comes from monotonic clocksource which does not tick when system suspended. Suspended time easily sums into hours and days rendering human readable timestamps in dmesg useless. Adjusting timestamps accouring to current delta between boottime and monotonic clocksources produces accurate timestamps for messages printed since last resume. Which are supposed to be most interesting. Signed-off-by: Konstantin Khlebnikov --- include/monotonic.h | 2 ++ lib/monotonic.c | 12 ++++++++++++ sys-utils/dmesg.1 | 2 ++ sys-utils/dmesg.c | 22 +++++++++++++++++----- 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/include/monotonic.h b/include/monotonic.h index 7a69d9e4b51e..380e59c3791e 100644 --- a/include/monotonic.h +++ b/include/monotonic.h @@ -15,6 +15,8 @@ extern int get_boot_time(struct timeval *boot_time); +extern time_t get_suspended_time(void); + extern int gettime_monotonic(struct timeval *tv); #endif /* UTIL_LINUX_MONOTONIC_H */ diff --git a/lib/monotonic.c b/lib/monotonic.c index b684d8dd650a..f0aeba6828e7 100644 --- a/lib/monotonic.c +++ b/lib/monotonic.c @@ -48,6 +48,18 @@ int get_boot_time(struct timeval *boot_time) #endif } +time_t get_suspended_time(void) +{ +#if defined(CLOCK_BOOTTIME) && defined(CLOCK_MONOTONIC) + struct timespec boot, mono; + + if (clock_gettime(CLOCK_BOOTTIME, &boot) == 0 && + clock_gettime(CLOCK_MONOTONIC, &mono) == 0) + return boot.tv_sec - mono.tv_sec; +#endif + return 0; +} + int gettime_monotonic(struct timeval *tv) { #ifdef CLOCK_MONOTONIC diff --git a/sys-utils/dmesg.1 b/sys-utils/dmesg.1 index 61a6ce89465d..6c5773a6b211 100644 --- a/sys-utils/dmesg.1 +++ b/sys-utils/dmesg.1 @@ -161,6 +161,8 @@ source used for the logs is .B not updated after system .BR SUSPEND / RESUME . +Timestamps are adjusted according to current delta between boottime and monotonic +clocks, this works only for messages printed after last resume. .IP "\fB\-t\fR, \fB\-\-notime\fR" Do not print kernel's timestamps. .IP "\fB\-\-time\-format\fR \fIformat\fR" diff --git a/sys-utils/dmesg.c b/sys-utils/dmesg.c index ae1ebc74a2d9..c78f01ca8755 100644 --- a/sys-utils/dmesg.c +++ b/sys-utils/dmesg.c @@ -169,6 +169,7 @@ struct dmesg_control { struct timeval lasttime; /* last printed timestamp */ struct tm lasttm; /* last localtime */ struct timeval boot_time; /* system boot time */ + time_t suspended_time; /* time spent in suspeneded state */ int action; /* SYSLOG_ACTION_* */ int method; /* DMESG_METHOD_* */ @@ -824,7 +825,7 @@ static struct tm *record_localtime(struct dmesg_control *ctl, struct dmesg_record *rec, struct tm *tm) { - time_t t = ctl->boot_time.tv_sec + rec->tv.tv_sec; + time_t t = ctl->boot_time.tv_sec + ctl->suspended_time + rec->tv.tv_sec; return localtime_r(&t, tm); } @@ -852,7 +853,7 @@ static char *iso_8601_time(struct dmesg_control *ctl, struct dmesg_record *rec, char *buf, size_t bufsz) { struct timeval tv = { - .tv_sec = ctl->boot_time.tv_sec + rec->tv.tv_sec, + .tv_sec = ctl->boot_time.tv_sec + ctl->suspended_time + rec->tv.tv_sec, .tv_usec = rec->tv.tv_usec }; @@ -1301,8 +1302,16 @@ static inline int dmesg_get_boot_time(struct timeval *tv) return get_boot_time(tv); } + +static inline time_t dmesg_get_suspended_time(void) +{ + if (getenv("DMESG_TEST_BOOTIME")) + return 0; + return get_suspended_time(); +} #else # define dmesg_get_boot_time get_boot_time +# define dmesg_get_suspended_time get_suspended_time #endif int main(int argc, char *argv[]) @@ -1499,9 +1508,12 @@ int main(int argc, char *argv[]) if ((is_timefmt(&ctl, RELTIME) || is_timefmt(&ctl, CTIME) || - is_timefmt(&ctl, ISO8601)) - && dmesg_get_boot_time(&ctl.boot_time) != 0) - ctl.time_fmt = DMESG_TIMEFTM_NONE; + is_timefmt(&ctl, ISO8601))) { + if (dmesg_get_boot_time(&ctl.boot_time) != 0) + ctl.time_fmt = DMESG_TIMEFTM_NONE; + else + ctl.suspended_time = dmesg_get_suspended_time(); + } if (delta) switch (ctl.time_fmt) {