Skip to content

Commit d27a6cc

Browse files
committed
add virtio-fs device
1 parent 3198ffe commit d27a6cc

File tree

29 files changed

+6095
-0
lines changed

29 files changed

+6095
-0
lines changed

Cargo.lock

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,7 @@ panic = "abort"
2626
lto = true
2727
panic = "abort"
2828

29+
[features]
30+
vtfs = ["api_server/vtfs"]
31+
2932
[workspace]

api_server/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,6 @@ kernel = { path = "../kernel" }
2626
memory_model = { path = "../memory_model" }
2727
net_util = { path = "../net_util" }
2828
rate_limiter = { path = "../rate_limiter" }
29+
30+
[features]
31+
vtfs = ["vmm/vtfs"]

api_server/src/http_service.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ use vmm::vmm_config::logger::LoggerConfig;
2727
use vmm::vmm_config::machine_config::VmConfig;
2828
use vmm::vmm_config::net::{NetworkInterfaceConfig, NetworkInterfaceUpdateConfig};
2929
use vmm::vmm_config::vsock::VsockDeviceConfig;
30+
#[cfg(feature = "vtfs")]
31+
use vmm::vmm_config::vtfs::VtfsDeviceConfig;
3032

3133
fn build_response_base<B: Into<hyper::Body>>(
3234
status: StatusCode,
@@ -380,6 +382,35 @@ fn parse_vsock_req<'a>(path: &'a str, method: Method, body: &Chunk) -> Result<'a
380382
}
381383
}
382384

385+
#[cfg(feature = "vtfs")]
386+
// Turns a GET/PUT /vtfs HTTP request into a ParsedRequest.
387+
fn parse_vtfs_req<'a>(path: &'a str, method: Method, body: &Chunk) -> Result<'a, ParsedRequest> {
388+
let path_tokens: Vec<&str> = path[1..].split_terminator('/').collect();
389+
let id_from_path = if path_tokens.len() > 1 {
390+
checked_id(path_tokens[1])?
391+
} else {
392+
return Err(Error::EmptyID);
393+
};
394+
395+
match path_tokens[1..].len() {
396+
1 if method == Method::Put => {
397+
METRICS.put_api_requests.drive_count.inc();
398+
399+
let vtfs_cfg = serde_json::from_slice::<VtfsDeviceConfig>(body).map_err(|e| {
400+
METRICS.put_api_requests.drive_fails.inc();
401+
Error::SerdeJson(e)
402+
})?;
403+
Ok(vtfs_cfg
404+
.into_parsed_request(Some(id_from_path.to_string()), method)
405+
.map_err(|s| {
406+
METRICS.put_api_requests.drive_fails.inc();
407+
Error::Generic(StatusCode::BadRequest, s)
408+
})?)
409+
}
410+
_ => Err(Error::InvalidPathMethod(path, method)),
411+
}
412+
}
413+
383414
// This turns an incoming HTTP request into a ParsedRequest, which is an item containing both the
384415
// message to be passed to the VMM, and associated entities, such as channels which allow the
385416
// reception of the response back from the VMM.
@@ -426,6 +457,8 @@ fn parse_request<'a>(method: Method, path: &'a str, body: &Chunk) -> Result<'a,
426457
"network-interfaces" => parse_netif_req(path, method, body),
427458
"mmds" => parse_mmds_request(path, method, body),
428459
"vsock" => parse_vsock_req(path, method, body),
460+
#[cfg(feature = "vtfs")]
461+
"vtfs" => parse_vtfs_req(path, method, body),
429462
_ => Err(Error::InvalidPathMethod(path, method)),
430463
}
431464
}

api_server/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ use vmm::vmm_config::logger::LoggerConfig;
4444
use vmm::vmm_config::machine_config::VmConfig;
4545
use vmm::vmm_config::net::{NetworkInterfaceConfig, NetworkInterfaceUpdateConfig};
4646
use vmm::vmm_config::vsock::VsockDeviceConfig;
47+
#[cfg(feature = "vtfs")]
48+
use vmm::vmm_config::vtfs::VtfsDeviceConfig;
49+
4750
use vmm::VmmActionError;
4851

4952
/// This enum represents the public interface of the VMM. Each action contains various
@@ -71,6 +74,9 @@ pub enum VmmAction {
7174
/// `VsockDeviceConfig` as input. This action can only be called before the microVM has
7275
/// booted.
7376
SetVsockDevice(VsockDeviceConfig),
77+
#[cfg(feature = "vtfs")]
78+
/// Add a vtfs device config
79+
InsertVtfsDevice(VtfsDeviceConfig),
7480
/// Update the size of an existing block device specified by an ID. The ID is the first data
7581
/// associated with this enum variant. This action can only be called after the microVM is
7682
/// started.

api_server/src/request/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ pub mod logger;
88
pub mod machine_configuration;
99
pub mod net;
1010
pub mod vsock;
11+
#[cfg(feature = "vtfs")]
12+
pub mod vtfs;
1113

1214
use serde_json::Value;
1315
use std::result;

api_server/src/request/vtfs.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2019 UCloud.cn, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
use std::result;
5+
6+
use futures::sync::oneshot;
7+
use hyper::Method;
8+
9+
use request::{IntoParsedRequest, ParsedRequest};
10+
use vmm::vmm_config::vtfs::VtfsDeviceConfig;
11+
use super::{VmmAction, VmmRequest};
12+
13+
impl IntoParsedRequest for VtfsDeviceConfig {
14+
fn into_parsed_request(
15+
self,
16+
id_from_path: Option<String>,
17+
_: Method,
18+
) -> result::Result<ParsedRequest, String> {
19+
let id_from_path = id_from_path.unwrap_or_default();
20+
if id_from_path != self.drive_id.as_str() {
21+
return Err(String::from(
22+
"The id from the path does not match the id from the body!",
23+
));
24+
}
25+
26+
let (sender, receiver) = oneshot::channel();
27+
Ok(ParsedRequest::Sync(
28+
VmmRequest::new(
29+
VmmAction::InsertVtfsDevice(self), sender),
30+
receiver,
31+
))
32+
}
33+
}
34+
35+
#[cfg(test)]
36+
mod tests {
37+
38+
}

devices/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ net_gen = { path = "../net_gen" }
1818
rate_limiter = { path = "../rate_limiter" }
1919
sys_util = { path = "../sys_util" }
2020
virtio_gen = { path = "../virtio_gen" }
21+
fuse_gen = { path = "../fuse_gen", optional = true}
2122

2223
[dev-dependencies]
2324
tempfile = ">=3.0.2"
25+
26+
[features]
27+
vtfs = ["fuse_gen", "sys_util/vtfs"]

devices/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ extern crate libc;
1313
extern crate dumbo;
1414
#[macro_use]
1515
extern crate logger;
16+
#[cfg(feature = "vtfs")]
17+
extern crate fuse_gen;
1618
extern crate memory_model;
1719
extern crate net_gen;
1820
extern crate net_util;

devices/src/virtio/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,16 @@ mod mmio;
1717
pub mod net;
1818
mod queue;
1919
pub mod vsock;
20+
#[cfg(feature = "vtfs")]
21+
pub mod vtfs;
2022

2123
pub use self::block::*;
2224
pub use self::mmio::*;
2325
pub use self::net::*;
2426
pub use self::queue::*;
2527
pub use self::vsock::*;
28+
#[cfg(feature = "vtfs")]
29+
pub use self::vtfs::*;
2630

2731
use super::EpollHandler;
2832

0 commit comments

Comments
 (0)