# zosstorage Architecture This document defines the repository layout, module boundaries, public API surface (signatures only), defaults, and high-level execution flow for the initramfs-only provisioning utility. Baseline decisions and labels - External tools inside initramfs are allowed and will be wrapped via helpers: sgdisk, blkid, mkfs.vfat, mkfs.btrfs, mkfs.bcachefs, udevadm. - Kernel cmdline key: zosstorage.config= - Default config path: /etc/zosstorage/config.yaml - JSON state report path: /run/zosstorage/state.json - Optional log file path: /run/zosstorage/zosstorage.log - fstab generation: disabled by default - GPT partition names: zosboot, zosdata, zoscache - Filesystem labels: - ESP: ZOSBOOT - Data filesystems including bcachefs: ZOSDATA Repository layout Top level - [Cargo.toml](Cargo.toml) - [PROMPT.md](PROMPT.md) - [README.md](README.md) - [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) - [docs/SCHEMA.md](docs/SCHEMA.md) - [examples/config/minimal.yaml](examples/config/minimal.yaml) - [examples/config/dual-btrfs.yaml](examples/config/dual-btrfs.yaml) - [examples/config/ssd-hdd-bcachefs.yaml](examples/config/ssd-hdd-bcachefs.yaml) - [tests/](tests/) - [tests/integration_single_disk.rs](tests/integration_single_disk.rs) - [tests/integration_dual_disk.rs](tests/integration_dual_disk.rs) - [tests/integration_ssd_hdd.rs](tests/integration_ssd_hdd.rs) Crate sources - [src/main.rs](../src/main.rs) - [src/lib.rs](../src/lib.rs) - [src/errors.rs](../src/errors.rs) - [src/cli/args.rs](../src/cli/args.rs) - [src/logging/mod.rs](../src/logging/mod.rs) - [src/config/loader.rs](../src/config/loader.rs) - [src/types.rs](../src/types.rs) - [src/device/discovery.rs](../src/device/discovery.rs) - [src/partition/plan.rs](../src/partition/plan.rs) - [src/fs/plan.rs](../src/fs/plan.rs) - [src/mount/ops.rs](../src/mount/ops.rs) - [src/report/state.rs](../src/report/state.rs) - [src/orchestrator/run.rs](../src/orchestrator/run.rs) - [src/idempotency/mod.rs](../src/idempotency/mod.rs) - [src/util/mod.rs](../src/util/mod.rs) Module responsibilities - [src/main.rs](../src/main.rs) - Entrypoint. Parse CLI, initialize logging, load and merge configuration per precedence, call orchestrator. No stdout spam. - [src/lib.rs](../src/lib.rs) - Crate exports, prelude, version constants, Result alias. - [src/errors.rs](../src/errors.rs) - Common error enum and Result alias via thiserror. - [src/cli/args.rs](../src/cli/args.rs) - CLI definition mirroring kernel cmdline semantics; provide non-interactive interface. Stub --force returns unimplemented. - [src/logging/mod.rs](../src/logging/mod.rs) - Initialize tracing; levels error, warn, info, debug; default to stderr; optional file target. - [src/config/loader.rs](../src/config/loader.rs) and [src/types.rs](../src/types.rs) - YAML schema types, validation, loading, and merging with CLI and kernel cmdline. - [src/device/discovery.rs](../src/device/discovery.rs) - Device discovery under /dev with filters and allowlist; probe emptiness safely. - [src/partition/plan.rs](../src/partition/plan.rs) - GPT-only planning and application; 1 MiB alignment; create bios boot, ESP, data and cache partitions with strict safety checks. - [src/fs/plan.rs](../src/fs/plan.rs) - Filesystem provisioning: vfat for ESP, btrfs for ZOSDATA, bcachefs for SSD+HDD mode; all data filesystems labeled ZOSDATA. - [src/mount/ops.rs](../src/mount/ops.rs) - Mount scheme: - Root-mount all data filesystems under `/var/mounts/{UUID}` (runtime only) - btrfs root: `rw,noatime,subvolid=5` - bcachefs root: `rw,noatime` - Create or ensure subvolumes on the primary data filesystem: `system`, `etc`, `modules`, `vm-meta` - Mount final subvolume/subdir targets at `/var/cache/{system,etc,modules,vm-meta}` - Optional fstab writing: only the four final targets, deterministic order, `UUID=` sources; disabled by default - [src/report/state.rs](../src/report/state.rs) - Build and write JSON state report with version field. - [src/orchestrator/run.rs](../src/orchestrator/run.rs) - One-shot flow orchestration with abort-on-any-validation-error policy. - [src/idempotency/mod.rs](../src/idempotency/mod.rs) - Detect prior provisioning via GPT names and labels; return success-without-changes. - [src/util/mod.rs](../src/util/mod.rs) - Shell-out, udev settle, and helpers. Public API surface (signatures; implementation to follow after approval) Entrypoint and orchestrator - [fn main()](../src/main.rs:1) - [struct Context](../src/orchestrator/run.rs:1) - [fn run(ctx: &Context) -> Result<()>](../src/orchestrator/run.rs:1) CLI - [struct Cli](../src/cli/args.rs:1) - [fn from_args() -> Cli](../src/cli/args.rs:1) Logging - [struct LogOptions](../src/logging/mod.rs:1) - [fn init_logging(opts: &LogOptions) -> Result<()>](../src/logging/mod.rs:1) Config - [struct Config](../src/types.rs:1) - [enum Topology](../src/types.rs:1) - [struct DeviceSelection](../src/types.rs:1) - [struct FsOptions](../src/types.rs:1) - [struct MountScheme](../src/types.rs:1) - [fn load_and_merge(cli: &Cli) -> Result](../src/config/loader.rs:1) - [fn validate(cfg: &Config) -> Result<()>](../src/config/loader.rs:1) Device discovery - [struct Disk](../src/device/discovery.rs:1) - [struct DeviceFilter](../src/device/discovery.rs:1) - [trait DeviceProvider](../src/device/discovery.rs:1) - [fn discover(filter: &DeviceFilter) -> Result>](../src/device/discovery.rs:1) Partitioning - [struct PartitionSpec](../src/partition/plan.rs:1) - [struct PartitionPlan](../src/partition/plan.rs:1) - [struct PartitionResult](../src/partition/plan.rs:1) - [fn plan_partitions(disks: &[Disk], cfg: &Config) -> Result](../src/partition/plan.rs:1) - [fn apply_partitions(plan: &PartitionPlan) -> Result>](../src/partition/plan.rs:1) Filesystems - [enum FsKind](../src/fs/plan.rs:1) - [struct FsSpec](../src/fs/plan.rs:1) - [struct FsPlan](../src/fs/plan.rs:1) - [struct FsResult](../src/fs/plan.rs:1) - [fn plan_filesystems(disks: &[Disk], parts: &[PartitionResult], cfg: &Config) -> Result](../src/fs/plan.rs:1) - [fn make_filesystems(plan: &FsPlan) -> Result>](../src/fs/plan.rs:1) Mounting - [struct MountPlan](../src/mount/ops.rs:1) - [struct MountResult](../src/mount/ops.rs:1) - [fn plan_mounts(fs_results: &[FsResult], cfg: &Config) -> Result](../src/mount/ops.rs:1) - [fn apply_mounts(plan: &MountPlan) -> Result>](../src/mount/ops.rs:1) - [fn maybe_write_fstab(mounts: &[MountResult], cfg: &Config) -> Result<()>](../src/mount/ops.rs:1) Reporting - [const REPORT_VERSION: &str](../src/report/state.rs:1) - [struct StateReport](../src/report/state.rs:1) - [fn build_report(...) -> StateReport](../src/report/state.rs:1) - [fn write_report(report: &StateReport) -> Result<()>](../src/report/state.rs:1) Idempotency - [fn detect_existing_state() -> Result>](../src/idempotency/mod.rs:1) - [fn is_empty_disk(disk: &Disk) -> Result](../src/idempotency/mod.rs:1) Errors and Result - [enum Error](../src/errors.rs:1) - [type Result = std::result::Result](../src/errors.rs:1) Execution flow ```mermaid flowchart TD A[Start] --> B[Initialize logging] B --> C[Parse CLI and kernel cmdline] C --> D[Load and validate config] D --> E[Idempotency detection] E -->|already provisioned| Z[Exit success] E -->|not provisioned| F[Discover devices] F --> G[Plan partitions] G --> H[Apply partitions] H --> I[Plan filesystems] I --> J[Create filesystems] J --> K[Plan mounts] K --> L[Apply mounts] L --> M[Write state report] M --> N[Finalize] N --> Z[Exit success] ``` Configuration precedence - Kernel cmdline key zosstorage.config= overrides CLI and file - CLI flags override config file - Config file provides defaults at /etc/zosstorage/config.yaml - No interactive prompts in initramfs Device discovery and filtering - Include device classes by default: /dev/sd*, /dev/nvme*, /dev/vd* - Exclude pseudodevices: /dev/ram*, /dev/zram*, /dev/fd*, /dev/loop*, etc. - Allow future allowlists and removable media policies via configuration - If no eligible disks are found, return a well-defined error Partitioning plan - GPT exclusively with 1 MiB alignment - bios boot partition first, 1 MiB - ESP 512 MiB FAT32, label ZOSBOOT, GPT name zosboot - Data partition consumes remainder, GPT name zosdata - When cache is requested, create GPT name zoscache partitions as needed - Abort if any pre-existing partitions or filesystem signatures are detected - Ensure unique partition UUIDs and identical labels where required Filesystem provisioning defaults - Single disk: btrfs labeled ZOSDATA - Two disks: btrfs per disk labeled ZOSDATA, no RAID by default - SSD plus HDD: bcachefs with SSD as cache or promote and HDD as backing, filesystem label ZOSDATA - Filesystem tuning options configurable with sensible defaults and extension points Mount scheme and fstab policy - Runtime root mounts: - Each data filesystem is root-mounted at `/var/mounts/{UUID}` (runtime only) - btrfs: `rw,noatime,subvolid=5`; bcachefs: `rw,noatime` - Final targets (from primary data filesystem only): - `/var/cache/system`, `/var/cache/etc`, `/var/cache/modules`, `/var/cache/vm-meta` - btrfs subvolume option: `-o subvol={name},noatime` - bcachefs subdir option: `-o X-mount.subdir={name},noatime` - /etc/fstab generation: - Disabled by default. When enabled, write only the four final targets with `UUID=` sources in deterministic order. Root mounts under `/var/mounts` are excluded. Idempotency detection - Consider the system provisioned when expected GPT names and filesystem labels are present and consistent - On a provisioned system, exit success without making any changes Reporting - Emit machine-readable JSON state report at /run/zosstorage/state.json - Report includes enumerated disks and roles, created partitions with identifiers, filesystems with labels and mountpoints, overall status and timestamp - Version the report payload via REPORT_VERSION Logging - Use tracing with levels error, warn, info, debug - Default to stderr; optionally log to file at /run/zosstorage/zosstorage.log - Avoid println and stdout spam External tooling policy - Invoke system utilities via wrappers that check for tool availability, capture stderr, and emit structured logs - Provide udev settle helper; avoid reliance on long-running services Planned dependencies to add via cargo add - clap - serde, serde_yaml, serde_json - thiserror - anyhow or eyre - tracing, tracing-subscriber - nix - regex - uuid - which - time - tempfile Open items and assumptions to track - Exact BIOS boot size and placement pending confirmation; currently 1 MiB first - Final mount naming scheme under /var/cache may evolve - Filesystem tuning defaults for btrfs and bcachefs require stakeholder input - Paths for config, report, and log file may be adjusted later - fstab generation remains disabled by default pending decision Next steps after approval - Formalize configuration schema and validation rules in [docs/SCHEMA.md](docs/SCHEMA.md) - Define detailed doc comments for all listed types and functions - Prepare code-mode implementation skeletons with todo placeholders and add dependencies via cargo add