From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Bruno Haible Newsgroups: gmane.comp.lib.gnulib.bugs,gmane.emacs.devel Subject: Re: boot time on Linux Date: Thu, 10 Aug 2023 17:30:06 +0200 Message-ID: <3699692.1sqS2uS86G@nimes> References: <87tttmpt5h.fsf@turtle.gmx.de> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7Bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="15260"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Robert Pluim , bug-gnulib@gnu.org, =?ISO-8859-1?Q?P=E1draig?= Brady , Sven Joachim , 64937@debbugs.gnu.org, Po Lu , Emacs Development , Thorsten Kukuk , Natanael Copa To: Paul Eggert , Natanael Copa Original-X-From: bug-gnulib-bounces+gnu-bug-gnulib=m.gmane-mx.org@gnu.org Thu Aug 10 17:30:40 2023 Return-path: Envelope-to: gnu-bug-gnulib@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qU7cV-0003li-Ob for gnu-bug-gnulib@m.gmane-mx.org; Thu, 10 Aug 2023 17:30:39 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qU7cI-0002zl-5I; Thu, 10 Aug 2023 11:30:26 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qU7cG-0002zV-2Q; Thu, 10 Aug 2023 11:30:24 -0400 Original-Received: from mo4-p01-ob.smtp.rzone.de ([81.169.146.167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qU7cD-0001hf-QA; Thu, 10 Aug 2023 11:30:23 -0400 ARC-Seal: i=1; a=rsa-sha256; t=1691681407; cv=none; d=strato.com; s=strato-dkim-0002; b=JgjTqhz1NosdpYPkLsjY013q2b1+OSug1GZwFfv1cvXvB9JBEDsYjnUKscp/hLHlIC qg9P1I9Z8IK62larIdw3I1AS6tnsswbiGiOYeLc3De2NJZ54hzM41wj6wDfnC3pvsMLg zQ/Grl8PN5CAvkXdMuc5hh+tjsKYZbbS0vYXi53MSVsID7Hx6Ej8vieB33qZ1+bslNTN 4vKlDpp80WGNIepkhJCLxSVvdio3VsM75dIRj57uPe15xJnTcEV7ziHwMalBdWMjJ6Jg qz8oa2w99lAGx5SqkO1kuZSFvWDQ44hocIu/GT5HDQG3M2lTMhgJ/fR6GFmX+gNAw6ss l4Mw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; t=1691681407; s=strato-dkim-0002; d=strato.com; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=KQVk5SCYmHv5y7uDYq5UybN1nLJkASUjS9JdTj/31SU=; b=F+RiqcOYMwx6AR+7aWQV4D25a5szd89tH+JDqbsCXNJ1A7JSs6QxSgo6aTKPu9hLed P8Vu3T0EcQz7ne0x0O5DUzFMgMtuCTKHMFEpSm8hlPBeUBDl1THSGHkSa9N0HDY3ED9W FZAvAL1G/57rlpszv/5T7KjSvvpIPApAu9RdY02LC3943+qWVGPLGHLfFWiyAL+aNety x24cPdAohNCKhbMMlu7Uver68I9OojuVFVA8BE92R+K2LyloeroUjY6E9i9u1Kjpymis +bta8ZJA6lrbLnGtSbDi/O43MhthFfp5q1QgNLplV/wGZ3nGLk0fwai54BL8uyVK5QWV MT/Q== ARC-Authentication-Results: i=1; strato.com; arc=none; dkim=none X-RZG-CLASS-ID: mo01 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1691681407; s=strato-dkim-0002; d=clisp.org; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=KQVk5SCYmHv5y7uDYq5UybN1nLJkASUjS9JdTj/31SU=; b=RM2TBjs5SsThStyQC9l0NDwEjSlnAA1mUczdBQtdJWFqOvtVeYzDixL83Y/84bsXWx WCet+v8A6UWMyh22Cvb0D2PpH+lbgmwp8ae2DOrLRnNXRhWVw7A/tRIZIcP5MiYvEU99 XKo6Qbe3kMvm/M1lyddQw11QbjoFQr0F8pbRZrBQewHtpjN80dB8sLxiY8sIbfsJZraW qBDkMX+b/kr1x6X10QHqck4NS6MEuGcaoYxNHEwS6cJUgftbcS2z5nleNkDE70z5Yyes CvQ/3WJCbL4lruFdmWOeqjWA5J2zzaRlocYtnLF6+mcWH6y5wevagQ22fKzeh0nIXrYR F8Ag== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; t=1691681407; s=strato-dkim-0003; d=clisp.org; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=KQVk5SCYmHv5y7uDYq5UybN1nLJkASUjS9JdTj/31SU=; b=bMZazSXtd5JEnMn0SIzrps0jDTUTzHNevkPRV4kWyhE3rWz1NsngiUfVsKHWXh7fRR MssE+uPFGIJIkhF0D2Cw== X-RZG-AUTH: ":Ln4Re0+Ic/6oZXR1YgKryK8brlshOcZlIWs+iCP5vnk6shH0WWb0LN8XZoH94zq68+3cfpOS3/KAj5mP2WdWFYXnsMspu5Gi+A==" Original-Received: from nimes.localnet by smtp.strato.de (RZmta 49.6.6 AUTH) with ESMTPSA id x129eaz7AFU6wy9 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Thu, 10 Aug 2023 17:30:06 +0200 (CEST) In-Reply-To: Received-SPF: none client-ip=81.169.146.167; envelope-from=bruno@clisp.org; helo=mo4-p01-ob.smtp.rzone.de X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: bug-gnulib@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gnulib discussion list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnulib-bounces+gnu-bug-gnulib=m.gmane-mx.org@gnu.org Original-Sender: bug-gnulib-bounces+gnu-bug-gnulib=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.comp.lib.gnulib.bugs:48150 gmane.emacs.devel:308539 Archived-At: Natanael Copa wrote: > There are machines without RTC (Raspberry PI for example), and in > this case the time stamp may end up to be the same every reboot (if > correctly set up it should save the shutdown time for the reboot and set > time to this on next boot, but there is no guarantee). Indeed, on a Raspi with Raspbian (Debian derivative), /var/run/utmp contains a BOOT_TIME entry with time = 1970-01-01 00:00:05. Which is unusable. The clock gets set during the boot process, apparently through NTP. Then, some files get touched: /var/lib/systemd/timers/stamp-apt-daily.timer /var/lib/systemd/timers/stamp-apt-daily-upgrade.timer /var/lib/apt/daily_lock But I suspect that they may be touched at other moments than during boot. Therefore here, the workaround with the file time stamps does not work. But another workaround works: 2023-08-10 Bruno Haible readutmp: Fix the boot time returned on Raspbian. * lib/readutmp.c (read_utmp_from_file): When the time of the BOOT_TIME entry is very close to the Epoch, replace it with the time from the "runlevel"/"~" entry. diff --git a/lib/readutmp.c b/lib/readutmp.c index b344d8294d..e383531474 100644 --- a/lib/readutmp.c +++ b/lib/readutmp.c @@ -369,6 +369,12 @@ read_utmp_from_file (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf, SET_UTMP_ENT (); +# if defined __linux__ && !defined __ANDROID__ + bool file_is_utmp = (strcmp (file, UTMP_FILE) == 0); + /* Timestamp of the "runlevel" entry, if any. */ + struct timespec runlevel_ts = {0}; +# endif + void const *entry; while ((entry = GET_UTMP_ENT ()) != NULL) @@ -408,6 +414,13 @@ read_utmp_from_file (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf, struct UTMP_STRUCT_NAME const *ut = (struct UTMP_STRUCT_NAME const *) entry; # endif + struct timespec ts = + #if (HAVE_UTMPX_H ? 1 : HAVE_STRUCT_UTMP_UT_TV) + { .tv_sec = ut->ut_tv.tv_sec, .tv_nsec = ut->ut_tv.tv_usec * 1000 }; + #else + { .tv_sec = ut->ut_time, .tv_nsec = 0 }; + #endif + a = add_utmp (a, options, UT_USER (ut), strnlen (UT_USER (ut), UT_USER_SIZE), #if (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_ID : HAVE_STRUCT_UTMP_UT_ID) @@ -431,11 +444,7 @@ read_utmp_from_file (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf, #else 0, #endif - #if (HAVE_UTMPX_H ? 1 : HAVE_STRUCT_UTMP_UT_TV) - (struct timespec) { .tv_sec = ut->ut_tv.tv_sec, .tv_nsec = ut->ut_tv.tv_usec * 1000 }, - #else - (struct timespec) { .tv_sec = ut->ut_time, .tv_nsec = 0 }, - #endif + ts, #if (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_SESSION : HAVE_STRUCT_UTMP_UT_SESSION) ut->ut_session, #else @@ -443,6 +452,12 @@ read_utmp_from_file (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf, #endif UT_EXIT_E_TERMINATION (ut), UT_EXIT_E_EXIT (ut) ); +# if defined __linux__ && !defined __ANDROID__ + if (file_is_utmp + && memcmp (UT_USER (ut), "runlevel", strlen ("runlevel") + 1) == 0 + && memcmp (ut->ut_line, "~", strlen ("~") + 1) == 0) + runlevel_ts = ts; +# endif } END_UTMP_ENT (); @@ -450,9 +465,19 @@ read_utmp_from_file (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf, # if defined __linux__ && !defined __ANDROID__ /* On Alpine Linux, UTMP_FILE is not filled. It is always empty. So, fake a BOOT_TIME entry, by getting the time stamp of a file that - gets touched only during the boot process. */ + gets touched only during the boot process. + + On Raspbian, which runs on hardware without a real-time clock, during boot, + 1. the clock gets set to 1970-01-01 00:00:00, + 2. an entry gets written into /var/run/utmp, with ut_type = BOOT_TIME, + ut_user = "reboot", ut_line = "~", time = 1970-01-01 00:00:05 or so, + 3. the clock gets set to a correct value through NTP, + 4. an entry gets written into /var/run/utmp, with + ut_user = "runlevel", ut_line = "~", time = correct value. + In this case, copy the time from the "runlevel" entry to the "reboot" + entry. */ if ((options & (READ_UTMP_USER_PROCESS | READ_UTMP_NO_BOOT_TIME)) == 0 - && strcmp (file, UTMP_FILE) == 0) + && file_is_utmp) { bool have_boot_time = false; for (idx_t i = 0; i < a.filled; i++) @@ -460,12 +485,16 @@ read_utmp_from_file (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf, struct gl_utmp *ut = &a.utmp[i]; if (UT_TYPE_BOOT_TIME (ut)) { + /* Workaround for Raspbian: */ + if (ut->ut_ts.tv_sec <= 60 && runlevel_ts.tv_sec != 0) + ut->ut_ts = runlevel_ts; have_boot_time = true; break; } } if (!have_boot_time) { + /* Workaround for Alpine Linux: */ const char * const boot_touched_files[] = { "/var/lib/systemd/random-seed", /* seen on distros with systemd */