diff options
Diffstat (limited to 'lib/mnesia/src')
-rw-r--r-- | lib/mnesia/src/mnesia.app.src | 3 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia.erl | 10 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia.hrl | 4 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_controller.erl | 18 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_dumper.erl | 29 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_event.erl | 4 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_index.erl | 14 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_lib.erl | 72 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_locker.erl | 8 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_log.erl | 14 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_monitor.erl | 98 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_recover.erl | 8 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_snmp_hook.erl | 8 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_tm.erl | 5 |
14 files changed, 187 insertions, 108 deletions
diff --git a/lib/mnesia/src/mnesia.app.src b/lib/mnesia/src/mnesia.app.src index 3715488ec2..e755864792 100644 --- a/lib/mnesia/src/mnesia.app.src +++ b/lib/mnesia/src/mnesia.app.src @@ -47,6 +47,7 @@ mnesia_tm ]}, {applications, [kernel, stdlib]}, - {mod, {mnesia_sup, []}}]}. + {mod, {mnesia_sup, []}}, + {runtime_dependencies, ["stdlib-2.0","kernel-3.0","erts-6.0"]}]}. diff --git a/lib/mnesia/src/mnesia.erl b/lib/mnesia/src/mnesia.erl index 70466d10d7..b7d80c1370 100644 --- a/lib/mnesia/src/mnesia.erl +++ b/lib/mnesia/src/mnesia.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2013. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -104,7 +104,8 @@ set_master_nodes/1, set_master_nodes/2, %% Misc admin - dump_log/0, subscribe/1, unsubscribe/1, report_event/1, + dump_log/0, sync_log/0, + subscribe/1, unsubscribe/1, report_event/1, %% Snmp snmp_open_table/2, snmp_close_table/1, @@ -1808,7 +1809,7 @@ do_dirty_rpc(Tab, Node, M, F, Args) -> {badrpc, Reason} -> timer:sleep(20), %% Do not be too eager, and can't use yield on SMP %% Sync with mnesia_monitor - try sys:get_status(mnesia_monitor) catch _:_ -> ok end, + _ = try sys:get_status(mnesia_monitor) catch _:_ -> ok end, case mnesia_controller:call({check_w2r, Node, Tab}) of % Sync NewNode when NewNode =:= Node -> ErrorTag = mnesia_lib:dirty_rpc_error_tag(Reason), @@ -2554,6 +2555,9 @@ set_master_nodes(Tab, Nodes) -> dump_log() -> mnesia_controller:sync_dump_log(user). +sync_log() -> + mnesia_monitor:sync_log(latest_log). + subscribe(What) -> mnesia_subscr:subscribe(self(), What). diff --git a/lib/mnesia/src/mnesia.hrl b/lib/mnesia/src/mnesia.hrl index 2855792646..c8010d5466 100644 --- a/lib/mnesia/src/mnesia.hrl +++ b/lib/mnesia/src/mnesia.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2011. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -35,7 +35,7 @@ -define(ets_last(Tab), ets:last(Tab)). -define(ets_prev(Tab, Key), ets:prev(Tab, Key)). -define(ets_slot(Tab, Pos), ets:slot(Tab, Pos)). --define(ets_new_table(Tab, Props), ets:new(Tab, Props)). +-define(ets_new_table(Tab, Props), _ = ets:new(Tab, Props)). -define(ets_delete_table(Tab), ets:delete(Tab)). -define(ets_fixtable(Tab, Bool), ets:fixtable(Tab, Bool)). diff --git a/lib/mnesia/src/mnesia_controller.erl b/lib/mnesia/src/mnesia_controller.erl index 78f7bfa325..a83e55ac62 100644 --- a/lib/mnesia/src/mnesia_controller.erl +++ b/lib/mnesia/src/mnesia_controller.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2013. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -198,7 +198,8 @@ sync_dump_log(InitBy) -> call({sync_dump_log, InitBy}). async_dump_log(InitBy) -> - ?SERVER_NAME ! {async_dump_log, InitBy}. + ?SERVER_NAME ! {async_dump_log, InitBy}, + ok. %% Wait for tables to be active %% If needed, we will wait for Mnesia to start @@ -293,10 +294,11 @@ update(Fun) -> mnesia_down(Node) -> - case cast({mnesia_down, Node}) of - {error, _} -> mnesia_monitor:mnesia_down(?SERVER_NAME, Node); - _Pid -> ok + case whereis(?SERVER_NAME) of + undefined -> mnesia_monitor:mnesia_down(?SERVER_NAME, Node); + Pid -> gen_server:cast(Pid, {mnesia_down, Node}) end. + wait_for_schema_commit_lock() -> link(whereis(?SERVER_NAME)), unsafe_call(wait_for_schema_commit_lock). @@ -467,7 +469,7 @@ connect_nodes2(Father, Ns, UserFun) -> process_flag(trap_exit, true), Res = try_merge_schema(New, [], UserFun), Msg = {schema_is_merged, [], late_merge, []}, - multicall([node()|Ns], Msg), + _ = multicall([node()|Ns], Msg), After = val({current, db_nodes}), Father ! {?MODULE, self(), Res, mnesia_lib:intersect(Ns,After)}, unlink(Father), @@ -548,7 +550,7 @@ schema_is_merged() -> cast(Msg) -> case whereis(?SERVER_NAME) of - undefined ->{error, {node_not_running, node()}}; + undefined -> ok; Pid -> gen_server:cast(Pid, Msg) end. @@ -1789,7 +1791,7 @@ sync_and_block_table_whereabouts(Tab, ToNode, RemoteS, AccessMode) when Tab /= s true -> Current -- [ToNode]; false -> Current end, - remote_call(ToNode, block_table, [Tab]), + _ = remote_call(ToNode, block_table, [Tab]), [remote_call(Node, add_active_replica, [Tab, ToNode, RemoteS, AccessMode]) || Node <- [ToNode | Ns]], ok. diff --git a/lib/mnesia/src/mnesia_dumper.erl b/lib/mnesia/src/mnesia_dumper.erl index e2a0aa3bda..14665797a0 100644 --- a/lib/mnesia/src/mnesia_dumper.erl +++ b/lib/mnesia/src/mnesia_dumper.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2011. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -85,7 +85,7 @@ adjust_log_writes(DoCast) -> %% Don't care if we lost a few writes mnesia_lib:set_counter(trans_log_writes_left, Max), Diff = Max - Left, - mnesia_lib:incr_counter(trans_log_writes, Diff), + _ = mnesia_lib:incr_counter(trans_log_writes, Diff), global:del_lock(Token, [node()]) end. @@ -451,7 +451,8 @@ disc_delete_table(Tab, Storage) -> Storage == disc_only_copies; Tab == schema -> mnesia_monitor:unsafe_close_dets(Tab), Dat = mnesia_lib:tab2dat(Tab), - file:delete(Dat); + file:delete(Dat), + ok; true -> DclFile = mnesia_lib:tab2dcl(Tab), case get({?MODULE,Tab}) of @@ -466,13 +467,14 @@ disc_delete_table(Tab, Storage) -> file:delete(DcdFile), ok end, - erase({?MODULE, Tab}); + erase({?MODULE, Tab}), + ok; false -> - ignore + ok end. disc_delete_indecies(_Tab, _Cs, Storage) when Storage /= disc_only_copies -> - ignore; + ok; disc_delete_indecies(Tab, Cs, disc_only_copies) -> Indecies = Cs#cstruct.index, mnesia_index:del_transient(Tab, Indecies, disc_only_copies). @@ -522,10 +524,11 @@ insert_op(Tid, _, {op, change_table_copy_type, N, FromS, ToS, TabDef}, InPlace, {disc_copies, ram_copies} when Tab == schema -> mnesia_lib:set(use_dir, false), mnesia_monitor:unsafe_close_dets(Tab), - file:delete(Dat); + ok = file:delete(Dat); {disc_copies, ram_copies} -> - file:delete(Dcl), - file:delete(Dcd); + _ = file:delete(Dcl), + _ = file:delete(Dcd), + ok; {ram_copies, disc_only_copies} -> ok = ensure_rename(Dmp, Dat), true = open_files(Tab, disc_only_copies, InPlace, InitBy), @@ -544,7 +547,8 @@ insert_op(Tid, _, {op, change_table_copy_type, N, FromS, ToS, TabDef}, InPlace, startup -> ignore; _ -> - mnesia_controller:get_disc_copy(Tab) + mnesia_controller:get_disc_copy(Tab), + ok end, disc_delete_table(Tab, disc_only_copies); {disc_copies, disc_only_copies} -> @@ -553,8 +557,9 @@ insert_op(Tid, _, {op, change_table_copy_type, N, FromS, ToS, TabDef}, InPlace, mnesia_schema:ram_delete_table(Tab, FromS), PosList = Cs#cstruct.index, mnesia_index:init_indecies(Tab, disc_only_copies, PosList), - file:delete(Dcl), - file:delete(Dcd); + _ = file:delete(Dcl), + _ = file:delete(Dcd), + ok; {disc_only_copies, disc_copies} -> mnesia_monitor:unsafe_close_dets(Tab), disc_delete_indecies(Tab, Cs, disc_only_copies), diff --git a/lib/mnesia/src/mnesia_event.erl b/lib/mnesia/src/mnesia_event.erl index 35fe2d4035..67ec9d7399 100644 --- a/lib/mnesia/src/mnesia_event.erl +++ b/lib/mnesia/src/mnesia_event.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2013. All Rights Reserved. +%% Copyright Ericsson AB 1997-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -63,7 +63,7 @@ handle_event(Event, State) -> %%----------------------------------------------------------------- handle_info(Msg, State) -> - handle_any_event(Msg, State), + {ok, _} = handle_any_event(Msg, State), {ok, State}. %%----------------------------------------------------------------- diff --git a/lib/mnesia/src/mnesia_index.erl b/lib/mnesia/src/mnesia_index.erl index 54db45e3ba..87cb58dae1 100644 --- a/lib/mnesia/src/mnesia_index.erl +++ b/lib/mnesia/src/mnesia_index.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2013. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -52,7 +52,11 @@ val(Var) -> case ?catch_val(Var) of - {'EXIT', _ReASoN_} -> mnesia_lib:other_val(Var, _ReASoN_); + {'EXIT', _ReASoN_} -> + case mnesia_lib:other_val(Var) of + error -> mnesia_lib:pr_other(Var, _ReASoN_); + Val -> Val + end; _VaLuE_ -> _VaLuE_ end. @@ -229,7 +233,7 @@ del_transient(Tab, Storage) -> PosList = val({Tab, index}), del_transient(Tab, PosList, Storage). -del_transient(_, [], _) -> done; +del_transient(_, [], _) -> ok; del_transient(Tab, [Pos | Tail], Storage) -> delete_transient_index(Tab, Pos, Storage), del_transient(Tab, Tail, Storage). @@ -237,7 +241,7 @@ del_transient(Tab, [Pos | Tail], Storage) -> delete_transient_index(Tab, Pos, disc_only_copies) -> Tag = {Tab, index, Pos}, mnesia_monitor:unsafe_close_dets(Tag), - file:delete(tab2filename(Tab, Pos)), + _ = file:delete(tab2filename(Tab, Pos)), del_index_info(Tab, Pos), %% Uses val(..) mnesia_lib:unset({Tab, {index, Pos}}); @@ -255,7 +259,7 @@ init_disc_index(_Tab, []) -> init_disc_index(Tab, [Pos | Tail]) when is_integer(Pos) -> Fn = tab2filename(Tab, Pos), IxTag = {Tab, index, Pos}, - file:delete(Fn), + _ = file:delete(Fn), Args = [{file, Fn}, {keypos, 1}, {type, bag}], mnesia_monitor:open_dets(IxTag, Args), Storage = disc_only_copies, diff --git a/lib/mnesia/src/mnesia_lib.erl b/lib/mnesia/src/mnesia_lib.erl index ae6631646c..a32c69c59e 100644 --- a/lib/mnesia/src/mnesia_lib.erl +++ b/lib/mnesia/src/mnesia_lib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2011. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -115,6 +115,8 @@ mkcore/1, not_active_here/1, other_val/2, + other_val/1, + pr_other/2, overload_read/0, overload_read/1, overload_set/2, @@ -296,11 +298,7 @@ active_here(Tab) -> not_active_here(Tab) -> not active_here(Tab). -exists(Fname) -> - case file:open(Fname, [raw,read]) of - {ok, F} ->file:close(F), true; - _ -> false - end. +exists(Fname) -> filelib:is_regular(Fname). dir() -> mnesia_monitor:get_env(dir). @@ -393,16 +391,19 @@ unset(Var) -> ?ets_delete(mnesia_gvar, Var). other_val(Var, Other) -> + case other_val(Var) of + error -> pr_other(Var, Other); + Val -> Val + end. + +other_val(Var) -> case Var of {_, where_to_read} -> nowhere; {_, where_to_write} -> []; {_, active_replicas} -> []; - _ -> - pr_other(Var, Other) + _ -> error end. --spec pr_other(_,_) -> no_return(). - pr_other(Var, Other) -> Why = case is_running() of @@ -596,7 +597,7 @@ coredump(CrashInfo) -> Core = mkcore(CrashInfo), Out = core_file(), important("Writing Mnesia core to file: ~p...~p~n", [Out, CrashInfo]), - file:write_file(Out, Core), + _ = file:write_file(Out, Core), Out. core_file() -> @@ -620,7 +621,7 @@ mkcore(CrashInfo) -> Core = [ CrashInfo, {time, {date(), time()}}, - {self, catch process_info(self())}, + {self, proc_dbg_info(self())}, {nodes, catch rpc:multicall(Nodes, ?MODULE, get_node_number, [])}, {applications, catch lists:sort(application:loaded_applications())}, {flags, catch init:get_arguments()}, @@ -697,7 +698,7 @@ relatives() -> Info = fun(Name) -> case whereis(Name) of undefined -> false; - Pid -> {true, {Name, Pid, catch process_info(Pid)}} + Pid -> {true, {Name, Pid, proc_dbg_info(Pid)}} end end, lists:zf(Info, mnesia:ms()). @@ -706,14 +707,14 @@ workers({workers, Loaders, Senders, Dumper}) -> Info = fun({Pid, {send_table, Tab, _Receiver, _St}}) -> case Pid of undefined -> false; - Pid -> {true, {Pid, Tab, catch process_info(Pid)}} + Pid -> {true, {Pid, Tab, proc_dbg_info(Pid)}} end; ({Pid, What}) when is_pid(Pid) -> - {true, {Pid, What, catch process_info(Pid)}}; + {true, {Pid, What, proc_dbg_info(Pid)}}; ({Name, Pid}) -> case Pid of undefined -> false; - Pid -> {true, {Name, Pid, catch process_info(Pid)}} + Pid -> {true, {Name, Pid, proc_dbg_info(Pid)}} end end, SInfo = lists:zf(Info, Senders), @@ -727,13 +728,21 @@ locking_procs(LockList) when is_list(LockList) -> Pid = Tid#tid.pid, case node(Pid) == node() of true -> - {true, {Pid, catch process_info(Pid)}}; + {true, {Pid, proc_dbg_info(Pid)}}; _ -> false end end, lists:zf(Info, UT). +proc_dbg_info(Pid) -> + try + [process_info(Pid, current_stacktrace)| + process_info(Pid)] + catch _:R -> + [{process_info,crashed,R}] + end. + view() -> Bin = mkcore({crashinfo, {"view only~n", []}}), vcore(Bin). @@ -806,9 +815,9 @@ vcore(File) -> vcore_elem({schema_file, {ok, B}}) -> Fname = "/tmp/schema.DAT", - file:write_file(Fname, B), - dets:view(Fname), - file:delete(Fname); + _ = file:write_file(Fname, B), + _ = dets:view(Fname), + _ = file:delete(Fname); vcore_elem({logfile, {ok, BinList}}) -> Fun = fun({F, Info}) -> @@ -922,7 +931,7 @@ random_time(Retries, _Counter0) -> case get(random_seed) of undefined -> {X, Y, Z} = erlang:now(), %% time() - random:seed(X, Y, Z), + _ = random:seed(X, Y, Z), Time = Dup + random:uniform(MaxIntv), %% dbg_out("---random_test rs ~w max ~w val ~w---~n", [Retries, MaxIntv, Time]), Time; @@ -958,20 +967,17 @@ report_system_event({'EXIT', Reason}, Event) -> unlink(Pid), %% We get an exit signal if server dies - receive - {'EXIT', Pid, _Reason} -> - {error, {node_not_running, node()}} - after 0 -> - gen_event:stop(mnesia_event), - ok + receive {'EXIT', Pid, _Reason} -> ok + after 0 -> gen_event:stop(mnesia_event) end; Error -> Msg = "Mnesia(~p): Cannot report event ~p: ~p (~p)~n", error_logger:format(Msg, [node(), Event, Reason, Error]) - end; + end, + ok; report_system_event(_Res, _Event) -> - ignore. + ok. %% important messages are reported regardless of debug level important(Format, Args) -> @@ -1025,8 +1031,8 @@ copy_file(From, To) -> case file:open(To, [raw, binary, write]) of {ok, T} -> Res = copy_file_loop(F, T, 8000), - file:close(F), - file:close(T), + ok = file:close(F), + ok = file:close(T), Res; {error, Reason} -> {error, Reason} @@ -1038,7 +1044,7 @@ copy_file(From, To) -> copy_file_loop(F, T, ChunkSize) -> case file:read(F, ChunkSize) of {ok, Bin} -> - file:write(T, Bin), + ok = file:write(T, Bin), copy_file_loop(F, T, ChunkSize); eof -> ok; @@ -1205,7 +1211,7 @@ dets_to_ets(Tabname, Tab, File, Type, Rep, Lock) -> {keypos, 2}, {repair, Rep}]) of {ok, Tabname} -> Res = dets:to_ets(Tabname, Tab), - Close(Tabname), + ok = Close(Tabname), trav_ret(Res, Tab); Other -> Other diff --git a/lib/mnesia/src/mnesia_locker.erl b/lib/mnesia/src/mnesia_locker.erl index c4fe370ec1..81b435c6dc 100644 --- a/lib/mnesia/src/mnesia_locker.erl +++ b/lib/mnesia/src/mnesia_locker.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2013. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -103,7 +103,8 @@ val(Var) -> end. reply(From, R) -> - From ! {?MODULE, node(), R}. + From ! {?MODULE, node(), R}, + true. %% Quiets dialyzer l_request(Node, X, Store) -> {?MODULE, Node} ! {self(), X}, @@ -269,7 +270,8 @@ try_sticky_lock(Tid, Op, Pid, {Tab, _} = Oid) -> try_lock(Tid, Op, Pid, Oid); [{_,N}] -> Req = {Pid, {Op, Tid, Oid}}, - Pid ! {?MODULE, node(), {switch, N, Req}} + Pid ! {?MODULE, node(), {switch, N, Req}}, + true end. try_lock(Tid, read_write, Pid, Oid) -> diff --git a/lib/mnesia/src/mnesia_log.erl b/lib/mnesia/src/mnesia_log.erl index 18303869ed..d2fd04a60b 100644 --- a/lib/mnesia/src/mnesia_log.erl +++ b/lib/mnesia/src/mnesia_log.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2011. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -393,13 +393,15 @@ unsafe_close_log(Log) -> purge_some_logs() -> mnesia_monitor:unsafe_close_log(latest_log), - file:delete(latest_log_file()), - file:delete(decision_tab_file()). + _ = file:delete(latest_log_file()), + _ = file:delete(decision_tab_file()), + ok. purge_all_logs() -> - file:delete(previous_log_file()), - file:delete(latest_log_file()), - file:delete(decision_tab_file()). + _ = file:delete(previous_log_file()), + _ = file:delete(latest_log_file()), + _ = file:delete(decision_tab_file()), + ok. %% Prepare dump by renaming the open logfile if possible %% Returns a tuple on the following format: {Res, OpenLog} diff --git a/lib/mnesia/src/mnesia_monitor.erl b/lib/mnesia/src/mnesia_monitor.erl index 438da65158..6fc1a394a6 100644 --- a/lib/mnesia/src/mnesia_monitor.erl +++ b/lib/mnesia/src/mnesia_monitor.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2013. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -44,6 +44,7 @@ set_env/2, start/0, start_proc/4, + sync_log/1, terminate_proc/3, unsafe_close_dets/1, unsafe_close_log/1, @@ -78,7 +79,7 @@ -record(state, {supervisor, pending_negotiators = [], going_down = [], tm_started = false, early_connects = [], - connecting, mq = []}). + connecting, mq = [], remote_node_status = []}). -define(current_protocol_version, {8,1}). @@ -118,6 +119,9 @@ open_log(Args) -> reopen_log(Name, Fname, Head) -> unsafe_call({reopen_log, Name, Fname, Head}). +sync_log(Name) -> + unsafe_call({sync_log, Name}). + close_log(Name) -> unsafe_call({close_log, Name}). @@ -202,7 +206,7 @@ needs_protocol_conversion(Node) -> cast(Msg) -> case whereis(?MODULE) of - undefined -> ignore; + undefined -> ok; Pid -> gen_server:cast(Pid, Msg) end. @@ -382,6 +386,9 @@ handle_call({reopen_log, Name, Fname, Head}, _From, State) -> {noreply, State} end; +handle_call({sync_log, Name}, _From, State) -> + {reply, disk_log:sync(Name), State}; + handle_call({close_log, Name}, _From, State) -> case disk_log:close(Name) of ok -> @@ -395,7 +402,7 @@ handle_call({close_log, Name}, _From, State) -> end; handle_call({unsafe_close_log, Name}, _From, State) -> - disk_log:close(Name), + _ = disk_log:close(Name), {reply, ok, State}; handle_call({negotiate_protocol, Mon, _Version, _Protocols}, _From, State) @@ -439,7 +446,7 @@ handle_call({negotiate_protocol, Nodes}, From, State) -> end; handle_call(init, _From, State) -> - net_kernel:monitor_nodes(true), + _ = net_kernel:monitor_nodes(true), EarlyNodes = State#state.early_connects, State2 = State#state{tm_started = true}, {reply, EarlyNodes, State2}; @@ -488,17 +495,18 @@ handle_cast({mnesia_down, mnesia_tm, Node}, State) -> GoingDown = lists:delete(Node, State#state.going_down), State2 = State#state{going_down = GoingDown}, Pending = State#state.pending_negotiators, + State3 = check_raise_conditon_nodeup(Node, State2), case lists:keysearch(Node, 1, Pending) of {value, {Node, Mon, ReplyTo, Reply}} -> %% Late reply to remote monitor link(Mon), %% link to remote Monitor gen_server:reply(ReplyTo, Reply), P2 = lists:keydelete(Node, 1,Pending), - State3 = State2#state{pending_negotiators = P2}, - process_q(State3); + State4 = State3#state{pending_negotiators = P2}, + process_q(State4); false -> %% No pending remote monitors - process_q(State2) + process_q(State3) end; handle_cast({disconnect, Node}, State) -> @@ -564,27 +572,18 @@ handle_info({protocol_negotiated, From,Res}, State) -> gen_server:reply(From, Res), process_q(State#state{connecting = undefined}); -handle_info({nodeup, Node}, State) -> - %% Ok, we are connected to yet another Erlang node - %% Let's check if Mnesia is running there in order - %% to detect if the network has been partitioned - %% due to communication failure. - - HasDown = mnesia_recover:has_mnesia_down(Node), - ImRunning = mnesia_lib:is_running(), +handle_info({check_nodeup, Node}, State) -> + State2 = check_mnesia_down(Node, State), + {noreply, State2}; - if - %% If I'm not running the test will be made later. - HasDown == true, ImRunning == yes -> - spawn_link(?MODULE, detect_partitioned_network, [self(), Node]); - true -> - ignore - end, - {noreply, State}; +handle_info({nodeup, Node}, State) -> + State2 = remote_node_status(Node, up, State), + State3 = check_mnesia_down(Node, State2), + {noreply, State3}; -handle_info({nodedown, _Node}, State) -> - %% Ignore, we are only caring about nodeup's - {noreply, State}; +handle_info({nodedown, Node}, State) -> + State2 = remote_node_status(Node, down, State), + {noreply, State2}; handle_info({disk_log, _Node, Log, Info}, State) -> case Info of @@ -826,3 +825,48 @@ report_inconsistency([{badrpc, _Reason} | Replies], Context, Status) -> report_inconsistency(Replies, Context, Status); report_inconsistency([], _Context, Status) -> Status. + +remote_node_status(Node, Status, State) -> + {ok, Nodes} = mnesia_schema:read_nodes(), + case lists:member(Node, Nodes) of + true -> + update_node_status({Node, Status}, State); + _ -> + State + end. + +update_node_status({Node, down}, State = #state{remote_node_status = RNodeS}) -> + RNodeS2 = lists:ukeymerge(1, [{Node, down}], RNodeS), + State#state{remote_node_status = RNodeS2}; +update_node_status({Node, up}, State = #state{remote_node_status = RNodeS}) -> + case lists:keyfind(Node, 1, RNodeS) of + {Node, down} -> + RNodeS2 = lists:ukeymerge(1, [{Node, up}], RNodeS), + State#state{remote_node_status = RNodeS2}; + _ -> + State + end. + +check_raise_conditon_nodeup(Node, State = #state{remote_node_status = RNodeS}) -> + case lists:keyfind(Node, 1, RNodeS) of + {Node, up} -> + self() ! {check_nodeup, Node}; + _ -> + ignore + end, + State#state{remote_node_status = lists:keydelete(Node, 1, RNodeS)}. + +check_mnesia_down(Node, State = #state{remote_node_status = RNodeS}) -> + %% Check if the network has been partitioned + %% due to communication failure. + + HasDown = mnesia_recover:has_mnesia_down(Node), + ImRunning = mnesia_lib:is_running(), + if + %% If I'm not running the test will be made later. + HasDown == true, ImRunning == yes -> + spawn_link(?MODULE, detect_partitioned_network, [self(), Node]), + State#state{remote_node_status = lists:keydelete(Node, 1, RNodeS)}; + true -> + State + end. diff --git a/lib/mnesia/src/mnesia_recover.erl b/lib/mnesia/src/mnesia_recover.erl index 7aa03bda37..b6492707e2 100644 --- a/lib/mnesia/src/mnesia_recover.erl +++ b/lib/mnesia/src/mnesia_recover.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2013. All Rights Reserved. +%% Copyright Ericsson AB 1997-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -178,7 +178,11 @@ log_decision(D) -> val(Var) -> case ?catch_val(Var) of - {'EXIT', Reason} -> mnesia_lib:other_val(Var, Reason); + {'EXIT', Reason} -> + case mnesia_lib:other_val(Var) of + error -> mnesia_lib:pr_other(Var, Reason); + Val -> Val + end; Value -> Value end. diff --git a/lib/mnesia/src/mnesia_snmp_hook.erl b/lib/mnesia/src/mnesia_snmp_hook.erl index 893b39f3c0..256f83b029 100644 --- a/lib/mnesia/src/mnesia_snmp_hook.erl +++ b/lib/mnesia/src/mnesia_snmp_hook.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2011. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -32,7 +32,11 @@ val(Var) -> case ?catch_val(Var) of - {'EXIT', _ReASoN_} -> mnesia_lib:other_val(Var, _ReASoN_); + {'EXIT', _ReASoN_} -> + case mnesia_lib:other_val(Var) of + error -> mnesia_lib:pr_other(Var, _ReASoN_); + Val -> Val + end; _VaLuE_ -> _VaLuE_ end. diff --git a/lib/mnesia/src/mnesia_tm.erl b/lib/mnesia/src/mnesia_tm.erl index 17af0cad44..af658150da 100644 --- a/lib/mnesia/src/mnesia_tm.erl +++ b/lib/mnesia/src/mnesia_tm.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2013. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -183,7 +183,8 @@ mnesia_down(Node) -> undefined -> mnesia_monitor:mnesia_down(?MODULE, Node); Pid -> - Pid ! {mnesia_down, Node} + Pid ! {mnesia_down, Node}, + ok end. prepare_checkpoint(Nodes, Cp) -> |