Coverage Report

Created: 2024-05-21 06:19

/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
}