diff options
author | Eric Bélanger <snowmaniscool@gmail.com> | 2010-03-01 22:44:08 -0500 |
---|---|---|
committer | Pierre Schmitz <pierre@archlinux.de> | 2010-03-03 21:02:15 +0100 |
commit | 17dd60ced8eb8ca461b73dd8429be0fda83264e5 (patch) | |
tree | 6622d1d2e10e7b2368b0c43c2c096942331da8df | |
parent | 18a74ca61a44a6716f6e3a160cc32efc6cc6cbab (diff) |
Make repo locking an atomic process and added timeout argument
The repo locking function now use a lock directory instead of a lock
file. This makes the lock checking and creation an atomic process.
The repo_lock function will now try to obtain a lock every $LOCK_DELAY
seconds until it is successful. An optional third argument can be use
to give a timeout in seconds; this is intended for scripts that runs
unattended. Repo locking is now used in the ftpdir-cleanup script.
This should fix the problem of the ftpdir-cleanup script removing the
new package instead of the old one (FS#17058).
Signed-off-by: Eric Bélanger <snowmaniscool@gmail.com>
-rw-r--r-- | config | 3 | ||||
-rw-r--r-- | db-functions | 48 | ||||
-rwxr-xr-x | misc-scripts/ftpdir-cleanup | 10 |
3 files changed, 42 insertions, 19 deletions
@@ -8,6 +8,9 @@ CLEANUP_DESTDIR="/srv/package-cleanup" CLEANUP_DRYRUN=false SOURCE_CLEANUP_DESTDIR="/srv/source-cleanup" +LOCK_DELAY=10 +LOCK_TIMEOUT=300 + STAGING="$HOME/staging" TMPDIR="/srv/tmp" ARCHES=(i686 x86_64) diff --git a/db-functions b/db-functions index c27366c..df50f22 100644 --- a/db-functions +++ b/db-functions @@ -15,27 +15,43 @@ restore_umask () { umask $UMASK } -repo_lock () { #repo_lock repo-name arch - LOCKFILE="$TMPDIR/.repolock.$1.$2" - if [ -f "$LOCKFILE" ]; then - owner="$(/usr/bin/stat -c %U $LOCKFILE)" - echo "error: db generation is already in progress (started by $owner)" >&2 - exit 1 - else - /bin/touch "$LOCKFILE" - if [ ! -f "$LOCKFILE" ]; then - echo "error: could not create repo lock... something went wrong!" >&2 - fi - set_umask +repo_lock () { #repo_lock <repo-name> <arch> [timeout] + LOCKDIR="$TMPDIR/.repolock.$1.$2" + local _count + local _trial + local _timeout + local _lockblock + local _owner + + if [ $# -eq 2 ]; then + _lockblock=true + _trial=0 + elif [ $# -eq 3 ]; then + _lockblock=false + _timeout=$3 + let _trial=$_timeout/$LOCK_DELAY fi + + _count=0 + while [ $_count -le $_trial ] || $_lockblock ; do + if ! mkdir "$LOCKDIR" >/dev/null 2>&1 ; then + _owner="$(/usr/bin/stat -c %U $LOCKDIR)" + echo "error: Repo $1-$2 is already locked by $_owner. Retrying in $LOCK_DELAY seconds..." >&2 + else + set_umask + break + fi + sleep $LOCK_DELAY + let _count=$_count+1 + done } -repo_unlock () { #repo_unlock repo-name arch - LOCKFILE="$TMPDIR/.repolock.$1.$2" - if [ ! -f "$LOCKFILE" ]; then +repo_unlock () { #repo_unlock <repo-name> <arch> + LOCKDIR="$TMPDIR/.repolock.$1.$2" + if [ ! -d "$LOCKDIR" ]; then echo "error: repo lock doesn't exist... something went terribly wrong!" >&2 else - rm -f "$LOCKFILE" + rmdir "$LOCKDIR" fi restore_umask } diff --git a/misc-scripts/ftpdir-cleanup b/misc-scripts/ftpdir-cleanup index a185090..4c559b9 100755 --- a/misc-scripts/ftpdir-cleanup +++ b/misc-scripts/ftpdir-cleanup @@ -10,7 +10,7 @@ dest=$2 ############################################################ -. "$(dirname $0)/../db-functions" +. "$(dirname $0)/../db-functions" . "$(dirname $0)/../config" ${CLEANUP_DRYRUN} && echo 'dry run mode is active' @@ -19,6 +19,8 @@ ftppath_base="$FTP_BASE/$reponame/$FTP_OS_SUFFIX" for arch in ${ARCHES[@]}; do + repo_lock $reponame $arch $LOCK_TIMEOUT + TMPDIR=$(mktemp -d /tmp/cleanup-XXXXXX) || exit 1 ftppath="$ftppath_base/$arch" MISSINGFILES="" @@ -80,10 +82,10 @@ for arch in ${ARCHES[@]}; do dbpkgname=$(grep -A1 '^%FILENAME%$' "${p}/desc" 2>/dev/null| tail -n1) if [ "${dbpkgname}" = "${pkgname}" ]; then continue 2 - fi + fi done EXTRAFILES="$EXTRAFILES $pkg" - done + done rm -rf ${TMPDIR} @@ -100,6 +102,8 @@ for arch in ${ARCHES[@]}; do fi done + repo_unlock $reponame $arch + #Make sure we've done *something* before outputting anything if [ -z "$DELETEFILES$DELETESYMLINKS$MISSINGFILES$EXTRAFILES" ]; then continue |