1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//! Lightweight state types and constants shared across the freeze
//! coordinator's call sites.
//!
//! Pure types and constants only — no behaviour. Behaviour lives in
//! the modules that consume these (the run-loop closure in
//! [`super`], the snapshot request handlers in [`super::snapshot`]).
//! Splitting the types out here lets the closure body shrink and
//! lets each consumer use the same vocabulary without re-deriving it
//! locally.
//!
//! Three groups live here:
//!
//! * [`FREEZE_RENDEZVOUS_TIMEOUT`] — wall-clock budget for parked-
//! vCPU rendezvous and the matching post-thaw barrier.
//! * [`BspExitReason`] — diagnostic enum logged when the BSP run
//! loop breaks.
//! * [`SnapshotRequest`] — typed view of a guest-side
//! `MSG_TYPE_SNAPSHOT_REQUEST` TLV.
//! * [`FreezeState`] — the dump state machine the run-loop closure
//! advances on each freeze cycle.
//!
//! All four were previously defined inline at the top of
//! `freeze_coord.rs` (or, for `FreezeState`, inside the run-loop
//! closure body); the public surface is unchanged.
use Duration;
/// Maximum wall-clock duration the freeze coordinator will wait for
/// every vCPU to acknowledge parked state before logging a timeout
/// and giving up on the dump. Well above the worst-case drain-dance
/// and single-iteration park latency on healthy guests; a real
/// timeout indicates a vCPU stuck in KVM_RUN that the
/// `immediate_exit` kick failed to interrupt.
pub const FREEZE_RENDEZVOUS_TIMEOUT: Duration = from_secs;
/// Why [`super::KtstrVm::run_bsp_loop`] exited. Logged at break time
/// so an operator reading stderr (`BSP: loop exit reason=...`) can
/// diagnose a `code=-1` exit without correlating to peer-vCPU
/// stderr or `tracing` output.
///
/// Mapping to the BSP loop's exit_code:
/// - [`Shutdown`](Self::Shutdown) → exit_code = 0 (the only path
/// that overwrites the local `-1` sentinel).
/// - Every other variant → exit_code = -1, but
/// [`super::super::KtstrVm::collect_results`] re-derives the
/// final [`super::super::result::VmResult::exit_code`] from the
/// bulk-port `MSG_TYPE_EXIT` payload (or COM2 `KTSTR_EXIT:`
/// sentinel) when either is present, so a `-1` from the BSP
/// run-loop is not authoritative for caller-visible test
/// outcome.
pub
/// Decoded contents of a guest-side `MSG_TYPE_SNAPSHOT_REQUEST` TLV
/// frame consumed from the virtio-console port-1 TX stream by the
/// coordinator's TOKEN_TX handler. The request id is echoed in the
/// matching `MSG_TYPE_SNAPSHOT_REPLY` payload so the guest's blocking
/// reader can pair the reply against its outstanding request; `kind`
/// selects the CAPTURE / WATCH dispatch path and `tag` carries the
/// snapshot name (CAPTURE) or symbol path (WATCH).
pub
/// Dual-snapshot state machine the freeze coordinator's run-loop
/// advances on each capture cycle. Only the `TookEarly` variant is
/// reachable when `freeze_coord_dual_snapshot` is true; the single-
/// snapshot path drives the same transitions but skips the early
/// branch entirely.
///
/// * [`Idle`](Self::Idle) — no dump captured yet.
/// * [`TookEarly`](Self::TookEarly) — early snapshot captured
/// (dual-snapshot mode only); waiting for the err_exit latch to
/// fire.
/// * [`Done`](Self::Done) — late snapshot captured and emission
/// complete; coord just idles until kill / bsp_done.
pub