summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoerg Jaspert <joerg@debian.org>2010-01-01 22:55:26 +0100
committerJoerg Jaspert <joerg@debian.org>2010-01-01 22:57:57 +0100
commitc7696b5c7b2e9f033536e57b6cf2beee281ec5bf (patch)
tree5fd286b87fcffc0db1f90eed315121f32ba91649
parentdd604ee0d2ad2a6d06aed3171fddabbd3865245b (diff)
ftpsync locking
have three ways of locking, depending on the bash version old bash (older than 4 :) ) does not have BASHPID variable, nor a good way to find the pid of a backgrounded subshell. so if we have old bash, go the way of guessing if its still running, by comparing the age of the LOCK file or by taking our proc/self target as pid Signed-off-by: Joerg Jaspert <joerg@debian.org>
-rwxr-xr-xbin/ftpsync47
-rw-r--r--etc/ftpsync.conf.sample3
2 files changed, 41 insertions, 9 deletions
diff --git a/bin/ftpsync b/bin/ftpsync
index fc588f1..103c4f2 100755
--- a/bin/ftpsync
+++ b/bin/ftpsync
@@ -251,6 +251,8 @@ LOGROTATE=${LOGROTATE:-14}
# Our lockfile
LOCK=${LOCK:-"${TO}/Archive-Update-in-Progress-${MIRRORNAME}"}
+# timeout for the lockfile, in case we have bash older than v4 (and no /proc)
+LOCKTIMEOUT=${LOCKTIMEOUT:-3600}
# Do we need another rsync run?
UPDATEREQUIRED="${TO}/Archive-Update-Required-${MIRRORNAME}"
# Trace file for mirror stats and checks (make sure we get full hostname)
@@ -337,8 +339,17 @@ HUB=${HUB:-"false"}
function mainroutine() {
if [ $BASH_SUBSHELL -gt 0 ]; then
log "Mirrorrun is done backgrounded"
- # Update our pid in our lockfile. Helps for the cases we go background
- echo "${BASHPID}" > "${LOCK}"
+ # Old bash sucks, no easy way to get the PID of a backgrounded function
+ # So if thats true, dont update the pid. The script has to do other things
+ # to find out if we are still there.
+ if [ ${BASH_VERSINFO[0]} -gt 3 ]; then
+ # Update our pid in our lockfile. Helps for the cases we go background
+ echo "${BASHPID}" > "${LOCK}"
+ elif [ -L /proc/self ]; then
+ echo $(basename $(readlink -f /proc/self)) > "${LOCK}"
+ else
+ echo "$$" > "${LOCK}"
+ fi
fi
# Look who pushed us and note that in the log.
log "Mirrorsync start"
@@ -531,13 +542,31 @@ touch "${UPDATEREQUIRED}"
# Check to see if another sync is in progress
if ! ( set -o noclobber; echo "$$" > "${LOCK}") 2> /dev/null; then
- if ! $(kill -0 $(cat ${LOCK}) 2>/dev/null); then
- # Process does either not exist or is not owned by us.
- echo "$$" > "${LOCK}"
- else
- echo "Unable to start rsync, lock file still exists, PID $(cat ${LOCK})"
- exit 1
- fi
+ if [ ${BASH_VERSINFO[0]} -gt 3 ] || [ -L /proc/self ]; then
+ # We have a recent enough bash version, lets do it the easy way,
+ # the lock will contain the right pid, thanks to $BASHPID
+ if ! $(kill -0 $(cat ${LOCK}) 2>/dev/null); then
+ # Process does either not exist or is not owned by us.
+ echo "$$" > "${LOCK}"
+ else
+ echo "Unable to start rsync, lock file still exists, PID $(cat ${LOCK})"
+ exit 1
+ fi
+ else
+ # Old bash, means we dont have the right pid in our lockfile
+ # So take a different way - guess if it is still there by comparing its age.
+ # Not optimal, but hey.
+ stamptime=$(date --reference="${LOCK}" +%s)
+ unixtime=$(date +%s)
+ difference=$(( $unixtime - $stamptime ))
+ if [ ${difference} -ge ${LOCKTIMEOUT} ]; then
+ # Took longer than 60 minutes? Assume it broke and take the lock
+ echo "$$" > "${LOCK}"
+ else
+ echo "Unable to start rsync, lock file younger than one hour"
+ exit 1
+ fi
+ fi
fi
# When we exit normally we call cleanup on our own. Otherwise we want it called by
diff --git a/etc/ftpsync.conf.sample b/etc/ftpsync.conf.sample
index 8310fb2..b96c3d8 100644
--- a/etc/ftpsync.conf.sample
+++ b/etc/ftpsync.conf.sample
@@ -78,6 +78,9 @@
## Our own lockfile (only one sync should run at any time)
#LOCK="${TO}/Archive-Update-in-Progress-${MIRRORNAME}"
+# Timeout for the lockfile, in case we have bash older than v4 (and no /proc)
+# LOCKTIMEOUT=${LOCKTIMEOUT:-3600}
+
## The following file is used to make sure we will end up with a correctly
## synced mirror even if we get multiple pushes in a short timeframe
#UPDATEREQUIRED="${TO}/Archive-Update-Required-${MIRRORNAME}"