3

I am trying to create a service wrapper (init.d script) around one of my favorite applications. The application creates both a PID and a lock file, and so I'm trying to use those to ensure that I can report accurate status of the application and prevent my service from starting multiple copies.

Unfortunately, the application (or system) crashes from time to time, leaving the PID and lock files behind, so I can't just check for the existence of those files to determine if my application is running or not.

The application does create a lock on the lock file, a POSIX WRITE lock, according to lslocks, but it seems that if I try to create a lock with flock -x -n "$file" echo dummy, the command succeeds, to my surprise. Deleting the file also succeeded (rm "$file"), as well as writing to it, which on a BTRFS system does make a small amount of sense, though doesn't make it any less aggravating.

So, how can I query the file in such a way that I would know if the file has a lock (POSIX or FLOCK) on it or not?

palswim
  • 5,167

1 Answers1

0

I used the following function in my script to accomplish this:

getPIDLock () {
    if [ ! -e "$LockFile" ]; then
        return 0 # Not an error, but lsof will emit a lot of text if the file doesn't exist
    fi
    local PIDLock=$( lsof -F p "$1" | head -n 1 )
    local strEcho='echo ${PID:1}'
    bash -c "PID=\"$PIDLock\";$strEcho;" # Assuming system has BASH, but not assuming that the default shell is BASH
    return 0
}

This will emit a PID if the file in question has a lock on it; otherwise, it will emit a blank string.

PID=$( getPIDLock "/path/to/pidfile" )
if [ -n $PID ]; then
    # Do your thing
fi
palswim
  • 5,167