]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
rtc: factor out RTC_Linux_ReadTimeAfterInterrupt
authorAhmad Fatoum <a.fatoum@pengutronix.de>
Wed, 17 Jul 2024 11:00:39 +0000 (13:00 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Wed, 4 Dec 2024 13:54:04 +0000 (14:54 +0100)
We have code to read time after an RTC's 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 06e19308302dacbb7291f63380aef61eed76d6dc..7e3b904dcd853baf22d48d7c593831b73758a140 100644 (file)
@@ -785,11 +785,31 @@ RTC_Linux_CheckInterrupt(int fd)
   return (data & RTC_UF) == RTC_UF;
 }
 
+time_t
+RTC_Linux_ReadTimeAfterInterrupt(int fd, int utc, struct timespec *sys_time_cooked)
+{
+  int status;
+  struct rtc_time rtc_raw;
+
+  /* Read RTC time, sandwiched between two polls of the system clock
+     so we can bound any error */
+
+  SCH_GetLastEventTime(sys_time_cooked, NULL, NULL);
+
+  status = ioctl(fd, RTC_RD_TIME, &rtc_raw);
+  if (status < 0) {
+    LOG(LOGS_ERR, "Could not read time from %s : %s", CNF_GetRtcDevice(), strerror(errno));
+    return -1;
+  }
+
+  /* Convert RTC time into a struct timespec */
+  return t_from_rtc(&rtc_raw, utc);
+}
+
 static void
 read_from_device(int fd_, int event, void *any)
 {
   struct timespec sys_time;
-  struct rtc_time rtc_raw;
   int status, error = 0;
   time_t rtc_t;
 
@@ -801,22 +821,12 @@ read_from_device(int fd_, int event, void *any)
     fd = -1;
     return;
   } else if (status == 0) {
+    /* Wait for the next interrupt, this one may be bogus */
     return;
   }
 
-  SCH_GetLastEventTime(&sys_time, NULL, NULL);
-
-  status = ioctl(fd, RTC_RD_TIME, &rtc_raw);
-  if (status < 0) {
-    LOG(LOGS_ERR, "Could not read time from %s : %s", CNF_GetRtcDevice(), strerror(errno));
-    error = 1;
-    goto turn_off_interrupt;
-  }
-
-  /* Convert RTC time into a struct timespec */
-  rtc_t = t_from_rtc(&rtc_raw, rtc_on_utc);
-
-  if (rtc_t == (time_t)(-1)) {
+  rtc_t = RTC_Linux_ReadTimeAfterInterrupt(fd, rtc_on_utc, &sys_time);
+  if (rtc_t == (time_t)-1) {
     error = 1;
     goto turn_off_interrupt;
   }
index 1f67ba8044809178406e8759d6239468c15992a5..952736d96177a61c6da70438d6fa90b05615e9b2 100644 (file)
@@ -44,5 +44,7 @@ extern void RTC_Linux_CycleLogFile(void);
 
 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);
 
 #endif /* _GOT_RTC_LINUX_H */