virtio-devices: Forward correct evset in vsock muxer

When forwarding an epoll event from the unix muxer to the
targeted connection event handler, the eventset the connection
registered is forwarded instead of the actual epoll
operation (IN/OUT).

For example, if the connection was registered for EPOLLIN,
and receives an EPOLLOUT, the connection will actually handle
an EPOLLOUT.

This is the root cause of previous bug, which caused the
introduction of some workarounds (i.e: handling ewouldblock
when reading after receiving EPOLLIN, which should never happen).

When matching the connection, we retrieve and use the evset of
the connection instead of the one passed as a parameter.
The compiler does not complain for an unused variable because
it was first logged in a debug! statement.

This is an unfortunate naming mistake that caused a lot of problems.

Fixes #3497

Signed-off-by: Eduard Kyvenko <eduard.kyvenko@gmail.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
(cherry picked from commit c47ab55e99)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Sebastien Boeuf 2022-01-03 11:38:47 +01:00 committed by Rob Bradford
parent 0f54fb1f5f
commit 868e566c08

View File

@ -362,25 +362,24 @@ impl VsockMuxer {
/// Handle/dispatch an epoll event to its listener. /// Handle/dispatch an epoll event to its listener.
/// ///
fn handle_event(&mut self, fd: RawFd, evset: epoll::Events) { fn handle_event(&mut self, fd: RawFd, event_set: epoll::Events) {
debug!( debug!(
"vsock: muxer processing event: fd={}, evset={:?}", "vsock: muxer processing event: fd={}, event_set={:?}",
fd, evset fd, event_set
); );
match self.listener_map.get_mut(&fd) { match self.listener_map.get_mut(&fd) {
// This event needs to be forwarded to a `MuxerConnection` that is listening for // This event needs to be forwarded to a `MuxerConnection` that is listening for
// it. // it.
// //
Some(EpollListener::Connection { key, evset }) => { Some(EpollListener::Connection { key, evset: _ }) => {
let key_copy = *key; let key_copy = *key;
let evset_copy = *evset;
// The handling of this event will most probably mutate the state of the // The handling of this event will most probably mutate the state of the
// receiving connection. We'll need to check for new pending RX, event set // receiving connection. We'll need to check for new pending RX, event set
// mutation, and all that, so we're wrapping the event delivery inside those // mutation, and all that, so we're wrapping the event delivery inside those
// checks. // checks.
self.apply_conn_mutation(key_copy, |conn| { self.apply_conn_mutation(key_copy, |conn| {
conn.notify(evset_copy); conn.notify(event_set);
}); });
} }
@ -443,7 +442,10 @@ impl VsockMuxer {
} }
_ => { _ => {
info!("vsock: unexpected event: fd={:?}, evset={:?}", fd, evset); info!(
"vsock: unexpected event: fd={:?}, event_set={:?}",
fd, event_set
);
} }
} }
} }