mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-08-21 23:41:15 +00:00
vm-virtio: vsock: Don't return error when epoll_wait is interrupted
The existing code taking care of the epoll loop was too restrictive as it was considering all errors the same. But in case the error is EINTR, this means the syscall has been interrupted while waiting, and it should be resumed to wait again. This patch enforces the parsing of the returned error and prevent the code from assuming EINTR should be handled as all other errors. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
6e6b2b84fe
commit
56d7c04226
@ -32,7 +32,7 @@
|
|||||||
/// mapping `RawFd`s to `EpollListener`s.
|
/// mapping `RawFd`s to `EpollListener`s.
|
||||||
///
|
///
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::io::Read;
|
use std::io::{self, Read};
|
||||||
use std::os::unix::io::{AsRawFd, RawFd};
|
use std::os::unix::io::{AsRawFd, RawFd};
|
||||||
use std::os::unix::net::{UnixListener, UnixStream};
|
use std::os::unix::net::{UnixListener, UnixStream};
|
||||||
|
|
||||||
@ -285,22 +285,35 @@ impl VsockEpollListener for VsockMuxer {
|
|||||||
debug!("vsock: muxer received kick");
|
debug!("vsock: muxer received kick");
|
||||||
|
|
||||||
let mut epoll_events = vec![epoll::Event::new(epoll::Events::empty(), 0); 32];
|
let mut epoll_events = vec![epoll::Event::new(epoll::Events::empty(), 0); 32];
|
||||||
match epoll::wait(self.epoll_fd, 0, epoll_events.as_mut_slice()) {
|
'epoll: loop {
|
||||||
Ok(ev_cnt) => {
|
match epoll::wait(self.epoll_fd, 0, epoll_events.as_mut_slice()) {
|
||||||
#[allow(clippy::needless_range_loop)]
|
Ok(ev_cnt) => {
|
||||||
for i in 0..ev_cnt {
|
#[allow(clippy::needless_range_loop)]
|
||||||
self.handle_event(
|
for i in 0..ev_cnt {
|
||||||
epoll_events[i].data as RawFd,
|
self.handle_event(
|
||||||
// It's ok to unwrap here, since the `epoll_events[i].events` is filled
|
epoll_events[i].data as RawFd,
|
||||||
// in by `epoll::wait()`, and therefore contains only valid epoll
|
// It's ok to unwrap here, since the `epoll_events[i].events` is filled
|
||||||
// flags.
|
// in by `epoll::wait()`, and therefore contains only valid epoll
|
||||||
epoll::Events::from_bits(epoll_events[i].events).unwrap(),
|
// flags.
|
||||||
);
|
epoll::Events::from_bits(epoll_events[i].events).unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
warn!("vsock: failed to consume muxer epoll event: {}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
break 'epoll;
|
||||||
warn!("vsock: failed to consume muxer epoll event: {}", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user