From 17dd60ced8eb8ca461b73dd8429be0fda83264e5 Mon Sep 17 00:00:00 2001 From: Eric Bélanger Date: Mon, 1 Mar 2010 22:44:08 -0500 Subject: Make repo locking an atomic process and added timeout argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- db-functions | 48 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 16 deletions(-) (limited to 'db-functions') 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 [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 + 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 } -- cgit v1.2.3-24-g4f1b