Skip to main content

microsandbox_utils/index/
types.rs

1//! Wire format types for the layer sidecar index.
2//!
3//! Binary mmap-friendly index generated at OCI layer extraction time and consumed
4//! by OverlayFs at runtime. See `layer-index-format.md` for the full specification.
5//!
6//! All types are `#[repr(C)]` with natural alignment for zero-copy mmap access on
7//! little-endian targets (x86_64, aarch64).
8
9//--------------------------------------------------------------------------------------------------
10// Constants
11//--------------------------------------------------------------------------------------------------
12
13/// Magic bytes: "MSBi" in little-endian.
14pub const INDEX_MAGIC: u32 = 0x6942_534D;
15
16/// Current wire format version.
17pub const INDEX_VERSION: u32 = 1;
18
19/// DirRecord flag: directory is opaque (hides all lower entries).
20pub const DIR_FLAG_OPAQUE: u8 = 0x01;
21
22/// EntryRecord flag: entry is a whiteout (masks a lower entry).
23pub const ENTRY_FLAG_WHITEOUT: u8 = 0x01;
24
25/// Sentinel value for `EntryRecord.dir_record_idx` on non-directory entries.
26pub const DIR_RECORD_IDX_NONE: u32 = 0xFFFF_FFFF;
27
28//--------------------------------------------------------------------------------------------------
29// Types
30//--------------------------------------------------------------------------------------------------
31
32/// Index file header (32 bytes, offset 0).
33#[repr(C)]
34#[derive(Debug, Clone, Copy)]
35pub struct IndexHeader {
36    /// Magic bytes (`INDEX_MAGIC`).
37    pub magic: u32,
38    /// Wire format version (`INDEX_VERSION`).
39    pub version: u32,
40    /// Reserved flags (must be 0).
41    pub flags: u32,
42    /// Number of `DirRecord` entries.
43    pub dir_count: u32,
44    /// Total number of `EntryRecord` entries across all directories.
45    pub entry_count: u32,
46    /// Number of `HardlinkRef` entries.
47    pub hardlink_ref_count: u32,
48    /// Total bytes in the string pool.
49    pub string_pool_size: u32,
50    /// CRC32C of entire file with this field zeroed.
51    pub checksum: u32,
52}
53
54/// A directory in the index (24 bytes). Sorted by path (lexicographic).
55#[repr(C)]
56#[derive(Debug, Clone, Copy)]
57pub struct DirRecord {
58    /// String pool offset for directory path.
59    pub path_off: u32,
60    /// Byte length of path (`""` for root, `"etc"`, `"usr/bin"`).
61    pub path_len: u16,
62    /// Flags (bit 0 = `DIR_FLAG_OPAQUE`).
63    pub flags: u8,
64    /// Padding.
65    pub _pad: u8,
66    /// Index of first child in the entry table.
67    pub first_entry: u32,
68    /// Number of children in this directory.
69    pub entry_count: u32,
70    /// String pool offset for overflow tombstone data (0 = none).
71    pub tombstone_off: u32,
72    /// Number of overflow tombstoned names.
73    pub tombstone_count: u16,
74    /// Padding.
75    pub _pad2: u16,
76}
77
78/// A filesystem entry in the index (40 bytes, 8-byte aligned).
79/// Grouped by parent directory (contiguous), sorted by name within each group.
80#[repr(C)]
81#[derive(Debug, Clone, Copy)]
82pub struct EntryRecord {
83    /// Host inode number (`LowerOriginId.object_id`).
84    pub host_ino: u64,
85    /// File size in bytes.
86    pub size: u64,
87    /// String pool offset for entry name.
88    pub name_off: u32,
89    /// Full stat mode including `S_IFMT` type bits.
90    pub mode: u32,
91    /// Guest-visible uid (from `override_stat` xattr).
92    pub uid: u32,
93    /// Guest-visible gid (from `override_stat` xattr).
94    pub gid: u32,
95    /// Byte length of name.
96    pub name_len: u16,
97    /// Flags (bit 0 = `ENTRY_FLAG_WHITEOUT`).
98    pub flags: u8,
99    /// Padding.
100    pub _pad: u8,
101    /// `DirRecord` index for directory entries; `DIR_RECORD_IDX_NONE` for non-dirs.
102    pub dir_record_idx: u32,
103}
104
105/// A hardlink reference (16 bytes, 8-byte aligned).
106/// Sorted by `host_ino`, then by path. Only entries with nlink > 1 within the layer.
107#[repr(C)]
108#[derive(Debug, Clone, Copy)]
109pub struct HardlinkRef {
110    /// Shared host inode number.
111    pub host_ino: u64,
112    /// String pool offset for full path (e.g. `"usr/bin/tool"`).
113    pub path_off: u32,
114    /// Byte length of path.
115    pub path_len: u32,
116}
117
118// Compile-time size assertions.
119const _: () = assert!(size_of::<IndexHeader>() == 32);
120const _: () = assert!(size_of::<DirRecord>() == 24);
121const _: () = assert!(size_of::<EntryRecord>() == 40);
122const _: () = assert!(size_of::<HardlinkRef>() == 16);