diff --git a/db/hints/manager.cc b/db/hints/manager.cc index 74d00593f9..9c24d668dd 100644 --- a/db/hints/manager.cc +++ b/db/hints/manager.cc @@ -547,10 +547,16 @@ future<> manager::change_host_filter(host_filter filter) { const auto maybe_host_id_and_ip = std::invoke([&] () -> std::optional { try { locator::host_id_or_endpoint hid_or_ep{de.name}; - if (hid_or_ep.has_host_id()) { + + // If hinted handoff is host-ID-based, hint directories representing IP addresses must've + // been created by mistake and they're invalid. The same for pre-host-ID hinted handoff + // -- hint directories representing host IDs are NOT valid. + if (hid_or_ep.has_host_id() && _uses_host_id) { return std::make_optional(pair_type{hid_or_ep.id(), hid_or_ep.resolve_endpoint(*tmptr)}); - } else { + } else if (hid_or_ep.has_endpoint() && !_uses_host_id) { return std::make_optional(pair_type{hid_or_ep.resolve_id(*tmptr), hid_or_ep.endpoint()}); + } else { + return std::nullopt; } } catch (...) { return std::nullopt; @@ -712,8 +718,6 @@ future<> manager::with_file_update_mutex_for(const std::variant manager::initialize_endpoint_managers() { auto maybe_create_ep_mgr = [this] (const locator::host_id& host_id, const gms::inet_address& ip) -> future<> { if (!check_dc_for(host_id)) { @@ -747,12 +751,23 @@ future<> manager::initialize_endpoint_managers() { } if (_uses_host_id) { + // If hinted handoff is host-ID-based but the directory doesn't represent a host ID, + // it's invalid. Ignore it. + if (!maybe_host_id_or_ep->has_host_id()) { + co_return; + } + // If hinted handoff is host-ID-based, `get_ep_manager` will NOT use the passed IP address, // so we simply pass the default value there. co_return co_await maybe_create_ep_mgr(maybe_host_id_or_ep->id(), gms::inet_address{}); } // If we have got to this line, hinted handoff is still IP-based and we need to map the IP. + if (!maybe_host_id_or_ep->has_endpoint()) { + // If the directory name doesn't represent an IP, it's invalid. We ignore it. + co_return; + } + const auto maybe_host_id = std::invoke([&] () -> std::optional { try { return maybe_host_id_or_ep->resolve_id(*tmptr); diff --git a/db/hints/manager.hh b/db/hints/manager.hh index b2a9a5bfc6..64041c2601 100644 --- a/db/hints/manager.hh +++ b/db/hints/manager.hh @@ -323,6 +323,10 @@ public: void update_backlog(size_t backlog, size_t max_backlog); + bool uses_host_id() const noexcept { + return _uses_host_id; + } + private: bool stopping() const noexcept { return _state.contains(state::stopping); diff --git a/db/hints/resource_manager.cc b/db/hints/resource_manager.cc index 00b2b439eb..ceae530c71 100644 --- a/db/hints/resource_manager.cc +++ b/db/hints/resource_manager.cc @@ -148,10 +148,16 @@ void space_watchdog::on_timer() { auto maybe_variant = std::invoke([&] () -> std::optional> { try { const auto hid_or_ep = locator::host_id_or_endpoint{de.name}; - if (hid_or_ep.has_host_id()) { + + // If hinted handoff is host-ID-based, hint directories representing IP addresses must've + // been created by mistake and they're invalid. The same for pre-host-ID hinted handoff + // -- hint directories representing host IDs are NOT valid. + if (hid_or_ep.has_host_id() && shard_manager.uses_host_id()) { return std::variant(hid_or_ep.id()); - } else { + } else if (hid_or_ep.has_endpoint() && !shard_manager.uses_host_id()) { return std::variant(hid_or_ep.endpoint()); + } else { + return std::nullopt; } } catch (...) { return std::nullopt;