storage_service: join_token_ring: reject replace on different dc or rack

Do not allow replacing a node on one dc/rack
with a node on a different dc/rack as this violates
the assumption of replace node operation that
all token ranges previously owned by the dead
node would be rebuilt on the new node.

Fixes #16858
Refs scylladb/scylla-enterprise#3518

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
(cherry picked from commit 34dfa4d3a3)

Closes scylladb/scylladb#19281
This commit is contained in:
Benny Halevy
2024-01-18 17:45:31 +02:00
committed by Botond Dénes
parent b18d9e5d0d
commit 6122f9454d

View File

@@ -1492,6 +1492,15 @@ future<> storage_service::join_token_ring(sharded<db::system_distributed_keyspac
throw std::runtime_error("Cannot replace address with a node that is already bootstrapped");
}
ri = co_await prepare_replacement_info(initial_contact_nodes, loaded_peer_features);
const auto& my_location = tmptr->get_topology().get_location();
if (my_location != ri->dc_rack) {
auto msg = fmt::format("Cannot replace node {}/{} with a node on a different data center or rack. Current location={}/{}, new location={}/{}",
ri->host_id, ri->address, ri->dc_rack.dc, ri->dc_rack.rack, my_location.dc, my_location.rack);
slogger.error("{}", msg);
throw std::runtime_error(msg);
}
replace_address = ri->address;
raft_replace_info = raft_group0::replace_info {
.ip_addr = *replace_address,