Skip to main content

squib_snapshot/
lib.rs

1//! `squib-snapshot` — bitcode state file, sparse memory file, dirty-page tracking.
2//!
3//! Implements Phase 5 of the squib roadmap. The crate is split into:
4//!
5//! - [`error`] — wire-stable [`SnapshotError`] (I-RC-8 in 11 § 7).
6//! - [`state`] — `MicrovmState` and child structs (vCPU, GIC, MMDS, devices).
7//! - [`envelope`] — `Snapshot<T>` outer container with bitcode + CRC64 trailer.
8//! - [`atomic`] — D25 temp-file + fsync + rename writer with cross-FS pre-flight check.
9//! - [`memory`] — Full / sparse-of-dirty memory-file writer.
10//! - [`dirty`] — `Box<[AtomicU64]>` dirty bitmap + adaptive heuristic (D11 + D21).
11//! - [`mod@save`] / [`mod@load`] — high-level orchestrators that tie the pieces together.
12//!
13//! Cross-references: [16-snapshots.md](../../../specs/16-snapshots.md),
14//! [10-data-model.md §
15//! 5–6](../../../specs/10-data-model.md#5-microvmstate--the-snapshot-state-blob), [11-runtime-core.
16//! md § 6](../../../specs/11-runtime-core.md#6-error-types), [99-key-decisions.md § D5, D11, D21,
17//! D25](../../../specs/99-key-decisions.md).
18//!
19//! # Quality bar
20//!
21//! `#![forbid(unsafe_code)]` — every public surface is safe Rust. The Mach-exception
22//! pager that backs `--mem-backend=Uffd` lives in the sibling `squib-host` crate
23//! where the `unsafe` is bounded and reviewed.
24
25#![forbid(unsafe_code)]
26#![warn(missing_docs)]
27// Snapshot prose talks about hardware names (CRC64, ECMA-182, GICR, CPU_ON, ...) and
28// path types; backticking each adds noise.
29#![allow(clippy::doc_markdown)]
30// `unwrap_or` on infallible conversions in test fixtures keeps the test surface
31// readable without injecting explicit error paths the test does not exercise.
32#![allow(clippy::cast_possible_truncation)]
33// The snapshot subsystem is synchronous by design: a save quiesces vCPUs, encodes
34// state, fsyncs, renames, resumes. Going through `tokio::fs` here would force
35// async-fn-coloring on a producer that holds the vCPU pause — and the spec's
36// quiesce timeout (1 s) bounds the blocking time. `clippy::disallowed_methods` is
37// a runtime-code lint per the project's policy (see `crates/vmm/src/lib.rs`).
38#![allow(clippy::disallowed_methods, clippy::disallowed_types)]
39
40pub mod atomic;
41pub mod dirty;
42pub mod envelope;
43pub mod error;
44pub mod load;
45pub mod memory;
46pub mod save;
47pub mod state;
48pub mod vcpu_save;
49
50pub use atomic::{
51    AtomicWriter, TEMP_SUFFIX, UnlinkOnDrop, check_same_filesystem, derive_temp_path,
52};
53pub use dirty::{
54    ADAPTIVE_WINDOW, AdaptiveController, DEFAULT_STEP_DOWN_THRESHOLD, DirtyBitmap, TrackedRegion,
55    TrackingGranule,
56};
57pub use envelope::{
58    Crc64Writer, SNAPSHOT_DESERIALIZATION_BYTES_LIMIT, SNAPSHOT_MAGIC_AARCH64, SNAPSHOT_VERSION,
59    Snapshot, SnapshotHdr, arch_magic,
60};
61pub use error::{Result, SnapshotError};
62pub use load::{LoadedSnapshot, SnapshotDescription, describe, load};
63pub use memory::{MemorySnapshotKind, MemoryWriter, PageReader, VecPageReader};
64pub use save::{SaveReport, SaveRequest, SnapshotKind, save};
65pub use state::{
66    DeviceState, DeviceStates, FpSimdRegs, GicState, GpRegs, MicrovmState, MmdsState,
67    PsciVcpuState, VcpuState, VmInfo,
68};
69pub use vcpu_save::{
70    GicRestoreTarget, GicSnapshotSource, MmdsRestoreTarget, MmdsSnapshotSource, VcpuRestoreTarget,
71    VcpuSnapshotSource, capture_vcpu_state, normalized_psci_state, restore_vcpu_state,
72};