summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Bélanger <snowmaniscool@gmail.com>2010-03-02 04:44:08 +0100
committerPierre Schmitz <pierre@archlinux.de>2010-03-03 21:02:15 +0100
commit17dd60ced8eb8ca461b73dd8429be0fda83264e5 (patch)
tree6622d1d2e10e7b2368b0c43c2c096942331da8df
parent18a74ca61a44a6716f6e3a160cc32efc6cc6cbab (diff)
downloaddbscripts-17dd60ced8eb8ca461b73dd8429be0fda83264e5.tar.gz
dbscripts-17dd60ced8eb8ca461b73dd8429be0fda83264e5.tar.xz
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--config3
-rw-r--r--db-functions48
-rwxr-xr-xmisc-scripts/ftpdir-cleanup10
3 files changed, 42 insertions, 19 deletions
diff --git a/config b/config
index 8e582d9..a563f35 100644
--- a/config
+++ b/config
@@ -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