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