summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2012-01-21 03:15:54 +0100
committerLennart Poettering <lennart@poettering.net>2012-01-21 03:15:54 +0100
commit51122dc9e36cdafe76a07d1ddf1a3a7e4726bb7b (patch)
treec5ecbaf984c34e08489db01683971ae5712ce1d3
parent05aa9edde0f9f4077b8120389c93cb0134eda9c5 (diff)
util: open the first RTC that has hctosys=1 set
-rw-r--r--TODO2
-rw-r--r--src/util.c69
-rw-r--r--src/util.h2
3 files changed, 69 insertions, 4 deletions
diff --git a/TODO b/TODO
index 2c7e2b02f0..3b4d45fb7c 100644
--- a/TODO
+++ b/TODO
@@ -23,8 +23,6 @@ Features:
* document the exit codes when services fail before they are exec()ed
-* use the rtc which has: /sys/class/rtc/*/hctosys == "1" as the system RTC
-
* rework namespace support, don't use pivot_root, and mount things after creating the namespace, not before
* systemctl journal command
diff --git a/src/util.c b/src/util.c
index fbc37c4f0c..de5feeb8d0 100644
--- a/src/util.c
+++ b/src/util.c
@@ -5155,13 +5155,78 @@ int hwclock_reset_localtime_delta(void) {
return 0;
}
+int rtc_open(int flags) {
+ int fd;
+ DIR *d;
+
+ /* We open the first RTC which has hctosys=1 set. If we don't
+ * find any we just take the first one */
+
+ d = opendir("/sys/class/rtc");
+ if (!d)
+ goto fallback;
+
+ for (;;) {
+ char *p, *v;
+ struct dirent buf, *de;
+ int r;
+
+ r = readdir_r(d, &buf, &de);
+ if (r != 0)
+ goto fallback;
+
+ if (!de)
+ goto fallback;
+
+ if (ignore_file(de->d_name))
+ continue;
+
+ p = join("/sys/class/rtc/", de->d_name, "/hctosys", NULL);
+ if (!p) {
+ closedir(d);
+ return -ENOMEM;
+ }
+
+ r = read_one_line_file(p, &v);
+ free(p);
+
+ if (r < 0)
+ continue;
+
+ r = parse_boolean(v);
+ free(v);
+
+ if (r <= 0)
+ continue;
+
+ p = strappend("/dev/", de->d_name);
+ fd = open(p, flags);
+ free(p);
+
+ if (fd >= 0) {
+ closedir(d);
+ return fd;
+ }
+ }
+
+fallback:
+ if (d)
+ closedir(d);
+
+ fd = open("/dev/rtc0", flags);
+ if (fd < 0)
+ return -errno;
+
+ return fd;
+}
+
int hwclock_get_time(struct tm *tm) {
int fd;
int err = 0;
assert(tm);
- fd = open("/dev/rtc0", O_RDONLY|O_CLOEXEC);
+ fd = rtc_open(O_RDONLY|O_CLOEXEC);
if (fd < 0)
return -errno;
@@ -5185,7 +5250,7 @@ int hwclock_set_time(const struct tm *tm) {
assert(tm);
- fd = open("/dev/rtc0", O_RDONLY|O_CLOEXEC);
+ fd = rtc_open(O_RDONLY|O_CLOEXEC);
if (fd < 0)
return -errno;
diff --git a/src/util.h b/src/util.h
index 6acfcc8373..114b24c3e7 100644
--- a/src/util.h
+++ b/src/util.h
@@ -529,4 +529,6 @@ int fd_wait_for_event(int fd, int event);
void* memdup(const void *p, size_t l);
+int rtc_open(int flags);
+
#endif