Manually Setting the System Clock

On one of our devices we are allowing users to manually adjust the system time. This is because we expect that a majority of the time we wonn’t have internet connectivity.

What we did was implement an endpoint in one of our existing containers that set the system clock based on the time it receives. It uses the this node library. It works just fine to set the time and I can see the time reflected in the containers and in the host OS by using the date command. The logs also output updated timestamps as I would expect.

The issue is when the device is rebooted the time is different. For example, on my host OS after changing the time it shows:

~# date
Mon Apr 13 10:41:35 UTC 2020

Now when I reboot I get:

~# date
Mon Apr 13 15:44:31 UTC 2020

It should be noted that I’m currently in CST (UTC -5:00). Does anyone know what’s happening here?

Hello @AdamLee,

Can you provide the version of balenaOS your device is running? The time management works a little differently on older versions so I want to make sure we are looking at the correct services.

Host OS Version: balenaOS 2.47.0+rev1
Supervisor Version: 10.6.27

Thanks for that information. When you reboot the device it will initially poll the NTP sources and use that time if it reaches them. (More information about that here: https://www.balena.io/docs/reference/OS/time/#chrony ) So if you are setting the time to something other than the current UTC and then rebooting, your example appears to be the expected behavior.

Thanks - I read the time management docs, very useful information.

Is there any way to turn of NTP polling, by chance? Like let’s say if I wanted to turn this thing into a wrist watch with a RTC.

Hi there, chrony does have RTC support, but since most hardware (RPi) doesn’t have one on-board by default, you would need to add a RTC hardware module (via GPIO) first and configure chrony to use it. This is documented in the chrony docs.

I’ve got an RTC hooked up and added the overlay parameters.

How do I change the chrony configuration file? I tried doing it from the host OS but it complained that it was read only. I can’t see it in the SD card (using Windows). I’m a super Linux noob.

Hey @AdamLee,
balenaOS is already configured to use RTC, you can check the default set here. It is using rtcsync. If I understand correctly, you need to disable the chrony service in the hostOS which will prevent NTP from updating the time. Here is how you could proceed:

Use a container with dbus-send and execute the following command:
DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket dbus-send --system --dest=org.freedesktop.systemd1 --type=method_call --print-reply /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager.StopUnit string:"chronyd.service" string:"replace"

For this to work, you will need to set

labels:
     io.balena.features.dbus: '1'

for your service. You can refer to the documentation on how to communicate with the hostOS from a container using dbus.

Hope this is helpful. Let us know how it goes.

Thanks

This did not seem to work. I must admit it took a little bit to get it to function because I fell into this pitfall:

This is the reply from the dbus-send command:

17.04.20 09:58:00 (+0000)  api  method return time=1587117480.786902 sender=:1.1 -> destination=:1.6250 serial=177495 reply_serial=2
17.04.20 09:58:00 (+0000)  api     object path "/org/freedesktop/systemd1/job/79940"

When I changed the system time on the device, disconnected from the network, and power cycled it came up with a completely incorrect time. I thought originally that I would have to change the rtcsync directive in chrony to rtcfile, which is why I had originally asked how to edit that configuration:

The hwclock program is often set-up by default in the boot and shutdown scripts with many Linux installations. With the kernel RTC synchronisation ( rtcsync directive), the RTC will be set also every 11 minutes as long as the system clock is synchronised. If you want to use chronyd 's RTC monitoring ( rtcfile directive), it’s important to disable hwclock in the shutdown procedure. If you don’t, it will over-write the RTC with a new value, unknown to chronyd . At the next reboot, chronyd started with the -s option will compensate this (wrong) time with its estimate of how far the RTC has drifted whilst the power was off, giving a meaningless initial system time.

There is no need to remove hwclock from the boot process, as long as chronyd is started after it has run.

https://chrony.tuxfamily.org/faq.html#_i_want_to_use_code_chronyd_code_s_rtc_support_must_i_disable_code_hwclock_code

After reconnecting to the network, and then power cycling again it’s clear that NTP was used because the system time now reflects the current UTC time.

My guess after reading some docs is that command is happening after the clock is already synchronized with NTP.