Files
zosstorage/PROMPT.md

9.3 KiB
Raw Permalink Blame History

You are GPT-5 Codex paired with KILO coder. Produce only what is requested. Do not improvise.

Objective

  • Implement zosstorage, a Rust binary compiled for static musl, embedded in an Alpine Linux initramfs (x86_64 only).
  • Purpose: one-shot disk initializer invoked during the first boot of a fresh node. Idempotent; if rerun on a system already provisioned, it must perform no changes and exit success.
  • Absolutely never destroy, overwrite, or repartition devices containing existing data. Development/testing uses pristine virtual disks only. Abort immediately if a target device is not empty.

Execution Context

  • Runs inside initramfs on Alpine Linux (busybox environment). No reliance on system services or long-running daemons.
  • No Cargo.toml manual edits; dependencies managed via cargo add. All code must compile with stable Rust toolchains available in the build system.
  • Avoid stdout spam. Implement structured logging/tracing (details TBD) but no stray println!.

Development Methodology

  • Compartmentalize the codebase into clear modules from the outset.
  • Begin by proposing the repository layout (directories, modules, tests, docs).
  • Define public APIs first: traits, structs, enums, function signatures, and associated documentation comments.
  • Only after obtaining approval on the API surface may you proceed to fill in function bodies.
  • Use todo!() or explanatory comments as temporary placeholders until behavior is agreed upon.
  • Preserve this iterative approach for every major module: outline first, implementation after review.

Device Discovery

  • Enumerate candidate block devices under /dev and filter out all pseudodevices (/dev/ram*, /dev/zram*, /dev/fd*, /dev/loop*, etc.). The filtering rules must be configurable for future allowlists (e.g., removable media).
  • Default device classes include /dev/sd*, /dev/nvme*, /dev/vd*. If no eligible disks are found, return a well-defined error.

Partitioning Requirements

  • Use GPT exclusively. Honor 1MiB alignment boundaries.
  • For BIOS compatibility on BIOS systems, create a small bios_boot partition (size 1MiB, placed first). When running under UEFI (/sys/firmware/efi present), the BIOS boot partition is suppressed.
  • Create a 512MiB FAT32 ESP on each disk, label ZOSBOOT. Each ESP is independent; synchronization will be handled by another tool (out of scope). Ensure unique partition UUIDs while keeping identical labels.
  • Remaining disk capacity is provisioned per configuration (see below).
  • Before making changes, verify the device has no existing partitions or filesystem signatures; abort otherwise.

Filesystem Provisioning

  • Mount scheme and subvolumes:
    • Root mounts for each data filesystem at /var/mounts/{UUID} (runtime only). For btrfs root, use -o subvolid=5; for bcachefs root, no subdir option.
    • Create or ensure subvolumes on the primary data filesystem with names: system, etc, modules, vm-meta.
    • Mount subvolumes to final targets:
      • /var/cache/system
      • /var/cache/etc
      • /var/cache/modules
      • /var/cache/vm-meta
    • Use UUID= sources for all mounts (never device paths).
    • Subvolume options:
      • btrfs: -o subvol={name},noatime
      • bcachefs: -o X-mount.subdir={name},noatime
  • Supported backends:
    • Single disk: default to btrfs, label ZOSDATA.
    • Two disks/NVMe (dual_independent): default to independent btrfs per disk, each labeled ZOSDATA; root-mount all under /var/mounts/{UUID}, pick the first data FS as primary for final subvol mounts.
    • Mixed SSD/NVMe + HDD: default to bcachefs with SSD as cache/promote and HDD as backing store, resulting FS labeled ZOSDATA. Alternative mode: separate btrfs per device (label ZOSDATA).
  • Reserved filesystem labels: ZOSBOOT (ESP), ZOSDATA (all data filesystems). GPT partition names: zosboot (bios_boot and ESP), zosdata (data), zoscache (cache).
  • Filesystem tuning options (compression, RAID profile, etc.) must be configurable; define sensible defaults and provide extension points.

Configuration Input

  • Accept configuration via:
    • Kernel command line parameter zosstorage.config= pointing to a YAML configuration descriptor.
    • Optional CLI flags when run in user space (mirror kernel cmdline semantics).
    • On-disk YAML config file (default path /etc/zosstorage/config.yaml).
  • Precedence: kernel cmdline overrides CLI arguments, which override config file, which override built-in defaults. No interactive prompts inside initramfs.
  • YAML schema must describe disk selection rules, desired filesystem layout, boot partition preferences, filesystem options, mount targets, and logging verbosity. See docs/SCHEMA.md and src/types.rs.

State Reporting

  • After successful provisioning, emit a JSON state report (path TBD, e.g., /run/zosstorage/state.json) capturing:
    • Enumerated disks and their roles,
    • Created partitions with identifiers,
    • Filesystems, labels (ZOSBOOT, ZOSDATA, ZOSCACHE), mountpoints,
    • Overall status and timestamp.
  • Ensure the report is machine-readable and versioned.

Logging

  • Integrate a structured logging/tracing backend (e.g., tracing crate). Provide log levels (error, warn, info, debug) and allow configuration through CLI/config/cmdline.
  • By default, logs go to stderr; design for optional redirection to a file (path TBD). Avoid using println!.

System Integration

  • /etc/fstab generation: optional via CLI/config. When enabled, write only the four final subvolume/subdir mount entries (system, etc, modules, vm-meta) with UUID= sources in deterministic order. Root mounts under /var/mounts/{UUID} are runtime-only and excluded from fstab.
  • After provisioning, ensure the initramfs can mount the new filesystems (e.g., call udevadm settle if necessary). No external services are invoked.
  • No responsibility for updating vmlinuz.efi; another subsystem handles kernel updates.

Failure Handling

  • If any target disk fails validation (non-empty, filtered out, or errors occur), abort the entire run with a descriptive error message. Provide a --force flag stub for future use, but keep it non-functional for now (must return “unimplemented”).

Testing & Validation (initial expectations)

  • Provide integration test scaffolding targeting QEMU/KVM scenarios (e.g., single virtio disk 40GiB, dual NVMe 40GiB each, SSD+HDD mix). Tests can be smoke-level initially but must compile.
  • Document manual testing steps for developers to reproduce in VMs.
  • VM test matrix using virtio disks (/dev/vd?) to validate topologies:
    • 1 disk (/dev/vda): single topology → create btrfs on the data partition labeled ZOSDATA.
    • 2 disks (/dev/vda, /dev/vdb):
      • dual_independent: btrfs per disk (two independent ZOSDATA filesystems).
      • bcachefs cache/backing: treat /dev/vda as cache (SSD-like) and /dev/vdb as backing (HDD-like); create one bcachefs labeled ZOSDATA.
      • btrfs_raid1: mirrored btrfs across the two data partitions labeled ZOSDATA.
    • 3 disks (/dev/vda, /dev/vdb, /dev/vdc):
      • bcachefs: cache on /dev/vda; backing on /dev/vdb and /dev/vdc with two replicas (two copies), labeled ZOSDATA.
  • Ensure device discovery includes /dev/vd* by default and filters pseudodevices. Documentation & Deliverables
  • Produce comprehensive README including: overview, prerequisites, configuration schema, example YAML, command-line usage, JSON report format, filesystem label semantics (ZOSBOOT, ZOSDATA, ZOSCACHE), limitations, and roadmap.
  • Ensure Rust code contains module-level and public API documentation (/// doc comments). Implement --help output mirroring README usage.
  • Include architectural notes describing module boundaries (device discovery, partitioning, filesystem provisioning, config parsing, logging, reporting).

Open Items (call out explicitly)

  • BIOS vs UEFI: bios_boot partition size fixed at 1MiB and created only on BIOS systems; suppressed under UEFI (/sys/firmware/efi present).
  • Mount scheme finalized:
    • Root mounts for each data filesystem at /var/mounts/{UUID} (runtime only).
    • Final subvolume/subdir mounts from the primary data filesystem to /var/cache/{system,etc,modules,vm-meta}.
  • Filesystem-specific tuning parameters (compression, RAID values, bcachefs options) remain open for refinement; sensible defaults applied.
  • Config paths and keys stabilized:
    • Kernel cmdline key: zosstorage.config=
    • Default config file: /etc/zosstorage/config.yaml
    • Default report path: /run/zosstorage/state.json
    • Optional log file: /run/zosstorage/zosstorage.log
  • /etc/fstab generation policy decided: optional flag; writes only the four final subvolume/subdir entries.

Implementation Constraints

  • Stick to clear module boundaries. Provide unit tests where possible (e.g., config parsing, device filtering).
  • Maintain strict idempotency: detect when provisioning already occurred (e.g., presence of ZOSBOOT partitions and expected filesystem labels ZOSDATA/ZOSCACHE) and exit gracefully.
  • Write clean, production-quality Rust adhering to idiomatic practices and Clippy.

Deliverables

  • Repository layout proposal (src modules, tests directory, docs). Highlight major components and their responsibilities.
  • API skeletons (traits, structs, function signatures) with doc comments, using todo!() placeholders for bodies until approved.
  • After API approval, progressively fill in implementations, preserving the compartmentalized structure and documenting assumptions.