From 70addce9a1347e2fd14aebf5e7e326bc6c24f66c Mon Sep 17 00:00:00 2001 From: Roman Tsisyk <roman@tsisyk.com> Date: Mon, 28 Dec 2015 12:42:29 +0300 Subject: [PATCH] Fix #1230: Assertion on attempt to JOIN read-only master A prerequisite for #1219 test case. --- src/box/box.cc | 9 ++++++++- test/replication-py/cluster.result | 4 ++++ test/replication-py/cluster.test.py | 17 +++++++++++++++++ test/replication-py/failed.lua | 9 +++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 test/replication-py/failed.lua diff --git a/src/box/box.cc b/src/box/box.cc index c43982f5ef..67cf1d363b 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 8f0de85a59..c84116802a 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 86c7a494df..73ced6b822 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 0000000000..3a08208e06 --- /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')) -- GitLab