- Orchestrator: - Add mutually exclusive modes: --mount-existing, --report-current, --apply - Wire mount-existing/report-current flows and JSON summaries - Reuse mount planning/application; never mount ESP - Context builders for new flags (see: src/orchestrator/run.rs:1) - CLI: - Add --mount-existing and --report-current flags - Keep -t/--topology (ValueEnum) as before (see: src/cli/args.rs:1) - FS: - Implement probe_existing_filesystems() using blkid to detect ZOSDATA/ZOSBOOT and dedupe by UUID (see: src/fs/plan.rs:1) - Config loader: - Precedence now: CLI flags > kernel cmdline (zosstorage.topo) > built-in defaults - Read kernel cmdline topology only if CLI didn’t set -t/--topology - Default topology set to DualIndependent - Do not read /etc config by default in initramfs (see: src/config/loader.rs:1) - Main: - Wire new Context builder flags (see: src/main.rs:1) Rationale: - Enables running from in-kernel initramfs with no config file - Topology can be selected via kernel cmdline (zosstorage.topo) or CLI; CLI has priority
zosstorage
One-shot disk provisioning utility intended for initramfs. It discovers eligible disks, plans a GPT layout based on a chosen topology, creates filesystems, mounts them under a predictable scheme, and emits a machine-readable report. Safe-by-default with a non-destructive preview mode.
Status: apply mode implemented. Partition application (sgdisk), filesystem creation (vfat/btrfs/bcachefs), mount scheme with subvolumes, and optional fstab writing are available. Preview mode remains supported.
Key modules
- CLI and entrypoint:
- Orchestration and preview JSON:
- Configuration loader, overlays, defaults:
- Device discovery (sysfs + regex filters, removable policy):
- Idempotency detection and emptiness checks:
- Partition planning (topology-aware):
- Filesystem planning/creation and mkfs integration:
- Mount planning and application (skeleton):
Features at a glance
- Topology-driven planning with built-in defaults: BtrfsSingle, BcachefsSingle, DualIndependent, Bcachefs2Copy, BtrfsRaid1, SsdHddBcachefs
- Non-destructive preview: --show/--report outputs JSON summary (disks, partition plan, filesystems, planned mountpoints)
- Safe discovery: excludes removable media by default (USB sticks) unless explicitly allowed
- Config-optional: the tool runs without any YAML; sensible defaults are always present and may be overridden/merged by config
Requirements
- Linux with /proc and /sys mounted (initramfs friendly)
- External tools discovered at runtime:
- blkid (for probing UUIDs and signatures)
- sgdisk (for GPT application)
- mkfs.vfat, mkfs.btrfs, bcachefs (for formatting)
- udevadm (optional; for settle after partitioning)
- Tracing/logging to stderr by default; optional file at /run/zosstorage/zosstorage.log
Install and build
- System Rust toolchain: cargo build --release
Binary is target/release/zosstorage.
CLI usage
- Topology selection (config optional): -t, --topology btrfs-single|bcachefs-single|dual-independent|bcachefs-2copy|btrfs-raid1|ssd-hdd-bcachefs
- Preview (non-destructive): --show Print JSON summary to stdout --report PATH Write JSON summary to a file
- Discovery policy: --allow-removable Include removable devices (USB) during discovery
- Tracing/logging: -l, --log-level LEVEL error|warn|info|debug (default: info) -L, --log-to-file Also write logs to /run/zosstorage/zosstorage.log
- Other: -c, --config PATH Merge a YAML config file (overrides defaults) -s, --fstab Enable writing /etc/fstab entries (when mounts are applied) -a, --apply Perform partitioning, filesystem creation, and mounts (destructive) -f, --force Present but not implemented (returns an error)
Examples
- Single disk plan with debug logs: sudo ./zosstorage --show -t btrfs-single -l debug
- RAID1 btrfs across two disks; print and write summary: sudo ./zosstorage --show --report /run/zosstorage/plan.json -t btrfs-raid1 -l debug -L
- SSD+HDD bcachefs plan, include removable devices (for lab cases): sudo ./zosstorage --show -t ssd-hdd-bcachefs --allow-removable -l debug
- Quiet plan to file: sudo ./zosstorage --report /run/zosstorage/plan.json -t dual-independent
- Apply single-disk btrfs (DESTRUCTIVE; wipes target disk): sudo ./zosstorage --apply -t btrfs-single
Preview JSON shape (examples)
-
Already provisioned (idempotency success): { "version": "v1", "timestamp": "2025-09-26T12:34:56Z", "status": "already_provisioned", "state": { ... full StateReport JSON ... } }
-
Planned (not yet provisioned): { "version": "v1", "timestamp": "2025-09-26T12:34:56Z", "status": "planned", "topology": "btrfs_raid1", "alignment_mib": 1, "require_empty_disks": true, "disks": [ { "path": "/dev/nvme0n1", "size_bytes": 1000204886016, "rotational": false, "model": "...", "serial": "..." }, { "path": "/dev/nvme1n1", "size_bytes": 1000204886016, "rotational": false, "model": "...", "serial": "..." } ], "partition_plan": [ { "disk": "/dev/nvme0n1", "parts": [ { "role": "bios_boot", "size_mib": 1, "gpt_name": "zosboot" }, { "role": "esp", "size_mib": 512, "gpt_name": "zosboot" }, { "role": "data", "size_mib": null, "gpt_name": "zosdata" } ] }, { "disk": "/dev/nvme1n1", "parts": [ { "role": "data", "size_mib": null, "gpt_name": "zosdata" } ] } ], "filesystems_planned": [ { "kind": "vfat", "from_roles": ["esp"], "label": "ZOSBOOT" }, { "kind": "btrfs", "from_roles": ["data"], "devices_planned": 2, "label": "ZOSDATA" } ], "mount": { "scheme": "per_uuid", "base_dir": "/var/cache", "fstab_enabled": false, "root_mount_template": "/var/mounts/{UUID}", "final_targets": ["/var/cache/system", "/var/cache/etc", "/var/cache/modules", "/var/cache/vm-meta"] } }
Defaults and policies
- Device selection defaults (see src/config/loader.rs):
include_patterns: ^/dev/sd\w+
, ^/dev/nvme\w+n\d+, ^/dev/vd\w+$ exclude_patterns: ^/dev/ram\d+, ^/dev/zram\d+, ^/dev/loop\d+, ^/dev/fd\d+allow_removable: false (USB excluded unless --allow-removable) min_size_gib: 10 - Partitioning defaults: alignment_mib: 1 bios_boot: enabled (1 MiB), gpt_name: zosboot esp: 512 MiB, label: ZOSBOOT, gpt_name: zosboot data: gpt_name: zosdata cache: gpt_name: zoscache (only used in SSD+HDD topology)
- Filesystem defaults: vfat (ESP) label: ZOSBOOT btrfs (data) label: ZOSDATA bcachefs (data/cache) label: ZOSDATA
- Mount scheme:
- Root mounts (runtime only): each data filesystem is mounted at /var/mounts/{UUID}
- btrfs root options: rw,noatime,subvolid=5
- bcachefs root options: rw,noatime
- Subvolume mounts (from the primary data filesystem only) to final targets:
- /var/cache/system
- /var/cache/etc
- /var/cache/modules
- /var/cache/vm-meta
- Subvolume mount options:
- btrfs: -o rw,noatime,subvol={name}
- bcachefs: -o rw,noatime,X-mount.subdir={name}
- /etc/fstab generation is disabled by default; when enabled, only the four subvolume mounts are written (UUID= sources, deterministic order)
- Root mounts (runtime only): each data filesystem is mounted at /var/mounts/{UUID}
Tracing and logs
- stderr logging level controlled by -l/--log-level (info by default)
- optional file logging with -L/--log-to-file at /run/zosstorage/zosstorage.log
- Debug spans provide insight into discovery, idempotency, planning, and tool invocations
Extending and execution plan
- Near-term:
- Implement sgdisk partition apply and udev settle
- Pass btrfs raid profile flags -m/-d from config (raid1, none) to mkfs
- Create per-UUID mount targets; persist fstab when enabled
- Atomic report write via tempfile+rename
- Longer-term:
- Dry-run mode with richer diffs
- Richer schema for disks/partitions/filesystems in the report
- Additional filesystem and tuning support
Safety model
- Preview mode never mutates block devices
- Emptiness checks guard destructive actions (skipped only in preview)
- Reserved labels and GPT names validated to reduce risk
Troubleshooting
- No eligible disks found: adjust include/exclude patterns or use --allow-removable for test media
- Removable media excluded: either add --allow-removable or exclude it explicitly via config patterns
- blkid missing: install util-linux; preview can still plan but cannot capture UUIDs for mkfs outputs
- bcachefs command missing: install bcachefs-tools or skip the SSD+HDD topology
License
- TBD (add your preferred license)