//! /test/system/services/vfs-test — a ring-3 client that proves the kernel VFS //! end to end through the plain `file_system` API: resolve its OWN binary under //! the kernel-served /test mount, check its metadata, read its ELF magic, and //! list /system/services. On success it heartbeats "vfstest: ok" so the kernel //! test can observe it; on failure it reports what went wrong. //! //! The "park" role (the fat-client-death test): open a file on the FAT volume, //! then hold the handle forever without closing — the kill and the fat //! server's release-on-death sweep are the point. const std = @import("std"); const fs = @import("file-system"); const process = @import("process"); const time = @import("time"); const logging = @import("logging"); pub fn main(init: process.Init) void { if (init.arguments.count > 1) { park(); return; } // Our own binary, resolved through the kernel mount table. const self_path = "/test/system/services/vfs-test"; var file = fs.open(self_path, .{}) orelse { _ = logging.write("vfstest: open of own binary failed\n"); return; }; defer file.close(); const attributes = file.attributes() orelse { _ = logging.write("vfstest: attributes failed\n"); return; }; if (attributes.kind != .regular or attributes.size == 0) { _ = logging.write("vfstest: bad attributes\n"); return; } var header: [4]u8 = undefined; const n = file.read(&header) orelse 0; if (n != 4 or header[0] != 0x7f or header[1] != 'E' or header[2] != 'L' or header[3] != 'F') { _ = logging.write("vfstest: ELF magic mismatch\n"); return; } // The write refusal: the initrd trees are read-only by construction. if (file.write("x") != null or fs.open("/test/system/services/new-file", .{ .create = true }) != null) { _ = logging.write("vfstest: the initrd tree accepted a write\n"); return; } // Listing: /system/services contains init. var saw_init = false; if (fs.openDirectory("/system/services")) |listing| { var directory = listing; defer directory.close(); var entry: fs.Entry = .{}; while (directory.next(&entry)) { if (std.mem.eql(u8, entry.name(), "init")) saw_init = true; } } if (!saw_init) { _ = logging.write("vfstest: /system/services listing missed init\n"); return; } while (true) { _ = logging.write("vfstest: ok\n"); time.sleepMillis(1000); } } fn park() void { // The storage chain (usb -> block -> fat -> mounts) takes a few seconds; // retry until the volume appears. var parked: ?fs.File = null; var tries: u32 = 0; while (parked == null and tries < 1000) : (tries += 1) { parked = fs.open("/volumes/usb/parked", .{ .create = true }); if (parked == null) time.sleepMillis(20); } if (parked == null) { _ = logging.write("vfstest: park open failed\n"); return; } while (true) { _ = logging.write("vfstest: parked\n"); time.sleepMillis(500); } }