diff options
Diffstat (limited to 'lib/sasl')
-rw-r--r-- | lib/sasl/doc/src/appup.xml | 14 | ||||
-rw-r--r-- | lib/sasl/doc/src/notes.xml | 20 | ||||
-rw-r--r-- | lib/sasl/doc/src/sasl_app.xml | 183 | ||||
-rw-r--r-- | lib/sasl/src/release_handler.erl | 14 | ||||
-rw-r--r-- | lib/sasl/src/sasl.app.src | 3 | ||||
-rw-r--r-- | lib/sasl/src/sasl.appup.src | 8 | ||||
-rw-r--r-- | lib/sasl/src/sasl.erl | 90 | ||||
-rw-r--r-- | lib/sasl/src/systools_make.erl | 205 | ||||
-rw-r--r-- | lib/sasl/test/sasl_SUITE.erl | 14 | ||||
-rw-r--r-- | lib/sasl/test/sasl_report_SUITE.erl | 18 | ||||
-rw-r--r-- | lib/sasl/test/systools_SUITE.erl | 30 | ||||
-rw-r--r-- | lib/sasl/vsn.mk | 2 |
12 files changed, 379 insertions, 222 deletions
diff --git a/lib/sasl/doc/src/appup.xml b/lib/sasl/doc/src/appup.xml index a43a966dcb..d9d339884f 100644 --- a/lib/sasl/doc/src/appup.xml +++ b/lib/sasl/doc/src/appup.xml @@ -249,9 +249,17 @@ <pre> {restart_application, Application} Application = atom()</pre> - <p>Restarting an application means that the application is - stopped and then started again, similar to using the instructions - <c>remove_application</c> and <c>add_application</c> in sequence.</p> + <p>Restarting an application means that the application is stopped + and then started again, similar to using the instructions + <c>remove_application</c> and <c>add_application</c> in sequence. + Note that, even if the application has been started before the + release upgrade is performed, <c>restart_application</c> may only + <c>load</c> it rather than <c>start</c> it, depending on the + application's <c>start type</c>: + If <c>Type = load</c>, the application is only loaded. + If <c>Type = none</c>, the application is not loaded and not + started, although the code for its modules is loaded. + </p> </section> <section> diff --git a/lib/sasl/doc/src/notes.xml b/lib/sasl/doc/src/notes.xml index e532c3cd6f..791e9c063a 100644 --- a/lib/sasl/doc/src/notes.xml +++ b/lib/sasl/doc/src/notes.xml @@ -31,6 +31,26 @@ </header> <p>This document describes the changes made to the SASL application.</p> +<section><title>SASL 3.1.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + When upgrading with instruction 'restart_new_emulator', + the generated temporary boot file used 'kernelProcess' + statements from the old release instead of the new + release. This is now corrected.</p> + <p> + This correction is needed for upgrade to OTP-21.</p> + <p> + Own Id: OTP-15017</p> + </item> + </list> + </section> + +</section> + <section><title>SASL 3.1.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/sasl/doc/src/sasl_app.xml b/lib/sasl/doc/src/sasl_app.xml index e0693fcb60..48b0b8eafb 100644 --- a/lib/sasl/doc/src/sasl_app.xml +++ b/lib/sasl/doc/src/sasl_app.xml @@ -34,12 +34,9 @@ <p>The SASL application provides the following services:</p> <list type="bulleted"> <item><c>alarm_handler</c></item> - <item><c>rb</c></item> <item><c>release_handler</c></item> <item><c>systools</c></item> </list> - <p>The SASL application also includes <c>error_logger</c> event - handlers for formatting SASL error and crash reports.</p> <note> <p>The SASL application in OTP has nothing to do with "Simple Authentication and Security Layer" (RFC 4422).</p> @@ -47,51 +44,109 @@ </description> <section> - <title>Error Logger Event Handlers</title> - <p>The following error logger event handlers are used by - the SASL application.</p> + <title>Configuration</title> + <p>The following configuration parameters are defined for the SASL + application. For more information about configuration parameters, see + <seealso marker="kernel:app"><c>app(4)</c></seealso> in Kernel.</p> + <p>All configuration parameters are optional.</p> + <taglist> + <tag><c><![CDATA[start_prg = string() ]]></c></tag> + <item> + <p>Specifies the program to be used when restarting the system + during release installation. Default is + <c>$OTP_ROOT/bin/start</c>.</p> + </item> + <tag><c><![CDATA[masters = [atom()] ]]></c></tag> + <item> + <p>Specifies the nodes used by this node to read/write release + information. This parameter is ignored if parameter + <c>client_directory</c> is not set.</p> + </item> + <tag><c><![CDATA[client_directory = string() ]]></c></tag> + <item> + <p>This parameter specifies the client directory at the master + nodes. For details, see + <seealso marker="doc/design_principles:release_handling">Release Handling</seealso> + in <em>OTP Design Principles</em>. This parameter is + ignored if parameter <c>masters</c> is not set.</p> + </item> + <tag><c><![CDATA[static_emulator = true | false ]]></c></tag> + <item> + <p>Indicates if the Erlang emulator is statically installed. A + node with a static emulator cannot switch dynamically to a + new emulator, as the executable files are written into memory + statically. This parameter is ignored if parameters <c>masters</c> + and <c>client_directory</c> are not set.</p> + </item> + <tag><c><![CDATA[releases_dir = string() ]]></c></tag> + <item> + <p>Indicates where the <c>releases</c> directory is located. + The release handler writes all its files to this directory. + If this parameter is not set, the OS environment parameter + <c>RELDIR</c> is used. By default, this is + <c>$OTP_ROOT/releases</c>.</p> + </item> + <tag><c><![CDATA[utc_log = true | false ]]></c></tag> + <item> + <p>If set to <c>true</c>, all dates in textual log outputs are + displayed in Universal Coordinated Time with the string + <c>UTC</c> appended.</p> + </item> + </taglist> + </section> + + <section> + <title>Deprecated Error Logger Event Handlers and Configuration</title> + <p>In OTP-21, a new API for logging was added to Erlang/OTP. The + old <c>error_logger</c> event manager, and event handlers + running on this manager, will still work, but they are not used + by default.</p> + <p>The error logger event handlers <c>sasl_report_tty_h</c> + and <c>sasl_report_file_h</c>, were earliger used for printing + the so called SASL reports, i.e. <em>supervisor + reports</em>, <em>crash reports</em>, and <em>progress + reports</em>. These reports are now also printed by the standard + logger handler started by the Kernel application. Progress + reports are by default stopped by a filter, but can easily be + added by setting the Kernel configuration + parameter <seealso marker="kernel:kernel_app#logger_log_progress"><c>logger_log_progress=true</c></seealso>.</p> + <p>If the old error logger event handlers are still desired, they + must be added by + calling <c>error_logger:add_report_handler/1,2</c>.</p> <taglist> <tag><c>sasl_report_tty_h</c></tag> <item> <p>Formats and writes <em>supervisor reports</em>, <em>crash reports</em>, and <em>progress reports</em> to <c>stdio</c>. This error logger event handler uses - <seealso marker="kernel:kernel_app#error_logger_format_depth">error_logger_format_depth</seealso> - in the Kernel application to limit how much detail is - printed in crash and supervisor reports.</p> + <seealso marker="kernel:kernel_app#logger_format_depth"><c>logger_format_depth</c></seealso> + in the Kernel application to limit how much detail is printed + in crash and supervisor reports. If <c>logger_format_depth</c> + is not set, it uses the old <c>error_logger_format_depth</c> + instead.</p> </item> <tag><c>sasl_report_file_h</c></tag> <item> <p>Formats and writes <em>supervisor reports</em>, <em>crash report</em>, and <em>progress report</em> to a single file. This error logger event handler uses - <seealso marker="kernel:kernel_app#error_logger_format_depth">error_logger_format_depth</seealso> - in the Kernel application to limit the details - printed in crash and supervisor reports.</p> - </item> - <tag><c>log_mf_h</c></tag> - <item> - <p>This error logger writes <em>all</em> events sent to the - error logger to disk. Multiple files and log rotation are - used. For efficiency reasons, each event is written as a - binary. For more information about this handler, - see <seealso marker="stdlib:log_mf_h">the STDLIB Reference - Manual</seealso>.</p> - <p>To activate this event handler, three SASL - configuration parameters must be set, - <c>error_logger_mf_dir</c>, <c>error_logger_mf_maxbytes</c>, - and <c>error_logger_mf_maxfiles</c>. The next section provides - more information about the configuration parameters.</p> + <seealso marker="kernel:kernel_app#logger_format_depth"><c>logger_format_depth</c></seealso> + in the Kernel application to limit the details printed in + crash and supervisor reports. If <c>logger_format_depth</c> is + not set, it uses the old <c>error_logger_format_depth</c> + instead.</p> </item> </taglist> - </section> - - <section> - <title>Configuration</title> - <p>The following configuration parameters are defined for the SASL - application. For more information about configuration parameters, see - <seealso marker="kernel:app"><c>app(4)</c></seealso> in Kernel.</p> - <p>All configuration parameters are optional.</p> + <p>A similar behaviour, but still using the new logger API, can be + obtained by setting the Kernel application environment + variable <seealso marker="kernel:kernel_app#logger_sasl_compatible"><c>logger_sasl_compatible=true</c></seealso>. This will add a + second instance of the standard logger handler + named <c>sasl_h</c>, which will only print the SASL reports. No + SASL reports will then be printed by the Kernel logger + handler.</p> + <p>The <c>sasl_h</c> handler will be configured according to the + values of the following SASL application environment + variables.</p> <taglist> <tag><c><![CDATA[sasl_error_logger = Value ]]></c></tag> <item> @@ -124,6 +179,19 @@ <c>sasl_error_logger</c> to error reports or progress reports, or both. Default is <c>all</c>.</p> </item> + </taglist> + + <p>The error logger event handler <c>log_mf_h</c> can also still + be used. This event handler writes <em>all</em> events sent to + the error logger to disk. Multiple files and log rotation are + used. For efficiency reasons, each event is written as a + binary. For more information about this handler, + see <seealso marker="stdlib:log_mf_h">the STDLIB Reference + Manual</seealso>.</p> + <p>To activate this event handler, three SASL configuration + parameters must be + set:</p> + <taglist> <tag><c><![CDATA[error_logger_mf_dir = string() | false ]]></c></tag> <item> <p>Specifies in which directory <c>log_mf_h</c> is to store @@ -142,49 +210,12 @@ this parameter is undefined, the <c>log_mf_h</c> handler is not installed.</p> </item> - <tag><c><![CDATA[start_prg = string() ]]></c></tag> - <item> - <p>Specifies the program to be used when restarting the system - during release installation. Default is - <c>$OTP_ROOT/bin/start</c>.</p> - </item> - <tag><c><![CDATA[masters = [atom()] ]]></c></tag> - <item> - <p>Specifies the nodes used by this node to read/write release - information. This parameter is ignored if parameter - <c>client_directory</c> is not set.</p> - </item> - <tag><c><![CDATA[client_directory = string() ]]></c></tag> - <item> - <p>This parameter specifies the client directory at the master - nodes. For details, see - <seealso marker="doc/design_principles:release_handling">Release Handling</seealso> - in <em>OTP Design Principles</em>. This parameter is - ignored if parameter <c>masters</c> is not set.</p> - </item> - <tag><c><![CDATA[static_emulator = true | false ]]></c></tag> - <item> - <p>Indicates if the Erlang emulator is statically installed. A - node with a static emulator cannot switch dynamically to a - new emulator, as the executable files are written into memory - statically. This parameter is ignored if parameters <c>masters</c> - and <c>client_directory</c> are not set.</p> - </item> - <tag><c><![CDATA[releases_dir = string() ]]></c></tag> - <item> - <p>Indicates where the <c>releases</c> directory is located. - The release handler writes all its files to this directory. - If this parameter is not set, the OS environment parameter - <c>RELDIR</c> is used. By default, this is - <c>$OTP_ROOT/releases</c>.</p> - </item> - <tag><c><![CDATA[utc_log = true | false ]]></c></tag> - <item> - <p>If set to <c>true</c>, all dates in textual log outputs are - displayed in Universal Coordinated Time with the string - <c>UTC</c> appended.</p> - </item> </taglist> + <p>The new <seealso marker="kernel:logger_disk_log_h"> + <c>logger_disk_log_h</c></seealso> might be an alternative + to <c>log_mf_h</c> if log rotation is desired. This does, + however, write the log events in clear text and not as binaries.</p> + </section> <section> diff --git a/lib/sasl/src/release_handler.erl b/lib/sasl/src/release_handler.erl index bfa49fc05d..4fd3fc0d36 100644 --- a/lib/sasl/src/release_handler.erl +++ b/lib/sasl/src/release_handler.erl @@ -1052,8 +1052,8 @@ new_emulator_make_tmp_release(CurrentRelease,ToRelease,RelDir,Opts,Masters) -> ToVsn = ToRelease#release.vsn, TmpVsn = ?tmp_vsn(CurrentVsn), case get_base_libs(ToRelease#release.libs) of - {ok,{Kernel,Stdlib,Sasl}=BaseLibs,_} -> - case get_base_libs(ToRelease#release.libs) of + {ok,{Kernel,Stdlib,Sasl},_} -> + case get_base_libs(CurrentRelease#release.libs) of {ok,_,RestLibs} -> TmpErtsVsn = ToRelease#release.erts_vsn, TmpLibs = [Kernel,Stdlib,Sasl|RestLibs], @@ -1062,7 +1062,7 @@ new_emulator_make_tmp_release(CurrentRelease,ToRelease,RelDir,Opts,Masters) -> libs = TmpLibs, status = unpacked}, new_emulator_make_hybrid_boot(CurrentVsn,ToVsn,TmpVsn, - BaseLibs,RelDir,Opts,Masters), + RelDir,Opts,Masters), new_emulator_make_hybrid_config(CurrentVsn,ToVsn,TmpVsn, RelDir,Masters), {TmpVsn,TmpRelease}; @@ -1095,7 +1095,7 @@ get_base_libs([],_Kernel,_Stdlib,undefined,_Rest) -> get_base_libs([],Kernel,Stdlib,Sasl,Rest) -> {ok,{Kernel,Stdlib,Sasl},lists:reverse(Rest)}. -new_emulator_make_hybrid_boot(CurrentVsn,ToVsn,TmpVsn,BaseLibs,RelDir,Opts,Masters) -> +new_emulator_make_hybrid_boot(CurrentVsn,ToVsn,TmpVsn,RelDir,Opts,Masters) -> FromBootFile = filename:join([RelDir,CurrentVsn,"start.boot"]), ToBootFile = filename:join([RelDir,ToVsn,"start.boot"]), TmpBootFile = filename:join([RelDir,TmpVsn,"start.boot"]), @@ -1103,11 +1103,7 @@ new_emulator_make_hybrid_boot(CurrentVsn,ToVsn,TmpVsn,BaseLibs,RelDir,Opts,Maste Args = [ToVsn,Opts], {ok,FromBoot} = read_file(FromBootFile,Masters), {ok,ToBoot} = read_file(ToBootFile,Masters), - {{_,_,KernelPath},{_,_,StdlibPath},{_,_,SaslPath}} = BaseLibs, - Paths = {filename:join(KernelPath,"ebin"), - filename:join(StdlibPath,"ebin"), - filename:join(SaslPath,"ebin")}, - case systools_make:make_hybrid_boot(TmpVsn,FromBoot,ToBoot,Paths,Args) of + case systools_make:make_hybrid_boot(TmpVsn,FromBoot,ToBoot,Args) of {ok,TmpBoot} -> write_file(TmpBootFile,TmpBoot,Masters); {error,Reason} -> diff --git a/lib/sasl/src/sasl.app.src b/lib/sasl/src/sasl.app.src index 1e8e58a978..60d08ffa54 100644 --- a/lib/sasl/src/sasl.app.src +++ b/lib/sasl/src/sasl.app.src @@ -40,8 +40,7 @@ ]}, {registered, [sasl_sup, alarm_handler, release_handler]}, {applications, [kernel, stdlib]}, - {env, [{sasl_error_logger, tty}, - {errlog_type, all}]}, + {env, []}, {mod, {sasl, []}}, {runtime_dependencies, ["tools-2.6.14","stdlib-3.4","kernel-5.3", "erts-9.0"]}]}. diff --git a/lib/sasl/src/sasl.appup.src b/lib/sasl/src/sasl.appup.src index 94af164b20..221427874c 100644 --- a/lib/sasl/src/sasl.appup.src +++ b/lib/sasl/src/sasl.appup.src @@ -18,7 +18,11 @@ %% %CopyrightEnd% {"%VSN%", %% Up from - max one major revision back - [{<<"3\\.0\\.4(\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-20.* + [{<<"3\\.0\\.4(\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-20.0 + {<<"3\\.1(\\.[0-2]+)*">>,[restart_new_emulator]}, % OTP-20.1+ + {<<"3\\.1(\\.[3-9]+)*">>,[restart_new_emulator]}], % OTP-21 %% Down to - max one major revision back - [{<<"3\\.0\\.4(\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-20.* + [{<<"3\\.0\\.4(\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-20.* + {<<"3\\.1(\\.[0-2]+)*">>,[restart_new_emulator]}, % OTP-20.1+ + {<<"3\\.1(\\.[3-9]+)*">>,[restart_new_emulator]}] % OTP-21 }. diff --git a/lib/sasl/src/sasl.erl b/lib/sasl/src/sasl.erl index 24afaee183..657eb6688a 100644 --- a/lib/sasl/src/sasl.erl +++ b/lib/sasl/src/sasl.erl @@ -31,45 +31,52 @@ %%%----------------------------------------------------------------- -behaviour(application). --record(state, {sasl_error_logger, error_logger_mf}). +-record(state, {sasl_logger, error_logger_mf}). start(_, []) -> - Handler = get_sasl_error_logger(), - Type = get_sasl_error_logger_type(), + {Dest,Level} = get_logger_info(), Mf = get_error_logger_mf(), - add_sasl_error_logger(Handler, Type), + add_sasl_logger(Dest, Level), add_error_logger_mf(Mf), - State = #state{sasl_error_logger = Handler, error_logger_mf = Mf}, + State = #state{sasl_logger = Dest, error_logger_mf = Mf}, case supervisor:start_link({local, sasl_sup}, sasl, []) of {ok, Pid} -> {ok, Pid, State}; Error -> Error end. stop(State) -> - delete_sasl_error_logger(State#state.sasl_error_logger), + delete_sasl_logger(State#state.sasl_logger), delete_error_logger_mf(State#state.error_logger_mf). %%----------------------------------------------------------------- %% Internal functions %%----------------------------------------------------------------- -get_sasl_error_logger() -> +get_logger_info() -> + case application:get_env(kernel, logger_sasl_compatible) of + {ok,true} -> + {get_logger_dest(),get_logger_level()}; + _ -> + {std,undefined} + end. + +get_logger_dest() -> case application:get_env(sasl, sasl_error_logger) of - {ok, false} -> undefined; - {ok, tty} -> tty; - {ok, {file, File}} when is_list(File) -> {file, File, [write]}; - {ok, {file, File, Modes}} when is_list(File), is_list(Modes) -> - {file, File, Modes}; - {ok, Bad} -> exit({bad_config, {sasl, {sasl_error_logger, Bad}}}); - _ -> undefined + {ok, false} -> undefined; + {ok, tty} -> standard_io; + {ok, {file, File}} when is_list(File) -> {file, File}; + {ok, {file, File, Modes}} when is_list(File), is_list(Modes) -> + {file, File, Modes}; + {ok, Bad} -> exit({bad_config, {sasl, {sasl_logger_dest, Bad}}}); + undefined -> standard_io end. -get_sasl_error_logger_type() -> +get_logger_level() -> case application:get_env(sasl, errlog_type) of - {ok, error} -> error; - {ok, progress} -> progress; - {ok, all} -> all; - {ok, Bad} -> exit({bad_config, {sasl, {errlog_type, Bad}}}); - _ -> all + {ok, error} -> error; + {ok, progress} -> info; + {ok, all} -> info; + {ok, Bad} -> exit({bad_config, {sasl, {errlog_type, Bad}}}); + _ -> info end. get_error_logger_mf() -> @@ -119,23 +126,32 @@ get_mf_maxf() -> {ok, Bad} -> exit({bad_config, {sasl, {error_logger_mf_maxfiles, Bad}}}) end. -add_sasl_error_logger(undefined, _Type) -> ok; -add_sasl_error_logger(Handler, Type) -> - error_logger:add_report_handler(mod(Handler), args(Handler, Type)). - -delete_sasl_error_logger(undefined) -> ok; -delete_sasl_error_logger(Type) -> - error_logger:delete_report_handler(mod(Type)). - -mod(tty) -> sasl_report_tty_h; -mod({file, _File, _Modes}) -> sasl_report_file_h. - -args({file, File, Modes}, Type) -> {File, Modes, type(Type)}; -args(_, Type) -> type(Type). - -type(error) -> error; -type(progress) -> progress; -type(_) -> all. +add_sasl_logger(undefined, _Level) -> ok; +add_sasl_logger(std, undefined) -> ok; +add_sasl_logger(Dest, Level) -> + FC0 = #{legacy_header=>true, + template=>[{logger_formatter,header},"\n",msg,"\n"]}, + FC = case application:get_env(sasl,utc_log) of + {ok,Bool} when is_boolean(Bool) -> + FC0#{utc=>Bool}; + _ -> + FC0 + end, + ok = logger:add_handler(sasl_h,logger_std_h, + #{level=>Level, + filter_default=>stop, + filters=> + [{sasl_domain, + {fun logger_filters:domain/2, + {log,equals,[beam,erlang,otp,sasl]}}}], + logger_std_h=>#{type=>Dest}, + formatter=>{logger_formatter,FC}}). + +delete_sasl_logger(undefined) -> ok; +delete_sasl_logger(std) -> ok; +delete_sasl_logger(_Type) -> + _ = logger:remove_handler(sasl_h), + ok. add_error_logger_mf(undefined) -> ok; add_error_logger_mf({Dir, MaxB, MaxF}) -> diff --git a/lib/sasl/src/systools_make.erl b/lib/sasl/src/systools_make.erl index fa3182cc08..f4b1b54fd1 100644 --- a/lib/sasl/src/systools_make.erl +++ b/lib/sasl/src/systools_make.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2017. All Rights Reserved. +%% Copyright Ericsson AB 1996-2018. 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. @@ -32,7 +32,7 @@ -export([read_application/4]). --export([make_hybrid_boot/5]). +-export([make_hybrid_boot/4]). -import(lists, [filter/2, keysort/2, keysearch/3, map/2, reverse/1, append/1, foldl/3, member/2, foreach/2]). @@ -178,94 +178,153 @@ return({error,Mod,Error},_,Flags) -> %% and sasl. %% %% TmpVsn = string(), -%% Paths = {KernelPath,StdlibPath,SaslPath} %% Returns {ok,Boot} | {error,Reason} %% Boot1 = Boot2 = Boot = binary() %% Reason = {app_not_found,App} | {app_not_replaced,App} -%% App = kernel | stdlib | sasl -make_hybrid_boot(TmpVsn, Boot1, Boot2, Paths, Args) -> - catch do_make_hybrid_boot(TmpVsn, Boot1, Boot2, Paths, Args). -do_make_hybrid_boot(TmpVsn, Boot1, Boot2, Paths, Args) -> - {script,{_RelName1,_RelVsn1},Script1} = binary_to_term(Boot1), - {script,{RelName2,_RelVsn2},Script2} = binary_to_term(Boot2), - MatchPaths = get_regexp_path(Paths), - NewScript1 = replace_paths(Script1,MatchPaths), - {Kernel,Stdlib,Sasl} = get_apps(Script2,undefined,undefined,undefined), - NewScript2 = replace_apps(NewScript1,Kernel,Stdlib,Sasl), - NewScript3 = add_apply_upgrade(NewScript2,Args), - Boot = term_to_binary({script,{RelName2,TmpVsn},NewScript3}), +%% App = stdlib | sasl +make_hybrid_boot(TmpVsn, Boot1, Boot2, Args) -> + catch do_make_hybrid_boot(TmpVsn, Boot1, Boot2, Args). +do_make_hybrid_boot(TmpVsn, OldBoot, NewBoot, Args) -> + {script,{_RelName1,_RelVsn1},OldScript} = binary_to_term(OldBoot), + {script,{NewRelName,_RelVsn2},NewScript} = binary_to_term(NewBoot), + + %% Everyting upto kernel_load_completed must come from the new script + Fun1 = fun({progress,kernel_load_completed}) -> false; + (_) -> true + end, + {_OldKernelLoad,OldRest1} = lists:splitwith(Fun1,OldScript), + {NewKernelLoad,NewRest1} = lists:splitwith(Fun1,NewScript), + + Fun2 = fun({progress,modules_loaded}) -> false; + (_) -> true + end, + {OldModLoad,OldRest2} = lists:splitwith(Fun2,OldRest1), + {NewModLoad,NewRest2} = lists:splitwith(Fun2,NewRest1), + + Fun3 = fun({kernelProcess,_,_}) -> false; + (_) -> true + end, + {OldPaths,OldRest3} = lists:splitwith(Fun3,OldRest2), + {NewPaths,NewRest3} = lists:splitwith(Fun3,NewRest2), + + Fun4 = fun({progress,init_kernel_started}) -> false; + (_) -> true + end, + {_OldKernelProcs,OldApps} = lists:splitwith(Fun4,OldRest3), + {NewKernelProcs,NewApps} = lists:splitwith(Fun4,NewRest3), + + %% Then comes all module load, which for each app consist of: + %% {path,[AppPath]}, + %% {primLoad,ModuleList} + %% Replace kernel, stdlib and sasl here + MatchPaths = get_regexp_path(), + ModLoad = replace_module_load(OldModLoad,NewModLoad,MatchPaths), + Paths = replace_paths(OldPaths,NewPaths,MatchPaths), + + {Stdlib,Sasl} = get_apps(NewApps,undefined,undefined), + Apps0 = replace_apps(OldApps,Stdlib,Sasl), + Apps = add_apply_upgrade(Apps0,Args), + + Script = NewKernelLoad++ModLoad++Paths++NewKernelProcs++Apps, + Boot = term_to_binary({script,{NewRelName,TmpVsn},Script}), {ok,Boot}. %% For each app, compile a regexp that can be used for finding its path -get_regexp_path({KernelPath,StdlibPath,SaslPath}) -> +get_regexp_path() -> {ok,KernelMP} = re:compile("kernel-[0-9\.]+",[unicode]), {ok,StdlibMP} = re:compile("stdlib-[0-9\.]+",[unicode]), {ok,SaslMP} = re:compile("sasl-[0-9\.]+",[unicode]), - [{KernelMP,KernelPath},{StdlibMP,StdlibPath},{SaslMP,SaslPath}]. - -%% For each path in the script, check if it matches any of the MPs -%% found above, and if so replace it with the correct new path. -replace_paths([{path,Path}|Script],MatchPaths) -> - [{path,replace_path(Path,MatchPaths)}|replace_paths(Script,MatchPaths)]; -replace_paths([Stuff|Script],MatchPaths) -> - [Stuff|replace_paths(Script,MatchPaths)]; -replace_paths([],_) -> + [KernelMP,StdlibMP,SaslMP]. + +replace_module_load(Old,New,[MP|MatchPaths]) -> + replace_module_load(do_replace_module_load(Old,New,MP),New,MatchPaths); +replace_module_load(Script,_,[]) -> + Script. + +do_replace_module_load([{path,[OldAppPath]},{primLoad,OldMods}|OldRest],New,MP) -> + case re:run(OldAppPath,MP,[{capture,none}]) of + nomatch -> + [{path,[OldAppPath]},{primLoad,OldMods}| + do_replace_module_load(OldRest,New,MP)]; + match -> + get_module_load(New,MP) ++ OldRest + end; +do_replace_module_load([Other|Rest],New,MP) -> + [Other|do_replace_module_load(Rest,New,MP)]; +do_replace_module_load([],_,_) -> + []. + +get_module_load([{path,[AppPath]},{primLoad,Mods}|Rest],MP) -> + case re:run(AppPath,MP,[{capture,none}]) of + nomatch -> + get_module_load(Rest,MP); + match -> + [{path,[AppPath]},{primLoad,Mods}] + end; +get_module_load([_|Rest],MP) -> + get_module_load(Rest,MP); +get_module_load([],_) -> []. -replace_path([Path|Paths],MatchPaths) -> - [do_replace_path(Path,MatchPaths)|replace_path(Paths,MatchPaths)]; -replace_path([],_) -> +replace_paths([{path,OldPaths}|Old],New,MatchPaths) -> + {path,NewPath} = lists:keyfind(path,1,New), + [{path,do_replace_paths(OldPaths,NewPath,MatchPaths)}|Old]; +replace_paths([Other|Old],New,MatchPaths) -> + [Other|replace_paths(Old,New,MatchPaths)]. + +do_replace_paths(Old,New,[MP|MatchPaths]) -> + do_replace_paths(do_replace_paths1(Old,New,MP),New,MatchPaths); +do_replace_paths(Paths,_,[]) -> + Paths. + +do_replace_paths1([P|Ps],New,MP) -> + case re:run(P,MP,[{capture,none}]) of + nomatch -> + [P|do_replace_paths1(Ps,New,MP)]; + match -> + get_path(New,MP) ++ Ps + end; +do_replace_paths1([],_,_) -> []. -do_replace_path(Path,[{MP,ReplacePath}|MatchPaths]) -> - case re:run(Path,MP,[{capture,none}]) of - nomatch -> do_replace_path(Path,MatchPaths); - match -> ReplacePath +get_path([P|Ps],MP) -> + case re:run(P,MP,[{capture,none}]) of + nomatch -> + get_path(Ps,MP); + match -> + [P] end; -do_replace_path(Path,[]) -> - Path. - -%% Return the entries for loading the three base applications -get_apps([{kernelProcess,application_controller, - {application_controller,start,[{application,kernel,_}]}}=Kernel| - Script],_,Stdlib,Sasl) -> - get_apps(Script,Kernel,Stdlib,Sasl); +get_path([],_) -> + []. + + +%% Return the entries for loading stdlib and sasl get_apps([{apply,{application,load,[{application,stdlib,_}]}}=Stdlib|Script], - Kernel,_,Sasl) -> - get_apps(Script,Kernel,Stdlib,Sasl); + _,Sasl) -> + get_apps(Script,Stdlib,Sasl); get_apps([{apply,{application,load,[{application,sasl,_}]}}=Sasl|_Script], - Kernel,Stdlib,_) -> - {Kernel,Stdlib,Sasl}; -get_apps([_|Script],Kernel,Stdlib,Sasl) -> - get_apps(Script,Kernel,Stdlib,Sasl); -get_apps([],undefined,_,_) -> - throw({error,{app_not_found,kernel}}); -get_apps([],_,undefined,_) -> + Stdlib,_) -> + {Stdlib,Sasl}; +get_apps([_|Script],Stdlib,Sasl) -> + get_apps(Script,Stdlib,Sasl); +get_apps([],undefined,_) -> throw({error,{app_not_found,stdlib}}); -get_apps([],_,_,undefined) -> +get_apps([],_,undefined) -> throw({error,{app_not_found,sasl}}). - -%% Replace the entries for loading the base applications -replace_apps([{kernelProcess,application_controller, - {application_controller,start,[{application,kernel,_}]}}| - Script],Kernel,Stdlib,Sasl) -> - [Kernel|replace_apps(Script,undefined,Stdlib,Sasl)]; +%% Replace the entries for loading the stdlib and sasl replace_apps([{apply,{application,load,[{application,stdlib,_}]}}|Script], - Kernel,Stdlib,Sasl) -> - [Stdlib|replace_apps(Script,Kernel,undefined,Sasl)]; + Stdlib,Sasl) -> + [Stdlib|replace_apps(Script,undefined,Sasl)]; replace_apps([{apply,{application,load,[{application,sasl,_}]}}|Script], - _Kernel,_Stdlib,Sasl) -> + _Stdlib,Sasl) -> [Sasl|Script]; -replace_apps([Stuff|Script],Kernel,Stdlib,Sasl) -> - [Stuff|replace_apps(Script,Kernel,Stdlib,Sasl)]; -replace_apps([],undefined,undefined,_) -> +replace_apps([Stuff|Script],Stdlib,Sasl) -> + [Stuff|replace_apps(Script,Stdlib,Sasl)]; +replace_apps([],undefined,_) -> throw({error,{app_not_replaced,sasl}}); -replace_apps([],undefined,_,_) -> - throw({error,{app_not_replaced,stdlib}}); -replace_apps([],_,_,_) -> - throw({error,{app_not_replaced,kernel}}). - +replace_apps([],_,_) -> + throw({error,{app_not_replaced,stdlib}}). %% Finally add an apply of release_handler:new_emulator_upgrade - which will %% complete the execution of the upgrade script (relup). @@ -275,8 +334,6 @@ add_apply_upgrade(Script,Args) -> {apply,{release_handler,new_emulator_upgrade,Args}} | RevScript]). - - %%----------------------------------------------------------------- %% Create a release package from a release file. %% Options is a list of {path, Path} | silent | @@ -1489,6 +1546,12 @@ mandatory_modules() -> gen_server, heart, kernel, + logger, + logger_filters, + logger_server, + logger_backend, + logger_config, + logger_simple, lists, proc_lib, supervisor @@ -1500,7 +1563,7 @@ mandatory_modules() -> preloaded() -> %% Sorted [erl_prim_loader,erl_tracer,erlang, - erts_code_purger,erts_dirty_process_code_checker, + erts_code_purger,erts_dirty_process_signal_handler, erts_internal,erts_literal_area_collector, init,otp_ring0,prim_buffer,prim_eval,prim_file, prim_inet,prim_zip,zlib]. @@ -1513,7 +1576,7 @@ preloaded() -> kernel_processes() -> [{heart, heart, start, []}, - {error_logger, error_logger, start_link, []}, + {logger, logger_server, start_link, []}, {application_controller, application_controller, start, fun(Appls) -> [{_,App}] = filter(fun({{kernel,_},_App}) -> true; diff --git a/lib/sasl/test/sasl_SUITE.erl b/lib/sasl/test/sasl_SUITE.erl index f12bde9b3d..7b63684c53 100644 --- a/lib/sasl/test/sasl_SUITE.erl +++ b/lib/sasl/test/sasl_SUITE.erl @@ -21,6 +21,7 @@ -include_lib("common_test/include/ct.hrl"). %% Test server specific exports +-export([init_per_suite/1,end_per_suite/1]). -export([all/0,groups/0,init_per_group/2,end_per_group/2]). -export([init_per_testcase/2, end_per_testcase/2]). @@ -37,6 +38,19 @@ all() -> groups() -> []. +init_per_suite(Config) -> + S = application:get_env(kernel,logger_sasl_compatible), + application:set_env(kernel,logger_sasl_compatible,true), + [{sasl_compatible,S}|Config]. + +end_per_suite(Config) -> + case ?config(sasl_compatible,Config) of + {ok,X} -> + application:set_env(kernel,logger_sasl_compatible,X); + undefined -> + application:unset_env(kernel,logger_sasl_compatible) + end. + init_per_group(_GroupName, Config) -> Config. diff --git a/lib/sasl/test/sasl_report_SUITE.erl b/lib/sasl/test/sasl_report_SUITE.erl index 92df5e6e40..96975aaf69 100644 --- a/lib/sasl/test/sasl_report_SUITE.erl +++ b/lib/sasl/test/sasl_report_SUITE.erl @@ -53,13 +53,17 @@ gen_server_crash_unicode(Config) -> gen_server_crash(Config, unicode). gen_server_crash(Config, Encoding) -> + StopFilter = {fun(_,_) -> stop end, ok}, + logger:add_handler_filter(logger_std_h,stop_all,StopFilter), + logger:add_handler_filter(cth_log_redirect,stop_all,StopFilter), try do_gen_server_crash(Config, Encoding) after - error_logger:tty(true), + ok = application:unset_env(kernel, logger_sasl_compatible), ok = application:unset_env(sasl, sasl_error_logger), ok = application:unset_env(kernel, error_logger_format_depth), - error_logger:add_report_handler(cth_log_redirect) + logger:remove_handler_filter(logger_std_h,stop_all), + logger:remove_handler_filter(cth_log_redirect,stop_all) end, ok. @@ -70,26 +74,26 @@ do_gen_server_crash(Config, Encoding) -> SaslLog = filename:join(LogDir, "sasl.log"), ok = filelib:ensure_dir(SaslLog), - error_logger:delete_report_handler(cth_log_redirect), - error_logger:tty(false), application:stop(sasl), Modes = [write, {encoding, Encoding}], + ok = application:set_env(kernel, logger_sasl_compatible, true), ok = application:set_env(sasl, sasl_error_logger, {file,SaslLog,Modes}, [{persistent,true}]), application:set_env(kernel, error_logger_format_depth, 30), error_logger:logfile({open,KernelLog}), application:start(sasl), - io:format("~p\n", [gen_event:which_handlers(error_logger)]), + logger:i(print), crash_me(), error_logger:logfile(close), + application:stop(sasl), check_file(KernelLog, utf8, 70000, 150000), check_file(SaslLog, Encoding, 70000, 150000), - %% ok = file:delete(KernelLog), - %% ok = file:delete(SaslLog), + ok = file:delete(KernelLog), + ok = file:delete(SaslLog), ok. check_file(File, Encoding, Min, Max) -> diff --git a/lib/sasl/test/systools_SUITE.erl b/lib/sasl/test/systools_SUITE.erl index c8b2f31120..ad61186921 100644 --- a/lib/sasl/test/systools_SUITE.erl +++ b/lib/sasl/test/systools_SUITE.erl @@ -1795,27 +1795,28 @@ normal_hybrid(Config) -> ok = file:set_cwd(OldDir), - BasePaths = {"testkernelpath","teststdlibpath","testsaslpath"}, {ok,Hybrid} = systools_make:make_hybrid_boot("tmp_vsn",Boot1,Boot2, - BasePaths, [dummy,args]), + [dummy,args]), {script,{"Test release","tmp_vsn"},Script} = binary_to_term(Hybrid), ct:log("~p.~n",[Script]), %% Check that all paths to base apps are replaced by paths from BaseLib Boot1Str = io_lib:format("~p~n",[binary_to_term(Boot1)]), + Boot2Str = io_lib:format("~p~n",[binary_to_term(Boot2)]), HybridStr = io_lib:format("~p~n",[binary_to_term(Hybrid)]), ReOpts = [global,{capture,first,list},unicode], {match,OldKernelMatch} = re:run(Boot1Str,"kernel-[0-9\.]+",ReOpts), {match,OldStdlibMatch} = re:run(Boot1Str,"stdlib-[0-9\.]+",ReOpts), {match,OldSaslMatch} = re:run(Boot1Str,"sasl-[0-9\.]+",ReOpts), - nomatch = re:run(HybridStr,"kernel-[0-9\.]+",ReOpts), - nomatch = re:run(HybridStr,"stdlib-[0-9\.]+",ReOpts), - nomatch = re:run(HybridStr,"sasl-[0-9\.]+",ReOpts), - {match,NewKernelMatch} = re:run(HybridStr,"testkernelpath",ReOpts), - {match,NewStdlibMatch} = re:run(HybridStr,"teststdlibpath",ReOpts), - {match,NewSaslMatch} = re:run(HybridStr,"testsaslpath",ReOpts), + {match,NewKernelMatch} = re:run(Boot2Str,"kernel-[0-9\.]+",ReOpts), + {match,NewStdlibMatch} = re:run(Boot2Str,"stdlib-[0-9\.]+",ReOpts), + {match,NewSaslMatch} = re:run(Boot2Str,"sasl-[0-9\.]+",ReOpts), + + {match,NewKernelMatch} = re:run(HybridStr,"kernel-[0-9\.]+",ReOpts), + {match,NewStdlibMatch} = re:run(HybridStr,"stdlib-[0-9\.]+",ReOpts), + {match,NewSaslMatch} = re:run(HybridStr,"sasl-[0-9\.]+",ReOpts), NewKernelN = length(NewKernelMatch), NewKernelN = length(OldKernelMatch), @@ -1824,6 +1825,11 @@ normal_hybrid(Config) -> NewSaslN = length(NewSaslMatch), NewSaslN = length(OldSaslMatch), + %% Check that kernelProcesses are taken from new boot script + {script,_,Script2} = binary_to_term(Boot2), + NewKernelProcs = [KP || KP={kernelProcess,_,_} <- Script2], + NewKernelProcs = [KP || KP={kernelProcess,_,_} <- Script], + %% Check that application load instruction has correct versions Apps = application:loaded_applications(), {_,_,KernelVsn} = lists:keyfind(kernel,1,Apps), @@ -1894,10 +1900,8 @@ hybrid_no_old_sasl(Config) -> {ok,Boot1} = file:read_file(Name1 ++ ".boot"), {ok,Boot2} = file:read_file(Name2 ++ ".boot"), - BasePaths = {"testkernelpath","teststdlibpath","testsaslpath"}, {error,{app_not_replaced,sasl}} = - systools_make:make_hybrid_boot("tmp_vsn",Boot1,Boot2, - BasePaths,[dummy,args]), + systools_make:make_hybrid_boot("tmp_vsn",Boot1,Boot2,[dummy,args]), ok = file:set_cwd(OldDir), ok. @@ -1927,10 +1931,8 @@ hybrid_no_new_sasl(Config) -> {ok,Boot1} = file:read_file(Name1 ++ ".boot"), {ok,Boot2} = file:read_file(Name2 ++ ".boot"), - BasePaths = {"testkernelpath","teststdlibpath","testsaslpath"}, {error,{app_not_found,sasl}} = - systools_make:make_hybrid_boot("tmp_vsn",Boot1,Boot2, - BasePaths,[dummy,args]), + systools_make:make_hybrid_boot("tmp_vsn",Boot1,Boot2,[dummy,args]), ok = file:set_cwd(OldDir), ok. diff --git a/lib/sasl/vsn.mk b/lib/sasl/vsn.mk index 2488197ec5..52b168598a 100644 --- a/lib/sasl/vsn.mk +++ b/lib/sasl/vsn.mk @@ -1 +1 @@ -SASL_VSN = 3.1.1 +SASL_VSN = 3.1.2 |