lib/machine/src/checkpoint/stream/root.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 //! Moving a machine capture between processes, files, and hosts requires
 2 //! turning that capture into bytes. 4096 contiguous bytes of a machine's
 3 //! memory, named by its zero-based index, form a *page*. The machine's fixed
 4 //! 67,108,864 bytes, addressed from zero and holding 16,384 pages, form its
 5 //! *memory*. A memory image whose page tables have been rewritten to their
 6 //! canonical form and whose boot frame, request ring, event ring, and kernel
 7 //! stack are zeroed is *normalized memory*. A checkpoint holding a complete
 8 //! normalized memory image in two caller-owned regions is a *durable
 9 //! checkpoint*. The calls here write one complete durable checkpoint as bytes
10 //! and read one back. The fixed 67,112,960-byte encoding of one durable
11 //! checkpoint, formed by 4096 leading bytes followed by all normalized memory,
12 //! is the *checkpoint stream*. The stream's first 4096 bytes form the *header*.
13 //!
14 //! The digest binding one profile fingerprint to one state digest is the
15 //! *checkpoint root*. The SHA-256 identity of a normalized memory image is the
16 //! *memory digest*. The record of a stopped machine boundary with activation
17 //! authority removed, so one guest state keeps one identity across runs, is the
18 //! *settled receipt*. The ten register values a restarted machine begins with
19 //! form the *CPU restart frame*. The kernel image's digest, the initial CPU
20 //! state it admits, its entry offset, and up to four load ranges placing image
21 //! bytes in memory form the *immutable image descriptor*. Header byte ranges
22 //! the writer fills with zero and the reader requires to be zero are the
23 //! *reserved bytes*. The header encodes the checkpoint root, the memory digest,
24 //! the settled receipt, the CPU restart frame, and the immutable image
25 //! descriptor in little-endian fields.
26 //!
27 //! A capture arriving as bytes comes from outside the reader's control, so
28 //! every field it carries has to be checked before the capture is used. Two
29 //! builds have to agree on the layout down to the byte, so the header states
30 //! its own field widths and the reader compares each one.
31 //!
32 //! The caller-owned metadata region holding a publication status and the
33 //! authenticated metadata behind it is the *checkpoint storage*. A reader that
34 //! claimed the caller's storage and then failed would leave that storage
35 //! unusable.
36 //!
37 //! Encoding verifies the checkpoint before it writes a byte.
38 //!
39 //! Decoding rejects a wrong magic value, version, header size, flag word,
40 //! format, stream or memory byte count, page size, interface version, or field
41 //! width. Decoding requires every reserved range to be zero. Decoding requires
42 //! the header's checkpoint root to equal the root the caller expected, and it
43 //! reads that root before the memory bytes arrive. Decoding rejects a stream
44 //! that ends early and a stream with bytes after the memory image. The
45 //! fixed-size values needed to recompute an identity and rebuild execution:
46 //! profile fingerprint, settled receipt, CPU restart frame, and immutable image
47 //! descriptor, are the *material*. Decoding rejects material that fails its own
48 //! verification, so a settled receipt that does not check out returns
49 //! `CheckpointCorrupt`. Decoding rejects a reader whose object or buffer
50 //! overlaps either destination.
51 //!
52 //! A publication claim held open while another source fills the memory,
53 //! published only after the filled bytes authenticate, is a *materialization*.
54 //! Decoding conducts that materialization across the caller's checkpoint
55 //! storage and memory region, authenticating the bytes against the header's
56 //! memory digest and checkpoint root. A failure after the claim aborts it and
57 //! returns the storage to empty.
58 
59 const codec = @import("codec.zig");
60 const decode = @import("decode.zig");
61 const encode = @import("encode.zig");
62 
63 pub const Error = codec.Error;
64 pub const decodeHeader = decode.header;
65 pub const decodeDisjoint = codec.decodeDisjoint;
66 pub const encodeHeader = encode.header;
67 pub const encodeDisjoint = codec.encodeDisjoint;
68 pub const header_bytes = codec.header_bytes;
69 pub const stream_bytes = codec.stream_bytes;