CacheDir

Struct CacheDir 

Source
#[non_exhaustive]
pub struct CacheDir { /* private fields */ }
Expand description

Handle to the kernel image cache directory.

Implementations§

Source§

impl CacheDir

Source

pub fn new() -> Result<Self>

Open a cache directory at the resolved root path.

Source

pub fn with_root(root: PathBuf) -> Self

Open a cache directory at a specific path.

Source

pub fn default_root() -> Result<PathBuf>

Resolve the default cache root path without side effects.

Source

pub fn root(&self) -> &Path

Root directory this CacheDir is anchored at.

Source

pub fn lookup(&self, cache_key: &str) -> Option<CacheEntry>

Look up a cached kernel by cache key.

On hit, emits a tracing::warn! via warn_if_unstripped_vmlinux when the cached entry took the strip-failure fallback (see should_warn_unstripped for the exact predicate). Caller-facing call sites want the warning; internal call sites that look the entry up only to compare against caller intent (notably Self::store’s in-lock recheck) use Self::lookup_silent to avoid double-emitting the same warning the caller will see on its next lookup.

Source

pub fn list(&self) -> Result<Vec<ListedEntry>>

List all cached kernel entries, sorted by build time (newest first).

Source

pub fn store( &self, cache_key: &str, artifacts: &CacheArtifacts<'_>, metadata: &KernelMetadata, ) -> Result<CacheEntry>

Store a kernel image (and optional vmlinux sidecar) in the cache under cache_key. Atomic install via temp directory + renameat2(RENAME_EXCHANGE), so a concurrent reader never observes a partially-written entry.

§Steps (in order)
  1. Validate inputs. validate_cache_key rejects .., slashes, NUL, leading-dot keys (the TMP_DIR_PREFIX reservation plus any other dotfile-shaped key, since list() skips every dotfile child); validate_filename rejects path-separator characters in the image basename. Invalid input fails before any I/O.
  2. Acquire the per-key store lock. LOCK_EX on <root>/.locks/<cache_key>.lock. Timeout defaults to STORE_EXCLUSIVE_LOCK_DEFAULT_TIMEOUT (5 minutes) and can be overridden via STORE_EXCLUSIVE_LOCK_TIMEOUT_ENV for environments where a slow vmlinux strip stacks many contending peers behind the head writer. The lock excludes other writers for the same key while letting readers and writers for unrelated keys proceed. Timeout produces an error rather than blocking forever — a hung writer cannot indefinitely block a fresh rebuild attempt.
  3. Double-checked re-lookup inside the lock. After acquiring LOCK_EX, re-run Self::lookup_silent for cache_key. When N peers race to publish the same key they all miss the pre-lock cache check, queue on LOCK_EX, and serialise behind the head writer. Without this recheck, every peer re-runs the full copy + strip + publish steps in series even though the head writer’s output already satisfies them. The recheck early-returns when the existing cached entry’s content-defining metadata fields (cache_content_matches — config_hash, ktstr_kconfig_hash, extra_kconfig_hash, has_vmlinux) match the caller’s intent for this publish, so only the head writer pays the strip/copy/rename cost. Cache-relevant differences (a fresh kconfig hash, a different vmlinux presence) bypass the early-return and proceed to a real overwrite-publish. Cache-irrelevant differences (a fresh built_at timestamp, a different version display string) trigger the early-return — the on-disk bytes the overwrite would write are byte-equivalent to what’s already cached, so the publish is redundant.
  4. Stage into a temp directory. <root>/.tmp-<key>-<pid> is created (or pruned and recreated if a previous attempt by the same PID exists), with TmpDirGuard enrolling the path for cleanup on any subsequent error. A best-effort clean_orphaned_tmp_dirs pass also runs here so dead sibling temp directories from crashed PIDs are GC’d before we add another one.
  5. Copy the boot image. metadata.image_name lands at tmp/<image_name> via reflink::reflink_or_copy (copy-on-write when the cache filesystem supports it, else a plain byte copy).
  6. Strip and copy vmlinux (if supplied). When artifacts.vmlinux is Some, strip_vmlinux_debug runs the two-stage strip pipeline and the result is written to tmp/vmlinux. Strip-fallback rationale: if the strip pipeline returns an error (e.g. an unrecognised ELF layout from a future toolchain or an exotic config), the write does NOT abort — it falls back to copying the raw unstripped vmlinux and records vmlinux_stripped: false in metadata. The cache trades a much larger on-disk payload for “still usable for monitoring/probes,” and cargo ktstr kernel list --json exposes the vmlinux_stripped field so operators can spot entries that need rebuilding once the strip-failure root cause is fixed. A hard failure here would be worse: it would effectively brick the cache for that build.
  7. Write metadata.json. A pretty-printed serde dump of KernelMetadata (with has_vmlinux and vmlinux_stripped set from step 6) at tmp/metadata.json. Pretty-print is intentional — operators inspect this file directly when debugging cache state.
  8. Atomic publish. fs::rename(tmp → final) if final does not exist; otherwise atomic_swap_dirs uses renameat2(RENAME_EXCHANGE) to swap the two directories in a single atomic syscall. Either way, no reader observes a partial entry; the swap path also cleans up the now-stale prior version under the temp name.
Source

pub fn clean_all(&self) -> Result<usize>

Remove every cached entry. Returns the number of entries removed. Preserves the .locks/ subdirectory.

Source

pub fn clean_keep(&self, keep: usize) -> Result<usize>

Remove every cached entry except the keep most recent ones (by built_at timestamp). Preserves the .locks/ subdirectory.

Source

pub fn acquire_shared_lock(&self, cache_key: &str) -> Result<SharedLockGuard>

Acquire LOCK_SH on the cache-entry lockfile.

Source

pub fn acquire_exclusive_lock_blocking( &self, cache_key: &str, timeout: Duration, ) -> Result<ExclusiveLockGuard>

Acquire LOCK_EX on the cache-entry lockfile, blocking up to timeout. On timeout, the error message surfaces the STORE_EXCLUSIVE_LOCK_TIMEOUT_ENV override so an operator hitting a contended store() discovers the env-var remediation without reading the docs.

Source

pub fn try_acquire_exclusive_lock( &self, cache_key: &str, ) -> Result<ExclusiveLockGuard>

Non-blocking LOCK_EX attempt on the cache-entry lockfile.

Trait Implementations§

Source§

impl Debug for CacheDir

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<T> MaybeSend for T
where T: Send,

§

impl<T> MaybeSend for T
where T: Send,