diff options
Diffstat (limited to 'lib/mnesia/src')
-rw-r--r-- | lib/mnesia/src/Makefile | 1 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia.app.src | 48 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia.erl | 12 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia.hrl | 2 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_event.erl | 8 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_kernel_sup.erl | 1 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_lib.erl | 56 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_loader.erl | 4 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_monitor.erl | 8 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_rpc.erl | 86 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_schema.erl | 2 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_sp.erl | 13 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_sup.erl | 2 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_text.erl | 4 | ||||
-rw-r--r-- | lib/mnesia/src/mnesia_tm.erl | 6 |
15 files changed, 178 insertions, 75 deletions
diff --git a/lib/mnesia/src/Makefile b/lib/mnesia/src/Makefile index 7d316df263..90e8780754 100644 --- a/lib/mnesia/src/Makefile +++ b/lib/mnesia/src/Makefile @@ -65,6 +65,7 @@ MODULES= \ mnesia_monitor \ mnesia_recover \ mnesia_registry \ + mnesia_rpc \ mnesia_schema\ mnesia_snmp_hook \ mnesia_subscr \ diff --git a/lib/mnesia/src/mnesia.app.src b/lib/mnesia/src/mnesia.app.src index c755b4d4b9..77bd1a7816 100644 --- a/lib/mnesia/src/mnesia.app.src +++ b/lib/mnesia/src/mnesia.app.src @@ -2,36 +2,37 @@ [{description, "MNESIA CXC 138 12"}, {vsn, "%VSN%"}, {modules, [ - mnesia, + mnesia, mnesia_app, mnesia_backend_type, - mnesia_backup, - mnesia_bup, - mnesia_checkpoint, + mnesia_backup, + mnesia_bup, + mnesia_checkpoint, mnesia_checkpoint_sup, mnesia_controller, - mnesia_dumper, - mnesia_event, + mnesia_dumper, + mnesia_event, mnesia_ext_sup, - mnesia_frag, - mnesia_frag_hash, - mnesia_index, + mnesia_frag, + mnesia_frag_hash, + mnesia_index, mnesia_kernel_sup, mnesia_late_loader, - mnesia_lib, - mnesia_loader, - mnesia_locker, - mnesia_log, - mnesia_monitor, + mnesia_lib, + mnesia_loader, + mnesia_locker, + mnesia_log, + mnesia_monitor, mnesia_recover, mnesia_registry, - mnesia_schema, - mnesia_snmp_hook, - mnesia_subscr, - mnesia_sup, + mnesia_rpc, + mnesia_schema, + mnesia_snmp_hook, + mnesia_subscr, + mnesia_sup, mnesia_sp, mnesia_text, - mnesia_tm + mnesia_tm ]}, {registered, [ mnesia_dumper_load_regulator, @@ -39,12 +40,13 @@ mnesia_fallback, mnesia_controller, mnesia_kernel_sup, - mnesia_late_loader, - mnesia_locker, + mnesia_late_loader, + mnesia_locker, mnesia_monitor, mnesia_recover, - mnesia_substr, - mnesia_sup, + mnesia_rpc, + mnesia_substr, + mnesia_sup, mnesia_tm ]}, {applications, [kernel, stdlib]}, diff --git a/lib/mnesia/src/mnesia.erl b/lib/mnesia/src/mnesia.erl index 02bc884e36..560ebca824 100644 --- a/lib/mnesia/src/mnesia.erl +++ b/lib/mnesia/src/mnesia.erl @@ -2057,8 +2057,14 @@ dirty_rpc(Tab, M, F, Args) -> do_dirty_rpc(_Tab, nowhere, _, _, Args) -> mnesia:abort({no_exists, Args}); +do_dirty_rpc(_Tab, Local, M, F, Args) when Local =:= node() -> + try apply(M,F,Args) + catch + throw:Res -> Res; + _:_ -> mnesia:abort({badarg, Args}) + end; do_dirty_rpc(Tab, Node, M, F, Args) -> - case rpc:call(Node, M, F, Args) of + case mnesia_rpc:call(Node, M, F, Args) of {badrpc, Reason} -> timer:sleep(20), %% Do not be too eager, and can't use yield on SMP %% Sync with mnesia_monitor @@ -2166,7 +2172,7 @@ raw_table_info(Tab, Item) -> disc_only_copies -> info_reply(dets:info(Tab, Item), Tab, Item); {ext, Alias, Mod} -> - info_reply(catch Mod:info(Alias, Tab, Item), Tab, Item); + info_reply(Mod:info(Alias, Tab, Item), Tab, Item); unknown -> bad_info_reply(Tab, Item) end @@ -2731,7 +2737,7 @@ create_table(Arg) -> create_table(Name, Arg) when is_list(Arg) -> mnesia_schema:create_table([{name, Name}| Arg]); create_table(Name, Arg) -> - {aborted, badarg, Name, Arg}. + {aborted, {badarg, Name, Arg}}. -spec delete_table(Tab::table()) -> t_result('ok'). delete_table(Tab) -> diff --git a/lib/mnesia/src/mnesia.hrl b/lib/mnesia/src/mnesia.hrl index fe48a6fe3d..4ddfc17a06 100644 --- a/lib/mnesia/src/mnesia.hrl +++ b/lib/mnesia/src/mnesia.hrl @@ -44,6 +44,8 @@ -define(SAFE(OP), try (OP) catch error:_ -> ok end). -define(CATCH(OP), try (OP) catch _:_Reason -> {'EXIT', _Reason} end). +-define(CATCHU(OP), fun() -> try (OP) catch _:_Reason -> {'EXIT', _Reason} end end()). + -define(catch_val(Var), (try ?ets_lookup_element(mnesia_gvar, Var, 2) catch error:_ -> {'EXIT', {badarg, []}} end)). diff --git a/lib/mnesia/src/mnesia_event.erl b/lib/mnesia/src/mnesia_event.erl index 49b3990086..0e96d5c73f 100644 --- a/lib/mnesia/src/mnesia_event.erl +++ b/lib/mnesia/src/mnesia_event.erl @@ -36,6 +36,8 @@ dumped_core = false, %% only dump fatal core once args}). +-include("mnesia.hrl"). + %%%---------------------------------------------------------------- %%% Callback functions from gen_server %%%---------------------------------------------------------------- @@ -131,14 +133,14 @@ handle_system_event({mnesia_down, Node}, State) -> "must be restarted. Forcing shutdown " "after mnesia_down from ~p...~n", report_fatal(Msg, [Node], nocore, State#state.dumped_core), - catch exit(whereis(mnesia_monitor), fatal), + ?SAFE(exit(whereis(mnesia_monitor), fatal)), {ok, State}; {UserMod, UserFunc} -> Msg = "Warning: A fallback is installed and Mnesia got mnesia_down " "from ~p. ~n", report_info(Msg, [Node]), - case catch apply(UserMod, UserFunc, [Node]) of - {'EXIT', {undef, _Reason}} -> + case ?CATCH(apply(UserMod, UserFunc, [Node])) of + {'EXIT', {undef, _R}} -> %% Backward compatibility apply(UserMod, UserFunc, []); {'EXIT', Reason} -> diff --git a/lib/mnesia/src/mnesia_kernel_sup.erl b/lib/mnesia/src/mnesia_kernel_sup.erl index a761d5eed0..7f226d92c4 100644 --- a/lib/mnesia/src/mnesia_kernel_sup.erl +++ b/lib/mnesia/src/mnesia_kernel_sup.erl @@ -42,6 +42,7 @@ init([]) -> worker_spec(mnesia_locker, timer:seconds(3), ProcLib), worker_spec(mnesia_recover, timer:minutes(3), [gen_server]), worker_spec(mnesia_tm, timer:seconds(30), ProcLib), + worker_spec(mnesia_rpc, timer:seconds(3), [gen_server]), supervisor_spec(mnesia_checkpoint_sup), worker_spec(mnesia_controller, timer:seconds(3), [gen_server]), worker_spec(mnesia_late_loader, timer:seconds(3), ProcLib) diff --git a/lib/mnesia/src/mnesia_lib.erl b/lib/mnesia/src/mnesia_lib.erl index 6abc05fade..dd28686f78 100644 --- a/lib/mnesia/src/mnesia_lib.erl +++ b/lib/mnesia/src/mnesia_lib.erl @@ -675,41 +675,41 @@ mkcore(CrashInfo) -> % dbg_out("Making a Mnesia core dump...~p~n", [CrashInfo]), Nodes = [node() |nodes()], %%TidLocks = (catch ets:tab2list(mnesia_tid_locks)), - HeldLocks = (catch mnesia:system_info(held_locks)), + HeldLocks = ?CATCHU(mnesia:system_info(held_locks)), Core = [ CrashInfo, {time, {date(), time()}}, {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()}, - {code_path, catch code:get_path()}, - {code_loaded, catch lists:sort(code:all_loaded())}, - {etsinfo, catch ets_info(ets:all())}, - - {version, catch mnesia:system_info(version)}, - {schema, catch ets:tab2list(schema)}, - {gvar, catch ets:tab2list(mnesia_gvar)}, - {master_nodes, catch mnesia_recover:get_master_node_info()}, - - {processes, catch procs()}, - {relatives, catch relatives()}, - {workers, catch workers(mnesia_controller:get_workers(2000))}, - {locking_procs, catch locking_procs(HeldLocks)}, + {nodes, ?CATCHU(rpc:multicall(Nodes, ?MODULE, get_node_number, []))}, + {applications, ?CATCHU(lists:sort(application:loaded_applications()))}, + {flags, ?CATCHU(init:get_arguments())}, + {code_path, ?CATCHU(code:get_path())}, + {code_loaded, ?CATCHU(lists:sort(code:all_loaded()))}, + {etsinfo, ?CATCHU(ets_info(ets:all()))}, + + {version, ?CATCHU(mnesia:system_info(version))}, + {schema, ?CATCHU(ets:tab2list(schema))}, + {gvar, ?CATCHU(ets:tab2list(mnesia_gvar))}, + {master_nodes, ?CATCHU(mnesia_recover:get_master_node_info())}, + + {processes, ?CATCHU(procs())}, + {relatives, ?CATCHU(relatives())}, + {workers, ?CATCHU(workers(mnesia_controller:get_workers(2000)))}, + {locking_procs, ?CATCHU(locking_procs(HeldLocks))}, {held_locks, HeldLocks}, - {lock_queue, catch mnesia:system_info(lock_queue)}, - {load_info, catch mnesia_controller:get_info(2000)}, - {trans_info, catch mnesia_tm:get_info(2000)}, + {lock_queue, ?CATCHU(mnesia:system_info(lock_queue))}, + {load_info, ?CATCHU(mnesia_controller:get_info(2000))}, + {trans_info, ?CATCHU(mnesia_tm:get_info(2000))}, - {schema_file, catch file:read_file(tab2dat(schema))}, - {dir_info, catch dir_info()}, - {logfile, catch {ok, read_log_files()}} + {schema_file, ?CATCHU(file:read_file(tab2dat(schema)))}, + {dir_info, ?CATCHU(dir_info())}, + {logfile, ?CATCHU({ok, read_log_files()})} ], term_to_binary(Core). procs() -> - Fun = fun(P) -> {P, (catch lists:zf(fun proc_info/1, process_info(P)))} end, + Fun = fun(P) -> {P, (?CATCH(lists:zf(fun proc_info/1, process_info(P))))} end, lists:map(Fun, processes()). proc_info({registered_name, Val}) -> {true, Val}; @@ -730,7 +730,7 @@ have_majority(_Tab, AllNodes, HaveNodes) -> length(Present) > length(Missing). read_log_files() -> - [{F, catch file:read_file(F)} || F <- mnesia_log:log_files()]. + [{F, ?CATCH(file:read_file(F))} || F <- mnesia_log:log_files()]. dir_info() -> {ok, Cwd} = file:get_cwd(), @@ -739,7 +739,7 @@ dir_info() -> {mnesia_dir, Dir, file:read_file_info(Dir)}] ++ case file:list_dir(Dir) of {ok, Files} -> - [{mnesia_file, F, catch file:read_file_info(dir(F))} || F <- Files]; + [{mnesia_file, F, ?CATCH(file:read_file_info(dir(F)))} || F <- Files]; Other -> [Other] end. @@ -854,7 +854,7 @@ vcore(Bin) when is_binary(Bin) -> Core = binary_to_term(Bin), Fun = fun({Item, Info}) -> show("***** ~tp *****~n", [Item]), - case catch vcore_elem({Item, Info}) of + case ?CATCHU(vcore_elem({Item, Info})) of {'EXIT', Reason} -> show("{'EXIT', ~tp}~n", [Reason]); _ -> ok @@ -1446,7 +1446,7 @@ eval_debug_fun(FunId, EvalContext, EvalFile, EvalLine) -> ok end end - catch error -> + catch _:_ -> ok end. diff --git a/lib/mnesia/src/mnesia_loader.erl b/lib/mnesia/src/mnesia_loader.erl index 2cdae0c906..c34a83bb6c 100644 --- a/lib/mnesia/src/mnesia_loader.erl +++ b/lib/mnesia/src/mnesia_loader.erl @@ -654,8 +654,8 @@ down(Tab, Storage) -> mnesia_lib:dets_sync_close(Tab), file:delete(TmpFile); {ext, Alias, Mod} -> - catch Mod:close_table(Alias, Tab), - catch Mod:delete_table(Alias, Tab) + ?CATCHU(Mod:close_table(Alias, Tab)), + ?CATCHU(Mod:delete_table(Alias, Tab)) end, mnesia_checkpoint:tm_del_copy(Tab, node()), mnesia_controller:sync_del_table_copy_whereabouts(Tab, node()), diff --git a/lib/mnesia/src/mnesia_monitor.erl b/lib/mnesia/src/mnesia_monitor.erl index 4e50b46da8..5ce1439298 100644 --- a/lib/mnesia/src/mnesia_monitor.erl +++ b/lib/mnesia/src/mnesia_monitor.erl @@ -83,9 +83,9 @@ going_down = [], tm_started = false, early_connects = [], connecting, mq = [], remote_node_status = []}). --define(current_protocol_version, {8,4}). +-define(current_protocol_version, {8,5}). --define(previous_protocol_version, {8,3}). +-define(previous_protocol_version, {8,4}). start() -> gen_server:start_link({local, ?MODULE}, ?MODULE, @@ -196,7 +196,7 @@ protocol_version() -> %% A sorted list of acceptable protocols the %% preferred protocols are first in the list acceptable_protocol_versions() -> - [protocol_version(), ?previous_protocol_version]. + [protocol_version(), ?previous_protocol_version, {8,3}]. needs_protocol_conversion(Node) -> case {?catch_val({protocol, Node}), protocol_version()} of @@ -409,7 +409,7 @@ handle_call({unsafe_close_log, Name}, _From, State) -> {reply, ok, State}; handle_call({unsafe_create_external, Tab, Alias, Mod, Cs}, _From, State) -> - case catch Mod:create_table(Alias, Tab, mnesia_schema:cs2list(Cs)) of + case ?CATCH(Mod:create_table(Alias, Tab, mnesia_schema:cs2list(Cs))) of {'EXIT', ExitReason} -> {reply, {error, ExitReason}, State}; Reply -> diff --git a/lib/mnesia/src/mnesia_rpc.erl b/lib/mnesia/src/mnesia_rpc.erl new file mode 100644 index 0000000000..bbeacce9db --- /dev/null +++ b/lib/mnesia/src/mnesia_rpc.erl @@ -0,0 +1,86 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2019. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +%% Don't use the system rpc server since it may overload other +%% applications when using a lot of dirty read operations. + +-module(mnesia_rpc). +-behaviour(gen_server). + +-export([start/0, + call/4 + ]). + + +%% gen_server callbacks +-export([init/1, + handle_call/3, + handle_cast/2, + handle_info/2, + terminate/2, + code_change/3 + ]). + +-include("mnesia.hrl"). + +start() -> + gen_server:start_link({local, ?MODULE}, ?MODULE, [self()], + [{timeout, infinity} %%, {debug, [trace]} + ]). + +call(Node, M, F, Args) -> + case ?catch_val({protocol, Node}) of + {Ver, _} when Ver < {8,5} -> + rpc:call(Node, M, F, Args); + _ -> + try gen_server:call({?MODULE, Node}, {apply, M, F, Args}, infinity) + catch + _:Reason -> {badrpc, {'EXIT', Reason}} + end + end. + +init([_Parent]) -> + {ok, #{}}. + +handle_call({apply, Mod, Fun, Args}, _From, State) -> + %% rpc is just for ets:lookups so no need to spawn requests + Result = try apply(Mod, Fun, Args) + catch throw:Res -> Res; + _:Reason -> {badrpc, {'EXIT', Reason}} + end, + {reply, Result, State}; +handle_call(Msg, _From, State) -> + error("~p got unexpected call: ~tp~n", [?MODULE, Msg]), + {reply, badop, State}. + +handle_cast(Msg, State) -> + mnesia_lib:error("~p got unexpected cast: ~tp~n", [?MODULE, Msg]), + {noreply, State}. + +handle_info(Msg, State) -> + mnesia_lib:error("~p got unexpected info: ~tp~n", [?MODULE, Msg]), + {noreply, State}. + + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +terminate(_Reason, _State) -> + ok. diff --git a/lib/mnesia/src/mnesia_schema.erl b/lib/mnesia/src/mnesia_schema.erl index d0f5d0e07b..4a65f3996a 100644 --- a/lib/mnesia/src/mnesia_schema.erl +++ b/lib/mnesia/src/mnesia_schema.erl @@ -1271,7 +1271,7 @@ verify_nodes(Cs) -> lists:foreach(AtomCheck, Nodes). verify(Expected, Fun, Error) when is_function(Fun) -> - do_verify(Expected, catch Fun(), Error); + do_verify(Expected, ?CATCH(Fun()), Error); verify(Expected, Actual, Error) -> do_verify(Expected, Actual, Error). diff --git a/lib/mnesia/src/mnesia_sp.erl b/lib/mnesia/src/mnesia_sp.erl index d65c659690..0c56107c41 100644 --- a/lib/mnesia/src/mnesia_sp.erl +++ b/lib/mnesia/src/mnesia_sp.erl @@ -30,12 +30,15 @@ init_proc(Who, Mod, Fun, Args) -> mnesia_lib:verbose("~p starting: ~p~n", [Who, self()]), - case catch apply(Mod, Fun, Args) of - {'EXIT', Reason} -> - mnesia_monitor:terminate_proc(Who, Reason, Args), + try + apply(Mod, Fun, Args) + catch + exit:Reason when Reason =:= shutdown; Reason =:= kill; Reason =:= normal -> + mnesia_monitor:terminate_proc(Who, Reason, Args), exit(Reason); - Other -> - Other + _:Reason:ST -> + mnesia_monitor:terminate_proc(Who, {Reason,ST}, Args), + exit(Reason) end. diff --git a/lib/mnesia/src/mnesia_sup.erl b/lib/mnesia/src/mnesia_sup.erl index 3e5792900b..fd5156d2a4 100644 --- a/lib/mnesia/src/mnesia_sup.erl +++ b/lib/mnesia/src/mnesia_sup.erl @@ -88,7 +88,7 @@ add_event_handler() -> kill() -> Mnesia = [mnesia_fallback | mnesia:ms()], - Kill = fun(Name) -> catch exit(whereis(Name), kill) end, + Kill = fun(Name) -> try exit(whereis(Name), kill) catch _:_ -> ok end end, lists:foreach(Kill, Mnesia), lists:foreach(fun ensure_dead/1, Mnesia), timer:sleep(10), diff --git a/lib/mnesia/src/mnesia_text.erl b/lib/mnesia/src/mnesia_text.erl index cc21621ff4..ee31fdfd27 100644 --- a/lib/mnesia/src/mnesia_text.erl +++ b/lib/mnesia/src/mnesia_text.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2018. All Rights Reserved. +%% Copyright Ericsson AB 1996-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -170,7 +170,7 @@ read_terms(Stream, File, Line, L) -> end. read_term_from_stream(Stream, File, Line) -> - R = io:request(Stream, {get_until,'',erl_scan,tokens,[Line]}), + R = io:request(Stream, {get_until,latin1,'',erl_scan,tokens,[Line]}), case R of {ok,Toks,EndLine} -> case erl_parse:parse_term(Toks) of diff --git a/lib/mnesia/src/mnesia_tm.erl b/lib/mnesia/src/mnesia_tm.erl index 18520423ba..41e7ddce87 100644 --- a/lib/mnesia/src/mnesia_tm.erl +++ b/lib/mnesia/src/mnesia_tm.erl @@ -2082,9 +2082,9 @@ ask_commit(_Protocol, _Tid, [], _DiscNs, _RamNs, WaitFor, Local) -> {WaitFor, Local}. convert_old(sync_asym_trans, Node) -> - case mnesia_monitor:needs_protocol_conversion(Node) of - true -> asym_trans; - false -> sync_asym_trans + case ?catch_val({protocol, Node}) of + {{8,3}, _} -> asym_trans; + _ -> sync_asym_trans end; convert_old(Protocol, _) -> Protocol. |