Finish the direct-import convention: a protocol is now aliased to its module name in snake_case in every file that imports one — consumers and the runtime client wrappers alike. This kills the last of the alias variety (the generic `protocol`, plus `power` and `transfer`), so `device_manager_protocol.Hello` means the same thing everywhere and grepping a module name finds all its uses. Pure rename (identifier uses only; prose references left untouched via a guarded pattern). 14 files, 299/299 lines. zig build + test green; 16 QEMU cases pass (smoke, device-manager, driver-restart, device-list, pci-scan, usb-hid, usb-storage, display-service, display-native, display-reattach, input, acpi-ps2, vfs, fat-mount, power-button, orderly-shutdown).
40 lines
2.0 KiB
Zig
40 lines
2.0 KiB
Zig
//! crash-test — a test fixture, not a driver: claims the device it is assigned,
|
|
//! hellos the device manager, announces itself, then faults on purpose. The
|
|
//! driver-restart scenario drives the manager's whole restart machinery with
|
|
//! it: fault → exit reason → backoff → respawn → the **same claim succeeding
|
|
//! again** (claim release on death, M17.1, through the manager's path) → the
|
|
//! crash-loop cap. Spawned bare (the initial-ramdisk sweep starts every bundled
|
|
//! binary), it exits silently so it cannot derange other tests.
|
|
|
|
const std = @import("std");
|
|
const runtime = @import("runtime");
|
|
const device_manager_protocol = @import("device-manager-protocol");
|
|
|
|
pub fn main(init: runtime.process.Init) void {
|
|
const argument = init.arguments.get(1) orelse return; // bare: stay silent
|
|
const assigned = std.fmt.parseInt(u64, argument, 10) catch return;
|
|
|
|
// The respawn only reaches this line because the kernel released the
|
|
// previous instance's claim at death. A failed claim exits cleanly — the
|
|
// manager reads "meant to stop" and the scenario fails loudly by silence.
|
|
if (!runtime.device.claim(assigned)) {
|
|
_ = runtime.system.write("crash-test: claim failed\n");
|
|
return;
|
|
}
|
|
|
|
var manager: ?runtime.ipc.Handle = null;
|
|
var tries: u32 = 0;
|
|
while (manager == null and tries < 100) : (tries += 1) {
|
|
manager = runtime.ipc.lookup(.device_manager);
|
|
if (manager == null) runtime.system.sleep(20);
|
|
}
|
|
const h = manager orelse return;
|
|
const hello = device_manager_protocol.Hello{ .role = @intFromEnum(device_manager_protocol.Role.device), .device_id = assigned };
|
|
var reply: [device_manager_protocol.message_maximum]u8 = undefined;
|
|
_ = runtime.ipc.call(h, std.mem.asBytes(&hello), &reply) catch return;
|
|
|
|
_ = runtime.system.write("crash-test: faulting now\n");
|
|
const poison: *volatile u32 = @ptrFromInt(0xdead0000);
|
|
poison.* = 1; // the restart machinery's fuel: a real segmentation fault
|
|
}
|