aboutsummaryrefslogtreecommitdiff
path: root/tests/lock
diff options
context:
space:
mode:
authorLena <lena@omega>2026-08-01 00:00:00 +0000
committerLena <lena@omega>2026-08-01 00:00:00 +0000
commitc235cb62beefd03087e7cfc7f7f55f0c7c6601c9 (patch)
tree2776f86d9226d55c78e3d735764fcd9ecbe5e08e /tests/lock
downloadvmm-c235cb62beefd03087e7cfc7f7f55f0c7c6601c9.tar.gz
Enter vmmHEADmaster
A QEMU/KVM virtual machine manager in one POSIX shell script. Each VM is a directory of plain files under $VMMDIR, configured by a hand-edited KEY=VALUE file that is parsed rather than sourced, so nothing in it can inject a raw QEMU argument. Control is a QMP FIFO pair inside that directory, guarded by its permissions alone; nothing binds a TCP port. The tests are TAP without a framework and boot real guests where the host allows.
Diffstat (limited to 'tests/lock')
-rw-r--r--tests/lock51
1 files changed, 51 insertions, 0 deletions
diff --git a/tests/lock b/tests/lock
new file mode 100644
index 0000000..09c357f
--- /dev/null
+++ b/tests/lock
@@ -0,0 +1,51 @@
+# 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