plugins: add configure support for overriding RTC fallback datetime

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2023-04-10 16:35:42 +02:00
parent 1f4acb322a
commit 42ef3d3cf7
2 changed files with 38 additions and 8 deletions
+13
View File
@@ -159,6 +159,10 @@ AC_ARG_WITH(plugin-path,
AS_HELP_STRING([--with-plugin-path=DIR], [Search path for external plugins, default /usr/lib/finit/plugins:/usr/local/lib/finit/plugins]), AS_HELP_STRING([--with-plugin-path=DIR], [Search path for external plugins, default /usr/lib/finit/plugins:/usr/local/lib/finit/plugins]),
[plugin_path=$withval], [plugin_path=yes]) [plugin_path=$withval], [plugin_path=yes])
AC_ARG_WITH(rtc-date,
AS_HELP_STRING([--with-rtc-date=DATE], [If RTC date/time is too old, restore to DATE, format "YYYY-MM-DD HH:MM", default "2000-01-01 00:00"]),
[rtc_date=$withval], [rtc_date=no])
### Enable features ########################################################################### ### Enable features ###########################################################################
# Create config.h from selected features and fallback defaults # Create config.h from selected features and fallback defaults
@@ -242,6 +246,10 @@ AS_IF([test "x$with_random_seed" != "xno"], [
AC_EXPAND_DIR(random_path, "$random_seed") AC_EXPAND_DIR(random_path, "$random_seed")
AC_DEFINE_UNQUOTED(RANDOMSEED, "$random_path", [Improve random at boot by seeding it with sth from before.])]) AC_DEFINE_UNQUOTED(RANDOMSEED, "$random_path", [Improve random at boot by seeding it with sth from before.])])
AS_IF([test "x$rtc_date" != "xno"], [
AC_DEFINE(RTC_TIMESTAMP_CUSTOM, "$rtc_date", [Custom RTC restore date, default: 2000-01-01 00:00])], [
rtc_date=""])
AS_IF([test "x$with_keventd" != "xno"], [with_keventd=yes]) AS_IF([test "x$with_keventd" != "xno"], [with_keventd=yes])
AS_IF([test "x$with_sulogin" != "xno"], [with_sulogin=yes]) AS_IF([test "x$with_sulogin" != "xno"], [with_sulogin=yes])
@@ -302,6 +310,10 @@ AC_DEFINE_UNQUOTED(SAMPLE_CONF, "$sample_conf", [Finit sameple.conf for initctl
AS_IF([test "$heading" = ""], [heading="<DEFAULT>"]) AS_IF([test "$heading" = ""], [heading="<DEFAULT>"])
AS_IF([test "$heading" = "no"], [heading="<NONE>"]) AS_IF([test "$heading" = "no"], [heading="<NONE>"])
RTC_DATE=$rtc_date
AS_IF([test "$rtc_date" = ""], [RTC_DATE="<DEFAULT>"])
AS_IF([test "$rtc_date" = "no"], [RTC_DATE="<DEFAULT>"])
# Generate all files # Generate all files
AC_OUTPUT AC_OUTPUT
@@ -326,6 +338,7 @@ cat <<EOF
Behavior: Behavior:
Boot heading..........: $heading Boot heading..........: $heading
Plugins...............: $plugins Plugins...............: $plugins
RTC restore date......: $RTC_DATE
Optional features: Optional features:
Install doc/..........: $enable_doc Install doc/..........: $enable_doc
+25 -8
View File
@@ -21,6 +21,8 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include "config.h"
#include <time.h> #include <time.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <linux/rtc.h> #include <linux/rtc.h>
@@ -35,7 +37,13 @@
#include "plugin.h" #include "plugin.h"
/* Kernel RTC driver validates against this date for sanity check */ /* Kernel RTC driver validates against this date for sanity check */
#define RTC_TIMESTAMP_BEGIN_2000 946684800LL /* 2000-01-01 00:00:00 */ #define RTC_TIMESTAMP_BEGIN_2000 "2000-01-01 00:00:00"
#ifdef RTC_TIMESTAMP_CUSTOM
static char *rtc_timestamp = RTC_TIMESTAMP_CUSTOM;
#else
static char *rtc_timestamp = RTC_TIMESTAMP_BEGIN_2000;
#endif
static time_t rtc_date_fallback = 946684800LL;
static void tz_set(char *tz, size_t len) static void tz_set(char *tz, size_t len)
{ {
@@ -99,10 +107,10 @@ static void rtc_save(void *arg)
tz_set(tz, sizeof(tz)); tz_set(tz, sizeof(tz));
rc = gettimeofday(&tv, NULL); rc = gettimeofday(&tv, NULL);
if (rc < 0 || tv.tv_sec < RTC_TIMESTAMP_BEGIN_2000) { if (rc < 0 || tv.tv_sec < rtc_date_fallback) {
print_desc(NULL, "System clock invalid, not saving to RTC"); print_desc(NULL, "System clock invalid, not saving to RTC");
invalid: invalid:
logit(LOG_ERR, "System clock invalid, before 2000-01-01 00:00, not saving to RTC"); logit(LOG_ERR, "System clock invalid, before %s, not saving to RTC", rtc_timestamp);
rc = 2; rc = 2;
goto out; goto out;
} }
@@ -136,8 +144,10 @@ static void rtc_restore(void *arg)
} }
fd = rtc_open(); fd = rtc_open();
if (fd < 0) if (fd < 0) {
logit(LOG_NOTICE, "System has no RTC (missing driver?), skipping restore.");
return; return;
}
tz_set(tz, sizeof(tz)); tz_set(tz, sizeof(tz));
if (ioctl(fd, RTC_RD_TIME, &tm) < 0) { if (ioctl(fd, RTC_RD_TIME, &tm) < 0) {
@@ -151,7 +161,7 @@ static void rtc_restore(void *arg)
invalid: invalid:
logit(LOG_ERR, "Failed restoring system clock from RTC."); logit(LOG_ERR, "Failed restoring system clock from RTC.");
if (EINVAL == errno) if (EINVAL == errno)
logit(LOG_ERR, "RTC time is too old (before 2000-01-01 00:00)"); logit(LOG_ERR, "RTC time is too old (before %s)", rtc_timestamp);
else if (ENOENT == errno) else if (ENOENT == errno)
logit(LOG_ERR, "RTC has no previously saved (valid) time."); logit(LOG_ERR, "RTC has no previously saved (valid) time.");
else else
@@ -162,18 +172,18 @@ static void rtc_restore(void *arg)
goto out; goto out;
/* Attempt to set RTC to a sane value ... */ /* Attempt to set RTC to a sane value ... */
tv.tv_sec = RTC_TIMESTAMP_BEGIN_2000; tv.tv_sec = rtc_date_fallback;
if (!gmtime_r(&tv.tv_sec, &tm)) if (!gmtime_r(&tv.tv_sec, &tm))
goto out; goto out;
logit(LOG_NOTICE, "Resetting RTC to kernel default, 2000-01-01 00:00."); logit(LOG_NOTICE, "Resetting RTC to kernel default, %s.", rtc_timestamp);
rc = 2; rc = 2;
} }
print_desc(NULL, "Restoring system clock (UTC) from RTC"); print_desc(NULL, "Restoring system clock (UTC) from RTC");
tm.tm_isdst = -1; /* Use tzdata to figure it out, please. */ tm.tm_isdst = -1; /* Use tzdata to figure it out, please. */
tv.tv_sec = mktime(&tm); tv.tv_sec = mktime(&tm);
if (tv.tv_sec < RTC_TIMESTAMP_BEGIN_2000) { if (tv.tv_sec < rtc_date_fallback) {
errno = EINVAL; errno = EINVAL;
goto invalid; goto invalid;
} }
@@ -199,6 +209,13 @@ static plugin_t plugin = {
PLUGIN_INIT(plugin_init) PLUGIN_INIT(plugin_init)
{ {
struct tm tm = { 0 };
if (!strptime(rtc_timestamp, "%Y-%m-%d %H:%M", &tm))
rtc_date_fallback = mktime(&tm);
else
rtc_timestamp = RTC_TIMESTAMP_BEGIN_2000;
plugin_register(&plugin); plugin_register(&plugin);
} }