diff --git a/board/aarch64/dts/styx/dcp-sc-28p.dtsi b/board/aarch64/dts/styx/dcp-sc-28p.dtsi index c7402b3a9..ae5ff48b2 100644 --- a/board/aarch64/dts/styx/dcp-sc-28p.dtsi +++ b/board/aarch64/dts/styx/dcp-sc-28p.dtsi @@ -33,6 +33,14 @@ }; }; +/* + * RTC has no valid bit, and this board does not connect any + * backup power (e.g. supercap) to it, so it returns garbage + * after every cold reset. + */ +&cp0_rtc { + status = "disabled"; +}; /* UART0 (Console) */ diff --git a/board/common/qemu/Config.in.in b/board/common/qemu/Config.in.in index 2a2f2a49f..4e9f7c0cb 100644 --- a/board/common/qemu/Config.in.in +++ b/board/common/qemu/Config.in.in @@ -106,6 +106,8 @@ config QEMU_DTB_EXTEND depends on QEMU_LOADER_UBOOT default y if QEMU_aarch64 +if QEMU_ROOTFS_INITRD + config QEMU_RW string "Writable /cfg layer" depends on QEMU_ROOTFS_INITRD @@ -123,6 +125,8 @@ config QEMU_RW_VAR default "var.ext4" endif +endif + config QEMU_VPD bool "Emulate a Vital Product Data (VPD) Memory" @@ -137,6 +141,51 @@ config QEMU_APPEND config QEMU_EXTRA string "Extra QEMU options" + +comment "RTC" + +choice + prompt "Mode" + default QEMU_RTC_UTC + +config QEMU_RTC_UTC + bool "UTC" + +config QEMU_RTC_LOCAL + bool "Local time" + +config QEMU_RTC_RANDOM + bool "Random" + +endchoice + +choice + prompt "Clock" + default QEMU_CLOCK_HOST + +config QEMU_CLOCK_HOST + bool "Host clock" + +config QEMU_CLOCK_RT + bool "Independent (monotonic)" + +config QEMU_CLOCK_VM + bool "Virtual" + +endchoice + +config QEMU_RTC + string + default "utc" if QEMU_RTC_UTC + default "localtime" if QEMU_RTC_LOCAL + default "random" if QEMU_RTC_RANDOM + +config QEMU_CLOCK + string + default "host" if QEMU_CLOCK_HOST + default "rt" if QEMU_CLOCK_RT + default "vm" if QEMU_CLOCK_VM + comment "Networking" choice diff --git a/board/common/qemu/qemu.sh b/board/common/qemu/qemu.sh index add2c4195..3813d4b43 100755 --- a/board/common/qemu/qemu.sh +++ b/board/common/qemu/qemu.sh @@ -261,7 +261,25 @@ EOF wdt_args() { - echo -n "-device i6300esb -rtc clock=host" + echo -n "-device i6300esb " +} + +random_date() +{ + rand=$(($(date +%_s) * $$ + $(date +%N | sed 's/^0*//'))) + when=$((rand % 7258118400)) # 1970 - 2200 + date -d "@$when" +"%Y-%m-%dT%H:%M:%S" +} + +rtc_args() +{ + rtc="${CONFIG_QEMU_RTC:-utc}" + clock="${CONFIG_QEMU_CLOCK:-host}" + if [ "$rtc" = "random" ]; then + rtc=$(random_date) + fi + + echo -n "-rtc base=$rtc,clock=$clock" } gdb_args() @@ -273,11 +291,19 @@ gdb_args() run_qemu() { if [ "$CONFIG_QEMU_ROOTFS_VSCSI" = "y" ]; then - qemu-img create -f qcow2 -o backing_file=$CONFIG_QEMU_ROOTFS -F raw $CONFIG_QEMU_ROOTFS.qcow2 > /dev/null + if ! qemu-img check "${CONFIG_QEMU_ROOTFS}.qcow2"; then + rm -f "${CONFIG_QEMU_ROOTFS}.qcow2" + fi + if [ ! -f "${CONFIG_QEMU_ROOTFS}.qcow2" ]; then + echo "Creating qcow2 disk image for Qemu ..." + qemu-img create -f qcow2 -o backing_file="$CONFIG_QEMU_ROOTFS" \ + -F raw "${CONFIG_QEMU_ROOTFS}.qcow2" > /dev/null + fi fi + local qemu read qemu </dev/null); do if [ "$(cat $tag | tr -d '\0')" = hostfs ]; then diff --git a/configs/aarch64_defconfig b/configs/aarch64_defconfig index 6a89a92fc..cccc610e9 100644 --- a/configs/aarch64_defconfig +++ b/configs/aarch64_defconfig @@ -142,6 +142,8 @@ BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y BR2_PACKAGE_FINIT_PLUGIN_HOOK_SCRIPTS=y BR2_PACKAGE_FINIT_PLUGIN_MODULES_LOAD=y BR2_PACKAGE_FINIT_PLUGIN_RTC=y +BR2_PACKAGE_FINIT_RTC_DATE="2024-11-04 10:54:00" +BR2_PACKAGE_FINIT_RTC_FILE="/var/lib/misc/rtc" BR2_PACKAGE_FINIT_PLUGIN_TTY=y BR2_PACKAGE_FINIT_PLUGIN_URANDOM=y BR2_PACKAGE_IITO=y diff --git a/configs/aarch64_minimal_defconfig b/configs/aarch64_minimal_defconfig index e4df9be79..736c64d0e 100644 --- a/configs/aarch64_minimal_defconfig +++ b/configs/aarch64_minimal_defconfig @@ -122,6 +122,8 @@ BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y BR2_PACKAGE_FINIT_PLUGIN_HOOK_SCRIPTS=y BR2_PACKAGE_FINIT_PLUGIN_MODULES_LOAD=y BR2_PACKAGE_FINIT_PLUGIN_RTC=y +BR2_PACKAGE_FINIT_RTC_DATE="2024-11-04 10:54:00" +BR2_PACKAGE_FINIT_RTC_FILE="/var/lib/misc/rtc" BR2_PACKAGE_FINIT_PLUGIN_TTY=y BR2_PACKAGE_FINIT_PLUGIN_URANDOM=y BR2_PACKAGE_IITO=y diff --git a/configs/r2s_defconfig b/configs/r2s_defconfig index 124291a23..b41c3f625 100644 --- a/configs/r2s_defconfig +++ b/configs/r2s_defconfig @@ -183,6 +183,8 @@ BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y BR2_PACKAGE_FINIT_PLUGIN_HOOK_SCRIPTS=y BR2_PACKAGE_FINIT_PLUGIN_MODULES_LOAD=y BR2_PACKAGE_FINIT_PLUGIN_RTC=y +BR2_PACKAGE_FINIT_RTC_DATE="2024-11-04 10:54:00" +BR2_PACKAGE_FINIT_RTC_FILE="/var/lib/misc/rtc" BR2_PACKAGE_FINIT_PLUGIN_TTY=y BR2_PACKAGE_FINIT_PLUGIN_URANDOM=y BR2_PACKAGE_IITO=y diff --git a/configs/riscv64_defconfig b/configs/riscv64_defconfig index 64105dd81..6b8b292fa 100644 --- a/configs/riscv64_defconfig +++ b/configs/riscv64_defconfig @@ -173,6 +173,8 @@ BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y BR2_PACKAGE_FINIT_PLUGIN_HOOK_SCRIPTS=y BR2_PACKAGE_FINIT_PLUGIN_MODULES_LOAD=y BR2_PACKAGE_FINIT_PLUGIN_RTC=y +BR2_PACKAGE_FINIT_RTC_DATE="2024-11-04 10:54:00" +BR2_PACKAGE_FINIT_RTC_FILE="/var/lib/misc/rtc" BR2_PACKAGE_FINIT_PLUGIN_TTY=y BR2_PACKAGE_FINIT_PLUGIN_URANDOM=y BR2_PACKAGE_IITO=y diff --git a/configs/x86_64_defconfig b/configs/x86_64_defconfig index e47daea83..f2b13bde8 100644 --- a/configs/x86_64_defconfig +++ b/configs/x86_64_defconfig @@ -146,6 +146,8 @@ BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y BR2_PACKAGE_FINIT_PLUGIN_HOOK_SCRIPTS=y BR2_PACKAGE_FINIT_PLUGIN_MODULES_LOAD=y BR2_PACKAGE_FINIT_PLUGIN_RTC=y +BR2_PACKAGE_FINIT_RTC_DATE="2024-11-04 10:54:00" +BR2_PACKAGE_FINIT_RTC_FILE="/var/lib/misc/rtc" BR2_PACKAGE_FINIT_PLUGIN_TTY=y BR2_PACKAGE_FINIT_PLUGIN_URANDOM=y BR2_PACKAGE_IITO=y diff --git a/configs/x86_64_minimal_defconfig b/configs/x86_64_minimal_defconfig index d0368b44d..9d6ca50f9 100644 --- a/configs/x86_64_minimal_defconfig +++ b/configs/x86_64_minimal_defconfig @@ -126,6 +126,8 @@ BR2_PACKAGE_FINIT_PLUGIN_HOTPLUG=y BR2_PACKAGE_FINIT_PLUGIN_HOOK_SCRIPTS=y BR2_PACKAGE_FINIT_PLUGIN_MODULES_LOAD=y BR2_PACKAGE_FINIT_PLUGIN_RTC=y +BR2_PACKAGE_FINIT_RTC_DATE="2024-11-04 10:54:00" +BR2_PACKAGE_FINIT_RTC_FILE="/var/lib/misc/rtc" BR2_PACKAGE_FINIT_PLUGIN_TTY=y BR2_PACKAGE_FINIT_PLUGIN_URANDOM=y BR2_PACKAGE_IITO=y diff --git a/doc/ChangeLog.md b/doc/ChangeLog.md index 71ccd00c5..9981568e3 100644 --- a/doc/ChangeLog.md +++ b/doc/ChangeLog.md @@ -9,8 +9,25 @@ All notable changes to the project are documented in this file. ### Changes +- Support for showing interfaces owned by running containers in the CLI + command `show interfaces`. This also adds support for showing the + peer interface of VETH pairs. Issue #626 +- Reboot system on kernel "oops", on "oops" the kernel now panics and + reboots after 20 seconds. Issue #740 +- Update static factory-config for NanoPi R2S: enable NACM, securing all + passwords, and enabling `iburst` for the NTP client. Issue #750 - Updated QoS documentation with pictures and more information on VLAN - interface ingress/egress priority handling. + interface ingress/egress priority handling, issue #759 +- Disable RTC device in Styx device tree, issue #794 +- Support for saving and restoring system clock from a disk file. This + allows restoring the system clock to a sane date in case the RTC is + disabled or does not have a valid time, issue #794 + +### Fixes +- Fix #685: DSA conduit interface not always detected, randomly causing + major issues configuring systems with multiple switch cores +- Fix #778: reactivate OpenSSL backend for libssh/libssh2 for NanoPI R2S. + This fixes a regression in v24.10.0 causing loss of NETCONF supprt [v24.10.1][] - 2024-10-18 diff --git a/package/finit/0001-Only-mark-rdeps-dirty-if-main-service-is-nohup.patch b/package/finit/0001-Only-mark-rdeps-dirty-if-main-service-is-nohup.patch index f184e4cfa..f53430df0 100644 --- a/package/finit/0001-Only-mark-rdeps-dirty-if-main-service-is-nohup.patch +++ b/package/finit/0001-Only-mark-rdeps-dirty-if-main-service-is-nohup.patch @@ -1,7 +1,7 @@ From 46ffa81f5c88ce95db011369d8bfb802313e4217 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Thu, 17 Oct 2024 14:23:24 +0200 -Subject: [PATCH 1/2] Only mark rdeps dirty if main service is nohup +Subject: [PATCH 1/6] Only mark rdeps dirty if main service is nohup Organization: Addiva Elektronik This patch changes a behavior that's been default since Finit 4.0, diff --git a/package/finit/0002-Reset-color-attributes-and-clear-screen-when-startin.patch b/package/finit/0002-Reset-color-attributes-and-clear-screen-when-startin.patch index d46c51b40..d20ea0e78 100644 --- a/package/finit/0002-Reset-color-attributes-and-clear-screen-when-startin.patch +++ b/package/finit/0002-Reset-color-attributes-and-clear-screen-when-startin.patch @@ -1,7 +1,7 @@ From 119e66a7e9c95283918639b51dd03a3d666955f8 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Mon, 28 Oct 2024 10:58:04 +0100 -Subject: [PATCH 2/2] Reset color attributes and clear screen when starting up +Subject: [PATCH 2/6] Reset color attributes and clear screen when starting up Organization: Addiva Elektronik Some boot loaders, like GRUB, leave background color artifacts from diff --git a/package/finit/0003-plugins-refactor-rtc.so.patch b/package/finit/0003-plugins-refactor-rtc.so.patch new file mode 100644 index 000000000..cd47adc64 --- /dev/null +++ b/package/finit/0003-plugins-refactor-rtc.so.patch @@ -0,0 +1,196 @@ +From 0c0e880f3fdd38f7bbde618408378dc0a19ff005 Mon Sep 17 00:00:00 2001 +From: Joachim Wiberg +Date: Sun, 3 Nov 2024 09:39:46 +0100 +Subject: [PATCH 3/6] plugins: refactor rtc.so +Organization: Addiva Elektronik + +Factor out time_set() and time_get() for readability and reuse. + +Signed-off-by: Joachim Wiberg +--- + plugins/rtc.c | 116 +++++++++++++++++++++++++++++--------------------- + 1 file changed, 68 insertions(+), 48 deletions(-) + +diff --git a/plugins/rtc.c b/plugins/rtc.c +index 238791f..9520c7d 100644 +--- a/plugins/rtc.c ++++ b/plugins/rtc.c +@@ -68,6 +68,60 @@ static void tz_restore(char *tz) + tzset(); + } + ++static int time_set(struct tm *tm) ++{ ++ struct tm fallback = { 0 }; ++ struct timeval tv = { 0 }; ++ char tz[128]; ++ int rc = 0; ++ ++ tz_set(tz, sizeof(tz)); ++ ++ if (!tm) { ++ logit(LOG_NOTICE, "Resetting system clock to kernel default, %s.", rtc_timestamp); ++ tm = &fallback; ++ ++ /* Attempt to set RTC to a sane value ... */ ++ tv.tv_sec = rtc_date_fallback; ++ if (!gmtime_r(&tv.tv_sec, tm)) { ++ rc = 1; ++ goto out; ++ } ++ } ++ ++ tm->tm_isdst = -1; /* Use tzdata to figure it out, please. */ ++ tv.tv_sec = mktime(tm); ++ if (tv.tv_sec == (time_t)-1 || tv.tv_sec < rtc_date_fallback) { ++ errno = EINVAL; ++ rc = 2; ++ } else { ++ if (settimeofday(&tv, NULL) == -1) ++ rc = 1; ++ } ++out: ++ tz_restore(tz); ++ return rc; ++} ++ ++static int time_get(struct tm *tm) ++{ ++ struct timeval tv = { 0 }; ++ char tz[128]; ++ int rc = 0; ++ ++ tz_set(tz, sizeof(tz)); ++ ++ rc = gettimeofday(&tv, NULL); ++ if (rc < 0 || tv.tv_sec < rtc_date_fallback) ++ rc = 2; ++ else ++ gmtime_r(&tv.tv_sec, tm); ++ ++ tz_restore(tz); ++ ++ return rc; ++} ++ + static int rtc_open(void) + { + char *alt[] = { +@@ -91,10 +145,8 @@ static int rtc_open(void) + + static void rtc_save(void *arg) + { +- struct timeval tv = { 0 }; + struct tm tm = { 0 }; + int fd, rc = 0; +- char tz[128]; + + if (rescue) { + dbg("Skipping %s plugin in rescue mode.", __FILE__); +@@ -105,38 +157,26 @@ static void rtc_save(void *arg) + if (fd < 0) + return; + +- tz_set(tz, sizeof(tz)); +- rc = gettimeofday(&tv, NULL); +- if (rc < 0 || tv.tv_sec < rtc_date_fallback) { ++ if ((rc = time_get(&tm))) { + print_desc(NULL, "System clock invalid, not saving to RTC"); +- invalid: +- logit(LOG_ERR, "System clock invalid, before %s, not saving to RTC", rtc_timestamp); +- rc = 2; +- goto out; ++ } else { ++ print_desc(NULL, "Saving system clock (UTC) to RTC"); ++ rc = ioctl(fd, RTC_SET_TIME, &tm); + } + +- print_desc(NULL, "Saving system time (UTC) to RTC"); +- +- gmtime_r(&tv.tv_sec, &tm); +- if (ioctl(fd, RTC_SET_TIME, &tm) < 0) { +- if (EINVAL == errno) +- goto invalid; +- rc = 1; +- goto out; ++ if (rc && errno == EINVAL) { ++ logit(LOG_ERR, "System clock invalid, before %s, not saving to RTC", rtc_timestamp); ++ rc = 2; + } + +-out: +- tz_restore(tz); + print(rc, NULL); + close(fd); + } + + static void rtc_restore(void *arg) + { +- struct timeval tv = { 0 }; + struct tm tm = { 0 }; + int fd, rc = 0; +- char tz[128]; + + if (rescue) { + dbg("Skipping %s plugin in rescue mode.", __FILE__); +@@ -149,16 +189,19 @@ static void rtc_restore(void *arg) + return; + } + +- tz_set(tz, sizeof(tz)); +- if (ioctl(fd, RTC_RD_TIME, &tm) < 0) { ++ if ((rc = ioctl(fd, RTC_RD_TIME, &tm)) < 0) { + char msg[120]; + + snprintf(msg, sizeof(msg), "Failed restoring system clock, %s", + EINVAL == errno ? "RTC time is too old" : + ENOENT == errno ? "RTC has no saved time" : "see log for details"); + print_desc(NULL, msg); ++ } else { ++ print_desc(NULL, "Restoring system clock (UTC) from RTC"); ++ rc = time_set(&tm); ++ } + +- invalid: ++ if (rc) { + logit(LOG_ERR, "Failed restoring system clock from RTC."); + if (EINVAL == errno) + logit(LOG_ERR, "RTC time is too old (before %s)", rtc_timestamp); +@@ -167,33 +210,10 @@ static void rtc_restore(void *arg) + else + logit(LOG_ERR, "RTC error code %d: %s", errno, strerror(errno)); + +- /* Been here already? */ +- if (rc) +- goto out; +- +- /* Attempt to set RTC to a sane value ... */ +- tv.tv_sec = rtc_date_fallback; +- if (!gmtime_r(&tv.tv_sec, &tm)) +- goto out; +- +- logit(LOG_NOTICE, "Resetting RTC to kernel default, %s.", rtc_timestamp); ++ time_set(NULL); + rc = 2; + } + +- if (!rc) +- print_desc(NULL, "Restoring system clock (UTC) from RTC"); +- tm.tm_isdst = -1; /* Use tzdata to figure it out, please. */ +- tv.tv_sec = mktime(&tm); +- if (tv.tv_sec == (time_t)-1 || tv.tv_sec < rtc_date_fallback) { +- errno = EINVAL; +- goto invalid; +- } +- +- if (settimeofday(&tv, NULL) == -1) +- rc = 1; +- +-out: +- tz_restore(tz); + print(rc, NULL); + close(fd); + } +-- +2.43.0 + diff --git a/package/finit/0004-Fix-418-support-systems-with-a-broken-RTC.patch b/package/finit/0004-Fix-418-support-systems-with-a-broken-RTC.patch new file mode 100644 index 000000000..bea15500e --- /dev/null +++ b/package/finit/0004-Fix-418-support-systems-with-a-broken-RTC.patch @@ -0,0 +1,239 @@ +From bc8118d515839dc598f437aa01f07a771646968d Mon Sep 17 00:00:00 2001 +From: Joachim Wiberg +Date: Sun, 3 Nov 2024 09:47:16 +0100 +Subject: [PATCH 4/6] Fix #418: support systems with a broken RTC +Organization: Addiva Elektronik + +This patch introduces a new configure option --with-rtc-file=FILE. When +enabled the RTC plugin detects missing RTC device and falls back to save +and restore system time from a file instead. When --with-rtc-file is +used without an argument the default file is /var/lib/misc/rtc, but the +feature itself is disabled by default. + +The usefulness of this feature may not be obvious at first, but some +systems are equipped with an RTC that resets to a random date at power +on. This can be really bad in the case the date is far in the future, +because an NTP sync would then cause time skips backwards, which shows +up in logs and causes a whole lot of pain in alarm systems. + +The solution is to disable the RTC driver or device tree node, and when +Finit starts up, the RTC plugin detects a the device node and instead +restores time from the last save game. Meaning time will always only +move forwards. + +NOTE: when Finit is built --with-rtc-file we always save to disk, but + only restore from the "save game" if restoring from RTC fails. + If the system has no RTC we always restore from disk. + + As an added bonus, this change also makes sure to periodically + sync also the RTC with the system clock. Useful for systems + that do not run an NTP client. + +Signed-off-by: Joachim Wiberg +--- + configure.ac | 12 ++++++ + plugins/rtc.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++---- + 2 files changed, 110 insertions(+), 7 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 483457f..ae7cd23 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -180,6 +180,10 @@ 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]) + ++AC_ARG_WITH(rtc-file, ++ AS_HELP_STRING([--with-rtc-file=FILE], [If RTC is missing, save and restore system clock from this file, default: no]), ++ [rtc_file=$withval], [rtc_file=no]) ++ + ### Enable features ########################################################################### + + # Create config.h from selected features and fallback defaults +@@ -281,6 +285,13 @@ 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$rtc_file" != "xno"], [ ++ AS_IF([test "x$rtc_file" = "xyes"], [ ++ rtc_file=/var/lib/misc/rtc]) ++ AC_EXPAND_DIR(rtcfile_path, "$rtc_file") ++ AC_DEFINE_UNQUOTED(RTC_FILE, "$rtcfile_path", [Save and restore system time from this file if /dev/rtc is missing.])],[ ++ AC_DEFINE_UNQUOTED(RTC_FILE, NULL)]) ++ + AS_IF([test "x$with_keventd" != "xno"], [with_keventd=yes]) + + AS_IF([test "x$with_sulogin" != "xno"], [ +@@ -387,6 +398,7 @@ Behavior: + Boot heading..........: $heading + Plugins...............: $plugins + RTC restore date......: $RTC_DATE ++ RTC fallback file.....: $rtc_file + + Optional features: + Install doc/..........: $enable_doc +diff --git a/plugins/rtc.c b/plugins/rtc.c +index 9520c7d..9b4eeae 100644 +--- a/plugins/rtc.c ++++ b/plugins/rtc.c +@@ -36,8 +36,15 @@ + #include "helpers.h" + #include "plugin.h" + +-/* Kernel RTC driver validates against this date for sanity check */ ++/* ++ * Kernel RTC driver validates against this date for sanity check. The ++ * on NTP sync the driver can also update the RTC every 11 mins. We use ++ * the same update interval to handle manual time set and file save. ++ */ + #define RTC_TIMESTAMP_BEGIN_2000 "2000-01-01 00:00:00" ++#define RTC_FMT "%Y-%m-%d %H:%M:%S" ++#define RTC_PERIOD (11 * 60 * 1000) ++ + #ifdef RTC_TIMESTAMP_CUSTOM + static char *rtc_timestamp = RTC_TIMESTAMP_CUSTOM; + #else +@@ -45,6 +52,10 @@ static char *rtc_timestamp = RTC_TIMESTAMP_BEGIN_2000; + #endif + static time_t rtc_date_fallback = 946684800LL; + ++static char *rtc_file = RTC_FILE; ++static uev_t rtc_timer; ++ ++ + static void tz_set(char *tz, size_t len) + { + char *ptr; +@@ -122,6 +133,68 @@ static int time_get(struct tm *tm) + return rc; + } + ++static void file_save(void *arg) ++{ ++ struct tm tm = { 0 }; ++ int rc = 0; ++ FILE *fp; ++ ++ fp = fopen(rtc_file, "w"); ++ if (!fp) { ++ logit(LOG_WARNING, "Failed saving system clock to %s, code %d: %s", ++ rtc_file, errno, strerror(errno)); ++ return; ++ } ++ ++ if ((rc = time_get(&tm))) { ++ logit(LOG_ERR, "System clock invalid, before %s, not saving", rtc_timestamp); ++ print_desc(NULL, "System clock invalid, skipping"); ++ } else { ++ char buf[32] = { 0 }; ++ ++ print_desc(NULL, "Saving system clock to file"); ++ strftime(buf, sizeof(buf), RTC_FMT, &tm); ++ fprintf(fp, "%s\n", buf); ++ } ++ ++ print(rc, NULL); ++ fclose(fp); ++} ++ ++static void file_restore(void *arg) ++{ ++ struct tm tm = { 0 }; ++ int rc = 1; ++ FILE *fp; ++ ++ if (!rtc_file) { ++ logit(LOG_NOTICE, "System has no RTC (missing driver?), skipping restore."); ++ return; ++ } ++ ++ print_desc(NULL, "Restoring system clock from backup"); ++ ++ fp = fopen(rtc_file, "r"); ++ if (fp) { ++ char buf[32]; ++ ++ if (fgets(buf, sizeof(buf), fp)) { ++ chomp(buf); ++ strptime(buf, RTC_FMT, &tm); ++ rc = time_set(&tm); ++ } ++ fclose(fp); ++ } else ++ logit(LOG_WARNING, "Missing %s", rtc_file); ++ ++ if (rc) { ++ time_set(NULL); ++ rc = 2; ++ } ++ ++ print(rc, NULL); ++} ++ + static int rtc_open(void) + { + char *alt[] = { +@@ -185,7 +258,7 @@ static void rtc_restore(void *arg) + + fd = rtc_open(); + if (fd < 0) { +- logit(LOG_NOTICE, "System has no RTC (missing driver?), skipping restore."); ++ file_restore(arg); + return; + } + +@@ -210,21 +283,37 @@ static void rtc_restore(void *arg) + else + logit(LOG_ERR, "RTC error code %d: %s", errno, strerror(errno)); + +- time_set(NULL); +- rc = 2; +- } ++ print(2, NULL); ++ ++ /* Try restoring from last save game */ ++ if (rtc_file) ++ file_restore(arg); ++ } else ++ print(0, NULL); + +- print(rc, NULL); + close(fd); + } + ++ ++static void save(void *arg) ++{ ++ rtc_save(arg); ++ file_save(arg); ++} ++ ++static void update(uev_t *w, void *arg, int events) ++{ ++ save(arg); ++} ++ ++ + static plugin_t plugin = { + .name = __FILE__, + .hook[HOOK_BASEFS_UP] = { + .cb = rtc_restore + }, + .hook[HOOK_SHUTDOWN] = { +- .cb = rtc_save ++ .cb = save + } + }; + +@@ -237,6 +326,8 @@ PLUGIN_INIT(plugin_init) + else + rtc_timestamp = RTC_TIMESTAMP_BEGIN_2000; + ++ uev_timer_init(ctx, &rtc_timer, update, NULL, RTC_PERIOD, RTC_PERIOD); ++ + plugin_register(&plugin); + } + +-- +2.43.0 + diff --git a/package/finit/0005-Fix-buggy-with-rtc-date-DATE-introduced-in-Finit-v4..patch b/package/finit/0005-Fix-buggy-with-rtc-date-DATE-introduced-in-Finit-v4..patch new file mode 100644 index 000000000..b2c2d86bb --- /dev/null +++ b/package/finit/0005-Fix-buggy-with-rtc-date-DATE-introduced-in-Finit-v4..patch @@ -0,0 +1,73 @@ +From 6be16f2f6d093ef495d0fe4313f7b05b4ba3e08f Mon Sep 17 00:00:00 2001 +From: Joachim Wiberg +Date: Sun, 3 Nov 2024 10:38:38 +0100 +Subject: [PATCH 5/6] Fix buggy --with-rtc-date=DATE, introduced in Finit v4.4 +Organization: Addiva Elektronik + +In 42ef3d3c, for v4.4-rc1, support for setting a custom RTC restore date +was introduced. Unfortunately the configure script was wrong and caused +config.h to contain + + #define RTC_TIMESTAMP_CUSTOM "$rtc_date" + +instead of + + #define RTC_TIMESTAMP_CUSTOM "2023-04-10 14:35:42" + +Furthermore, the error handling for strptime() was wrong, so the restore +date was always reverted to the default. + +This patch fixes both issues and extends the DATE of --with-rtc-date to +also include seconds. + +Signed-off-by: Joachim Wiberg +--- + configure.ac | 4 ++-- + plugins/rtc.c | 8 +++++--- + 2 files changed, 7 insertions(+), 5 deletions(-) + +diff --git a/configure.ac b/configure.ac +index ae7cd23..58b78ac 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -177,7 +177,7 @@ AC_ARG_WITH(plugin-path, + [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"]), ++ AS_HELP_STRING([--with-rtc-date=DATE], [If RTC date/time is too old, restore to DATE, format "YYYY-MM-DD HH:MM:SS", default "2000-01-01 00:00:00"]), + [rtc_date=$withval], [rtc_date=no]) + + AC_ARG_WITH(rtc-file, +@@ -282,7 +282,7 @@ AS_IF([test "x$with_random_seed" != "xno"], [ + 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])], [ ++ AC_DEFINE_UNQUOTED(RTC_TIMESTAMP_CUSTOM, "$rtc_date", [Custom RTC restore date, default: 2000-01-01 00:00])], [ + rtc_date=""]) + + AS_IF([test "x$rtc_file" != "xno"], [ +diff --git a/plugins/rtc.c b/plugins/rtc.c +index 9b4eeae..a733f75 100644 +--- a/plugins/rtc.c ++++ b/plugins/rtc.c +@@ -321,10 +321,12 @@ PLUGIN_INIT(plugin_init) + { + struct tm tm = { 0 }; + +- if (!strptime(rtc_timestamp, "%Y-%m-%d %H:%M", &tm)) +- rtc_date_fallback = mktime(&tm); +- else ++ if (!strptime(rtc_timestamp, RTC_FMT, &tm)) { ++ logit(LOG_ERR, "Invalid restore date '%s', reverting to '%s'", ++ rtc_timestamp, RTC_TIMESTAMP_BEGIN_2000); + rtc_timestamp = RTC_TIMESTAMP_BEGIN_2000; ++ } else ++ rtc_date_fallback = mktime(&tm); + + uev_timer_init(ctx, &rtc_timer, update, NULL, RTC_PERIOD, RTC_PERIOD); + +-- +2.43.0 + diff --git a/package/finit/0006-plugins-reduce-log-level-LOG_ERR-LOG_WARNING.patch b/package/finit/0006-plugins-reduce-log-level-LOG_ERR-LOG_WARNING.patch new file mode 100644 index 000000000..c76b9e16e --- /dev/null +++ b/package/finit/0006-plugins-reduce-log-level-LOG_ERR-LOG_WARNING.patch @@ -0,0 +1,85 @@ +From 49c0557cedd8d3c1a2f74d27fa7db83dd529914a Mon Sep 17 00:00:00 2001 +From: Joachim Wiberg +Date: Sun, 3 Nov 2024 20:49:04 +0100 +Subject: [PATCH 6/6] plugins: reduce log level LOG_ERR -> LOG_WARNING +Organization: Addiva Elektronik + +These plugins signal success and failure directly to the console, the +user should inspect syslog for more information. + +This change is a follow-up to 340cae4, where kernel logs of LOG_ERR and +higher are allowed to log directly to the console. Since syslogd has +not been started before these plugins, the log messages would otherwise +leak to the console. + +Signed-off-by: Joachim Wiberg +--- + plugins/rtc.c | 14 +++++++------- + plugins/urandom.c | 2 +- + 2 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/plugins/rtc.c b/plugins/rtc.c +index a733f75..96203a0 100644 +--- a/plugins/rtc.c ++++ b/plugins/rtc.c +@@ -147,7 +147,7 @@ static void file_save(void *arg) + } + + if ((rc = time_get(&tm))) { +- logit(LOG_ERR, "System clock invalid, before %s, not saving", rtc_timestamp); ++ logit(LOG_WARNING, "System clock invalid, before %s, not saving", rtc_timestamp); + print_desc(NULL, "System clock invalid, skipping"); + } else { + char buf[32] = { 0 }; +@@ -238,7 +238,7 @@ static void rtc_save(void *arg) + } + + if (rc && errno == EINVAL) { +- logit(LOG_ERR, "System clock invalid, before %s, not saving to RTC", rtc_timestamp); ++ logit(LOG_WARNING, "System clock invalid, before %s, not saving to RTC", rtc_timestamp); + rc = 2; + } + +@@ -275,13 +275,13 @@ static void rtc_restore(void *arg) + } + + if (rc) { +- logit(LOG_ERR, "Failed restoring system clock from RTC."); ++ logit(LOG_WARNING, "Failed restoring system clock from RTC."); + if (EINVAL == errno) +- logit(LOG_ERR, "RTC time is too old (before %s)", rtc_timestamp); ++ logit(LOG_WARNING, "RTC time is too old (before %s)", rtc_timestamp); + else if (ENOENT == errno) +- logit(LOG_ERR, "RTC has no previously saved (valid) time."); ++ logit(LOG_WARNING, "RTC has no previously saved (valid) time."); + else +- logit(LOG_ERR, "RTC error code %d: %s", errno, strerror(errno)); ++ logit(LOG_WARNING, "RTC error code %d: %s", errno, strerror(errno)); + + print(2, NULL); + +@@ -322,7 +322,7 @@ PLUGIN_INIT(plugin_init) + struct tm tm = { 0 }; + + if (!strptime(rtc_timestamp, RTC_FMT, &tm)) { +- logit(LOG_ERR, "Invalid restore date '%s', reverting to '%s'", ++ logit(LOG_WARNING, "Invalid restore date '%s', reverting to '%s'", + rtc_timestamp, RTC_TIMESTAMP_BEGIN_2000); + rtc_timestamp = RTC_TIMESTAMP_BEGIN_2000; + } else +diff --git a/plugins/urandom.c b/plugins/urandom.c +index b9f6039..6f82779 100644 +--- a/plugins/urandom.c ++++ b/plugins/urandom.c +@@ -154,7 +154,7 @@ static void setup(void *arg) + close(fd); + free(rpi); + if (rc < 0) +- logit(LOG_ERR, "Failed adding entropy to kernel random pool: %s", strerror(err)); ++ logit(LOG_WARNING, "Failed adding entropy to kernel random pool: %s", strerror(err)); + print_result(rc < 0); + return; + fallback: +-- +2.43.0 + diff --git a/package/finit/Config.in b/package/finit/Config.in index 831cf43f3..e4c8a8c2a 100644 --- a/package/finit/Config.in +++ b/package/finit/Config.in @@ -165,7 +165,6 @@ config BR2_PACKAGE_FINIT_PLUGIN_RTC For lxc/docker application builds you do not need this. if BR2_PACKAGE_FINIT_PLUGIN_RTC - config BR2_PACKAGE_FINIT_RTC_DATE string "Fallback RTC date" help @@ -184,7 +183,21 @@ config BR2_PACKAGE_FINIT_RTC_DATE Ensuring the default system time to be closer to actual time for a period after releasing a firmware image. -endif +config BR2_PACKAGE_FINIT_RTC_FILE + string "Fallback file if /dev/rtc is missing" + help + For systems with broken RTC, where the default value can be + completely random, e.g., a time far in the future, it might + be better to disable the RTC driver or device tree node. + + Enable this to allow the RTC plugin to save and restore the + system clock from a file when the plugin does not find any + usable device node. + + Since /var/lib/misc is usually persistent across reboots, we + recommend using: /var/lib/misc/rtc + +endif # RTC_PLUGIN config BR2_PACKAGE_FINIT_PLUGIN_TTY bool "TTY plugin" diff --git a/package/finit/finit.mk b/package/finit/finit.mk index 677c81014..ee828a440 100644 --- a/package/finit/finit.mk +++ b/package/finit/finit.mk @@ -13,11 +13,19 @@ FINIT_DEPENDENCIES = host-pkgconf libite libuev FINIT_INSTALL_STAGING = YES FINIT_D = $(TARGET_DIR)/etc/finit.d -# Create configure script using autoreconf when building from git +# Create configure script using autoreconf when building from git, +# or when patching any of the GNU build files (*.ac, *.am, etc.) #FINIT_VERSION = 438d6b4e638418a2a22024a3cead2f47909d72b9 #FINIT_SITE = $(call github,troglobit,finit,$(FINIT_VERSION)) -#FINIT_AUTORECONF = YES -#FINIT_DEPENDENCIES += host-automake host-autoconf host-libtool +FINIT_AUTORECONF = YES +FINIT_DEPENDENCIES += host-automake host-autoconf host-libtool + +# Strip "" from variables +FINIT_HOSTNAME = $(call qstrip,$(BR2_TARGET_GENERIC_HOSTNAME)) +FINIT_GROUP = $(call qstrip,$(BR2_PACKAGE_FINIT_INITCTL_GROUP)) +FINIT_FSTAB = $(call qstrip,$(BR2_PACKAGE_FINIT_CUSTOM_FSTAB)) +FINIT_RTC_DATE = $(call qstrip,$(BR2_PACKAGE_FINIT_RTC_DATE)) +FINIT_RTC_FILE = $(call qstrip,$(BR2_PACKAGE_FINIT_RTC_FILE)) # Buildroot defaults to /usr for both prefix and exec-prefix, this we # must override because we want to install into /sbin and /bin for the @@ -31,7 +39,7 @@ FINIT_CONF_OPTS = \ --disable-contrib \ --disable-rescue \ --disable-silent-rules \ - --with-group=$(BR2_PACKAGE_FINIT_INITCTL_GROUP) + --with-group="$(FINIT_GROUP)" ifeq ($(BR2_ROOTFS_MERGED_USR),y) FINIT_CONF_OPTS += --exec-prefix=/usr @@ -40,8 +48,8 @@ FINIT_CONF_OPTS += --exec-prefix= endif ifeq ($(BR2_PACKAGE_FINIT_ADVANCED),y) -ifneq ($(BR2_PACKAGE_FINIT_CUSTOM_FSTAB),) -FINIT_CONF_OPTS += --with-fstab=$(BR2_PACKAGE_FINIT_CUSTOM_FSTAB) +ifneq ($(FINIT_FSTAB),) +FINIT_CONF_OPTS += --with-fstab="$(FINIT_FSTAB)" else FINIT_CONF_OPTS += --without-fstab endif @@ -101,12 +109,18 @@ else FINIT_CONF_OPTS += --disable-rtc-plugin endif -ifeq ($(BR2_PACKAGE_FINIT_RTC_DATE),y) -FINIT_CONF_OPTS += --with-rtc-date="$(BR2_PACKAGE_FINIT_RTC_DATE)" +ifneq ($(FINIT_RTC_DATE),) +FINIT_CONF_OPTS += --with-rtc-date="$(FINIT_RTC_DATE)" else FINIT_CONF_OPTS += --without-rtc-date endif +ifneq ($(FINIT_RTC_FILE),) +FINIT_CONF_OPTS += --with-rtc-file="$(FINIT_RTC_FILE)" +else +FINIT_CONF_OPTS += --without-rtc-file +endif + ifeq ($(BR2_PACKAGE_FINIT_PLUGIN_TTY),y) FINIT_CONF_OPTS += --enable-tty-plugin else @@ -119,8 +133,11 @@ else FINIT_CONF_OPTS += --disable-urandom-plugin endif -ifneq ($(SKELETON_INIT_COMMON_HOSTNAME),) -FINIT_CONF_OPTS += --with-hostname="$(SKELETON_INIT_COMMON_HOSTNAME)" + +ifneq ($(FINIT_HOSTNAME),) +FINIT_CONF_OPTS += --with-hostname="$(FINIT_HOSTNAME)" +else +FINIT_CONF_OPTS += --without-hostname endif # Disable/Enable features depending on other packages