Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Architecture Overview

ktstr has three execution domains:

  1. Host process – the test binary running on the host. Manages VM lifecycle, monitors guest memory, evaluates results.

  2. Guest process – the same test binary running inside the VM as PID 1. Mounts filesystems, starts the scheduler, creates cgroups, forks workers, runs scenarios, writes results to SHM (COM2 fallback).

  3. Monitor thread – runs on the host while the guest executes. Reads guest VM memory directly to observe scheduler state without instrumenting it.

Execution flow

Host                          Guest
----                          -----
test binary                   
  |                           
  +-- build initramfs         
  |   (test binary as /init   
  |    + optional scheduler)  
  |                           
  +-- boot KVM VM             
  |                           test binary (PID 1 init)
  |                             |
  +-- start monitor thread      +-- mount filesystems
  |   (reads guest memory)      +-- start scheduler (if any)
  |                             +-- create cgroups
  |                             +-- fork workers
  |                             +-- move workers to cgroups
  |                             +-- signal workers to start
  |                             +-- poll scheduler liveness
  |                             +-- stop workers, collect reports
  |                             +-- evaluate results
  |                             +-- write result to SHM (COM2 fallback)
  |                           
  +-- read result from SHM (COM2 fallback)
  +-- evaluate monitor data   
  +-- report pass/fail        

Key design decisions

Same binary, two roles. The test binary serves as both host controller and guest test runner. The initramfs embeds the binary as /init. When running as PID 1, the Rust init code (vmm::rust_init) handles the full guest lifecycle: mounts, scheduler start, test dispatch, and reboot.

Forked workers, not threads. Workers are fork()ed processes because cgroups operate on PIDs. Each worker must be a separate process to be placed in its own cgroup.

Host-side monitoring. The monitor reads guest memory via KVM, avoiding BPF instrumentation of the scheduler under test. This eliminates observer effects on scheduling decisions.

Typed flag declarations. Flags use static references instead of string matching, enabling compile-time dependency resolution.