blob: 05771d4dcdca7eddba0a9deafb06b6ae384ba4be [file] [log] [blame]
#!/bin/sh
# Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Run tasks periodically.
# Usage: $0 <delay_seconds> <timeout_seconds> <task_name> <task_binary>
#
# Executes task <task_name> by running <task_binary> every <delay_seconds>.
set -e -u
SCRIPT_NAME="$(basename "$0")"
CHECK_DELAY=300 # Check every 5 minutes.
KILL_DELAY=10 # How long to let the job clean up after a timeout.
# Let the unittests override.
: ${SPOOL_DIR:=/var/spool/cron-lite}
log() {
logger -p local3.info -t "${SCRIPT_NAME}" "$@"
}
trap "log 'exiting'" EXIT
check_and_fix_spool_paths() {
# Avoid weird spool paths if possible.
rm -f "$(dirname "${SPOOL_DIR}")" "${SPOOL_DIR}" 2>/dev/null || :
mkdir -p "${SPOOL_DIR}"
if [ ! -O "${SPOOL_DIR}" -o ! -d "${SPOOL_DIR}" ]; then
log "Spool directory is damaged. Aborting!"
exit 1
fi
}
main() {
local delay="$1"
local timeout="$2"
local name="$3"
local spool_file="${SPOOL_DIR}/${name}"
shift 3
[ -z "${delay}" ] && exit 1
[ -z "${timeout}" ] && exit 1
[ -z "${name}" ] && exit 1
[ $# -eq 0 ] && exit 1
check_and_fix_spool_paths
while true; do
# Allow the sleep to be killed manually without terminating the handler.
# Send stderr to /dev/null to suppress the shell's "Terminated" message.
sleep $(( CHECK_DELAY + KILL_DELAY )) 2>/dev/null || true
[ ! -e "${spool_file}" ] && touch "${spool_file}"
local last_rotation="$(stat -c "%Y" "${spool_file}" 2>/dev/null || echo 0)"
local now="$(date +%s)"
local time_diff=$((now - last_rotation))
if [ ${time_diff} -gt ${delay} ]; then
rm "${spool_file}" || true
touch "${spool_file}"
log "${name}: running $*"
timeout -k ${KILL_DELAY} ${timeout} "$@" || true
log "${name}: job completed"
fi
done
}
main "$@"