]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
rtc: factor out RTC_Linux_ReadTimeNow
authorAhmad Fatoum <a.fatoum@pengutronix.de>
Mon, 22 Jul 2024 15:46:44 +0000 (17:46 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Wed, 4 Dec 2024 14:24:48 +0000 (15:24 +0100)
We have code to read RTC time and handle the error associated with
having no UIE interrupt, which we currently use as part of maintaining
the correction file.

In a later commit, we will need the same functionality for using the RTC
as reference clock, so export the function and give it a descriptive
name appropriate for a globally visible function.

rtc_linux.c
rtc_linux.h

index 7e3b904dcd853baf22d48d7c593831b73758a140..849bca053706270c0e9f21d16010a6541cfdfb8a 100644 (file)
@@ -929,6 +929,28 @@ RTC_Linux_WriteParameters(void)
   return(retval);
 }
 
+time_t
+RTC_Linux_ReadTimeNow(int fd, int utc, struct timespec *old_sys_time)
+{
+  struct rtc_time rtc_raw, rtc_raw_retry;
+  int status;
+
+  /* Retry reading the RTC until both read attempts give the same sec value.
+     This way the race condition is prevented that the RTC has updated itself
+     during the first read operation. */
+  do {
+    status = ioctl(fd, RTC_RD_TIME, &rtc_raw);
+    if (status >= 0) {
+      status = ioctl(fd, RTC_RD_TIME, &rtc_raw_retry);
+    }
+  } while (status >= 0 && rtc_raw.tm_sec != rtc_raw_retry.tm_sec);
+
+  /* Read system clock */
+  LCL_ReadCookedTime(old_sys_time, NULL);
+
+  return status >= 0 ? t_from_rtc(&rtc_raw, utc) : -1;
+}
+
 /* ================================================== */
 /* Try to set the system clock from the RTC, in the same manner as
    /sbin/hwclock -s would do.  We're not as picky about OS version
@@ -938,11 +960,10 @@ RTC_Linux_WriteParameters(void)
 int
 RTC_Linux_TimePreInit(time_t driftfile_time)
 {
-  int fd, status;
-  struct rtc_time rtc_raw, rtc_raw_retry;
   time_t rtc_t;
   double accumulated_error, sys_offset;
   struct timespec new_sys_time, old_sys_time;
+  int fd;
 
   coefs_file_name = CNF_GetRtcFile();
 
@@ -955,58 +976,40 @@ RTC_Linux_TimePreInit(time_t driftfile_time)
     return 0; /* Can't open it, and won't be able to later */
   }
 
-  /* Retry reading the rtc until both read attempts give the same sec value.
-     This way the race condition is prevented that the RTC has updated itself
-     during the first read operation. */
-  do {
-    status = ioctl(fd, RTC_RD_TIME, &rtc_raw);
-    if (status >= 0) {
-      status = ioctl(fd, RTC_RD_TIME, &rtc_raw_retry);
-    }
-  } while (status >= 0 && rtc_raw.tm_sec != rtc_raw_retry.tm_sec);
-
-  /* Read system clock */
-  LCL_ReadCookedTime(&old_sys_time, NULL);
+  rtc_t = RTC_Linux_ReadTimeNow(fd, rtc_on_utc, &old_sys_time);
 
   close(fd);
 
-  if (status >= 0) {
-    /* Convert to seconds since 1970 */
-    rtc_t = t_from_rtc(&rtc_raw, rtc_on_utc);
-
-    if (rtc_t != (time_t)(-1)) {
+  if (rtc_t != (time_t)(-1)) {
 
-      /* Work out approximatation to correct time (to about the
-         nearest second) */
-      if (valid_coefs_from_file) {
-        accumulated_error = file_ref_offset +
-          (rtc_t - file_ref_time) * 1.0e-6 * file_rate_ppm;
-      } else {
-        accumulated_error = 0.0;
-      }
+    /* Work out approximation to correct time (to about the
+       nearest second) */
+    if (valid_coefs_from_file) {
+      accumulated_error = file_ref_offset +
+        (rtc_t - file_ref_time) * 1.0e-6 * file_rate_ppm;
+    } else {
+      accumulated_error = 0.0;
+    }
 
-      /* Correct time */
+    /* Correct time */
 
-      new_sys_time.tv_sec = rtc_t;
-      /* Average error in the RTC reading */
-      new_sys_time.tv_nsec = 500000000;
+    new_sys_time.tv_sec = rtc_t;
+    /* Average error in the RTC reading */
+    new_sys_time.tv_nsec = 500000000;
 
-      UTI_AddDoubleToTimespec(&new_sys_time, -accumulated_error, &new_sys_time);
+    UTI_AddDoubleToTimespec(&new_sys_time, -accumulated_error, &new_sys_time);
 
-      if (new_sys_time.tv_sec < driftfile_time) {
-        LOG(LOGS_WARN, "RTC time before last driftfile modification (ignored)");
-        return 0;
-      }
+    if (new_sys_time.tv_sec < driftfile_time) {
+      LOG(LOGS_WARN, "RTC time before last driftfile modification (ignored)");
+      return 0;
+    }
 
-      sys_offset = UTI_DiffTimespecsToDouble(&old_sys_time, &new_sys_time);
+    sys_offset = UTI_DiffTimespecsToDouble(&old_sys_time, &new_sys_time);
 
-      /* Set system time only if the step is larger than 1 second */
-      if (fabs(sys_offset) >= 1.0) {
-        if (LCL_ApplyStepOffset(sys_offset))
-          LOG(LOGS_INFO, "System time set from RTC");
-      }
-    } else {
-      return 0;
+    /* Set system time only if the step is larger than 1 second */
+    if (fabs(sys_offset) >= 1.0) {
+      if (LCL_ApplyStepOffset(sys_offset))
+        LOG(LOGS_INFO, "System time set from RTC");
     }
   } else {
     return 0;
index 952736d96177a61c6da70438d6fa90b05615e9b2..c48b294d8547182740e5f8b6334c9e4ccd69bc53 100644 (file)
@@ -46,5 +46,7 @@ extern int RTC_Linux_SwitchInterrupt(int fd, int on_off);
 extern int RTC_Linux_CheckInterrupt(int fd);
 extern time_t RTC_Linux_ReadTimeAfterInterrupt(int fd, int utc,
                                                struct timespec *sys_time_cooked);
+extern time_t RTC_Linux_ReadTimeNow(int fd, int utc,
+                                    struct timespec *sys_time_cooked);
 
 #endif /* _GOT_RTC_LINUX_H */