From: Bruno Haible <bruno@clisp.org>
To: 65255@debbugs.gnu.org
Subject: bug#65255: uptime's boot time is inconsistent after VM sleep & resume
Date: Sun, 13 Aug 2023 01:00:37 +0200 [thread overview]
Message-ID: <33634105.ORx6IIuMYd@nimes> (raw)
[-- Attachment #1: Type: text/plain, Size: 2754 bytes --]
On the following platforms:
- Linux (that includes glibc-based systems, Alpine Linux, Raspbian),
- NetBSD,
- Cygwin,
- Minix,
the "up" duration is inconsistent after the VM in which the OS is running
has been
1. put into sleep / saved / pause mode (terminology depends on the
hypervisor),
2. resumed,
3. a date bump has been done in the VM (either automatically or manually).
VM sleep and a date adjustment after resume is a common operation, as can
be seen
- from the fact that it's automatic in VirtualBox machines with the
"guest extensions" installed [1],
- from the fact that it's automatic in KVM [2],
- from the fact that it's automatic in Haiku as guest,
- from a remark in the libvirt documentation [3],
- from stackoverflow questions such as [4].
After such a VM sleep and a date adjustment, coreutils' "uptime" is
inconsistent in three ways:
* On Linux, the displayed "up" duration includes active time and
hardware suspend time [5], but excludes VM sleep time.
Such a figure is not useful for estimating the boot time, since
(time now) - (that "up" time) is not the boot time.
It is also not useful for estimating when e.g. a file system check
would be necessary on file systems without a journal, or how much
electricity was consumed — since the hardware suspend time was included.
So this figure is useless.
* The displayed "up" duration is inconsistent with the boot time displayed
by "who -a". (Since the Gnulib module 'readutmp' makes efforts to find
the boot time in a way that does not change when the date is adjusted.)
* The behaviour is inconsistent among platforms: On platforms which have
a /proc/uptime file, the displayed "up" time _excludes_ VM sleep time.
On the other platforms it _includes_ VM sleep time.
Seen on Linux (Fedora Rawhide, Alpine Linux 3.18, Raspbian), NetBSD 9.3,
Cygwin 2.9.0, Minix 3.3.
I see this as a bug. Find attached a fix for this bug. I'll provide a NEWS
entry afterwards, that summarizes the changes in coreutils + gnulib on the
various platforms.
Bruno
[1] https://docs.oracle.com/en/virtualization/virtualbox/6.1/user/guestadditions.html#4.1.-Introduction-to-Guest-Additions
[2] https://bugzilla.redhat.com/show_bug.cgi?id=1115340
[3] https://libvirt.gitlab.io/libvirt-appdev-guide-python/libvirt_application_development_guide_using_python-Guest_Domains-Lifecycle-Save.html
[4] https://serverfault.com/questions/334698/
[5] This is indicated by glibc's <bits/time.h>:
/* Monotonic system-wide clock that includes time spent in suspension. */
# define CLOCK_BOOTTIME 7
I also verified this on a laptop.
[-- Attachment #2: 0001-uptime-Include-VM-sleep-time-in-the-up-duration.patch --]
[-- Type: text/x-patch, Size: 2725 bytes --]
From ff6e92f38b560ade54df4c94e9d91657f740bb4b Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 13 Aug 2023 00:57:23 +0200
Subject: [PATCH] uptime: Include VM sleep time in the "up" duration
* src/uptime.c: Don't include c-strtod.h.
(print_uptime): Don't read /proc/uptime, because the value it provides
does not change when a date adjustment occurs.
* bootstrap.conf (gnulib_modules): Remove 'uptime'.
---
bootstrap.conf | 1 -
src/uptime.c | 36 ++++++------------------------------
2 files changed, 6 insertions(+), 31 deletions(-)
diff --git a/bootstrap.conf b/bootstrap.conf
index 6ce27d5dd..d758a9ff6 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -285,7 +285,6 @@ gnulib_modules="
unlocked-io
unsetenv
update-copyright
- uptime
useless-if-before-free
userspec
utimecmp
diff --git a/src/uptime.c b/src/uptime.c
index c29798d32..0cc1dedba 100644
--- a/src/uptime.c
+++ b/src/uptime.c
@@ -22,7 +22,6 @@
#include <sys/types.h>
#include "system.h"
-#include "c-strtod.h"
#include "long-options.h"
#include "quote.h"
#include "readutmp.h"
@@ -42,33 +41,13 @@ print_uptime (idx_t n, struct gl_utmp const *this)
idx_t entries = 0;
time_t boot_time = 0;
time_t time_now;
- time_t uptime = 0;
+ time_t uptime;
intmax_t updays;
int uphours;
int upmins;
struct tm *tmn;
double avg[3];
int loads;
-#ifdef HAVE_PROC_UPTIME
- FILE *fp;
-
- fp = fopen ("/proc/uptime", "r");
- if (fp != nullptr)
- {
- char buf[BUFSIZ];
- char *b = fgets (buf, BUFSIZ, fp);
- if (b == buf)
- {
- char *end_ptr;
- double upsecs = c_strtod (buf, &end_ptr);
- if (buf != end_ptr)
- uptime = (0 <= upsecs && upsecs < TYPE_MAXIMUM (time_t)
- ? upsecs : -1);
- }
-
- fclose (fp);
- }
-#endif /* HAVE_PROC_UPTIME */
/* Loop through all the utmp entries we just read and count up the valid
ones, also in the process possibly gleaning boottime. */
@@ -79,16 +58,13 @@ print_uptime (idx_t n, struct gl_utmp const *this)
boot_time = this->ut_ts.tv_sec;
++this;
}
+ /* The gnulib module 'readutmp' is supposed to provide a BOOT_TIME entry
+ on all platforms. */
+ if (boot_time == 0)
+ error (EXIT_FAILURE, errno, _("couldn't get boot time"));
time_now = time (nullptr);
-#if defined HAVE_PROC_UPTIME
- if (uptime == 0)
-#endif
- {
- if (boot_time == 0)
- error (EXIT_FAILURE, errno, _("couldn't get boot time"));
- uptime = time_now - boot_time;
- }
+ uptime = time_now - boot_time;
updays = uptime / 86400;
uphours = uptime % 86400 / 3600;
upmins = uptime % 86400 % 3600 / 60;
--
2.34.1
next reply other threads:[~2023-08-12 23:01 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-12 23:00 Bruno Haible [this message]
2023-08-12 23:21 ` bug#65255: uptime's boot time is inconsistent after VM sleep & resume Bruno Haible
2023-08-13 6:49 ` Paul Eggert
2023-08-15 13:03 ` Bruno Haible
2023-08-15 21:14 ` Paul Eggert
2023-08-15 21:23 ` Bruno Haible
2023-08-15 22:24 ` Paul Eggert
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://lists.gnu.org/mailman/listinfo/bug-coreutils
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=33634105.ORx6IIuMYd@nimes \
--to=bruno@clisp.org \
--cc=65255@debbugs.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).