mirror of https://github.com/grpc/grpc.git
[iomgr and EE logging] Log ERROR if socket() returns EMFILE on posix (#32204)
There are potentially surprising deployment bugs that can cause `EMFILE` to be hit. For example, file descriptor limits can be easily reached if - the round robin LB policy is used - the load balancer hands out an assignment with a lot of backends - using debian's default 1024 file descriptor limit. To make such problems more apparent, we can pay special attention to this error and log ERROR when it happens. Related: b/265199104pull/32549/head
parent
141592df55
commit
27ee3913d1
12 changed files with 191 additions and 11 deletions
@ -0,0 +1,53 @@ |
|||||||
|
// Copyright 2023 gRPC authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include <errno.h> |
||||||
|
#include <sys/socket.h> |
||||||
|
|
||||||
|
#include "absl/status/status.h" |
||||||
|
#include "absl/status/statusor.h" |
||||||
|
#include "gmock/gmock.h" |
||||||
|
#include "gtest/gtest.h" |
||||||
|
|
||||||
|
#include "src/core/lib/event_engine/posix_engine/tcp_socket_utils.h" |
||||||
|
#include "src/core/lib/event_engine/tcp_socket_utils.h" |
||||||
|
#include "test/core/util/test_config.h" |
||||||
|
|
||||||
|
using ::grpc_event_engine::experimental::PosixSocketWrapper; |
||||||
|
|
||||||
|
// There is a special code path in create_socket to log errors upon EMFILE.
|
||||||
|
// Goal of this test is just to exercise that code path and also make sure
|
||||||
|
// it doesn't mess up "errno", so that we get the right error message.
|
||||||
|
TEST(LogTooManyOpenFilesTest, MainTest) { |
||||||
|
const auto mock_socket_factory = [](int, int, int) { |
||||||
|
errno = EMFILE; |
||||||
|
return -1; |
||||||
|
}; |
||||||
|
auto addr = grpc_event_engine::experimental::URIToResolvedAddress( |
||||||
|
"ipv4:127.0.0.1:80"); |
||||||
|
ASSERT_TRUE(addr.ok()); |
||||||
|
PosixSocketWrapper::DSMode dsmode; |
||||||
|
absl::StatusOr<PosixSocketWrapper> result = |
||||||
|
PosixSocketWrapper::CreateDualStackSocket(mock_socket_factory, *addr, |
||||||
|
SOCK_STREAM, AF_INET, dsmode); |
||||||
|
EXPECT_FALSE(result.ok()); |
||||||
|
EXPECT_THAT(result.status().message(), |
||||||
|
::testing::HasSubstr("Too many open files")); |
||||||
|
} |
||||||
|
|
||||||
|
int main(int argc, char** argv) { |
||||||
|
grpc::testing::TestEnvironment env(&argc, argv); |
||||||
|
::testing::InitGoogleTest(&argc, argv); |
||||||
|
return RUN_ALL_TESTS(); |
||||||
|
} |
Loading…
Reference in new issue