#!/bin/bash # Sync time via network . /etc/openslx month_num() { case "$1" in Jan) echo 01 ;; Feb) echo 02 ;; Mar) echo 03 ;; Apr) echo 04 ;; May) echo 05 ;; Jun) echo 06 ;; Jul) echo 07 ;; Aug) echo 08 ;; Sep) echo 09 ;; Oct) echo 10 ;; Nov) echo 11 ;; Dec) echo 12 ;; *) echo "INVALID MONTH NAME '$1'" >&2 ;; esac } adjust_rtc() { if [ "$SLX_BIOS_CLOCK" = "local" ]; then usleep 100000 hwclock -l -w || echo "... but could not set BIOS clock to localtime" elif [ "$SLX_BIOS_CLOCK" = "utc" ]; then usleep 100000 hwclock -u -w || echo "... but could not set BIOS clock to UTC" else local rtc sys diff arg re out mon for arg in "-l" "-u"; do rtc= out=$( LC_ALL=C hwclock "$arg" ) re="([A-Za-z]{3})\\s+([0-9]{1,2})\\s+([0-9:]{8})\\s+([0-9]{4})" if [[ $out =~ $re ]]; then mon=$( month_num "${BASH_REMATCH[1]}" ) [ -n "$mon" ] && rtc="${BASH_REMATCH[4]}-${mon}-${BASH_REMATCH[2]} ${BASH_REMATCH[3]}" fi re="[0-9-]{10}\\s+[0-9:]{8}" if [[ $out =~ $re ]]; then rtc="${BASH_REMATCH[0]}" fi if [ -z "$rtc" ]; then echo "Error parsing hwclock output" break fi rtc=$( date -d "$rtc" +%s ) sys=$( date +%s ) if [ -z "$rtc" ] || [ -z "$sys" ]; then echo "Error converting date/time to unix timestamp" break fi diff=$(( sys - rtc )) if [ "$diff" -gt -900 ] && [ "$diff" -lt 900 ]; then # Less than 15 minutes off, assume it's the correct mode hwclock "$arg" -w || echo "... but could not set BIOS clock ($arg)" break fi done fi } # Try to merge with servers from DHCP. Prefer DHCP, skip duplicates for SERVER in $SLX_NTP_SERVER; do if ! echo "$SLX_DHCP_NTP" | grep -wq "$SERVER"; then SLX_DHCP_NTP="$SLX_DHCP_NTP $SERVER" fi done SUCCESS= for SERVER in $SLX_DHCP_NTP; do if timeout 3 ntpd -q -n -p "$SERVER"; then echo "Successfully queried $SERVER for time." adjust_rtc SUCCESS=1 break fi echo "Error querying $SERVER for current time." done if [ -z "$SUCCESS" ]; then echo "No NTP server reachable" # See if we have a timestamp in our server-config - should only be a few seconds off by now if [ -n "$SLX_NOW" ] && [ "$SLX_NOW" -gt 1234567890 ]; then TTS="$SLX_NOW" CONFIG_DOWNLOAD_TIME=$( cat /tmp/config-download-time 2> /dev/null ) if [ -n "$CONFIG_DOWNLOAD_TIME" ]; then # times are in centiseconds NOW_TIME=$(sed -r 's/^([0-9]+)\.([0-9][0-9]).*$/\1\2/' /proc/uptime) if [ "$CONFIG_DOWNLOAD_TIME" -gt 0 ] && [ "$NOW_TIME" -gt 0 ]; then TTS=$(( TTS + ( NOW_TIME - CONFIG_DOWNLOAD_TIME ) / 100 )) fi fi echo "Setting time to SLX_NOW ($SLX_NOW, corrected $TTS)" date -s "@$TTS" adjust_rtc else echo "No fallback option for timesync available, relying on correct RTC setup" if [ "$SLX_BIOS_CLOCK" = "local" ]; then # Linux defaults to RTC = UTC, so read again in this case hwclock -l -s fi fi fi echo "Timesync finished" exit 0