diff --git a/src/box/box.cc b/src/box/box.cc index c43982f5efdf30e49bd5f9d2d23c9896dd0a77a1..67cf1d363b9ef5587e5148fa3180fb37a9bb7e46 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -649,6 +649,9 @@ box_upsert(uint32_t space_id, uint32_t index_id, const char *tuple, static void box_on_cluster_join(const tt_uuid *server_uuid) { + if (is_ro) + tnt_raise(LoggedError, ER_READONLY); + /** Find the largest existing server id. */ struct space *space = space_cache_find(BOX_CLUSTER_ID); class MemtxIndex *index = index_find_system(space, 0); @@ -669,11 +672,15 @@ box_on_cluster_join(const tt_uuid *server_uuid) void box_process_join(int fd, struct xrow_header *header) { + assert(header->type == IPROTO_JOIN); + /* Check permissions */ access_check_universe(PRIV_R); access_check_space(space_cache_find(BOX_CLUSTER_ID), PRIV_W); - assert(header->type == IPROTO_JOIN); + /* Check that we actually can register a new replica */ + if (is_ro) + tnt_raise(LoggedError, ER_READONLY); /* Process JOIN request via a replication relay */ relay_join(fd, header, recovery->server_id, diff --git a/test/replication-py/cluster.result b/test/replication-py/cluster.result index 8f0de85a59bb0a43950827f7883ded0087f9dbd7..c84116802af6d67150ac981493d4661ddf746333 100644 --- a/test/replication-py/cluster.result +++ b/test/replication-py/cluster.result @@ -263,6 +263,10 @@ box.info.vclock[10] == nil - true ... ------------------------------------------------------------- +JOIN replica to read-only master +------------------------------------------------------------- +'ER_READONLY' exists in server log +------------------------------------------------------------- Cleanup ------------------------------------------------------------- box.schema.user.revoke('guest', 'replication') diff --git a/test/replication-py/cluster.test.py b/test/replication-py/cluster.test.py index 86c7a494dfc097c5a37f607a17dbbaa2817c74ca..73ced6b8220c3a31db0e4b238a9ceada2be211d0 100644 --- a/test/replication-py/cluster.test.py +++ b/test/replication-py/cluster.test.py @@ -242,6 +242,23 @@ replica.admin('box.info.server.ro') replica.admin('box.info.server.lsn == -1') replica.admin('box.info.vclock[%d] == nil' % replica_id2) +print '-------------------------------------------------------------' +print 'JOIN replica to read-only master' +print '-------------------------------------------------------------' + +#gh-1230 Assertion vclock_has on attempt to JOIN read-only master +failed = TarantoolServer(server.ini) +failed.script = 'replication-py/failed.lua' +failed.vardir = server.vardir +failed.rpl_master = replica +failed.name = "failed" +try: + failed.deploy() +except Exception as e: + line = "ER_READONLY" + if failed.logfile_pos.seek_once(line) >= 0: + print "'%s' exists in server log" % line + print '-------------------------------------------------------------' print 'Cleanup' print '-------------------------------------------------------------' diff --git a/test/replication-py/failed.lua b/test/replication-py/failed.lua new file mode 100644 index 0000000000000000000000000000000000000000..3a08208e065f353d7999aebea94592b85e5133c5 --- /dev/null +++ b/test/replication-py/failed.lua @@ -0,0 +1,9 @@ +#!/usr/bin/env tarantool + +box.cfg({ + listen = os.getenv("LISTEN"), + replication_source = os.getenv("MASTER"), + slab_alloc_arena = 0.1, +}) + +require('console').listen(os.getenv('ADMIN'))