diff --git a/src/server/server_family.cc b/src/server/server_family.cc index 58a6fbce36fd..e01cd2a9df95 100644 --- a/src/server/server_family.cc +++ b/src/server/server_family.cc @@ -2839,6 +2839,13 @@ void ServerFamily::ReplTakeOver(CmdArgList args, ConnectionContext* cntx) { } void ServerFamily::ReplConf(CmdArgList args, ConnectionContext* cntx) { + { + util::fb2::LockGuard lk(replicaof_mu_); + if (!ServerState::tlocal()->is_master) { + return cntx->SendError("Replicating a replica is unsupported"); + } + } + if (args.size() % 2 == 1) goto err; for (unsigned i = 0; i < args.size(); i += 2) { diff --git a/tests/dragonfly/replication_test.py b/tests/dragonfly/replication_test.py index 95cf423974ef..dfc63bcad46c 100644 --- a/tests/dragonfly/replication_test.py +++ b/tests/dragonfly/replication_test.py @@ -2663,3 +2663,25 @@ async def check_master_status(): assert await seeder.compare(capture, port=master.port) await disconnect_clients(c_master, c_replica) + + +@pytest.mark.asyncio +async def test_replica_of_replica(df_factory): + # Can't connect a replica to a replica, but OK to connect 2 replicas to the same master + master = df_factory.create(proactor_threads=2) + replica = df_factory.create(proactor_threads=2) + replica2 = df_factory.create(proactor_threads=2) + + df_factory.start_all([master, replica, replica2]) + + c_replica = replica.client() + c_replica2 = replica2.client() + + assert await c_replica.execute_command(f"REPLICAOF localhost {master.port}") == "OK" + + with pytest.raises(redis.exceptions.ResponseError): + await c_replica2.execute_command(f"REPLICAOF localhost {replica.port}") + + assert await c_replica2.execute_command(f"REPLICAOF localhost {master.port}") == "OK" + + await disconnect_clients(c_replica, c_replica2)