# 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 <<EOF
NOSUCHKEY=1
EOF
refuses 'unknown key' "start refuses a broken config" start lk1
exits 0 "and gives back the lock it had already taken" stop lk1

# Two real vmm processes, not a directory made by hand. A guest with no
# OS ignores ACPI, so stop holds the lock for SHUTDOWN_TIMEOUT, which is
# long enough to fire a start at it and require a refusal.
"$VMM" create lk2 64M >/dev/null 2>&1
cfg lk2 <<EOF
MEM=256
CPUS=1
HWACCEL=no
EOF
if "$VMM" start 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
