Skip to content

Commit cea28a0

Browse files
vibharyadianpopa
authored andcommitted
[snapshot-ga] Additional info added to snap state
Signed-off-by: Vibha Acharya <vibharya@amazon.co.uk>
1 parent 8a7152a commit cea28a0

File tree

10 files changed

+150
-42
lines changed

10 files changed

+150
-42
lines changed

src/vmm/benches/main.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion};
1616
use snapshot::Snapshot;
1717
use utils::tempfile::TempFile;
1818
use versionize::VersionMap;
19-
use vmm::persist::MicrovmState;
19+
use vmm::persist::{MicrovmState, VmInfo};
2020
use vmm::utilities::mock_resources::NOISY_KERNEL_IMAGE;
2121
use vmm::utilities::test_utils::create_vmm;
2222
use vmm::version_map::VERSION_MAP;
23+
use vmm::vmm_config::boot_source::BootSourceConfig;
24+
use vmm::vmm_config::machine_config::CpuFeaturesTemplate;
2325
use vmm::vmm_config::snapshot::{CreateSnapshotParams, SnapshotType};
2426
use vmm::{persist, FcExitCode};
2527

@@ -78,10 +80,20 @@ fn create_microvm_state(is_diff: bool) -> MicrovmState {
7880
mem_file_path: memory_file.as_path().to_path_buf(),
7981
version: None,
8082
};
83+
let mut vm_info = VmInfo {
84+
mem_size_mib: 1u64,
85+
..Default::default()
86+
};
8187

8288
{
8389
let mut locked_vmm = vmm.lock().unwrap();
84-
persist::create_snapshot(&mut locked_vmm, &snapshot_params, VERSION_MAP.clone()).unwrap();
90+
persist::create_snapshot(
91+
&mut locked_vmm,
92+
&mut vm_info,
93+
&snapshot_params,
94+
VERSION_MAP.clone(),
95+
)
96+
.unwrap();
8597
}
8698

8799
vmm.lock().unwrap().stop(FcExitCode::Ok);

src/vmm/src/builder.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ use crate::vmm_config::machine_config::{VmConfigError, VmUpdateConfig};
5151
use crate::vstate::system::KvmContext;
5252
use crate::vstate::vcpu::{Vcpu, VcpuConfig};
5353
use crate::vstate::vm::Vm;
54-
use crate::{device_manager, mem_size_mib, Error, EventManager, Vmm, VmmEventsObserver};
54+
use crate::{device_manager, Error, EventManager, Vmm, VmmEventsObserver};
5555

5656
/// Errors associated with starting the instance.
5757
#[derive(Debug)]
@@ -565,12 +565,15 @@ pub fn build_microvm_from_snapshot(
565565

566566
vm_resources.update_vm_config(&VmUpdateConfig {
567567
vcpu_count: Some(vcpu_count),
568-
mem_size_mib: Some(mem_size_mib(&guest_memory) as usize),
569-
smt: Some(false),
570-
cpu_template: None,
568+
mem_size_mib: Some(microvm_state.vm_info.mem_size_mib as usize),
569+
smt: Some(microvm_state.vm_info.smt),
570+
cpu_template: Some(microvm_state.vm_info.cpu_template),
571571
track_dirty_pages: Some(track_dirty_pages),
572572
})?;
573573

574+
// Restore the boot source config paths.
575+
vm_resources.set_boot_source_config(microvm_state.vm_info.boot_source);
576+
574577
// Restore devices states.
575578
let mmio_ctor_args = MMIODevManagerConstructorArgs {
576579
mem: guest_memory,

src/vmm/src/lib.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,10 @@ impl Vmm {
461461
}
462462

463463
/// Saves the state of a paused Microvm.
464-
pub fn save_state(&mut self) -> std::result::Result<MicrovmState, MicrovmStateError> {
464+
pub fn save_state(
465+
&mut self,
466+
vm_info: &VmInfo,
467+
) -> std::result::Result<MicrovmState, MicrovmStateError> {
465468
use self::MicrovmStateError::SaveVmState;
466469
let vcpu_states = self.save_vcpu_states()?;
467470
let vm_state = {
@@ -478,11 +481,10 @@ impl Vmm {
478481
};
479482
let device_states = self.mmio_device_manager.save();
480483

481-
let mem_size_mib = mem_size_mib(self.guest_memory());
482484
let memory_state = self.guest_memory().describe();
483485

484486
Ok(MicrovmState {
485-
vm_info: VmInfo { mem_size_mib },
487+
vm_info: vm_info.clone(),
486488
memory_state,
487489
vm_state,
488490
vcpu_states,

src/vmm/src/persist.rs

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use arch::regs::{get_manufacturer_id_from_host, get_manufacturer_id_from_state};
1616
#[cfg(target_arch = "x86_64")]
1717
use cpuid::common::{get_vendor_id_from_cpuid, get_vendor_id_from_host};
1818
use devices::virtio::TYPE_NET;
19-
use logger::{error, info};
19+
use logger::{error, info, warn};
2020
use seccompiler::BpfThreadMap;
2121
use serde::Serialize;
2222
use snapshot::Snapshot;
@@ -34,8 +34,9 @@ use crate::resources::VmResources;
3434
#[cfg(target_arch = "x86_64")]
3535
use crate::version_map::FC_V0_23_SNAP_VERSION;
3636
use crate::version_map::{FC_V1_0_SNAP_VERSION, FC_V1_1_SNAP_VERSION, FC_VERSION_TO_SNAP_VERSION};
37+
use crate::vmm_config::boot_source::BootSourceConfig;
3738
use crate::vmm_config::instance_info::InstanceInfo;
38-
use crate::vmm_config::machine_config::MAX_SUPPORTED_VCPUS;
39+
use crate::vmm_config::machine_config::{CpuFeaturesTemplate, MAX_SUPPORTED_VCPUS};
3940
use crate::vmm_config::snapshot::{
4041
CreateSnapshotParams, LoadSnapshotParams, MemBackendType, SnapshotType,
4142
};
@@ -47,11 +48,59 @@ use crate::{mem_size_mib, memory_snapshot, vstate, Error as VmmError, EventManag
4748
const FC_V0_23_MAX_DEVICES: u32 = 11;
4849

4950
/// Holds information related to the VM that is not part of VmState.
50-
#[derive(Debug, PartialEq, Versionize)]
51+
#[derive(Clone, Debug, Default, PartialEq, Versionize, Serialize)]
5152
// NOTICE: Any changes to this structure require a snapshot version bump.
5253
pub struct VmInfo {
5354
/// Guest memory size.
5455
pub mem_size_mib: u64,
56+
/// smt information
57+
#[version(start = 2, default_fn = "def_smt", ser_fn = "ser_smt")]
58+
pub smt: bool,
59+
/// CPU template type
60+
#[version(
61+
start = 2,
62+
default_fn = "def_cpu_template",
63+
ser_fn = "ser_cpu_template"
64+
)]
65+
pub cpu_template: CpuFeaturesTemplate,
66+
/// Boot source information.
67+
#[version(start = 2, default_fn = "def_boot_source", ser_fn = "ser_boot_source")]
68+
pub boot_source: BootSourceConfig,
69+
}
70+
71+
impl VmInfo {
72+
fn def_smt(_: u16) -> bool {
73+
warn!("SMT field not found in snapshot.");
74+
false
75+
}
76+
77+
fn ser_smt(&mut self, _target_version: u16) -> VersionizeResult<()> {
78+
// v1.1 and older versions do not include smt info.
79+
warn!("Saving to older snapshot version, SMT information will not be saved.");
80+
Ok(())
81+
}
82+
83+
fn def_cpu_template(_: u16) -> CpuFeaturesTemplate {
84+
warn!("CPU template field not found in snapshot.");
85+
CpuFeaturesTemplate::None
86+
}
87+
88+
fn ser_cpu_template(&mut self, _target_version: u16) -> VersionizeResult<()> {
89+
// v1.1 and older versions do not include cpu template info.
90+
warn!("Saving to older snapshot version, CPU template information will not be saved.");
91+
Ok(())
92+
}
93+
94+
fn def_boot_source(_: u16) -> BootSourceConfig {
95+
warn!("Boot source information not found in snapshot.");
96+
BootSourceConfig::default()
97+
}
98+
99+
fn ser_boot_source(&mut self, _target_version: u16) -> VersionizeResult<()> {
100+
// v1.1 and older versions do not include boot source info.
101+
warn!("Saving to older snapshot version, boot source information will not be saved.");
102+
Ok(())
103+
}
55104
}
56105

57106
/// Contains the necesary state for saving/restoring a microVM.
@@ -195,14 +244,15 @@ impl Display for CreateSnapshotError {
195244
/// Creates a Microvm snapshot.
196245
pub fn create_snapshot(
197246
vmm: &mut Vmm,
247+
vm_info: &VmInfo,
198248
params: &CreateSnapshotParams,
199249
version_map: VersionMap,
200250
) -> std::result::Result<(), CreateSnapshotError> {
201251
// Fail early from invalid target version.
202252
let snapshot_data_version = get_snapshot_data_version(&params.version, &version_map, &vmm)?;
203253

204254
let microvm_state = vmm
205-
.save_state()
255+
.save_state(vm_info)
206256
.map_err(CreateSnapshotError::MicrovmState)?;
207257

208258
snapshot_state_to_file(
@@ -787,7 +837,10 @@ mod tests {
787837
device_states: states,
788838
memory_state,
789839
vcpu_states,
790-
vm_info: VmInfo { mem_size_mib: 1u64 },
840+
vm_info: VmInfo {
841+
mem_size_mib: 1u64,
842+
..Default::default()
843+
},
791844
#[cfg(target_arch = "aarch64")]
792845
vm_state: vmm.vm.save_state(&mpidrs).unwrap(),
793846
#[cfg(target_arch = "x86_64")]

src/vmm/src/rpc_interface.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use super::{
2222
resources::VmResources, Vmm,
2323
};
2424
use crate::builder::StartMicrovmError;
25-
use crate::persist::{CreateSnapshotError, RestoreFromSnapshotError};
25+
use crate::persist::{CreateSnapshotError, RestoreFromSnapshotError, VmInfo};
2626
use crate::resources::VmmConfig;
2727
use crate::version_map::VERSION_MAP;
2828
use crate::vmm_config::balloon::{
@@ -743,9 +743,21 @@ impl RuntimeApiController {
743743
}
744744

745745
let mut locked_vmm = self.vmm.lock().unwrap();
746+
let vm_cfg = self.vm_resources.vm_config();
747+
let vm_info = VmInfo {
748+
mem_size_mib: vm_cfg.mem_size_mib as u64,
749+
smt: vm_cfg.smt,
750+
cpu_template: vm_cfg.cpu_template,
751+
boot_source: self.vm_resources.boot_source_config().clone(),
752+
};
746753
let create_start_us = utils::time::get_time_us(utils::time::ClockType::Monotonic);
747754

748-
create_snapshot(&mut locked_vmm, create_params, VERSION_MAP.clone())?;
755+
create_snapshot(
756+
&mut locked_vmm,
757+
&vm_info,
758+
create_params,
759+
VERSION_MAP.clone(),
760+
)?;
749761

750762
match create_params.snapshot_type {
751763
SnapshotType::Full => {
@@ -865,6 +877,7 @@ mod tests {
865877
pub vsock: VsockBuilder,
866878
balloon_config_called: bool,
867879
balloon_set: bool,
880+
boot_src: BootSourceConfig,
868881
boot_cfg_set: bool,
869882
block_set: bool,
870883
vsock_set: bool,
@@ -927,17 +940,22 @@ mod tests {
927940

928941
pub fn build_boot_source(
929942
&mut self,
930-
_: BootSourceConfig,
943+
boot_source: BootSourceConfig,
931944
) -> Result<(), BootSourceConfigError> {
932945
if self.force_errors {
933946
return Err(BootSourceConfigError::InvalidKernelPath(
934947
std::io::Error::from_raw_os_error(0),
935948
));
936949
}
950+
self.boot_src = boot_source;
937951
self.boot_cfg_set = true;
938952
Ok(())
939953
}
940954

955+
pub fn boot_source_config(&mut self) -> &BootSourceConfig {
956+
&self.boot_src
957+
}
958+
941959
pub fn set_block_device(&mut self, _: BlockDeviceConfig) -> Result<(), DriveError> {
942960
if self.force_errors {
943961
return Err(DriveError::RootBlockDeviceAlreadyAdded);
@@ -1140,6 +1158,7 @@ mod tests {
11401158
// instead of our mocks.
11411159
pub fn create_snapshot(
11421160
_: &mut Vmm,
1161+
_: &VmInfo,
11431162
_: &CreateSnapshotParams,
11441163
_: versionize::VersionMap,
11451164
) -> std::result::Result<(), CreateSnapshotError> {

src/vmm/src/version_map.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use lazy_static::lazy_static;
1111
use versionize::{VersionMap, Versionize};
1212

1313
use crate::device_manager::persist::DeviceStates;
14+
use crate::persist::VmInfo;
1415
#[cfg(target_arch = "x86_64")]
1516
use crate::vstate::vcpu::VcpuState;
1617

@@ -25,6 +26,8 @@ pub const FC_V0_25_SNAP_VERSION: u16 = 3;
2526
pub const FC_V1_0_SNAP_VERSION: u16 = 4;
2627
/// Snap version for Firecracker v1.1
2728
pub const FC_V1_1_SNAP_VERSION: u16 = 5;
29+
/// Snap version for Firecracker v1.2
30+
pub const FC_V1_2_SNAP_VERSION: u16 = 6;
2831

2932
lazy_static! {
3033
// Note: until we have a better design, this needs to be updated when the version changes.
@@ -48,6 +51,9 @@ lazy_static! {
4851
// v1.1 state change mappings.
4952
version_map.new_version().set_type_version(DeviceStates::type_id(), 3);
5053

54+
// v1.2 state change mappings.
55+
version_map.new_version().set_type_version(VmInfo::type_id(), 2);
56+
5157
version_map
5258
};
5359

@@ -62,6 +68,7 @@ lazy_static! {
6268
mapping.insert(String::from("0.25.0"), FC_V0_25_SNAP_VERSION);
6369
mapping.insert(String::from("1.0.0"), FC_V1_0_SNAP_VERSION);
6470
mapping.insert(String::from("1.1.0"), FC_V1_1_SNAP_VERSION);
71+
mapping.insert(String::from("1.2.0"), FC_V1_2_SNAP_VERSION);
6572

6673
mapping
6774
};

src/vmm/src/vmm_config/boot_source.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use std::fs::File;
66
use std::io;
77

88
use serde::{Deserialize, Serialize};
9+
use versionize::{VersionMap, Versionize, VersionizeResult};
10+
use versionize_derive::Versionize;
911

1012
/// Default guest kernel command line:
1113
/// - `reboot=k` shut down the guest on reboot, instead of well... rebooting;
@@ -22,7 +24,7 @@ pub const DEFAULT_KERNEL_CMDLINE: &str = "reboot=k panic=1 pci=off nomodules 825
2224

2325
/// Strongly typed data structure used to configure the boot source of the
2426
/// microvm.
25-
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
27+
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize, Versionize)]
2628
#[serde(deny_unknown_fields)]
2729
pub struct BootSourceConfig {
2830
/// Path of the kernel image.

src/vmm/src/vmm_config/machine_config.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
3-
43
use std::fmt;
54

65
use serde::{de, Deserialize, Serialize};
6+
use versionize::{VersionMap, Versionize, VersionizeError, VersionizeResult};
7+
use versionize_derive::Versionize;
78

89
/// The default memory size of the VM, in MiB.
910
pub const DEFAULT_MEM_SIZE_MIB: usize = 128;
@@ -237,7 +238,7 @@ where
237238

238239
/// Template types available for configuring the CPU features that map
239240
/// to EC2 instances.
240-
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
241+
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize, Versionize)]
241242
pub enum CpuFeaturesTemplate {
242243
/// C3 Template.
243244
C3,

0 commit comments

Comments
 (0)