diff --git a/vm-virtio/src/block.rs b/vm-virtio/src/block.rs index 04aad2a21..7e0b2d50e 100755 --- a/vm-virtio/src/block.rs +++ b/vm-virtio/src/block.rs @@ -422,8 +422,22 @@ impl BlockEpollHandler { let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN]; 'epoll: loop { - let num_events = - epoll::wait(epoll_fd, -1, &mut events[..]).map_err(DeviceError::EpollWait)?; + let num_events = match epoll::wait(epoll_fd, -1, &mut events[..]) { + Ok(res) => res, + Err(e) => { + if e.kind() == io::ErrorKind::Interrupted { + // It's well defined from the epoll_wait() syscall + // documentation that the epoll loop can be interrupted + // before any of the requested events occurred or the + // timeout expired. In both those cases, epoll_wait() + // returns an error of type EINTR, but this should not + // be considered as a regular error. Instead it is more + // appropriate to retry, by calling into epoll_wait(). + continue; + } + return Err(DeviceError::EpollWait(e)); + } + }; for event in events.iter().take(num_events) { let ev_type = event.data as u16; diff --git a/vm-virtio/src/console.rs b/vm-virtio/src/console.rs index 0827223e0..f41b19f38 100755 --- a/vm-virtio/src/console.rs +++ b/vm-virtio/src/console.rs @@ -170,8 +170,22 @@ impl ConsoleEpollHandler { let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN]; 'epoll: loop { - let num_events = - epoll::wait(epoll_fd, -1, &mut events[..]).map_err(DeviceError::EpollWait)?; + let num_events = match epoll::wait(epoll_fd, -1, &mut events[..]) { + Ok(res) => res, + Err(e) => { + if e.kind() == io::ErrorKind::Interrupted { + // It's well defined from the epoll_wait() syscall + // documentation that the epoll loop can be interrupted + // before any of the requested events occurred or the + // timeout expired. In both those cases, epoll_wait() + // returns an error of type EINTR, but this should not + // be considered as a regular error. Instead it is more + // appropriate to retry, by calling into epoll_wait(). + continue; + } + return Err(DeviceError::EpollWait(e)); + } + }; for event in events.iter().take(num_events) { let ev_type = event.data as u16; diff --git a/vm-virtio/src/fs.rs b/vm-virtio/src/fs.rs index 9f21b6a72..571793355 100644 --- a/vm-virtio/src/fs.rs +++ b/vm-virtio/src/fs.rs @@ -121,8 +121,22 @@ impl FsEpollHandler { let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN]; 'epoll: loop { - let num_events = - epoll::wait(epoll_fd, -1, &mut events[..]).map_err(DeviceError::EpollWait)?; + let num_events = match epoll::wait(epoll_fd, -1, &mut events[..]) { + Ok(res) => res, + Err(e) => { + if e.kind() == io::ErrorKind::Interrupted { + // It's well defined from the epoll_wait() syscall + // documentation that the epoll loop can be interrupted + // before any of the requested events occurred or the + // timeout expired. In both those cases, epoll_wait() + // returns an error of type EINTR, but this should not + // be considered as a regular error. Instead it is more + // appropriate to retry, by calling into epoll_wait(). + continue; + } + return Err(DeviceError::EpollWait(e)); + } + }; for event in events.iter().take(num_events) { let ev_type = event.data as usize; diff --git a/vm-virtio/src/net.rs b/vm-virtio/src/net.rs index 0050fb426..29fb6d88e 100644 --- a/vm-virtio/src/net.rs +++ b/vm-virtio/src/net.rs @@ -333,8 +333,22 @@ impl NetEpollHandler { let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN]; 'epoll: loop { - let num_events = - epoll::wait(epoll_fd, -1, &mut events[..]).map_err(DeviceError::EpollWait)?; + let num_events = match epoll::wait(epoll_fd, -1, &mut events[..]) { + Ok(res) => res, + Err(e) => { + if e.kind() == io::ErrorKind::Interrupted { + // It's well defined from the epoll_wait() syscall + // documentation that the epoll loop can be interrupted + // before any of the requested events occurred or the + // timeout expired. In both those cases, epoll_wait() + // returns an error of type EINTR, but this should not + // be considered as a regular error. Instead it is more + // appropriate to retry, by calling into epoll_wait(). + continue; + } + return Err(DeviceError::EpollWait(e)); + } + }; for event in events.iter().take(num_events) { let ev_type = event.data as u16; diff --git a/vm-virtio/src/pmem.rs b/vm-virtio/src/pmem.rs index cc3de2122..0f1191201 100644 --- a/vm-virtio/src/pmem.rs +++ b/vm-virtio/src/pmem.rs @@ -237,8 +237,22 @@ impl PmemEpollHandler { let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN]; 'epoll: loop { - let num_events = - epoll::wait(epoll_fd, -1, &mut events[..]).map_err(DeviceError::EpollWait)?; + let num_events = match epoll::wait(epoll_fd, -1, &mut events[..]) { + Ok(res) => res, + Err(e) => { + if e.kind() == io::ErrorKind::Interrupted { + // It's well defined from the epoll_wait() syscall + // documentation that the epoll loop can be interrupted + // before any of the requested events occurred or the + // timeout expired. In both those cases, epoll_wait() + // returns an error of type EINTR, but this should not + // be considered as a regular error. Instead it is more + // appropriate to retry, by calling into epoll_wait(). + continue; + } + return Err(DeviceError::EpollWait(e)); + } + }; for event in events.iter().take(num_events) { let ev_type = event.data as u16; diff --git a/vm-virtio/src/rng.rs b/vm-virtio/src/rng.rs index b86692b7a..c0f62b1cd 100755 --- a/vm-virtio/src/rng.rs +++ b/vm-virtio/src/rng.rs @@ -105,8 +105,22 @@ impl RngEpollHandler { let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN]; 'epoll: loop { - let num_events = - epoll::wait(epoll_fd, -1, &mut events[..]).map_err(DeviceError::EpollWait)?; + let num_events = match epoll::wait(epoll_fd, -1, &mut events[..]) { + Ok(res) => res, + Err(e) => { + if e.kind() == io::ErrorKind::Interrupted { + // It's well defined from the epoll_wait() syscall + // documentation that the epoll loop can be interrupted + // before any of the requested events occurred or the + // timeout expired. In both those cases, epoll_wait() + // returns an error of type EINTR, but this should not + // be considered as a regular error. Instead it is more + // appropriate to retry, by calling into epoll_wait(). + continue; + } + return Err(DeviceError::EpollWait(e)); + } + }; for event in events.iter().take(num_events) { let ev_type = event.data as u16;