| # Copyright (c) 2011 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. |
| |
| description "Spawns a dumb cron knockoff" |
| author "chromium-os-dev@chromium.org" |
| |
| # We have two scheduled tasks: |
| # - hourly crash reporter |
| # - daily log cleanup and rotation |
| # Instead of pulling in all of cron, we simply run a check every 5 |
| # minutes to see if the last run file for a given task exceeds that |
| # tasks expected "deadline" to run in seconds. If it has, the task is |
| # run. There is no support for de-duping or locking. This means this |
| # shell script is not suitable for tasks that may overlap execution |
| # instances. |
| start on starting system-services |
| stop on stopping system-services |
| |
| script |
| |
| SPOOL_DIR=/var/spool/cron-lite |
| CHECK_DELAY=300 # 5 minutes |
| LOGGER="logger -p local3.info -t $UPSTART_JOB" |
| |
| # comma separated fields, newline separated entries |
| TASKS=" |
| 3600,crash_sender,/sbin/crash_sender |
| 86400,cleanup_logs,/usr/sbin/chromeos-cleanup-logs |
| " |
| |
| # Exits successfully if rotation is needed. |
| should_run() { |
| local name="$1" |
| local delay="$2" |
| local file="$SPOOL_DIR/$name" |
| |
| local last_rotation=0 |
| if [ ! -e $file ]; then |
| touch $file |
| fi |
| last_rotation=$(stat -c "%Y" $file &>/dev/null) |
| if [ $? -ne 0 ]; then |
| last_rotation=0 |
| fi |
| local now=$(date +%s) |
| local time_diff=$((now - last_rotation)) |
| |
| [ $time_diff -lt $delay ] && return 1 |
| $LOGGER "$name needs to be run: $time_diff >= $delay" |
| return 0 |
| } |
| |
| $LOGGER "cleanup main loop started." |
| trap "$LOGGER 'exiting'" EXIT |
| |
| # Avoid weird spool paths if possible |
| test -L /var/spool && unlink /var/spool |
| test -L $SPOOL_DIR && unlink $SPOOL_DIR |
| mkdir -p $SPOOL_DIR |
| if [ ! -O $SPOOL_DIR -o ! -d $SPOOL_DIR ]; then |
| $LOGGER "Spool directory is damaged. Aborting!" |
| exit 1 |
| fi |
| |
| while true; do |
| # Allow the sleep to be killed manually without terminating the handler. |
| sleep $CHECK_DELAY || true |
| printf "$TASKS" | while read task; do |
| delay=$(echo $task | cut -f1 -d,) |
| name=$(echo $task | cut -f2 -d,) |
| script=$(echo $task | cut -f3 -d,) |
| if [ -z "$name" ]; then |
| continue |
| fi |
| if should_run $name $delay; then |
| rm "$SPOOL_DIR/$name" || true |
| touch "$SPOOL_DIR/$name" |
| $LOGGER "running $script for $name" |
| (sh -c "$script" || true; $LOGGER "$name completed") & |
| fi |
| done |
| done |
| |
| end script |
| |