Skip to content

Commit a426253

Browse files
committed
gunion-reroot plan: §4.4 — keep miniroot as Approach C, explain
mfsBSD use cases vs. ours Per follow-up: instead of just rejecting the miniroot pattern, document it as a real architectural option (Approach C) and explain which mfsBSD-shape use cases it earns its complexity for. §4.4 now contains: - The actual loader.conf + init.sh shape for dual-memdisk miniroot. - A scenario table mapping mfsBSD's reasons-to-use-miniroot against whether each applies to our livecd: PXE / netboot → no, we boot from optical/USB Eject-media-mid-install → no, we don't have an installer yet Multiple payload images → no, single rootfs.uzip today Diskless workstations → no, single-machine livecd Offline rescue → partial; cd9660 already serves this Smaller loader I/O → marginal; Approach A's 5-15s is fine - Verdict: keep miniroot documented as the right choice for mfsBSD-shape use cases. If freebsd-launchd ever grows into one of them (most plausibly: installer that ejects the USB stick after install completes), this is the architecture to revisit. For the current livecd, Approach A (cd9660 as rescue + loader-preloaded rootfs) wins. Captures the design exploration in the plan instead of relegating it to a "rejected" footnote — keeps the option visible for future sessions where someone asks "why don't we just use a miniroot?"
1 parent c9322cd commit a426253

1 file changed

Lines changed: 45 additions & 4 deletions

File tree

‎freebsd-livecd-gunion-reroot-plan.html‎

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -265,13 +265,54 @@ <h3>4.3 Recommendation</h3>
265265

266266
<p>Try Approach A first — it's the canonical pattern, less code, and if the loader supports the file size we get a clean boot. Fall back to B if loader-preload fails on real hardware.</p>
267267

268-
<h3>4.4 Rejected: separate rescue.img + dual-memdisk</h3>
268+
<h3>4.4 Approach C: separate rescue.img + dual-memdisk (mfsBSD pattern)</h3>
269269

270-
<p>Considered briefly: build a tiny <code>rescue.img</code> (~30MB, separate UFS image with just init + tools) that the loader preloads alongside <code>rootfs.uzip</code>. Kernel boots from rescue.img; rescue's init.sh sets up gunion over the second memdisk; reroots to gunion-backed UFS. Eventually rescue.img unmounts.</p>
270+
<p>The mfsBSD-canonical alternative: build a tiny <code>rescue.img</code> (~30MB UFS with just init + tools) and have the loader preload it alongside <code>rootfs.uzip</code>. Kernel boots from rescue.img (RAM-backed memdisk); rescue's init.sh sets up gunion over the second RAM-backed memdisk; reroots to gunion-backed UFS. cd9660 may not even be mounted at runtime.</p>
271271

272-
<p>Rejected because: <strong>cd9660 already serves the same role.</strong> The cd9660 has <code>/rescue/sh</code>, <code>/sbin/mdconfig</code>, <code>/sbin/gunion</code>, <code>/sbin/reboot</code>, <code>/sbin/kenv</code> — every tool /init.sh needs. Building a separate rescue.img adds an entire build pipeline (extra UFS image, extra Makefile target, extra place to track tool versions) for zero functional gain. The mfsBSD model has a separate rescue image because mfsBSD targets installation media where you might want to eject the boot media or boot over network — neither applies to a livecd where the cd9660 is the rootfs origin and stays accessible until reroot.</p>
272+
<pre class="shell"><code># cdroot/boot/loader.conf:
273+
mfs_load="YES"
274+
mfs_name="/rescue.img"
275+
mfs_type="mfs_root"
273276

274-
<p>The cd9660 IS the rescue environment. Don't reinvent it.</p>
277+
# Second memdisk (rootfs payload) loaded as a separate kernel preload:
278+
rootfs_load="YES"
279+
rootfs_name="/rootfs.uzip"
280+
rootfs_type="md_image"</code></pre>
281+
282+
<pre class="shell"><code># /init.sh inside rescue.img:
283+
gunion create /dev/md1.uzip # md1 is the rootfs payload
284+
kenv vfs.root.mountfrom="ufs:/dev/gunion0"
285+
exec /sbin/reboot -r</code></pre>
286+
287+
<h4>What this pattern fixes (for mfsBSD's use cases)</h4>
288+
289+
<table class="compact">
290+
<thead><tr><th>Scenario</th><th>Why miniroot helps</th><th>Applies to our livecd?</th></tr></thead>
291+
<tbody>
292+
<tr><td>PXE / netboot</td><td>kernel + rescue.img are small files PXE-servable in seconds. The big payload can come later over NFS / HTTP / wherever, decoupled from the boot path.</td><td>No — we boot from cd9660 / USB optical media.</td></tr>
293+
<tr><td>Eject-boot-media-mid-install</td><td>Once the rescue is in RAM, the user can yank the USB stick / eject the disc; install continues from a target disk. Useful for "USB stick → install to internal NVMe, eject USB."</td><td>No — our livecd assumes media stays attached. We don't currently have an installer.</td></tr>
294+
<tr><td>Multiple payload images</td><td>Rescue can pick at boot time which rootfs to load (minimal / full / desktop / server). One disc, several flavors.</td><td>No — we ship a single rootfs.uzip. Could become useful if we ever ship "freebsd-launchd minimal" + "freebsd-launchd full Plasma" on the same image.</td></tr>
295+
<tr><td>Diskless workstations</td><td>Rescue is the fixed in-RAM boot env; payload comes from a network server. Common in fleet deployments.</td><td>No — single-machine livecd, no fleet scenario.</td></tr>
296+
<tr><td>Offline rescue when rootfs is broken</td><td>If the big rootfs fails to load (corrupt download, hardware failure mid-install), the rescue is guaranteed-working in RAM and the user gets a shell.</td><td>Partial — our cd9660 already serves this role. If <code>/rootfs.uzip</code> is corrupt, the cd9660 is still mounted with all its tools and the user is in a working shell.</td></tr>
297+
<tr><td>Smaller loader I/O footprint</td><td>Loader handles only ~30MB rescue, not 400MB+ rootfs. Faster initial boot on slow media.</td><td>Marginal — Approach A's loader-preload of the full rootfs costs 5-15s extra. Acceptable tradeoff for build simplicity.</td></tr>
298+
</tbody>
299+
</table>
300+
301+
<h4>Why we're not adopting this</h4>
302+
303+
<p>None of the scenarios where miniroot earns its complexity apply to our livecd today:</p>
304+
305+
<ul>
306+
<li>We don't PXE-boot.</li>
307+
<li>We don't eject media mid-boot.</li>
308+
<li>We ship a single rootfs payload.</li>
309+
<li>We're not diskless.</li>
310+
<li>The cd9660 already provides offline-rescue behavior — its <code>/rescue/sh</code> + tools are reachable any time the cd9660 is mounted, which is "until reroot." Anything that fails before reroot lands the user in cd9660's rescue shell.</li>
311+
</ul>
312+
313+
<p>Cost of adopting it anyway: an entire second build pipeline (rescue.img generation, separate Makefile target, separate set of binaries to keep version-aligned with the rootfs), debug surface (two stages of init), and the mfsBSD-canonical pattern's quirks (loader configuration of multiple memdisks, kernel preload type for the secondary md, etc.). All for "the same outcome we already get from cd9660."</p>
314+
315+
<p><strong>Verdict: keep this pattern documented as the right choice for mfsBSD-shape use cases (PXE, ejectable media, multi-payload, diskless rescue).</strong> If freebsd-launchd ever grows into one of those use cases — most plausibly an installer that wants to eject the USB stick after install completes — this is the right architecture to revisit. For the current livecd, Approach A (cd9660 as rescue + loader-preloaded rootfs) is correct and simpler.</p>
275316

276317
<h2 id="why-gunion">5. Why gunion specifically (vs. unionfs, vs. tmpfs root)</h2>
277318

0 commit comments

Comments
 (0)