aboutsummaryrefslogtreecommitdiffstats
path: root/lib/sasl/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sasl/src')
-rw-r--r--lib/sasl/src/release_handler.erl42
-rw-r--r--lib/sasl/src/release_handler_1.erl44
-rw-r--r--lib/sasl/src/systools_rc.erl28
-rw-r--r--lib/sasl/src/systools_relup.erl6
4 files changed, 84 insertions, 36 deletions
diff --git a/lib/sasl/src/release_handler.erl b/lib/sasl/src/release_handler.erl
index 4c43277848..b60aa847df 100644
--- a/lib/sasl/src/release_handler.erl
+++ b/lib/sasl/src/release_handler.erl
@@ -791,7 +791,7 @@ check_rel(Root, RelFile, Masters) ->
check_rel(Root, RelFile, LibDirs, Masters) ->
case consult(RelFile, Masters) of
{ok, [RelData]} ->
- check_rel_data(RelData, Root, LibDirs);
+ check_rel_data(RelData, Root, LibDirs, Masters);
{ok, _} ->
throw({error, {bad_rel_file, RelFile}});
{error, Reason} when is_tuple(Reason) ->
@@ -800,7 +800,8 @@ check_rel(Root, RelFile, LibDirs, Masters) ->
throw({error, {FileError, RelFile}})
end.
-check_rel_data({release, {Name, Vsn}, {erts, EVsn}, Libs}, Root, LibDirs) ->
+check_rel_data({release, {Name, Vsn}, {erts, EVsn}, Libs}, Root, LibDirs,
+ Masters) ->
Libs2 =
lists:map(fun(LibSpec) ->
Lib = element(1, LibSpec),
@@ -810,7 +811,7 @@ check_rel_data({release, {Name, Vsn}, {erts, EVsn}, Libs}, Root, LibDirs) ->
case lists:keysearch(Lib, 1, LibDirs) of
{value, {_Lib, _Vsn, Dir}} ->
Path = filename:join(Dir,LibName),
- check_path(Path),
+ check_path(Path, Masters),
Path;
_ ->
filename:join([Root, "lib", LibName])
@@ -820,19 +821,34 @@ check_rel_data({release, {Name, Vsn}, {erts, EVsn}, Libs}, Root, LibDirs) ->
Libs),
#release{name = Name, vsn = Vsn, erts_vsn = EVsn,
libs = Libs2, status = unpacking};
-check_rel_data(RelData, _Root, _LibDirs) ->
+check_rel_data(RelData, _Root, _LibDirs, _Masters) ->
throw({error, {bad_rel_data, RelData}}).
check_path(Path) ->
- case file:read_file_info(Path) of
- {ok, Info} when Info#file_info.type==directory ->
- ok;
- {ok, _Info} ->
- throw({error, {not_a_directory, Path}});
- {error, _Reason} ->
- throw({error, {no_such_directory, Path}})
- end.
-
+ check_path_response(Path, file:read_file_info(Path)).
+check_path(Path, false) -> check_path(Path);
+check_path(Path, Masters) -> check_path_master(Masters, Path).
+
+%%-----------------------------------------------------------------
+%% check_path at any master node.
+%% If the path does not exist or is not a directory
+%% at one node it should not exist at any other node either.
+%%-----------------------------------------------------------------
+check_path_master([Master|Ms], Path) ->
+ case rpc:call(Master, file, read_file_info, [Path]) of
+ {badrpc, _} -> consult_master(Ms, Path);
+ Res -> check_path_response(Path, Res)
+ end;
+check_path_master([], _Path) ->
+ {error, no_master}.
+
+check_path_response(_Path, {ok, Info}) when Info#file_info.type==directory ->
+ ok;
+check_path_response(Path, {ok, _Info}) ->
+ throw({error, {not_a_directory, Path}});
+check_path_response(Path, {error, _Reason}) ->
+ throw({error, {no_such_directory, Path}}).
+
do_check_install_release(RelDir, Vsn, Releases, Masters) ->
case lists:keysearch(Vsn, #release.vsn, Releases) of
{value, #release{status = current}} ->
diff --git a/lib/sasl/src/release_handler_1.erl b/lib/sasl/src/release_handler_1.erl
index 9c0edf4e99..8d050fb7b0 100644
--- a/lib/sasl/src/release_handler_1.erl
+++ b/lib/sasl/src/release_handler_1.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. 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
@@ -20,7 +20,7 @@
%% External exports
-export([eval_script/3, eval_script/4, check_script/2]).
--export([get_vsn/1]). %% exported because used in a test case
+-export([get_current_vsn/1]). %% exported because used in a test case
-record(eval_state, {bins = [], stopped = [], suspended = [], apps = [],
libdirs, unpurged = [], vsns = [], newlibs = [],
@@ -223,7 +223,7 @@ eval({load_object_code, {Lib, LibVsn, Modules}}, EvalState) ->
FName = filename:join(Ebin, File),
case erl_prim_loader:get_file(FName) of
{ok, Bin, FName2} ->
- NVsns = add_new_vsn(Mod, FName2, Vsns),
+ NVsns = add_new_vsn(Mod, Bin, Vsns),
{[{Mod, Bin, FName2} | Bins],NVsns};
error ->
throw({error, {no_such_file,FName}})
@@ -609,17 +609,17 @@ sync_nodes(Id, Nodes) ->
add_old_vsn(Mod, Vsns) ->
case lists:keysearch(Mod, 1, Vsns) of
{value, {Mod, undefined, NewVsn}} ->
- OldVsn = get_vsn(code:which(Mod)),
+ OldVsn = get_current_vsn(Mod),
lists:keyreplace(Mod, 1, Vsns, {Mod, OldVsn, NewVsn});
{value, {Mod, _OldVsn, _NewVsn}} ->
Vsns;
false ->
- OldVsn = get_vsn(code:which(Mod)),
+ OldVsn = get_current_vsn(Mod),
[{Mod, OldVsn, undefined} | Vsns]
end.
-add_new_vsn(Mod, File, Vsns) ->
- NewVsn = get_vsn(File),
+add_new_vsn(Mod, Bin, Vsns) ->
+ NewVsn = get_vsn(Bin),
case lists:keysearch(Mod, 1, Vsns) of
{value, {Mod, OldVsn, undefined}} ->
lists:keyreplace(Mod, 1, Vsns, {Mod, OldVsn, NewVsn});
@@ -627,17 +627,35 @@ add_new_vsn(Mod, File, Vsns) ->
[{Mod, undefined, NewVsn} | Vsns]
end.
-
+%%-----------------------------------------------------------------
+%% Func: get_current_vsn/1
+%% Args: Mod = atom()
+%% Purpose: This function returns the equivalent of
+%% beam_lib:version(code:which(Mod)), but it will also handle the
+%% case when using erl_prim_loader loader different from 'efile'.
+%% The reason for not using the Binary from the 'bins' or the
+%% version directly from the 'vsns' state field is that these are
+%% updated already by load_object_code, and this function is called
+%% from load and remove.
+%% Returns: Vsn = term()
+%%-----------------------------------------------------------------
+get_current_vsn(Mod) ->
+ File = code:which(Mod),
+ case erl_prim_loader:get_file(File) of
+ {ok, Bin, _File2} ->
+ get_vsn(Bin);
+ error ->
+ throw({error, {no_such_file, File}})
+ end.
%%-----------------------------------------------------------------
%% Func: get_vsn/1
-%% Args: File = string()
+%% Args: Bin = binary()
%% Purpose: Finds the version attribute of a module.
-%% Returns: Vsn
-%% Vsn = term()
+%% Returns: Vsn = term()
%%-----------------------------------------------------------------
-get_vsn(File) ->
- {ok, {_Mod, Vsn}} = beam_lib:version(File),
+get_vsn(Bin) ->
+ {ok, {_Mod, Vsn}} = beam_lib:version(Bin),
case misc_supp:is_string(Vsn) of
true ->
Vsn;
diff --git a/lib/sasl/src/systools_rc.erl b/lib/sasl/src/systools_rc.erl
index 23d1a52b66..daadb79967 100644
--- a/lib/sasl/src/systools_rc.erl
+++ b/lib/sasl/src/systools_rc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. 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
@@ -34,7 +34,7 @@
%% {add_module, Mod, [Mod]}
%% {remove_module, Mod, PrePurge, PostPurge, [Mod]}
%% {restart_application, Appl}
-%% {add_application, Appl}
+%% {add_application, Appl, Type}
%% {remove_application, Appl}
%%
%% Low-level
@@ -109,6 +109,8 @@ expand_script([I|Script]) ->
{delete_module, Mod} ->
[{remove, {Mod, brutal_purge, brutal_purge}},
{purge, [Mod]}];
+ {add_application, Application} ->
+ {add_application, Application, permanent};
_ ->
I
end,
@@ -317,14 +319,18 @@ translate_independent_instrs(Before, After, Appls, PreAppls) ->
translate_application_instrs(Script, Appls, PreAppls) ->
%% io:format("Appls ~n~p~n",[Appls]),
L = lists:map(
- fun({add_application, Appl}) ->
+ fun({add_application, Appl, Type}) ->
case lists:keysearch(Appl, #application.name, Appls) of
{value, Application} ->
Mods =
remove_vsn(Application#application.modules),
+ ApplyL = case Type of
+ none -> [];
+ load -> [{apply, {application, load, [Appl]}}];
+ _ -> [{apply, {application, start, [Appl, Type]}}]
+ end,
[{add_module, M, []} || M <- Mods] ++
- [{apply, {application, start,
- [Appl, permanent]}}];
+ ApplyL;
false ->
throw({error, {no_such_application, Appl}})
end;
@@ -750,8 +756,9 @@ check_op({remove_module, Mod, PrePurge, PostPurge, Mods}) ->
lists:foreach(fun(M) -> check_mod(M) end, Mods);
check_op({remove_application, Appl}) ->
check_appl(Appl);
-check_op({add_application, Appl}) ->
- check_appl(Appl);
+check_op({add_application, Appl, Type}) ->
+ check_appl(Appl),
+ check_start_type(Type);
check_op({restart_application, Appl}) ->
check_appl(Appl);
check_op(restart) -> ok;
@@ -839,6 +846,13 @@ check_node(Node) -> throw({error, {bad_node, Node}}).
check_appl(Appl) when is_atom(Appl) -> ok;
check_appl(Appl) -> throw({error, {bad_application, Appl}}).
+check_start_type(none) -> ok;
+check_start_type(load) -> ok;
+check_start_type(temporary) -> ok;
+check_start_type(transient) -> ok;
+check_start_type(permanent) -> ok;
+check_start_type(T) -> throw({error, {bad_start_type, T}}).
+
check_func(Func) when is_atom(Func) -> ok;
check_func(Func) -> throw({error, {bad_func, Func}}).
diff --git a/lib/sasl/src/systools_relup.erl b/lib/sasl/src/systools_relup.erl
index 177d50be80..6b0f77703e 100644
--- a/lib/sasl/src/systools_relup.erl
+++ b/lib/sasl/src/systools_relup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. 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
@@ -370,10 +370,10 @@ collect_appup_scripts(_, [], _, Ws, RUs) -> {RUs, Ws}.
%% ToApps = [#application]
%%
create_add_app_scripts(FromRel, ToRel, RU0s, W0s) ->
- AddedNs = [N || {N, _V, _T} <- ToRel#release.applications,
+ AddedNs = [{N, T} || {N, _V, T} <- ToRel#release.applications,
not lists:keymember(N, 1, FromRel#release.applications)],
%% io:format("Added apps: ~p~n", [AddedNs]),
- RUs = [[{add_application, N}] || N <- AddedNs],
+ RUs = [[{add_application, N, T}] || {N, T} <- AddedNs],
{RUs ++ RU0s, W0s}.