Skip to content

Commit 6ecd60a

Browse files
acatangiualxiord
authored andcommitted
vmm: std::convert::From<T> for VmmActionError
Decorate VmmActionErrors with the correct ErrorKind. Signed-off-by: Adrian Catangiu <[email protected]>
1 parent 7c40663 commit 6ecd60a

File tree

2 files changed

+54
-50
lines changed

2 files changed

+54
-50
lines changed

vmm/src/lib.rs

Lines changed: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ use kernel::loader as kernel_loader;
7474
use logger::error::LoggerError;
7575
use logger::{AppInfo, Level, LogOption, Metric, LOGGER, METRICS};
7676
use memory_model::{GuestAddress, GuestMemory};
77+
use net_util::TapError;
7778
#[cfg(target_arch = "aarch64")]
7879
use serde_json::Value;
7980
pub use sigsys_handler::setup_sigsys_handler;
@@ -230,6 +231,46 @@ impl std::convert::From<DriveError> for VmmActionError {
230231
}
231232
}
232233

234+
// It's convenient to turn VmConfigErrors into VmmActionErrors directly.
235+
impl std::convert::From<VmConfigError> for VmmActionError {
236+
fn from(e: VmConfigError) -> Self {
237+
VmmActionError::MachineConfig(
238+
match e {
239+
// User errors.
240+
VmConfigError::InvalidVcpuCount
241+
| VmConfigError::InvalidMemorySize
242+
| VmConfigError::UpdateNotAllowedPostBoot => ErrorKind::User,
243+
},
244+
e,
245+
)
246+
}
247+
}
248+
249+
// It's convenient to turn NetworkInterfaceErrors into VmmActionErrors directly.
250+
impl std::convert::From<NetworkInterfaceError> for VmmActionError {
251+
fn from(e: NetworkInterfaceError) -> Self {
252+
let kind = match e {
253+
// User errors.
254+
NetworkInterfaceError::GuestMacAddressInUse(_)
255+
| NetworkInterfaceError::HostDeviceNameInUse(_)
256+
| NetworkInterfaceError::DeviceIdNotFound
257+
| NetworkInterfaceError::UpdateNotAllowedPostBoot => ErrorKind::User,
258+
// Internal errors.
259+
NetworkInterfaceError::EpollHandlerNotFound(_)
260+
| NetworkInterfaceError::RateLimiterUpdateFailed(_) => ErrorKind::Internal,
261+
NetworkInterfaceError::OpenTap(ref te) => match te {
262+
// User errors.
263+
TapError::OpenTun(_) | TapError::CreateTap(_) | TapError::InvalidIfname => {
264+
ErrorKind::User
265+
}
266+
// Internal errors.
267+
TapError::IoctlError(_) | TapError::NetUtil(_) => ErrorKind::Internal,
268+
},
269+
};
270+
VmmActionError::NetworkConfig(kind, e)
271+
}
272+
}
273+
233274
// It's convenient to turn StartMicrovmErrors into VmmActionErrors directly.
234275
impl std::convert::From<StartMicrovmError> for VmmActionError {
235276
fn from(e: StartMicrovmError) -> Self {
@@ -1504,29 +1545,20 @@ impl Vmm {
15041545
machine_config: VmConfig,
15051546
) -> std::result::Result<VmmData, VmmActionError> {
15061547
if self.is_instance_initialized() {
1507-
return Err(VmmActionError::MachineConfig(
1508-
ErrorKind::User,
1509-
VmConfigError::UpdateNotAllowedPostBoot,
1510-
));
1548+
Err(VmConfigError::UpdateNotAllowedPostBoot)?;
15111549
}
15121550

15131551
if let Some(vcpu_count_value) = machine_config.vcpu_count {
15141552
// Check that the vcpu_count value is >=1.
15151553
if vcpu_count_value == 0 {
1516-
return Err(VmmActionError::MachineConfig(
1517-
ErrorKind::User,
1518-
VmConfigError::InvalidVcpuCount,
1519-
));
1554+
Err(VmConfigError::InvalidVcpuCount)?;
15201555
}
15211556
}
15221557

15231558
if let Some(mem_size_mib_value) = machine_config.mem_size_mib {
15241559
// TODO: add other memory checks
15251560
if mem_size_mib_value == 0 {
1526-
return Err(VmmActionError::MachineConfig(
1527-
ErrorKind::User,
1528-
VmConfigError::InvalidMemorySize,
1529-
));
1561+
Err(VmConfigError::InvalidMemorySize)?;
15301562
}
15311563
}
15321564

@@ -1543,10 +1575,7 @@ impl Vmm {
15431575
// If hyperthreading is enabled or is to be enabled in this call
15441576
// only allow vcpu count to be 1 or even.
15451577
if ht_enabled && vcpu_count_value > 1 && vcpu_count_value % 2 == 1 {
1546-
return Err(VmmActionError::MachineConfig(
1547-
ErrorKind::User,
1548-
VmConfigError::InvalidVcpuCount,
1549-
));
1578+
Err(VmConfigError::InvalidVcpuCount)?;
15501579
}
15511580

15521581
// Update all the fields that have a new value.
@@ -1569,10 +1598,7 @@ impl Vmm {
15691598
body: NetworkInterfaceConfig,
15701599
) -> std::result::Result<VmmData, VmmActionError> {
15711600
if self.is_instance_initialized() {
1572-
return Err(VmmActionError::NetworkConfig(
1573-
ErrorKind::User,
1574-
NetworkInterfaceError::UpdateNotAllowedPostBoot,
1575-
));
1601+
Err(NetworkInterfaceError::UpdateNotAllowedPostBoot)?;
15761602
}
15771603
self.network_interface_configs
15781604
.insert(body)
@@ -1591,10 +1617,7 @@ impl Vmm {
15911617
.network_interface_configs
15921618
.iter_mut()
15931619
.find(|&&mut ref c| c.iface_id == new_cfg.iface_id)
1594-
.ok_or(VmmActionError::NetworkConfig(
1595-
ErrorKind::User,
1596-
NetworkInterfaceError::DeviceIdNotFound,
1597-
))?;
1620+
.ok_or(NetworkInterfaceError::DeviceIdNotFound)?;
15981621

15991622
// Check if we need to update the RX rate limiter.
16001623
if let Some(new_rlim_cfg) = new_cfg.rx_rate_limiter {
@@ -1624,19 +1647,15 @@ impl Vmm {
16241647
// If we got to here, the VM is running. We need to update the live device.
16251648
//
16261649

1627-
let handler_id = *self.net_handler_id_map.get(&new_cfg.iface_id).ok_or(
1628-
VmmActionError::NetworkConfig(ErrorKind::User, NetworkInterfaceError::DeviceIdNotFound),
1629-
)?;
1650+
let handler_id = *self
1651+
.net_handler_id_map
1652+
.get(&new_cfg.iface_id)
1653+
.ok_or(NetworkInterfaceError::DeviceIdNotFound)?;
16301654

16311655
let handler = self
16321656
.epoll_context
16331657
.get_device_handler(handler_id)
1634-
.map_err(|e| {
1635-
VmmActionError::NetworkConfig(
1636-
ErrorKind::User,
1637-
NetworkInterfaceError::EpollHandlerNotFound(e),
1638-
)
1639-
})?;
1658+
.map_err(NetworkInterfaceError::EpollHandlerNotFound)?;
16401659

16411660
// Hack because velocity (my new favorite phrase): fake an epoll event, because we can only
16421661
// contact a live device via its `EpollHandler`.
@@ -1663,12 +1682,7 @@ impl Vmm {
16631682
.unwrap_or(None),
16641683
},
16651684
)
1666-
.map_err(|e| {
1667-
VmmActionError::NetworkConfig(
1668-
ErrorKind::Internal,
1669-
NetworkInterfaceError::RateLimiterUpdateFailed(e),
1670-
)
1671-
})?;
1685+
.map_err(NetworkInterfaceError::RateLimiterUpdateFailed)?;
16721686

16731687
Ok(VmmData::Empty)
16741688
}

vmm/src/vmm_config/net.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
use std::fmt::{Display, Formatter, Result};
5-
use std::io;
65
use std::result;
76

87
use super::super::Error as VmmInternalError;
@@ -91,8 +90,6 @@ pub enum NetworkInterfaceError {
9190
DeviceIdNotFound,
9291
/// Cannot open/create tap device.
9392
OpenTap(TapError),
94-
/// Downstream error from a RateLimiter.
95-
RateLimiterError(io::Error),
9693
/// Error updating (patching) the rate limiters.
9794
RateLimiterUpdateFailed(devices::Error),
9895
/// The update is not allowed after booting the microvm.
@@ -130,9 +127,6 @@ impl Display for NetworkInterfaceError {
130127
tap_err
131128
)
132129
}
133-
RateLimiterError(ref e) => {
134-
write!(f, "Unable to create rate limiter: {}", e.to_string())
135-
}
136130
RateLimiterUpdateFailed(ref e) => write!(f, "Unable to update rate limiter: {:?}", e),
137131
UpdateNotAllowedPostBoot => {
138132
write!(f, "The update operation is not allowed after boot.",)
@@ -285,6 +279,7 @@ impl NetworkInterfaceConfigs {
285279

286280
#[cfg(test)]
287281
mod tests {
282+
use std::io;
288283
use std::str;
289284

290285
use super::*;
@@ -457,11 +452,6 @@ mod tests {
457452
NetworkInterfaceError::OpenTap(TapError::InvalidIfname),
458453
NetworkInterfaceError::OpenTap(TapError::InvalidIfname)
459454
);
460-
let _ = format!(
461-
"{}{:?}",
462-
NetworkInterfaceError::RateLimiterError(io::Error::last_os_error()),
463-
NetworkInterfaceError::RateLimiterError(io::Error::last_os_error())
464-
);
465455
let _ = format!(
466456
"{}{:?}",
467457
NetworkInterfaceError::RateLimiterUpdateFailed(devices::Error::IoError(

0 commit comments

Comments
 (0)