#!/bin/bash ############################################################################### # # # IPFire.org - A linux based firewall # # Copyright (C) 2012 Michael Tremer & Christian Schmidt # # # # This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation, either version 3 of the License, or # # (at your option) any later version. # # # # This program is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU General Public License for more details. # # # # You should have received a copy of the GNU General Public License # # along with this program. If not, see . # # # ############################################################################### __lock_path() { local name=${1} if [ "${name:0:1}" = "/" ]; then echo "${name}" else echo "${LOCK_DIR}/network-${name}" fi } lock() { local lock="${1}" shift local timeout="60" # Make partent directory make_parent_directory "${lock}" ( log DEBUG "Trying to acquire lock ${lock}" # Try to acquire lock on fd 9 if ! flock -w "${timeout}" 9; then log ERROR "Failed to acquire lock ${lock} after ${timeout} seconds" exit ${EXIT_ERROR} fi log DEBUG "Acquired lock ${lock}" # Remember return code ret=${EXIT_OK} # Run command "$@" || ret=$? log DEBUG "Released lock ${lock}" exit ${ret} ) 9>${lock} || exit $? } lock_exists() { local name=${1} assert isset name local lockfile=$(__lock_path ${name}) if [ -e "${lockfile}" ]; then return ${EXIT_TRUE} else return ${EXIT_FALSE} fi } lock_acquire() { local name=${1} assert isset name # timeout value in seconds local timeout=${2} if ! isset timeout; then timeout=0 fi local lockfile=$(__lock_path ${name}) timeout=$(( ${timeout} * 4 )) log DEBUG "Acquiring lock '${name}'" # Wait until lock is available while [ ${timeout} -gt 0 ] && [ -e "${lockfile}" ]; do timeout=$(( ${timeout} - 1 )) sleep 0.25 done # If another lock still exists, we return an error if [ -e "${lockfile}" ]; then error "Could not acquire lock '${name}'" return ${EXIT_ERROR} fi # Write out pid to the lockfile and make sure that # nobody else can access it. echo "$$" > ${lockfile} chmod 600 ${lockfile} } lock_release() { local name=${1} assert isset name local lockfile=$(__lock_path ${name}) log DEBUG "Releasing lock '${name}'" # Remove the lockfile (okay if it does not exist). rm -f ${lockfile} }