166 lines
5.2 KiB
Diff
166 lines
5.2 KiB
Diff
From 6ac9cdc2b5c38153a5faaf41ce8421b09aaf053e Mon Sep 17 00:00:00 2001
|
|
From: licunlong <licunlong1@huawei.com>
|
|
Date: Wed, 31 May 2023 11:20:33 +0800
|
|
Subject: [PATCH 8/9] fix: change the socket logic to keep the same as systemd
|
|
1. check the events number got from wait_for_events(), quick return when it
|
|
is 0. 2. make flush_accept() return the error. 3. close the accepted fd
|
|
instead port fd itself.
|
|
|
|
---
|
|
coms/socket/src/mng.rs | 1 +
|
|
coms/socket/src/port.rs | 54 ++++++++++++++++++++++++++---------------
|
|
core/lib/error.rs | 28 +++++++++++++++++++++
|
|
3 files changed, 63 insertions(+), 20 deletions(-)
|
|
|
|
diff --git a/coms/socket/src/mng.rs b/coms/socket/src/mng.rs
|
|
index 0435827..da396de 100644
|
|
--- a/coms/socket/src/mng.rs
|
|
+++ b/coms/socket/src/mng.rs
|
|
@@ -597,6 +597,7 @@ impl SocketMng {
|
|
if port.fd() < 0 {
|
|
continue;
|
|
}
|
|
+ let _ = port.flush_accept();
|
|
port.flush_fd();
|
|
}
|
|
}
|
|
diff --git a/coms/socket/src/port.rs b/coms/socket/src/port.rs
|
|
index 870cb70..0500669 100644
|
|
--- a/coms/socket/src/port.rs
|
|
+++ b/coms/socket/src/port.rs
|
|
@@ -151,29 +151,43 @@ impl SocketPort {
|
|
}
|
|
}
|
|
|
|
- pub(super) fn flush_accept(&self) {
|
|
+ pub(super) fn flush_accept(&self) -> Result<()> {
|
|
if let Ok(true) = socket::getsockopt(self.fd(), sockopt::AcceptConn) {
|
|
for _i in 1..1024 {
|
|
- while let Err(e) = io_util::wait_for_events(self.fd(), PollFlags::POLLIN, 0) {
|
|
- if let basic::Error::Nix {
|
|
- source: Errno::EINTR,
|
|
- } = e
|
|
- {
|
|
- continue;
|
|
+ let events = match io_util::wait_for_events(self.fd(), PollFlags::POLLIN, 0) {
|
|
+ Err(e) => {
|
|
+ if let basic::Error::Nix {
|
|
+ source: Errno::EINTR,
|
|
+ } = e
|
|
+ {
|
|
+ continue;
|
|
+ }
|
|
+ return Err(e.into());
|
|
}
|
|
- return;
|
|
+ Ok(v) => v,
|
|
+ };
|
|
+ if events == 0 {
|
|
+ return Ok(());
|
|
}
|
|
- match socket::accept4(self.fd(), SockFlag::SOCK_NONBLOCK | SockFlag::SOCK_CLOEXEC)
|
|
- .map(|_| fd_util::close(self.fd()))
|
|
- {
|
|
- Ok(_) => {}
|
|
- Err(_e) => {
|
|
- // todo!(): if e == Errno::EAGAIN { return; }
|
|
- return;
|
|
+ let cfd = match socket::accept4(
|
|
+ self.fd(),
|
|
+ SockFlag::SOCK_NONBLOCK | SockFlag::SOCK_CLOEXEC,
|
|
+ ) {
|
|
+ Err(e) => {
|
|
+ if e == Errno::EAGAIN {
|
|
+ return Ok(());
|
|
+ }
|
|
+ if error_is_accept_again(&e) {
|
|
+ continue;
|
|
+ }
|
|
+ return Err(e.into());
|
|
}
|
|
- }
|
|
+ Ok(v) => v,
|
|
+ };
|
|
+ fd_util::close(cfd);
|
|
}
|
|
}
|
|
+ Ok(())
|
|
}
|
|
|
|
pub(super) fn flush_fd(&self) {
|
|
@@ -356,7 +370,7 @@ mod tests {
|
|
assert_ne!(port.fd(), SOCKET_INVALID_FD);
|
|
assert_eq!(port.family(), AddressFamily::Inet);
|
|
|
|
- port.flush_accept();
|
|
+ assert!(port.flush_accept().is_ok());
|
|
port.flush_fd();
|
|
port.close(false);
|
|
}
|
|
@@ -387,7 +401,7 @@ mod tests {
|
|
assert_ne!(port.fd(), SOCKET_INVALID_FD);
|
|
assert_eq!(port.family(), AddressFamily::Unix);
|
|
|
|
- port.flush_accept();
|
|
+ assert!(port.flush_accept().is_ok());
|
|
port.flush_fd();
|
|
port.close(false);
|
|
}
|
|
@@ -424,7 +438,7 @@ mod tests {
|
|
assert_ne!(port.fd(), SOCKET_INVALID_FD);
|
|
assert_eq!(port.family(), AddressFamily::Netlink);
|
|
|
|
- port.flush_accept();
|
|
+ assert!(port.flush_accept().is_ok());
|
|
port.flush_fd();
|
|
port.close(false);
|
|
}
|
|
@@ -519,7 +533,7 @@ mod tests {
|
|
}
|
|
|
|
// Rosource reclaim
|
|
- port.flush_accept();
|
|
+ assert!(port.flush_accept().is_ok());
|
|
port.flush_fd();
|
|
port.close(false);
|
|
}
|
|
diff --git a/core/lib/error.rs b/core/lib/error.rs
|
|
index 100eb3c..331f367 100644
|
|
--- a/core/lib/error.rs
|
|
+++ b/core/lib/error.rs
|
|
@@ -289,3 +289,31 @@ impl From<event::Error> for Error {
|
|
|
|
/// new Result
|
|
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
|
+
|
|
+pub fn error_is_disconnect(e: &Errno) -> bool {
|
|
+ [
|
|
+ Errno::ECONNABORTED,
|
|
+ Errno::ECONNREFUSED,
|
|
+ Errno::ECONNRESET,
|
|
+ Errno::EHOSTDOWN,
|
|
+ Errno::EHOSTUNREACH,
|
|
+ Errno::ENETDOWN,
|
|
+ Errno::ENETRESET,
|
|
+ Errno::ENONET,
|
|
+ Errno::ENOPROTOOPT,
|
|
+ Errno::ENOTCONN,
|
|
+ Errno::EPIPE,
|
|
+ Errno::EPROTO,
|
|
+ Errno::ESHUTDOWN,
|
|
+ Errno::ETIMEDOUT,
|
|
+ ]
|
|
+ .contains(e)
|
|
+}
|
|
+
|
|
+pub fn error_is_transient(e: &Errno) -> bool {
|
|
+ [Errno::EAGAIN, Errno::EINTR].contains(e)
|
|
+}
|
|
+
|
|
+pub fn error_is_accept_again(e: &Errno) -> bool {
|
|
+ error_is_disconnect(e) || error_is_transient(e) || e == &Errno::EOPNOTSUPP
|
|
+}
|
|
--
|
|
2.30.2
|
|
|