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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ test_results/*
/resources/linux
/resources/x86_64
/resources/aarch64
.env
2 changes: 2 additions & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
gcloud 534.0.0
rust 1.79.0
33 changes: 11 additions & 22 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-include .env

.PHONY: build
build:
./scripts/build.sh

.PHONY: upload
upload:
./scripts/upload.sh $(GCP_PROJECT_ID)

.PHONY: build-and-upload
make build-and-upload: build upload
17 changes: 17 additions & 0 deletions scripts/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

set -euo pipefail

# The format will be: v<major>.<minor>.<patch>_g<commit_hash> — e.g. v1.7.2_g8bb88311
# Extract full version from src/firecracker/swagger/firecracker.yaml
FC_VERSION=$(awk '/^info:/{flag=1} flag && /^ version:/{print $2; exit}' src/firecracker/swagger/firecracker.yaml)
commit_hash=$(git rev-parse --short HEAD)
version_name="v${FC_VERSION}_g${commit_hash}"
echo "Version name: $version_name"

echo "Starting to build Firecracker version: $version_name"
tools/devtool -y build --release

mkdir -p "./build/fc/${version_name}"
cp ./build/cargo_target/x86_64-unknown-linux-musl/release/firecracker "./build/fc/${version_name}/firecracker"
echo "Finished building Firecracker version: $version_name and copied to ./build/fc/${version_name}/firecracker"
13 changes: 13 additions & 0 deletions scripts/upload.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash

set -euo pipefail

GCP_PROJECT_ID=$1

gsutil -h "Cache-Control:no-cache, max-age=0" cp -r "build/fc/*" "gs://${GCP_PROJECT_ID}-fc-versions"
if [ "$GCP_PROJECT_ID" == "e2b-prod" ]; then
# Upload kernel to GCP public builds bucket
gsutil -h "Cache-Control:no-cache, max-age=0" cp -r "build/fc/*" "gs://${GCP_PROJECT_ID}-public-builds/firecrackers/"
fi

rm -rf build/fc/*
1 change: 1 addition & 0 deletions src/cpu-template-helper/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ pub fn build_microvm_from_config(
state: VmState::NotStarted,
vmm_version: CPU_TEMPLATE_HELPER_VERSION.to_string(),
app_name: "cpu-template-helper".to_string(),
memory_regions: None,
};
let mut vm_resources =
VmResources::from_json(&config, &instance_info, HTTP_MAX_PAYLOAD_SIZE, None)
Expand Down
12 changes: 10 additions & 2 deletions src/firecracker/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ vmm-sys-util = { version = "0.12.1", features = ["with-serde"] }
[dev-dependencies]
cargo_toml = "0.20.5"
libc = "0.2.161"
regex = { version = "1.11.1", default-features = false, features = ["std", "unicode-perl"] }
regex = { version = "1.11.1", default-features = false, features = [
"std",
"unicode-perl",
] }

# Dev-Dependencies for uffd examples
serde = { version = "1.0.214", features = ["derive"] }
Expand All @@ -48,7 +51,12 @@ serde = { version = "1.0.214" }
serde_json = "1.0.132"

[features]
tracing = ["log-instrument", "seccompiler/tracing", "utils/tracing", "vmm/tracing"]
tracing = [
"log-instrument",
"seccompiler/tracing",
"utils/tracing",
"vmm/tracing",
]
gdb = ["vmm/gdb"]

[lints]
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 @@ -274,7 +274,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 @@ -287,7 +287,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
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 @@ -139,7 +139,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 @@ -153,7 +153,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
1 change: 1 addition & 0 deletions src/firecracker/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ fn main_exec() -> Result<(), MainError> {
state: VmState::NotStarted,
vmm_version: FIRECRACKER_VERSION.to_string(),
app_name: "Firecracker".to_string(),
memory_regions: None,
};

if let Some(metrics_path) = arguments.single_value("metrics-path") {
Expand Down
27 changes: 26 additions & 1 deletion src/firecracker/swagger/firecracker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -990,6 +990,32 @@ definitions:
vmm_version:
description: MicroVM hypervisor build version.
type: string
memory_regions:
type: array
description: The regions of the guest memory.
items:
$ref: "#/definitions/GuestMemoryRegionMapping"

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

Logger:
type: object
Expand Down Expand Up @@ -1192,7 +1218,6 @@ definitions:
SnapshotCreateParams:
type: object
required:
- mem_file_path
- snapshot_path
properties:
mem_file_path:
Expand Down
19 changes: 15 additions & 4 deletions src/vmm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,18 @@ license = "Apache-2.0"
bench = false

[dependencies]
acpi_tables = { path = "../acpi-tables" }
aes-gcm = { version = "0.10.1", default-features = false, features = ["aes"] }
acpi_tables = { path = "../acpi-tables" }
aes-gcm = { version = "0.10.1", default-features = false, features = ["aes"] }
arrayvec = { version = "0.7.6", optional = true }
aws-lc-rs = { version = "1.10.0", features = ["bindgen"] }
base64 = "0.22.1"
bincode = "1.2.1"
bitflags = "2.6.0"
crc64 = "2.0.0"
derive_more = { version = "1.0.0", default-features = false, features = ["from", "display"] }
derive_more = { version = "1.0.0", default-features = false, features = [
"from",
"display",
] }
displaydoc = "0.2.5"
event-manager = "0.4.0"
gdbstub = { version = "0.7.3", optional = true }
Expand All @@ -43,7 +46,10 @@ userfaultfd = "0.8.1"
utils = { path = "../utils" }
vhost = { version = "0.13.0", features = ["vhost-user-frontend"] }
vm-allocator = "0.1.0"
vm-memory = { version = "0.16.0", features = ["backend-mmap", "backend-bitmap"] }
vm-memory = { version = "0.16.0", features = [
"backend-mmap",
"backend-bitmap",
] }
vm-superio = "0.8.0"
vmm-sys-util = { version = "0.12.1", features = ["with-serde"] }
zerocopy = { version = "0.8.8" }
Expand Down Expand Up @@ -80,3 +86,8 @@ harness = false

[lints]
workspace = true

[patch.crates-io]
aws-lc-sys = "=0.29.0"
aws-lc-rs = "=1.13.1"
aws-lc-fips-sys = "=0.13.7"
31 changes: 31 additions & 0 deletions src/vmm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ use crate::vstate::memory::{
use crate::vstate::vcpu::VcpuState;
pub use crate::vstate::vcpu::{Vcpu, VcpuConfig, VcpuEvent, VcpuHandle, VcpuResponse};
pub use crate::vstate::vm::Vm;
use serde::{Deserialize, Serialize};

/// Shorthand type for the EventManager flavour used by Firecracker.
pub type EventManager = BaseEventManager<Arc<Mutex<dyn MutEventSubscriber>>>;
Expand Down Expand Up @@ -191,6 +192,20 @@ pub enum FcExitCode {
ArgParsing = 153,
}

/// Describes the region of guest memory that can be used for creating the memfile.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Deserialize, Serialize)]
pub struct GuestMemoryRegionMapping {
/// Base host virtual address where the guest memory contents for this region
/// should be copied/populated.
pub base_host_virt_addr: u64,
/// Region size.
pub size: usize,
/// Offset in the backend file/buffer where the region contents are.
pub offset: u64,
/// The configured page size for this memory region.
pub page_size: usize,
}

/// Timeout used in recv_timeout, when waiting for a vcpu response on
/// Pause/Resume/Save/Restore. A high enough limit that should not be reached during normal usage,
/// used to detect a potential vcpu deadlock.
Expand Down Expand Up @@ -451,6 +466,22 @@ impl Vmm {
&self.guest_memory
}

/// Returns the memory mappings for the guest memory.
pub fn guest_memory_mappings(&self, vm_info: &VmInfo) -> Vec<GuestMemoryRegionMapping> {
let mut offset = 0;
let mut mappings = Vec::new();
for mem_region in self.guest_memory().iter() {
mappings.push(GuestMemoryRegionMapping {
base_host_virt_addr: mem_region.as_ptr() as u64,
size: mem_region.size(),
offset,
page_size: vm_info.huge_pages.page_size_kib(),
});
offset += mem_region.size() as u64;
}
mappings
}

/// Sets RDA bit in serial console
pub fn emulate_serial_init(&self) -> Result<(), EmulateSerialInitError> {
// When restoring from a previously saved state, there is no serial
Expand Down
5 changes: 4 additions & 1 deletion src/vmm/src/persist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,10 @@ pub fn create_snapshot(

snapshot_state_to_file(&microvm_state, &params.snapshot_path)?;

snapshot_memory_to_file(vmm, &params.mem_file_path, params.snapshot_type)?;
// Dump memory to file only if mem_file_path is specified
if let Some(ref mem_file_path) = params.mem_file_path {
snapshot_memory_to_file(vmm, mem_file_path, params.snapshot_type)?;
}

Ok(())
}
Expand Down
15 changes: 11 additions & 4 deletions src/vmm/src/rpc_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -646,9 +646,16 @@ impl RuntimeApiController {
GetVmMachineConfig => Ok(VmmData::MachineConfiguration(MachineConfig::from(
&self.vm_resources.vm_config,
))),
GetVmInstanceInfo => Ok(VmmData::InstanceInformation(
self.vmm.lock().expect("Poisoned lock").instance_info(),
)),
GetVmInstanceInfo => {
let locked_vmm = self.vmm.lock().expect("Poisoned lock");

let mut instance_info = locked_vmm.instance_info();

instance_info.memory_regions =
Some(locked_vmm.guest_memory_mappings(&VmInfo::from(&self.vm_resources)));

Ok(VmmData::InstanceInformation(instance_info))
}
GetVmmVersion => Ok(VmmData::VmmVersion(
self.vmm.lock().expect("Poisoned lock").version(),
)),
Expand Down Expand Up @@ -1150,7 +1157,7 @@ mod tests {
CreateSnapshotParams {
snapshot_type: SnapshotType::Full,
snapshot_path: PathBuf::new(),
mem_file_path: PathBuf::new(),
mem_file_path: Some(PathBuf::new()),
},
)));
#[cfg(target_arch = "x86_64")]
Expand Down
Loading
Loading