From: Lennart Poettering Date: Sat, 21 Jan 2012 02:15:54 +0000 (+0100) Subject: util: open the first RTC that has hctosys=1 set X-Git-Tag: v39~20 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=51122dc9e36cdafe76a07d1ddf1a3a7e4726bb7b;p=systemd util: open the first RTC that has hctosys=1 set --- diff --git a/TODO b/TODO index 2c7e2b02..3b4d45fb 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 fbc37c4f..de5feeb8 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 6acfcc83..114b24c3 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