#
# Copyright (c) 2005 XenSource Ltd.
+# Copyright (c) 2007 Red Hat
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# Serialisation
#
-LOCK_SLEEPTIME=1
-LOCK_SPINNING_RETRIES=5
-LOCK_RETRIES=100
LOCK_BASEDIR=/var/run/xen-hotplug
-
-claim_lock()
-{
- local lockdir="$LOCK_BASEDIR/$1"
- mkdir -p "$LOCK_BASEDIR"
- _claim_lock "$lockdir"
-}
-
-
-release_lock()
+_setlockfd()
{
- _release_lock "$LOCK_BASEDIR/$1"
+ local i
+ for ((i = 0; i < ${#_lockdict}; i++))
+ do [ -z "${_lockdict[$i]}" -o "${_lockdict[$i]}" = "$1" ] && break
+ done
+ _lockdict[$i]="$1"
+ let _lockfd=200+i
}
-# This function will be redefined in xen-hotplug-common.sh.
-sigerr() {
- exit 1
-}
-
-
-_claim_lock()
-{
- local lockdir="$1"
- local owner=$(_lock_owner "$lockdir")
- local retries=0
-
- while [ $retries -lt $LOCK_RETRIES ]
- do
- mkdir "$lockdir" 2>/dev/null && trap "_release_lock $lockdir; sigerr" ERR &&
- _update_lock_info "$lockdir" && return
-
- local new_owner=$(_lock_owner "$lockdir")
- if [ "$new_owner" != "$owner" ]
- then
- owner="$new_owner"
- retries=0
- else
- local pid=$(echo $owner | cut -d : -f 1)
- if [ -n "$pid" -a "$pid" != "unknown" -a ! -f "/proc/$pid/status" ]
- then
- _release_lock $lockdir
- fi
- fi
-
- if [ $retries -gt $LOCK_SPINNING_RETRIES ]
- then
- sleep $LOCK_SLEEPTIME
- else
- sleep 0
- fi
- retries=$(($retries + 1))
- done
- _steal_lock "$lockdir"
-}
-
-
-_release_lock()
-{
- trap sigerr ERR
- rm -rf "$1" 2>/dev/null || true
-}
-
-
-_steal_lock()
-{
- local lockdir="$1"
- local owner=$(cat "$lockdir/owner" 2>/dev/null || echo "unknown")
- log err "Forced to steal lock on $lockdir from $owner!"
- _release_lock "$lockdir"
- _claim_lock "$lockdir"
-}
-
-
-_lock_owner()
+claim_lock()
{
- cat "$1/owner" 2>/dev/null || echo "unknown"
+ mkdir -p "$LOCK_BASEDIR"
+ _setlockfd $1
+ eval "exec $_lockfd>>$LOCK_BASEDIR/$1"
+ flock -x $_lockfd
}
-_update_lock_info()
+release_lock()
{
- echo "$$: $0" >"$1/owner"
+ _setlockfd $1
+ flock -u $_lockfd
}