Skip to content

Commit 3552b19

Browse files
acatangiusandreim
authored andcommitted
[rust-vmm/event-manager 7/7] migrate Metrics & API
This series of 7 commits migrates Firecracker from using local 'polly' crate, to using 'rust-vmm/event-manager' crate. Note: The project doesn't build with only part of this patchset. Signed-off-by: Adrian Catangiu <[email protected]>
1 parent 9be82cd commit 3552b19

File tree

5 files changed

+27
-75
lines changed

5 files changed

+27
-75
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/firecracker/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ homepage = "https://firecracker-microvm.github.io/"
99
license = "Apache-2.0"
1010

1111
[dependencies]
12+
event-manager = ">=0.2.1"
1213
libc = ">=0.2.39"
1314
timerfd = ">=1.0"
1415

1516
api_server = { path = "../api_server" }
1617
logger = { path = "../logger" }
1718
mmds = { path = "../mmds" }
18-
polly = { path = "../polly" }
1919
seccompiler = { path = "../seccompiler" }
2020
snapshot = { path = "../snapshot"}
2121
utils = { path = "../utils" }

src/firecracker/src/api_server_adapter.rs

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,16 @@ use std::sync::{Arc, Mutex};
1010
use std::thread;
1111

1212
use api_server::{ApiRequest, ApiResponse, ApiServer};
13+
use event_manager::{EventOps, Events, MutEventSubscriber, SubscriberOps};
1314
use logger::{error, warn, ProcessTimeReporter};
1415
use mmds::MMDS;
15-
use polly::event_manager::{EventManager, Subscriber};
1616
use seccompiler::BpfThreadMap;
17-
use utils::{
18-
epoll::{EpollEvent, EventSet},
19-
eventfd::EventFd,
20-
};
17+
use utils::{epoll::EventSet, eventfd::EventFd};
2118
use vmm::{
2219
resources::VmResources,
2320
rpc_interface::{PrebootApiController, RuntimeApiController, VmmAction},
2421
vmm_config::instance_info::InstanceInfo,
25-
ExitCode, Vmm,
22+
EventManager, ExitCode, Vmm,
2623
};
2724

2825
struct ApiServerAdapter {
@@ -49,10 +46,7 @@ impl ApiServerAdapter {
4946
to_api,
5047
controller: RuntimeApiController::new(vm_resources, vmm.clone()),
5148
}));
52-
event_manager
53-
.add_subscriber(api_adapter)
54-
.expect("Cannot register the api event to the event manager.");
55-
49+
event_manager.add_subscriber(api_adapter);
5650
loop {
5751
event_manager
5852
.run()
@@ -72,9 +66,9 @@ impl ApiServerAdapter {
7266
.expect("one-shot channel closed");
7367
}
7468
}
75-
impl Subscriber for ApiServerAdapter {
69+
impl MutEventSubscriber for ApiServerAdapter {
7670
/// Handle a read event (EPOLLIN).
77-
fn process(&mut self, event: &EpollEvent, _: &mut EventManager) {
71+
fn process(&mut self, event: Events, _: &mut EventOps) {
7872
let source = event.fd();
7973
let event_set = event.event_set();
8074

@@ -115,11 +109,10 @@ impl Subscriber for ApiServerAdapter {
115109
}
116110
}
117111

118-
fn interest_list(&self) -> Vec<EpollEvent> {
119-
vec![EpollEvent::new(
120-
EventSet::IN,
121-
self.api_event_fd.as_raw_fd() as u64,
122-
)]
112+
fn init(&mut self, ops: &mut EventOps) {
113+
if let Err(e) = ops.add(Events::new(&self.api_event_fd, EventSet::IN)) {
114+
error!("Failed to register activate event: {}", e);
115+
}
123116
}
124117
}
125118

@@ -178,9 +171,7 @@ pub(crate) fn run_with_api(
178171
let mut event_manager = EventManager::new().expect("Unable to create EventManager");
179172
// Create the firecracker metrics object responsible for periodically printing metrics.
180173
let firecracker_metrics = Arc::new(Mutex::new(super::metrics::PeriodicMetrics::new()));
181-
event_manager
182-
.add_subscriber(firecracker_metrics.clone())
183-
.expect("Cannot register the metrics event to the event manager.");
174+
event_manager.add_subscriber(firecracker_metrics.clone());
184175

185176
// Configure, build and start the microVM.
186177
let build_result = match config_json {

src/firecracker/src/main.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,19 @@ use std::path::PathBuf;
1010
use std::process;
1111
use std::sync::{Arc, Mutex};
1212

13+
use event_manager::SubscriberOps;
1314
use logger::{error, info, warn, IncMetric, ProcessTimeReporter, LOGGER, METRICS};
14-
use polly::event_manager::EventManager;
1515
use seccompiler::BpfThreadMap;
1616
use snapshot::Snapshot;
1717
use utils::arg_parser::{ArgParser, Argument, Arguments};
1818
use utils::terminal::Terminal;
1919
use utils::validators::validate_instance_id;
20-
use vmm::resources::VmResources;
2120
use vmm::seccomp_filters::{get_filters, SeccompConfig};
2221
use vmm::signal_handler::register_signal_handlers;
2322
use vmm::version_map::{FC_VERSION_TO_SNAP_VERSION, VERSION_MAP};
2423
use vmm::vmm_config::instance_info::{InstanceInfo, VmState};
2524
use vmm::vmm_config::logger::{init_logger, LoggerConfig, LoggerLevel};
26-
use vmm::ExitCode;
25+
use vmm::{resources::VmResources, EventManager, ExitCode};
2726

2827
// The reason we place default API socket under /run is that API socket is a
2928
// runtime file.
@@ -464,9 +463,7 @@ fn run_without_api(
464463

465464
// Create the firecracker metrics object responsible for periodically printing metrics.
466465
let firecracker_metrics = Arc::new(Mutex::new(metrics::PeriodicMetrics::new()));
467-
event_manager
468-
.add_subscriber(firecracker_metrics.clone())
469-
.expect("Cannot register the metrics event to the event manager.");
466+
event_manager.add_subscriber(firecracker_metrics.clone());
470467

471468
// Build the microVm. We can ignore VmResources since it's not used without api.
472469
let (_, vmm) = match build_microvm_from_json(

src/firecracker/src/metrics.rs

Lines changed: 11 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
use std::os::unix::io::AsRawFd;
55
use std::time::Duration;
66

7+
use event_manager::{EventOps, Events, MutEventSubscriber};
78
use logger::{error, warn, IncMetric, METRICS};
8-
use polly::event_manager::{EventManager, Subscriber};
99
use timerfd::{ClockId, SetTimeFlags, TimerFd, TimerState};
10-
use utils::epoll::{EpollEvent, EventSet};
10+
use utils::epoll::EventSet;
1111

1212
/// Metrics reporting period.
1313
pub(crate) const WRITE_METRICS_PERIOD_MS: u64 = 60000;
@@ -60,9 +60,9 @@ impl PeriodicMetrics {
6060
}
6161
}
6262

63-
impl Subscriber for PeriodicMetrics {
63+
impl MutEventSubscriber for PeriodicMetrics {
6464
/// Handle a read event (EPOLLIN).
65-
fn process(&mut self, event: &EpollEvent, _: &mut EventManager) {
65+
fn process(&mut self, event: Events, _: &mut EventOps) {
6666
let source = event.fd();
6767
let event_set = event.event_set();
6868

@@ -85,11 +85,10 @@ impl Subscriber for PeriodicMetrics {
8585
}
8686
}
8787

88-
fn interest_list(&self) -> Vec<EpollEvent> {
89-
vec![EpollEvent::new(
90-
EventSet::IN,
91-
self.write_metrics_event_fd.as_raw_fd() as u64,
92-
)]
88+
fn init(&mut self, ops: &mut EventOps) {
89+
if let Err(e) = ops.add(Events::new(&self.write_metrics_event_fd, EventSet::IN)) {
90+
error!("Failed to register metrics event: {}", e);
91+
}
9392
}
9493
}
9594

@@ -98,48 +97,13 @@ pub mod tests {
9897
use std::sync::{Arc, Mutex};
9998

10099
use super::*;
101-
use polly::event_manager::EventManager;
102-
use utils::eventfd::EventFd;
103-
104-
#[test]
105-
fn test_interest_list() {
106-
let metrics = PeriodicMetrics::new();
107-
let interest_list = metrics.interest_list();
108-
assert_eq!(interest_list.len(), 1);
109-
assert_eq!(
110-
interest_list[0].data() as i32,
111-
metrics.write_metrics_event_fd.as_raw_fd()
112-
);
113-
assert_eq!(
114-
EventSet::from_bits(interest_list[0].events()).unwrap(),
115-
EventSet::IN
116-
);
117-
}
100+
use event_manager::{EventManager, SubscriberOps};
118101

119102
#[test]
120103
fn test_periodic_metrics() {
121104
let mut event_manager = EventManager::new().expect("Unable to create EventManager");
122-
let mut metrics = PeriodicMetrics::new();
123-
124-
// Test invalid read event.
125-
let unrelated_object = EventFd::new(libc::EFD_NONBLOCK).unwrap();
126-
let unrelated_event = EpollEvent::new(EventSet::IN, unrelated_object.as_raw_fd() as u64);
127-
metrics.process(&unrelated_event, &mut event_manager);
128-
// No flush happened.
129-
assert_eq!(metrics.flush_counter, 0);
130-
131-
// Test unsupported event type.
132-
let unsupported_event = EpollEvent::new(
133-
EventSet::OUT,
134-
metrics.write_metrics_event_fd.as_raw_fd() as u64,
135-
);
136-
metrics.process(&unsupported_event, &mut event_manager);
137-
assert_eq!(metrics.flush_counter, 0);
138-
139-
let metrics = Arc::new(Mutex::new(metrics));
140-
event_manager
141-
.add_subscriber(metrics.clone())
142-
.expect("Cannot register the metrics event to the event manager.");
105+
let metrics = Arc::new(Mutex::new(PeriodicMetrics::new()));
106+
event_manager.add_subscriber(metrics.clone());
143107

144108
let flush_period_ms = 50;
145109
metrics

0 commit comments

Comments
 (0)