Frustrated by openwrt booting up with wildly obsolete time, causing certain time-sensitive apps to break upon restart, I finally tracked down /etc/init.d/sysfixtime, which reportedly sets the openwrt syste clock using the timestamp of the newest file in /etc to a "reasonably" approximate time, on hardware that has no RTC or battery for time-keeping.
A gander in / shows it is probably the "best" approach. However, it is still not good enough for my hardware that has no hardware clock or battery. Even though mine is plugged into a UPS, sys time after reboot is still often wildly off, I guess because my /etc doesn't get changed THAT often.
I have been manually executing "ntpd -qnN -p [ip-addr-of-some-ntp-server]" to force-adjust systime after reboot, in order for the affected apps to start up correctly. I'm wondering what the best approach is to automate this:
Append the ntpd commands in /etc/init.d/sysfixtime? I realize this assumes internet or LAN network access, while checking /etc doesn't. Is ntpd likely to be removed from the default openwrt (base?) install in the future?
Use a shutdown script to write an empty file in /etc? Or, is there a better approach?
Changed /etc/init.d/sysfixtime would get overwriten by new openwrt (snapshots) installs, so it doesn't cover that scenario. Can shutdown script be preserved in /etc/sysupgrade.conf and survive new openwrt snapshot install?
There is only one real solution, getting a device with battery backed rtc - everything else is just trying to approximating the time and diving (deeper-) into race conditions or expecting too much from the conditionals of the network coming up.
In normal situations, the router does not reboot and the time remains valid.
If you have known /planned reboots, the best approach is to help sysfixtime to have a reasonably good time from a file in /etc
Or if your router crashes often, you might write a file in /etc every hour, or so. That would marginally shorten the lifetime of flash, but likely no issue.
When I want to "save time", I use /etc/urandom.seed that is in overlay in any case.
This is an old thread, but yesterday we had a power failure, which made it relevant (to me).
OP’s suggestion to use a shutdown script would have made no difference.
Instead I now added a cron job to touch /etc/sysfixtime daily:
0 3 * * * touch /etc/sysfixtime
Would it be useful if OpenWRT also touch /etc/sysfixtime or something similar on shutdown? It would make the cron is just a fallback for power failures etc.
A once-a-day write wearing out the ROM? Wow.
For DoH/DoT with a shortening certificate validity, the system date is becoming more important as it should fall between not-before and not-after.
Then you end up with chicken/egg. Apparently certificate validity is changing towards a maximum of 47 days. If you use public NTP services (like pool.ntp.org), then pool.ntp.org requires a lookup, which fails -when using DoT/DoH- if the system date is outside not-before and not-after.
A touch of something (in /etc ) on shutdown would be great and then once-a-day write (you could even do it only once or twice a week by filtering on day number) seems like a reasonable fallback for outages like I just had yesterday.
it doesn't require DoT/DoH though, it requires a DNS server, this is the only unencrypted lookup you have to do.
alt use IPs for initial NTP server sync, instead of host name(s).
Or if you need proper time then use a proper clock.
(Yes I had to even attach an Receiver for dcf77 via serial many many years ago https://en.wikipedia.org/wiki/DCF77 and an other option is gps. Or just an RTC!)
Not sure if what follows is relevant because my use case is slightly different: I need to take action as soon as the device has restarted and it's time succesfully sync by means of an ntp server.
To do that, I use the following script:
/etc/hotplug.d/ntp/20-Router_restart.sh
#!/bin/sh
# Script /etc/hotplug.d/ntp/20-Router_restart.sh
STILL_ALIVE="/tmp/Router_is_still_alive"
DEVICES="lan1 lan4"
# Check if Router has actually restarted
if { [ "$ACTION" = "step" ] || [ "$ACTION" = "stratum" ]; } && [ ! -f "$STILL_ALIVE" ]; then
touch "$STILL_ALIVE"
# Loop through devices
for DEV in $DEVICES; do
SYS_PATH="/sys/class/net/$DEV"
if [ -d "$SYS_PATH" ]; then
STATE=$(cat "$SYS_PATH/operstate")
if [ "$STATE" = "up" ]; then
[....time related script launch....]
else
[....]
fi
fi
done
fi
Router is succesfully synced as soon as lan1 is definitely up, and only at that time I launch a time related script; I also need to do something when lan4 is up. I don't need to take action if Router has not actually restarted.
+1. Still waiting to see a failing flash mem because of some writes. And I used the first Sandisk 40MB flash drive about 30 yrs ago, under Win 3.11. Its phys. size was like a box of cigars, and priced like a small Mercedes
Yes. For some flash chips (e.g. Macronix NOR eLiteFlash ca. 2018) the number of erase cycles is limited to 100. Yes, one hundred. Without wear leveling, a single write per day to the same location can kill the flash chip in less than half a year.
I know because I read the datasheets because I was writing drivers for those chips. Fun fact: The low-endurance flash chips had exactly the same electronic ID as reasonable-endurance flash chips from before/after that series.
That's what I have, 4x system ntp servers are all ip addresses, then have an entry in rc.local calling a script to sync time upon successfull ifstatus up of wan.
Works nicely with wireguard, & dot (stubby) upon reboots.
Sounds like you hit the jackpot, then. 8 years ago ... Any flash chips around, from previous years, without wear leveling ? BTW, creating/deleting random files once a day then should reduce/eliminate the risk in your worst case example, or not ? I mean, not to use touch for same file once a day, but to create new random file, and delete previous one.
Wear leveling for raw NAND and raw NOR flash is in almost all cases performed by the file system and/or an intermediate layer in the kernel. With eMMC (a glorified SD) and SD, the wear leveling is in almost all cases internal to the eMMC/SD because those are flash+controller combinations where the controller takes care of wear leveling (some do a very bad job, though).
For flash chips in the 4-32 MByte range, you have almost exclusively raw NOR flash needing wear leveling for heavy writes, but depending on the file system, wear leveling may not be supported. Fortunately, OpenWrt uses JFFS2 for writable partitions on raw NOR flash, and JFFS2 has some wear leveling.