Quantcast
Channel: Blocking lock for dpkg - Code Review Stack Exchange
Viewing all articles
Browse latest Browse all 2

Blocking lock for dpkg

$
0
0

My deployment and configuration process entails multiple processes trying to invoke dpkg on my VM at the same time. While dpkg has a locking mechanism, it causes anyone not holding the lock who is trying to acquire it to fail, as opposed to blocking.

I want blocking behavior, so I renamed dpkg to dpkg-exec and am using the following shell script as dpkg (on Ubuntu 22.04). One tricky bit is making the lock re-entrant for spawned invocations of dpkg -- we only want locking against independent processes calling dpkg.

What I have below seems to work. I know there is at least one race condition, involving writing the PID of the acquiring process into the lockfile after acquiring it (somebody might be checking their process tree against the contents of this file between these two steps). I would appreciate any suggestions or improvements.

#!/bin/bash# Path to the original dpkg executableDPKG_EXEC="/usr/bin/dpkg-exec"# Lock file pathLOCKFILE="/var/lib/dpkg/lock-custom"# Acquire an exclusive lock using a file descriptortouch $LOCKFILEexec {LOCK_FD}<>$LOCKFILE# Function to check if a PID is an ancestor of the current processis_ancestor() {    target_pid=$1    current_pid=$2    while [[ $current_pid -ne 1 ]]; do        if [[ $current_pid -eq $target_pid ]]; then            return 0        fi        current_pid=$(awk '{ print $4 }'"/proc/$current_pid/stat")    done    return 1}# Function to clean up lock on exitcleanup() {    # Check if the current process holds the lock    if [[ "$(cat $LOCKFILE)" == "$$" ]]; then    echo "*** Process $$ releasing dpkg lock" >&2        rm -f $LOCKFILE        flock -u $LOCK_FD    fi}# Set up a trap to call cleanup on script exittrap cleanup EXIT# Create the lock file if it doesn't existtouch $LOCKFILE# Check if the lock is already held by an ancestor of this processlock_pid=$(cat $LOCKFILE)if ! is_ancestor "$lock_pid" $$; then# Acquire an exclusive lockecho "*** Process $$ trying to acquire dpkg lock" >&2    flock -x $LOCK_FD    echo "$$"> $LOCKFILEecho "*** Process $$ acquired dpkg lock" >&2fi# Execute the original dpkg command with all arguments passed to the script"$DPKG_EXEC" "$@"```

Viewing all articles
Browse latest Browse all 2

Latest Images

Trending Articles





Latest Images