@@ -2129,12 +2129,18 @@ func (m *Manager) PrepareGoldenSnapshot() error {
21292129 // Step 3: Flush filesystem, quiesce network, close agent, pause VM, snapshot
21302130 _ = agent .SyncFS (context .Background ())
21312131
2132- // Quiesce eth0 before snapshotting to ensure clean virtio-net virtqueues.
2133- // Flush all addresses first so the host stops sending ARP/IPv6 ND traffic to
2134- // this TAP, eliminating the race where a packet arrives in the RX used ring
2135- // while NAPI is draining. Without this, snapshot restore triggers
2136- // "input.0:id 0 is not a head!" (vq->broken=true) which permanently breaks
2137- // virtio-net RX for every sandbox created from this golden snapshot.
2132+ // Quiesce networking before snapshotting to ensure clean virtio-net virtqueues.
2133+ //
2134+ // The host-side TAP must be brought down FIRST to stop all packet delivery
2135+ // into the guest's virtio-net RX ring. Only then is the guest side flushed
2136+ // and downed. Without this ordering, the host can push ARP/IPv6 ND packets
2137+ // into the RX used ring between the guest flush and the VM pause, corrupting
2138+ // the virtqueue state. On restore this manifests as:
2139+ // "virtio_net virtio2: input.0:id 0 is not a head!"
2140+ // (vq->broken=true) which permanently breaks virtio-net RX for every
2141+ // sandbox created from this golden snapshot.
2142+ _ = run ("ip" , "link" , "set" , netCfg .TAPName , "down" )
2143+
21382144 _ , _ = agent .Exec (context .Background (), & pb.ExecRequest {
21392145 Command : "/bin/sh" ,
21402146 Args : []string {"-c" , "ip addr flush dev eth0 && ip link set eth0 down" },
0 commit comments