aboutsummaryrefslogtreecommitdiffstats
path: root/lib/sasl/src/systools_make.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sasl/src/systools_make.erl')
-rw-r--r--lib/sasl/src/systools_make.erl169
1 files changed, 116 insertions, 53 deletions
diff --git a/lib/sasl/src/systools_make.erl b/lib/sasl/src/systools_make.erl
index 8fd90c50f9..61e660e918 100644
--- a/lib/sasl/src/systools_make.erl
+++ b/lib/sasl/src/systools_make.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2012. 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
@@ -375,7 +375,7 @@ get_release1(File, Path, ModTestP, Machine) ->
{ok, Release, Warnings1} = read_release(File, Path),
{ok, Appls0} = collect_applications(Release, Path),
{ok, Appls1} = check_applications(Appls0),
- {ok, Appls2} = sort_included_applications(Appls1, Release), % OTP-4121
+ {ok, Appls2} = sort_used_and_incl_appls(Appls1, Release), % OTP-4121, OTP-9984
{ok, Warnings2} = check_modules(Appls2, Path, ModTestP, Machine),
{ok, Appls} = sort_appls(Appls2),
{ok, Release, Appls, Warnings1 ++ Warnings2}.
@@ -463,30 +463,35 @@ check_appl(Appl) ->
end,
Appl) of
[] ->
- {ok,Ws} = mandatory_applications(Appl),
- {split_app_incl(Appl),Ws};
+ {ApplsNoIncls,Incls} = split_app_incl(Appl),
+ {ok,Ws} = mandatory_applications(ApplsNoIncls,undefined,
+ undefined,undefined),
+ {{ApplsNoIncls,Incls},Ws};
Illegal ->
throw({error, {illegal_applications,Illegal}})
end.
-mandatory_applications(Appl) ->
- AppNames = map(fun(AppT) -> element(1, AppT) end,
- Appl),
- Mand = mandatory_applications(),
- case filter(fun(X) -> member(X, AppNames) end, Mand) of
- Mand ->
- case member(sasl,AppNames) of
- true ->
- {ok,[]};
- _ ->
- {ok, [{warning,missing_sasl}]}
- end;
- _ ->
- throw({error, {missing_mandatory_app, Mand}})
- end.
-
-mandatory_applications() ->
- [kernel, stdlib].
+mandatory_applications([{kernel,_,Type}|Apps],undefined,Stdlib,Sasl) ->
+ mandatory_applications(Apps,Type,Stdlib,Sasl);
+mandatory_applications([{stdlib,_,Type}|Apps],Kernel,undefined,Sasl) ->
+ mandatory_applications(Apps,Kernel,Type,Sasl);
+mandatory_applications([{sasl,_,Type}|Apps],Kernel,Stdlib,undefined) ->
+ mandatory_applications(Apps,Kernel,Stdlib,Type);
+mandatory_applications([_|Apps],Kernel,Stdlib,Sasl) ->
+ mandatory_applications(Apps,Kernel,Stdlib,Sasl);
+mandatory_applications([],Type,_,_) when Type=/=permanent ->
+ error_mandatory_application(kernel,Type);
+mandatory_applications([],_,Type,_) when Type=/=permanent ->
+ error_mandatory_application(stdlib,Type);
+mandatory_applications([],_,_,undefined) ->
+ {ok, [{warning,missing_sasl}]};
+mandatory_applications([],_,_,_) ->
+ {ok,[]}.
+
+error_mandatory_application(App,undefined) ->
+ throw({error, {missing_mandatory_app, App}});
+error_mandatory_application(App,Type) ->
+ throw({error, {mandatory_app, App, Type}}).
split_app_incl(Appl) -> split_app_incl(Appl, [], []).
@@ -837,34 +842,45 @@ undefined_applications(Appls) ->
filter(fun(X) -> not member(X, Defined) end, Uses).
%%______________________________________________________________________
-%% sort_included_applications(Applications, Release) -> Applications
+%% sort_used_and_incl_appls(Applications, Release) -> Applications
%% Applications = [{{Name,Vsn},#application}]
%% Release = #release{}
%%
-%% Check that included applications are given in the same order as in
-%% the release resource file (.rel). Otherwise load instructions in
-%% the boot script, and consequently release upgrade instructions in
-%% relup, may end up in the wrong order.
+%% OTP-4121, OTP-9984
+%% Check that used and included applications are given in the same
+%% order as in the release resource file (.rel). Otherwise load and
+%% start instructions in the boot script, and consequently release
+%% upgrade instructions in relup, may end up in the wrong order.
-sort_included_applications(Applications, Release) when is_tuple(Release) ->
+sort_used_and_incl_appls(Applications, Release) when is_tuple(Release) ->
{ok,
- sort_included_applications(Applications, Release#release.applications)};
-
-sort_included_applications([{Tuple,Appl}|Appls], OrderedAppls) ->
- case Appl#application.includes of
- Incls when length(Incls)>1 ->
- IndexedIncls = find_pos(Incls, OrderedAppls),
- SortedIndexedIncls = lists:keysort(1, IndexedIncls),
- Incls2 = lists:map(fun({_Index,Name}) -> Name end,
- SortedIndexedIncls),
- Appl2 = Appl#application{includes=Incls2},
- [{Tuple,Appl2}|sort_included_applications(Appls, OrderedAppls)];
- _Incls ->
- [{Tuple,Appl}|sort_included_applications(Appls, OrderedAppls)]
- end;
-sort_included_applications([], _OrderedAppls) ->
+ sort_used_and_incl_appls(Applications, Release#release.applications)};
+
+sort_used_and_incl_appls([{Tuple,Appl}|Appls], OrderedAppls) ->
+ Incls2 =
+ case Appl#application.includes of
+ Incls when length(Incls)>1 ->
+ sort_appl_list(Incls, OrderedAppls);
+ Incls ->
+ Incls
+ end,
+ Uses2 =
+ case Appl#application.uses of
+ Uses when length(Uses)>1 ->
+ sort_appl_list(Uses, OrderedAppls);
+ Uses ->
+ Uses
+ end,
+ Appl2 = Appl#application{includes=Incls2, uses=Uses2},
+ [{Tuple,Appl2}|sort_used_and_incl_appls(Appls, OrderedAppls)];
+sort_used_and_incl_appls([], _OrderedAppls) ->
[].
+sort_appl_list(List, Order) ->
+ IndexedList = find_pos(List, Order),
+ SortedIndexedList = lists:keysort(1, IndexedList),
+ lists:map(fun({_Index,Name}) -> Name end, SortedIndexedList).
+
find_pos([Name|Incs], OrderedAppls) ->
[find_pos(1, Name, OrderedAppls)|find_pos(Incs, OrderedAppls)];
find_pos([], _OrderedAppls) ->
@@ -1248,7 +1264,8 @@ sort_appls(Appls) -> {ok, sort_appls(Appls, [], [], [])}.
sort_appls([{N, A}|T], Missing, Circular, Visited) ->
{Name,_Vsn} = N,
- {Uses, T1, NotFnd1} = find_all(Name, A#application.uses, T, Visited, [], []),
+ {Uses, T1, NotFnd1} = find_all(Name, lists:reverse(A#application.uses),
+ T, Visited, [], []),
{Incs, T2, NotFnd2} = find_all(Name, lists:reverse(A#application.includes),
T1, Visited, [], []),
Missing1 = NotFnd1 ++ NotFnd2 ++ Missing,
@@ -1451,15 +1468,18 @@ pack_app(#application{name=Name,vsn=V,id=Id,description=D,modules=M,
{applications, App},
{included_applications, Incs},
{env, Env},
- {start_phases, SF},
{maxT, MaxT},
{maxP, MaxP} |
- behave(Mod)]}.
-
+ behave([{start_phases,SF},{mod,Mod}])]}.
+
+behave([{mod,[]}|T]) ->
+ behave(T);
+behave([{start_phases,undefined}|T]) ->
+ behave(T);
+behave([H|T]) ->
+ [H|behave(T)];
behave([]) ->
- [];
-behave(Mod) ->
- [{mod, Mod}].
+ [].
%%______________________________________________________________________
%% mandatory modules; this modules must be loaded before processes
@@ -1677,6 +1697,7 @@ add_system_files(Tar, RelName, Release, Path1) ->
false ->
ignore;
Relup ->
+ check_relup(Relup),
add_to_tar(Tar, Relup, filename:join(RelVsnDir, "relup"))
end,
@@ -1684,6 +1705,7 @@ add_system_files(Tar, RelName, Release, Path1) ->
false ->
ignore;
Sys ->
+ check_sys_config(Sys),
add_to_tar(Tar, Sys, filename:join(RelVsnDir, "sys.config"))
end,
@@ -1700,6 +1722,44 @@ lookup_file(Name, [Dir|Path]) ->
lookup_file(_Name, []) ->
false.
+%% Check that relup can be parsed and has expected format
+check_relup(File) ->
+ case file:consult(File) of
+ {ok,[{Vsn,UpFrom,DownTo}]} when is_list(Vsn), is_integer(hd(Vsn)),
+ is_list(UpFrom), is_list(DownTo) ->
+ ok;
+ {ok,_} ->
+ throw({error,{tar_error,{add,"relup",[invalid_format]}}});
+ Other ->
+ throw({error,{tar_error,{add,"relup",[Other]}}})
+ end.
+
+%% Check that sys.config can be parsed and has expected format
+check_sys_config(File) ->
+ case file:consult(File) of
+ {ok,[SysConfig]} ->
+ case lists:all(fun({App,KeyVals}) when is_atom(App),
+ is_list(KeyVals)->
+ true;
+ (OtherConfig) when is_list(OtherConfig),
+ is_integer(hd(OtherConfig)) ->
+ true;
+ (_) ->
+ false
+ end,
+ SysConfig) of
+ true ->
+ ok;
+ false ->
+ throw({error,{tar_error,
+ {add,"sys.config",[invalid_format]}}})
+ end;
+ {ok,_} ->
+ throw({error,{tar_error,{add,"sys.config",[invalid_format]}}});
+ Other ->
+ throw({error,{tar_error,{add,"sys.config",[Other]}}})
+ end.
+
%%______________________________________________________________________
%% Add either a application located under a variable dir or all other
%% applications to a tar file.
@@ -2187,9 +2247,12 @@ format_error({missing_parameter,Par}) ->
format_error({illegal_applications,Names}) ->
io_lib:format("Illegal applications in the release file: ~p~n",
[Names]);
-format_error({missing_mandatory_app,Names}) ->
- io_lib:format("Mandatory applications (~p) must be specified in the release file~n",
- [Names]);
+format_error({missing_mandatory_app,Name}) ->
+ io_lib:format("Mandatory application ~p must be specified in the release file~n",
+ [Name]);
+format_error({mandatory_app,Name,Type}) ->
+ io_lib:format("Mandatory application ~p must be of type 'permanent' in the release file. Is '~p'.~n",
+ [Name,Type]);
format_error({duplicate_register,Dups}) ->
io_lib:format("Duplicated register names: ~n~s",
[map(fun({{Reg,App1,_,_},{Reg,App2,_,_}}) ->