From 626dfb2c4943219c85ba2262559ef5479728fe4b Mon Sep 17 00:00:00 2001 From: Vladimir Davydov <vdavydov.dev@gmail.com> Date: Wed, 3 Oct 2018 16:10:31 +0300 Subject: [PATCH] vinyl: fix master crash on replica join failure This patch fixes a trivial error on vy_send_range() error path which results in a master crash in case a file needed to join a replica is missing or corrupted. See #3708 --- src/box/vinyl.c | 6 ++--- test/vinyl/errinj.result | 51 ++++++++++++++++++++++++++++++++++++++ test/vinyl/errinj.test.lua | 18 ++++++++++++++ 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/box/vinyl.c b/src/box/vinyl.c index 2d0360c116..0cd7b18827 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -2983,13 +2983,13 @@ vy_send_range(struct vy_join_ctx *ctx, vy_send_range_f, NULL, TIMEOUT_INFINITY); fiber_set_cancellable(cancellable); +out_delete_wi: + ctx->wi->iface->close(ctx->wi); + ctx->wi = NULL; out_delete_slices: rlist_foreach_entry_safe(slice, &ctx->slices, in_join, tmp) vy_slice_delete(slice); rlist_create(&ctx->slices); -out_delete_wi: - ctx->wi->iface->close(ctx->wi); - ctx->wi = NULL; out: return rc; } diff --git a/test/vinyl/errinj.result b/test/vinyl/errinj.result index b4dc5b69a0..63d14c612a 100644 --- a/test/vinyl/errinj.result +++ b/test/vinyl/errinj.result @@ -2232,3 +2232,54 @@ test_run:cmd("clear filter") --- - true ... +-- +-- Check that an instance doesn't crash if a run file needed for +-- joining a replica is corrupted (see gh-3708). +-- +s = box.schema.space.create('test', {engine = 'vinyl'}) +--- +... +_ = s:create_index('pk') +--- +... +s:replace{1, 2, 3} +--- +- [1, 2, 3] +... +box.snapshot() +--- +- ok +... +box.schema.user.grant('guest', 'replication') +--- +... +errinj.set('ERRINJ_VYRUN_INDEX_GARBAGE', true) +--- +- ok +... +test_run:cmd("create server replica with rpl_master=default, script='replication/replica.lua'") +--- +- true +... +test_run:cmd("start server replica with crash_expected=True") +--- +- false +... +test_run:cmd("cleanup server replica") +--- +- true +... +test_run:cmd("delete server replica") +--- +- true +... +errinj.set('ERRINJ_VYRUN_INDEX_GARBAGE', false) +--- +- ok +... +box.schema.user.revoke('guest', 'replication') +--- +... +s:drop() +--- +... diff --git a/test/vinyl/errinj.test.lua b/test/vinyl/errinj.test.lua index e82b6aee8c..b6f697d3cf 100644 --- a/test/vinyl/errinj.test.lua +++ b/test/vinyl/errinj.test.lua @@ -882,3 +882,21 @@ i:stat().disk.compact.queue -- none s:drop() test_run:cmd("clear filter") + +-- +-- Check that an instance doesn't crash if a run file needed for +-- joining a replica is corrupted (see gh-3708). +-- +s = box.schema.space.create('test', {engine = 'vinyl'}) +_ = s:create_index('pk') +s:replace{1, 2, 3} +box.snapshot() +box.schema.user.grant('guest', 'replication') +errinj.set('ERRINJ_VYRUN_INDEX_GARBAGE', true) +test_run:cmd("create server replica with rpl_master=default, script='replication/replica.lua'") +test_run:cmd("start server replica with crash_expected=True") +test_run:cmd("cleanup server replica") +test_run:cmd("delete server replica") +errinj.set('ERRINJ_VYRUN_INDEX_GARBAGE', false) +box.schema.user.revoke('guest', 'replication') +s:drop() -- GitLab