Implement per source locking.

This commit is contained in:
Darko Poljak 2016-06-13 13:40:32 +02:00
parent 5356370233
commit 86d5628577
2 changed files with 87 additions and 1 deletions

View file

@ -54,6 +54,67 @@ CDATE="date +%Y%m%d-%H%M"
DDATE="date +%Y-%m-%d-%H:%M:%S" DDATE="date +%Y-%m-%d-%H:%M:%S"
SDATE="date +%s" SDATE="date +%s"
#
# LOCKING: use flock if available, otherwise mkdir
# Locking is done for each source so that only one instance per source
# can run.
#
LOCKDIR="${CSOURCES}"
# printf pattern: ccollect_<source>.lock
LOCKFILE_PATTERN="ccollect_%s.lock"
LOCKFD=4
#
# locking functions using flock
#
lock_flock()
{
# $1 = source to backup
lockfile="${LOCKDIR}/$(printf "${LOCKFILE_PATTERN}" "$1")"
eval "exec ${LOCKFD}> ${lockfile}"
flock -n ${LOCKFD} && return 0 || return 1
}
unlock_flock()
{
# $1 = source to backup
lockfile="${LOCKDIR}/$(printf "${LOCKFILE_PATTERN}" "$1")"
eval "exec ${LOCKFD}>&-"
rm -f "${lockfile}"
}
#
# locking functions using mkdir (mkdir is atomic)
#
lock_mkdir()
{
# $1 = source to backup
lockfile="${LOCKDIR}/$(printf "${LOCKFILE_PATTERN}" "$1")"
mkdir "${lockfile}" && return 0 || return 1
}
unlock_mkdir()
{
# $1 = source to backup
lockfile="${LOCKDIR}/$(printf "${LOCKFILE_PATTERN}" "$1")"
rmdir "${lockfile}"
}
#
# determine locking tool: flock or mkdir
#
if $(which flock > /dev/null 2>&1)
then
lockf="lock_flock"
unlockf="unlock_flock"
else
lockf="lock_mkdir"
unlockf="unlock_mkdir"
fi
# #
# unset values # unset values
# #
@ -63,7 +124,8 @@ USE_ALL=""
# #
# catch signals # catch signals
# #
trap "rm -f \"${TMP}\"" 1 2 15 TRAPFUNC="rm -f \"${TMP}\""
trap "${TRAPFUNC}" 1 2 15
# #
# Functions # Functions
@ -136,6 +198,18 @@ eof
exit 0 exit 0
} }
# locking functions
lock()
{
"${lockf}" "$@" || _exit_err \
"Only one instance of ${__myname} for source \"$1\" can run at one time."
}
unlock()
{
"${unlockf}" "$@"
}
# #
# Parse options # Parse options
# #
@ -287,6 +361,16 @@ while [ "${source_no}" -lt "${no_sources}" ]; do
_exit_err "\"${backup}\" is not a cconfig-directory. Skipping." _exit_err "\"${backup}\" is not a cconfig-directory. Skipping."
fi fi
#
# Acquire lock for source. If lock cannot be acquired, lock will exit
# with error message.
#
lock "${name}"
# redefine trap to also unlock (rm lockfile)
TRAPFUNC="${TRAPFUNC} && unlock \"${name}\""
trap "${TRAPFUNC}" 1 2 15
# #
# First execute pre_exec, which may generate destination or other parameters # First execute pre_exec, which may generate destination or other parameters
# #
@ -561,4 +645,5 @@ if [ -x "${CPOSTEXEC}" ]; then
fi fi
rm -f "${TMP}" rm -f "${TMP}"
unlock "${name}"
_techo "Finished" _techo "Finished"

View file

@ -1,3 +1,4 @@
* Add locking (Darko Poljak)
* Fix source-is-up check (Nikita Koshikov) * Fix source-is-up check (Nikita Koshikov)
* Fix some minor command line parsing issues (Nico Schottelius) * Fix some minor command line parsing issues (Nico Schottelius)
* Correct output, if configuration is not in cconfig format (Nico Schottelius) * Correct output, if configuration is not in cconfig format (Nico Schottelius)