#!/bin/sh cd /var/log/ntpstats || exit 1 LOCKF=reset_ntp.lock ntpdrift_good=`sed 's/\.//' ]" 1>&2 exit 1 fi done if [[ "$min_ddiff" == "" ]] then min_ddiff=$((ntpdrift_agood / 400 + 500 )) min_plloff=25 [[ $verbose -gt 0 ]] && echo "min_ddiff: $min_ddiff ($ntpdrift_agood / 400 + 500) min_plloff: $min_plloff" fi # find the ntp hosts that we can get time from . /etc/default/ntpdate if [[ -z "$NTPSERVERS" ]] then exit 0 elif [[ $verbose -gt 0 ]] then echo "ntp servers: $NTPSERVERS" fi # if we are not connected to the net, we can't check the time LOC=`/usr/local/sbin/laptop_state` if [[ "$LOC" == "ROAM" ]] then [[ $verbose -gt 0 ]] && echo "Not connected to the net (ROAM)" exit fi # not exactly the most secure locking system, but... find . -name "$LOCKF" -mmin +30 -exec rm '{}' \; if [[ -f $LOCKF ]] then echo "`basename $0` is already running." 1>&2 exit 1 fi touch $LOCKF trap "rm -f $LOCKF" 0 1 2 3 15 #trap "echo \`date +'%D %T'\` \$SECONDS >>reset_times.log; rm -f $LOCKF" 0 # sometimes when you reset the clock, ntp gets off to a bad start with # a very large difference in the drift. We may have to reset it several times. num_check=0 while [[ $num_check -lt 4 ]] do num_check=$((num_check + 1)) if [[ $num_check -gt 1 ]] then # wait for the ntp daemon to get some useful data sleep 64 & spid=$! if [[ $verbose -gt 0 ]] then ntp-wait -v else ntp-wait fi wait $spid fi # figure out how far the current drift is from the known good value ntpdrift=`ntpq -c rv 2>/dev/null | sed -n '/frequency/ { s/.*frequency=\(-*[0-9]*\)\.\([0-9]*\),* *.*/\1\2/; p }'` ntpdrift_diff=$((ntpdrift - ntpdrift_good)) [[ $ntpdrift_diff -lt 0 ]] && ntpdrift_diff=$(( -ntpdrift_diff )) ntperr=`ntpdc -c kerninfo | grep "^estimated error" | sed -e "s/^.* *\([0-9]*\)\.\([0-9][0-9][0-9]\)[0-9]* s$/\1\2/" -e "s/^\(-*\)0*\([0-9]\)/\1\2/" -e "s/^.* *[.0-9]*e-[0-9][0-9] s$/0/"` ntpplloff=`ntpdc -c kerninfo | grep "^pll offset:" | sed -e "s/^.* *\(-*[0-9]*\)\.\([0-9][0-9][0-9]\)[0-9]* s$/\1\2/" -e "s/^.* *0 s$/0/" -e "s/^\(-*\)0*\([0-9]\)/\1\2/" -e "s/^.* *-*[.0-9]*e-[0-9][0-9] s$/0/"` ntpplloffa=$ntpplloff [[ $ntpplloffa -lt 0 ]] && ntpplloffa=$(( -ntpplloffa )) ntpoffset=`ntpq -c rv 2>/dev/null | sed -n -e '/offset/ { s/.*offset=\(-*[0-9]*\)\.\([0-9]*\),* .*/\1\2/; p }' | sed -e "s/^\(-*\)0*\([0-9]\)/\1\2/"` # see how far we have drifted since the last time we did an ntpdate if [[ -r last_ntpdate ]] then read >ntpdate_delta.log else ntpdate_delta=999999999 fi # if the current drift is close enough, then don't bother check further [[ $verbose -gt 0 ]] && echo "$num_check -eq 1 && $force -eq 0 && ( $ntpdate_delta -le 10000 || (( $ntpdrift_diff -le $min_ddiff || $ntpplloffa -le $min_plloff ) && $ntpdrift_diff -le $((min_ddiff * 3)) ))" if [[ $num_check -eq 1 && $force -eq 0 && ( $ntpdate_delta -le 10000 || (( $ntpdrift_diff -le $min_ddiff || $ntpplloffa -le $min_plloff ) && $ntpdrift_diff -le $((min_ddiff * 3)) )) ]] then [[ $verbose -gt 0 ]] && echo "Quick check exit: ntpdrift_diff: $ntpdrift_diff est error: $ntperr pll offset: $ntpplloff rv offset: $ntpoffset ntpdate_delta: $ntpdate_delta" # echo "checking ntpd: `date +'%D %T'` drift: $ntpdrift_diff (quick exit) pll offset: $ntpplloff delta: $ntpdate_delta" >>est_error.log exit 0 fi # get the current time and see how far off we are. ntpout=`ntpdate -q $NTPSERVERS` offset=`echo "$ntpout" | grep "\(step\|adjust\) time server" | sed -e "s/.* offset \([0-9.-]*\) sec.*/\1/" | awk '{if ( $0 < 0 ) { print int( $0 * 1000 - .5 ) } else {print int( $0 * 1000 + .5)}}'` if [[ "x$offset" == "x" ]] then [[ $verbose -gt 0 ]] && echo "Could not get offset: $ntpout" exit 0 fi echo >last_ntpdate `date +%s` $ntpplloff $ntpdrift_diff # make sure that abnormal delays don't fool us time_check=0 while [[ $time_check -lt 4 ]] do sleep $(( time_check * 3 + 2 )) ntpout=`ntpdate -q $NTPSERVERS` offset2=`echo "$ntpout" | grep "\(step\|adjust\) time server" | sed -e "s/.* offset \([0-9.-]*\) sec.*/\1/" | awk '{if ( $0 < 0 ) { print int( $0 * 1000 - .5 ) } else {print int( $0 * 1000 + .5)}}'` if [[ "x$offset2" == "x" ]] then [[ $verbose -gt 0 ]] && echo "Could not get offset: $ntpout" sleep 30 offset2=$(( offset + 999 )) fi delta=$(( offset - offset2 )) if [[ $delta -lt 16 && $delta -gt -16 ]] then break fi [[ $verbose -gt 0 ]] && echo "unstable time returned from ntpdate. offsets: ( $offset - $offset2 ) = $delta" offset=$offset2 time_check=$((time_check + 1)) done if [[ $time_check -ge 4 ]] then echo "Error: Could not get ntpdate to return a stable time." 1>&2 exit 1 fi # calculate the maximum allowable offset ntppoll=`ntpq -c rv 2>/dev/null | sed -n '/poll/ { s/.*poll=\([0-9]*\),.*/\1/; p }'` max_ddiff=$(((ntppoll * ntpdrift_agood) / 150 + 1500 )) [[ $verbose -gt 0 ]] && echo "max_ddiff: $max_ddiff ($ntppoll * $ntpdrift_agood / 150 + 1500)" echo "checking ntpd: `date +'%D %T'` drift: $ntpdrift_diff offset: $offset pll offset: $ntpplloff delta: $ntpdate_delta" >>est_error.log [[ $verbose -gt 0 ]] && echo "checking ntpd: `date +'%D %T'` drift: $ntpdrift_diff offset: $offset pll offset: $ntpplloff delta: $ntpdate_delta" # restart the ntp server, if needed if [[ $time_check -lt 4 && ( $offset -ge 75 || $offset -le -75 || $ntpdrift_diff -gt $max_ddiff || $force -eq 1 ) ]] then echo "Resetting time: $offset ms ($time_check) `date +'%D %T'` $((`TZ=GMT date '+((%H * 60) + %M) * 60 + %S' | sed 's/0\([1-9]\)/\1/g'`))" echo "drift good: $ntpdrift_good current: $ntpdrift diff: $ntpdrift_diff" /etc/init.d/ntp-server stop | grep -v "Stopping NTP server: ntpd." bad_ntp=`ps auwx | grep ntpd | grep -v grep` if [[ "$bad_ntp" != "" ]] then echo "kill the outstanding ntp process" echo "$bad_ntp" fi touch $LOCKF if ! cmp --quiet /var/lib/ntp/ntp.drift.good /var/lib/ntp/ntp.drift then echo "replacing ntp drift info `cat /var/lib/ntp/ntp.drift` with `cat /var/lib/ntp/ntp.drift.good`" cp -a /var/lib/ntp/ntp.drift.good /var/lib/ntp/ntp.drift fi /etc/init.d/ntp-server start | grep -v "Starting NTP server: ntpd." sleep 2 echo else if [[ $verbose -gt 0 ]] then echo "*NOT* Resetting time: $offset ms ($time_check) `date +'%D %T'` $((`TZ=GMT date '+((%H * 60) + %M) * 60 + %S' | sed 's/0\([1-9]\)/\1/g'`))" echo "drift good: $ntpdrift_good current: $ntpdrift diff: $ntpdrift_diff" fi if [[ $num_check -eq 1 ]] then exit 0 fi touch $LOCKF fi force=0 done