Skip to content

Commit 0dc6a29

Browse files
snapshot: add container_snapshot_path to load snapshot request
When a snapshot of a VM created by firecracker-containerd is restored, due to the non-deterministic container snapshot path (it depends on the containerd snapshotter implementation), the container snapshot path at the time of the snapshot creation is different from the container snapshot path at the time of the snapshot loading. Firecracker does not support renaming resources at snapshot-restore, so as a workaround we manually substitute the VM state with the path of the block device backing the container snapshot to the path of the new container snapshot path received from the LoadSnapshot request. Closes firecracker-microvm#4014 Signed-off-by: Georgiy Lebedev <[email protected]>
1 parent 1639a95 commit 0dc6a29

File tree

5 files changed

+30
-2
lines changed

5 files changed

+30
-2
lines changed

src/api_server/src/request/snapshot.rs

+1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ fn parse_put_snapshot_load(body: &Body) -> Result<ParsedRequest, Error> {
9494
mem_backend,
9595
enable_diff_snapshots: snapshot_config.enable_diff_snapshots,
9696
resume_vm: snapshot_config.resume_vm,
97+
container_snapshot_path: snapshot_config.container_snapshot_path,
9798
};
9899

99100
// Construct the `ParsedRequest` object.

src/api_server/swagger/firecracker.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -1188,6 +1188,7 @@ definitions:
11881188
the two `mem_*` fields must be present in the body of the request.
11891189
required:
11901190
- snapshot_path
1191+
- container_snapshot_path
11911192
properties:
11921193
enable_diff_snapshots:
11931194
type: boolean
@@ -1212,6 +1213,10 @@ definitions:
12121213
type: boolean
12131214
description:
12141215
When set to true, the vm is also resumed if the snapshot load is successful.
1216+
container_snapshot_path:
1217+
type: string
1218+
description:
1219+
Path to the disk device backing the disk state at the time of the snapshot creation.
12151220

12161221
TokenBucket:
12171222
type: object

src/vmm/src/devices/virtio/block/persist.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ pub struct BlockState {
9595
)]
9696
cache_type: CacheTypeState,
9797
root_device: bool,
98-
disk_path: String,
98+
pub disk_path: String,
9999
virtio_state: VirtioDeviceState,
100100
rate_limiter_state: RateLimiterState,
101101
#[version(start = 3)]

src/vmm/src/persist.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,25 @@ pub fn restore_from_snapshot(
521521
version_map: VersionMap,
522522
vm_resources: &mut VmResources,
523523
) -> Result<Arc<Mutex<Vmm>>, RestoreFromSnapshotError> {
524-
let microvm_state = snapshot_state_from_file(&params.snapshot_path, version_map)?;
524+
let mut microvm_state = snapshot_state_from_file(&params.snapshot_path, version_map)?;
525+
526+
let container_snapshot_path = &params.container_snapshot_path;
527+
// We assume that each microVM is backed by exactly one container image
528+
// snapshot device (i.e., that no more than one container is run on each microVM).
529+
assert_eq!(microvm_state.device_states.block_devices.len(), 2);
530+
for i in 0..2 {
531+
// We assume that one of the block devices is the rootfs, the other being the
532+
// container image snapshot.
533+
if microvm_state.device_states.block_devices[i]
534+
.device_state
535+
.disk_path
536+
.contains("snap")
537+
{
538+
microvm_state.device_states.block_devices[i]
539+
.device_state
540+
.disk_path = container_snapshot_path.clone();
541+
}
542+
}
525543

526544
// Some sanity checks before building the microvm.
527545
snapshot_state_sanity_check(&microvm_state)?;

src/vmm/src/vmm_config/snapshot.rs

+4
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ pub struct LoadSnapshotParams {
6363
/// When set to true, the vm is also resumed if the snapshot load
6464
/// is successful.
6565
pub resume_vm: bool,
66+
/// Path to the disk device backing the container snapshot.
67+
pub container_snapshot_path: String,
6668
}
6769

6870
/// Stores the configuration for loading a snapshot that is provided by the user.
@@ -85,6 +87,8 @@ pub struct LoadSnapshotConfig {
8587
/// Whether or not to resume the vm post snapshot load.
8688
#[serde(default)]
8789
pub resume_vm: bool,
90+
/// Path to the disk device backing the container snapshot.
91+
pub container_snapshot_path: String,
8892
}
8993

9094
/// Stores the configuration used for managing snapshot memory.

0 commit comments

Comments
 (0)