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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//! axum-based management HTTP server (`http-axum` feature).
//!
//! Runs an axum `Router` on a tokio current-thread runtime and serves the
//! management API. Routes and JSON fields mirror the hand-rolled pilot's API,
//! but dispatch and JSON construction are delegated to axum + serde_json.
//!
//! ```text
//! GET /api/vms → 200, JSON array (summary form)
//! GET /api/vms/{id} → 200, JSON detail (with vcpu_states) | 404
//! POST /api/vms/create → 200 {"id":N} | 400 | 409 | 500 (body {"toml": "..."})
//! DELETE /api/vms/{id} → 204 | 404 | 500
//! POST /api/vms/{id}/start → 200 {"ok":true,"status":...} | 404 | 409 | 503
//! POST /api/vms/{id}/stop → 200 {"ok":true,"status":...} | 404 | 409 | 503
//! POST /api/vms/{id}/pause → 200 {"ok":true,"status":...} | 404 | 409 | 503
//! POST /api/vms/{id}/resume → 200 {"ok":true,"status":...} | 404 | 409 | 503
//! ```
//!
//! Mutating routes (`create`/`delete`/`start`/`stop`/`pause`/`resume`) require
//! `Authorization: Bearer <token>` with the build-time `[env] AXVM_HTTP_TOKEN`;
//! see [`crate::http::auth`]. GET routes are open. The listener binds
//! [`bind_addr`], loopback by default.
//!
//! The tokio reactor is initialized with `enable_io()` only (no time driver),
//! which needs only epoll, so no `timerfd` syscall is required.
//!
//! # Lifecycle semantics and known limits
//!
//! The pause/resume routes are backed by the axvm lifecycle state machine,
//! which accepts only `Running → Paused` (pause) and `Paused → Running`
//! (resume). Callers must not assume stronger guarantees than the runtime
//! provides:
//!
//! - `pause` is fire-and-forget: the status flips to `Paused` synchronously,
//! but running vCPUs park only at their next run-loop iteration. There is no
//! synchronous pause-quiesce wait and **no completion-confirmation API** — a
//! `Paused` status only means the pause request was accepted, not that the
//! execution surface has gone quiet (see `virtualization/axvm/docs/
//! lifecycle.md`). To *observe* a vCPU actually parking (not a full
//! quiescence guarantee), poll the VM detail: `guest_park_count` advances
//! only when a vCPU has genuinely parked in the suspend wait, and
//! `guest_entry_count` advances only after the guest has actually re-entered
//! (on first start and on every wake from suspend). Both are **VM-level
//! monotonic aggregate** counters shared by every vCPU task of the VM — they
//! prove that *at least one* vCPU made progress, not that every vCPU, device,
//! or timer has quiesced (see the device/timer limits below).
//! - Pause does not save or mask guest timer state. Host time keeps flowing
//! while the guest is suspended, so on resume the guest observes a time
//! jump; long pauses drift time-sensitive guests.
//! - Device suspension covers only devices registered with lifecycle
//! semantics; other devices are not quiesced while paused.
use ;
use Context;
use Router;
use cratevm;
use ;
static LISTENING: AtomicBool = new;
;
/// Assemble only the HTTP services selected by build features.
/// Bind address for the management HTTP server.
///
/// Defaults to loopback (`127.0.0.1:8080`) so a stock `http-axum` build is not
/// reachable from the management network. Test/dev flows that need QEMU
/// hostfwd to reach the in-guest listener must opt in to all interfaces by
/// setting `[env] AXVM_HTTP_BIND = "0.0.0.0:8080"` in their build config; the
/// mutating routes still require the bearer token regardless of the bind.
pub
/// Blocking serve: build a tokio current-thread runtime and hand it to axum.
///
/// `main` spawns this on its own task via `std::thread::spawn(|| http::serve())`;
/// the runtime is built here. Only the IO driver is enabled — the epoll
/// reactor suffices for `axum::serve`; a time driver would need `timerfd`.
pub