mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-01 17:35:19 +00:00
vmm: Simplify snapshot/restore path handling
Extend the existing url_to_path() to take the URL string and then use that to simplify the snapshot/restore code paths. Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
ebcbab739e
commit
cc78a597cd
@ -6,6 +6,7 @@ extern crate hypervisor;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::config::SgxEpcConfig;
|
||||
use crate::config::{HotplugMethod, MemoryConfig, MemoryZoneConfig};
|
||||
use crate::migration::url_to_path;
|
||||
use crate::MEMORY_MANAGER_SNAPSHOT_ID;
|
||||
#[cfg(feature = "acpi")]
|
||||
use acpi_tables::{aml, aml::Aml};
|
||||
@ -851,9 +852,7 @@ impl MemoryManager {
|
||||
)?;
|
||||
|
||||
if let Some(source_url) = source_url {
|
||||
let url = Url::parse(source_url).unwrap();
|
||||
/* url must be valid dir which is verified in recv_vm_snapshot() */
|
||||
let vm_snapshot_path = url.to_file_path().unwrap();
|
||||
let vm_snapshot_path = url_to_path(source_url).map_err(Error::Restore)?;
|
||||
|
||||
if let Some(mem_section) = snapshot
|
||||
.snapshot_data
|
||||
|
@ -7,61 +7,40 @@ use anyhow::anyhow;
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
use std::path::PathBuf;
|
||||
use url::Url;
|
||||
use vm_migration::{MigratableError, Snapshot};
|
||||
|
||||
pub const VM_SNAPSHOT_FILE: &str = "vm.json";
|
||||
|
||||
pub fn url_to_path(url: &Url) -> std::result::Result<PathBuf, MigratableError> {
|
||||
match url.scheme() {
|
||||
"file" => url
|
||||
.to_file_path()
|
||||
.map_err(|_| {
|
||||
MigratableError::MigrateSend(anyhow!(
|
||||
"Could not convert file URL to a file path: {}",
|
||||
url.as_str()
|
||||
))
|
||||
})
|
||||
.and_then(|path| {
|
||||
if !path.is_dir() {
|
||||
return Err(MigratableError::MigrateSend(anyhow!(
|
||||
"Destination is not a directory"
|
||||
)));
|
||||
}
|
||||
Ok(path)
|
||||
}),
|
||||
pub fn url_to_path(url: &str) -> std::result::Result<PathBuf, MigratableError> {
|
||||
let path: PathBuf = url
|
||||
.strip_prefix("file://")
|
||||
.ok_or_else(|| {
|
||||
MigratableError::MigrateSend(anyhow!("Could not extract path from URL: {}", url))
|
||||
})
|
||||
.map(|s| s.into())?;
|
||||
|
||||
_ => Err(MigratableError::MigrateSend(anyhow!(
|
||||
"URL scheme is not file: {}",
|
||||
url.scheme()
|
||||
))),
|
||||
if !path.is_dir() {
|
||||
return Err(MigratableError::MigrateSend(anyhow!(
|
||||
"Destination is not a directory"
|
||||
)));
|
||||
}
|
||||
|
||||
Ok(path)
|
||||
}
|
||||
|
||||
pub fn recv_vm_snapshot(source_url: &str) -> std::result::Result<Snapshot, MigratableError> {
|
||||
let url = Url::parse(source_url).map_err(|e| {
|
||||
MigratableError::MigrateSend(anyhow!("Could not parse destination URL: {}", e))
|
||||
})?;
|
||||
let mut vm_snapshot_path = url_to_path(source_url)?;
|
||||
|
||||
match url.scheme() {
|
||||
"file" => {
|
||||
let mut vm_snapshot_path = url_to_path(&url)?;
|
||||
vm_snapshot_path.push(VM_SNAPSHOT_FILE);
|
||||
vm_snapshot_path.push(VM_SNAPSHOT_FILE);
|
||||
|
||||
// Try opening the snapshot file
|
||||
let vm_snapshot_file =
|
||||
File::open(vm_snapshot_path).map_err(|e| MigratableError::MigrateSend(e.into()))?;
|
||||
let vm_snapshot_reader = BufReader::new(vm_snapshot_file);
|
||||
let vm_snapshot = serde_json::from_reader(vm_snapshot_reader)
|
||||
.map_err(|e| MigratableError::MigrateReceive(e.into()))?;
|
||||
// Try opening the snapshot file
|
||||
let vm_snapshot_file =
|
||||
File::open(vm_snapshot_path).map_err(|e| MigratableError::MigrateSend(e.into()))?;
|
||||
let vm_snapshot_reader = BufReader::new(vm_snapshot_file);
|
||||
let vm_snapshot = serde_json::from_reader(vm_snapshot_reader)
|
||||
.map_err(|e| MigratableError::MigrateReceive(e.into()))?;
|
||||
|
||||
Ok(vm_snapshot)
|
||||
}
|
||||
_ => Err(MigratableError::MigrateSend(anyhow!(
|
||||
"Unsupported VM transport URL scheme: {}",
|
||||
url.scheme()
|
||||
))),
|
||||
}
|
||||
Ok(vm_snapshot)
|
||||
}
|
||||
|
||||
pub fn get_vm_snapshot(snapshot: &Snapshot) -> std::result::Result<VmSnapshot, MigratableError> {
|
||||
|
@ -71,7 +71,6 @@ use std::num::Wrapping;
|
||||
use std::ops::Deref;
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
use std::{result, str, thread};
|
||||
use url::Url;
|
||||
use vm_device::Bus;
|
||||
use vm_memory::{
|
||||
Address, Bytes, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic,
|
||||
@ -2311,52 +2310,37 @@ impl Transportable for Vm {
|
||||
snapshot: &Snapshot,
|
||||
destination_url: &str,
|
||||
) -> std::result::Result<(), MigratableError> {
|
||||
let url = Url::parse(destination_url).map_err(|e| {
|
||||
MigratableError::MigrateSend(anyhow!("Could not parse destination URL: {}", e))
|
||||
})?;
|
||||
let mut vm_snapshot_path = url_to_path(destination_url)?;
|
||||
vm_snapshot_path.push(VM_SNAPSHOT_FILE);
|
||||
|
||||
match url.scheme() {
|
||||
"file" => {
|
||||
let mut vm_snapshot_path = url_to_path(&url)?;
|
||||
vm_snapshot_path.push(VM_SNAPSHOT_FILE);
|
||||
// Create the snapshot file
|
||||
let mut vm_snapshot_file = OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.create_new(true)
|
||||
.open(vm_snapshot_path)
|
||||
.map_err(|e| MigratableError::MigrateSend(e.into()))?;
|
||||
|
||||
// Create the snapshot file
|
||||
let mut vm_snapshot_file = OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.create_new(true)
|
||||
.open(vm_snapshot_path)
|
||||
.map_err(|e| MigratableError::MigrateSend(e.into()))?;
|
||||
// Serialize and write the snapshot
|
||||
let vm_snapshot =
|
||||
serde_json::to_vec(snapshot).map_err(|e| MigratableError::MigrateSend(e.into()))?;
|
||||
|
||||
// Serialize and write the snapshot
|
||||
let vm_snapshot = serde_json::to_vec(snapshot)
|
||||
.map_err(|e| MigratableError::MigrateSend(e.into()))?;
|
||||
vm_snapshot_file
|
||||
.write(&vm_snapshot)
|
||||
.map_err(|e| MigratableError::MigrateSend(e.into()))?;
|
||||
|
||||
vm_snapshot_file
|
||||
.write(&vm_snapshot)
|
||||
.map_err(|e| MigratableError::MigrateSend(e.into()))?;
|
||||
|
||||
// Tell the memory manager to also send/write its own snapshot.
|
||||
if let Some(memory_manager_snapshot) =
|
||||
snapshot.snapshots.get(MEMORY_MANAGER_SNAPSHOT_ID)
|
||||
{
|
||||
self.memory_manager
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(&*memory_manager_snapshot.clone(), destination_url)?;
|
||||
} else {
|
||||
return Err(MigratableError::Restore(anyhow!(
|
||||
"Missing memory manager snapshot"
|
||||
)));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(MigratableError::MigrateSend(anyhow!(
|
||||
"Unsupported VM transport URL scheme: {}",
|
||||
url.scheme()
|
||||
)))
|
||||
}
|
||||
// Tell the memory manager to also send/write its own snapshot.
|
||||
if let Some(memory_manager_snapshot) = snapshot.snapshots.get(MEMORY_MANAGER_SNAPSHOT_ID) {
|
||||
self.memory_manager
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(&*memory_manager_snapshot.clone(), destination_url)?;
|
||||
} else {
|
||||
return Err(MigratableError::Restore(anyhow!(
|
||||
"Missing memory manager snapshot"
|
||||
)));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user