changeset 1668:7e3372a47248 draft

fix hwclock's rtc selection For systems using /dev/rtcN, /dev/rtc0 isn't necessarily the RTC that's used to provide the system time at boot time. We need to search for the RTC whose /sys/class/rtc/rtcN/hctosys contains "1".
author Elliott Hughes <enh@google.com>
date Tue, 20 Jan 2015 16:03:29 -0600
parents aa6487c2c5f8
children e3d20011b68e
files toys/pending/hwclock.c
diffstat 1 files changed, 31 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/toys/pending/hwclock.c	Tue Jan 20 15:52:41 2015 -0600
+++ b/toys/pending/hwclock.c	Tue Jan 20 16:03:29 2015 -0600
@@ -30,13 +30,43 @@
   int utc;
 )
 
+static int check_hctosys(struct dirtree* node)
+{
+  FILE *fp;
+
+  if (!node->parent) return DIRTREE_RECURSE;
+
+  snprintf(toybuf, sizeof(toybuf), "/sys/class/rtc/%s/hctosys", node->name);
+  fp = fopen(toybuf, "r");
+  if (fp) {
+    int hctosys = 0;
+    int items = fscanf(fp, "%d", &hctosys);
+    fclose(fp);
+    if (items == 1 && hctosys == 1) {
+      snprintf(toybuf, sizeof(toybuf), "/dev/%s", node->name);
+      TT.fname = toybuf;
+      return DIRTREE_ABORT;
+    }
+  }
+  return 0;
+}
+
+// Search /sys/class/rtc for the RTC that the system clock is set from.
+// See the kernel's Documentation/rtc.txt.
+static int open_wall_clock_rtc(int flag)
+{
+  TT.fname = NULL;
+  dirtree_read("/sys/class/rtc", check_hctosys);
+  return TT.fname ? xopen(TT.fname, flag) : -1;
+}
+
 static int rtc_open(int flag)
 {
   if (!TT.fname) {
     int fd; 
 
     if ((fd = open((TT.fname = "/dev/rtc"), flag)) != -1) return fd;
-    else if ((fd = open((TT.fname = "/dev/rtc0"), flag)) != -1) return fd;
+    else if ((fd = open_wall_clock_rtc(flag)) != -1) return fd;
     else TT.fname = "/dev/misc/rtc";
   }
   return xopen(TT.fname, flag);