You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Everything I still have open after the restore-latency work landed (#802, #803, #804 merged; #805 open). Each item below was re-verified against main at 0594e96 today rather than carried forward from notes, and items already covered by an existing issue are cross-referenced instead of restated.
Restore path: the remaining 136ms
The guest restore ACK is now 136ms p50 / 195 p95 (from ~643ms), attributed per phase by the telemetry that rides every ACK. What is left, measured on Graviton3 at concurrency 1 across 141 restores:
phase
p50
p95
boundary reopen
66.1
96.1
gateway ARP
27.6
41.0
boundary verify
16.4
34.3
clock step
3.6
12.3
boundary destroy
0.9
1.4
Reopen (66ms) is the last spawn cluster. It is one iptables-restore per family plus one ip -batch per family. The link up/down already moved to SIOCSIFFLAGS; the same treatment for route reinstatement (rtnetlink RTM_NEWROUTE) and for the gate teardown would remove the last four spawns on the path. Each spawn on a freshly restored clone costs roughly 15-20ms because its text and libraries fault back in through the memory backend, so this is where the remaining budget is.
Gateway ARP (28ms) has no spawn left — it is already a native AF_PACKET frame with no reply wait. The cost is first-touch page faults in that code path, which suggests prefetching the boundary's working set into the clone rather than micro-optimising the send.
Verify (16ms) is two iptables -S reads and is the safety argument itself, so it should only go away if the gate state can be proven some cheaper way (reading nftables directly, or carrying a gate fingerprint in the manifest and validating that).
Interface naming: eth0 is still assumed outside the snapshot boundary
a6b6af4f (#797) taught the snapshot boundary to discover the guest's external interface, because Cloud Hypervisor's PCI virtio-net is renamed to enp0s4 by udev while Firecracker's MMIO device keeps eth0. The rest of the codebase still hardcodes the name. Verified counts of "eth0" as a literal in code (not comments, not test fixtures) on main:
fc-agent/src/network.rs — 8 sites: IPv6 add/del/show, the IPv6 default route, and the loopback DNAT publication
rootfs-config.toml — the 10-eth0.network systemd unit and its mmds.conf drop-in match on Name=eth0
Reuse the boundary's external_interface() discovery (sysfs device symlink) for these paths, or thread the discovered name through once at boot. The systemd unit is the interesting one: it runs before anything of ours and matching on Name=eth0 is what makes the kernel ip= address survive the rename.
Snapshot cache: three opt-outs remain
AGENTS.md says cache everything and take no opt-out unless behaviourally required. snapshot_cache_opt_out (src/commands/podman/mod.rs:313) still has three:
FCVM_BOOTPLAN=vsock — root-caused, small fix.snapshot_key() hashes the serialized FirecrackerConfig, which has no field for the boot-plan transport, so a vsock-built snapshot and an MMDS-built one collide on one key; the opt-out exists only to stop the former being restored under the latter. Adding a serialized transport field gives vsock-built entries their own namespace and lets the opt-out be deleted. Guard: that struct has #[serde(skip)] fields, so confirm the new field is not skipped, or the key will not change.
rootfs_override — a disk-only clone cold-boots from a captured disk, so this looks behaviourally required. Re-verify against the principle rather than assuming.
Kernel: attribute the 7.x nested wedge
#751 repinned to 6.18.44 away from a wedging config; attribution between upstream 7.x and our FUSE remap patch is still undetermined. The previously banked CONTROL_VERDICT=RED is invalid and should not be reused: the 7.1.8-noremap inner run died at Reflink copy failed ... requires a kernel profile with this patch, a prerequisite failure that never reaches the virtio-blk read path under test. A positive control is banked (6.18.44 + all patches, inner run succeeded).
bench/restore-matrix.py (#805) covers backend × network × concurrency 1/4/16 × volumes × kill-mid-restore, and is clean at 33/33 cells. It is a closed-loop harness.
Drive the open-loop scale harness (reqscale, from Salvage the unlanded work from the archived WIP branches #795) at arrival rates the closed-loop bench cannot produce, deconfounding FILE vs UFFD within a rate interval, plus sustained and fan-out phases. The goal is to surface defects, not to publish numbers: every failure gets root-caused rather than retried.
A matrix cell that exercises the boundary repair path in vivo. Today only the unit tests cover verified_armed == false; the natural in-vivo shape is a --privileged workload mutating the gate from inside the guest while a clone restores, which is also the scenario that motivated asserting the link-down unconditionally.
CI hygiene
Deduplicate the btrfs bootstrap..github/workflows/kernels.yml sets up /mnt/fcvm-btrfs inline in two places; make setup-btrfs does the same thing and is what a developer runs. One of them should call the other so they cannot drift.
Already tracked elsewhere (listed so this issue is not read as the whole picture)
Everything I still have open after the restore-latency work landed (#802, #803, #804 merged; #805 open). Each item below was re-verified against
mainat 0594e96 today rather than carried forward from notes, and items already covered by an existing issue are cross-referenced instead of restated.Restore path: the remaining 136ms
The guest restore ACK is now 136ms p50 / 195 p95 (from ~643ms), attributed per phase by the telemetry that rides every ACK. What is left, measured on Graviton3 at concurrency 1 across 141 restores:
iptables-restoreper family plus oneip -batchper family. The link up/down already moved toSIOCSIFFLAGS; the same treatment for route reinstatement (rtnetlinkRTM_NEWROUTE) and for the gate teardown would remove the last four spawns on the path. Each spawn on a freshly restored clone costs roughly 15-20ms because its text and libraries fault back in through the memory backend, so this is where the remaining budget is.iptables -Sreads and is the safety argument itself, so it should only go away if the gate state can be proven some cheaper way (reading nftables directly, or carrying a gate fingerprint in the manifest and validating that).Interface naming:
eth0is still assumed outside the snapshot boundarya6b6af4f(#797) taught the snapshot boundary to discover the guest's external interface, because Cloud Hypervisor's PCI virtio-net is renamed toenp0s4by udev while Firecracker's MMIO device keepseth0. The rest of the codebase still hardcodes the name. Verified counts of"eth0"as a literal in code (not comments, not test fixtures) on main:fc-agent/src/network.rs— 8 sites: IPv6 add/del/show, the IPv6 default route, and the loopback DNAT publicationsrc/network/{veth,routed,bridged}.rs,src/commands/podman/vm_config.rs,src/storage/snapshot.rsrootfs-config.toml— the10-eth0.networksystemd unit and itsmmds.confdrop-in match onName=eth0Reuse the boundary's
external_interface()discovery (sysfsdevicesymlink) for these paths, or thread the discovered name through once at boot. The systemd unit is the interesting one: it runs before anything of ours and matching onName=eth0is what makes the kernelip=address survive the rename.Snapshot cache: three opt-outs remain
AGENTS.md says cache everything and take no opt-out unless behaviourally required.
snapshot_cache_opt_out(src/commands/podman/mod.rs:313) still has three:FCVM_BOOTPLAN=vsock— root-caused, small fix.snapshot_key()hashes the serializedFirecrackerConfig, which has no field for the boot-plan transport, so a vsock-built snapshot and an MMDS-built one collide on one key; the opt-out exists only to stop the former being restored under the latter. Adding a serialized transport field gives vsock-built entries their own namespace and lets the opt-out be deleted. Guard: that struct has#[serde(skip)]fields, so confirm the new field is not skipped, or the key will not change.podman runpre-start snapshot cache is simply not wired up for CH (explicitsnapshot create/runalready work). Wiring it is the real fix and is larger than the above. Related: [epic] Hypervisor-agnostic abstraction: support Firecracker AND Cloud Hypervisor (the two microVMs) behind a pluggable trait #632.rootfs_override— a disk-only clone cold-boots from a captured disk, so this looks behaviourally required. Re-verify against the principle rather than assuming.Kernel: attribute the 7.x nested wedge
#751 repinned to 6.18.44 away from a wedging config; attribution between upstream 7.x and our FUSE remap patch is still undetermined. The previously banked
CONTROL_VERDICT=REDis invalid and should not be reused: the 7.1.8-noremap inner run died atReflink copy failed ... requires a kernel profile with this patch, a prerequisite failure that never reaches the virtio-blk read path under test. A positive control is banked (6.18.44 + all patches, inner run succeeded)./mnt/fcvm-btrfsso the host btrfs performs the reflink, then boot L2 inside an L1 on 7.1.8-with-patches versus 7.1.8-minus-remap and hammer virtio-blk reads (reads never callremap_file_range). Wedge on both ⇒ upstream 7.x; wedge only with our patch ⇒ ours. Related: Host kernel upgrade 6.18.3 → 7.1 (fallback 6.19.y): pick up upstream NV fixes, then re-evaluate multi-vCPU L2 #659, Kernel patch audit vs 7.0.14: NV2 crash has an upstream fix we lack; 4 patches can be dropped #770.Stress beyond the gate
bench/restore-matrix.py(#805) covers backend × network × concurrency 1/4/16 × volumes × kill-mid-restore, and is clean at 33/33 cells. It is a closed-loop harness.verified_armed == false; the natural in-vivo shape is a--privilegedworkload mutating the gate from inside the guest while a clone restores, which is also the scenario that motivated asserting the link-down unconditionally.CI hygiene
.github/workflows/kernels.ymlsets up/mnt/fcvm-btrfsinline in two places;make setup-btrfsdoes the same thing and is what a developer runs. One of them should call the other so they cannot drift.Already tracked elsewhere (listed so this issue is not read as the whole picture)
PastaNetwork::cleanupreturningOkafter a failed kill or PID-file removal — PastaNetwork::cleanup returns Ok after a failed kill or PID-file removal #800#[ignore]d NV2-flaky nested L3/L4 tests intests/test_kvm.rs— Re-measure and re-enable the expensive nested tests (L3/L4, podman-load-over-fuse) post-#630 #660 (and Nested-test CI gaps after #630: x86 L2-over-restored-L1, vsock-integrity runner capacity, remaining re-enables #664 for the surrounding CI gaps)