/src/cloud-hypervisor/vmm/src/api/mod.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright © 2019 Intel Corporation |
2 | | // Copyright 2024 Alyssa Ross <hi@alyssa.is> |
3 | | // |
4 | | // SPDX-License-Identifier: Apache-2.0 |
5 | | // |
6 | | |
7 | | //! The internal VMM API for Cloud Hypervisor. |
8 | | //! |
9 | | //! This API is a synchronous, [mpsc](https://doc.rust-lang.org/std/sync/mpsc/) |
10 | | //! based IPC for sending commands to the VMM thread, from other |
11 | | //! Cloud Hypervisor threads. The IPC follows a command-response protocol, i.e. |
12 | | //! each command will receive a response back. |
13 | | //! |
14 | | //! The main Cloud Hypervisor thread creates an API event file descriptor |
15 | | //! to notify the VMM thread about pending API commands, together with an |
16 | | //! API mpsc channel. The former is the IPC control plane, the latter is the |
17 | | //! IPC data plane. |
18 | | //! In order to use the IPC, a Cloud Hypervisor thread needs to have a clone |
19 | | //! of both the API event file descriptor and the channel Sender. Then it must |
20 | | //! go through the following steps: |
21 | | //! |
22 | | //! 1. The thread creates an mpsc channel for receiving the command response. |
23 | | //! 2. The thread sends an ApiRequest to the Sender endpoint. The ApiRequest |
24 | | //! encapsulates the response channel Sender, for the VMM API server to be |
25 | | //! able to send the response back. |
26 | | //! 3. The thread writes to the API event file descriptor to notify the VMM |
27 | | //! API server about a pending command. |
28 | | //! 4. The thread reads the response back from the VMM API server, from the |
29 | | //! response channel Receiver. |
30 | | //! 5. The thread handles the response and forwards potential errors. |
31 | | |
32 | | #[cfg(feature = "dbus_api")] |
33 | | pub mod dbus; |
34 | | pub mod http; |
35 | | |
36 | | #[cfg(feature = "dbus_api")] |
37 | | pub use self::dbus::start_dbus_thread; |
38 | | pub use self::http::start_http_fd_thread; |
39 | | pub use self::http::start_http_path_thread; |
40 | | |
41 | | use crate::config::{ |
42 | | DeviceConfig, DiskConfig, FsConfig, NetConfig, PmemConfig, RestoreConfig, UserDeviceConfig, |
43 | | VdpaConfig, VmConfig, VsockConfig, |
44 | | }; |
45 | | use crate::device_tree::DeviceTree; |
46 | | use crate::vm::{Error as VmError, VmState}; |
47 | | use crate::Error as VmmError; |
48 | | use core::fmt; |
49 | | use micro_http::Body; |
50 | | use serde::{Deserialize, Serialize}; |
51 | | use std::fmt::Display; |
52 | | use std::io; |
53 | | use std::sync::mpsc::{channel, RecvError, SendError, Sender}; |
54 | | use std::sync::{Arc, Mutex}; |
55 | | use vm_migration::MigratableError; |
56 | | use vmm_sys_util::eventfd::EventFd; |
57 | | |
58 | | /// API errors are sent back from the VMM API server through the ApiResponse. |
59 | 0 | #[derive(Debug)] |
60 | | pub enum ApiError { |
61 | | /// Cannot write to EventFd. |
62 | | EventFdWrite(io::Error), |
63 | | |
64 | | /// API request send error |
65 | | RequestSend(SendError<ApiRequest>), |
66 | | |
67 | | /// Wrong response payload type |
68 | | ResponsePayloadType, |
69 | | |
70 | | /// API response receive error |
71 | | ResponseRecv(RecvError), |
72 | | |
73 | | /// The VM could not boot. |
74 | | VmBoot(VmError), |
75 | | |
76 | | /// The VM could not be created. |
77 | | VmCreate(VmError), |
78 | | |
79 | | /// The VM could not be deleted. |
80 | | VmDelete(VmError), |
81 | | |
82 | | /// The VM info is not available. |
83 | | VmInfo(VmError), |
84 | | |
85 | | /// The VM could not be paused. |
86 | | VmPause(VmError), |
87 | | |
88 | | /// The VM could not resume. |
89 | | VmResume(VmError), |
90 | | |
91 | | /// The VM is not booted. |
92 | | VmNotBooted, |
93 | | |
94 | | /// The VM is not created. |
95 | | VmNotCreated, |
96 | | |
97 | | /// The VM could not shutdown. |
98 | | VmShutdown(VmError), |
99 | | |
100 | | /// The VM could not reboot. |
101 | | VmReboot(VmError), |
102 | | |
103 | | /// The VM could not be snapshotted. |
104 | | VmSnapshot(VmError), |
105 | | |
106 | | /// The VM could not restored. |
107 | | VmRestore(VmError), |
108 | | |
109 | | /// The VM could not be coredumped. |
110 | | VmCoredump(VmError), |
111 | | |
112 | | /// The VMM could not shutdown. |
113 | | VmmShutdown(VmError), |
114 | | |
115 | | /// The VM could not be resized |
116 | | VmResize(VmError), |
117 | | |
118 | | /// The memory zone could not be resized. |
119 | | VmResizeZone(VmError), |
120 | | |
121 | | /// The device could not be added to the VM. |
122 | | VmAddDevice(VmError), |
123 | | |
124 | | /// The user device could not be added to the VM. |
125 | | VmAddUserDevice(VmError), |
126 | | |
127 | | /// The device could not be removed from the VM. |
128 | | VmRemoveDevice(VmError), |
129 | | |
130 | | /// Cannot create seccomp filter |
131 | | CreateSeccompFilter(seccompiler::Error), |
132 | | |
133 | | /// Cannot apply seccomp filter |
134 | | ApplySeccompFilter(seccompiler::Error), |
135 | | |
136 | | /// The disk could not be added to the VM. |
137 | | VmAddDisk(VmError), |
138 | | |
139 | | /// The fs could not be added to the VM. |
140 | | VmAddFs(VmError), |
141 | | |
142 | | /// The pmem device could not be added to the VM. |
143 | | VmAddPmem(VmError), |
144 | | |
145 | | /// The network device could not be added to the VM. |
146 | | VmAddNet(VmError), |
147 | | |
148 | | /// The vDPA device could not be added to the VM. |
149 | | VmAddVdpa(VmError), |
150 | | |
151 | | /// The vsock device could not be added to the VM. |
152 | | VmAddVsock(VmError), |
153 | | |
154 | | /// Error starting migration receiever |
155 | | VmReceiveMigration(MigratableError), |
156 | | |
157 | | /// Error starting migration sender |
158 | | VmSendMigration(MigratableError), |
159 | | |
160 | | /// Error triggering power button |
161 | | VmPowerButton(VmError), |
162 | | |
163 | | /// Error triggering NMI |
164 | | VmNmi(VmError), |
165 | | } |
166 | | pub type ApiResult<T> = Result<T, ApiError>; |
167 | | |
168 | | impl Display for ApiError { |
169 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
170 | 0 | use self::ApiError::*; |
171 | 0 | match self { |
172 | 0 | EventFdWrite(serde_error) => write!(f, "{}", serde_error), |
173 | 0 | RequestSend(send_error) => write!(f, "{}", send_error), |
174 | 0 | ResponsePayloadType => write!(f, "Wrong response payload type"), |
175 | 0 | ResponseRecv(recv_error) => write!(f, "{}", recv_error), |
176 | 0 | VmBoot(vm_error) => write!(f, "{}", vm_error), |
177 | 0 | VmCreate(vm_error) => write!(f, "{}", vm_error), |
178 | 0 | VmDelete(vm_error) => write!(f, "{}", vm_error), |
179 | 0 | VmInfo(vm_error) => write!(f, "{}", vm_error), |
180 | 0 | VmPause(vm_error) => write!(f, "{}", vm_error), |
181 | 0 | VmResume(vm_error) => write!(f, "{}", vm_error), |
182 | 0 | VmNotBooted => write!(f, "VM is not booted"), |
183 | 0 | VmNotCreated => write!(f, "VM is not created"), |
184 | 0 | VmShutdown(vm_error) => write!(f, "{}", vm_error), |
185 | 0 | VmReboot(vm_error) => write!(f, "{}", vm_error), |
186 | 0 | VmSnapshot(vm_error) => write!(f, "{}", vm_error), |
187 | 0 | VmRestore(vm_error) => write!(f, "{}", vm_error), |
188 | 0 | VmCoredump(vm_error) => write!(f, "{}", vm_error), |
189 | 0 | VmmShutdown(vm_error) => write!(f, "{}", vm_error), |
190 | 0 | VmResize(vm_error) => write!(f, "{}", vm_error), |
191 | 0 | VmResizeZone(vm_error) => write!(f, "{}", vm_error), |
192 | 0 | VmAddDevice(vm_error) => write!(f, "{}", vm_error), |
193 | 0 | VmAddUserDevice(vm_error) => write!(f, "{}", vm_error), |
194 | 0 | VmRemoveDevice(vm_error) => write!(f, "{}", vm_error), |
195 | 0 | CreateSeccompFilter(seccomp_error) => write!(f, "{}", seccomp_error), |
196 | 0 | ApplySeccompFilter(seccomp_error) => write!(f, "{}", seccomp_error), |
197 | 0 | VmAddDisk(vm_error) => write!(f, "{}", vm_error), |
198 | 0 | VmAddFs(vm_error) => write!(f, "{}", vm_error), |
199 | 0 | VmAddPmem(vm_error) => write!(f, "{}", vm_error), |
200 | 0 | VmAddNet(vm_error) => write!(f, "{}", vm_error), |
201 | 0 | VmAddVdpa(vm_error) => write!(f, "{}", vm_error), |
202 | 0 | VmAddVsock(vm_error) => write!(f, "{}", vm_error), |
203 | 0 | VmReceiveMigration(migratable_error) => write!(f, "{}", migratable_error), |
204 | 0 | VmSendMigration(migratable_error) => write!(f, "{}", migratable_error), |
205 | 0 | VmPowerButton(vm_error) => write!(f, "{}", vm_error), |
206 | 0 | VmNmi(vm_error) => write!(f, "{}", vm_error), |
207 | | } |
208 | 0 | } |
209 | | } |
210 | | |
211 | 39 | #[derive(Clone, Deserialize, Serialize)] Unexecuted instantiation: <<vmm::api::VmInfoResponse as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> Unexecuted instantiation: <<vmm::api::VmInfoResponse as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_> Unexecuted instantiation: <<vmm::api::VmInfoResponse as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> Unexecuted instantiation: <<vmm::api::VmInfoResponse as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> Unexecuted instantiation: <vmm::api::VmInfoResponse as serde::de::Deserialize>::deserialize::<_> Unexecuted instantiation: <<vmm::api::VmInfoResponse as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_map::<_> Unexecuted instantiation: <<vmm::api::VmInfoResponse as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> Unexecuted instantiation: <<vmm::api::VmInfoResponse as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::expecting Unexecuted instantiation: <<vmm::api::VmInfoResponse as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::expecting |
212 | | pub struct VmInfoResponse { |
213 | | pub config: Arc<Mutex<VmConfig>>, |
214 | | pub state: VmState, |
215 | | pub memory_actual_size: u64, |
216 | | pub device_tree: Option<Arc<Mutex<DeviceTree>>>, |
217 | | } |
218 | | |
219 | 9 | #[derive(Clone, Deserialize, Serialize)] Unexecuted instantiation: <vmm::api::VmmPingResponse as serde::de::Deserialize>::deserialize::<_> Unexecuted instantiation: <<vmm::api::VmmPingResponse as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> Unexecuted instantiation: <<vmm::api::VmmPingResponse as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_map::<_> Unexecuted instantiation: <<vmm::api::VmmPingResponse as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> Unexecuted instantiation: <<vmm::api::VmmPingResponse as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> Unexecuted instantiation: <<vmm::api::VmmPingResponse as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> Unexecuted instantiation: <<vmm::api::VmmPingResponse as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_> Unexecuted instantiation: <<vmm::api::VmmPingResponse as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::expecting Unexecuted instantiation: <<vmm::api::VmmPingResponse as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::expecting |
220 | | pub struct VmmPingResponse { |
221 | | pub build_version: String, |
222 | | pub version: String, |
223 | | pub pid: i64, |
224 | | pub features: Vec<String>, |
225 | | } |
226 | | |
227 | 2.16k | #[derive(Clone, Deserialize, Serialize, Default, Debug)] <<vmm::api::VmResizeData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<serde_json::error::Error> Line | Count | Source | 227 | 1.04k | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmResizeData as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<serde_json::de::SeqAccess<serde_json::read::SliceRead>> Line | Count | Source | 227 | 402 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<vmm::api::VmResizeData as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer<serde_json::read::SliceRead>> Line | Count | Source | 227 | 749 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmResizeData as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_map::<serde_json::de::MapAccess<serde_json::read::SliceRead>> Line | Count | Source | 227 | 718 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmResizeData as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<serde_json::de::MapKey<serde_json::read::SliceRead>> Line | Count | Source | 227 | 1.09k | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
Unexecuted instantiation: <<vmm::api::VmResizeData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> Unexecuted instantiation: <<vmm::api::VmResizeData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> <<vmm::api::VmResizeData as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::expecting Line | Count | Source | 227 | 104 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
Unexecuted instantiation: <<vmm::api::VmResizeData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::expecting |
228 | | pub struct VmResizeData { |
229 | | pub desired_vcpus: Option<u8>, |
230 | | pub desired_ram: Option<u64>, |
231 | | pub desired_balloon: Option<u64>, |
232 | | } |
233 | | |
234 | 1.53k | #[derive(Clone, Deserialize, Serialize, Default, Debug)] <<vmm::api::VmResizeZoneData as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<serde_json::de::SeqAccess<serde_json::read::SliceRead>> Line | Count | Source | 234 | 182 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmResizeZoneData as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_map::<serde_json::de::MapAccess<serde_json::read::SliceRead>> Line | Count | Source | 234 | 532 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmResizeZoneData as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<serde_json::de::MapKey<serde_json::read::SliceRead>> Line | Count | Source | 234 | 839 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<vmm::api::VmResizeZoneData as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer<serde_json::read::SliceRead>> Line | Count | Source | 234 | 382 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmResizeZoneData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<serde_json::error::Error> Line | Count | Source | 234 | 817 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
Unexecuted instantiation: <<vmm::api::VmResizeZoneData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> Unexecuted instantiation: <<vmm::api::VmResizeZoneData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> Unexecuted instantiation: <<vmm::api::VmResizeZoneData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::expecting <<vmm::api::VmResizeZoneData as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::expecting Line | Count | Source | 234 | 9 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
|
235 | | pub struct VmResizeZoneData { |
236 | | pub id: String, |
237 | | pub desired_ram: u64, |
238 | | } |
239 | | |
240 | 918 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] <vmm::api::VmRemoveDeviceData as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer<serde_json::read::SliceRead>> Line | Count | Source | 240 | 310 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmRemoveDeviceData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<serde_json::error::Error> Line | Count | Source | 240 | 388 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmRemoveDeviceData as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<serde_json::de::MapKey<serde_json::read::SliceRead>> Line | Count | Source | 240 | 401 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmRemoveDeviceData as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_map::<serde_json::de::MapAccess<serde_json::read::SliceRead>> Line | Count | Source | 240 | 449 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmRemoveDeviceData as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<serde_json::de::SeqAccess<serde_json::read::SliceRead>> Line | Count | Source | 240 | 81 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
Unexecuted instantiation: <<vmm::api::VmRemoveDeviceData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> Unexecuted instantiation: <<vmm::api::VmRemoveDeviceData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> Unexecuted instantiation: <<vmm::api::VmRemoveDeviceData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::expecting <<vmm::api::VmRemoveDeviceData as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::expecting Line | Count | Source | 240 | 7 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
|
241 | | pub struct VmRemoveDeviceData { |
242 | | pub id: String, |
243 | | } |
244 | | |
245 | 680 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] <<vmm::api::VmSnapshotConfig as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<serde_json::error::Error> Line | Count | Source | 245 | 276 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmSnapshotConfig as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<serde_json::de::MapKey<serde_json::read::SliceRead>> Line | Count | Source | 245 | 286 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmSnapshotConfig as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<serde_json::de::SeqAccess<serde_json::read::SliceRead>> Line | Count | Source | 245 | 50 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmSnapshotConfig as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_map::<serde_json::de::MapAccess<serde_json::read::SliceRead>> Line | Count | Source | 245 | 354 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<vmm::api::VmSnapshotConfig as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer<serde_json::read::SliceRead>> Line | Count | Source | 245 | 507 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
Unexecuted instantiation: <<vmm::api::VmSnapshotConfig as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> Unexecuted instantiation: <<vmm::api::VmSnapshotConfig as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> <<vmm::api::VmSnapshotConfig as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::expecting Line | Count | Source | 245 | 262 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
Unexecuted instantiation: <<vmm::api::VmSnapshotConfig as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::expecting |
246 | | pub struct VmSnapshotConfig { |
247 | | /// The snapshot destination URL |
248 | | pub destination_url: String, |
249 | | } |
250 | | |
251 | 713 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] <<vmm::api::VmCoredumpData as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<serde_json::de::MapKey<serde_json::read::SliceRead>> Line | Count | Source | 251 | 307 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmCoredumpData as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_map::<serde_json::de::MapAccess<serde_json::read::SliceRead>> Line | Count | Source | 251 | 364 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmCoredumpData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<serde_json::error::Error> Line | Count | Source | 251 | 297 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmCoredumpData as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<serde_json::de::SeqAccess<serde_json::read::SliceRead>> Line | Count | Source | 251 | 52 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<vmm::api::VmCoredumpData as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer<serde_json::read::SliceRead>> Line | Count | Source | 251 | 235 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
Unexecuted instantiation: <<vmm::api::VmCoredumpData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> Unexecuted instantiation: <<vmm::api::VmCoredumpData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> Unexecuted instantiation: <<vmm::api::VmCoredumpData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::expecting <<vmm::api::VmCoredumpData as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::expecting Line | Count | Source | 251 | 2 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
|
252 | | pub struct VmCoredumpData { |
253 | | /// The coredump destination file |
254 | | pub destination_url: String, |
255 | | } |
256 | | |
257 | 862 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] <<vmm::api::VmReceiveMigrationData as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_map::<serde_json::de::MapAccess<serde_json::read::SliceRead>> Line | Count | Source | 257 | 353 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmReceiveMigrationData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<serde_json::error::Error> Line | Count | Source | 257 | 337 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmReceiveMigrationData as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<serde_json::de::SeqAccess<serde_json::read::SliceRead>> Line | Count | Source | 257 | 172 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmReceiveMigrationData as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<serde_json::de::MapKey<serde_json::read::SliceRead>> Line | Count | Source | 257 | 354 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<vmm::api::VmReceiveMigrationData as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer<serde_json::read::SliceRead>> Line | Count | Source | 257 | 348 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
Unexecuted instantiation: <<vmm::api::VmReceiveMigrationData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> Unexecuted instantiation: <<vmm::api::VmReceiveMigrationData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> <<vmm::api::VmReceiveMigrationData as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::expecting Line | Count | Source | 257 | 44 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
Unexecuted instantiation: <<vmm::api::VmReceiveMigrationData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::expecting |
258 | | pub struct VmReceiveMigrationData { |
259 | | /// URL for the reception of migration state |
260 | | pub receiver_url: String, |
261 | | } |
262 | | |
263 | 1.23k | #[derive(Clone, Deserialize, Serialize, Default, Debug)] <<vmm::api::VmSendMigrationData as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<serde_json::de::MapKey<serde_json::read::SliceRead>> Line | Count | Source | 263 | 706 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmSendMigrationData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<serde_json::error::Error> Line | Count | Source | 263 | 682 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<vmm::api::VmSendMigrationData as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer<serde_json::read::SliceRead>> Line | Count | Source | 263 | 317 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmSendMigrationData as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_map::<serde_json::de::MapAccess<serde_json::read::SliceRead>> Line | Count | Source | 263 | 472 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
<<vmm::api::VmSendMigrationData as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<serde_json::de::SeqAccess<serde_json::read::SliceRead>> Line | Count | Source | 263 | 80 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
Unexecuted instantiation: <<vmm::api::VmSendMigrationData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> Unexecuted instantiation: <<vmm::api::VmSendMigrationData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> Unexecuted instantiation: <<vmm::api::VmSendMigrationData as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::expecting <<vmm::api::VmSendMigrationData as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::expecting Line | Count | Source | 263 | 7 | #[derive(Clone, Deserialize, Serialize, Default, Debug)] |
|
264 | | pub struct VmSendMigrationData { |
265 | | /// URL to migrate the VM to |
266 | | pub destination_url: String, |
267 | | /// Send memory across socket without copying |
268 | | #[serde(default)] |
269 | | pub local: bool, |
270 | | } |
271 | | |
272 | | pub enum ApiResponsePayload { |
273 | | /// No data is sent on the channel. |
274 | | Empty, |
275 | | |
276 | | /// Virtual machine information |
277 | | VmInfo(VmInfoResponse), |
278 | | |
279 | | /// Vmm ping response |
280 | | VmmPing(VmmPingResponse), |
281 | | |
282 | | /// Vm action response |
283 | | VmAction(Option<Vec<u8>>), |
284 | | } |
285 | | |
286 | | /// This is the response sent by the VMM API server through the mpsc channel. |
287 | | pub type ApiResponse = Result<ApiResponsePayload, ApiError>; |
288 | | |
289 | | pub trait RequestHandler { |
290 | | fn vm_create(&mut self, config: Arc<Mutex<VmConfig>>) -> Result<(), VmError>; |
291 | | |
292 | | fn vm_boot(&mut self) -> Result<(), VmError>; |
293 | | |
294 | | fn vm_pause(&mut self) -> Result<(), VmError>; |
295 | | |
296 | | fn vm_resume(&mut self) -> Result<(), VmError>; |
297 | | |
298 | | fn vm_snapshot(&mut self, destination_url: &str) -> Result<(), VmError>; |
299 | | |
300 | | fn vm_restore(&mut self, restore_cfg: RestoreConfig) -> Result<(), VmError>; |
301 | | |
302 | | #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] |
303 | | fn vm_coredump(&mut self, destination_url: &str) -> Result<(), VmError>; |
304 | | |
305 | | fn vm_shutdown(&mut self) -> Result<(), VmError>; |
306 | | |
307 | | fn vm_reboot(&mut self) -> Result<(), VmError>; |
308 | | |
309 | | fn vm_info(&self) -> Result<VmInfoResponse, VmError>; |
310 | | |
311 | | fn vmm_ping(&self) -> VmmPingResponse; |
312 | | |
313 | | fn vm_delete(&mut self) -> Result<(), VmError>; |
314 | | |
315 | | fn vmm_shutdown(&mut self) -> Result<(), VmError>; |
316 | | |
317 | | fn vm_resize( |
318 | | &mut self, |
319 | | desired_vcpus: Option<u8>, |
320 | | desired_ram: Option<u64>, |
321 | | desired_balloon: Option<u64>, |
322 | | ) -> Result<(), VmError>; |
323 | | |
324 | | fn vm_resize_zone(&mut self, id: String, desired_ram: u64) -> Result<(), VmError>; |
325 | | |
326 | | fn vm_add_device(&mut self, device_cfg: DeviceConfig) -> Result<Option<Vec<u8>>, VmError>; |
327 | | |
328 | | fn vm_add_user_device( |
329 | | &mut self, |
330 | | device_cfg: UserDeviceConfig, |
331 | | ) -> Result<Option<Vec<u8>>, VmError>; |
332 | | |
333 | | fn vm_remove_device(&mut self, id: String) -> Result<(), VmError>; |
334 | | |
335 | | fn vm_add_disk(&mut self, disk_cfg: DiskConfig) -> Result<Option<Vec<u8>>, VmError>; |
336 | | |
337 | | fn vm_add_fs(&mut self, fs_cfg: FsConfig) -> Result<Option<Vec<u8>>, VmError>; |
338 | | |
339 | | fn vm_add_pmem(&mut self, pmem_cfg: PmemConfig) -> Result<Option<Vec<u8>>, VmError>; |
340 | | |
341 | | fn vm_add_net(&mut self, net_cfg: NetConfig) -> Result<Option<Vec<u8>>, VmError>; |
342 | | |
343 | | fn vm_add_vdpa(&mut self, vdpa_cfg: VdpaConfig) -> Result<Option<Vec<u8>>, VmError>; |
344 | | |
345 | | fn vm_add_vsock(&mut self, vsock_cfg: VsockConfig) -> Result<Option<Vec<u8>>, VmError>; |
346 | | |
347 | | fn vm_counters(&mut self) -> Result<Option<Vec<u8>>, VmError>; |
348 | | |
349 | | fn vm_power_button(&mut self) -> Result<(), VmError>; |
350 | | |
351 | | fn vm_receive_migration( |
352 | | &mut self, |
353 | | receive_data_migration: VmReceiveMigrationData, |
354 | | ) -> Result<(), MigratableError>; |
355 | | |
356 | | fn vm_send_migration( |
357 | | &mut self, |
358 | | send_data_migration: VmSendMigrationData, |
359 | | ) -> Result<(), MigratableError>; |
360 | | |
361 | | fn vm_nmi(&mut self) -> Result<(), VmError>; |
362 | | } |
363 | | |
364 | | /// It would be nice if we could pass around an object like this: |
365 | | /// |
366 | | /// ``` |
367 | | /// # use vmm::api::ApiAction; |
368 | | /// struct ApiRequest<Action: ApiAction + 'static> { |
369 | | /// action: &'static Action, |
370 | | /// body: Action::RequestBody, |
371 | | /// } |
372 | | /// ``` |
373 | | /// |
374 | | /// Unfortunately, it's not possible to use such a type in a trait object, |
375 | | /// so as a workaround, we instead encapsulate that data in a closure, and have |
376 | | /// the event loop call that closure to process a request. |
377 | | pub type ApiRequest = |
378 | | Box<dyn FnOnce(&mut dyn RequestHandler) -> Result<bool, VmmError> + Send + 'static>; |
379 | | |
380 | 430 | fn get_response<Action: ApiAction>( |
381 | 430 | action: &Action, |
382 | 430 | api_evt: EventFd, |
383 | 430 | api_sender: Sender<ApiRequest>, |
384 | 430 | data: Action::RequestBody, |
385 | 430 | ) -> ApiResult<ApiResponsePayload> { |
386 | 430 | let (response_sender, response_receiver) = channel(); |
387 | 430 | |
388 | 430 | let request = action.request(data, response_sender); |
389 | 430 | |
390 | 430 | // Send the VM request. |
391 | 430 | api_sender.send(request).map_err(ApiError::RequestSend)?; |
392 | 430 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; |
393 | | |
394 | 430 | response_receiver.recv().map_err(ApiError::ResponseRecv)? |
395 | 430 | } vmm::api::get_response::<vmm::api::VmResizeZone> Line | Count | Source | 380 | 10 | fn get_response<Action: ApiAction>( | 381 | 10 | action: &Action, | 382 | 10 | api_evt: EventFd, | 383 | 10 | api_sender: Sender<ApiRequest>, | 384 | 10 | data: Action::RequestBody, | 385 | 10 | ) -> ApiResult<ApiResponsePayload> { | 386 | 10 | let (response_sender, response_receiver) = channel(); | 387 | 10 | | 388 | 10 | let request = action.request(data, response_sender); | 389 | 10 | | 390 | 10 | // Send the VM request. | 391 | 10 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 10 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 10 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 10 | } |
vmm::api::get_response::<vmm::api::VmInfo> Line | Count | Source | 380 | 39 | fn get_response<Action: ApiAction>( | 381 | 39 | action: &Action, | 382 | 39 | api_evt: EventFd, | 383 | 39 | api_sender: Sender<ApiRequest>, | 384 | 39 | data: Action::RequestBody, | 385 | 39 | ) -> ApiResult<ApiResponsePayload> { | 386 | 39 | let (response_sender, response_receiver) = channel(); | 387 | 39 | | 388 | 39 | let request = action.request(data, response_sender); | 389 | 39 | | 390 | 39 | // Send the VM request. | 391 | 39 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 39 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 39 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 39 | } |
vmm::api::get_response::<vmm::api::VmCounters> Line | Count | Source | 380 | 12 | fn get_response<Action: ApiAction>( | 381 | 12 | action: &Action, | 382 | 12 | api_evt: EventFd, | 383 | 12 | api_sender: Sender<ApiRequest>, | 384 | 12 | data: Action::RequestBody, | 385 | 12 | ) -> ApiResult<ApiResponsePayload> { | 386 | 12 | let (response_sender, response_receiver) = channel(); | 387 | 12 | | 388 | 12 | let request = action.request(data, response_sender); | 389 | 12 | | 390 | 12 | // Send the VM request. | 391 | 12 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 12 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 12 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 12 | } |
vmm::api::get_response::<vmm::api::VmResize> Line | Count | Source | 380 | 6 | fn get_response<Action: ApiAction>( | 381 | 6 | action: &Action, | 382 | 6 | api_evt: EventFd, | 383 | 6 | api_sender: Sender<ApiRequest>, | 384 | 6 | data: Action::RequestBody, | 385 | 6 | ) -> ApiResult<ApiResponsePayload> { | 386 | 6 | let (response_sender, response_receiver) = channel(); | 387 | 6 | | 388 | 6 | let request = action.request(data, response_sender); | 389 | 6 | | 390 | 6 | // Send the VM request. | 391 | 6 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 6 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 6 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 6 | } |
vmm::api::get_response::<vmm::api::VmReboot> Line | Count | Source | 380 | 11 | fn get_response<Action: ApiAction>( | 381 | 11 | action: &Action, | 382 | 11 | api_evt: EventFd, | 383 | 11 | api_sender: Sender<ApiRequest>, | 384 | 11 | data: Action::RequestBody, | 385 | 11 | ) -> ApiResult<ApiResponsePayload> { | 386 | 11 | let (response_sender, response_receiver) = channel(); | 387 | 11 | | 388 | 11 | let request = action.request(data, response_sender); | 389 | 11 | | 390 | 11 | // Send the VM request. | 391 | 11 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 11 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 11 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 11 | } |
vmm::api::get_response::<vmm::api::VmCoredump> Line | Count | Source | 380 | 12 | fn get_response<Action: ApiAction>( | 381 | 12 | action: &Action, | 382 | 12 | api_evt: EventFd, | 383 | 12 | api_sender: Sender<ApiRequest>, | 384 | 12 | data: Action::RequestBody, | 385 | 12 | ) -> ApiResult<ApiResponsePayload> { | 386 | 12 | let (response_sender, response_receiver) = channel(); | 387 | 12 | | 388 | 12 | let request = action.request(data, response_sender); | 389 | 12 | | 390 | 12 | // Send the VM request. | 391 | 12 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 12 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 12 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 12 | } |
vmm::api::get_response::<vmm::api::VmResume> Line | Count | Source | 380 | 7 | fn get_response<Action: ApiAction>( | 381 | 7 | action: &Action, | 382 | 7 | api_evt: EventFd, | 383 | 7 | api_sender: Sender<ApiRequest>, | 384 | 7 | data: Action::RequestBody, | 385 | 7 | ) -> ApiResult<ApiResponsePayload> { | 386 | 7 | let (response_sender, response_receiver) = channel(); | 387 | 7 | | 388 | 7 | let request = action.request(data, response_sender); | 389 | 7 | | 390 | 7 | // Send the VM request. | 391 | 7 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 7 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 7 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 7 | } |
vmm::api::get_response::<vmm::api::VmPowerButton> Line | Count | Source | 380 | 33 | fn get_response<Action: ApiAction>( | 381 | 33 | action: &Action, | 382 | 33 | api_evt: EventFd, | 383 | 33 | api_sender: Sender<ApiRequest>, | 384 | 33 | data: Action::RequestBody, | 385 | 33 | ) -> ApiResult<ApiResponsePayload> { | 386 | 33 | let (response_sender, response_receiver) = channel(); | 387 | 33 | | 388 | 33 | let request = action.request(data, response_sender); | 389 | 33 | | 390 | 33 | // Send the VM request. | 391 | 33 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 33 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 33 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 33 | } |
vmm::api::get_response::<vmm::api::VmNmi> Line | Count | Source | 380 | 11 | fn get_response<Action: ApiAction>( | 381 | 11 | action: &Action, | 382 | 11 | api_evt: EventFd, | 383 | 11 | api_sender: Sender<ApiRequest>, | 384 | 11 | data: Action::RequestBody, | 385 | 11 | ) -> ApiResult<ApiResponsePayload> { | 386 | 11 | let (response_sender, response_receiver) = channel(); | 387 | 11 | | 388 | 11 | let request = action.request(data, response_sender); | 389 | 11 | | 390 | 11 | // Send the VM request. | 391 | 11 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 11 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 11 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 11 | } |
vmm::api::get_response::<vmm::api::VmRestore> Line | Count | Source | 380 | 18 | fn get_response<Action: ApiAction>( | 381 | 18 | action: &Action, | 382 | 18 | api_evt: EventFd, | 383 | 18 | api_sender: Sender<ApiRequest>, | 384 | 18 | data: Action::RequestBody, | 385 | 18 | ) -> ApiResult<ApiResponsePayload> { | 386 | 18 | let (response_sender, response_receiver) = channel(); | 387 | 18 | | 388 | 18 | let request = action.request(data, response_sender); | 389 | 18 | | 390 | 18 | // Send the VM request. | 391 | 18 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 18 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 18 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 18 | } |
vmm::api::get_response::<vmm::api::VmRemoveDevice> Line | Count | Source | 380 | 15 | fn get_response<Action: ApiAction>( | 381 | 15 | action: &Action, | 382 | 15 | api_evt: EventFd, | 383 | 15 | api_sender: Sender<ApiRequest>, | 384 | 15 | data: Action::RequestBody, | 385 | 15 | ) -> ApiResult<ApiResponsePayload> { | 386 | 15 | let (response_sender, response_receiver) = channel(); | 387 | 15 | | 388 | 15 | let request = action.request(data, response_sender); | 389 | 15 | | 390 | 15 | // Send the VM request. | 391 | 15 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 15 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 15 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 15 | } |
vmm::api::get_response::<vmm::api::VmmShutdown> Line | Count | Source | 380 | 5 | fn get_response<Action: ApiAction>( | 381 | 5 | action: &Action, | 382 | 5 | api_evt: EventFd, | 383 | 5 | api_sender: Sender<ApiRequest>, | 384 | 5 | data: Action::RequestBody, | 385 | 5 | ) -> ApiResult<ApiResponsePayload> { | 386 | 5 | let (response_sender, response_receiver) = channel(); | 387 | 5 | | 388 | 5 | let request = action.request(data, response_sender); | 389 | 5 | | 390 | 5 | // Send the VM request. | 391 | 5 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 5 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 5 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 5 | } |
vmm::api::get_response::<vmm::api::VmShutdown> Line | Count | Source | 380 | 8 | fn get_response<Action: ApiAction>( | 381 | 8 | action: &Action, | 382 | 8 | api_evt: EventFd, | 383 | 8 | api_sender: Sender<ApiRequest>, | 384 | 8 | data: Action::RequestBody, | 385 | 8 | ) -> ApiResult<ApiResponsePayload> { | 386 | 8 | let (response_sender, response_receiver) = channel(); | 387 | 8 | | 388 | 8 | let request = action.request(data, response_sender); | 389 | 8 | | 390 | 8 | // Send the VM request. | 391 | 8 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 8 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 8 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 8 | } |
vmm::api::get_response::<vmm::api::VmReceiveMigration> Line | Count | Source | 380 | 21 | fn get_response<Action: ApiAction>( | 381 | 21 | action: &Action, | 382 | 21 | api_evt: EventFd, | 383 | 21 | api_sender: Sender<ApiRequest>, | 384 | 21 | data: Action::RequestBody, | 385 | 21 | ) -> ApiResult<ApiResponsePayload> { | 386 | 21 | let (response_sender, response_receiver) = channel(); | 387 | 21 | | 388 | 21 | let request = action.request(data, response_sender); | 389 | 21 | | 390 | 21 | // Send the VM request. | 391 | 21 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 21 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 21 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 21 | } |
vmm::api::get_response::<vmm::api::VmSendMigration> Line | Count | Source | 380 | 16 | fn get_response<Action: ApiAction>( | 381 | 16 | action: &Action, | 382 | 16 | api_evt: EventFd, | 383 | 16 | api_sender: Sender<ApiRequest>, | 384 | 16 | data: Action::RequestBody, | 385 | 16 | ) -> ApiResult<ApiResponsePayload> { | 386 | 16 | let (response_sender, response_receiver) = channel(); | 387 | 16 | | 388 | 16 | let request = action.request(data, response_sender); | 389 | 16 | | 390 | 16 | // Send the VM request. | 391 | 16 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 16 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 16 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 16 | } |
vmm::api::get_response::<vmm::api::VmAddNet> Line | Count | Source | 380 | 19 | fn get_response<Action: ApiAction>( | 381 | 19 | action: &Action, | 382 | 19 | api_evt: EventFd, | 383 | 19 | api_sender: Sender<ApiRequest>, | 384 | 19 | data: Action::RequestBody, | 385 | 19 | ) -> ApiResult<ApiResponsePayload> { | 386 | 19 | let (response_sender, response_receiver) = channel(); | 387 | 19 | | 388 | 19 | let request = action.request(data, response_sender); | 389 | 19 | | 390 | 19 | // Send the VM request. | 391 | 19 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 19 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 19 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 19 | } |
vmm::api::get_response::<vmm::api::VmmPing> Line | Count | Source | 380 | 9 | fn get_response<Action: ApiAction>( | 381 | 9 | action: &Action, | 382 | 9 | api_evt: EventFd, | 383 | 9 | api_sender: Sender<ApiRequest>, | 384 | 9 | data: Action::RequestBody, | 385 | 9 | ) -> ApiResult<ApiResponsePayload> { | 386 | 9 | let (response_sender, response_receiver) = channel(); | 387 | 9 | | 388 | 9 | let request = action.request(data, response_sender); | 389 | 9 | | 390 | 9 | // Send the VM request. | 391 | 9 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 9 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 9 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 9 | } |
vmm::api::get_response::<vmm::api::VmAddPmem> Line | Count | Source | 380 | 20 | fn get_response<Action: ApiAction>( | 381 | 20 | action: &Action, | 382 | 20 | api_evt: EventFd, | 383 | 20 | api_sender: Sender<ApiRequest>, | 384 | 20 | data: Action::RequestBody, | 385 | 20 | ) -> ApiResult<ApiResponsePayload> { | 386 | 20 | let (response_sender, response_receiver) = channel(); | 387 | 20 | | 388 | 20 | let request = action.request(data, response_sender); | 389 | 20 | | 390 | 20 | // Send the VM request. | 391 | 20 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 20 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 20 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 20 | } |
vmm::api::get_response::<vmm::api::VmAddDevice> Line | Count | Source | 380 | 22 | fn get_response<Action: ApiAction>( | 381 | 22 | action: &Action, | 382 | 22 | api_evt: EventFd, | 383 | 22 | api_sender: Sender<ApiRequest>, | 384 | 22 | data: Action::RequestBody, | 385 | 22 | ) -> ApiResult<ApiResponsePayload> { | 386 | 22 | let (response_sender, response_receiver) = channel(); | 387 | 22 | | 388 | 22 | let request = action.request(data, response_sender); | 389 | 22 | | 390 | 22 | // Send the VM request. | 391 | 22 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 22 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 22 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 22 | } |
vmm::api::get_response::<vmm::api::VmSnapshot> Line | Count | Source | 380 | 14 | fn get_response<Action: ApiAction>( | 381 | 14 | action: &Action, | 382 | 14 | api_evt: EventFd, | 383 | 14 | api_sender: Sender<ApiRequest>, | 384 | 14 | data: Action::RequestBody, | 385 | 14 | ) -> ApiResult<ApiResponsePayload> { | 386 | 14 | let (response_sender, response_receiver) = channel(); | 387 | 14 | | 388 | 14 | let request = action.request(data, response_sender); | 389 | 14 | | 390 | 14 | // Send the VM request. | 391 | 14 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 14 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 14 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 14 | } |
Unexecuted instantiation: vmm::api::get_response::<vmm::api::VmAddVsock> vmm::api::get_response::<vmm::api::VmDelete> Line | Count | Source | 380 | 6 | fn get_response<Action: ApiAction>( | 381 | 6 | action: &Action, | 382 | 6 | api_evt: EventFd, | 383 | 6 | api_sender: Sender<ApiRequest>, | 384 | 6 | data: Action::RequestBody, | 385 | 6 | ) -> ApiResult<ApiResponsePayload> { | 386 | 6 | let (response_sender, response_receiver) = channel(); | 387 | 6 | | 388 | 6 | let request = action.request(data, response_sender); | 389 | 6 | | 390 | 6 | // Send the VM request. | 391 | 6 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 6 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 6 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 6 | } |
vmm::api::get_response::<vmm::api::VmAddVdpa> Line | Count | Source | 380 | 17 | fn get_response<Action: ApiAction>( | 381 | 17 | action: &Action, | 382 | 17 | api_evt: EventFd, | 383 | 17 | api_sender: Sender<ApiRequest>, | 384 | 17 | data: Action::RequestBody, | 385 | 17 | ) -> ApiResult<ApiResponsePayload> { | 386 | 17 | let (response_sender, response_receiver) = channel(); | 387 | 17 | | 388 | 17 | let request = action.request(data, response_sender); | 389 | 17 | | 390 | 17 | // Send the VM request. | 391 | 17 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 17 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 17 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 17 | } |
vmm::api::get_response::<vmm::api::VmAddFs> Line | Count | Source | 380 | 13 | fn get_response<Action: ApiAction>( | 381 | 13 | action: &Action, | 382 | 13 | api_evt: EventFd, | 383 | 13 | api_sender: Sender<ApiRequest>, | 384 | 13 | data: Action::RequestBody, | 385 | 13 | ) -> ApiResult<ApiResponsePayload> { | 386 | 13 | let (response_sender, response_receiver) = channel(); | 387 | 13 | | 388 | 13 | let request = action.request(data, response_sender); | 389 | 13 | | 390 | 13 | // Send the VM request. | 391 | 13 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 13 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 13 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 13 | } |
vmm::api::get_response::<vmm::api::VmCreate> Line | Count | Source | 380 | 22 | fn get_response<Action: ApiAction>( | 381 | 22 | action: &Action, | 382 | 22 | api_evt: EventFd, | 383 | 22 | api_sender: Sender<ApiRequest>, | 384 | 22 | data: Action::RequestBody, | 385 | 22 | ) -> ApiResult<ApiResponsePayload> { | 386 | 22 | let (response_sender, response_receiver) = channel(); | 387 | 22 | | 388 | 22 | let request = action.request(data, response_sender); | 389 | 22 | | 390 | 22 | // Send the VM request. | 391 | 22 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 22 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 22 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 22 | } |
vmm::api::get_response::<vmm::api::VmBoot> Line | Count | Source | 380 | 9 | fn get_response<Action: ApiAction>( | 381 | 9 | action: &Action, | 382 | 9 | api_evt: EventFd, | 383 | 9 | api_sender: Sender<ApiRequest>, | 384 | 9 | data: Action::RequestBody, | 385 | 9 | ) -> ApiResult<ApiResponsePayload> { | 386 | 9 | let (response_sender, response_receiver) = channel(); | 387 | 9 | | 388 | 9 | let request = action.request(data, response_sender); | 389 | 9 | | 390 | 9 | // Send the VM request. | 391 | 9 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 9 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 9 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 9 | } |
vmm::api::get_response::<vmm::api::AddDisk> Line | Count | Source | 380 | 27 | fn get_response<Action: ApiAction>( | 381 | 27 | action: &Action, | 382 | 27 | api_evt: EventFd, | 383 | 27 | api_sender: Sender<ApiRequest>, | 384 | 27 | data: Action::RequestBody, | 385 | 27 | ) -> ApiResult<ApiResponsePayload> { | 386 | 27 | let (response_sender, response_receiver) = channel(); | 387 | 27 | | 388 | 27 | let request = action.request(data, response_sender); | 389 | 27 | | 390 | 27 | // Send the VM request. | 391 | 27 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 27 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 27 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 27 | } |
vmm::api::get_response::<vmm::api::VmPause> Line | Count | Source | 380 | 10 | fn get_response<Action: ApiAction>( | 381 | 10 | action: &Action, | 382 | 10 | api_evt: EventFd, | 383 | 10 | api_sender: Sender<ApiRequest>, | 384 | 10 | data: Action::RequestBody, | 385 | 10 | ) -> ApiResult<ApiResponsePayload> { | 386 | 10 | let (response_sender, response_receiver) = channel(); | 387 | 10 | | 388 | 10 | let request = action.request(data, response_sender); | 389 | 10 | | 390 | 10 | // Send the VM request. | 391 | 10 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 10 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 10 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 10 | } |
vmm::api::get_response::<vmm::api::VmAddUserDevice> Line | Count | Source | 380 | 18 | fn get_response<Action: ApiAction>( | 381 | 18 | action: &Action, | 382 | 18 | api_evt: EventFd, | 383 | 18 | api_sender: Sender<ApiRequest>, | 384 | 18 | data: Action::RequestBody, | 385 | 18 | ) -> ApiResult<ApiResponsePayload> { | 386 | 18 | let (response_sender, response_receiver) = channel(); | 387 | 18 | | 388 | 18 | let request = action.request(data, response_sender); | 389 | 18 | | 390 | 18 | // Send the VM request. | 391 | 18 | api_sender.send(request).map_err(ApiError::RequestSend)?; | 392 | 18 | api_evt.write(1).map_err(ApiError::EventFdWrite)?; | 393 | | | 394 | 18 | response_receiver.recv().map_err(ApiError::ResponseRecv)? | 395 | 18 | } |
|
396 | | |
397 | 355 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( |
398 | 355 | action: &Action, |
399 | 355 | api_evt: EventFd, |
400 | 355 | api_sender: Sender<ApiRequest>, |
401 | 355 | data: Action::RequestBody, |
402 | 355 | ) -> ApiResult<Option<Body>> { |
403 | 355 | let body = match get_response(action, api_evt, api_sender, data)? { |
404 | 148 | ApiResponsePayload::VmAction(response) => response.map(Body::new), |
405 | 207 | ApiResponsePayload::Empty => None, |
406 | 0 | _ => return Err(ApiError::ResponsePayloadType), |
407 | | }; |
408 | | |
409 | 355 | Ok(body) |
410 | 355 | } vmm::api::get_response_body::<vmm::api::VmNmi> Line | Count | Source | 397 | 11 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 11 | action: &Action, | 399 | 11 | api_evt: EventFd, | 400 | 11 | api_sender: Sender<ApiRequest>, | 401 | 11 | data: Action::RequestBody, | 402 | 11 | ) -> ApiResult<Option<Body>> { | 403 | 11 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 0 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 11 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 11 | Ok(body) | 410 | 11 | } |
vmm::api::get_response_body::<vmm::api::VmSnapshot> Line | Count | Source | 397 | 14 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 14 | action: &Action, | 399 | 14 | api_evt: EventFd, | 400 | 14 | api_sender: Sender<ApiRequest>, | 401 | 14 | data: Action::RequestBody, | 402 | 14 | ) -> ApiResult<Option<Body>> { | 403 | 14 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 0 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 14 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 14 | Ok(body) | 410 | 14 | } |
vmm::api::get_response_body::<vmm::api::VmResume> Line | Count | Source | 397 | 7 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 7 | action: &Action, | 399 | 7 | api_evt: EventFd, | 400 | 7 | api_sender: Sender<ApiRequest>, | 401 | 7 | data: Action::RequestBody, | 402 | 7 | ) -> ApiResult<Option<Body>> { | 403 | 7 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 0 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 7 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 7 | Ok(body) | 410 | 7 | } |
vmm::api::get_response_body::<vmm::api::VmBoot> Line | Count | Source | 397 | 9 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 9 | action: &Action, | 399 | 9 | api_evt: EventFd, | 400 | 9 | api_sender: Sender<ApiRequest>, | 401 | 9 | data: Action::RequestBody, | 402 | 9 | ) -> ApiResult<Option<Body>> { | 403 | 9 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 0 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 9 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 9 | Ok(body) | 410 | 9 | } |
vmm::api::get_response_body::<vmm::api::VmAddVdpa> Line | Count | Source | 397 | 17 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 17 | action: &Action, | 399 | 17 | api_evt: EventFd, | 400 | 17 | api_sender: Sender<ApiRequest>, | 401 | 17 | data: Action::RequestBody, | 402 | 17 | ) -> ApiResult<Option<Body>> { | 403 | 17 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 17 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 0 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 17 | Ok(body) | 410 | 17 | } |
vmm::api::get_response_body::<vmm::api::VmAddFs> Line | Count | Source | 397 | 13 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 13 | action: &Action, | 399 | 13 | api_evt: EventFd, | 400 | 13 | api_sender: Sender<ApiRequest>, | 401 | 13 | data: Action::RequestBody, | 402 | 13 | ) -> ApiResult<Option<Body>> { | 403 | 13 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 13 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 0 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 13 | Ok(body) | 410 | 13 | } |
vmm::api::get_response_body::<vmm::api::VmSendMigration> Line | Count | Source | 397 | 16 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 16 | action: &Action, | 399 | 16 | api_evt: EventFd, | 400 | 16 | api_sender: Sender<ApiRequest>, | 401 | 16 | data: Action::RequestBody, | 402 | 16 | ) -> ApiResult<Option<Body>> { | 403 | 16 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 0 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 16 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 16 | Ok(body) | 410 | 16 | } |
vmm::api::get_response_body::<vmm::api::VmResizeZone> Line | Count | Source | 397 | 10 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 10 | action: &Action, | 399 | 10 | api_evt: EventFd, | 400 | 10 | api_sender: Sender<ApiRequest>, | 401 | 10 | data: Action::RequestBody, | 402 | 10 | ) -> ApiResult<Option<Body>> { | 403 | 10 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 0 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 10 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 10 | Ok(body) | 410 | 10 | } |
vmm::api::get_response_body::<vmm::api::VmReceiveMigration> Line | Count | Source | 397 | 21 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 21 | action: &Action, | 399 | 21 | api_evt: EventFd, | 400 | 21 | api_sender: Sender<ApiRequest>, | 401 | 21 | data: Action::RequestBody, | 402 | 21 | ) -> ApiResult<Option<Body>> { | 403 | 21 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 0 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 21 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 21 | Ok(body) | 410 | 21 | } |
vmm::api::get_response_body::<vmm::api::VmPause> Line | Count | Source | 397 | 10 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 10 | action: &Action, | 399 | 10 | api_evt: EventFd, | 400 | 10 | api_sender: Sender<ApiRequest>, | 401 | 10 | data: Action::RequestBody, | 402 | 10 | ) -> ApiResult<Option<Body>> { | 403 | 10 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 0 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 10 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 10 | Ok(body) | 410 | 10 | } |
vmm::api::get_response_body::<vmm::api::VmAddPmem> Line | Count | Source | 397 | 20 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 20 | action: &Action, | 399 | 20 | api_evt: EventFd, | 400 | 20 | api_sender: Sender<ApiRequest>, | 401 | 20 | data: Action::RequestBody, | 402 | 20 | ) -> ApiResult<Option<Body>> { | 403 | 20 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 20 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 0 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 20 | Ok(body) | 410 | 20 | } |
vmm::api::get_response_body::<vmm::api::VmAddDevice> Line | Count | Source | 397 | 22 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 22 | action: &Action, | 399 | 22 | api_evt: EventFd, | 400 | 22 | api_sender: Sender<ApiRequest>, | 401 | 22 | data: Action::RequestBody, | 402 | 22 | ) -> ApiResult<Option<Body>> { | 403 | 22 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 22 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 0 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 22 | Ok(body) | 410 | 22 | } |
vmm::api::get_response_body::<vmm::api::VmPowerButton> Line | Count | Source | 397 | 33 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 33 | action: &Action, | 399 | 33 | api_evt: EventFd, | 400 | 33 | api_sender: Sender<ApiRequest>, | 401 | 33 | data: Action::RequestBody, | 402 | 33 | ) -> ApiResult<Option<Body>> { | 403 | 33 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 0 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 33 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 33 | Ok(body) | 410 | 33 | } |
vmm::api::get_response_body::<vmm::api::VmDelete> Line | Count | Source | 397 | 6 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 6 | action: &Action, | 399 | 6 | api_evt: EventFd, | 400 | 6 | api_sender: Sender<ApiRequest>, | 401 | 6 | data: Action::RequestBody, | 402 | 6 | ) -> ApiResult<Option<Body>> { | 403 | 6 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 0 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 6 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 6 | Ok(body) | 410 | 6 | } |
vmm::api::get_response_body::<vmm::api::VmCoredump> Line | Count | Source | 397 | 12 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 12 | action: &Action, | 399 | 12 | api_evt: EventFd, | 400 | 12 | api_sender: Sender<ApiRequest>, | 401 | 12 | data: Action::RequestBody, | 402 | 12 | ) -> ApiResult<Option<Body>> { | 403 | 12 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 0 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 12 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 12 | Ok(body) | 410 | 12 | } |
Unexecuted instantiation: vmm::api::get_response_body::<vmm::api::VmAddVsock> vmm::api::get_response_body::<vmm::api::VmShutdown> Line | Count | Source | 397 | 8 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 8 | action: &Action, | 399 | 8 | api_evt: EventFd, | 400 | 8 | api_sender: Sender<ApiRequest>, | 401 | 8 | data: Action::RequestBody, | 402 | 8 | ) -> ApiResult<Option<Body>> { | 403 | 8 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 0 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 8 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 8 | Ok(body) | 410 | 8 | } |
vmm::api::get_response_body::<vmm::api::VmRestore> Line | Count | Source | 397 | 18 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 18 | action: &Action, | 399 | 18 | api_evt: EventFd, | 400 | 18 | api_sender: Sender<ApiRequest>, | 401 | 18 | data: Action::RequestBody, | 402 | 18 | ) -> ApiResult<Option<Body>> { | 403 | 18 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 0 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 18 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 18 | Ok(body) | 410 | 18 | } |
vmm::api::get_response_body::<vmm::api::VmRemoveDevice> Line | Count | Source | 397 | 15 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 15 | action: &Action, | 399 | 15 | api_evt: EventFd, | 400 | 15 | api_sender: Sender<ApiRequest>, | 401 | 15 | data: Action::RequestBody, | 402 | 15 | ) -> ApiResult<Option<Body>> { | 403 | 15 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 0 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 15 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 15 | Ok(body) | 410 | 15 | } |
vmm::api::get_response_body::<vmm::api::VmAddUserDevice> Line | Count | Source | 397 | 18 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 18 | action: &Action, | 399 | 18 | api_evt: EventFd, | 400 | 18 | api_sender: Sender<ApiRequest>, | 401 | 18 | data: Action::RequestBody, | 402 | 18 | ) -> ApiResult<Option<Body>> { | 403 | 18 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 18 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 0 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 18 | Ok(body) | 410 | 18 | } |
vmm::api::get_response_body::<vmm::api::VmAddNet> Line | Count | Source | 397 | 19 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 19 | action: &Action, | 399 | 19 | api_evt: EventFd, | 400 | 19 | api_sender: Sender<ApiRequest>, | 401 | 19 | data: Action::RequestBody, | 402 | 19 | ) -> ApiResult<Option<Body>> { | 403 | 19 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 19 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 0 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 19 | Ok(body) | 410 | 19 | } |
vmm::api::get_response_body::<vmm::api::AddDisk> Line | Count | Source | 397 | 27 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 27 | action: &Action, | 399 | 27 | api_evt: EventFd, | 400 | 27 | api_sender: Sender<ApiRequest>, | 401 | 27 | data: Action::RequestBody, | 402 | 27 | ) -> ApiResult<Option<Body>> { | 403 | 27 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 27 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 0 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 27 | Ok(body) | 410 | 27 | } |
vmm::api::get_response_body::<vmm::api::VmResize> Line | Count | Source | 397 | 6 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 6 | action: &Action, | 399 | 6 | api_evt: EventFd, | 400 | 6 | api_sender: Sender<ApiRequest>, | 401 | 6 | data: Action::RequestBody, | 402 | 6 | ) -> ApiResult<Option<Body>> { | 403 | 6 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 0 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 6 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 6 | Ok(body) | 410 | 6 | } |
vmm::api::get_response_body::<vmm::api::VmReboot> Line | Count | Source | 397 | 11 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 11 | action: &Action, | 399 | 11 | api_evt: EventFd, | 400 | 11 | api_sender: Sender<ApiRequest>, | 401 | 11 | data: Action::RequestBody, | 402 | 11 | ) -> ApiResult<Option<Body>> { | 403 | 11 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 0 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 11 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 11 | Ok(body) | 410 | 11 | } |
vmm::api::get_response_body::<vmm::api::VmCounters> Line | Count | Source | 397 | 12 | fn get_response_body<Action: ApiAction<ResponseBody = Option<Body>>>( | 398 | 12 | action: &Action, | 399 | 12 | api_evt: EventFd, | 400 | 12 | api_sender: Sender<ApiRequest>, | 401 | 12 | data: Action::RequestBody, | 402 | 12 | ) -> ApiResult<Option<Body>> { | 403 | 12 | let body = match get_response(action, api_evt, api_sender, data)? { | 404 | 12 | ApiResponsePayload::VmAction(response) => response.map(Body::new), | 405 | 0 | ApiResponsePayload::Empty => None, | 406 | 0 | _ => return Err(ApiError::ResponsePayloadType), | 407 | | }; | 408 | | | 409 | 12 | Ok(body) | 410 | 12 | } |
|
411 | | |
412 | | pub trait ApiAction: Send + Sync { |
413 | | type RequestBody: Send + Sync + Sized; |
414 | | type ResponseBody: Send + Sized; |
415 | | |
416 | | fn request(&self, body: Self::RequestBody, response_sender: Sender<ApiResponse>) -> ApiRequest; |
417 | | |
418 | | fn send( |
419 | | &self, |
420 | | api_evt: EventFd, |
421 | | api_sender: Sender<ApiRequest>, |
422 | | data: Self::RequestBody, |
423 | | ) -> ApiResult<Self::ResponseBody>; |
424 | | } |
425 | | |
426 | | pub struct VmAddDevice; |
427 | | |
428 | | impl ApiAction for VmAddDevice { |
429 | | type RequestBody = DeviceConfig; |
430 | | type ResponseBody = Option<Body>; |
431 | | |
432 | 22 | fn request( |
433 | 22 | &self, |
434 | 22 | config: Self::RequestBody, |
435 | 22 | response_sender: Sender<ApiResponse>, |
436 | 22 | ) -> ApiRequest { |
437 | 22 | Box::new(move |vmm| { |
438 | 22 | info!("API request event: VmAddDevice {:?}", config); |
439 | | |
440 | 22 | let response = vmm |
441 | 22 | .vm_add_device(config) |
442 | 22 | .map_err(ApiError::VmAddDevice) |
443 | 22 | .map(ApiResponsePayload::VmAction); |
444 | 22 | |
445 | 22 | response_sender |
446 | 22 | .send(response) |
447 | 22 | .map_err(VmmError::ApiResponseSend)?; |
448 | | |
449 | 22 | Ok(false) |
450 | 22 | }) |
451 | 22 | } |
452 | | |
453 | 22 | fn send( |
454 | 22 | &self, |
455 | 22 | api_evt: EventFd, |
456 | 22 | api_sender: Sender<ApiRequest>, |
457 | 22 | data: Self::RequestBody, |
458 | 22 | ) -> ApiResult<Self::ResponseBody> { |
459 | 22 | get_response_body(self, api_evt, api_sender, data) |
460 | 22 | } |
461 | | } |
462 | | |
463 | | pub struct AddDisk; |
464 | | |
465 | | impl ApiAction for AddDisk { |
466 | | type RequestBody = DiskConfig; |
467 | | type ResponseBody = Option<Body>; |
468 | | |
469 | 27 | fn request( |
470 | 27 | &self, |
471 | 27 | config: Self::RequestBody, |
472 | 27 | response_sender: Sender<ApiResponse>, |
473 | 27 | ) -> ApiRequest { |
474 | 27 | Box::new(move |vmm| { |
475 | 27 | info!("API request event: AddDisk {:?}", config); |
476 | | |
477 | 27 | let response = vmm |
478 | 27 | .vm_add_disk(config) |
479 | 27 | .map_err(ApiError::VmAddDisk) |
480 | 27 | .map(ApiResponsePayload::VmAction); |
481 | 27 | |
482 | 27 | response_sender |
483 | 27 | .send(response) |
484 | 27 | .map_err(VmmError::ApiResponseSend)?; |
485 | | |
486 | 27 | Ok(false) |
487 | 27 | }) |
488 | 27 | } |
489 | | |
490 | 27 | fn send( |
491 | 27 | &self, |
492 | 27 | api_evt: EventFd, |
493 | 27 | api_sender: Sender<ApiRequest>, |
494 | 27 | data: Self::RequestBody, |
495 | 27 | ) -> ApiResult<Self::ResponseBody> { |
496 | 27 | get_response_body(self, api_evt, api_sender, data) |
497 | 27 | } |
498 | | } |
499 | | |
500 | | pub struct VmAddFs; |
501 | | |
502 | | impl ApiAction for VmAddFs { |
503 | | type RequestBody = FsConfig; |
504 | | type ResponseBody = Option<Body>; |
505 | | |
506 | 13 | fn request( |
507 | 13 | &self, |
508 | 13 | config: Self::RequestBody, |
509 | 13 | response_sender: Sender<ApiResponse>, |
510 | 13 | ) -> ApiRequest { |
511 | 13 | Box::new(move |vmm| { |
512 | 13 | info!("API request event: VmAddFs {:?}", config); |
513 | | |
514 | 13 | let response = vmm |
515 | 13 | .vm_add_fs(config) |
516 | 13 | .map_err(ApiError::VmAddFs) |
517 | 13 | .map(ApiResponsePayload::VmAction); |
518 | 13 | |
519 | 13 | response_sender |
520 | 13 | .send(response) |
521 | 13 | .map_err(VmmError::ApiResponseSend)?; |
522 | | |
523 | 13 | Ok(false) |
524 | 13 | }) |
525 | 13 | } |
526 | | |
527 | 13 | fn send( |
528 | 13 | &self, |
529 | 13 | api_evt: EventFd, |
530 | 13 | api_sender: Sender<ApiRequest>, |
531 | 13 | data: Self::RequestBody, |
532 | 13 | ) -> ApiResult<Self::ResponseBody> { |
533 | 13 | get_response_body(self, api_evt, api_sender, data) |
534 | 13 | } |
535 | | } |
536 | | |
537 | | pub struct VmAddPmem; |
538 | | |
539 | | impl ApiAction for VmAddPmem { |
540 | | type RequestBody = PmemConfig; |
541 | | type ResponseBody = Option<Body>; |
542 | | |
543 | 20 | fn request( |
544 | 20 | &self, |
545 | 20 | config: Self::RequestBody, |
546 | 20 | response_sender: Sender<ApiResponse>, |
547 | 20 | ) -> ApiRequest { |
548 | 20 | Box::new(move |vmm| { |
549 | 20 | info!("API request event: VmAddPmem {:?}", config); |
550 | | |
551 | 20 | let response = vmm |
552 | 20 | .vm_add_pmem(config) |
553 | 20 | .map_err(ApiError::VmAddPmem) |
554 | 20 | .map(ApiResponsePayload::VmAction); |
555 | 20 | |
556 | 20 | response_sender |
557 | 20 | .send(response) |
558 | 20 | .map_err(VmmError::ApiResponseSend)?; |
559 | | |
560 | 20 | Ok(false) |
561 | 20 | }) |
562 | 20 | } |
563 | | |
564 | 20 | fn send( |
565 | 20 | &self, |
566 | 20 | api_evt: EventFd, |
567 | 20 | api_sender: Sender<ApiRequest>, |
568 | 20 | data: Self::RequestBody, |
569 | 20 | ) -> ApiResult<Self::ResponseBody> { |
570 | 20 | get_response_body(self, api_evt, api_sender, data) |
571 | 20 | } |
572 | | } |
573 | | |
574 | | pub struct VmAddNet; |
575 | | |
576 | | impl ApiAction for VmAddNet { |
577 | | type RequestBody = NetConfig; |
578 | | type ResponseBody = Option<Body>; |
579 | | |
580 | 19 | fn request( |
581 | 19 | &self, |
582 | 19 | config: Self::RequestBody, |
583 | 19 | response_sender: Sender<ApiResponse>, |
584 | 19 | ) -> ApiRequest { |
585 | 19 | Box::new(move |vmm| { |
586 | 19 | info!("API request event: VmAddNet {:?}", config); |
587 | | |
588 | 19 | let response = vmm |
589 | 19 | .vm_add_net(config) |
590 | 19 | .map_err(ApiError::VmAddNet) |
591 | 19 | .map(ApiResponsePayload::VmAction); |
592 | 19 | |
593 | 19 | response_sender |
594 | 19 | .send(response) |
595 | 19 | .map_err(VmmError::ApiResponseSend)?; |
596 | | |
597 | 19 | Ok(false) |
598 | 19 | }) |
599 | 19 | } |
600 | | |
601 | 19 | fn send( |
602 | 19 | &self, |
603 | 19 | api_evt: EventFd, |
604 | 19 | api_sender: Sender<ApiRequest>, |
605 | 19 | data: Self::RequestBody, |
606 | 19 | ) -> ApiResult<Self::ResponseBody> { |
607 | 19 | get_response_body(self, api_evt, api_sender, data) |
608 | 19 | } |
609 | | } |
610 | | |
611 | | pub struct VmAddVdpa; |
612 | | |
613 | | impl ApiAction for VmAddVdpa { |
614 | | type RequestBody = VdpaConfig; |
615 | | type ResponseBody = Option<Body>; |
616 | | |
617 | 17 | fn request( |
618 | 17 | &self, |
619 | 17 | config: Self::RequestBody, |
620 | 17 | response_sender: Sender<ApiResponse>, |
621 | 17 | ) -> ApiRequest { |
622 | 17 | Box::new(move |vmm| { |
623 | 17 | info!("API request event: VmAddVdpa {:?}", config); |
624 | | |
625 | 17 | let response = vmm |
626 | 17 | .vm_add_vdpa(config) |
627 | 17 | .map_err(ApiError::VmAddVdpa) |
628 | 17 | .map(ApiResponsePayload::VmAction); |
629 | 17 | |
630 | 17 | response_sender |
631 | 17 | .send(response) |
632 | 17 | .map_err(VmmError::ApiResponseSend)?; |
633 | | |
634 | 17 | Ok(false) |
635 | 17 | }) |
636 | 17 | } |
637 | | |
638 | 17 | fn send( |
639 | 17 | &self, |
640 | 17 | api_evt: EventFd, |
641 | 17 | api_sender: Sender<ApiRequest>, |
642 | 17 | data: Self::RequestBody, |
643 | 17 | ) -> ApiResult<Self::ResponseBody> { |
644 | 17 | get_response_body(self, api_evt, api_sender, data) |
645 | 17 | } |
646 | | } |
647 | | |
648 | | pub struct VmAddVsock; |
649 | | |
650 | | impl ApiAction for VmAddVsock { |
651 | | type RequestBody = VsockConfig; |
652 | | type ResponseBody = Option<Body>; |
653 | | |
654 | 0 | fn request( |
655 | 0 | &self, |
656 | 0 | config: Self::RequestBody, |
657 | 0 | response_sender: Sender<ApiResponse>, |
658 | 0 | ) -> ApiRequest { |
659 | 0 | Box::new(move |vmm| { |
660 | 0 | info!("API request event: VmAddVsock {:?}", config); |
661 | | |
662 | 0 | let response = vmm |
663 | 0 | .vm_add_vsock(config) |
664 | 0 | .map_err(ApiError::VmAddVsock) |
665 | 0 | .map(ApiResponsePayload::VmAction); |
666 | 0 |
|
667 | 0 | response_sender |
668 | 0 | .send(response) |
669 | 0 | .map_err(VmmError::ApiResponseSend)?; |
670 | | |
671 | 0 | Ok(false) |
672 | 0 | }) |
673 | 0 | } |
674 | | |
675 | 0 | fn send( |
676 | 0 | &self, |
677 | 0 | api_evt: EventFd, |
678 | 0 | api_sender: Sender<ApiRequest>, |
679 | 0 | data: Self::RequestBody, |
680 | 0 | ) -> ApiResult<Self::ResponseBody> { |
681 | 0 | get_response_body(self, api_evt, api_sender, data) |
682 | 0 | } |
683 | | } |
684 | | |
685 | | pub struct VmAddUserDevice; |
686 | | |
687 | | impl ApiAction for VmAddUserDevice { |
688 | | type RequestBody = UserDeviceConfig; |
689 | | type ResponseBody = Option<Body>; |
690 | | |
691 | 18 | fn request( |
692 | 18 | &self, |
693 | 18 | config: Self::RequestBody, |
694 | 18 | response_sender: Sender<ApiResponse>, |
695 | 18 | ) -> ApiRequest { |
696 | 18 | Box::new(move |vmm| { |
697 | 18 | info!("API request event: VmAddUserDevice {:?}", config); |
698 | | |
699 | 18 | let response = vmm |
700 | 18 | .vm_add_user_device(config) |
701 | 18 | .map_err(ApiError::VmAddUserDevice) |
702 | 18 | .map(ApiResponsePayload::VmAction); |
703 | 18 | |
704 | 18 | response_sender |
705 | 18 | .send(response) |
706 | 18 | .map_err(VmmError::ApiResponseSend)?; |
707 | | |
708 | 18 | Ok(false) |
709 | 18 | }) |
710 | 18 | } |
711 | | |
712 | 18 | fn send( |
713 | 18 | &self, |
714 | 18 | api_evt: EventFd, |
715 | 18 | api_sender: Sender<ApiRequest>, |
716 | 18 | data: Self::RequestBody, |
717 | 18 | ) -> ApiResult<Self::ResponseBody> { |
718 | 18 | get_response_body(self, api_evt, api_sender, data) |
719 | 18 | } |
720 | | } |
721 | | |
722 | | pub struct VmBoot; |
723 | | |
724 | | impl ApiAction for VmBoot { |
725 | | type RequestBody = (); |
726 | | type ResponseBody = Option<Body>; |
727 | | |
728 | 9 | fn request(&self, _: Self::RequestBody, response_sender: Sender<ApiResponse>) -> ApiRequest { |
729 | 9 | Box::new(move |vmm| { |
730 | 9 | info!("API request event: VmBoot"); |
731 | | |
732 | 9 | let response = vmm |
733 | 9 | .vm_boot() |
734 | 9 | .map_err(ApiError::VmBoot) |
735 | 9 | .map(|_| ApiResponsePayload::Empty); |
736 | 9 | |
737 | 9 | response_sender |
738 | 9 | .send(response) |
739 | 9 | .map_err(VmmError::ApiResponseSend)?; |
740 | | |
741 | 9 | Ok(false) |
742 | 9 | }) |
743 | 9 | } |
744 | | |
745 | 9 | fn send( |
746 | 9 | &self, |
747 | 9 | api_evt: EventFd, |
748 | 9 | api_sender: Sender<ApiRequest>, |
749 | 9 | data: Self::RequestBody, |
750 | 9 | ) -> ApiResult<Self::ResponseBody> { |
751 | 9 | get_response_body(self, api_evt, api_sender, data) |
752 | 9 | } |
753 | | } |
754 | | |
755 | | #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] |
756 | | pub struct VmCoredump; |
757 | | |
758 | | #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] |
759 | | impl ApiAction for VmCoredump { |
760 | | type RequestBody = VmCoredumpData; |
761 | | type ResponseBody = Option<Body>; |
762 | | |
763 | 12 | fn request( |
764 | 12 | &self, |
765 | 12 | coredump_data: Self::RequestBody, |
766 | 12 | response_sender: Sender<ApiResponse>, |
767 | 12 | ) -> ApiRequest { |
768 | 12 | Box::new(move |vmm| { |
769 | 12 | info!("API request event: VmCoredump {:?}", coredump_data); |
770 | | |
771 | 12 | let response = vmm |
772 | 12 | .vm_coredump(&coredump_data.destination_url) |
773 | 12 | .map_err(ApiError::VmCoredump) |
774 | 12 | .map(|_| ApiResponsePayload::Empty); |
775 | 12 | |
776 | 12 | response_sender |
777 | 12 | .send(response) |
778 | 12 | .map_err(VmmError::ApiResponseSend)?; |
779 | | |
780 | 12 | Ok(false) |
781 | 12 | }) |
782 | 12 | } |
783 | | |
784 | 12 | fn send( |
785 | 12 | &self, |
786 | 12 | api_evt: EventFd, |
787 | 12 | api_sender: Sender<ApiRequest>, |
788 | 12 | data: Self::RequestBody, |
789 | 12 | ) -> ApiResult<Self::ResponseBody> { |
790 | 12 | get_response_body(self, api_evt, api_sender, data) |
791 | 12 | } |
792 | | } |
793 | | |
794 | | pub struct VmCounters; |
795 | | |
796 | | impl ApiAction for VmCounters { |
797 | | type RequestBody = (); |
798 | | type ResponseBody = Option<Body>; |
799 | | |
800 | 12 | fn request(&self, _: Self::RequestBody, response_sender: Sender<ApiResponse>) -> ApiRequest { |
801 | 12 | Box::new(move |vmm| { |
802 | 12 | info!("API request event: VmCounters"); |
803 | | |
804 | 12 | let response = vmm |
805 | 12 | .vm_counters() |
806 | 12 | .map_err(ApiError::VmInfo) |
807 | 12 | .map(ApiResponsePayload::VmAction); |
808 | 12 | |
809 | 12 | response_sender |
810 | 12 | .send(response) |
811 | 12 | .map_err(VmmError::ApiResponseSend)?; |
812 | | |
813 | 12 | Ok(false) |
814 | 12 | }) |
815 | 12 | } |
816 | | |
817 | 12 | fn send( |
818 | 12 | &self, |
819 | 12 | api_evt: EventFd, |
820 | 12 | api_sender: Sender<ApiRequest>, |
821 | 12 | data: Self::RequestBody, |
822 | 12 | ) -> ApiResult<Self::ResponseBody> { |
823 | 12 | get_response_body(self, api_evt, api_sender, data) |
824 | 12 | } |
825 | | } |
826 | | |
827 | | pub struct VmCreate; |
828 | | |
829 | | impl ApiAction for VmCreate { |
830 | | type RequestBody = Arc<Mutex<VmConfig>>; |
831 | | type ResponseBody = (); |
832 | | |
833 | 22 | fn request( |
834 | 22 | &self, |
835 | 22 | config: Self::RequestBody, |
836 | 22 | response_sender: Sender<ApiResponse>, |
837 | 22 | ) -> ApiRequest { |
838 | 22 | Box::new(move |vmm| { |
839 | 22 | info!("API request event: VmCreate {:?}", config); |
840 | | |
841 | 22 | let response = vmm |
842 | 22 | .vm_create(config) |
843 | 22 | .map_err(ApiError::VmCreate) |
844 | 22 | .map(|_| ApiResponsePayload::Empty); |
845 | 22 | |
846 | 22 | response_sender |
847 | 22 | .send(response) |
848 | 22 | .map_err(VmmError::ApiResponseSend)?; |
849 | | |
850 | 22 | Ok(false) |
851 | 22 | }) |
852 | 22 | } |
853 | | |
854 | 22 | fn send( |
855 | 22 | &self, |
856 | 22 | api_evt: EventFd, |
857 | 22 | api_sender: Sender<ApiRequest>, |
858 | 22 | data: Self::RequestBody, |
859 | 22 | ) -> ApiResult<()> { |
860 | 22 | get_response(self, api_evt, api_sender, data)?; |
861 | | |
862 | 22 | Ok(()) |
863 | 22 | } |
864 | | } |
865 | | |
866 | | pub struct VmDelete; |
867 | | |
868 | | impl ApiAction for VmDelete { |
869 | | type RequestBody = (); |
870 | | type ResponseBody = Option<Body>; |
871 | | |
872 | 6 | fn request(&self, _: Self::RequestBody, response_sender: Sender<ApiResponse>) -> ApiRequest { |
873 | 6 | Box::new(move |vmm| { |
874 | 6 | info!("API request event: VmDelete"); |
875 | | |
876 | 6 | let response = vmm |
877 | 6 | .vm_delete() |
878 | 6 | .map_err(ApiError::VmDelete) |
879 | 6 | .map(|_| ApiResponsePayload::Empty); |
880 | 6 | |
881 | 6 | response_sender |
882 | 6 | .send(response) |
883 | 6 | .map_err(VmmError::ApiResponseSend)?; |
884 | | |
885 | 6 | Ok(false) |
886 | 6 | }) |
887 | 6 | } |
888 | | |
889 | 6 | fn send( |
890 | 6 | &self, |
891 | 6 | api_evt: EventFd, |
892 | 6 | api_sender: Sender<ApiRequest>, |
893 | 6 | data: Self::RequestBody, |
894 | 6 | ) -> ApiResult<Self::ResponseBody> { |
895 | 6 | get_response_body(self, api_evt, api_sender, data) |
896 | 6 | } |
897 | | } |
898 | | |
899 | | pub struct VmInfo; |
900 | | |
901 | | impl ApiAction for VmInfo { |
902 | | type RequestBody = (); |
903 | | type ResponseBody = VmInfoResponse; |
904 | | |
905 | 39 | fn request(&self, _: Self::RequestBody, response_sender: Sender<ApiResponse>) -> ApiRequest { |
906 | 39 | Box::new(move |vmm| { |
907 | 39 | info!("API request event: VmInfo"); |
908 | | |
909 | 39 | let response = vmm |
910 | 39 | .vm_info() |
911 | 39 | .map_err(ApiError::VmInfo) |
912 | 39 | .map(ApiResponsePayload::VmInfo); |
913 | 39 | |
914 | 39 | response_sender |
915 | 39 | .send(response) |
916 | 39 | .map_err(VmmError::ApiResponseSend)?; |
917 | | |
918 | 39 | Ok(false) |
919 | 39 | }) |
920 | 39 | } |
921 | | |
922 | 39 | fn send( |
923 | 39 | &self, |
924 | 39 | api_evt: EventFd, |
925 | 39 | api_sender: Sender<ApiRequest>, |
926 | 39 | data: (), |
927 | 39 | ) -> ApiResult<VmInfoResponse> { |
928 | 39 | let vm_info = get_response(self, api_evt, api_sender, data)?; |
929 | | |
930 | 39 | match vm_info { |
931 | 39 | ApiResponsePayload::VmInfo(info) => Ok(info), |
932 | 0 | _ => Err(ApiError::ResponsePayloadType), |
933 | | } |
934 | 39 | } |
935 | | } |
936 | | |
937 | | pub struct VmPause; |
938 | | |
939 | | impl ApiAction for VmPause { |
940 | | type RequestBody = (); |
941 | | type ResponseBody = Option<Body>; |
942 | | |
943 | 10 | fn request(&self, _: Self::RequestBody, response_sender: Sender<ApiResponse>) -> ApiRequest { |
944 | 10 | Box::new(move |vmm| { |
945 | 10 | info!("API request event: VmPause"); |
946 | | |
947 | 10 | let response = vmm |
948 | 10 | .vm_pause() |
949 | 10 | .map_err(ApiError::VmPause) |
950 | 10 | .map(|_| ApiResponsePayload::Empty); |
951 | 10 | |
952 | 10 | response_sender |
953 | 10 | .send(response) |
954 | 10 | .map_err(VmmError::ApiResponseSend)?; |
955 | | |
956 | 10 | Ok(false) |
957 | 10 | }) |
958 | 10 | } |
959 | | |
960 | 10 | fn send( |
961 | 10 | &self, |
962 | 10 | api_evt: EventFd, |
963 | 10 | api_sender: Sender<ApiRequest>, |
964 | 10 | data: Self::RequestBody, |
965 | 10 | ) -> ApiResult<Self::ResponseBody> { |
966 | 10 | get_response_body(self, api_evt, api_sender, data) |
967 | 10 | } |
968 | | } |
969 | | |
970 | | pub struct VmPowerButton; |
971 | | |
972 | | impl ApiAction for VmPowerButton { |
973 | | type RequestBody = (); |
974 | | type ResponseBody = Option<Body>; |
975 | | |
976 | 33 | fn request(&self, _: Self::RequestBody, response_sender: Sender<ApiResponse>) -> ApiRequest { |
977 | 33 | Box::new(move |vmm| { |
978 | 33 | info!("API request event: VmPowerButton"); |
979 | | |
980 | 33 | let response = vmm |
981 | 33 | .vm_power_button() |
982 | 33 | .map_err(ApiError::VmPowerButton) |
983 | 33 | .map(|_| ApiResponsePayload::Empty); |
984 | 33 | |
985 | 33 | response_sender |
986 | 33 | .send(response) |
987 | 33 | .map_err(VmmError::ApiResponseSend)?; |
988 | | |
989 | 33 | Ok(false) |
990 | 33 | }) |
991 | 33 | } |
992 | | |
993 | 33 | fn send( |
994 | 33 | &self, |
995 | 33 | api_evt: EventFd, |
996 | 33 | api_sender: Sender<ApiRequest>, |
997 | 33 | data: Self::RequestBody, |
998 | 33 | ) -> ApiResult<Self::ResponseBody> { |
999 | 33 | get_response_body(self, api_evt, api_sender, data) |
1000 | 33 | } |
1001 | | } |
1002 | | |
1003 | | pub struct VmReboot; |
1004 | | |
1005 | | impl ApiAction for VmReboot { |
1006 | | type RequestBody = (); |
1007 | | type ResponseBody = Option<Body>; |
1008 | | |
1009 | 11 | fn request(&self, _: Self::RequestBody, response_sender: Sender<ApiResponse>) -> ApiRequest { |
1010 | 11 | Box::new(move |vmm| { |
1011 | 11 | info!("API request event: VmReboot"); |
1012 | | |
1013 | 11 | let response = vmm |
1014 | 11 | .vm_reboot() |
1015 | 11 | .map_err(ApiError::VmReboot) |
1016 | 11 | .map(|_| ApiResponsePayload::Empty); |
1017 | 11 | |
1018 | 11 | response_sender |
1019 | 11 | .send(response) |
1020 | 11 | .map_err(VmmError::ApiResponseSend)?; |
1021 | | |
1022 | 11 | Ok(false) |
1023 | 11 | }) |
1024 | 11 | } |
1025 | | |
1026 | 11 | fn send( |
1027 | 11 | &self, |
1028 | 11 | api_evt: EventFd, |
1029 | 11 | api_sender: Sender<ApiRequest>, |
1030 | 11 | data: Self::RequestBody, |
1031 | 11 | ) -> ApiResult<Self::ResponseBody> { |
1032 | 11 | get_response_body(self, api_evt, api_sender, data) |
1033 | 11 | } |
1034 | | } |
1035 | | |
1036 | | pub struct VmReceiveMigration; |
1037 | | |
1038 | | impl ApiAction for VmReceiveMigration { |
1039 | | type RequestBody = VmReceiveMigrationData; |
1040 | | type ResponseBody = Option<Body>; |
1041 | | |
1042 | 21 | fn request(&self, data: Self::RequestBody, response_sender: Sender<ApiResponse>) -> ApiRequest { |
1043 | 21 | Box::new(move |vmm| { |
1044 | 21 | info!("API request event: VmReceiveMigration {:?}", data); |
1045 | | |
1046 | 21 | let response = vmm |
1047 | 21 | .vm_receive_migration(data) |
1048 | 21 | .map_err(ApiError::VmReceiveMigration) |
1049 | 21 | .map(|_| ApiResponsePayload::Empty); |
1050 | 21 | |
1051 | 21 | response_sender |
1052 | 21 | .send(response) |
1053 | 21 | .map_err(VmmError::ApiResponseSend)?; |
1054 | | |
1055 | 21 | Ok(false) |
1056 | 21 | }) |
1057 | 21 | } |
1058 | | |
1059 | 21 | fn send( |
1060 | 21 | &self, |
1061 | 21 | api_evt: EventFd, |
1062 | 21 | api_sender: Sender<ApiRequest>, |
1063 | 21 | data: Self::RequestBody, |
1064 | 21 | ) -> ApiResult<Self::ResponseBody> { |
1065 | 21 | get_response_body(self, api_evt, api_sender, data) |
1066 | 21 | } |
1067 | | } |
1068 | | |
1069 | | pub struct VmRemoveDevice; |
1070 | | |
1071 | | impl ApiAction for VmRemoveDevice { |
1072 | | type RequestBody = VmRemoveDeviceData; |
1073 | | type ResponseBody = Option<Body>; |
1074 | | |
1075 | 15 | fn request( |
1076 | 15 | &self, |
1077 | 15 | remove_device_data: Self::RequestBody, |
1078 | 15 | response_sender: Sender<ApiResponse>, |
1079 | 15 | ) -> ApiRequest { |
1080 | 15 | Box::new(move |vmm| { |
1081 | 15 | info!("API request event: VmRemoveDevice {:?}", remove_device_data); |
1082 | | |
1083 | 15 | let response = vmm |
1084 | 15 | .vm_remove_device(remove_device_data.id) |
1085 | 15 | .map_err(ApiError::VmRemoveDevice) |
1086 | 15 | .map(|_| ApiResponsePayload::Empty); |
1087 | 15 | |
1088 | 15 | response_sender |
1089 | 15 | .send(response) |
1090 | 15 | .map_err(VmmError::ApiResponseSend)?; |
1091 | | |
1092 | 15 | Ok(false) |
1093 | 15 | }) |
1094 | 15 | } |
1095 | | |
1096 | 15 | fn send( |
1097 | 15 | &self, |
1098 | 15 | api_evt: EventFd, |
1099 | 15 | api_sender: Sender<ApiRequest>, |
1100 | 15 | data: Self::RequestBody, |
1101 | 15 | ) -> ApiResult<Self::ResponseBody> { |
1102 | 15 | get_response_body(self, api_evt, api_sender, data) |
1103 | 15 | } |
1104 | | } |
1105 | | |
1106 | | pub struct VmResize; |
1107 | | |
1108 | | impl ApiAction for VmResize { |
1109 | | type RequestBody = VmResizeData; |
1110 | | type ResponseBody = Option<Body>; |
1111 | | |
1112 | 6 | fn request( |
1113 | 6 | &self, |
1114 | 6 | resize_data: Self::RequestBody, |
1115 | 6 | response_sender: Sender<ApiResponse>, |
1116 | 6 | ) -> ApiRequest { |
1117 | 6 | Box::new(move |vmm| { |
1118 | 6 | info!("API request event: VmResize {:?}", resize_data); |
1119 | | |
1120 | 6 | let response = vmm |
1121 | 6 | .vm_resize( |
1122 | 6 | resize_data.desired_vcpus, |
1123 | 6 | resize_data.desired_ram, |
1124 | 6 | resize_data.desired_balloon, |
1125 | 6 | ) |
1126 | 6 | .map_err(ApiError::VmResize) |
1127 | 6 | .map(|_| ApiResponsePayload::Empty); |
1128 | 6 | |
1129 | 6 | response_sender |
1130 | 6 | .send(response) |
1131 | 6 | .map_err(VmmError::ApiResponseSend)?; |
1132 | | |
1133 | 6 | Ok(false) |
1134 | 6 | }) |
1135 | 6 | } |
1136 | | |
1137 | 6 | fn send( |
1138 | 6 | &self, |
1139 | 6 | api_evt: EventFd, |
1140 | 6 | api_sender: Sender<ApiRequest>, |
1141 | 6 | data: Self::RequestBody, |
1142 | 6 | ) -> ApiResult<Self::ResponseBody> { |
1143 | 6 | get_response_body(self, api_evt, api_sender, data) |
1144 | 6 | } |
1145 | | } |
1146 | | |
1147 | | pub struct VmResizeZone; |
1148 | | |
1149 | | impl ApiAction for VmResizeZone { |
1150 | | type RequestBody = VmResizeZoneData; |
1151 | | type ResponseBody = Option<Body>; |
1152 | | |
1153 | 10 | fn request( |
1154 | 10 | &self, |
1155 | 10 | resize_zone_data: Self::RequestBody, |
1156 | 10 | response_sender: Sender<ApiResponse>, |
1157 | 10 | ) -> ApiRequest { |
1158 | 10 | Box::new(move |vmm| { |
1159 | 10 | info!("API request event: VmResizeZone {:?}", resize_zone_data); |
1160 | | |
1161 | 10 | let response = vmm |
1162 | 10 | .vm_resize_zone(resize_zone_data.id, resize_zone_data.desired_ram) |
1163 | 10 | .map_err(ApiError::VmResizeZone) |
1164 | 10 | .map(|_| ApiResponsePayload::Empty); |
1165 | 10 | |
1166 | 10 | response_sender |
1167 | 10 | .send(response) |
1168 | 10 | .map_err(VmmError::ApiResponseSend)?; |
1169 | | |
1170 | 10 | Ok(false) |
1171 | 10 | }) |
1172 | 10 | } |
1173 | | |
1174 | 10 | fn send( |
1175 | 10 | &self, |
1176 | 10 | api_evt: EventFd, |
1177 | 10 | api_sender: Sender<ApiRequest>, |
1178 | 10 | data: Self::RequestBody, |
1179 | 10 | ) -> ApiResult<Self::ResponseBody> { |
1180 | 10 | get_response_body(self, api_evt, api_sender, data) |
1181 | 10 | } |
1182 | | } |
1183 | | |
1184 | | pub struct VmRestore; |
1185 | | |
1186 | | impl ApiAction for VmRestore { |
1187 | | type RequestBody = RestoreConfig; |
1188 | | type ResponseBody = Option<Body>; |
1189 | | |
1190 | 18 | fn request( |
1191 | 18 | &self, |
1192 | 18 | config: Self::RequestBody, |
1193 | 18 | response_sender: Sender<ApiResponse>, |
1194 | 18 | ) -> ApiRequest { |
1195 | 18 | Box::new(move |vmm| { |
1196 | 18 | info!("API request event: VmRestore {:?}", config); |
1197 | | |
1198 | 18 | let response = vmm |
1199 | 18 | .vm_restore(config) |
1200 | 18 | .map_err(ApiError::VmRestore) |
1201 | 18 | .map(|_| ApiResponsePayload::Empty); |
1202 | 18 | |
1203 | 18 | response_sender |
1204 | 18 | .send(response) |
1205 | 18 | .map_err(VmmError::ApiResponseSend)?; |
1206 | | |
1207 | 18 | Ok(false) |
1208 | 18 | }) |
1209 | 18 | } |
1210 | | |
1211 | 18 | fn send( |
1212 | 18 | &self, |
1213 | 18 | api_evt: EventFd, |
1214 | 18 | api_sender: Sender<ApiRequest>, |
1215 | 18 | data: Self::RequestBody, |
1216 | 18 | ) -> ApiResult<Self::ResponseBody> { |
1217 | 18 | get_response_body(self, api_evt, api_sender, data) |
1218 | 18 | } |
1219 | | } |
1220 | | |
1221 | | pub struct VmResume; |
1222 | | |
1223 | | impl ApiAction for VmResume { |
1224 | | type RequestBody = (); |
1225 | | type ResponseBody = Option<Body>; |
1226 | | |
1227 | 7 | fn request(&self, _: Self::RequestBody, response_sender: Sender<ApiResponse>) -> ApiRequest { |
1228 | 7 | Box::new(move |vmm| { |
1229 | 7 | info!("API request event: VmResume"); |
1230 | | |
1231 | 7 | let response = vmm |
1232 | 7 | .vm_resume() |
1233 | 7 | .map_err(ApiError::VmResume) |
1234 | 7 | .map(|_| ApiResponsePayload::Empty); |
1235 | 7 | |
1236 | 7 | response_sender |
1237 | 7 | .send(response) |
1238 | 7 | .map_err(VmmError::ApiResponseSend)?; |
1239 | | |
1240 | 7 | Ok(false) |
1241 | 7 | }) |
1242 | 7 | } |
1243 | | |
1244 | 7 | fn send( |
1245 | 7 | &self, |
1246 | 7 | api_evt: EventFd, |
1247 | 7 | api_sender: Sender<ApiRequest>, |
1248 | 7 | data: Self::RequestBody, |
1249 | 7 | ) -> ApiResult<Self::ResponseBody> { |
1250 | 7 | get_response_body(self, api_evt, api_sender, data) |
1251 | 7 | } |
1252 | | } |
1253 | | |
1254 | | pub struct VmSendMigration; |
1255 | | |
1256 | | impl ApiAction for VmSendMigration { |
1257 | | type RequestBody = VmSendMigrationData; |
1258 | | type ResponseBody = Option<Body>; |
1259 | | |
1260 | 16 | fn request(&self, data: Self::RequestBody, response_sender: Sender<ApiResponse>) -> ApiRequest { |
1261 | 16 | Box::new(move |vmm| { |
1262 | 16 | info!("API request event: VmSendMigration {:?}", data); |
1263 | | |
1264 | 16 | let response = vmm |
1265 | 16 | .vm_send_migration(data) |
1266 | 16 | .map_err(ApiError::VmSendMigration) |
1267 | 16 | .map(|_| ApiResponsePayload::Empty); |
1268 | 16 | |
1269 | 16 | response_sender |
1270 | 16 | .send(response) |
1271 | 16 | .map_err(VmmError::ApiResponseSend)?; |
1272 | | |
1273 | 16 | Ok(false) |
1274 | 16 | }) |
1275 | 16 | } |
1276 | | |
1277 | 16 | fn send( |
1278 | 16 | &self, |
1279 | 16 | api_evt: EventFd, |
1280 | 16 | api_sender: Sender<ApiRequest>, |
1281 | 16 | data: Self::RequestBody, |
1282 | 16 | ) -> ApiResult<Self::ResponseBody> { |
1283 | 16 | get_response_body(self, api_evt, api_sender, data) |
1284 | 16 | } |
1285 | | } |
1286 | | |
1287 | | pub struct VmShutdown; |
1288 | | |
1289 | | impl ApiAction for VmShutdown { |
1290 | | type RequestBody = (); |
1291 | | type ResponseBody = Option<Body>; |
1292 | | |
1293 | 8 | fn request( |
1294 | 8 | &self, |
1295 | 8 | config: Self::RequestBody, |
1296 | 8 | response_sender: Sender<ApiResponse>, |
1297 | 8 | ) -> ApiRequest { |
1298 | 8 | Box::new(move |vmm| { |
1299 | 8 | info!("API request event: VmShutdown {:?}", config); |
1300 | | |
1301 | 8 | let response = vmm |
1302 | 8 | .vm_shutdown() |
1303 | 8 | .map_err(ApiError::VmShutdown) |
1304 | 8 | .map(|_| ApiResponsePayload::Empty); |
1305 | 8 | |
1306 | 8 | response_sender |
1307 | 8 | .send(response) |
1308 | 8 | .map_err(VmmError::ApiResponseSend)?; |
1309 | | |
1310 | 8 | Ok(false) |
1311 | 8 | }) |
1312 | 8 | } |
1313 | | |
1314 | 8 | fn send( |
1315 | 8 | &self, |
1316 | 8 | api_evt: EventFd, |
1317 | 8 | api_sender: Sender<ApiRequest>, |
1318 | 8 | data: Self::RequestBody, |
1319 | 8 | ) -> ApiResult<Self::ResponseBody> { |
1320 | 8 | get_response_body(self, api_evt, api_sender, data) |
1321 | 8 | } |
1322 | | } |
1323 | | |
1324 | | pub struct VmSnapshot; |
1325 | | |
1326 | | impl ApiAction for VmSnapshot { |
1327 | | type RequestBody = VmSnapshotConfig; |
1328 | | type ResponseBody = Option<Body>; |
1329 | | |
1330 | 14 | fn request( |
1331 | 14 | &self, |
1332 | 14 | config: Self::RequestBody, |
1333 | 14 | response_sender: Sender<ApiResponse>, |
1334 | 14 | ) -> ApiRequest { |
1335 | 14 | Box::new(move |vmm| { |
1336 | 14 | info!("API request event: VmSnapshot {:?}", config); |
1337 | | |
1338 | 14 | let response = vmm |
1339 | 14 | .vm_snapshot(&config.destination_url) |
1340 | 14 | .map_err(ApiError::VmSnapshot) |
1341 | 14 | .map(|_| ApiResponsePayload::Empty); |
1342 | 14 | |
1343 | 14 | response_sender |
1344 | 14 | .send(response) |
1345 | 14 | .map_err(VmmError::ApiResponseSend)?; |
1346 | | |
1347 | 14 | Ok(false) |
1348 | 14 | }) |
1349 | 14 | } |
1350 | | |
1351 | 14 | fn send( |
1352 | 14 | &self, |
1353 | 14 | api_evt: EventFd, |
1354 | 14 | api_sender: Sender<ApiRequest>, |
1355 | 14 | data: Self::RequestBody, |
1356 | 14 | ) -> ApiResult<Self::ResponseBody> { |
1357 | 14 | get_response_body(self, api_evt, api_sender, data) |
1358 | 14 | } |
1359 | | } |
1360 | | |
1361 | | pub struct VmmPing; |
1362 | | |
1363 | | impl ApiAction for VmmPing { |
1364 | | type RequestBody = (); |
1365 | | type ResponseBody = VmmPingResponse; |
1366 | | |
1367 | 9 | fn request(&self, _: Self::RequestBody, response_sender: Sender<ApiResponse>) -> ApiRequest { |
1368 | 9 | Box::new(move |vmm| { |
1369 | 9 | info!("API request event: VmmPing"); |
1370 | | |
1371 | 9 | let response = ApiResponsePayload::VmmPing(vmm.vmm_ping()); |
1372 | 9 | |
1373 | 9 | response_sender |
1374 | 9 | .send(Ok(response)) |
1375 | 9 | .map_err(VmmError::ApiResponseSend)?; |
1376 | | |
1377 | 9 | Ok(false) |
1378 | 9 | }) |
1379 | 9 | } |
1380 | | |
1381 | 9 | fn send( |
1382 | 9 | &self, |
1383 | 9 | api_evt: EventFd, |
1384 | 9 | api_sender: Sender<ApiRequest>, |
1385 | 9 | data: (), |
1386 | 9 | ) -> ApiResult<VmmPingResponse> { |
1387 | 9 | let vmm_pong = get_response(self, api_evt, api_sender, data)?; |
1388 | | |
1389 | 9 | match vmm_pong { |
1390 | 9 | ApiResponsePayload::VmmPing(pong) => Ok(pong), |
1391 | 0 | _ => Err(ApiError::ResponsePayloadType), |
1392 | | } |
1393 | 9 | } |
1394 | | } |
1395 | | |
1396 | | pub struct VmmShutdown; |
1397 | | |
1398 | | impl ApiAction for VmmShutdown { |
1399 | | type RequestBody = (); |
1400 | | type ResponseBody = (); |
1401 | | |
1402 | 5 | fn request(&self, _: Self::RequestBody, response_sender: Sender<ApiResponse>) -> ApiRequest { |
1403 | 5 | Box::new(move |vmm| { |
1404 | 5 | info!("API request event: VmmShutdown"); |
1405 | | |
1406 | 5 | let response = vmm |
1407 | 5 | .vmm_shutdown() |
1408 | 5 | .map_err(ApiError::VmmShutdown) |
1409 | 5 | .map(|_| ApiResponsePayload::Empty); |
1410 | 5 | |
1411 | 5 | response_sender |
1412 | 5 | .send(response) |
1413 | 5 | .map_err(VmmError::ApiResponseSend)?; |
1414 | | |
1415 | 5 | Ok(true) |
1416 | 5 | }) |
1417 | 5 | } |
1418 | | |
1419 | 5 | fn send(&self, api_evt: EventFd, api_sender: Sender<ApiRequest>, data: ()) -> ApiResult<()> { |
1420 | 5 | get_response(self, api_evt, api_sender, data)?; |
1421 | | |
1422 | 5 | Ok(()) |
1423 | 5 | } |
1424 | | } |
1425 | | |
1426 | | pub struct VmNmi; |
1427 | | |
1428 | | impl ApiAction for VmNmi { |
1429 | | type RequestBody = (); |
1430 | | type ResponseBody = Option<Body>; |
1431 | | |
1432 | 11 | fn request(&self, _: Self::RequestBody, response_sender: Sender<ApiResponse>) -> ApiRequest { |
1433 | 11 | Box::new(move |vmm| { |
1434 | 11 | info!("API request event: VmNmi"); |
1435 | | |
1436 | 11 | let response = vmm |
1437 | 11 | .vm_nmi() |
1438 | 11 | .map_err(ApiError::VmNmi) |
1439 | 11 | .map(|_| ApiResponsePayload::Empty); |
1440 | 11 | |
1441 | 11 | response_sender |
1442 | 11 | .send(response) |
1443 | 11 | .map_err(VmmError::ApiResponseSend)?; |
1444 | | |
1445 | 11 | Ok(false) |
1446 | 11 | }) |
1447 | 11 | } |
1448 | | |
1449 | 11 | fn send( |
1450 | 11 | &self, |
1451 | 11 | api_evt: EventFd, |
1452 | 11 | api_sender: Sender<ApiRequest>, |
1453 | 11 | data: Self::RequestBody, |
1454 | 11 | ) -> ApiResult<Self::ResponseBody> { |
1455 | 11 | get_response_body(self, api_evt, api_sender, data) |
1456 | 11 | } |
1457 | | } |