Skip to content

Commit fdeba39

Browse files
committed
feat(snapshot): allow vsock uds path override on restore
This commit introduces the ability to override the vsock's backing Unix Domain Socket (UDS) path when restoring a VM from a snapshot. This is useful in scenarios where the original UDS path is not available on the host where the snapshot is being restored, for example when restoring on a different machine. A new `vsock_override` field has been added to the `/snapshot/load` API endpoint to specify the new UDS path. Signed-off-by: Sheng-Wei (Way) Chen <[email protected]>
1 parent 70745e1 commit fdeba39

File tree

6 files changed

+54
-2
lines changed

6 files changed

+54
-2
lines changed

docs/snapshotting/snapshot-support.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
- [Snapshot security and uniqueness](#snapshot-security-and-uniqueness)
2525
- [Secure and insecure usage examples](#usage-examples)
2626
- [Reusing snapshotted states securely](#reusing-snapshotted-states-securely)
27-
- [Vsock device limitation](#vsock-device-limitation)
27+
- [Vsock device reset](#vsock-device-reset)
2828
- [VMGenID device limitation](#vmgenid-device-limitation)
2929
- [Where can I resume my snapshots?](#where-can-i-resume-my-snapshots)
3030

src/firecracker/src/api_server/request/snapshot.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ fn parse_put_snapshot_load(body: &Body) -> Result<ParsedRequest, RequestError> {
110110
|| snapshot_config.track_dirty_pages,
111111
resume_vm: snapshot_config.resume_vm,
112112
network_overrides: snapshot_config.network_overrides,
113+
vsock_override: snapshot_config.vsock_override,
113114
};
114115

115116
// Construct the `ParsedRequest` object.
@@ -187,6 +188,7 @@ mod tests {
187188
track_dirty_pages: false,
188189
resume_vm: false,
189190
network_overrides: vec![],
191+
vsock_override: None,
190192
};
191193
let mut parsed_request = parse_put_snapshot(&Body::new(body), Some("load")).unwrap();
192194
assert!(
@@ -217,6 +219,7 @@ mod tests {
217219
track_dirty_pages: true,
218220
resume_vm: false,
219221
network_overrides: vec![],
222+
vsock_override: None,
220223
};
221224
let mut parsed_request = parse_put_snapshot(&Body::new(body), Some("load")).unwrap();
222225
assert!(
@@ -247,6 +250,7 @@ mod tests {
247250
track_dirty_pages: false,
248251
resume_vm: true,
249252
network_overrides: vec![],
253+
vsock_override: None,
250254
};
251255
let mut parsed_request = parse_put_snapshot(&Body::new(body), Some("load")).unwrap();
252256
assert!(
@@ -286,6 +290,7 @@ mod tests {
286290
iface_id: String::from("eth0"),
287291
host_dev_name: String::from("vmtap2"),
288292
}],
293+
vsock_override: None,
289294
};
290295
let mut parsed_request = parse_put_snapshot(&Body::new(body), Some("load")).unwrap();
291296
assert!(
@@ -313,6 +318,7 @@ mod tests {
313318
track_dirty_pages: false,
314319
resume_vm: true,
315320
network_overrides: vec![],
321+
vsock_override: None,
316322
};
317323
let parsed_request = parse_put_snapshot(&Body::new(body), Some("load")).unwrap();
318324
assert_eq!(

src/firecracker/swagger/firecracker.yaml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1233,7 +1233,19 @@ definitions:
12331233
type: string
12341234
description:
12351235
The new host device of the interface
1236-
1236+
VsockOverride:
1237+
type: object
1238+
description:
1239+
Allows for changing the backing Unix Domain Socket of a vsock device
1240+
during snapshot restore.
1241+
required:
1242+
- uds_path
1243+
properties:
1244+
uds_path:
1245+
type: string
1246+
description:
1247+
The new path for the backing Unix Domain Socket.
1248+
12371249
SnapshotLoadParams:
12381250
type: object
12391251
description:
@@ -1274,6 +1286,13 @@ definitions:
12741286
description: Network host device names to override
12751287
items:
12761288
$ref: "#/definitions/NetworkOverride"
1289+
vsock_override:
1290+
$ref: "#/definitions/VsockOverride"
1291+
description:
1292+
Overrides the vsock device's UDS path on snapshot restore. This is useful
1293+
for restoring a snapshot with a different socket path than the one used
1294+
when the snapshot was created. For example, when the original socket path
1295+
is no longer available or when deploying to a different environment.
12771296

12781297

12791298
TokenBucket:

src/vmm/src/persist.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use crate::cpu_config::x86_64::cpuid::CpuidTrait;
2626
#[cfg(target_arch = "x86_64")]
2727
use crate::cpu_config::x86_64::cpuid::common::get_vendor_id_from_host;
2828
use crate::device_manager::persist::{ACPIDeviceManagerState, DevicePersistError, DeviceStates};
29+
use crate::devices::virtio::vsock::persist::{VsockBackendState, VsockUdsState};
2930
use crate::logger::{info, warn};
3031
use crate::resources::VmResources;
3132
use crate::seccomp::BpfThreadMap;
@@ -347,6 +348,17 @@ pub fn restore_from_snapshot(
347348
return Err(SnapshotStateFromFileError::UnknownNetworkDevice.into());
348349
}
349350
}
351+
352+
if let Some(vsock_override) = &params.vsock_override {
353+
if let Some(vsock_device) = microvm_state.device_states.vsock_device.as_mut() {
354+
vsock_device.device_state.backend = VsockBackendState::Uds(VsockUdsState {
355+
path: vsock_override.uds_path.clone(),
356+
});
357+
} else {
358+
return Err(SnapshotStateFromFileError::UnknownVsockDevice.into());
359+
}
360+
}
361+
350362
let track_dirty_pages = params.track_dirty_pages;
351363

352364
let vcpu_count = microvm_state
@@ -420,6 +432,8 @@ pub enum SnapshotStateFromFileError {
420432
Load(#[from] crate::snapshot::SnapshotError),
421433
/// Unknown Network Device.
422434
UnknownNetworkDevice,
435+
/// Unknown Vsock Device.
436+
UnknownVsockDevice,
423437
}
424438

425439
fn snapshot_state_from_file(

src/vmm/src/rpc_interface.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,6 +1258,7 @@ mod tests {
12581258
track_dirty_pages: false,
12591259
resume_vm: false,
12601260
network_overrides: vec![],
1261+
vsock_override: None,
12611262
},
12621263
)));
12631264
check_unsupported(runtime_request(VmmAction::SetEntropyDevice(

src/vmm/src/vmm_config/snapshot.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ pub struct NetworkOverride {
5757
pub host_dev_name: String,
5858
}
5959

60+
/// Allows for changing the host UDS of the vsock backend during snapshot restore
61+
#[derive(Debug, PartialEq, Eq, Deserialize)]
62+
pub struct VsockOverride {
63+
/// The path to the UDS that will be used for the vsock interface
64+
pub uds_path: String,
65+
}
66+
6067
/// Stores the configuration that will be used for loading a snapshot.
6168
#[derive(Debug, PartialEq, Eq)]
6269
pub struct LoadSnapshotParams {
@@ -72,6 +79,8 @@ pub struct LoadSnapshotParams {
7279
pub resume_vm: bool,
7380
/// The network devices to override on load.
7481
pub network_overrides: Vec<NetworkOverride>,
82+
/// When set, the vsock backend UDS path will be overridden
83+
pub vsock_override: Option<VsockOverride>,
7584
}
7685

7786
/// Stores the configuration for loading a snapshot that is provided by the user.
@@ -101,6 +110,9 @@ pub struct LoadSnapshotConfig {
101110
/// The network devices to override on load.
102111
#[serde(default)]
103112
pub network_overrides: Vec<NetworkOverride>,
113+
/// Whether or not to override the vsock backend UDS path.
114+
#[serde(skip_serializing_if = "Option::is_none")]
115+
pub vsock_override: Option<VsockOverride>,
104116
}
105117

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

0 commit comments

Comments
 (0)