s6-svstat up, down and ready time not correct after system timestamp update.

From: Nikita Orlov <nikitos1550_at_yandex.ru>
Date: Tue, 18 Jul 2023 18:23:01 +0300

Hello!

I am setuping s6 for managing services on mine Linux embedded system.
Everything is fine. But I faced issue related to system datetime change.
My system does not have RTC, but it has GNSS module (managed by gpsd).
After GNSS get the location and time chronyd service update system time.

s6-svstat output after system start -> sys-dbus: up (pid 17428) 1
seconds, ready 1 seconds
s6-svstat output after system time changed by chronyd -> sys-dbus: up
(pid 17428) 106591835 seconds, ready 106591835 seconds

I found that s6-svstat uses CLOCK_REALTIME and I think it will be more
robust to use CLOCK_MONOTONIC.
I made brief patch (assumed to be used only in my project) for skalibs
and s6 (patch is below).

Is the patch correct? Maybe I miss something (maybe some other utils
also need to be patched).
Maybe I can expect to get some proper patch from somebody experienced,
who is much more familiar then I in skalibs+s6.
Also maybe authors will recognize my issue as something that need to be
corrected in the upstream.

diff -uraN skalibs-2.13.1.1/src/libstddjb/sysclock_get.c
skalibs-2.13.1.1-b/src/libstddjb/sysclock_get.c
--- skalibs-2.13.1.1/src/libstddjb/sysclock_get.c    2021-08-10
21:42:57.000000000 +0300
+++ skalibs-2.13.1.1-b/src/libstddjb/sysclock_get.c    2023-07-18
10:23:17.969707497 +0300
_at__at_ -17,6 +17,16 _at__at_
    return 1 ;
  }

+int uptimeclock_get (tain *a)
+{
+  tain aa ;
+  struct timespec now ;
+  if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) return 0 ;
+  if (!tain_from_timespec(&aa, &now)) return 0 ;
+  tain_add(a, &aa, &tain_nano500) ;
+  return 1 ;
+}
+
  #else

  #include <sys/time.h>
diff -uraN skalibs-2.13.1.1/src/libstddjb/tain_wallclock_read.c
skalibs-2.13.1.1-b/src/libstddjb/tain_wallclock_read.c
--- skalibs-2.13.1.1/src/libstddjb/tain_wallclock_read.c 2021-08-10
21:42:57.000000000 +0300
+++ skalibs-2.13.1.1-b/src/libstddjb/tain_wallclock_read.c 2023-07-18
10:24:03.065521651 +0300
_at__at_ -8,3 +8,11 _at__at_
    if (!sysclock_get(&aa)) return 0 ;
    return tain_from_sysclock(a, &aa) ;
  }
+
+int tain_uptime_read (tain *a)
+{
+  tain aa ;
+  if (!uptimeclock_get(&aa)) return 0 ;
+  return tain_from_sysclock(a, &aa) ;
+}
+
diff -uraN skalibs-2.13.1.1/src/include/skalibs/tai.h
skalibs-2.13.1.1-b/src/include/skalibs/tai.h
--- skalibs-2.13.1.1/src/include/skalibs/tai.h  2021-08-18
17:23:53.000000000 +0300
+++ skalibs-2.13.1.1-b/src/include/skalibs/tai.h        2023-07-18
10:32:42.363382534 +0300
_at__at_ -94,8 +94,11 _at__at_
  extern int tain_from_sysclock (tain *, tain const *) ;
  extern int sysclock_from_tain (tain *, tain const *) ;
  extern tain_clockread_func sysclock_get ;
+extern tain_clockread_func uptimeclock_get ;
  extern tain_clockread_func tain_wallclock_read ;
+extern tain_clockread_func tain_uptime_read ;
  #define tain_wallclock_read_g() tain_wallclock_read(&STAMP)
+#define tain_uptime_read_g() tain_uptime_read(&STAMP)
  extern int tain_stopwatch_init (tain *, clock_t, tain *) ;
  extern int tain_stopwatch_read (tain *, clock_t, tain const *) ;
  #define tain_stopwatch_read_g(cl, offset) tain_stopwatch_read(&STAMP,
(cl), offset)

diff -uraN s6-2.11.3.2/src/supervision/s6-permafailon.c
s6-2.11.3.2-b/src/supervision/s6-permafailon.c
--- s6-2.11.3.2/src/supervision/s6-permafailon.c    2022-11-29
13:09:35.000000000 +0300
+++ s6-2.11.3.2-b/src/supervision/s6-permafailon.c    2023-07-18
10:28:06.500518674 +0300
_at__at_ -99,7 +99,7 _at__at_
      tain_uint(&mintime, seconds) ;
      {
        tain now ;
-      tain_wallclock_read(&now) ;
+      tain_uptime_read(&now) ;
        tain_sub(&mintime, &now, &mintime) ;
      }

diff -uraN s6-2.11.3.2/src/supervision/s6-supervise.c
s6-2.11.3.2-b/src/supervision/s6-supervise.c
--- s6-2.11.3.2/src/supervision/s6-supervise.c    2023-02-06
19:52:23.000000000 +0300
+++ s6-2.11.3.2-b/src/supervision/s6-supervise.c    2023-07-18
10:26:55.140812645 +0300
_at__at_ -130,7 +130,7 _at__at_
    state = DOWN ;
    if (tai_sec(tain_secp(&nextstart))) deadline = nextstart ;
    else tain_addsec_g(&deadline, 1) ;
-  tain_wallclock_read(&status.readystamp) ;
+  tain_uptime_read(&status.readystamp) ;
    announce() ;
    ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, s, n) ;
  }
_at__at_ -386,7 +386,7 _at__at_
    state = UP ;
    status.pid = pid ;
    status.flagready = 0 ;
-  tain_wallclock_read(&status.stamp) ;
+  tain_uptime_read(&status.stamp) ;
    announce() ;
    ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, "u", 1) ;
    return ;
_at__at_ -458,7 +458,7 _at__at_
    status.flagpaused = 0 ;
    status.flagready = 0 ;
    gflags.dying = 0 ;
-  tain_wallclock_read(&status.stamp) ;
+  tain_uptime_read(&status.stamp) ;
    if (notifyfd >= 0)
    {
      fd_close(notifyfd) ;
_at__at_ -642,7 +642,7 _at__at_
      if (r > 0 && memchr(buf, '\n', r))
      {
        tain_addsec_g(&nextstart, 1) ;
-      tain_wallclock_read(&status.readystamp) ;
+      tain_uptime_read(&status.readystamp) ;
        status.flagready = 1 ;
        announce() ;
        ftrigw_notifyb_nosig(S6_SUPERVISE_EVENTDIR, "U", 1) ;
diff -uraN s6-2.11.3.2/src/supervision/s6-svstat.c
s6-2.11.3.2-b/src/supervision/s6-svstat.c
--- s6-2.11.3.2/src/supervision/s6-svstat.c     2022-11-29
13:09:35.000000000 +0300
+++ s6-2.11.3.2-b/src/supervision/s6-svstat.c   2023-07-18
10:35:09.966774690 +0300
_at__at_ -272,7 +272,7 _at__at_
    if (!s6_svstatus_read(argv[0], &status))
      strerr_diefu2sys(111, "read status for ", argv[0]) ;

-  tain_wallclock_read_g() ;
+  tain_uptime_read_g() ;
    if (tain_future(&status.stamp)) tain_copynow(&status.stamp) ;

    {
Received on Tue Jul 18 2023 - 17:23:01 CEST

This archive was generated by hypermail 2.4.0 : Tue Jul 18 2023 - 17:23:40 CEST