mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-23 06:05:21 +00:00
vmm, vm-virtio: Restore DeviceManager's devices in a paused state
The same way the VM and the vCPUs are restored in a paused state, all devices associated with the device manager must be restored in the same paused state. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
8a165b5314
commit
e382dc6657
@ -722,6 +722,14 @@ impl<T: DiskFile> BlockEpollHandler<T> {
|
|||||||
const EPOLL_EVENTS_LEN: usize = 100;
|
const EPOLL_EVENTS_LEN: usize = 100;
|
||||||
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN];
|
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN];
|
||||||
|
|
||||||
|
// Before jumping into the epoll loop, check if the device is expected
|
||||||
|
// to be in a paused state. This is helpful for the restore code path
|
||||||
|
// as the device thread should not start processing anything before the
|
||||||
|
// device has been resumed.
|
||||||
|
while paused.load(Ordering::SeqCst) {
|
||||||
|
thread::park();
|
||||||
|
}
|
||||||
|
|
||||||
'epoll: loop {
|
'epoll: loop {
|
||||||
let num_events = match epoll::wait(epoll_file.as_raw_fd(), -1, &mut events[..]) {
|
let num_events = match epoll::wait(epoll_file.as_raw_fd(), -1, &mut events[..]) {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
|
@ -236,6 +236,14 @@ impl ConsoleEpollHandler {
|
|||||||
const EPOLL_EVENTS_LEN: usize = 100;
|
const EPOLL_EVENTS_LEN: usize = 100;
|
||||||
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN];
|
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN];
|
||||||
|
|
||||||
|
// Before jumping into the epoll loop, check if the device is expected
|
||||||
|
// to be in a paused state. This is helpful for the restore code path
|
||||||
|
// as the device thread should not start processing anything before the
|
||||||
|
// device has been resumed.
|
||||||
|
while paused.load(Ordering::SeqCst) {
|
||||||
|
thread::park();
|
||||||
|
}
|
||||||
|
|
||||||
'epoll: loop {
|
'epoll: loop {
|
||||||
let num_events = match epoll::wait(epoll_file.as_raw_fd(), -1, &mut events[..]) {
|
let num_events = match epoll::wait(epoll_file.as_raw_fd(), -1, &mut events[..]) {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
|
@ -687,6 +687,14 @@ impl IommuEpollHandler {
|
|||||||
const EPOLL_EVENTS_LEN: usize = 100;
|
const EPOLL_EVENTS_LEN: usize = 100;
|
||||||
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN];
|
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN];
|
||||||
|
|
||||||
|
// Before jumping into the epoll loop, check if the device is expected
|
||||||
|
// to be in a paused state. This is helpful for the restore code path
|
||||||
|
// as the device thread should not start processing anything before the
|
||||||
|
// device has been resumed.
|
||||||
|
while paused.load(Ordering::SeqCst) {
|
||||||
|
thread::park();
|
||||||
|
}
|
||||||
|
|
||||||
'epoll: loop {
|
'epoll: loop {
|
||||||
let num_events = match epoll::wait(epoll_file.as_raw_fd(), -1, &mut events[..]) {
|
let num_events = match epoll::wait(epoll_file.as_raw_fd(), -1, &mut events[..]) {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
|
@ -634,6 +634,14 @@ impl MemEpollHandler {
|
|||||||
const EPOLL_EVENTS_LEN: usize = 100;
|
const EPOLL_EVENTS_LEN: usize = 100;
|
||||||
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN];
|
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN];
|
||||||
|
|
||||||
|
// Before jumping into the epoll loop, check if the device is expected
|
||||||
|
// to be in a paused state. This is helpful for the restore code path
|
||||||
|
// as the device thread should not start processing anything before the
|
||||||
|
// device has been resumed.
|
||||||
|
while paused.load(Ordering::SeqCst) {
|
||||||
|
thread::park();
|
||||||
|
}
|
||||||
|
|
||||||
'epoll: loop {
|
'epoll: loop {
|
||||||
let num_events = match epoll::wait(epoll_file.as_raw_fd(), -1, &mut events[..]) {
|
let num_events = match epoll::wait(epoll_file.as_raw_fd(), -1, &mut events[..]) {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
|
@ -323,6 +323,14 @@ impl NetEpollHandler {
|
|||||||
|
|
||||||
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); NET_EVENTS_COUNT];
|
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); NET_EVENTS_COUNT];
|
||||||
|
|
||||||
|
// Before jumping into the epoll loop, check if the device is expected
|
||||||
|
// to be in a paused state. This is helpful for the restore code path
|
||||||
|
// as the device thread should not start processing anything before the
|
||||||
|
// device has been resumed.
|
||||||
|
while paused.load(Ordering::SeqCst) {
|
||||||
|
thread::park();
|
||||||
|
}
|
||||||
|
|
||||||
'epoll: loop {
|
'epoll: loop {
|
||||||
let num_events = match epoll::wait(epoll_file.as_raw_fd(), -1, &mut events[..]) {
|
let num_events = match epoll::wait(epoll_file.as_raw_fd(), -1, &mut events[..]) {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
|
@ -16,6 +16,7 @@ use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::thread;
|
||||||
use virtio_bindings::bindings::virtio_net::*;
|
use virtio_bindings::bindings::virtio_net::*;
|
||||||
use vm_memory::{
|
use vm_memory::{
|
||||||
ByteValued, Bytes, GuestAddress, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryError,
|
ByteValued, Bytes, GuestAddress, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryError,
|
||||||
@ -278,6 +279,14 @@ impl NetCtrlEpollHandler {
|
|||||||
|
|
||||||
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); CTRL_EVENT_COUNT];
|
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); CTRL_EVENT_COUNT];
|
||||||
|
|
||||||
|
// Before jumping into the epoll loop, check if the device is expected
|
||||||
|
// to be in a paused state. This is helpful for the restore code path
|
||||||
|
// as the device thread should not start processing anything before the
|
||||||
|
// device has been resumed.
|
||||||
|
while paused.load(Ordering::SeqCst) {
|
||||||
|
thread::park();
|
||||||
|
}
|
||||||
|
|
||||||
'epoll: loop {
|
'epoll: loop {
|
||||||
let num_events = match epoll::wait(epoll_file.as_raw_fd(), -1, &mut events[..]) {
|
let num_events = match epoll::wait(epoll_file.as_raw_fd(), -1, &mut events[..]) {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
|
@ -278,6 +278,14 @@ impl PmemEpollHandler {
|
|||||||
const EPOLL_EVENTS_LEN: usize = 100;
|
const EPOLL_EVENTS_LEN: usize = 100;
|
||||||
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN];
|
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN];
|
||||||
|
|
||||||
|
// Before jumping into the epoll loop, check if the device is expected
|
||||||
|
// to be in a paused state. This is helpful for the restore code path
|
||||||
|
// as the device thread should not start processing anything before the
|
||||||
|
// device has been resumed.
|
||||||
|
while paused.load(Ordering::SeqCst) {
|
||||||
|
thread::park();
|
||||||
|
}
|
||||||
|
|
||||||
'epoll: loop {
|
'epoll: loop {
|
||||||
let num_events = match epoll::wait(epoll_file.as_raw_fd(), -1, &mut events[..]) {
|
let num_events = match epoll::wait(epoll_file.as_raw_fd(), -1, &mut events[..]) {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
|
@ -121,6 +121,14 @@ impl RngEpollHandler {
|
|||||||
const EPOLL_EVENTS_LEN: usize = 100;
|
const EPOLL_EVENTS_LEN: usize = 100;
|
||||||
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN];
|
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN];
|
||||||
|
|
||||||
|
// Before jumping into the epoll loop, check if the device is expected
|
||||||
|
// to be in a paused state. This is helpful for the restore code path
|
||||||
|
// as the device thread should not start processing anything before the
|
||||||
|
// device has been resumed.
|
||||||
|
while paused.load(Ordering::SeqCst) {
|
||||||
|
thread::park();
|
||||||
|
}
|
||||||
|
|
||||||
'epoll: loop {
|
'epoll: loop {
|
||||||
let num_events = match epoll::wait(epoll_file.as_raw_fd(), -1, &mut events[..]) {
|
let num_events = match epoll::wait(epoll_file.as_raw_fd(), -1, &mut events[..]) {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
|
@ -117,6 +117,14 @@ impl<S: VhostUserMasterReqHandler> VhostUserEpollHandler<S> {
|
|||||||
|
|
||||||
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); index + 1];
|
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); index + 1];
|
||||||
|
|
||||||
|
// Before jumping into the epoll loop, check if the device is expected
|
||||||
|
// to be in a paused state. This is helpful for the restore code path
|
||||||
|
// as the device thread should not start processing anything before the
|
||||||
|
// device has been resumed.
|
||||||
|
while paused.load(Ordering::SeqCst) {
|
||||||
|
thread::park();
|
||||||
|
}
|
||||||
|
|
||||||
'poll: loop {
|
'poll: loop {
|
||||||
let num_events = match epoll::wait(epoll_file.as_raw_fd(), -1, &mut events[..]) {
|
let num_events = match epoll::wait(epoll_file.as_raw_fd(), -1, &mut events[..]) {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
|
@ -253,6 +253,14 @@ where
|
|||||||
|
|
||||||
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EVENTS_LEN];
|
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EVENTS_LEN];
|
||||||
|
|
||||||
|
// Before jumping into the epoll loop, check if the device is expected
|
||||||
|
// to be in a paused state. This is helpful for the restore code path
|
||||||
|
// as the device thread should not start processing anything before the
|
||||||
|
// device has been resumed.
|
||||||
|
while paused.load(Ordering::SeqCst) {
|
||||||
|
thread::park();
|
||||||
|
}
|
||||||
|
|
||||||
'epoll: loop {
|
'epoll: loop {
|
||||||
let num_events = match epoll::wait(epoll_file.as_raw_fd(), -1, &mut events[..]) {
|
let num_events = match epoll::wait(epoll_file.as_raw_fd(), -1, &mut events[..]) {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
|
@ -3477,6 +3477,7 @@ impl Snapshottable for DeviceManager {
|
|||||||
if let Some(migratable) = &node.migratable {
|
if let Some(migratable) = &node.migratable {
|
||||||
debug!("Restoring {} from DeviceManager", node.id);
|
debug!("Restoring {} from DeviceManager", node.id);
|
||||||
if let Some(snapshot) = snapshot.snapshots.get(&node.id) {
|
if let Some(snapshot) = snapshot.snapshots.get(&node.id) {
|
||||||
|
migratable.lock().unwrap().pause()?;
|
||||||
migratable.lock().unwrap().restore(*snapshot.clone())?;
|
migratable.lock().unwrap().restore(*snapshot.clone())?;
|
||||||
} else {
|
} else {
|
||||||
return Err(MigratableError::Restore(anyhow!(
|
return Err(MigratableError::Restore(anyhow!(
|
||||||
|
Loading…
Reference in New Issue
Block a user