Skip to content

Commit 9b86a41

Browse files
committed
feat(virtio-pmem): add API requests parsing to Firecracker
Add /pmem/id PUT request for virtio-pmem configuration. Add corresponding metrics. Signed-off-by: Egor Lazarchuk <[email protected]>
1 parent d4a2ab0 commit 9b86a41

File tree

5 files changed

+86
-0
lines changed

5 files changed

+86
-0
lines changed

src/firecracker/src/api_server/parsed_request.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use super::request::machine_configuration::{
2424
use super::request::metrics::parse_put_metrics;
2525
use super::request::mmds::{parse_get_mmds, parse_patch_mmds, parse_put_mmds};
2626
use super::request::net::{parse_patch_net, parse_put_net};
27+
use super::request::pmem::parse_put_pmem;
2728
use super::request::snapshot::{parse_patch_vm_state, parse_put_snapshot};
2829
use super::request::version::parse_get_version;
2930
use super::request::vsock::parse_put_vsock;
@@ -90,6 +91,7 @@ impl TryFrom<&Request> for ParsedRequest {
9091
(Method::Put, "boot-source", Some(body)) => parse_put_boot_source(body),
9192
(Method::Put, "cpu-config", Some(body)) => parse_put_cpu_config(body),
9293
(Method::Put, "drives", Some(body)) => parse_put_drive(body, path_tokens.next()),
94+
(Method::Put, "pmem", Some(body)) => parse_put_pmem(body, path_tokens.next()),
9395
(Method::Put, "logger", Some(body)) => parse_put_logger(body),
9496
(Method::Put, "serial", Some(body)) => parse_put_serial(body),
9597
(Method::Put, "machine-config", Some(body)) => parse_put_machine_config(body),

src/firecracker/src/api_server/request/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub mod machine_configuration;
1313
pub mod metrics;
1414
pub mod mmds;
1515
pub mod net;
16+
pub mod pmem;
1617
pub mod serial;
1718
pub mod snapshot;
1819
pub mod version;
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
use vmm::logger::{IncMetric, METRICS};
5+
use vmm::rpc_interface::VmmAction;
6+
use vmm::vmm_config::pmem::PmemConfig;
7+
8+
use super::super::parsed_request::{ParsedRequest, RequestError, checked_id};
9+
use super::{Body, StatusCode};
10+
11+
pub(crate) fn parse_put_pmem(
12+
body: &Body,
13+
id_from_path: Option<&str>,
14+
) -> Result<ParsedRequest, RequestError> {
15+
METRICS.put_api_requests.pmem_count.inc();
16+
let id = if let Some(id) = id_from_path {
17+
checked_id(id)?
18+
} else {
19+
METRICS.put_api_requests.pmem_fails.inc();
20+
return Err(RequestError::EmptyID);
21+
};
22+
23+
let device_cfg = serde_json::from_slice::<PmemConfig>(body.raw()).inspect_err(|_| {
24+
METRICS.put_api_requests.pmem_fails.inc();
25+
})?;
26+
27+
if id != device_cfg.id {
28+
METRICS.put_api_requests.pmem_fails.inc();
29+
Err(RequestError::Generic(
30+
StatusCode::BadRequest,
31+
"The id from the path does not match the id from the body!".to_string(),
32+
))
33+
} else {
34+
Ok(ParsedRequest::new_sync(VmmAction::InsertPmemDevice(
35+
device_cfg,
36+
)))
37+
}
38+
}
39+
40+
#[cfg(test)]
41+
mod tests {
42+
use super::*;
43+
use crate::api_server::parsed_request::tests::vmm_action_from_request;
44+
45+
#[test]
46+
fn test_parse_put_pmem_request() {
47+
parse_put_pmem(&Body::new("invalid_payload"), None).unwrap_err();
48+
parse_put_pmem(&Body::new("invalid_payload"), Some("id")).unwrap_err();
49+
50+
let body = r#"{
51+
"id": "bar",
52+
}"#;
53+
parse_put_pmem(&Body::new(body), Some("1")).unwrap_err();
54+
let body = r#"{
55+
"foo": "1",
56+
}"#;
57+
parse_put_pmem(&Body::new(body), Some("1")).unwrap_err();
58+
59+
let body = r#"{
60+
"id": "1000",
61+
"path_on_host": "dummy",
62+
"root_device": true,
63+
"read_only": true
64+
}"#;
65+
let r = vmm_action_from_request(parse_put_pmem(&Body::new(body), Some("1000")).unwrap());
66+
67+
let expected_config = PmemConfig {
68+
id: "1000".to_string(),
69+
path_on_host: "dummy".to_string(),
70+
root_device: true,
71+
read_only: true,
72+
};
73+
assert_eq!(r, VmmAction::InsertPmemDevice(expected_config));
74+
}
75+
}

src/vmm/src/logger/metrics.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,10 @@ pub struct PutRequestsMetrics {
415415
pub vsock_count: SharedIncMetric,
416416
/// Number of failures in creating a vsock device.
417417
pub vsock_fails: SharedIncMetric,
418+
/// Number of PUTs triggering a pmem attach.
419+
pub pmem_count: SharedIncMetric,
420+
/// Number of failures in attaching a pmem device.
421+
pub pmem_fails: SharedIncMetric,
418422
/// Number of PUTs to /serial
419423
pub serial_count: SharedIncMetric,
420424
/// Number of failed PUTs to /serial
@@ -444,6 +448,8 @@ impl PutRequestsMetrics {
444448
mmds_fails: SharedIncMetric::new(),
445449
vsock_count: SharedIncMetric::new(),
446450
vsock_fails: SharedIncMetric::new(),
451+
pmem_count: SharedIncMetric::new(),
452+
pmem_fails: SharedIncMetric::new(),
447453
serial_count: SharedIncMetric::new(),
448454
serial_fails: SharedIncMetric::new(),
449455
}

tests/host_tools/fcmetrics.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ def validate_fc_metrics(metrics):
223223
"mmds_fails",
224224
"vsock_count",
225225
"vsock_fails",
226+
"pmem_count",
227+
"pmem_fails",
226228
"serial_count",
227229
"serial_fails",
228230
],

0 commit comments

Comments
 (0)