0

There is a file in "/usr/lib/udev/hwclock-set":

It shall set the correct date/time from RTC however it has a barrier:

if [ -e /run/systemd/system ] ; then
    exit 0
fi
/shin/hwclock ....

Now, when udev runs the hwclock rules, the above folder is already existing so the script will exit, without setting the system time.

What is the idea behind this condition?

Moreover, it's also preventing udev rules and systemd services to set the system time (via this script).

It drives me crazy. No udev rule or systemd service can work with this barrier.

Moreover2: when I uncomment the "exit", and an udev rule tries running this script, all "hwclock" calls return 1 (error).

When I run this script manually (with uncommented "exit"), it sets the time correctly.

Daniel
  • 339

1 Answers1

2

A modern systemd-udevd runs with a

CapabilityBoundingSet=~CAP_SYS_TIME CAP_WAKE_ALARM

in its service file. This means processes started by udev rules cannot manipulate system time, as the CAP_SYS_TIME capability has been excluded from udevd and its child processes.

On the other hand, systemd itself is supposed to handle setting the system clock from the (first) RTC very early in the boot process, essentially as soon as systemd starts up. In order to succeed in that, the kernel should have the driver for your hardware's RTC built in, not as a module.

Or if your hardware has multiple RTCs, the driver for the RTC you wish to use for system time should be built-in and any others as loadable modules. That should ensure the right RTC gets detected as rtc0, which is apparently the one used automatically by systemd to set up system time.

Apparently this behavior of systemd can cause some surprises if your hardware has multiple RTCs and the RTC you want to use does not get detected as the first one by the kernel, as evidenced by your other recent question.

Of course, if you are dealing with embedded systems with multiple RTCs and need the RTC drivers as modules, it might be a valid tradeoff to allow udev and its child processes manipulate the system time, by removing the CapabilityBoundingSet= line from the systemd-udevd.service file and the blocking condition from the /usr/lib/udev/hwclock-set file.

The main advantage of the new "standard setup" would seem to be that all logs should have correct timestamps as soon as systemd has started as a matter of course. If you make the changes to let udev rules handle setting the system clock once the appropriate RTC driver module is loaded, there might be some messages logged in early boot with incorrect timestamps, and you will need to remember that when reading your logs.

telcoM
  • 96,466
  • Clear explanation, thank you. I'm moving towards recompiling the kernel with excluding the non-battery-backed up RTC which was detected as rtc0 thus letting rtc1 eventually becoming rtc0. This way I can leave intact all systemd and udev configs. – Daniel Jul 10 '23 at 19:31
  • That sounds like a good solution, especially if you are building a custom kernel anyway. – telcoM Jul 11 '23 at 13:19
  • I rebuilt the kernel solely for this purpose :) I prefer the clean solutions :) – Daniel Jul 11 '23 at 19:36