LeonOS Documentation

Official BusyBox and Storage Tools

Status and Scope

The production build now packages unmodified upstream BusyBox, util-linux, e2fsprogs, dosfstools and exfatprogs. Former private storage commands are no longer dispatched as BusyBox applets. The project-specific boot-payload copier is a separate script, explicitly not GNU grub-install.

Both production root targets have built successfully:

Actual embedded tool/library bytes and compatibility links are checked with debugfs, not inferred from staging success. The seven previously failing guest checks now pass, with the expanded suite reporting 93 passing checks and zero failures for each root. This includes formatting and checking a disposable QEMU AHCI partition, not a host disk. Ordinary and installer ISOs are generated by run images-iso; VMDK and a complete graphical installation were not tested in this round. VMware remains unverified.

The earlier kernel compilation failure was resolved by replacing an undeclared memcpy with __builtin_memcpy, matching existing local code. The kernel and root-image builds now pass that compilation gate. Broader Linux ABI work remains paused. The existing storage change stops logging pending asynchronous DMA (-EAGAIN) as a device error and retains real errors; its host regression passes. This does not establish VMware transport stability.

Sources and Linkage

BusyBox

util-linux

Filesystem Tools

Pinned official archives, SHA256 values and checksum provenance are in configs/storage-upstream.json:

PackageVersionCommands
e2fsprogs1.47.3mkfs.ext2, fsck.ext2
dosfstools4.2mkfs.fat, fsck.fat
exfatprogs1.4.3mkfs.exfat, fsck.exfat

The builder verifies archives and extracted source trees, configures out-of-tree, and checks source integrity again after installation. No source patches apply. The six core tools are static target ELFs, using target util-linux UUID/blkid archives where needed. exfatprogs uses libtool -all-static and an explicit libblkid.a path to avoid installed .la host paths. Package licenses are staged under /usr/share/licenses; build commands and hashes are recorded under build/storage-upstream/, including root/.storage-package.json.

Command and Rootfs Ownership

CommandsCanonical locationOwner
fdisk, sfdisk, blkid, fsck, runuser/usr/sbinutil-linux via storage-util-linux ownership transfer
mount, umount, lsblk/binutil-linux via storage-util-linux ownership transfer
mkfs.ext2, fsck.ext2, mkfs.fat, fsck.fat, mkfs.exfat, fsck.exfat/usr/sbinofficial filesystem packages via storage-filesystems ownership transfer
leonos-grub-installer/usr/sbinproject shell script staged by tools/build/rootfs-stage.sh
sync, shell and selected standard applets/bin/busyboxofficial BusyBox
find, xargs/usr/binofficial Alpine findutils APK

tools/storage_tools.py declares package outputs and old /sbin aliases. tools/build/rootfs-stage.sh stages the layout and its compatibility links after the producers, replacing stale BusyBox storage links. mkfs.vfat/mkfs.fat32 resolve to mkfs.fat; fsck.vfat/fsck.fat32 resolve to fsck.fat. These are path aliases, not translations of the private CLI. Use upstream options: in particular FAT32 requires -F 32, including when using the mkfs.fat32 alias; dosfstools otherwise selects FAT width by volume size. The former private --force syntax is not emulated.

ChenPi cmd resolves storage commands directly to those external paths. /bin, /sbin, /lib, /usr/bin, /usr/sbin remain real separate directories; this is not a usr-merge. Normal, installer-runtime and installed-payload roots consume the same staging tree. Repeated storage staging replaces owned files before copying, preserving e2fsprogs' read-only archive modes without failing on the second build.

Before copying util-linux, staging checks every required command and library against the package root. A missing library or a link escaping that root fails before copying; an old staging library cannot satisfy the check.

Upstream BusyBox power commands normally signal PID 1. LeonOS init blocks and synchronously receives SIGUSR1 (halt), SIGUSR2 (poweroff) and SIGTERM (reboot), calls sync and the real reboot interface, and stays alive if that call fails. It also waits for SIGCHLD and reaps exited children. This preserves unmodified BusyBox command behavior without converting commands to forced reboot wrappers. This is not a service shutdown supervisor: orderly termination of every service before power transition remains unimplemented.

The boot copier validates its input files and destination directory, then copies EFI/BOOT/BOOTX64.EFI, loader.elf, leonos/kernel.sys and the complete grub directory. Default source is /install/esp; --source DIR supports an explicit prebuilt payload. It does not generate GRUB, format/mount an ESP, install boot sectors, or update NVRAM. The supplied destination must already be the intended mounted ESP. Tests cover spaces, exact bytes, absent destination, missing/partial source and nonzero failure reporting.

The graphical/TTY installer still uses its existing native shared block/format/ mount implementation. This task does not redesign or validate that workflow.

Verification


make iso
make installer
python3 tools/test_auth_source_integrity.py -v
python3 tools/test_storage_payload.py -v
python3 tools/test_upstream_tools_runtime.py -v
python3 tools/test_storage_upstream_runtime.py -v
LEONOS_STORAGE_TEST_ROOT=out/x86_64/release/stage/esp LEONOS_UPSTREAM_TEST_ROOT=out/x86_64/release/stage/esp \
  python3 tools/test_storage_upstream_runtime.py -v
python3 tools/test_storage_upstream_guest.py --root out/x86_64/release/images/installer-root.ext2 --smp 2
python3 tools/test_storage_upstream_guest.py --root out/x86_64/release/images/root.ext2 --smp 1
python3 tools/test_upstream_tools_images.py -v
python3 tools/test_regular_file_io.py
python3 tools/test_tmpfs.py
python3 tools/test_linux_memory.py
python3 tools/test_linux_threads.py
python3 tools/test_storage_mkdir_mount.py
python3 tools/test_storage_rename.py
python3 tools/test_storage_metadata.py
python3 tools/test_init_power.py
python3 tools/test_storage_upstream_guest.py --root out/x86_64/release/images/root.ext2 --power reboot
python3 tools/test_storage_upstream_guest.py --root out/x86_64/release/images/root.ext2 --power poweroff

Host reference tests execute the actual target ELFs with explicit target library search paths. They create GPT and ext2/FAT32/exFAT only on disposable regular files; checkers must reject unformatted files. Host mount tests are version and read-only listing tests. None of these tests writes a host block device.

Image tests compare 20 embedded commands/libraries at each of the three root locations and verify the declared compatibility links. The combined build log for this repair is build/storage-tools-build.log. Artifacts: build/images/leonos4.iso and build/images/leonos4-installer.iso. ISO and embedded payload verification is recorded in build/storage-tools-iso-evidence.json; obsolete hashes from the pre-fix images must not be used to identify this build.

Guest probes copy a production root, add only a test executable at the existing inventory autospawn slot, then build a diagnostic ISO. They do not patch the kernel or replace production tools. QEMU has no host block devices attached. The runner records base-image SHA256, invocation, complete serial output and failures under build/storage-upstream-guest/{install-smp2,live-smp1}/ and returns nonzero for failures; passing individual commands does not set package-wide acceptance.

The dedicated power probes pass with the rebuilt Live root: --power reboot receives SHUTDOWN reason=guest-reset, and --power poweroff receives SHUTDOWN reason=guest-shutdown. Both serial logs record the expected PID 1 reboot(2) command. Evidence is under the live-reboot and live-poweroff subdirectories. The host init harness separately covers halt/reboot/poweroff signal mappings, child reaping and failed reboot without invoking host power.

The inventory autospawn slot can execute before init finishes runtime startup. Power probes wait for the power signals to be blocked in /proc/1/stat before executing BusyBox. An earlier immediate request terminated PID 1 with SIGTERM: the kernel's missing early PID 1 default-signal protection remains a limitation. These passing post-initialization tests do not certify that early-boot case.

Repaired Guest Failures (2026-09-13)

Previous failureImplementation and observed resultStatus
lsblk inventoryReal disks/partitions, /sys/dev/block, /sys/block, /sys/class/block, sizes and matching st_rdev; disk0/disk0p1 listedVerified subset
mkfs.ext2Scalar I/O aggregates transport chunks, retaining progress across asynchronous retries; regular image and QEMU AHCI partition format successfullyVerified subset
fsck.ext2Checks both successfully formatted ext2 targetsVerified subset
blkid ext2Identifies the ext2 filesystem created by the official formatterVerified subset
fsck.fatFull 516096-byte read is no longer capped at 32768 bytes; checker succeedsVerified subset
mount tmpfsSource is a label; real sparse RAM filesystem with inode/page quotas and native metadataVerified subset
umount tmpfsReleases the filesystem, rejects live references with EBUSY, restores underlying directoryVerified subset

The expanded 93-check suite also covers 1 MiB scalar/positional transfers, shared descriptor offsets, held-unlinked files, non-sector-aligned block I/O, end-of-device partial transfers, fsync/fdatasync, tmpfs permissions/quotas, read-only remount and official BusyBox file/archive workflows. The original 27 checks and their expectations remain present.

Tmpfs mmap now maps the inode's physical pages. Shared mappings and read/write observe the same bytes; private mappings use COW. Fork and partial munmap retain and release references. Truncate revokes shared and private PTEs before freeing pages, clears the final page tail, and repeated growth uses current inode size. Out-of-file and quota-exhausted page faults deliver SIGBUS/BUS_ADRERR. The 18-case portable mapping test passes on host Linux and in the guest, with nine additional guest checks for quota and mount ownership. msync implements tmpfs and private-map behavior, including zero flags/length and locked INVALIDATE rejection, without pretending that a separate cached copy was written back.

Reference: fixed Linux v6.12 mm/shmem.c (shmem_fault, shmem_setattr), mm/msync.c, fs/read_write.c, and block/fops.c under build/linux-6.12. Host tests exercise the real tmpfs/I/O/page/signal implementations with ASan/UBSan; interrupted partial I/O drains pending DMA before signal delivery. Existing storage mkdir/rename/metadata harnesses now link the new backend.

Remaining Limits