build: the unix paths retire — configuration, logs, and volumes move into the danos tree

/etc/init.csv and /etc/devices.csv become /system/configuration/*.csv (the
repo's etc/ moves to system/configuration/, mirroring the runtime tree),
/var/log becomes /system/logs, and /mnt/usb becomes /volumes/usb. The
kernel VFS gains a carve-out so FAT may serve exactly /system/configuration
and /system/logs beneath the initrd-backed /system while /system and /test
themselves stay unshadowable; FAT's single /var mount splits into those two
rewritten mounts. The kvfs readdir check learns /system's third child and
the ramdisk spawn sweep skips the configuration tree.

Suite 106/106.
This commit is contained in:
Daniel Samson
2026-07-31 19:41:35 +01:00
parent e4da4e0610
commit c4f16a5448
31 changed files with 161 additions and 128 deletions
+15 -11
View File
@@ -1970,7 +1970,7 @@ fn initTest(boot_information: *const BootInformation) void {
check("init loaded and spawned as a process", spawned);
// Wait (real time) until the LAST write is a heartbeat — proving init got
// through its boot chatter (heap ok, the /etc/init.csv lookup) and settled
// through its boot chatter (heap ok, the /system/configuration/init.csv lookup) and settled
// into its beat-and-sleep loop (~1 s between beats). Waiting on the text
// rather than a raw write count: the boot chatter alone satisfies a count,
// which is exactly the too-early check that used to fail here.
@@ -2220,7 +2220,7 @@ fn vfsClientDeathTest(boot_information: *const BootInformation) void {
};
process.write_count = 0;
// The full tree: the storage chain must come up for /mnt/usb to exist —
// The full tree: the storage chain must come up for /volumes/usb to exist —
// the fat server (not a router) now owns client file state and its sweep.
process.setInitialRamdisk(image);
const init_ok = if (process.spawnBundled("/system/services/init")) true else |_| false;
@@ -2606,7 +2606,7 @@ fn usbStorageTest(boot_information: *const BootInformation) void {
/// The FAT mount chain: boot the full tree (init spawns the fat server, which
/// brings up the USB storage chain, mounts the FAT volume, and mounts itself into
/// the VFS at /mnt/usb), then spawn a fat-test client that lists and reads through
/// the VFS at /volumes/usb), then spawn a fat-test client that lists and reads through
/// the mount. The harness attaches a usb-storage device; the expect regex requires
/// the fat mount and the client's success.
fn fatMountTest(boot_information: *const BootInformation) void {
@@ -2801,11 +2801,13 @@ fn initialRamdiskTest(boot_information: *const BootInformation) void {
var i: u32 = 0;
while (i < rd.count) : (i += 1) {
const item = rd.entry(i) orelse continue;
// The FHS boot tree ferries data files too (/etc/devices.csv,
// /etc/init.csv — served read-only by the kernel VFS, never spawned);
// only the /system and /test trees hold programs, so only those count
// toward the spawn-everything sweep.
const is_program = std.mem.startsWith(u8, item.name, "/system/") or
// The boot tree ferries data files too (/system/configuration/devices.csv,
// /system/configuration/init.csv — served read-only by the kernel VFS,
// never spawned); only the /system and /test trees hold programs, and
// /system/configuration holds none, so only the rest counts toward the
// spawn-everything sweep.
const is_program = (std.mem.startsWith(u8, item.name, "/system/") and
!std.mem.startsWith(u8, item.name, "/system/configuration/")) or
std.mem.startsWith(u8, item.name, "/test/");
if (!is_program) continue;
programs += 1;
@@ -3267,21 +3269,23 @@ fn kernelVfsTest(boot_information: *const BootInformation) void {
check("its first bytes are an ELF magic", n == 4 and header[0] == 0x7f and header[1] == 'E' and header[2] == 'L' and header[3] == 'F');
}
// Directories resolve and enumerate: /system lists services/drivers.
// Directories resolve and enumerate: /system lists services/drivers/
// configuration (the CSV data files ride the same initrd tree).
const root_directory = kernel_vfs.resolvePath("/system", false);
check("/system resolves to a directory node", root_directory == .kernel_node);
var saw_services = false;
var saw_drivers = false;
var saw_configuration = false;
var saw_stray_in_root = false;
var saw_files_in_services = false;
if (root_directory == .kernel_node) {
var cursor: u64 = 0;
var name: [64]u8 = undefined;
while (kernel_vfs.nodeReaddir(root_directory.kernel_node, cursor, &name)) |entry| : (cursor += 1) {
if (eql(name[0..entry.name_len], "services")) saw_services = true else if (eql(name[0..entry.name_len], "drivers")) saw_drivers = true else saw_stray_in_root = true;
if (eql(name[0..entry.name_len], "services")) saw_services = true else if (eql(name[0..entry.name_len], "drivers")) saw_drivers = true else if (eql(name[0..entry.name_len], "configuration")) saw_configuration = true else saw_stray_in_root = true;
}
}
check("readdir /system yields services and drivers", saw_services and saw_drivers);
check("readdir /system yields services, drivers, configuration", saw_services and saw_drivers and saw_configuration);
check("readdir /system yields nothing else (no /test leakage)", !saw_stray_in_root);
const services = kernel_vfs.resolvePath("/system/services", false);
if (services == .kernel_node) {