virtio-devices: vhost_user: Shutdown communication after migration

During a migration, the vhost-user device talks to the backend to
retrieve the dirty pages. Once done with this, a snapshot will be taken,
meaning there's no need to communicate with the backend anymore. Closing
the communication is needed to let the destination VM being able to
connect to the same backend.

That's why we shutdown the communication with the backend in case a
migration has been started and we're asked for a snapshot.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2021-08-09 10:21:08 +02:00 committed by Bo Chen
parent a738808604
commit 152a3b98c9
3 changed files with 33 additions and 3 deletions

View File

@ -60,6 +60,7 @@ pub struct Blk {
socket_path: String,
epoll_thread: Option<thread::JoinHandle<()>>,
vu_num_queues: usize,
migration_started: bool,
}
impl Blk {
@ -147,6 +148,7 @@ impl Blk {
socket_path: vu_cfg.socket,
epoll_thread: None,
vu_num_queues: num_queues,
migration_started: false,
})
}
@ -409,7 +411,13 @@ impl Snapshottable for Blk {
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
Snapshot::new_from_versioned_state(&self.id(), &self.state())
let snapshot = Snapshot::new_from_versioned_state(&self.id(), &self.state())?;
if self.migration_started {
self.shutdown();
}
Ok(snapshot)
}
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
@ -421,6 +429,7 @@ impl Transportable for Blk {}
impl Migratable for Blk {
fn start_dirty_log(&mut self) -> std::result::Result<(), MigratableError> {
self.migration_started = true;
if let Some(vu) = &self.vu {
if let Some(guest_memory) = &self.guest_memory {
let last_ram_addr = guest_memory.memory().last_addr().raw_value();
@ -444,6 +453,7 @@ impl Migratable for Blk {
}
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!(

View File

@ -310,6 +310,7 @@ pub struct Fs {
socket_path: String,
epoll_thread: Option<thread::JoinHandle<()>>,
vu_num_queues: usize,
migration_started: bool,
}
impl Fs {
@ -398,6 +399,7 @@ impl Fs {
socket_path: path.to_string(),
epoll_thread: None,
vu_num_queues: num_queues,
migration_started: false,
})
}
@ -689,7 +691,13 @@ impl Snapshottable for Fs {
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
Snapshot::new_from_versioned_state(&self.id(), &self.state())
let snapshot = Snapshot::new_from_versioned_state(&self.id(), &self.state())?;
if self.migration_started {
self.shutdown();
}
Ok(snapshot)
}
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
@ -701,6 +709,7 @@ impl Transportable for Fs {}
impl Migratable for Fs {
fn start_dirty_log(&mut self) -> std::result::Result<(), MigratableError> {
self.migration_started = true;
if let Some(vu) = &self.vu {
if let Some(guest_memory) = &self.guest_memory {
let last_ram_addr = guest_memory.memory().last_addr().raw_value();
@ -724,6 +733,7 @@ impl Migratable for Fs {
}
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!(

View File

@ -116,6 +116,7 @@ pub struct Net {
epoll_thread: Option<thread::JoinHandle<()>>,
seccomp_action: SeccompAction,
vu_num_queues: usize,
migration_started: bool,
}
impl Net {
@ -208,6 +209,7 @@ impl Net {
epoll_thread: None,
seccomp_action,
vu_num_queues,
migration_started: false,
})
}
@ -495,7 +497,13 @@ impl Snapshottable for Net {
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
Snapshot::new_from_versioned_state(&self.id(), &self.state())
let snapshot = Snapshot::new_from_versioned_state(&self.id(), &self.state())?;
if self.migration_started {
self.shutdown();
}
Ok(snapshot)
}
fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
@ -507,6 +515,7 @@ impl Transportable for Net {}
impl Migratable for Net {
fn start_dirty_log(&mut self) -> std::result::Result<(), MigratableError> {
self.migration_started = true;
if let Some(vu) = &self.vu {
if let Some(guest_memory) = &self.guest_memory {
let last_ram_addr = guest_memory.memory().last_addr().raw_value();
@ -530,6 +539,7 @@ impl Migratable for Net {
}
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!(