diff --git a/bin/singlestart.sh b/bin/singlestart.sh index 61d20edd955125ae965aad5bc11ccedecc11c531..df3f158329d0dd11f0552c047d4cf7d1d011873e 100755 --- a/bin/singlestart.sh +++ b/bin/singlestart.sh @@ -10,39 +10,42 @@ bootnodekeyfile=${BFANETWORKDIR}/bootnode/key # Bail out if anything fails. trap "exit 1" ERR # Detect children dying -trap "reaper" SIGINT SIGCHLD -unset LOGDIR LOGPIPE PIDIDX -declare -A PIDIDX -trap "killallprocs" SIGTERM +trap "reaper" SIGCHLD +trap "killprocs" SIGTERM +trap "killallprocs" EXIT +unset LOGPIPE PIDIDX ALLPIDIDX TMPDIR SHUTTING_DOWN +declare -A PIDIDX ALLPIDIDX +SHUTTING_DOWN=0 function reaper() { - local wecare=0 + local reaped_a_child_status=0 + # Find out which child died for pid in ${!PIDIDX[*]} do kill -0 $pid 2>/dev/null && continue + reaped_a_child_status=1 local rc=0 wait $pid || rc=$? || true - echo "*** ${PIDIDX[$pid]} (pid $pid) has exited with value $rc" + local name=${PIDIDX[$pid]} + echo "*** $name (pid $pid) has exited with value $rc" + if [ $name = 'geth' ]; then geth_rc_status=$rc; fi unset PIDIDX[$pid] - wecare=1 done - test $wecare = 1 || return - # kill all - an extra kill doesn't hurt. I hope. + # Return if we didn't find out which child died. + if [ $reaped_a_child_status = 0 ]; then return; fi + # Kill all other registered processes for pid in ${!PIDIDX[*]} do - # don't kill log.sh, because it may still be logging for us - if [ "${PIDIDX[$pid]}" != "log.sh" ] - then - echo "*** Killing ${PIDIDX[$pid]} (pid $pid)." - kill $pid || true - fi + kill -0 $pid 2>/dev/null || continue + echo "*** Killing ${PIDIDX[$pid]} (pid $pid)." + kill $pid || true done - max=30 } -function killallprocs() +function killprocs() { + SHUTTING_DOWN=1 if [ ${#PIDIDX[*]} -gt 0 ] then echo "*** Killing all remaining processes: ${PIDIDX[*]} (${!PIDIDX[*]})." @@ -50,6 +53,30 @@ function killallprocs() fi } +function killallprocs() +{ + # merge the 2 pid list, to make killing and echoing easier + for pid in ${!ALLPIDIDX[*]} + do + PIDIDX[$pid]=${ALLPIDIDX[$pid]} + unset ALLPIDIDX[$pid] + done + killprocs + if [ -n "$TMPDIR" -a -e "$TMPDIR" ] + then + rm -rf "$TMPDIR" + fi +} + +function startgeth() +{ + echo "***" Starting geth $* + # "NoPruning=true" means "--gcmode archive" + geth --config ${BFATOML} $* & + gethpid=$! + PIDIDX[${gethpid}]="geth" +} + # You can start as: # BFAHOME=/home/bfa/bfa singlestart.sh # singlestart.sh /home/bfa/bfa @@ -75,8 +102,19 @@ else fi source ${BFAHOME}/bin/libbfa.sh +TMPDIR=$( mktemp -d ) +mknod ${TMPDIR}/sleeppipe p +sleep 987654321 > ${TMPDIR}/sleeppipe & +ALLPIDIDX[$!]='sleep' if [ "$VIRTUALIZATION" = "DOCKER" ] then + echo + echo + echo + echo + date + echo $0 startup + echo echo "See log info with \"docker logs\"" else echo "Logging mostly everything to ${BFANODEDIR}/log" @@ -86,21 +124,40 @@ else # Docker has it's own logging facility, so we will not use our own # logging functionality if we're in docker. echo "*** Setting up logging." - # Clean up logging - LOGDIR=$( mktemp -d ) - trap "rm -rf ${LOGDIR}" EXIT - LOGPIPE=${LOGDIR}/logpipe + LOGPIPE=${TMPDIR}/logpipe mknod ${LOGPIPE} p ${BFAHOME}/bin/log.sh ${BFANODEDIR}/log < ${LOGPIPE} & - PIDIDX[$!]="log.sh" + # Separate pididx for processes we don't want to send signals to + # until in the very end. + ALLPIDIDX[$!]="log.sh" exec > ${LOGPIPE} 2>&1 fi -echo "*** Starting geth." -# "NoPruning=true" means "--gcmode archive" -geth --config ${BFATOML} & -PIDIDX[$!]="geth" +function sleep() +{ + read -t ${1:-1} < ${TMPDIR}/sleeppipe || true +} + +# Start a sync +startgeth --exitwhensynced +echo "*** Starting monitor.js" +monitor.js & +PIDIDX[$!]="monitor.js" + +# geth will exit when it has synced, then we kill it's monitor. +# Then wait here for their exit status to get reaped +while [ "${#PIDIDX[*]}" -gt 0 ]; do sleep 1; done + +# if it went well, start a normal geth (to run "forever") +test $geth_rc_status = 0 || exit $geth_rc_status +test "$SHUTTING_DOWN" != 0 && exit 0 +# regular geth +startgeth +# monitor +echo "*** Starting monitor.js" + monitor.js & +PIDIDX[$!]="monitor.js" # bootnode if [ -r "$bootnodekeyfile" ] then @@ -109,16 +166,4 @@ then PIDIDX[$!]="bootnode" fi -echo "*** Starting monitor.js" -monitor.js & -PIDIDX[$!]="monitor.js" - -max=-1 -# Exit if only 1 process remains - we hope it is log.sh, but either way, -# it is time to end. -while [ "${#PIDIDX[*]}" -gt 1 -a $max -ne 0 ] -do - sleep 1 - max=$(( $max - 1 )) -done -killallprocs +while [ "${#PIDIDX[*]}" -gt 0 ]; do sleep 1; done