Skip to content

Commit f9e04dc

Browse files
acatangiuandreeaflorescu
authored andcommitted
Implement translation from RateLimiterDescription to an actual RateLimiter object
Signed-off-by: Adrian Catangiu <[email protected]>
1 parent 3692865 commit f9e04dc

File tree

8 files changed

+62
-49
lines changed

8 files changed

+62
-49
lines changed

api_server/src/request/sync/drive.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::result;
33
use futures::sync::oneshot;
44
use hyper::{Response, StatusCode};
55

6-
use super::rate_limiter::RateLimiter;
6+
use super::rate_limiter::RateLimiterDescription;
77
use super::{DeviceState, GenerateResponse, SyncRequest};
88
use http_service::{empty_response, json_fault_message, json_response};
99
use request::ParsedRequest;
@@ -25,7 +25,7 @@ pub struct DriveDescription {
2525
pub is_root_device: bool,
2626
pub permissions: DrivePermissions,
2727
#[serde(skip_serializing_if = "Option::is_none")]
28-
pub rate_limiter: Option<RateLimiter>,
28+
pub rate_limiter: Option<RateLimiterDescription>,
2929
}
3030

3131
impl DriveDescription {

api_server/src/request/sync/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ pub use self::boot_source::{BootSourceBody, BootSourceType, LocalImage};
1919
pub use self::drive::{DriveDescription, DriveError, DrivePermissions, PutDriveOutcome};
2020
pub use self::logger::{APILoggerDescription, APILoggerError, APILoggerLevel, PutLoggerOutcome};
2121
pub use self::net::NetworkInterfaceBody;
22-
pub use self::rate_limiter::RateLimiter;
22+
pub use self::rate_limiter::description_into_implementation as rate_limiter_description_into_implementation;
23+
pub use self::rate_limiter::RateLimiterDescription;
2324

2425
// Unlike async requests, sync request have outcomes which implement this trait. The idea is for
2526
// each outcome to be a struct which is cheaply and quickly instantiated by the VMM thread, then

api_server/src/request/sync/net.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::result;
22

33
use futures::sync::oneshot;
44

5-
use super::{DeviceState, RateLimiter, SyncRequest};
5+
use super::{DeviceState, RateLimiterDescription, SyncRequest};
66

77
use net_util::MacAddr;
88
use request::ParsedRequest;
@@ -17,9 +17,9 @@ pub struct NetworkInterfaceBody {
1717
#[serde(skip_serializing_if = "Option::is_none")]
1818
pub guest_mac: Option<MacAddr>,
1919
#[serde(skip_serializing_if = "Option::is_none")]
20-
pub rx_rate_limiter: Option<RateLimiter>,
20+
pub rx_rate_limiter: Option<RateLimiterDescription>,
2121
#[serde(skip_serializing_if = "Option::is_none")]
22-
pub tx_rate_limiter: Option<RateLimiter>,
22+
pub tx_rate_limiter: Option<RateLimiterDescription>,
2323
}
2424

2525
impl NetworkInterfaceBody {
@@ -74,8 +74,8 @@ mod tests {
7474
state: DeviceState::Attached,
7575
host_dev_name: String::from("bar"),
7676
guest_mac: Some(MacAddr::parse_str("12:34:56:78:9A:BC").unwrap()),
77-
rx_rate_limiter: Some(RateLimiter::default()),
78-
tx_rate_limiter: Some(RateLimiter::default()),
77+
rx_rate_limiter: Some(RateLimiterDescription::default()),
78+
tx_rate_limiter: Some(RateLimiterDescription::default()),
7979
};
8080

8181
// This is the json encoding of the netif variable.

api_server/src/request/sync/rate_limiter.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
use std::io;
2+
3+
use fc_util::ratelimiter::RateLimiter;
4+
15
// This struct represents the strongly typed equivalent of the json body for TokenBucket
26
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
37
pub struct TokenBucket {
@@ -16,11 +20,32 @@ impl Default for TokenBucket {
1620

1721
// This struct represents the strongly typed equivalent of the json body for RateLimiter
1822
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
19-
pub struct RateLimiter {
23+
pub struct RateLimiterDescription {
2024
pub bandwidth: TokenBucket,
2125
pub ops: TokenBucket,
2226
}
2327

28+
// TryFrom trait is sadly marked unstable, so make our own
29+
impl RateLimiterDescription {
30+
fn into_implementation(&self) -> io::Result<RateLimiter> {
31+
RateLimiter::new(
32+
self.bandwidth.size,
33+
self.bandwidth.refill_time,
34+
self.ops.size,
35+
self.ops.refill_time,
36+
)
37+
}
38+
}
39+
40+
pub fn description_into_implementation(
41+
rate_limiter_description: Option<&RateLimiterDescription>,
42+
) -> io::Result<Option<RateLimiter>> {
43+
match rate_limiter_description {
44+
Some(rld) => Ok(Some(rld.into_implementation()?)),
45+
None => Ok(None),
46+
}
47+
}
48+
2449
#[cfg(test)]
2550
mod tests {
2651
use super::*;
@@ -38,10 +63,17 @@ mod tests {
3863

3964
#[test]
4065
fn test_rate_limiter_default() {
41-
let l = RateLimiter::default();
66+
let l = RateLimiterDescription::default();
4267
assert_eq!(l.bandwidth.size, 0);
4368
assert_eq!(l.bandwidth.refill_time, 0);
4469
assert_eq!(l.ops.size, 0);
4570
assert_eq!(l.ops.refill_time, 0);
4671
}
72+
73+
#[test]
74+
fn test_rate_limiter_into_impl() {
75+
RateLimiterDescription::default()
76+
.into_implementation()
77+
.unwrap();
78+
}
4779
}

vmm/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ scopeguard = "=0.3.3"
1111
api_server = { path = "../api_server" }
1212
data_model = { path = "../data_model" }
1313
devices = { path = "../devices" }
14-
fc_util = { path = "../fc_util"}
1514
kernel_loader = { path = "../kernel_loader" }
1615
kvm = { path = "../kvm" }
1716
kvm_sys = { path = "../kvm_sys" }

vmm/src/device_config/drive.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::path::PathBuf;
33

44
use std::result;
55

6-
use api_server::request::sync::{DriveDescription, DriveError, RateLimiter};
6+
use api_server::request::sync::{DriveDescription, DriveError, RateLimiterDescription};
77

88
type Result<T> = result::Result<T, DriveError>;
99

@@ -14,7 +14,7 @@ pub struct BlockDeviceConfig {
1414
pub path_on_host: PathBuf,
1515
pub is_root_device: bool,
1616
pub is_read_only: bool,
17-
pub rate_limiter: Option<RateLimiter>,
17+
pub rate_limiter: Option<RateLimiterDescription>,
1818
}
1919

2020
// Wrapper for the collection that holds all the Block Devices Configs

vmm/src/device_config/net.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::rc::Rc;
44
use std::result;
55

66
use api_server::request::sync::{Error as SyncError, NetworkInterfaceBody,
7-
OkStatus as SyncOkStatus, RateLimiter};
7+
OkStatus as SyncOkStatus, RateLimiterDescription};
88
use net_util::{MacAddr, Tap, TapError};
99

1010
pub struct NetworkInterfaceConfig {
@@ -19,8 +19,8 @@ pub struct NetworkInterfaceConfig {
1919
// and if so, we want to report the failure back to the API caller immediately. This is an
2020
// option, because the inner value will be moved to the actual virtio net device before boot.
2121
pub tap: Option<Tap>,
22-
pub rx_rate_limiter: Option<RateLimiter>,
23-
pub tx_rate_limiter: Option<RateLimiter>,
22+
pub rx_rate_limiter: Option<RateLimiterDescription>,
23+
pub tx_rate_limiter: Option<RateLimiterDescription>,
2424
}
2525

2626
impl NetworkInterfaceConfig {
@@ -106,8 +106,8 @@ mod tests {
106106
state: DeviceState::Attached,
107107
host_dev_name: String::from("bar"),
108108
guest_mac: Some(mac.clone()),
109-
rx_rate_limiter: Some(RateLimiter::default()),
110-
tx_rate_limiter: Some(RateLimiter::default()),
109+
rx_rate_limiter: Some(RateLimiterDescription::default()),
110+
tx_rate_limiter: Some(RateLimiterDescription::default()),
111111
};
112112
assert!(netif_configs.put(netif_body.clone()).is_ok());
113113
assert_eq!(netif_configs.if_list.len(), 1);

vmm/src/lib.rs

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ extern crate libc;
44
extern crate api_server;
55
extern crate data_model;
66
extern crate devices;
7-
extern crate fc_util;
87
extern crate kernel_loader;
98
extern crate kvm;
109
extern crate kvm_sys;
@@ -35,10 +34,12 @@ use api_server::request::instance_info::{InstanceInfo, InstanceState};
3534
use api_server::request::sync::boot_source::{PutBootSourceConfigError, PutBootSourceOutcome};
3635
use api_server::request::sync::machine_configuration::{PutMachineConfigurationError,
3736
PutMachineConfigurationOutcome};
38-
use api_server::request::sync::{APILoggerDescription, BootSourceBody, DriveDescription,
37+
use api_server::request::sync::{rate_limiter_description_into_implementation,
38+
APILoggerDescription, BootSourceBody, DriveDescription,
3939
DriveError, Error as SyncError, GenerateResponse,
4040
NetworkInterfaceBody, OkStatus as SyncOkStatus, PutDriveOutcome,
4141
PutLoggerOutcome, SyncOutcomeSender, SyncRequest};
42+
4243
use api_server::ApiRequest;
4344
use data_model::vm::MachineConfiguration;
4445
use device_config::*;
@@ -47,7 +48,6 @@ use device_manager::mmio::MMIODeviceManager;
4748

4849
use devices::virtio;
4950
use devices::{DeviceEventT, EpollHandler};
50-
use fc_util::ratelimiter::RateLimiter;
5151
use kvm::*;
5252
use sys_util::{register_signal_handler, EventFd, GuestAddress, GuestMemory, Killable, Terminal};
5353
use vm_control::VmResponse;
@@ -565,15 +565,9 @@ impl Vmm {
565565
.map_err(Error::RootDiskImage)?;
566566
let epoll_config = epoll_context.allocate_virtio_block_tokens();
567567

568-
let rate_limiter = match drive_config.rate_limiter.as_ref() {
569-
Some(rl) => Some(RateLimiter::new(
570-
rl.bandwidth.size,
571-
rl.bandwidth.refill_time,
572-
rl.ops.size,
573-
rl.ops.refill_time,
574-
).map_err(Error::RateLimiterNew)?),
575-
None => None,
576-
};
568+
let rate_limiter = rate_limiter_description_into_implementation(
569+
drive_config.rate_limiter.as_ref(),
570+
).map_err(Error::RateLimiterNew)?;
577571
let block_box = Box::new(devices::virtio::Block::new(
578572
root_image,
579573
drive_config.is_read_only,
@@ -609,25 +603,12 @@ impl Vmm {
609603
for cfg in self.network_interface_configs.iter_mut() {
610604
let epoll_config = self.epoll_context.allocate_virtio_net_tokens();
611605

612-
// TODO: implement from to reduce code
613-
let rx_rate_limiter = match cfg.rx_rate_limiter.as_ref() {
614-
Some(rl) => Some(RateLimiter::new(
615-
rl.bandwidth.size,
616-
rl.bandwidth.refill_time,
617-
rl.ops.size,
618-
rl.ops.refill_time,
619-
).map_err(Error::RateLimiterNew)?),
620-
None => None,
621-
};
622-
let tx_rate_limiter = match cfg.tx_rate_limiter.as_ref() {
623-
Some(rl) => Some(RateLimiter::new(
624-
rl.bandwidth.size,
625-
rl.bandwidth.refill_time,
626-
rl.ops.size,
627-
rl.ops.refill_time,
628-
).map_err(Error::RateLimiterNew)?),
629-
None => None,
630-
};
606+
let rx_rate_limiter = rate_limiter_description_into_implementation(
607+
cfg.rx_rate_limiter.as_ref(),
608+
).map_err(Error::RateLimiterNew)?;
609+
let tx_rate_limiter = rate_limiter_description_into_implementation(
610+
cfg.tx_rate_limiter.as_ref(),
611+
).map_err(Error::RateLimiterNew)?;
631612

632613
if let Some(tap) = cfg.take_tap() {
633614
let net_box = Box::new(devices::virtio::Net::new_with_tap(

0 commit comments

Comments
 (0)