From e90c6a9444476e3d4cead401820ae18b5c7a4e49 Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Thu, 9 Sep 2021 06:09:54 +0000 Subject: [PATCH] crimson/net: make try_bind() aware about address_not_available. Signed-off-by: Radoslaw Zarzynski --- src/crimson/common/errorator.h | 1 + src/crimson/net/Messenger.h | 3 ++- src/crimson/net/Socket.cc | 4 ++++ src/crimson/net/Socket.h | 3 ++- src/crimson/net/SocketMessenger.cc | 30 ++++++++++++++++-------------- 5 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/crimson/common/errorator.h b/src/crimson/common/errorator.h index 53879cc9a002c..4978f6f1c072e 100644 --- a/src/crimson/common/errorator.h +++ b/src/crimson/common/errorator.h @@ -1128,6 +1128,7 @@ namespace ct_error { using file_too_large = ct_error_code; using address_in_use = ct_error_code; + using address_not_available = ct_error_code; struct pass_further_all { template diff --git a/src/crimson/net/Messenger.h b/src/crimson/net/Messenger.h index 179a752b746e1..10d9feae3dff8 100644 --- a/src/crimson/net/Messenger.h +++ b/src/crimson/net/Messenger.h @@ -63,7 +63,8 @@ public: } using bind_ertr = crimson::errorator< - crimson::ct_error::address_in_use // The address (range) is already bound + crimson::ct_error::address_in_use, // The address (range) is already bound + crimson::ct_error::address_not_available >; /// bind to the given address virtual bind_ertr::future<> bind(const entity_addrvec_t& addr) = 0; diff --git a/src/crimson/net/Socket.cc b/src/crimson/net/Socket.cc index baecdf7561ff2..642bda4921f08 100644 --- a/src/crimson/net/Socket.cc +++ b/src/crimson/net/Socket.cc @@ -217,6 +217,10 @@ FixedCPUServerSocket::listen(entity_addr_t addr) if (e.code() == std::errc::address_in_use) { logger().trace("FixedCPUServerSocket::listen({}): address in use", addr); return crimson::ct_error::address_in_use::make(); + } else if (e.code() == std::errc::address_not_available) { + logger().trace("FixedCPUServerSocket::listen({}): address not available", + addr); + return crimson::ct_error::address_not_available::make(); } logger().error("FixedCPUServerSocket::listen({}): " "got unexpeted error {}", addr, e); diff --git a/src/crimson/net/Socket.h b/src/crimson/net/Socket.h index 3a149cee14527..f2b9c2713913b 100644 --- a/src/crimson/net/Socket.h +++ b/src/crimson/net/Socket.h @@ -161,7 +161,8 @@ class Socket }; using listen_ertr = crimson::errorator< - crimson::ct_error::address_in_use // The address is already bound + crimson::ct_error::address_in_use, // The address is already bound + crimson::ct_error::address_not_available // https://techoverflow.net/2021/08/06/how-i-fixed-python-oserror-errno-99-cannot-assign-requested-address/ >; class FixedCPUServerSocket diff --git a/src/crimson/net/SocketMessenger.cc b/src/crimson/net/SocketMessenger.cc index eff85e1778ea1..2922c3a6d2391 100644 --- a/src/crimson/net/SocketMessenger.cc +++ b/src/crimson/net/SocketMessenger.cc @@ -102,27 +102,29 @@ SocketMessenger::try_bind(const entity_addrvec_t& addrs, auto to_bind = addr; to_bind.set_port(port); return do_listen(entity_addrvec_t{to_bind} - ).safe_then([this] () -> seastar::future> { + ).safe_then([this] () -> seastar::future> { logger().info("{} try_bind: done", *this); - return seastar::make_ready_future>( - std::make_optional(true)); + return seastar::make_ready_future>( + std::make_optional(std::error_code{/* success! */})); }, listen_ertr::all_same_way([this, max_port, &port] - (const std::error_code& e) mutable - -> seastar::future> { - assert(e == std::errc::address_in_use); - logger().trace("{} try_bind: {} already used", *this, port); + (const std::error_code& e) mutable + -> seastar::future> { + logger().trace("{} try_bind: {} got error {}", *this, port, e); if (port == max_port) { - return seastar::make_ready_future>( - std::make_optional(false)); + return seastar::make_ready_future>( + std::make_optional(e)); } ++port; - return seastar::make_ready_future>(); + return seastar::make_ready_future>( + std::optional{std::nullopt}); })); - }).then([] (bool success) -> bind_ertr::future<> { - if (success) { - return bind_ertr::now(); - } else { + }).then([] (const std::error_code e) -> bind_ertr::future<> { + if (!e) { + return bind_ertr::now(); // success! + } else if (e == std::errc::address_in_use) { return crimson::ct_error::address_in_use::make(); + } else if (e == std::errc::address_not_available) { + return crimson::ct_error::address_not_available::make(); } }); }); -- 2.39.5