lamzfs 0.1.1

no_std read-only ZFS reader for UEFI bootloaders (single/mirror/raidz1, unencrypted bpool)
Documentation

lamzfs

Crates.io Docs.rs CI License

A no_std + alloc, read-only ZFS pool reader for UEFI bootloaders.

lamzfs imports a ZFS pool over a plain byte source, walks to one dataset, and reads its files — enough for a bootloader to find a kernel and initramfs without the OpenZFS kernel module, without std, and without a GPL UEFI driver. The motivating target is Ubuntu / Debian root-on-ZFS, which keep a simple bpool boot pool. Read-only by construction: there is no write path and no BlockWrite.

Scope (v0.1)

Supported:

  • Topologies: single disk, mirror, and single-parity RAID-Z1 (including degraded reads that reconstruct a missing/corrupt column from parity).
  • Compression: off, zle, lzjb, lz4, gzip, zstd (each a feature).
  • Checksums: Fletcher-2/4 and SHA-256 (scalar).
  • The full read walk: vdev label → uberblock → MOS → DSL → dataset → ZPL → ZAP directories → indirect block-pointer tree (sparse-file aware).

Out of scope: any write path, encryption, RAID-Z2/3, dRAID, and gang blocks (each rejected with a typed error).

Usage

Implement BlockRead over your device, then import and read:

use lamzfs::{BlockRead, PoolMember, Zfs};

# struct Disk;
# impl BlockRead for Disk {
#     type Error = ();
#     fn read_at(&mut self, _off: u64, _buf: &mut [u8]) -> Result<(), ()> { Ok(()) }
# }
# fn members() -> Vec<PoolMember<Disk>> { Vec::new() }
let mut zfs = Zfs::import(members())?;          // one PoolMember per vdev member
println!("pool {} ({:#x})", zfs.pool_name(), zfs.pool_guid());

// Dataset path = child-directory components under the pool root; the second
// argument is the directory within that dataset (empty = its root).
for entry in zfs.read_dir(&["BOOT", "default"], &[])? {
    println!("{:?} {}", entry.kind, entry.name);
}
let kernel = zfs.read(&["BOOT", "default"], &["vmlinuz"])?;
# Ok::<(), lamzfs::Error>(())

See examples/zfsdump.rs for a runnable host tool.

Basis

The on-disk decoders are vendored from rzfs, electing the MIT half of its GPL-2.0 OR MIT dual license — a clean-room reader, not GPL kernel/userspace source. The orchestration (pool import, vdev routing, dataset walk, path resolve, file read) is new lamzfs code. The crate is scalar-only and #![forbid(unsafe_code)]. See NOTICE for attribution.

License

Licensed under either of

at your option. Vendored upstream portions retain their own terms (see NOTICE).

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be dual licensed as above, without any additional terms or conditions.