diff --git a/benchmarks/storage_bench/StorageBench.cc b/benchmarks/storage_bench/StorageBench.cc index 90851582..1b873f71 100644 --- a/benchmarks/storage_bench/StorageBench.cc +++ b/benchmarks/storage_bench/StorageBench.cc @@ -169,13 +169,13 @@ bool runBenchmarks() { endpointRawStrs.clear(); boost::split(endpointRawStrs, FLAGS_mgmtdEndpoints, boost::is_any_of(", ")); - std::vector mgmtdEndpoints; + std::vector mgmtdEndpoints; for (auto str : endpointRawStrs) { boost::trim(str); if (str.empty()) continue; - auto endpoint = net::Address::fromString(str); + auto endpoint = net::NamedAddress::from(str).value(); mgmtdEndpoints.push_back(endpoint); XLOGF(WARN, "Add mgmtd endpoint: {}", endpoint); } diff --git a/benchmarks/storage_bench/StorageBench.h b/benchmarks/storage_bench/StorageBench.h index b4f4c697..55cee2b3 100644 --- a/benchmarks/storage_bench/StorageBench.h +++ b/benchmarks/storage_bench/StorageBench.h @@ -52,7 +52,7 @@ class StorageBench : public test::UnitTestFabric { const std::string statsFilePath = "./perfstats.csv"; const std::vector ibvDevices = {}; const std::vector ibnetZones = {}; - const std::vector mgmtdEndpoints = {}; + const std::vector mgmtdEndpoints = {}; const std::string clusterId = kClusterId; const uint32_t chainTableId = 0; const uint32_t chainTableVersion = 0; diff --git a/src/client/mgmtd/MgmtdClient.cc b/src/client/mgmtd/MgmtdClient.cc index a2befecb..85baace1 100644 --- a/src/client/mgmtd/MgmtdClient.cc +++ b/src/client/mgmtd/MgmtdClient.cc @@ -9,12 +9,15 @@ #include #include #include +#include #include #include #include "common/app/ApplicationBase.h" #include "common/utils/BackgroundRunner.h" #include "common/utils/LogCommands.h" +#include "common/utils/Result.h" +#include "common/utils/Status.h" #include "core/utils/ServiceOperation.h" #include "core/utils/runOp.h" @@ -461,7 +464,18 @@ struct MgmtdClient::Impl { if (serverAddrs.empty()) { return makeError(StatusCode::kInvalidConfig, "Empty mgmtdServers"); } - for (auto addr : serverAddrs) { + std::vector resolved; + for (const auto &addr : serverAddrs) { + auto res = addr.resolve(std::back_inserter(resolved)); + if (res.hasError()) { + XLOG(WARN, "resolve mgmtd address: {}", res.error().describe()); + } + } + if (resolved.empty()) { + return makeError(StatusCode::kInvalidConfig, "No resolved mgmtdServers"); + } + + for (auto addr : resolved) { if (addr == net::Address(0)) return makeError(StatusCode::kInvalidConfig, "Invalid MGMTD address: " + addr.toString()); if (config_.network_type() && addr.type != *config_.network_type()) { diff --git a/src/client/mgmtd/MgmtdClient.h b/src/client/mgmtd/MgmtdClient.h index 5135fd26..5c05051c 100644 --- a/src/client/mgmtd/MgmtdClient.h +++ b/src/client/mgmtd/MgmtdClient.h @@ -5,6 +5,7 @@ #include "RoutingInfo.h" #include "common/utils/ConfigBase.h" #include "common/utils/Duration.h" +#include "common/utils/NamedAddress.h" #include "stubs/common/IStubFactory.h" #include "stubs/mgmtd/IMgmtdServiceStub.h" @@ -12,7 +13,7 @@ namespace hf3fs::client { class MgmtdClient { public: struct Config : public ConfigBase { - CONFIG_ITEM(mgmtd_server_addresses, std::vector{}); + CONFIG_ITEM(mgmtd_server_addresses, std::vector{}); CONFIG_ITEM(work_queue_size, 100, ConfigCheckers::checkPositive); CONFIG_ITEM(network_type, std::optional{}); diff --git a/src/common/utils/NamedAddress.cc b/src/common/utils/NamedAddress.cc new file mode 100644 index 00000000..766ce7b8 --- /dev/null +++ b/src/common/utils/NamedAddress.cc @@ -0,0 +1,71 @@ +#include "common/utils/NamedAddress.h" + +#include +#include +#include + +namespace hf3fs::net { + +template +requires std::output_iterator +Result NamedAddress::resolve(It out) const { + struct addrinfo req{ + .ai_family = AF_INET, + .ai_socktype = SOCK_STREAM, + }; + struct addrinfo *res; + int err = getaddrinfo(node.c_str(), service.c_str(), &req, &res); + if (err != 0) { + return MAKE_ERROR_F(StatusCode::kInvalidFormat, "failed to resolve {}:{}: {}", node, service, gai_strerror(err)); + } + SCOPE_EXIT { freeaddrinfo(res); }; + + auto iter = res; + while (iter != nullptr) { + if (iter->ai_family == AF_INET) { + auto sin = (struct sockaddr_in *)iter->ai_addr; + if (sin->sin_family == AF_INET) { + *out++ = Address(sin->sin_addr.s_addr, ntohs(sin->sin_port), type); + } + } + iter = iter->ai_next; + } + return Void{}; +} + +template Result NamedAddress::resolve(std::back_insert_iterator> out) const; + +Result NamedAddress::from(std::string_view sv) { + constexpr std::string_view delimiter = "://"; + auto pos = sv.find(delimiter); + auto tp = Address::Type::TCP; + if (pos != sv.npos) { + auto tpStr = sv.substr(0, pos); + auto opt = magic_enum::enum_cast(tpStr, magic_enum::case_insensitive); + if (!opt) { + return makeError(StatusCode::kInvalidFormat, "invalid address type: {}", tpStr); + } + tp = *opt; + sv = sv.substr(pos + delimiter.size()); + } + pos = sv.find_last_of(':'); + if (pos == sv.npos) { + return makeError(StatusCode::kInvalidFormat, "service not found in address: {}", sv); + } + return NamedAddress(std::string(sv.substr(0, pos)), std::string(sv.substr(pos + 1)), tp); +} + +NamedAddress to_named(Address addr) { + return NamedAddress(addr.ipStr(), std::to_string(addr.port), addr.type); +} + +std::vector to_named(const std::vector
&addrs) { + std::vector named; + named.reserve(addrs.size()); + for (auto a : addrs) { + named.push_back(to_named(a)); + } + return named; +} + +} diff --git a/src/common/utils/NamedAddress.h b/src/common/utils/NamedAddress.h new file mode 100644 index 00000000..35af64b6 --- /dev/null +++ b/src/common/utils/NamedAddress.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include + +#include "common/utils/Address.h" +#include "common/utils/Result.h" + +namespace hf3fs::net { + +struct NamedAddress { + std::string node, service; + Address::Type type = Address::Type::TCP; + + NamedAddress(std::string node, std::string service, Address::Type type) + : node(node), service(service), type(type) {} + + bool operator==(const NamedAddress &other) const { + return node == other.node && service == other.service && type == other.type; + } + + template + requires std::output_iterator + Result resolve(It out) const; + + std::string toString() const { + return fmt::format("{}://{}:{}", magic_enum::enum_name(type), node, service); + } + + static Result from(std::string_view sv); +}; + +inline auto format_as(const NamedAddress &a) { return a.toString(); } + +net::NamedAddress to_named(net::Address addr); +std::vector to_named(const std::vector &addrs); + +} diff --git a/tests/client/ClientWithConfig.h b/tests/client/ClientWithConfig.h index d3be48a0..aa743edc 100644 --- a/tests/client/ClientWithConfig.h +++ b/tests/client/ClientWithConfig.h @@ -16,7 +16,7 @@ struct MgmtdClientWithConfig { MgmtdClientWithConfig(String clusterId, stubs::ClientContextCreator clientContextCreator, std::vector mgmtdServerAddrs) { - config.set_mgmtd_server_addresses(mgmtdServerAddrs); + config.set_mgmtd_server_addresses(to_named(mgmtdServerAddrs)); config.set_enable_auto_refresh(false); config.set_enable_auto_heartbeat(false); config.set_enable_auto_extend_client_session(false); diff --git a/tests/client/ServerWithConfig.h b/tests/client/ServerWithConfig.h index 6ff42007..931fd6b5 100644 --- a/tests/client/ServerWithConfig.h +++ b/tests/client/ServerWithConfig.h @@ -81,7 +81,7 @@ struct MetaServerWithConfig : ServerWithConfig { MetaServerWithConfig(String clusterId, flat::NodeId nodeId, std::vector mgmtdServerAddrs) : Base(std::move(clusterId), nodeId) { auto &mgmtdClientConfig = config.mgmtd_client(); - mgmtdClientConfig.set_mgmtd_server_addresses(mgmtdServerAddrs); + mgmtdClientConfig.set_mgmtd_server_addresses(to_named(mgmtdServerAddrs)); } }; diff --git a/tests/client/TestMgmtdClient.cc b/tests/client/TestMgmtdClient.cc index 106f3bc9..82ae693c 100644 --- a/tests/client/TestMgmtdClient.cc +++ b/tests/client/TestMgmtdClient.cc @@ -144,7 +144,7 @@ TEST_F(MgmtdClientTest, testWhenNoPrimary) { }; MgmtdClient::Config config; - config.set_mgmtd_server_addresses({ada, adb, adc}); + config.set_mgmtd_server_addresses({to_named(ada), to_named(adb), to_named(adc)}); config.set_enable_auto_refresh(false); config.set_enable_auto_heartbeat(false); MgmtdClient client("", std::make_unique(), config); @@ -158,7 +158,7 @@ TEST_F(MgmtdClientTest, testWhenNoPrimary) { TEST_F(MgmtdClientTest, testInvalidAddress) { MgmtdClient::Config config; - config.set_mgmtd_server_addresses({ada, ade}); + config.set_mgmtd_server_addresses({to_named(ada), to_named(ade)}); MgmtdClient client("", nullptr, config); folly::coro::blockingWait([&]() -> CoTask { @@ -169,7 +169,7 @@ TEST_F(MgmtdClientTest, testInvalidAddress) { TEST_F(MgmtdClientTest, testAddressTypeMismatch) { MgmtdClient::Config config; - config.set_mgmtd_server_addresses({ada, adf}); + config.set_mgmtd_server_addresses({to_named(ada), to_named(adf)}); config.set_network_type(net::Address::TCP); MgmtdClient client("", nullptr, config); @@ -195,7 +195,7 @@ TEST_F(MgmtdClientTest, testWhenLastIsPrimary) { }; MgmtdClient::Config config; - config.set_mgmtd_server_addresses({ada, adb, adc}); + config.set_mgmtd_server_addresses({to_named(ada), to_named(adb), to_named(adc)}); config.set_enable_auto_refresh(false); config.set_enable_auto_heartbeat(false); MgmtdClient client("", std::make_unique(), config); @@ -229,7 +229,7 @@ TEST_F(MgmtdClientTest, testWhenPrimaryNotInConfig) { }; MgmtdClient::Config config; - config.set_mgmtd_server_addresses({ada, adb, adc}); + config.set_mgmtd_server_addresses({to_named(ada), to_named(adb), to_named(adc)}); config.set_enable_auto_refresh(false); config.set_enable_auto_heartbeat(false); MgmtdClient client("", std::make_unique(), config); @@ -272,7 +272,7 @@ TEST_F(MgmtdClientTest, testWhenGetPrimaryLoop) { }; MgmtdClient::Config config; - config.set_mgmtd_server_addresses(addresses); + config.set_mgmtd_server_addresses(to_named(addresses)); config.set_enable_auto_refresh(false); config.set_enable_auto_heartbeat(false); MgmtdClient client("", std::make_unique(addresses), config); @@ -321,7 +321,7 @@ TEST_F(MgmtdClientTest, testRetryOnRefreshFail) { }; MgmtdClient::Config config; - config.set_mgmtd_server_addresses(addresses); + config.set_mgmtd_server_addresses(to_named(addresses)); config.set_enable_auto_refresh(false); config.set_enable_auto_heartbeat(false); MgmtdClient client("", std::make_unique(), config); @@ -356,7 +356,7 @@ TEST_F(MgmtdClientTest, testRefreshRoutingInfoCallback) { }; MgmtdClient::Config config; - config.set_mgmtd_server_addresses(addresses); + config.set_mgmtd_server_addresses(to_named(addresses)); config.set_enable_auto_refresh(false); config.set_enable_auto_heartbeat(false); MgmtdClient client("", std::make_unique(), config); @@ -400,7 +400,7 @@ TEST_F(MgmtdClientTest, testRetryAllAvailableAddresses) { }; MgmtdClient::Config config; - config.set_mgmtd_server_addresses({adj}); + config.set_mgmtd_server_addresses({to_named(adj)}); config.set_enable_auto_refresh(false); config.set_enable_auto_heartbeat(false); config.set_network_type(net::Address::TCP); @@ -462,7 +462,7 @@ TEST_F(MgmtdClientTest, testRetryEndWhenNoPrimary) { }; MgmtdClient::Config config; - config.set_mgmtd_server_addresses({adj}); + config.set_mgmtd_server_addresses({to_named(adj)}); config.set_enable_auto_refresh(false); config.set_enable_auto_heartbeat(false); config.set_network_type(net::Address::TCP); @@ -522,7 +522,7 @@ TEST_F(MgmtdClientTest, testRetryUnknownAddrs) { }; MgmtdClient::Config config; - config.set_mgmtd_server_addresses({adj, add}); + config.set_mgmtd_server_addresses({to_named(adj), to_named(add)}); config.set_enable_auto_refresh(false); config.set_enable_auto_heartbeat(false); config.set_network_type(net::Address::TCP); @@ -562,7 +562,6 @@ TEST_F(MgmtdClientTest, testRetryUnknownAddrs) { } TEST_F(MgmtdClientTest, testSetGetConfigViaInvoke) { - std::vector addresses = {ada}; struct StubFactory : public stubs::IStubFactory { std::map configs; std::unique_ptr create(net::Address) { @@ -585,7 +584,7 @@ TEST_F(MgmtdClientTest, testSetGetConfigViaInvoke) { }; MgmtdClient::Config config; - config.set_mgmtd_server_addresses(addresses); + config.set_mgmtd_server_addresses({to_named(ada)}); config.set_enable_auto_refresh(false); config.set_enable_auto_heartbeat(false); MgmtdClient client("", std::make_unique(), config); diff --git a/tests/lib/UnitTestFabric.cc b/tests/lib/UnitTestFabric.cc index 98b826c7..9160e2e8 100644 --- a/tests/lib/UnitTestFabric.cc +++ b/tests/lib/UnitTestFabric.cc @@ -195,7 +195,7 @@ std::unique_ptr UnitTestFabric::createStorageServer(size serverConfig.targets().storage_target().kv_store().set_type(metaStoreType); serverConfig.targets().storage_target().file_store().set_preopen_chunk_size_list( std::set(chunkSizeList.begin(), chunkSizeList.end())); - serverConfig.mgmtd().set_mgmtd_server_addresses(mgmtdAddressList); + serverConfig.mgmtd().set_mgmtd_server_addresses(to_named(mgmtdAddressList)); serverConfig.coroutines_pool_read().set_threads_num(32); serverConfig.coroutines_pool_read().set_coroutines_num(4096); serverConfig.coroutines_pool_update().set_threads_num(32); @@ -417,7 +417,7 @@ bool UnitTestFabric::setUpStorageSystem() { mgmtdForClient_.reset((new FakeMgmtdClient(rawRoutingInfo_))->asCommon()); } else { - mgmtdClientConfig_.set_mgmtd_server_addresses(mgmtdAddressList); + mgmtdClientConfig_.set_mgmtd_server_addresses(to_named(mgmtdAddressList)); mgmtdClientConfig_.set_enable_auto_refresh(true); mgmtdClientConfig_.set_enable_auto_heartbeat(false); mgmtdClientConfig_.set_auto_refresh_interval(mgmtdServer_.config.service().check_status_interval()); diff --git a/tests/meta/MetaTestBase.h b/tests/meta/MetaTestBase.h index 3af80476..1d92be5a 100644 --- a/tests/meta/MetaTestBase.h +++ b/tests/meta/MetaTestBase.h @@ -371,7 +371,7 @@ class MockCluster { CONFIG_OBJ(mock_mgmtd, mgmtd::MockMgmtd::Config); CONFIG_OBJ(mgmtd_client, client::MgmtdClientForServer::Config, [](client::MgmtdClientForServer::Config &cfg) { cfg.set_enable_auto_heartbeat(false); // currently heartbeat is not needed in meta test - cfg.set_mgmtd_server_addresses({net::Address::from("TCP://127.0.0.1:8000").value()}); // just a fake TCP address. + cfg.set_mgmtd_server_addresses({net::NamedAddress::from("TCP://127.0.0.1:8000").value()}); // just a fake TCP address. }); CONFIG_OBJ_ARRAY(chain_tables, ChainTableConfig, 64, [](std::array &cfg) { diff --git a/tests/migration/TestMigrationService.cc b/tests/migration/TestMigrationService.cc index 2087d77f..a01e9766 100644 --- a/tests/migration/TestMigrationService.cc +++ b/tests/migration/TestMigrationService.cc @@ -65,7 +65,7 @@ TEST_F(TestTestMigrationService, StartAndStopServer) { const auto &mgmtdAddressList = mgmtdServer_.collectAddressList("Mgmtd"); server::MigrationServer::Config config; - config.mgmtd_client().set_mgmtd_server_addresses(mgmtdAddressList); + config.mgmtd_client().set_mgmtd_server_addresses(to_named(mgmtdAddressList)); server::MigrationServer server(config); auto result = server.setup();