mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
virtio-devices: Abort vhost-user client connect on kill_evt
Client connect retried for a full minute on every failure and did not watch kill_evt for early exit, unlike reconnect, so teardown and permanent connect errors both stalled for CONNECT_TIMEOUT. Update the client path to watch kill_evt for early abort, fail non-retryable errors immediately, and surface timeout with a dedicated error. Partially Fixes #8052 Signed-off-by: Chinmoy <daschinmoyy21@gmail.com> Assisted-by: GLM 5.2
This commit is contained in:
@@ -63,7 +63,7 @@ impl Blk {
|
|||||||
&vu_cfg.socket,
|
&vu_cfg.socket,
|
||||||
num_queues as u64,
|
num_queues as u64,
|
||||||
false,
|
false,
|
||||||
None,
|
&exit_evt,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let (
|
let (
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ impl Fs {
|
|||||||
|
|
||||||
// Connect to the vhost-user socket.
|
// Connect to the vhost-user socket.
|
||||||
let mut vu =
|
let mut vu =
|
||||||
VhostUserHandle::connect_vhost_user(false, path, num_queues as u64, false, None)?;
|
VhostUserHandle::connect_vhost_user(false, path, num_queues as u64, false, &exit_evt)?;
|
||||||
|
|
||||||
let (
|
let (
|
||||||
avail_features,
|
avail_features,
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ impl GenericVhostUser {
|
|||||||
|
|
||||||
// Connect to the vhost-user socket.
|
// Connect to the vhost-user socket.
|
||||||
let mut vu =
|
let mut vu =
|
||||||
VhostUserHandle::connect_vhost_user(false, path, num_queues as u64, false, None)?;
|
VhostUserHandle::connect_vhost_user(false, path, num_queues as u64, false, &exit_evt)?;
|
||||||
|
|
||||||
let (
|
let (
|
||||||
avail_features,
|
avail_features,
|
||||||
|
|||||||
@@ -179,6 +179,8 @@ pub enum Error {
|
|||||||
EpollWait(#[source] io::Error),
|
EpollWait(#[source] io::Error),
|
||||||
#[error("Aborted vhost-user connect: kill event received")]
|
#[error("Aborted vhost-user connect: kill event received")]
|
||||||
ConnectKilled,
|
ConnectKilled,
|
||||||
|
#[error("Timed out waiting for vhost-user connection")]
|
||||||
|
VhostUserConnectTimeout,
|
||||||
}
|
}
|
||||||
type Result<T> = result::Result<T, Error>;
|
type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
@@ -329,7 +331,7 @@ impl<S: VhostUserFrontendReqHandler> VhostUserEpollHandler<S> {
|
|||||||
&self.socket_path,
|
&self.socket_path,
|
||||||
self.queues.len() as u64,
|
self.queues.len() as u64,
|
||||||
true,
|
true,
|
||||||
Some(&self.kill_evt),
|
&self.kill_evt,
|
||||||
) {
|
) {
|
||||||
Ok(vu) => vu,
|
Ok(vu) => vu,
|
||||||
// Kill event fired during the connect retry loop; abandon the
|
// Kill event fired during the connect retry loop; abandon the
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ impl Net {
|
|||||||
&vu_cfg.socket,
|
&vu_cfg.socket,
|
||||||
num_queues as u64,
|
num_queues as u64,
|
||||||
false,
|
false,
|
||||||
None,
|
&exit_evt,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let (
|
let (
|
||||||
|
|||||||
@@ -17,9 +17,13 @@ use vhost::vhost_user::message::{
|
|||||||
VhostUserProtocolFeatures, VhostUserVirtioFeatures,
|
VhostUserProtocolFeatures, VhostUserVirtioFeatures,
|
||||||
};
|
};
|
||||||
use vhost::vhost_user::{
|
use vhost::vhost_user::{
|
||||||
Frontend, FrontendReqHandler, VhostUserFrontend, VhostUserFrontendReqHandler,
|
Error as VhostUserError, Frontend, FrontendReqHandler, VhostUserFrontend,
|
||||||
|
VhostUserFrontendReqHandler,
|
||||||
|
};
|
||||||
|
use vhost::{
|
||||||
|
Error as VhostError, VhostBackend, VhostUserDirtyLogRegion, VhostUserMemoryRegionInfo,
|
||||||
|
VringConfigData,
|
||||||
};
|
};
|
||||||
use vhost::{VhostBackend, VhostUserDirtyLogRegion, VhostUserMemoryRegionInfo, VringConfigData};
|
|
||||||
use virtio_queue::desc::RawDescriptor;
|
use virtio_queue::desc::RawDescriptor;
|
||||||
use virtio_queue::{Queue, QueueT};
|
use virtio_queue::{Queue, QueueT};
|
||||||
use vm_memory::guest_memory::Error as MmapError;
|
use vm_memory::guest_memory::Error as MmapError;
|
||||||
@@ -381,7 +385,7 @@ impl VhostUserHandle {
|
|||||||
socket_path: &str,
|
socket_path: &str,
|
||||||
num_queues: u64,
|
num_queues: u64,
|
||||||
unlink_socket: bool,
|
unlink_socket: bool,
|
||||||
kill_evt: Option<&EventFd>,
|
kill_evt: &EventFd,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
if server {
|
if server {
|
||||||
if unlink_socket {
|
if unlink_socket {
|
||||||
@@ -427,15 +431,13 @@ impl VhostUserHandle {
|
|||||||
)
|
)
|
||||||
.map_err(Error::EpollCtl)?;
|
.map_err(Error::EpollCtl)?;
|
||||||
|
|
||||||
if let Some(kill_evt) = kill_evt {
|
epoll
|
||||||
epoll
|
.ctl(
|
||||||
.ctl(
|
ControlOperation::Add,
|
||||||
ControlOperation::Add,
|
kill_evt.as_raw_fd(),
|
||||||
kill_evt.as_raw_fd(),
|
EpollEvent::new(EventSet::IN, ConnectEvent::Kill as u64),
|
||||||
EpollEvent::new(EventSet::IN, ConnectEvent::Kill as u64),
|
)
|
||||||
)
|
.map_err(Error::EpollCtl)?;
|
||||||
.map_err(Error::EpollCtl)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let mut events = [EpollEvent::default(); 1];
|
let mut events = [EpollEvent::default(); 1];
|
||||||
@@ -457,13 +459,30 @@ impl VhostUserHandle {
|
|||||||
Err(e) => e,
|
Err(e) => e,
|
||||||
};
|
};
|
||||||
|
|
||||||
if start.elapsed() >= CONNECT_TIMEOUT {
|
let retryable = match &err {
|
||||||
|
VhostError::VhostUserProtocol(VhostUserError::SocketConnect(io_err)) => {
|
||||||
|
matches!(
|
||||||
|
io_err.kind(),
|
||||||
|
io::ErrorKind::NotFound
|
||||||
|
| io::ErrorKind::Interrupted
|
||||||
|
| io::ErrorKind::ConnectionRefused
|
||||||
|
)
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
if !retryable {
|
||||||
error!(
|
error!(
|
||||||
"Failed connecting the backend after trying for 1 minute for socket {socket_path}: {err:?}"
|
"Failed connecting to vhost-user backend for socket {socket_path}: {err:?}"
|
||||||
);
|
);
|
||||||
return Err(Error::VhostUserConnect(err));
|
return Err(Error::VhostUserConnect(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if start.elapsed() >= CONNECT_TIMEOUT {
|
||||||
|
error!("Timed out waiting for vhost-user connection on socket {socket_path}");
|
||||||
|
return Err(Error::VhostUserConnectTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match epoll.wait(-1, &mut events) {
|
match epoll.wait(-1, &mut events) {
|
||||||
Ok(_) => break,
|
Ok(_) => break,
|
||||||
|
|||||||
Reference in New Issue
Block a user