ktstr/cache/
mod.rs

1//! Kernel image cache for ktstr.
2//!
3//! Manages a local cache of built kernel images under an XDG-compliant
4//! directory. Each cached kernel is a directory containing the boot
5//! image, optionally a stripped vmlinux ELF (symbol table, BTF, and
6//! the section headers that monitor/probe code reads), and a
7//! `metadata.json` descriptor. `CONFIG_HZ` is recovered from the
8//! embedded IKCONFIG blob in the stripped vmlinux (ktstr.kconfig
9//! forces `CONFIG_IKCONFIG=y`), so no separate `.config` sidecar is
10//! cached.
11//!
12//! # Cache location
13//!
14//! Resolved in order:
15//! 1. `KTSTR_CACHE_DIR` environment variable
16//! 2. `$XDG_CACHE_HOME/ktstr/kernels/`
17//! 3. `$HOME/.cache/ktstr/kernels/`
18//!
19//! # Submodule layout
20//!
21//! - `metadata` — public types: [`KernelSource`], [`KernelMetadata`],
22//!   [`CacheArtifacts`], [`KconfigStatus`], [`CacheEntry`],
23//!   [`ListedEntry`], plus the internal `classify_corrupt_reason`
24//!   dispatcher.
25//! - `cache_dir` — [`CacheDir`] handle, lock guards
26//!   ([`SharedLockGuard`], [`ExclusiveLockGuard`]), store/lookup/list/
27//!   clean lifecycle, and reader/writer-asymmetric lock policy.
28//! - `housekeeping` — atomic-rename install primitives, cache-key
29//!   and image-name validators, `read_metadata` decoder, and the
30//!   `clean_orphaned_tmp_dirs` cross-PID sweep.
31//! - `vmlinux_strip` — ELF strip pipeline (`strip_vmlinux_debug`,
32//!   `neutralize_relocs`, `strip_keep_list`, `strip_debug_prefix`)
33//!   plus the keep-list / zero-data section-name unions.
34//! - `resolve` — env-cascade root resolution
35//!   (`resolve_cache_root_with_suffix`, `validate_home_for_cache`,
36//!   `path_inside_cache_root`) and source-tree path helpers
37//!   ([`prefer_source_tree_for_dwarf`], [`recover_local_source_tree`]).
38//!
39//! Each submodule owns its tests in a `#[cfg(test)] mod tests`
40//! block — inline in the same file except `cache_dir`, whose tests
41//! live in `cache_dir_tests.rs` via `#[path]`; shared test fixtures
42//! used by
43//! more than one submodule's tests live in
44//! `shared_test_helpers`.
45
46use crate::flock::LOCK_DIR_NAME;
47
48mod cache_dir;
49mod housekeeping;
50mod metadata;
51mod resolve;
52mod vmlinux_strip;
53
54#[cfg(test)]
55pub(crate) mod shared_test_helpers;
56
57// Public API re-exports — preserve every `crate::cache::*` path that
58// external callers (lib.rs, cli, fetch.rs, monitor/*, probe/btf.rs,
59// vmm/disk_template, test_support/*, remote_cache.rs, stats,
60// flock) rely on.
61
62pub use cache_dir::{CacheDir, ExclusiveLockGuard, SharedLockGuard};
63pub use metadata::{
64    CacheArtifacts, CacheEntry, KconfigStatus, KernelMetadata, KernelSource, ListedEntry,
65};
66pub use resolve::{prefer_source_tree_for_dwarf, recover_local_source_tree};
67
68// Re-export KernelId from kernel_path (canonical definition, std-only).
69pub use crate::kernel_path::KernelId;
70
71// Crate-internal API re-exports for callers in other modules:
72// path_inside_cache_root (monitor/btf_offsets),
73// resolve_cache_root_with_suffix (vmm/disk_template,
74// vmm/cast_analysis_load), resolve_lock_dir
75// (vmm/host_topology, cli/locks).
76pub(crate) use resolve::{
77    path_inside_cache_root, resolve_cache_root_with_suffix, resolve_lock_dir,
78};
79
80/// Cache root for the `cargo ktstr affected` per-scheduler input-set cache.
81///
82/// Exposed as `pub` (unlike the crate-internal
83/// `resolve_cache_root_with_suffix`) because the affected engine lives in
84/// the cargo-ktstr BIN crate, a separate crate that reaches it as
85/// `ktstr::cache::affected_cache_root()`. Runs the same `KTSTR_CACHE_DIR` ->
86/// `$XDG_CACHE_HOME` -> `$HOME/.cache` cascade as every other ktstr cache,
87/// under the `affected` suffix.
88pub fn affected_cache_root() -> anyhow::Result<std::path::PathBuf> {
89    resolve_cache_root_with_suffix("affected")
90}
91// Durable-publish primitives shared by both cache layers
92// (cache_dir::CacheDir::store and vmm/disk_template::store_atomic) so
93// the two stay consistent — see fsync_staging_dir's contract.
94pub(crate) use housekeeping::{fsync_parent, fsync_staging_dir};
95// Re-exported so the `[`crate::cache::strip_vmlinux_debug`]`
96// intra-doc links in probe/btf.rs, monitor/mod.rs, and
97// monitor/symbols.rs resolve under cargo doc. No
98// `crate::cache::strip_vmlinux_debug` code call sites today;
99// intra-cache callers (cache_dir.rs, tests) reach the function
100// via `super::vmlinux_strip::strip_vmlinux_debug`.
101#[allow(unused_imports)]
102pub(crate) use vmlinux_strip::strip_vmlinux_debug;
103
104/// Filename prefix that marks an in-progress atomic-store directory
105/// under the cache root. Format: `{TMP_DIR_PREFIX}{cache_key}-{pid}`.
106/// Centralized here so the three roles that reference it — emitter
107/// ([`cache_dir::CacheDir::store`]), scanner
108/// ([`housekeeping::clean_orphaned_tmp_dirs`]), and validator
109/// ([`housekeeping::validate_cache_key`]) — cannot drift.
110/// [`cache_dir::CacheDir::list`] does not reference the const; it
111/// skips these directories via its broader leading-`.` filter.
112pub(crate) const TMP_DIR_PREFIX: &str = ".tmp-";