From b858433a79633bdef1ebea7d5ea4cc2585dcbaab Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 19 Apr 2024 19:20:40 +0200
Subject: [PATCH 1159/1160] timedate: handle gracefully if RTC lost time
because of power loss
Apparently some RTC drivers return EINVAL in that case when we try to
read it. Handle that reasonably gracefully.
Fixes: #31854
(cherry picked from commit 5c81de98fcb533c0889ed6c6f6cd8640bb626360)
src/shared/clock-util.c | 7 ++++---
src/timedate/timedated.c | 2 ++
2 files changed, 6 insertions(+), 3 deletions(-)
@@ -27,10 +27,11 @@ int clock_get_hwclock(struct tm *tm) {
if (fd < 0)
return -errno;
- /* This leaves the timezone fields of struct tm
- * uninitialized! */
+ /* This leaves the timezone fields of struct tm uninitialized! */
if (ioctl(fd, RTC_RD_TIME, tm) < 0)
- return -errno;
+ /* Some drivers return -EINVAL in case the time could not be kept, i.e. power loss
+ * happened. Let's turn that into a clearly recognizable error */
+ return errno == EINVAL ? -ENODATA : -errno;
/* We don't know daylight saving, so we reset this in order not
* to confuse mktime(). */
@@ -584,6 +584,8 @@ static int property_get_rtc_time(
log_warning("/dev/rtc is busy. Is somebody keeping it open continuously? That's not a good idea... Returning a bogus RTC timestamp.");
else if (r == -ENOENT)
log_debug("/dev/rtc not found.");
+ else if (r == -ENODATA)
+ log_debug("/dev/rtc has no valid time, power loss probably occurred?");
else if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to read RTC: %m");
else
--
2.33.0