Files
zosstorage/docs/SPECS.md

13 KiB

zosstorage Detailed Specifications

This document finalizes core specifications required before code skeleton implementation. It complements docs/ARCHITECTURE.md and docs/SCHEMA.md, and references the API declarations listed in docs/API.md.

Linked modules and functions


1. Logging and tracing

Goals

  • Structured, low-noise logging compatible with initramfs.
  • Defaults to stderr. Optional file at /run/zosstorage/zosstorage.log controlled by config or CLI.

Configuration

  • Levels: error, warn, info, debug (default info).
  • Propagation: single global initialization via fn init_logging. Subsequent calls must be no-ops.

Implementation notes

  • Use tracing and tracing-subscriber.
  • Format: compact, with fields level, target, message, and optional module path. Avoid timestamps if writing to stderr in initramfs; include timestamps when logging to file.

Example behavior

  • CLI --log-level debug sets level to debug.
  • CLI --log-to-file or config.logging.to_file true enables file layer at /run/zosstorage/zosstorage.log.

2. JSON state report schema v1

Location

  • Default output: /run/zosstorage/state.json

Versioning

  • Include a top-level string field version equal to REPORT_VERSION. Start with v1.

Schema example

{
  "version": "v1",
  "timestamp": "2025-09-25T12:00:00Z",
  "status": "success",
  "disks": [
    {
      "path": "/dev/nvme0n1",
      "size_bytes": 40007973632,
      "rotational": false,
      "model": "QEMU NVMe Ctrl",
      "serial": "nvme-1234",
      "selected": true,
      "roles": ["esp", "data"]
    }
  ],
  "partitions": [
    {
      "disk": "/dev/nvme0n1",
      "number": 1,
      "role": "bios_boot",
      "gpt_name": "zosboot",
      "uuid": "11111111-1111-1111-1111-111111111111",
      "start_mib": 1,
      "size_mib": 1
    },
    {
      "disk": "/dev/nvme0n1",
      "number": 2,
      "role": "esp",
      "gpt_name": "zosboot",
      "uuid": "22222222-2222-2222-2222-222222222222",
      "start_mib": 2,
      "size_mib": 512,
      "fs_label": "ZOSBOOT"
    },
    {
      "disk": "/dev/nvme0n1",
      "number": 3,
      "role": "data",
      "gpt_name": "zosdata",
      "uuid": "33333333-3333-3333-3333-333333333333",
      "start_mib": 514,
      "size_mib": 39000
    }
  ],
  "filesystems": [
    {
      "kind": "vfat",
      "device": "/dev/nvme0n1p2",
      "uuid": "AAAA-BBBB",
      "label": "ZOSBOOT",
      "mountpoint": null
    },
    {
      "kind": "btrfs",
      "device": "/dev/nvme0n1p3",
      "uuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeffffffff",
      "label": "ZOSDATA",
      "mountpoint": "/var/cache/aaaaaaaa-bbbb-cccc-dddd-eeeeffffffff"
    }
  ],
  "mounts": [
    {
      "source": "/dev/nvme0n1p3",
      "target": "/var/cache/aaaaaaaa-bbbb-cccc-dddd-eeeeffffffff",
      "fstype": "btrfs",
      "options": "defaults,ssd,compress=zstd:3"
    }
  ]
}

Notes

  • UUID formats follow tool output: VFAT UUID short form allowed.
  • Status values: success, already_provisioned, error. On error, add error field with reason.

3. Device discovery and filtering rules

Default include patterns

  • ^/dev/sd\w+$
  • ^/dev/nvme\w+n\d+$
  • ^/dev/vd\w+$

Default exclude patterns

  • ^/dev/ram\d+$
  • ^/dev/zram\d+$
  • ^/dev/loop\d+$
  • ^/dev/fd\d+$

Selection policy

  • Compile include and exclude regex into DeviceFilter.
  • Enumerate device candidates and apply:
    • Must match at least one include.
    • Must not match any exclude.
    • Must be larger than min_size_gib (default 10).
  • Probing
    • Gather size, rotational flag, model, serial when available.
    • Expose via struct Disk.

No eligible disks


4. Partitioning plan

Constraints

  • GPT only; enforce 1 MiB alignment.
  • Abort immediately if any target disk is non-empty when require_empty_disks is true.

Layout defaults

  • BIOS boot: 1 MiB first, role BiosBoot, GPT name zosboot, no filesystem.
  • ESP: 512 MiB FAT32, GPT name zosboot; filesystem label ZOSBOOT.
  • Data: remainder, GPT name zosdata.
  • Cache partitions (only in ssd_hdd_bcachefs): GPT name zoscache on SSD.

Per-topology specifics

  • btrfs_single: All roles on the single disk; data formatted as btrfs.
  • bcachefs_single: All roles on the single disk; data formatted as bcachefs.
  • dual_independent: On each eligible disk (one or more), create BIOS boot (if applicable), ESP, and data.
  • bcachefs-2copy: Create data partitions on two or more disks; later formatted as one multi-device bcachefs spanning all data partitions.
  • ssd_hdd_bcachefs: SSD gets BIOS boot + ESP + zoscache; HDD gets BIOS boot + ESP + zosdata; combined later into one bcachefs.
  • btrfs_raid1: Two disks minimum; data partitions mirrored via btrfs RAID1.

Safety checks

  • Ensure unique partition UUIDs.
  • Verify no pre-existing partitions or signatures. Use blkid or similar via run_cmd_capture.
  • After partition creation, run udev settle via udev_settle.

Application


5. Filesystem provisioning strategies

Kinds

  • Vfat for ESP, label ZOSBOOT.
  • Btrfs for data in btrfs_single, dual_independent, and btrfs_raid1 (with RAID1 profile).
  • Bcachefs for data in bcachefs_single, ssd_hdd_bcachefs (SSD cache + HDD backing), and bcachefs-2copy (multi-device).
  • All data filesystems use label ZOSDATA.

Defaults

  • btrfs: compression zstd:3, raid_profile none unless explicitly set; for btrfs_raid1 use -m raid1 -d raid1.
  • bcachefs: cache_mode promote, compression zstd, checksum crc32c; for bcachefs-2copy use --replicas=2 (data and metadata).
  • vfat: ESP label ZOSBOOT.

Planning and execution


6. Mount scheme and fstab policy

Runtime root mounts (all data filesystems)

  • Each data filesystem is root-mounted at /var/mounts/{UUID} (runtime only).
  • btrfs root mount options: rw,noatime,subvolid=5
  • bcachefs root mount options: rw,noatime

Final subvolume/subdir mounts (from the primary data filesystem)

  • Create or ensure subvolumes named: system, etc, modules, vm-meta
  • Mount targets: /var/cache/system, /var/cache/etc, /var/cache/modules, /var/cache/vm-meta
  • btrfs options: -o rw,noatime,subvol={name}
  • bcachefs options: -o rw,noatime,X-mount.subdir={name}

fstab policy

  • Disabled by default.
  • When enabled, maybe_write_fstab writes only the four final subvolume/subdir entries using UUID= sources, in deterministic target order. Root mounts under /var/mounts are excluded.

7. Idempotency detection

Signals for already-provisioned system

  • Expected GPT names found: zosboot, zosdata, and zoscache when applicable.
  • Filesystems with labels ZOSBOOT for ESP and ZOSDATA for all data filesystems.
  • When consistent with selected topology, detect_existing_state returns a StateReport and orchestrator exits success without changes.

Disk emptiness

  • is_empty_disk checks for absence of partitions and FS signatures before any modification.

8. CLI flags and help text outline

Flags mirrored by struct Cli parsed via from_args

  • --config PATH
  • --log-level LEVEL error | warn | info | debug
  • --log-to-file
  • --fstab enable fstab generation
  • --show print preview JSON to stdout (non-destructive)
  • --report PATH write preview JSON to file (non-destructive)
  • --apply perform partitioning, filesystem creation, and mounts (DESTRUCTIVE)
  • --force present but returns unimplemented error

Kernel cmdline

  • zosstorage.config= accepts a path or file: URI or data: URL as described in docs/SCHEMA.md.

Help text sections

  • NAME, SYNOPSIS, DESCRIPTION
  • CONFIG PRECEDENCE
  • TOPOLOGIES: btrfs_single, bcachefs_single, dual_independent, bcachefs-2copy, ssd_hdd_bcachefs, btrfs_raid1
  • SAFETY AND IDEMPOTENCY
  • REPORTS
  • EXIT CODES: 0 success or already_provisioned, non-zero on error

9. Integration testing plan (QEMU KVM)

Scenarios to scaffold in tests/

  • Single disk 40 GiB virtio: validates btrfs_single topology end-to-end smoke.
  • Dual NVMe 40 GiB each: validates dual_independent topology (independent btrfs per disk).
  • SSD NVMe + HDD virtio: validates ssd_hdd_bcachefs topology (bcachefs with SSD cache/promote, HDD backing).
  • Three disks: validates bcachefs-2copy across data partitions using --replicas=2.
  • Negative: no eligible disks, or non-empty disk should abort.

Test strategy

  • Tests will be staged as integration test scaffolds that compile and document manual steps or automated harness placeholders.
  • Mocks
    • Provide a test DeviceProvider to simulate discovery when running without QEMU.
    • Wrap external tools via utility trait to enable command capture in dry-runs.

Artifacts to validate

  • Presence of expected partition GPT names.
  • Filesystems created with correct labels.
  • Runtime root mounts under /var/mounts/{UUID} and final subvolume targets at /var/cache/{system,etc,modules,vm-meta}.
  • JSON report validates against v1 schema.

10. Documentation deliverables


11. Build and packaging for static musl and Alpine initramfs

Rust build

  • Target: x86_64-unknown-linux-musl
  • Avoid glibc-only dependencies.

Binary constraints

  • No reliance on services; suitable for busybox initramfs.

Embedding in initramfs

  • Place the statically linked binary in initramfs.
  • Ensure required external tools (sgdisk, blkid, mkfs.vfat, mkfs.btrfs, mkfs.bcachefs, udevadm) are present in the same initramfs environment.

Runtime notes

  • Minimal stdout use; all status via tracing.
  • Exit codes:
    • 0 on success and on already provisioned.
    • Non-zero on any validation or execution error.

12. Open items carried forward

  • Confirm exact BIOS boot partition requirements across target platforms; currently set to 1 MiB first.
  • Finalize btrfs and bcachefs tuning defaults after stakeholder review.
  • Decide if/when to enable fstab generation by default in future.
  • Allow removable media policies and additional device classes in configuration.

13. Next steps

  • Proceed to code-mode to scaffold modules and types as declared in docs/API.md.
  • Add dependencies via cargo add as listed in docs/ARCHITECTURE.md.
  • Implement bodies with todo!() placeholders and exhaustive doc comments before enabling functional behavior.

End of specifications.