From 3f3f7298347c88cc5e2265f949d60bc40e0d0ebe Mon Sep 17 00:00:00 2001 From: Bastian Krause Date: Fri, 24 Oct 2025 17:32:20 +0200 Subject: [PATCH] hwclock: skip RTC_PARAM_SET for --param-set with unchanged value Parameters set with `hwclock --param-set` tend to be persisted in the RTC's EEPROM. Writing the same value over and over again can wear out the EEPROM (e.g. on each boot). So read the current value first. Only if the parameter is changed, actually write the new value. This allows for easier integrations, especially since there is no machine-readable way of retrieving the current value via hwclock. Signed-off-by: Bastian Krause --- sys-utils/hwclock-rtc.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/sys-utils/hwclock-rtc.c b/sys-utils/hwclock-rtc.c index f8af5545d..318e692e9 100644 --- a/sys-utils/hwclock-rtc.c +++ b/sys-utils/hwclock-rtc.c @@ -498,6 +498,7 @@ int get_param_rtc(const struct hwclock_control *ctl, int set_param_rtc(const struct hwclock_control *ctl, const char *opt0) { int rtc_fd, rc = 1; + struct rtc_param current_param = { .index = ctl->param_idx }; struct rtc_param param = { .index = ctl->param_idx }; char *tok, *opt = xstrdup(opt0); @@ -520,13 +521,25 @@ int set_param_rtc(const struct hwclock_control *ctl, const char *opt0) goto done; } - /* set parameter */ rtc_fd = open_rtc(ctl); if (rtc_fd < 0) { warnx(_("cannot open %s"), rtc_dev_name); goto done; } + /* get parameter and compare with value */ + current_param.param = param.param; + if (!ioctl(rtc_fd, RTC_PARAM_GET, ¤t_param) + && current_param.uvalue == param.uvalue) { + /* value to be written matches current value, skip write */ + if (ctl->verbose) + printf(_("skipping ioctl(%d, RTC_PARAM_GET, param) to %s: value unchanged\n"), + rtc_fd, rtc_dev_name); + rc = 0; + goto done; + } + + /* set parameter */ if (ioctl(rtc_fd, RTC_PARAM_SET, ¶m) == -1) { warn(_("ioctl(%d, RTC_PARAM_SET, param) to %s failed"), rtc_fd, rtc_dev_name); -- 2.47.3