Changeset View
Changeset View
Standalone View
Standalone View
contrib/devtools/bitcoind-exit-on-log.sh
#!/usr/bin/env bash | #!/usr/bin/env bash | ||||
export LC_ALL=C | export LC_ALL=C | ||||
set -euxo pipefail | set -euxo pipefail | ||||
# Do not leave any dangling subprocesses when this script exits | |||||
trap "kill 0" SIGINT | |||||
TOPLEVEL=$(git rev-parse --show-toplevel) | TOPLEVEL=$(git rev-parse --show-toplevel) | ||||
DEFAULT_BITCOIND="${TOPLEVEL}/build/src/bitcoind" | DEFAULT_BITCOIND="${TOPLEVEL}/build/src/bitcoind" | ||||
DEFAULT_LOG_FILE=~/".bitcoin/debug.log" | DEFAULT_LOG_FILE=~/".bitcoin/debug.log" | ||||
help_message() { | help_message() { | ||||
set +x | set +x | ||||
echo "Run bitcoind until a given log message is encountered, then kill bitcoind." | echo "Run bitcoind until a given log message is encountered, then kill bitcoind." | ||||
echo "" | echo "" | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | *) | ||||
;; | ;; | ||||
esac | esac | ||||
done | done | ||||
if [ -z "${GREP_PATTERN}" ]; then | if [ -z "${GREP_PATTERN}" ]; then | ||||
echo "Error: A grep pattern was not specified." | echo "Error: A grep pattern was not specified." | ||||
echo "" | echo "" | ||||
help_message | help_message | ||||
exit 1 | exit 2 | ||||
fi | fi | ||||
# Make sure the debug log exists so that tail does not fail | # Make sure the debug log exists so that tail does not fail | ||||
touch "${LOG_FILE}" | touch "${LOG_FILE}" | ||||
# Launch bitcoind using custom parameters | # Launch bitcoind using custom parameters | ||||
read -a BITCOIND_PARAMS <<< "${BITCOIND_PARAMS}" | read -a BITCOIND_PARAMS <<< "${BITCOIND_PARAMS}" | ||||
BITCOIND_PID_FILE=/tmp/bitcoind-exit-on-log.pid | |||||
# Make sure the PID file doesn't already exist for some reason | |||||
rm -f "${BITCOIND_PID_FILE}" | |||||
BITCOIND_PARAMS+=("-pid=${BITCOIND_PID_FILE}") | |||||
BITCOIND_PARAMS+=("-daemon") | |||||
START_TIME=$(date +%s) | START_TIME=$(date +%s) | ||||
if [ "${#BITCOIND_PARAMS[@]}" -gt 0 ]; then | "${BITCOIND}" "${BITCOIND_PARAMS[@]}" | ||||
"${BITCOIND}" "${BITCOIND_PARAMS[@]}" & | |||||
else | # The PID file will not exist immediately, so wait for it | ||||
"${BITCOIND}" & | PID_WAIT_COUNT=0 | ||||
while [ ! -e "${BITCOIND_PID_FILE}" ]; do | |||||
((PID_WAIT_COUNT+=1)) | |||||
if [ "${PID_WAIT_COUNT}" -gt 10 ]; then | |||||
echo "Timed out waiting for bitcoind PID file" | |||||
exit 10 | |||||
fi | fi | ||||
BITCOIND_PID=$! | sleep 0.5 | ||||
done | |||||
BITCOIND_PID=$(cat "${BITCOIND_PID_FILE}") | |||||
# Wait for log checking to finish and kill the daemon | # Wait for log checking to finish and kill the daemon | ||||
( | ( | ||||
# When this subshell finishes, kill bitcoind | # When this subshell finishes, kill bitcoind | ||||
log_subshell_cleanup() { | log_subshell_cleanup() { | ||||
echo "Cleaning up bitcoin daemon (PID: ${BITCOIND_PID})." | echo "Cleaning up bitcoin daemon (PID: ${BITCOIND_PID})." | ||||
kill ${BITCOIND_PID} | kill ${BITCOIND_PID} | ||||
} | } | ||||
Show All 14 Lines | ( | ||||
# Optional callback for interacting with bitcoind before it's killed | # Optional callback for interacting with bitcoind before it's killed | ||||
if [ -n "${CALLBACK}" ]; then | if [ -n "${CALLBACK}" ]; then | ||||
"${CALLBACK}" | "${CALLBACK}" | ||||
fi | fi | ||||
) & | ) & | ||||
LOG_PID=$! | LOG_PID=$! | ||||
# Wait for bitcoind to exit, whether it exited on its own or the log subshell finished | # Wait for bitcoind to exit, whether it exited on its own or the log subshell finished | ||||
wait ${BITCOIND_PID} | set +x | ||||
BITCOIND_EXIT_CODE=$? | while [ -e "${BITCOIND_PID_FILE}" ]; do sleep 0.5; done | ||||
set -x | |||||
if [ "${BITCOIND_EXIT_CODE}" -ne "0" ]; then | # If the log subshell is still running, then GREP_PATTERN was not found | ||||
echo "bitcoind exited unexpectedly with code: ${BITCOIND_EXIT_CODE}" | if [ -e /proc/${LOG_PID} ]; then | ||||
exit ${BITCOIND_EXIT_CODE} | echo "bitcoind exited unexpectedly. See '${LOG_FILE}' for details." | ||||
exit 20 | |||||
fi | fi | ||||
# Get the exit code for the log subshell, which should have exited already | # Get the exit code for the log subshell, which should have exited already | ||||
# if GREP_PATTERN was found | |||||
wait ${LOG_PID} | wait ${LOG_PID} | ||||
LOG_EXIT_CODE=$? | LOG_EXIT_CODE=$? | ||||
# The log subshell should only exit with a non-zero code if the callback | # The log subshell should only exit with a non-zero code if the callback | ||||
# failed. | # failed. | ||||
if [ "${LOG_EXIT_CODE}" -ne "0" ]; then | if [ "${LOG_EXIT_CODE}" -ne "0" ]; then | ||||
echo "Log subshell failed with code: ${LOG_EXIT_CODE}" | echo "Log subshell failed with code: ${LOG_EXIT_CODE}" | ||||
exit ${LOG_EXIT_CODE} | exit ${LOG_EXIT_CODE} | ||||
fi | fi |