Boot Fruix from native FreeBSD world and kernel

This commit is contained in:
2026-04-03 02:21:23 +02:00
parent 4def04a357
commit 94e498f57d
8 changed files with 541 additions and 13 deletions

View File

@@ -3058,3 +3058,103 @@ Next recommended step:
1. wire the image/boot path to use the native kernel/world outputs end-to-end
2. validate locally with QEMU/UEFI
3. validate on the approved XCP-ng VM and VDI path
## 2026-04-03 — Phase 13.3: booted Fruix from native FreeBSD kernel/world outputs
Completed work:
- wrote the Phase 13.3 report:
- `docs/reports/phase13-native-base-boot-freebsd.md`
- completed the first end-to-end boot path using native `/usr/src`-built FreeBSD base artifacts in `/frx/store`
- fixed the first native-image sizing problem:
- the old fixed `root-size=256m` was too small once the image carried a native world
- added explicit root filesystem sizing support to the CLI/image path:
- `scripts/fruix.scm` now accepts `--root-size SIZE`
- image metadata now records `root_size`
- `tests/system/run-phase8-system-image.sh` now accepts:
- `ROOT_SIZE`
and records:
- `root_size`
- `native_base_store_count`
- `native_base_stores`
- fixed a follow-up image metadata bug:
- `materialize-bhyve-image` now returns:
- `native-base-stores`
- this removed the `length #f` failure in the native image path
- generalized the local PID1 QEMU harness a bit further:
- `tests/system/run-phase11-shepherd-pid1-qemu.sh` now accepts `OS_TEMPLATE`
- added dedicated Phase 13.3 native-base boot wrappers:
- `tests/system/run-phase13-native-base-qemu.sh`
- `tests/system/run-phase13-native-base-xcpng.sh`
- these wrappers reuse the validated PID1 boot path but additionally require the image metadata to prove the booted system is really using the intended Phase-13 base split:
- native kernel present
- native world present
- host base reduced to bootloader only
Working native-base boot configuration:
- local QEMU:
- `ROOT_SIZE=6g`
- `DISK_CAPACITY=8g`
- real XCP-ng:
- `ROOT_SIZE=6g`
- disk capacity kept matched to the fixed 30 GiB VDI as before
Validation:
- local QEMU/UEFI/TCG boot passes through the new wrapper:
- `tests/system/run-phase13-native-base-qemu.sh`
- workdir: `/tmp/phase13-3-qemu3-1775174863`
- result: `PASS phase13-native-base-qemu`
- confirmed:
- `disk_capacity=8g`
- `root_size=6g`
- `native_base_store_count=2`
- `host_base_store_count=1`
- `shepherd_pid=1`
- `sshd_status=running`
- `native_base_boot=ok`
- real XCP-ng boot passes through the new wrapper:
- `tests/system/run-phase13-native-base-xcpng.sh`
- workdir: `/tmp/phase13-3-xcpng-1775175086`
- result: `PASS phase13-native-base-xcpng`
- confirmed:
- `vm_id=90490f2e-e8fc-4b7a-388e-5c26f0157289`
- `vdi_id=0f1f90d3-48ca-4fa2-91d8-fc6339b95743`
- `guest_ip=192.168.213.62`
- `root_size=6g`
- `native_base_store_count=2`
- `host_base_store_count=1`
- `shepherd_pid=1`
- `sshd_status=running`
- `compat_prefix_shims=absent`
- `guile_module_smoke=ok`
- `native_base_boot=ok`
- validated native-base closure/image composition now boots with:
- native kernel store:
- `/frx/store/93f35ddcb9a03f63f83c9e8ae29788685d339789da664f881822b4a1914f5ff6-freebsd-native-kernel-15.0-STABLE`
- native world store:
- `/frx/store/3f6f7f8c06ed8dad4cae21a1e8ac8ba4823bdb7cf54328c9bbcccaeb858beb77-freebsd-native-world-15.0-STABLE`
- remaining host base store:
- `/frx/store/8ffcfe0356fea815726b610514a1280a11266851c2acb870047d559795569f0e-freebsd-bootloader-15.0-STABLE`
Important findings:
- the native world is large enough that the older 256 MiB rootfs assumption is no longer realistic; explicit image sizing is now part of the practical Phase-13 path
- after the native-base transition, the remaining transitional boundary is now much narrower and explicit:
- host-staged bootloader/boot assets
- native kernel
- native core world runtime
- the real XCP-ng upload path still works with the larger native-world image, but the dynamic VHD is naturally much bigger now (~4.42 GiB)
Current assessment:
- Phase 13 is complete
- Fruix now builds FreeBSD kernel/world artifacts from `/usr/src` into `/frx/store` and successfully boots a declarative system from those native outputs
- this is the main architectural pivot Plan 3 called for before Phase 14
Next recommended step:
1. begin Phase 14 by replacing the remaining host-copy boot assets first
2. keep shrinking the host-staged base boundary around the now-working native world/kernel path
3. revisit cleaner runtime vs. development splits after the boot asset transition

View File

@@ -0,0 +1,191 @@
# Phase 13.3: booted Fruix using native store-built FreeBSD base artifacts
Date: 2026-04-03
## Goal
Phase 13.3 was the first end-to-end boot validation of the new native FreeBSD base path.
The target was a Fruix system/image that boots using:
- native `/usr/src`-built kernel output in `/frx/store`
- native `/usr/src`-built world output in `/frx/store`
- host-staged bootloader only, as the remaining explicit transitional boundary
Validation still followed the established strategy:
- local QEMU/UEFI/TCG
- real XCP-ng on the approved VM/VDI path
## Issues found and fixed
### 1. The old fixed 256 MiB root filesystem image was too small
The first native-base image attempt failed during `makefs` with:
```text
size of .../image-rootfs is larger than the maxsize of 268435456
```
That was expected once the image started carrying a native world instead of the earlier curated host-copy runtime slice.
To fix this cleanly, Fruix image generation gained an explicit root filesystem size parameter:
- `scripts/fruix.scm` now accepts:
- `--root-size SIZE`
- image metadata now emits:
- `root_size=...`
- `tests/system/run-phase8-system-image.sh` now accepts:
- `ROOT_SIZE`
and records the reported root size in metadata
For the native-base boot validation, the working values were:
- local QEMU:
- `ROOT_SIZE=6g`
- `DISK_CAPACITY=8g`
- real XCP-ng:
- `ROOT_SIZE=6g`
- disk capacity kept matched to the fixed 30 GiB VDI as before
### 2. `materialize-bhyve-image` needed to propagate native-base metadata
After adding the new `native_base_*` metadata path, the first native image run hit a Scheme error because `materialize-bhyve-image` still returned:
- `host-base-stores`
- `fruix-runtime-stores`
but not:
- `native-base-stores`
That was corrected so image-generation results now carry the native-base store set too.
## Harness updates
### Reused/extended existing Phase 11 boot harnesses
- `tests/system/run-phase11-shepherd-pid1-qemu.sh`
- now accepts `OS_TEMPLATE` like the XCP-ng PID1 harness already did
- `tests/system/run-phase8-system-image.sh`
- now records:
- `native_base_store_count`
- `native_base_stores`
- `root_size`
### Added native-base boot wrappers
New wrappers:
- `tests/system/run-phase13-native-base-qemu.sh`
- `tests/system/run-phase13-native-base-xcpng.sh`
These wrappers reuse the already-validated PID1 boot path but require the image metadata to confirm that the booted system really uses the intended Phase-13 base split:
- `native_base_store_count=2`
- native kernel present
- native world present
- `host_base_store_count=1`
- host base reduced to bootloader only
## Validation
### Local QEMU / UEFI / TCG
Passing run:
- `PASS phase13-native-base-qemu`
- workdir: `/tmp/phase13-3-qemu3-1775174863`
Key metadata:
```text
disk_capacity=8g
root_size=6g
native_base_store_count=2
host_base_store_count=1
shepherd_pid=1
sshd_status=running
native_base_boot=ok
```
The wrapped underlying Phase 11 PID1 harness also confirmed the full guest runtime path:
- ready marker present
- `/run/current-system` correct
- Shepherd socket present
- Shepherd PID is `1`
- `sshd` running
- activation completed successfully
- `/etc/login.conf` regular + databases present
### Real XCP-ng VM
Passing run:
- `PASS phase13-native-base-xcpng`
- workdir: `/tmp/phase13-3-xcpng-1775175086`
Key metadata:
```text
vm_id=90490f2e-e8fc-4b7a-388e-5c26f0157289
vdi_id=0f1f90d3-48ca-4fa2-91d8-fc6339b95743
guest_ip=192.168.213.62
root_size=6g
native_base_store_count=2
host_base_store_count=1
shepherd_pid=1
sshd_status=running
compat_prefix_shims=absent
guile_module_smoke=ok
native_base_boot=ok
```
The dynamic VHD upload remained workable even with the larger native-world image payload, though naturally much larger than the earlier minimal image path:
- upload size: `4740784128` bytes (~4.42 GiB)
## What booted
The validated native-base system closure used:
- native kernel store:
- `/frx/store/93f35ddcb9a03f63f83c9e8ae29788685d339789da664f881822b4a1914f5ff6-freebsd-native-kernel-15.0-STABLE`
- native world store:
- `/frx/store/3f6f7f8c06ed8dad4cae21a1e8ac8ba4823bdb7cf54328c9bbcccaeb858beb77-freebsd-native-world-15.0-STABLE`
- remaining host base store:
- `/frx/store/8ffcfe0356fea815726b610514a1280a11266851c2acb870047d559795569f0e-freebsd-bootloader-15.0-STABLE`
That means Phase 13 has now crossed its main success boundary:
- the kernel is native
- the core world runtime is native
- the system actually boots from those outputs
## Assessment
Phase 13 is complete.
Fruix has now moved from:
- building a FreeBSD system from curated host copies
into:
- building kernel/world artifacts from `/usr/src` into `/frx/store`, then booting a declarative Fruix system from those outputs.
The remaining major transitional boundary is now much narrower and explicit:
- host-staged bootloader/boot assets remain
- native kernel + native core world runtime are already in place
That is a real architectural shift, not just more documentation.
## Next recommended step
Proceed to Phase 14:
1. replace the remaining host-copy boot assets first
2. then keep reducing the older host-staged FreeBSD base slice around the now-working native world/kernel path
3. revisit cleaner runtime vs. development splits once the boot asset transition is done