# The VM directory is the mutex. "$VMM" create lk1 64M >/dev/null 2>&1 # Every mutating verb serialises, including the two that destroy data. exec 9<"$VMMDIR/lk1" flock -n 9 exits 4 "start refuses while the lock is held" start lk1 exits 4 "delete refuses while the lock is held" delete -f lk1 exits 4 "clone refuses while the lock is held" clone lk1 lk9 flock -u 9 exec 9>&- # The kernel releases the lock when vmm exits on an error. cfg lk1 </dev/null 2>&1 cfg lk2 </dev/null 2>&1; then "$VMM" stop lk2 >/dev/null 2>&1 & stopper=$! i=0 while flock -n "$VMMDIR/lk2" true && [ "$i" -lt 5 ]; do sleep 1 i=$((i + 1)) done # That loop ends on the lock being taken or on running out of # patience, and only the first of those says anything about vmm. if flock -n "$VMMDIR/lk2" true; then skip 1 "the backgrounded stop never took the lock" else exits 4 "a second vmm is refused while the first holds the lock" \ start lk2 fi wait "$stopper" 2>/dev/null || : holds "and the lock is available once the first is done" \ flock -n "$VMMDIR/lk2" true else skip 2 "lk2 did not start" fi