Commit 67fb4482 authored by Kay Sievers's avatar Kay Sievers

always unconditionally create /dev/rtc and use it internally

Partially revert 2b3c81b0, which
tried to avoid inconsistent rules about when and how to create the
/dev/rtc symlink.

Instead of conditionally or not creating the /dev/rtc link at all,
now always create it with additional and more reliable udev rules.

First try to find the "system rtc" with the hctosys flag, if this
is not found, fall back to create the link for /dev/rtc0.

Our code now never actively searches for the "system rtc" it can
always use /dev/rtc.
parent c3a170f3
......@@ -2,6 +2,10 @@
SUBSYSTEM=="virtio-ports", KERNEL=="vport*", ATTR{name}=="?*", SYMLINK+="virtio-ports/$attr{name}"
# select "system RTC" or just use the first one
SUBSYSTEM=="rtc", ATTR{hctosys}=="1", SYMLINK+="rtc"
SUBSYSTEM=="rtc", KERNEL=="rtc0", SYMLINK+="rtc", OPTIONS+="link_priority=-100"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb"
SUBSYSTEM=="input", ENV{ID_INPUT}=="", IMPORT{builtin}="input_id"
ENV{MODALIAS}!="", IMPORT{builtin}="hwdb --subsystem=$env{SUBSYSTEM}"
......
......@@ -43,89 +43,13 @@
#include "hwclock.h"
#include "fileio.h"
static int rtc_open(int flags) {
int fd;
DIR *d;
/*
* Some "chaotic platforms" have multiple RTCs and we need to
* find the "system RTC", which is in some setups /dev/rtc1.
*
* First, we try to find the RTC which has hctosys=1 set. If we
* don't find any we just take the first RTC that exists at all,
* then try to open /dev/rtc0.
*/
d = opendir("/sys/class/rtc");
if (!d)
goto fallback;
for (;;) {
char *p, *v;
struct dirent *de;
union dirent_storage buf;
int r;
r = readdir_r(d, &buf.de, &de);
if (r != 0)
goto fallback;
if (!de)
goto fallback;
if (ignore_file(de->d_name))
continue;
p = strjoin("/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);
if (!p) {
closedir(d);
return -ENOMEM;
}
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 = rtc_open(O_RDONLY|O_CLOEXEC);
fd = open("/dev/rtc", O_RDONLY|O_CLOEXEC);
if (fd < 0)
return -errno;
......@@ -149,7 +73,7 @@ int hwclock_set_time(const struct tm *tm) {
assert(tm);
fd = rtc_open(O_RDONLY|O_CLOEXEC);
fd = open("/dev/rtc", O_RDONLY|O_CLOEXEC);
if (fd < 0)
return -errno;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment