Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions resources/seccomp/x86_64-unknown-linux-musl.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
{
"syscall": "mincore"
},
{
"syscall": "pread64"
},
{
"syscall": "writev",
"comment": "Used by the VirtIO net device to write to tap"
Expand Down
4 changes: 2 additions & 2 deletions src/firecracker/src/api_server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ mod tests {
Box::new(VmmAction::CreateSnapshot(CreateSnapshotParams {
snapshot_type: SnapshotType::Diff,
snapshot_path: PathBuf::new(),
mem_file_path: PathBuf::new(),
mem_file_path: Some(PathBuf::new()),
})),
start_time_us,
);
Expand All @@ -288,7 +288,7 @@ mod tests {
Box::new(VmmAction::CreateSnapshot(CreateSnapshotParams {
snapshot_type: SnapshotType::Diff,
snapshot_path: PathBuf::new(),
mem_file_path: PathBuf::new(),
mem_file_path: Some(PathBuf::new()),
})),
start_time_us,
);
Expand Down
14 changes: 14 additions & 0 deletions src/firecracker/src/api_server/parsed_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use super::request::vsock::parse_put_vsock;
use crate::api_server::request::hotplug::memory::{
parse_get_memory_hotplug, parse_patch_memory_hotplug, parse_put_memory_hotplug,
};
use crate::api_server::request::memory_info::parse_get_memory;
use crate::api_server::request::serial::parse_put_serial;

#[derive(Debug)]
Expand Down Expand Up @@ -91,6 +92,7 @@ impl TryFrom<&Request> for ParsedRequest {
(Method::Get, "hotplug", None) if path_tokens.next() == Some("memory") => {
parse_get_memory_hotplug()
}
(Method::Get, "memory", None) => parse_get_memory(path_tokens),
(Method::Get, _, Some(_)) => method_to_error(Method::Get),
(Method::Put, "actions", Some(body)) => parse_put_actions(body),
(Method::Put, "balloon", Some(body)) => parse_put_balloon(body),
Expand Down Expand Up @@ -196,6 +198,9 @@ impl ParsedRequest {
&serde_json::json!({ "firecracker_version": version.as_str() }),
),
VmmData::FullVmConfig(config) => Self::success_response_with_data(config),
VmmData::MemoryMappings(mappings) => Self::success_response_with_data(mappings),
VmmData::Memory(meminfo) => Self::success_response_with_data(meminfo),
VmmData::MemoryDirty(dirty) => Self::success_response_with_data(dirty),
},
Err(vmm_action_error) => {
let mut response = match vmm_action_error {
Expand Down Expand Up @@ -610,6 +615,15 @@ pub mod tests {
&serde_json::json!({ "firecracker_version": version.as_str() }).to_string(),
200,
),
VmmData::MemoryMappings(mappings) => {
http_response(&serde_json::to_string(mappings).unwrap(), 200)
}
VmmData::Memory(meminfo) => {
http_response(&serde_json::to_string(meminfo).unwrap(), 200)
}
VmmData::MemoryDirty(dirty) => {
http_response(&serde_json::to_string(dirty).unwrap(), 200)
}
};
let response = ParsedRequest::convert_to_response(&data);
response.write_all(&mut buf).unwrap();
Expand Down
19 changes: 19 additions & 0 deletions src/firecracker/src/api_server/request/memory_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use micro_http::StatusCode;
use vmm::rpc_interface::VmmAction;

use crate::api_server::parsed_request::{ParsedRequest, RequestError};

pub(crate) fn parse_get_memory<'a, T>(mut path_tokens: T) -> Result<ParsedRequest, RequestError>
where
T: Iterator<Item = &'a str>,
{
match path_tokens.next() {
Some("mappings") => Ok(ParsedRequest::new_sync(VmmAction::GetMemoryMappings)),
Some("dirty") => Ok(ParsedRequest::new_sync(VmmAction::GetMemoryDirty)),
Some(unknown_path) => Err(RequestError::Generic(
StatusCode::BadRequest,
format!("Unrecognized GET request path `{unknown_path}`"),
)),
None => Ok(ParsedRequest::new_sync(VmmAction::GetMemory)),
}
}
1 change: 1 addition & 0 deletions src/firecracker/src/api_server/request/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub mod hotplug;
pub mod instance_info;
pub mod logger;
pub mod machine_configuration;
pub mod memory_info;
pub mod metrics;
pub mod mmds;
pub mod net;
Expand Down
4 changes: 2 additions & 2 deletions src/firecracker/src/api_server/request/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ mod tests {
let expected_config = CreateSnapshotParams {
snapshot_type: SnapshotType::Diff,
snapshot_path: PathBuf::from("foo"),
mem_file_path: PathBuf::from("bar"),
mem_file_path: Some(PathBuf::from("bar")),
};
assert_eq!(
vmm_action_from_request(parse_put_snapshot(&Body::new(body), Some("create")).unwrap()),
Expand All @@ -158,7 +158,7 @@ mod tests {
let expected_config = CreateSnapshotParams {
snapshot_type: SnapshotType::Full,
snapshot_path: PathBuf::from("foo"),
mem_file_path: PathBuf::from("bar"),
mem_file_path: Some(PathBuf::from("bar")),
};
assert_eq!(
vmm_action_from_request(parse_put_snapshot(&Body::new(body), Some("create")).unwrap()),
Expand Down
116 changes: 114 additions & 2 deletions src/firecracker/swagger/firecracker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,50 @@ paths:
schema:
$ref: "#/definitions/Error"

/memory/mappings:
get:
summary: Gets the memory mappings with skippable pages bitmap.
operationId: getMemoryMappings
responses:
200:
description: OK
schema:
$ref: "#/definitions/MemoryMappingsResponse"
default:
description: Internal server error
schema:
$ref: "#/definitions/Error"

/memory:
get:
summary: Gets the memory info (resident and empty pages).
description: Returns an object with resident and empty bitmaps. The resident bitmap marks all pages that are resident. The empty bitmap marks zero pages (subset of resident pages). This is checked at the pageSize of each region. All regions must have the same page size.
operationId: getMemory
responses:
200:
description: OK
schema:
$ref: "#/definitions/MemoryResponse"
default:
description: Internal server error
schema:
$ref: "#/definitions/Error"

/memory/dirty:
get:
summary: Gets the dirty guest memory
description: This returns the resident memory that has been written since last snapshot.
operationId: getDirtyMemory
responses:
200:
description: OK
schema:
$ref: "#/definitions/MemoryDirty"
default:
description: Internal server error
schema:
$ref: "#/definitions/Error"

/version:
get:
summary: Gets the Firecracker version.
Expand Down Expand Up @@ -1347,6 +1391,72 @@ definitions:
description: MicroVM hypervisor build version.
type: string

GuestMemoryRegionMapping:
type: object
description: Describes the region of guest memory that can be used for creating the memfile.
required:
- base_host_virt_addr
- size
- offset
- page_size
properties:
base_host_virt_addr:
type: integer
size:
description: The size of the region in bytes.
type: integer
offset:
description: The offset of the region in bytes.
type: integer
page_size:
description: The page size in bytes.
type: integer

MemoryMappingsResponse:
type: object
description: Response containing memory region mappings.
required:
- mappings
properties:
mappings:
type: array
description: The memory region mappings.
items:
$ref: "#/definitions/GuestMemoryRegionMapping"

MemoryResponse:
type: object
description: Response containing the memory info (resident and empty pages).
required:
- resident
- empty
properties:
resident:
type: array
description: The resident bitmap as a vector of u64 values. Each bit represents if the page is resident.
items:
type: integer
format: uint64
empty:
type: array
description: The empty bitmap as a vector of u64 values. Each bit represents if the page is zero (empty). This is a subset of the resident pages.
items:
type: integer
format: uint64

MemoryDirty:
type: object
description: Response containing the bitmap (one bit per page) of dirty pages of guest memory
required:
- bitmap:
properties:
bitmap:
type: array
description: The dirty bitmap as a vector of u64 values. Each bit respresents if the page is dirty.
itmes:
type: integer
format: uint64

Logger:
type: object
description:
Expand Down Expand Up @@ -1555,12 +1665,14 @@ definitions:
SnapshotCreateParams:
type: object
required:
- mem_file_path
- snapshot_path
properties:
mem_file_path:
type: string
description: Path to the file that will contain the guest memory.
description:
Path to the file that will contain the guest memory. It is optional.
In case that a user doesn't provide a path, they are responsible to
ensure they store the microVM's memory state via external means.
snapshot_path:
type: string
description: Path to the file that will contain the microVM state.
Expand Down
4 changes: 4 additions & 0 deletions src/vmm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ pub fn build_microvm_for_boot(
vcpus_handles: Vec::new(),
vcpus_exit_evt,
device_manager,
page_size: vm_resources.machine_config.huge_pages.page_size(),
};
let vmm = Arc::new(Mutex::new(vmm));

Expand Down Expand Up @@ -518,6 +519,7 @@ pub fn build_microvm_from_snapshot(
vcpus_handles: Vec::new(),
vcpus_exit_evt,
device_manager,
page_size: vm_resources.machine_config.huge_pages.page_size(),
};

// Move vcpus to their own threads and start their state machine in the 'Paused' state.
Expand Down Expand Up @@ -751,6 +753,7 @@ pub(crate) mod tests {
use vmm_sys_util::tempfile::TempFile;

use super::*;
use crate::arch::host_page_size;
use crate::device_manager::tests::default_device_manager;
use crate::devices::virtio::block::CacheType;
use crate::devices::virtio::generated::virtio_ids;
Expand Down Expand Up @@ -836,6 +839,7 @@ pub(crate) mod tests {
vcpus_handles: Vec::new(),
vcpus_exit_evt,
device_manager: default_device_manager(),
page_size: host_page_size(),
}
}

Expand Down
Loading