# Try to aquire a lock
# (Idea from http://mywiki.wooledge.org/BashFAQ/045)
# Return 0 on success and 1 on failure
try_get_lock() {
    PID=$$
    if (set -C; echo $PID >${LOCK_FILE} ) 2>/dev/null ; then
        trap 'release_lock' 0 1 2 3 15
        return 0
    fi
    return 1
}

# Unconditionally get a lock,
# taking over it after 10 seconds.
# Always return 0
get_lock() {
    local LOOP=0
    local STEP=100000 # 0.1 sec

    while ! try_get_lock ; do
        # Run 10 iterations during first second to catch lock ASAP, doing a check
        # of lockfile fresheness after one second is elapsed.
        # Then increment sleep time to 1 second and check for fresheness every time.
        if [ $((++LOOP)) -ge 10 ] ; then
            # We can't grab lock for more than second, check if everything is OK
            local MOD_TIME=`stat -c "%Y" ${LOCK_FILE}`
            local NOW=`date +%s`
            if [ $((MOD_TIME+1)) -lt ${NOW} ] ; then
                STEP=1000000 # 1 sec
                # OK, nobody touched lock while we are waiting
                local OWNER_PID=`cat ${LOCK_FILE}`
                kill -0 ${OWNER_PID} #2>/dev/null
                if [ $? -ne 0 -o $((MOD_TIME+10)) -lt ${NOW} ] ; then
                    # No such process exists or it holds lock for more than 10 seconds, take over it
                    rm -f ${LOCK_FILE}
                    echo "Problem with locking, taking over stale lock file!"
                    continue
                fi
            fi
        fi
        usleep ${STEP}
    done
    return 0
}

# Release held lock
release_lock() {
    rm -f ${LOCK_FILE}
    trap - 0 1 2 3 15
}

lvm_device_whitelist() {
    local device=$1

    local whitelist_string='"a|^'${device}'|"'
    local grep_string="^[[:space:]]*filter[[:space:]]*=[[:space:]]*\[.*\\\"a\|\^${device}\|\\\".*\]"

    LOCK_FILE="${HA_RSCTMP}/lvm.conf.lock"
    get_lock

    if ! grep -Eq "${grep_string}" /etc/lvm/lvm.conf ; then
        sed -ri 's%(^[[:space:]]*filter[[:space:]]*=[[:space:]]*\[[[:space:]]*.*)([[:space:]]*"r/.*/"[[:space:]]*\])%\1'${whitelist_string}' \2%' /etc/lvm/lvm.conf
    fi
    release_lock
}

lvm_device_unconfigure() {
    local device=$1

    local whitelist_string="\\\"a\|\^${device}\|\\\""
    LOCK_FILE="${HA_RSCTMP}/lvm.conf.lock"

    get_lock
    sed -ri 's%(^[[:space:]]*filter[[:space:]]*=[[:space:]]*\[[[:space:]]*.*)'"${whitelist_string}"'(.*[[:space:]]*"r/.*/"[[:space:]]*\])%\1\2%' /etc/lvm/lvm.conf
    release_lock
}
