diff options
author | Dan Gudmundsson <[email protected]> | 2019-06-28 13:13:13 +0200 |
---|---|---|
committer | Dan Gudmundsson <[email protected]> | 2019-06-28 13:13:13 +0200 |
commit | 2bf7b5b5abbc1097a0b30bea2d390a2a0bec004c (patch) | |
tree | 4a149a915f4d769a9567aa26f0afaab32ada0986 /lib/mnesia/test | |
parent | bf9e4be9ef971da7d7325424dde50d9bc6b186aa (diff) | |
download | otp-2bf7b5b5abbc1097a0b30bea2d390a2a0bec004c.tar.gz otp-2bf7b5b5abbc1097a0b30bea2d390a2a0bec004c.tar.bz2 otp-2bf7b5b5abbc1097a0b30bea2d390a2a0bec004c.zip |
mnesia: Fix deadlock caused by add_table_copy
If add_table_copy was called when a node was starting it deadlock
waiting for mnesia_controller, when schema was not merged.
Abort if that is the case.
Diffstat (limited to 'lib/mnesia/test')
-rw-r--r-- | lib/mnesia/test/mnesia_isolation_test.erl | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/lib/mnesia/test/mnesia_isolation_test.erl b/lib/mnesia/test/mnesia_isolation_test.erl index 49bcec14af..98a7840b72 100644 --- a/lib/mnesia/test/mnesia_isolation_test.erl +++ b/lib/mnesia/test/mnesia_isolation_test.erl @@ -1036,29 +1036,57 @@ add_table_copy(Config) when is_list(Config) -> Def = [{ram_copies, [ThisNode]}, {attributes, [key, attr1, attr2]}], ?match({atomic, ok}, mnesia:create_table(Tab, Def)), insert(Tab, 50), - {success, [A]} = ?start_activities([ThisNode]), + {success, [A]} = ?start_activities([ThisNode]), mnesia_test_lib:start_sync_transactions([A], 0), A ! fun() -> mnesia:write({Tab, 1, 1, updated}) end, ?match_receive({A, ok}), %% A is executed - Pid = spawn_link(?MODULE, op, [self(), mnesia, add_table_copy, + Pid = spawn_link(?MODULE, op, [self(), mnesia, add_table_copy, [Tab, Node2, ram_copies]]), - + ?match_receive(timeout), %% op waits for locks occupied by A A ! end_trans, %% Kill A, locks should be released - ?match_receive({A,{atomic,end_trans}}), - - receive + ?match_receive({A,{atomic,end_trans}}), + + receive Msg -> ?match({Pid, {atomic, ok}}, Msg) after timer:seconds(20) -> ?error("Operation timed out", []) end, + ?match_receive({'EXIT', Pid, normal}), sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async - ?match([], mnesia:system_info(held_locks)), - ?match([], mnesia:system_info(lock_queue)), + ?match([], mnesia:system_info(held_locks)), + ?match([], mnesia:system_info(lock_queue)), + + {atomic, ok} = mnesia:del_table_copy(Tab, Node2), + Self = self(), + New = spawn_link(Node2, + fun () -> + application:stop(mnesia), + Self ! {self(), ok}, + io:format(user, "restart mnesia~n", []), + Self ! {self(), catch application:start(mnesia)} + end), + receive {New,ok} -> ok end, + + Add = fun Add() -> + case mnesia:add_table_copy(Tab, Node2, disc_copies) of + {atomic, ok} -> ok; + _R -> io:format(user, "aborted with reason ~p~n", [_R]), + timer:sleep(10), + Add() + end + end, + + ?match(ok, Add()), + ?match_receive({New,ok}), + + sys:get_status(whereis(mnesia_locker)), % Explicit sync, release locks is async + ?match([], mnesia:system_info(held_locks)), + ?match([], mnesia:system_info(lock_queue)), ok. del_table_copy(suite) -> []; |