Expand description
VM-based test framework for Linux kernel subsystems, with a focus on sched_ext.
ktstr boots lightweight KVM virtual machines with controlled CPU topologies, runs scheduler test scenarios inside them, and evaluates results from the host via guest memory introspection. Each test creates cgroups, spawns worker processes, and checks that the scheduler handled the workload correctly. Also tests under the kernel’s default EEVDF scheduler.
§Quick start
Declare cgroups and workloads as data, let the framework handle lifecycle and checking:
use ktstr::prelude::*;
#[ktstr_test(llcs = 1, cores = 2, threads = 1)]
fn my_scheduler_test(ctx: &Ctx) -> Result<AssertResult> {
execute_defs(ctx, vec![
CgroupDef::named("cg_0").workers(2),
CgroupDef::named("cg_1").workers(2),
])
}Requires a kernel image; see find_kernel() for the resolution chain.
For multi-phase scenarios with dynamic topology changes:
use ktstr::prelude::*;
#[ktstr_test(llcs = 1, cores = 2, threads = 1)]
fn my_dynamic_test(ctx: &Ctx) -> Result<AssertResult> {
let steps = vec![
Step::with_defs(
vec![CgroupDef::named("cg_0").workers(4)],
HoldSpec::frac(0.5),
),
Step::new(
vec![Op::stop_cgroup("cg_0"), Op::remove_cgroup("cg_0")],
HoldSpec::frac(0.5),
),
];
execute_steps(ctx, steps)
}§Scheduler definition
Tests work with just topology parameters (as above). When multiple
tests share a scheduler, use declare_scheduler! to declare it
once with a binary, default topology, and any always-on args. Tests
reference the generated const and inherit its configuration:
use ktstr::prelude::*;
declare_scheduler!(MY_SCHED, {
name = "my_sched",
binary = "scx_my_sched",
});
#[ktstr_test(scheduler = MY_SCHED)]
fn basic(ctx: &Ctx) -> Result<AssertResult> {
execute_defs(ctx, vec![
CgroupDef::named("cg_0").workers(2),
CgroupDef::named("cg_1").workers(2),
])
}For full control over cgroup setup, worker spawning, and assertion you can use the low-level API directly:
use ktstr::prelude::*;
#[ktstr_test(llcs = 1, cores = 2, threads = 1)]
fn my_low_level_test(ctx: &Ctx) -> Result<AssertResult> {
let mut group = CgroupGroup::new(ctx.cgroups);
group.add_cgroup_no_cpuset("workers")?;
let cpus = ctx.topo.all_cpuset();
ctx.cgroups.set_cpuset("workers", &cpus)?;
let cfg = WorkloadConfig {
num_workers: 2,
work_type: WorkType::SpinWait,
..Default::default()
};
let mut handle = WorkloadHandle::spawn(&cfg)?;
ctx.cgroups.move_tasks("workers", &handle.worker_pids_for_cgroup_procs()?)?;
handle.start();
std::thread::sleep(ctx.duration);
let reports = handle.stop_and_collect();
let a = Assert::default_checks();
Ok(a.assert_cgroup(&reports, None))
}For pointwise assertions against captured stats — the most direct
way to express “this counter is at least N”, “this rate is between
A and B”, “this metric is finite” — use Verdict +
#[derive(Claim)] accessors and the claim! macro:
use ktstr::prelude::*;
use ktstr::workload::WorkerReport;
use std::collections::{BTreeMap, BTreeSet};
// A test author would obtain `cg` and `report` from `ctx`-driven
// execution; the literal here just illustrates the assertion shape.
let cg = CgroupStats {
num_workers: 2,
num_cpus: 2,
max_gap_ms: 50,
p99_wake_latency_us: 25.0,
median_wake_latency_us: 10.0,
total_iterations: 5_000,
..Default::default()
};
let work_units = 10_000u64;
let throughput = work_units as f64 / 5.0;
let mut v = Assert::default_checks().verdict();
cg.claim_max_gap_ms(&mut v).at_most(100); // typed CgroupStats accessor
cg.claim_p99_wake_latency_us(&mut v).at_most(50.0);
cg.claim_total_iterations(&mut v).at_least(1_000);
claim!(v, work_units).at_least(5_000); // local-binding label
claim!(v, throughput).is_finite(); // expression label
claim!(v, cg.wake_latency_tail_ratio()).between(1.0, 5.0);
let r = v.into_result();
assert!(r.passed);Every claim is labeled by stringify! on either a struct field name
(via the derive) or an identifier/expression (via the macro), so a
rename or refactor updates the failure-message label automatically
and a stale call site fails to compile. There is no manual-string
escape hatch — by design, every label is source-text-grounded.
Run with cargo nextest run (requires /dev/kvm).
See the prelude module for the full set of re-exports.
§Library usage
Default install (full feature set — includes the installed
ktstr / cargo-ktstr bins’ deps and the local LLM extractor):
[dev-dependencies]
ktstr = "0.10"Lean dev-dep (drops the host-tooling crates: tikv-jemallocator,
clap_complete, tree-sitter, tree-sitter-c, base64; keeps the
OutputFormat::LlmExtract path):
[dev-dependencies]
ktstr = { version = "0.10", default-features = false, features = ["llm"] }§Feature flags
llm(default) —OutputFormat::LlmExtractvia bundled Qwen3-4B GGUF. Pulls inllama-cpp-2(cmake C++ build).cli-bins(default) — umbrella for deps used only by the foursrc/bin/*.rsentry points and the matching test-binary dispatch hooks. Pulls intikv-jemallocator,clap_complete,tree-sitter,tree-sitter-c, and theexportfeature.export(pulled in bycli-bins) — gatesexportand thecargo ktstr exportdispatch path in the test binary. Dropsbase64from the manifest when off.wprof— embed the wprof BPF tracer in shell-mode VMs. First build clonesgithub.com/anakryiko/wprof(requires git, clang, elfutils-devel, zlib-devel).pretty-labels— grex-based regex synthesis forctprof_comparedisplay labels. With the feature off, labels fall back to the deterministic join key.remote-cache— GitHub Actions cache backend for blob storage. CI-only; off-by-default. Pulls inopendal+ minimaltokioruntime.integration— gatesresolve_func_ipvisibility for integration tests.
§Crate organization
cache– kernel image cache (XDG directories, metadata, atomic writes)cgroup– cgroup v2 filesystem operationscli– shared helpers backing thektstrandcargo-ktstrbinariesfetch– kernel tarball and git source acquisitionflock– advisory file-locking primitives used by cache + LLC reservationskernel_path– kernel ID parsing and filesystem image discoveryremote_cache– GitHub Actions cache integrationscenario– declarative ops API (CgroupDef,Step,Op,Backdrop,execute_defs,execute_steps,execute_scenario)scenario::scenarios– curated canned scenarios for common patternsassert– pass/fail assertions (starvation, isolation, fairness)test_support–#[ktstr_test]runtime and registrationtopology– CPU topology abstraction (LLCs, NUMA nodes)verifier– BPF verifier log parsing, cycle detection, and output formattingworker_ready/worker_ready_wait– pid-scoped marker file the alloc/test workers write before the parent samples themworkload– worker process types and telemetry collection
§ctprof subsystem
Per-thread + per-process runtime profile, captured via
ktstr ctprof capture and compared via
ktstr ctprof compare:
host_context– one-shot host snapshot (kernel, CPU, memory, tunables)host_heap– jemalloc global heap counters (mallctl)ctprof– per-thread procfs walk + cumulative scheduling, I/O, page-fault, jemalloc TSD countersctprof_compare– two-snapshot diff engine (group-by + delta tables)
host_thread_probe (the ELF/DWARF + ptrace + process_vm_readv
engine that pulls per-thread jemalloc TSD counters) is
pub(crate)-only and consumed exclusively by ctprof plus
the source-shared standalone ktstr-jemalloc-probe binary.
Direct probe access from downstream is intentionally not part
of the surface — scheduler authors get the captured counters
through ctprof::ThreadState.
Internal modules (not re-exported): host_thread_probe reads
per-thread jemalloc TSD counters via ptrace, monitor reads
live guest state, probe attaches BPF probes to traced
functions, vmm owns the KVM VM lifecycle, and timeline
correlates stimulus events with monitor samples for
phase-aligned reporting.
Re-exports§
pub use test_support::runtime::bypass_llc_locks_active;pub use ::linkme;
Modules§
- assert
- Pass/fail evaluation of scenario results.
- cache
- Kernel image cache for ktstr.
- cgroup
- Cgroup v2 filesystem operations for test cgroup management.
- cli
- CLI support functions shared between
ktstrandcargo-ktstr. - cpu_
util - CPU-affinity utilities shared across the crate.
- ctprof
- Per-thread ctprof (cgroup/thread profiler) data model + capture layer.
- ctprof_
compare - Group, aggregate, and render the comparison between two
CtprofSnapshots. - export
cargo ktstr export— package a registered test as a self-extracting.runfile that reproduces the scenario on bare metal without a VM.- fetch
- Kernel source acquisition: tarball download, git clone, local tree.
- flock
- Advisory flock(2) primitives shared across every ktstr lock file.
- fun
- Fun mode — context-hygiene for failure dumps. Funifies every
non-metric value by default so LLM context stays clean: strings
and integers under non-metric keys are replaced with
deterministic
adjective-animalnames or hashed numeric IDs, while values under metric-allowlisted keys (counts, rates, ratios, byte/duration units, structural enums) pass through unchanged. The result lets an LLM reason about the structural and relational shape of a dump without dragging real internal identifiers into its context. - host_
context - Host runtime state captured at sidecar-write time.
- host_
heap - Heap-state snapshot for the running ktstr binary.
- kernel_
path - live_
host - Public surface for the live-host introspection pipeline.
- metric_
types - Type-safe wrappers for per-thread metric values.
- prelude
- Re-exports for writing
#[ktstr_test]functions. - remote_
cache - Remote cache backend for GHA runners via opendal.
- scenario
- Scenario definitions and test execution.
- test_
support - Runtime support for
#[ktstr_test]integration tests. - timeline
- Stimulus/phase correlation for scenario execution.
- topology
- CPU topology abstraction.
- verifier
- BPF verifier log parsing, cycle detection, and output formatting.
- vm
- Gauntlet topology presets.
- worker_
ready - Shared ready-marker path format for the
ktstr-jemalloc-alloc-workerbinary and the integration tests that drive it. - worker_
ready_ wait - Test-side poll helper for the worker ready marker. Separated from
crate::worker_readybecause this helper referencescrate::scenario::payload_run::PayloadHandle; the bin cratektstr-jemalloc-alloc-workerpullsworker_ready.rsin via#[path]and must stay dependency-free (see that module’s doc for why). This module is library-only. - workload
- Worker process management and telemetry.
Macros§
- claim
- Open a
Verdictclaim from a local binding or expression. The label isstringify!(<expr-tokens>)so a regression that renames the binding or alters the expression updates the rendered failure message in lock-step. - declare_
scheduler - Function-style macro that registers a
Schedulerconst. - json
- Convert JSON-like Rust tokens into a
&'static strat compile time.
Constants§
- EMBEDDED_
KCONFIG - Contents of
ktstr.kconfig(the kernel-config fragment that enables sched_ext, BPF, kprobes, cgroups, and the other options ktstr requires) baked into the binary at build time viainclude_str!. Consumed by the kernel build pipeline toolddefconfiga kernel source tree, and used to derive the cache key suffix so a kconfig change produces a fresh cache entry. - KTSTR_
BUDGET_ SECS_ ENV - Name of the environment variable that overrides the per-test
budget in seconds for VM-boot dispatch. Empty / unset falls
back to the dispatcher’s default. Parsed as f64 seconds at
crate::test_support::dispatch(accepts fractional values like2.5); invalid or non-positive values surface a warn and the default applies. - KTSTR_
BUSYBOX_ PATH_ ENV - Name of the environment variable that points at the busybox
blob on-disk. Exported by
cargo-ktstr’s startupinstall_env(seebin/cargo_ktstr/blobs.rs) which extracts the embeddedBUSYBOX_BYTESto a tempfile and sets this var to the absolute path; read bycrate::vmm::blobs::load_busybox_bytes. Both unset and set-but-empty surface a hard error, BUT the diagnostic differs: unset hits theErr(_)arm and surfaces the “blob is provided bycargo-ktstrat startup” install-env hint; empty hits theOk("")arm and falls through to a genericfs::read("")ENOENT — less actionable. Operators invokingcargo ktstr <SUB>see neither case; rawcargo nextest runreliably triggers the unset diagnostic. Busybox is load-bearing for shell-mode VMs + disk-template builds. - KTSTR_
BYPASS_ LLC_ LOCKS_ ENV - Name of the environment variable that bypasses LLC resource
locks at scenario setup (test_support::dispatch / cargo-ktstr
shell). Set by the
--bypass-llc-locksCLI flag. - KTSTR_
CACHE_ DIR_ ENV - Name of the environment variable that overrides ktstr’s cache
root directory (kernel-build cache, btf-anchor cache, blob
cache, etc.). Empty / unset falls back to the per-user default
(typically
$HOME/.cache/ktstr). Heavy test usage —crate::test_support::test_helpers::IsolatedCacheDirsets it to a temp dir per-test so cache reads don’t leak host state into the test, and post-test the original value is restored viacrate::test_support::test_helpers::EnvVarGuard. - KTSTR_
CARGO_ TEST_ MODE_ ENV - Name of the environment variable that signals ktstr is running
in “cargo test” mode (raw test binary launched by cargo’s test
harness, no orchestrator). Distinct from
KTSTR_ORCHESTRATED_ENVwhich marks cargo-ktstr orchestration;KTSTR_CARGO_TEST_MODEis for narrower cases like in-process VMM tests that adapt their resource budgets when run viacargo test/cargo nextest. Read viacrate::cargo_test_mode::cargo_test_mode_active: treats unset and empty as disabled; ANY non-empty value enables — no trim, no special-case strings ("0"and"false"ENABLE because they’re non-empty). - KTSTR_
CGROUP_ WALK_ ROOT_ ENV - Name of the environment variable that overrides the cgroup-fs
root
crate::cgroup::CgroupManager::setupwalks down from when enabling controllers in every ancestor’scgroup.subtree_control. Empty / unset falls back to/sys/fs/cgroup(the canonical cgroup-v2 mount). Non-empty value must be a prefix ofKTSTR_HOST_CGROUP_PARENT_ENV’s configured parent so the walk stays inside the directory the operator owns; values that do not satisfy the prefix invariant are rejected upfront bycrate::cgroup::CgroupManager::with_walk_root. - KTSTR_
CONTENTION_ BYPASS_ ENV - Name of the environment variable that bypasses the contention
guard at scenario setup. Strict
v == "1"semantics (only the literal"1"enables; everything else disables). Used by tests that need to provoke contention scenarios without the production guard kicking in. - KTSTR_
CPU_ CAP_ ENV - Name of the environment variable that caps the host CPU count
the scenario engine sees, for testing scaling logic without a
real CPU narrowing. Read at
crate::vmm::host_topologyand set by the--cpu-capCLI flag in the bin entry points. Empty falls back to the host’s actual CPU count; non-empty numeric value caps the observed count. - KTSTR_
GHA_ CACHE_ ENV - Name of the environment variable that enables the GitHub Actions
remote-cache backend in
crate::remote_cache. Read at cache- init time; value-typed — only the exact string"1"enables; unset / empty / any other value (including"true","yes","0","false") is disabled. Set explicitly by GitHub Actions workflows when the runner has cache-API credentials; absent in dev environments where local-only caching is the right default. - KTSTR_
GUEST_ INIT_ ENV - Name of the environment variable cargo-ktstr’s spawn-pipeline
sets to “1” inside the guest-side init binary so the binary
detects it’s running as the guest init. Presence check via
var_os(...).is_none()atcrate::workload::spawn— absent in host-side dispatch. - KTSTR_
HOST_ CGROUP_ PARENT_ ENV - Name of the environment variable that overrides the default
host-mode cgroup parent (where
host_onlytests’ workload cgroups land). Empty / unset falls back to the canonical default; a non-empty value must be rooted under/sys/fs/cgroupand name a non-root subdirectory. - KTSTR_
JEMALLOC_ ALLOC_ WORKER_ BINARY_ ENV - Name of the environment variable that points at a worker
binary for jemalloc allocation-probe runs. Empty / unset
leaves the worker binary unwired — same shape as
KTSTR_JEMALLOC_PROBE_BINARY_ENV; reader atcrate::test_support::runtimeL799-806 conditionally calls.jemalloc_alloc_worker_binary()only on set+non-empty, nowhich-based fallback. Set alongside the probe via#[ctor]intests/jemalloc_probe_tests.rs. - KTSTR_
JEMALLOC_ PROBE_ BINARY_ ENV - Name of the environment variable that points at a probe binary
for jemalloc-feature detection. Empty / unset leaves the probe
binary unwired (the
crate::test_support::runtimereader at L789-797 conditionally calls.jemalloc_probe_binary()only on set+non-empty — there is nowhich-based fallback). Tests that need the probe set this var via#[ctor]before the harness runs (seetests/jemalloc_probe_tests.rs). - KTSTR_
KERNEL_ COMMIT_ ENV - Name of the environment variable cargo-ktstr sets to a
dir=commit;dir=commit;...map of each resolved SOURCE kernel’s short commit hash (with a-dirtysuffix when the tree is dirty), keyed by the same directory string exported inKTSTR_KERNEL_ENV/KTSTR_KERNEL_LIST_ENV. - KTSTR_
KERNEL_ ENV - KTSTR_* env-var empty-string contract
- KTSTR_
KERNEL_ HINT - Shared skip / error hint for call sites that cannot proceed
without a resolvable kernel. Phrased so the user sees the same
wording regardless of which layer surfaced the failure — tests,
CLI, monitor probes, and sidecar writers all point the operator
at the same remediation. Referenced by the non-VM-boot skip
paths in
cache.rs,probe/btf.rs,monitor/mod.rs,test_support/eval/mod.rs, andtest_support/mod.rs. - KTSTR_
KERNEL_ LIST_ ENV - Name of the environment variable that carries the multi-kernel
fan-out list across the
cargo ktstr→cargo nextest→ test- binary boundary. Format:label1=path1;label2=path2;…(semicolon entry separator,=separates label from absolute kernel-dir path). Empty / unset means “single-kernel mode” — the test binary honoursKTSTR_KERNEL_ENVdirectly. - KTSTR_
KERNEL_ PARALLELISM_ ENV - Name of the environment variable that overrides the rayon
pool width used by
cargo ktstr’sresolve_kernel_setto fan out per-spec kernel resolves (download / git-clone / build) in parallel. Default cap isavailable_parallelism()— the host’s logical CPU count — chosen so download streams do not outnumber threads the host can drive without thrashing a contended local network (kernel.org CDN per-IP throttle, developer ISP, CI shared NIC). - KTSTR_
LOCK_ DIR_ ENV - Name of the environment variable that overrides ktstr’s flock
directory for inter-process resource locking (cpuset / LLC
reservation locks). Empty / unset falls back to the hardcoded
/tmpdefault atcrate::cache::resolve::resolve_lock_dir(the literal string, notstd::env::temp_dir()/TMPDIRresolution — historical default kept for stability). Used by tests + CI environments that need isolated lock-dirs. - KTSTR_
LOG_ PASSES_ ENV - Name of the environment variable that opts into per-assertion
PASS logging in the verdict pipeline. Read once per call at
crate::assert::claim::Verdict::newvia thelog_passes_defaulthelper at src/assert/claim.rs L45-50: the reader is!(v.is_empty() || v == "0"), so empty and the literal"0"disable; any other value ("1","true","yes", even"false"because it isn’t"0") enables. Unset → disabled. Default-off keeps the PASS path unallocated under normal runs. - KTSTR_
NO_ PERF_ MODE_ ENV - Name of the environment variable that forces ktstr to skip the
perf_event_openaccess check + theperf_event_paranoid-relaxation gate. Read at scenario-engine startup (crate::test_support::runtime) and by thecargo ktstr shell/ verifier dispatch sites that disable perf collection when the operator passes--no-perf-mode. - KTSTR_
NO_ SKIP_ MODE_ ENV - Name of the environment variable cargo-ktstr’s test
dispatcher sets to disable the skip-on-contention test
behavior. Presence check via
var_os(...).is_some()— set to “1” bycargo ktstr test --no-skip-mode, absent otherwise. - KTSTR_
ORCHESTRATED_ ENV - Name of the environment variable cargo-ktstr sets to signal
“this test process was launched by a cargo-ktstr orchestration
path, not raw
cargo nextest”. cargo-ktstr’stestandverifiersubcommands set it to"1"before spawning the nextest child; the value content does not matter, only the presence —std::env::var(KTSTR_ORCHESTRATED_ENV).is_ok(). - KTSTR_
PERF_ ONLY_ ENV - Name of the environment variable that restricts a run to ONLY
performance_modetests: when set to a non-empty value, every test whose entry does not haveperformance_modeis skipped (skip sidecar recorded, libtest sees pass) before any VM boot. The mergebase perf-delta subcommand sets this so a regression run measures only the tests configured for clean performance numbers; an explicit nextest-Efilter narrows further within the perf-mode set. - KTSTR_
SCHEDULER_ ENV - Name of the environment variable that overrides the scheduler
binary path test_support::eval uses for in-process scheduler
dispatch. Read at
crate::test_support::eval. This is the COARSE (global) override: it applies to EVERYSchedulerSpec::Discoverscheduler regardless of name, so a test declaring multiple distinct schedulers can’t point them at different binaries through it — use the per-name variant (per_name_scheduler_env) for that. - KTSTR_
SCHEDULER_ PROFILE_ ENV - Name of the environment variable selecting the build profile for a
SchedulerSpec::Discoverscheduler built on demand bybuild_and_find_binary."release"builds the scheduler-under- test with the release profile; any other value (or unset) uses the default dev profile. This DECOUPLES the scheduler-under-test’s profile from the harness/test binary’s compile profile:cargo ktstr test --release-schedulersets this so the scheduler runs optimized while the harness keeps its dev-profile assertion thresholds andcatch_unwindbehavior;--releasesets both. - KTSTR_
SIDECAR_ DIR_ ENV - Name of the environment variable that overrides the sidecar
output directory (the per-test
*.ktstr.jsonwrite target). Empty / unset falls back to the per-testtarget/ktstr/<run-id>location. Read atcrate::test_support::sidecar+crate::cli::stats_cmds::dispatch(the stats reader). - KTSTR_
STALL_ POLL_ MS_ ENV - Name of the environment variable that overrides the poll cadence
(in milliseconds) of the host-mode stall monitor in
crate::scenario::host_stall. - KTSTR_
TEST_ KERNEL_ ENV - Name of the environment variable that overrides the kernel
path the eval dispatch reads (orthogonal to
KTSTR_KERNEL_ENVwhich the main entry points use). Read atcrate::test_support::eval::resolve_test_kernel: a set-but-emptyKTSTR_TEST_KERNEL=surfaces aKTSTR_TEST_KERNEL not found:hard error (typo-loud per reader comment); ONLY the unset /Err(NotPresent)case falls through tocrate::find_kernel()(cache + sysroot probes), which themselves fall through to aKernelUnavailableerror hinting at bothKTSTR_TEST_KERNELandKTSTR_KERNEL. - KTSTR_
VERBOSE_ ENV - Name of the environment variable that triggers verbose logging
in the VMM setup phase. Strict
v == "1"semantics (only the literal"1"enables; unset / empty / any other value — including"true","yes","0"— is disabled). Read atcrate::vmm::setupL1263-1266 (x86_64 cmdline) and L1680-1683 (aarch64 cmdline); both readers identical. - KTSTR_
VERIFIER_ RAW_ ENV - Name of the environment variable that switches the
cargo ktstr verifierper-cell handler from the cycle-collapsed default rendering to a raw scheduler-log dump. Set to any value (the presence of the variable is what matters; the value is ignored) by the dispatcher insrc/bin/cargo_ktstr/verifier.rswhen the operator passes--raw, and read bycrate::test_support::dispatch::run_verifier_cellbefore formatting viacrate::verifier::format_verifier_output. - KTSTR_
WPROF_ PATH_ ENV - WPROF_
MIN_ MEMORY_ MIB - Minimum guest memory (MiB) for test entries that enable wprof.
Functions§
- apply_
wprof_ memory_ floor - Apply the wprof memory floor to a raw memory size.
- build_
and_ find_ binary - Build a cargo binary package and return its output path.
- cache_
key_ suffix - Cache key suffix derived from the embedded kconfig fragment. Used in kernel cache keys so a kconfig change produces a distinct cache entry. The kernel binary is independent of ktstr userspace source, so no ktstr or consumer build identity feeds this suffix.
- cache_
key_ suffix_ with_ extra - Two-segment cache key suffix accounting for an optional
--extra-kconfigfragment. - extra_
kconfig_ hash - CRC32 hash (8 hex chars) of a user-supplied
--extra-kconfigfragment, hashed verbatim. - find_
kernel - Find a bootable kernel image on the host.
- kconfig_
hash - CRC32 hash of the embedded kconfig fragment (8 hex chars).
- ktstr_
kernel_ env - Read
KTSTR_KERNEL_ENVonce, normalizing the raw value: missing / empty / whitespace-only reads collapse toNone, and a surrounding-whitespace trim is applied so a shell-quotedKTSTR_KERNEL=" ../linux"behaves the same as the unquoted form. Every caller that reads the env var should route through this helper so the normalization rules live in one place; a future change to the rules (e.g. accepting a trailing slash) propagates to every site automatically. - merge_
kconfig_ fragments - Merge the user-supplied
--extra-kconfigfragment on top ofEMBEDDED_KCONFIGfor the configure pass. Returns astd::borrow::Cowso the no-extras branch borrowsbakedwithout allocating; only theSomebranch heaps the merged String. - per_
name_ scheduler_ env - Per-scheduler-NAME override environment variable for a
SchedulerSpec::Discover(name)scheduler:KTSTR_SCHEDULER_BIN_<NAME>, where<NAME>is the discover name uppercased with every non-alphanumeric character replaced by_(e.g.scx_layered->KTSTR_SCHEDULER_BIN_SCX_LAYERED,scx-ktstr->KTSTR_SCHEDULER_BIN_SCX_KTSTR). - precompute_
cast_ analysis - Pre-populate the on-disk cast analysis cache for a scheduler binary.
- read_
kmsg - Read the kernel ring buffer (equivalent to
dmesg --notime). Exposed aspubso scenario tests that need to assert on kernel-log content (e.g. the sched_ext stall duration emitted byscx_exit(SCX_EXIT_ERROR_STALL)inkernel/sched/ext.c) can read the same buffer the framework captures intoAssertResult::detailson scheduler-died failures. - resolve_
func_ ip - Resolve a kernel function name to its address via /proc/kallsyms.
- run_
shell - Boot a KVM VM in interactive shell mode.
- send_
kmsg - Forward the guest’s
/dev/kmsgring buffer to the host over the bulk port, so a host-side post_vm callback can read it viaVmResult::guest_kmsg. Mirrorsread_kmsg: that reads the ring buffer in the guest process; this forwards the bytes (typicallyread_kmsg().as_bytes()) to the host. The scx_exit SCX_EXIT_ERROR_STALL printk lands in /dev/kmsg but is suppressed from the COM1 console at the defaultloglevel=0, so it never reachesVmResult::stderr; this forward is the only host-visible path to it.
Attribute Macros§
- distributed_
slice linkme::distributed_slicere-exported as part of ktstr’s public surface. Combined withcrate::linkmefor the#[linkme(crate = ...)]annotation, this lets a downstream crate register entries intoKTSTR_TESTSorKTSTR_SCHEDULERSwithout addinglinkmeas a direct Cargo dependency:- ktstr_
test - Attribute macro that registers a function as a ktstr integration test.