mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-11-04 19:11:11 +00:00
vm-migration: Add start_migration() to Migratable trait
In order to clearly decouple when the migration is started compared to when the dirty logging is started, we introduce a new method to the Migratable trait. This clarifies the semantics as we don't end up using start_dirty_log() for identifying when the migration has been started. And similarly, we rely on the already existing complete_migration() method to know when the migration has been ended. A bug was reported when running a local migration with a vhost-user-net device in server mode. The reason was because the migration_started variable was never set to "true", since the start_dirty_log() function was never invoked. Signed-off-by: lizhaoxin1 <Lxiaoyouling@163.com> Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
a061bc32e4
commit
a45e458c50
@ -417,6 +417,10 @@ impl Migratable for Blk {
|
||||
self.vu_common.dirty_log(&self.guest_memory)
|
||||
}
|
||||
|
||||
fn start_migration(&mut self) -> std::result::Result<(), MigratableError> {
|
||||
self.vu_common.start_migration()
|
||||
}
|
||||
|
||||
fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> {
|
||||
self.vu_common
|
||||
.complete_migration(self.common.kill_evt.take())
|
||||
|
@ -698,6 +698,10 @@ impl Migratable for Fs {
|
||||
self.vu_common.dirty_log(&self.guest_memory)
|
||||
}
|
||||
|
||||
fn start_migration(&mut self) -> std::result::Result<(), MigratableError> {
|
||||
self.vu_common.start_migration()
|
||||
}
|
||||
|
||||
fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> {
|
||||
self.vu_common
|
||||
.complete_migration(self.common.kill_evt.take())
|
||||
|
@ -451,7 +451,6 @@ impl VhostUserCommon {
|
||||
&mut self,
|
||||
guest_memory: &Option<GuestMemoryAtomic<GuestMemoryMmap>>,
|
||||
) -> std::result::Result<(), MigratableError> {
|
||||
self.migration_started = true;
|
||||
if let Some(vu) = &self.vu {
|
||||
if let Some(guest_memory) = guest_memory {
|
||||
let last_ram_addr = guest_memory.memory().last_addr().raw_value();
|
||||
@ -475,7 +474,6 @@ impl VhostUserCommon {
|
||||
}
|
||||
|
||||
pub fn stop_dirty_log(&mut self) -> std::result::Result<(), MigratableError> {
|
||||
self.migration_started = false;
|
||||
if let Some(vu) = &self.vu {
|
||||
vu.lock().unwrap().stop_dirty_log().map_err(|e| {
|
||||
MigratableError::StopDirtyLog(anyhow!(
|
||||
@ -509,10 +507,17 @@ impl VhostUserCommon {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start_migration(&mut self) -> std::result::Result<(), MigratableError> {
|
||||
self.migration_started = true;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn complete_migration(
|
||||
&mut self,
|
||||
kill_evt: Option<EventFd>,
|
||||
) -> std::result::Result<(), MigratableError> {
|
||||
self.migration_started = false;
|
||||
|
||||
// Make sure the device thread is killed in order to prevent from
|
||||
// reconnections to the socket.
|
||||
if let Some(kill_evt) = kill_evt {
|
||||
|
@ -488,6 +488,10 @@ impl Migratable for Net {
|
||||
self.vu_common.dirty_log(&self.guest_memory)
|
||||
}
|
||||
|
||||
fn start_migration(&mut self) -> std::result::Result<(), MigratableError> {
|
||||
self.vu_common.start_migration()
|
||||
}
|
||||
|
||||
fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> {
|
||||
self.vu_common
|
||||
.complete_migration(self.common.kill_evt.take())
|
||||
|
@ -305,6 +305,10 @@ pub trait Migratable: Send + Pausable + Snapshottable + Transportable {
|
||||
Ok(MemoryRangeTable::default())
|
||||
}
|
||||
|
||||
fn start_migration(&mut self) -> std::result::Result<(), MigratableError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -4221,6 +4221,15 @@ impl Migratable for DeviceManager {
|
||||
Ok(MemoryRangeTable::new_from_tables(tables))
|
||||
}
|
||||
|
||||
fn start_migration(&mut self) -> std::result::Result<(), MigratableError> {
|
||||
for (_, device_node) in self.device_tree.lock().unwrap().iter() {
|
||||
if let Some(migratable) = &device_node.migratable {
|
||||
migratable.lock().unwrap().start_migration()?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> {
|
||||
for (_, device_node) in self.device_tree.lock().unwrap().iter() {
|
||||
if let Some(migratable) = &device_node.migratable {
|
||||
|
@ -1100,6 +1100,9 @@ impl Vmm {
|
||||
)));
|
||||
}
|
||||
|
||||
// Let every Migratable object know about the migration being started.
|
||||
vm.start_migration()?;
|
||||
|
||||
if send_data_migration.local {
|
||||
// Now pause VM
|
||||
vm.pause()?;
|
||||
|
@ -2675,6 +2675,11 @@ impl Migratable for Vm {
|
||||
]))
|
||||
}
|
||||
|
||||
fn start_migration(&mut self) -> std::result::Result<(), MigratableError> {
|
||||
self.memory_manager.lock().unwrap().start_migration()?;
|
||||
self.device_manager.lock().unwrap().start_migration()
|
||||
}
|
||||
|
||||
fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> {
|
||||
self.memory_manager.lock().unwrap().complete_migration()?;
|
||||
self.device_manager.lock().unwrap().complete_migration()
|
||||
|
Loading…
Reference in New Issue
Block a user