This is an automated email from the ASF dual-hosted git repository.
zwoop pushed a commit to branch 9.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/9.1.x by this push:
new cbbf345 Save and propagate epoll network error (#7809)
cbbf345 is described below
commit cbbf3456f29dbdd7b7663f4ddcc1d3727513fab6
Author: Susan Hinrichs <[email protected]>
AuthorDate: Mon May 17 19:23:48 2021 -0500
Save and propagate epoll network error (#7809)
(cherry picked from commit 23174f43ba543c9f56916e5d6aadb7a22f349355)
---
iocore/net/NetEvent.h | 17 +++++++++++++++++
iocore/net/UnixNet.cc | 19 ++++++++-----------
iocore/net/UnixNetVConnection.cc | 12 ++++++++++++
3 files changed, 37 insertions(+), 11 deletions(-)
diff --git a/iocore/net/NetEvent.h b/iocore/net/NetEvent.h
index 94e96fe..534f309 100644
--- a/iocore/net/NetEvent.h
+++ b/iocore/net/NetEvent.h
@@ -55,6 +55,9 @@ public:
// Close when EventIO close;
virtual int close() = 0;
+ bool has_error() const;
+ void set_error_from_socket();
+
// get fd
virtual int get_fd() = 0;
virtual Ptr<ProxyMutex> &get_mutex() = 0;
@@ -65,6 +68,7 @@ public:
NetState write{};
int closed = 0;
+ int error = 0;
NetHandler *nh = nullptr;
ink_hrtime inactivity_timeout_in = 0;
@@ -94,3 +98,16 @@ public:
} f;
};
};
+
+inline bool
+NetEvent::has_error() const
+{
+ return error != 0;
+}
+
+inline void
+NetEvent::set_error_from_socket()
+{
+ socklen_t errlen = sizeof(error);
+ getsockopt(this->get_fd(), SOL_SOCKET, SO_ERROR, (void *)&error, &errlen);
+}
diff --git a/iocore/net/UnixNet.cc b/iocore/net/UnixNet.cc
index 19ea5ae..ca803ff 100644
--- a/iocore/net/UnixNet.cc
+++ b/iocore/net/UnixNet.cc
@@ -507,27 +507,24 @@ NetHandler::waitForActivity(ink_hrtime timeout)
if (cop_list.in(ne)) {
cop_list.remove(ne);
}
- if (get_ev_events(pd, x) & (EVENTIO_READ | EVENTIO_ERROR)) {
+ int flags = get_ev_events(pd, x);
+ if (flags & (EVENTIO_ERROR)) {
+ ne->set_error_from_socket();
+ }
+ if (flags & (EVENTIO_READ)) {
ne->read.triggered = 1;
if (!read_ready_list.in(ne)) {
read_ready_list.enqueue(ne);
- } else if (get_ev_events(pd, x) & EVENTIO_ERROR) {
- // check for unhandled epoll events that should be handled
- Debug("iocore_net_main", "Unhandled epoll event on read: 0x%04x
read.enabled=%d closed=%d read.netready_queue=%d",
- get_ev_events(pd, x), ne->read.enabled, ne->closed,
read_ready_list.in(ne));
}
}
- if (get_ev_events(pd, x) & (EVENTIO_WRITE | EVENTIO_ERROR)) {
+ if (flags & (EVENTIO_WRITE)) {
ne->write.triggered = 1;
if (!write_ready_list.in(ne)) {
write_ready_list.enqueue(ne);
- } else if (get_ev_events(pd, x) & EVENTIO_ERROR) {
- // check for unhandled epoll events that should be handled
- Debug("iocore_net_main", "Unhandled epoll event on write: 0x%04x
write.enabled=%d closed=%d write.netready_queue=%d",
- get_ev_events(pd, x), ne->write.enabled, ne->closed,
write_ready_list.in(ne));
}
- } else if (!(get_ev_events(pd, x) & EVENTIO_READ)) {
+ } else if (!(flags & (EVENTIO_READ))) {
Debug("iocore_net_main", "Unhandled epoll event: 0x%04x",
get_ev_events(pd, x));
+ ink_release_assert(false);
}
} else if (epd->type == EVENTIO_DNS_CONNECTION) {
if (epd->data.dnscon != nullptr) {
diff --git a/iocore/net/UnixNetVConnection.cc b/iocore/net/UnixNetVConnection.cc
index 00ca4cf..7b297a7 100644
--- a/iocore/net/UnixNetVConnection.cc
+++ b/iocore/net/UnixNetVConnection.cc
@@ -199,6 +199,12 @@ read_from_net(NetHandler *nh, UnixNetVConnection *vc,
EThread *thread)
return;
}
+ if (vc->has_error()) {
+ vc->lerrno = vc->error;
+ vc->readSignalAndUpdate(VC_EVENT_ERROR);
+ return;
+ }
+
// It is possible that the closed flag got set from HttpSessionManager in the
// global session pool case. If so, the closed flag should be stable once
we get the
// s->vio.mutex (the global session pool mutex).
@@ -361,6 +367,12 @@ write_to_net_io(NetHandler *nh, UnixNetVConnection *vc,
EThread *thread)
return;
}
+ if (vc->has_error()) {
+ vc->lerrno = vc->error;
+ write_signal_and_update(VC_EVENT_ERROR, vc);
+ return;
+ }
+
// This function will always return true unless
// vc is an SSLNetVConnection.
if (!vc->getSSLHandShakeComplete()) {