Tiny Core Linux

Tiny Core Base => TCB Bugs => Topic started by: y_satou70 on July 17, 2018, 12:27:23 AM

Title: TC9.0 /etc/init.d/settime.sh broken
Post by: y_satou70 on July 17, 2018, 12:27:23 AM
Just found this issue while I replace my box's coin battery on motherboard....
/etc/init.d/settime.sh is failed to set time due to following code:

Code: [Select]
        XXX=$(/bin/date -I)
        XXX=${XXX:0:4}

        if [ "$XXX" -ge "2015" ];
        then
            break
        fi

not sure why this logic is implemented here, but due to this code, this script do nothing since 2015...

I checked both x86 and x86_64, both distribution core.gz / corepure64.gz has this bug.
Title: Re: TC9.0 /etc/init.d/settime.sh broken
Post by: Greg Erskine on July 17, 2018, 12:56:08 AM
hi y_satou70,

I "think" if the code was really broken someone would have noticed by now.  ;)

My "guess" is it is testing that the time is not epoch therefore the time has been set by a rtc. If time set by rtc then don't run ntp. The year 2015 was probably chosen as it was the year the fix was added. ???

regards
Greg
Title: Re: TC9.0 /etc/init.d/settime.sh broken
Post by: curaga on July 17, 2018, 03:31:45 AM
Yes, the logic works if your board was manufactured before 2015 and so sets its date to an epoch before that. Updating to 2018.
Title: Re: TC9.0 /etc/init.d/settime.sh broken
Post by: y_satou70 on July 17, 2018, 04:08:55 AM
oh wait, does it mean if system board 's clock has any timestamp 2018 then it does not do any set clock action ?
I think if boot option has "ntpserver=...." entry, it should pull current time from ntpserver and set it at booting regardless what time currently system board has.
And if it's expected that the time is set from RTC and that's good enough, then that system just need to omit "ntpserver=...." entry on boot option.
Title: Re: TC9.0 /etc/init.d/settime.sh broken
Post by: curaga on July 17, 2018, 10:16:03 AM
Yes. The current edition of settime.sh was written by Bela for rpi boards, which do not have a RTC. It also works for boards whose battery has run out.

Would you like to send a patch?
Title: Re: TC9.0 /etc/init.d/settime.sh broken
Post by: y_satou70 on July 20, 2018, 04:13:19 AM
not really as the patch, but simply nuke year check should be sufficient.

Code: [Select]
box:/etc/init.d$ diff settime.sh.orig settime.sh
--- settime.sh.orig
+++ settime.sh
@@ -16,14 +16,6 @@
     NRT=0
     while sleep 0
     do
-        XXX=$(/bin/date -I)
-        XXX=${XXX:0:4}
-
-        if [ "$XXX" -ge "2015" ];
-        then
-            break
-        fi
-
         if [ $CNT -gt 10 ];
         then
             /usr/bin/getTime.sh
box:/etc/init.d$


Title: Re: TC9.0 /etc/init.d/settime.sh broken
Post by: curaga on July 20, 2018, 10:13:44 AM
I believe that would cause issues on rpi with separate rtc. Those boot somewhat slow, and their users don't want the additional time taken by this if they already have a rtc set up. So conflicting requirements somewhat.
Title: Re: TC9.0 /etc/init.d/settime.sh broken
Post by: y_satou70 on July 21, 2018, 12:43:20 AM
I think that is the reason why we now have "nortc" in boot option, so those devices just need to set it.

in current 9.x code /etc/init.d/tc-config:
Code: [Select]
echo -n "${BLUE}Checking boot options...${NORMAL}"
for i in `cat /proc/cmdline`; do
case $i in
*)
case $i in
nortc) NORTC=1 ;;
esac
;;
esac
done

    ....

if [ -n "$NORTC" ]; then
echo "${BLUE}Skipping rtc as requested from the boot command line.${NORMAL}"
fi

if [ -n "$NODHCP" ]; then
echo "${GREEN}Skipping DHCP broadcast/network detection as requested on boot commandline.${NORMAL}"
else
[ -z "$DHCP_RAN" ] && /etc/init.d/dhcp.sh &
[ -z "$NORTC" ] || /etc/init.d/settime.sh &
fi

so the correct approach for this issue is,
Title: Re: TC9.0 /etc/init.d/settime.sh broken
Post by: curaga on July 21, 2018, 07:21:08 AM
They do want the correct time, booting with nortc leaves the time as the epoch...
Title: Re: TC9.0 /etc/init.d/settime.sh broken
Post by: y_satou70 on July 25, 2018, 10:23:27 AM
Hm, I think even in current code, the case

> ... cause issues on rpi with separate rtc. Those boot somewhat slow, and their users don't want the additional time taken by this if they already have a rtc set up.

does not handle like

> They do want the correct time, booting with nortc leaves the time as the epoch...

Because, even using RPi with separate slow RTC, if they do not set "nortc", it just wait until RTC device becomes available anyway.

As in current code, if "nortc" is *not* set then, we have eternal loop until /dev/rtc0 becomes available:

Code: [Select]
if [ -n "$NORTC" ]; then
echo "${BLUE}Skipping rtc as requested from the boot command line.${NORMAL}"
else
while [ ! -e /dev/rtc0 ]; do usleep 50000; done
if [ -n "$NOUTC" ]; then
/sbin/hwclock -l -s &
else
/sbin/hwclock -u -s &
fi
fi

so if they want to speed up the boot then they have to set "nortc" anyway.
Then in latter of this script,

Code: [Select]
[ -z "$NORTC" ] || /etc/init.d/settime.sh &

so if "nortc" is set, it won't refer ntpserver to set the time from ntpserver....
Title: Re: TC9.0 /etc/init.d/settime.sh broken
Post by: bmarkus on July 25, 2018, 11:38:55 AM
so if "nortc" is set, it won't refer ntpserver to set the time from ntpserver....

For RPi nortc is the default in command line. If there is Ethernet connected and network is up, RPi system time is set up during boot from NTP server.
Title: Re: TC9.0 /etc/init.d/settime.sh broken
Post by: y_satou70 on July 26, 2018, 11:20:04 AM
I see, so on RPi, it runs /etc/init.d/settime.sh -> /usr/bin/getTime.sh  by default.
then still not sure why we need to skip 2015 or later if we see on OS/kernel clock. shouldn't it be controlled by ntpserver boot option is set or not ...?
Title: Re: TC9.0 /etc/init.d/settime.sh broken
Post by: Greg Erskine on July 26, 2018, 03:45:57 PM
Hi y_satou70.

ntpserver bootcode:

Code: [Select]
Define alternative Network Time Protocol (ntp) server
<ntpserver=xxx.xxx.xxx.xxx> or <ntpserver=FQDN>
Default: pool.ntp.org

regards
Greg
Title: Re: TC9.0 /etc/init.d/settime.sh broken
Post by: y_satou70 on July 27, 2018, 10:44:16 AM
yeah, I meant, if ntpserver=..... is set in boot option then it should always try to set time by NTP with specified ntpserver in bootoption, regardless what time currently OS/kernel has.

* If the system does not have RTC, then simply set "nortc". then it skip the logic to set OS/kernel clock from RTC/hardware clock (in /etc/init.d/tc-config)
* If system (regardless it's x86 or RPi) wants to set OS/kernel clock by NTP, then set ntpserver=... in boot option. And if this option is specified then it should sync the clock by NTP with using NTP server which is specified in ntpserver=... option., and regardless the time which RTC/hadware clock has.

that is my proposal and code diff for /etc/init.d/settime.sh

And,

> I believe that would cause issues on rpi with separate rtc. Those boot somewhat slow, and their users don't want the additional time taken by this if they already have a rtc set up. So conflicting requirements somewhat.

I'm afraid not following this part - "those boot somewhat slow" - slow for becoming RTC device available from OS ? or slow for syncing OS/kernel clock with ntpserver by /usr/bin/ntpd ?
Title: Re: TC9.0 /etc/init.d/settime.sh broken
Post by: curaga on July 27, 2018, 10:54:18 AM
Removing the date check as in your patch would result in systems that didn't need a NTP check now doing one. I agree that if the user gave a ntpserver= bootcode, then the NTP check should happen no matter what the time was. We'd need the proper logic for that - marking it as set in tc-config and then testing for this in the date check in setTime.sh.
Title: Re: TC9.0 /etc/init.d/settime.sh broken
Post by: y_satou70 on July 27, 2018, 11:22:33 AM
also logically this part is also wrong in /etc/init.d/tc-config:

Code: [Select]
# After restore items
if [ -n "$NODHCP" ]; then
echo "${GREEN}Skipping DHCP broadcast/network detection as requested on boot commandline.${NORMAL}"
else
[ -z "$DHCP_RAN" ] && /etc/init.d/dhcp.sh &
[ -z "$NORTC" ] || /etc/init.d/settime.sh &
fi

by this logic, settime.sh won't be ran if "nodhcp" is set in boot option.
settime.sh has dependency for network availability (as it tries to set time by NTP), but network availability shouldn't be depending on using DHCP or not. Even static IP + gateway/route setting (use /etc/init.d/rcS as described in http://forum.tinycorelinux.net/index.php?topic=21290.0), network becomes working state, then enable to sync time with NTP.

so my proposal is

Code: [Select]
--- tc-config.orig
+++ tc-config
@@ -613,8 +613,8 @@
  echo "${GREEN}Skipping DHCP broadcast/network detection as requested on boot commandline.${NORMAL}"
 else
  [ -z "$DHCP_RAN" ] && /etc/init.d/dhcp.sh &
- [ -z "$NORTC" ] || /etc/init.d/settime.sh &
 fi
+[ -n "$NTPSERVER" ] && /etc/init.d/settime.sh &

 [ -n "$CRON" ] && /etc/init.d/services/crond start

--- settime.sh.orig
+++ settime.sh
@@ -16,14 +16,6 @@
     NRT=0
     while sleep 0
     do
-        XXX=$(/bin/date -I)
-        XXX=${XXX:0:4}
-
-        if [ "$XXX" -ge "2015" ];
-        then
-            break
-        fi
-
         if [ $CNT -gt 10 ];
         then
             /usr/bin/getTime.sh
tc@tc-008064c770c2:/etc/init.d$

and the rule is:

* if want to skip (do not want) setting OS/kernel time from RTC/hardware clock, then set "nortc"
* if want to set OS/kernel time from NTPserver, then set "ntpserver=(IPaddr)" or "ntpserver=(FQDN)"

do we see any problem with this rule for RPi devices ?
Title: Re: TC9.0 /etc/init.d/settime.sh broken
Post by: centralware on July 29, 2018, 03:19:08 AM
Attempting to maintain everyone's input with the option to skip everything (ie: if there's no NIC detected settime.sh would be a waste of effort/time)
I've also added to my notes (for a later date) to consider DHCP NTP option (especially if there's a local NTP!) and a few other items.

Code: [Select]
#!/bin/sh

##############
# SetTime.sh # /etc/init.d/settime.sh
###############################################################################
# This script is intended as a replacement for the existing init.d/settime.sh #
# which SHOULD take into account RasPi (with or without RTC), motherboards    #
# with dead clock batteries or systems which are perfectly fine regardless.   #
###############################################################################
#           Copyright © 1994-2018, CentralWare Development Centers            #
###############################################################################
# * ntpserver=time.nist.gov can be used to SET the server and FORCE the call  #
# * nosettime as a boot code will forcefully SKIP doing anything below        #
###############################################################################
. /etc/init.d/tc-functions


UPDATE=0; BOTHER=1; NODHCP=0; SKIP=0; CALL_UPDATE=0
test=$(cat /proc/cmdline | grep ntpserver);
if [ ! "${test}" == "" ]; then
for i in `cat /proc/cmdline`; do
  case $i in
    *=*)
      case $i in
        ntpserver*) NTPSERVER=${i#*=}; BOTHER=1; UPDATE=1; CALL_UPDATE=1 ;;
      esac
      ;;
    *)
      case $i in
        nosettime) SKIP=1 ;;
        nodhcp)    NODHCP=1 ;;
        nortc)     BOTHER=1; UPDATE=1; CALL_UPDATE=1 ;;
      esac
      ;;
  esac
done
fi


if [ $SKIP -ge 1 ]; then BOTHER=0; UPDATE=0; exit 0; fi


for i in $@; do
  case $i in
    -m) UPDATE=1; BOTHER=1; CALL_UPDATE=1 ;;
  esac
done


CUR=$(date -I); CUR=${CUR:0:4} # Current YEAR


# See if we're running on a Raspberry Pi
PICORE=0; if [ ! "$(uname -r | grep piCore)" == "" ]; then PICORE=1; fi


# There's no sense even doing anything NETWORK related if there's no NIC #
NICS=$(ifconfig -a | grep HWaddr); if [ "${NICS}" == "" ]; then BOTHER=0; fi



if [ $BOTHER -ge 1 ]; then


    if [ $UPDATE -ge 1 ]; then


        # Assuming static ifconfig or DHCP, wait for the network to settle
        echo -n "${CYAN}Waiting for network${NORMAL}: "
        CNT=0
        until ifconfig | grep -q Bcast; do
            [ $((CNT++)) -gt 60 ] && break || sleep 1
        done


        test=$(ifconfig | grep Bcast)
        if [ ! "${test}" == "" ]; then echo "${GREEN}OK${NORMAL}"; else echo "${RED}OFFLINE${NORMAL}"; UPDATE=0; fi


        if [ $UPDATE -ge 1 ]; then
            OLD=$(cat /etc/sysconfig/tcedir/curyear >/dev/null 2>&1)
            if [ ! "${OLD}" == "${CUR}" ]; then CALL_UPDATE=1; fi
        fi


    fi


fi


if [ $PICORE -ge 1 ]; then if [ $CUR -le 2015 ]; then CALL_UPDATE=1; fi; fi


if [ $CALL_UPDATE -ge 1 ]; then
    if [ "${NTPSERVER}" == "" ]; then NTPSERVER=$(cat /etc/sysconfig/ntpserver); fi
    echo -n "${CYAN}Calling Time Server${NORMAL}: "
    /usr/sbin/ntpd -d -q -n -N -p $NTPSERVER >/tmp/ntpd.test 2>&1
    test=`cat /tmp/ntpd.test | grep offset`
    if [ ! "${test}" == "" ]; then echo "${GREEN}OK${NORMAL}"; else echo "${RED}FAILED${NORMAL}"; echo $test; fi
fi