diff options
Diffstat (limited to 'lib/sasl')
-rw-r--r-- | lib/sasl/doc/src/appup.xml | 14 | ||||
-rw-r--r-- | lib/sasl/doc/src/release_handler.xml | 2 | ||||
-rw-r--r-- | lib/sasl/doc/src/sasl_app.xml | 183 | ||||
-rw-r--r-- | lib/sasl/doc/src/systools.xml | 6 | ||||
-rw-r--r-- | lib/sasl/src/Makefile | 2 | ||||
-rw-r--r-- | lib/sasl/src/erlsrv.erl | 25 | ||||
-rw-r--r-- | lib/sasl/src/format_lib_supp.erl | 6 | ||||
-rw-r--r-- | lib/sasl/src/rb.erl | 6 | ||||
-rw-r--r-- | lib/sasl/src/rb_format_supp.erl | 2 | ||||
-rw-r--r-- | lib/sasl/src/release_handler.erl | 18 | ||||
-rw-r--r-- | lib/sasl/src/sasl.app.src | 5 | ||||
-rw-r--r-- | lib/sasl/src/sasl.appup.src | 12 | ||||
-rw-r--r-- | lib/sasl/src/sasl.erl | 91 | ||||
-rw-r--r-- | lib/sasl/src/si.erl | 169 | ||||
-rw-r--r-- | lib/sasl/src/si_sasl_supp.erl | 380 | ||||
-rw-r--r-- | lib/sasl/src/systools_make.erl | 34 | ||||
-rw-r--r-- | lib/sasl/test/release_handler_SUITE.erl | 90 | ||||
-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 | 37 | ||||
-rw-r--r-- | lib/sasl/test/test_lib.hrl | 4 |
21 files changed, 353 insertions, 765 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/release_handler.xml b/lib/sasl/doc/src/release_handler.xml index 8f073807fb..975188f489 100644 --- a/lib/sasl/doc/src/release_handler.xml +++ b/lib/sasl/doc/src/release_handler.xml @@ -61,6 +61,7 @@ <list type="bulleted"> <item>A release upgrade file, <c>relup</c></item> <item>A system configuration file, <c>sys.config</c></item> + <item>A system configuration source file, <c>sys.config.src</c></item> </list> <p>The <c>relup</c> file contains instructions for how to upgrade to, or downgrade from, this version of the release.</p> @@ -819,4 +820,3 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). <seealso marker="systools"><c>systools(3)</c></seealso></p> </section> </erlref> - 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/doc/src/systools.xml b/lib/sasl/doc/src/systools.xml index e7c3c499da..4842c732b1 100644 --- a/lib/sasl/doc/src/systools.xml +++ b/lib/sasl/doc/src/systools.xml @@ -349,10 +349,11 @@ myapp-1/ebin/myapp.app the release version as specified in <c>Name.rel</c>.</p> <p><c>releases/RelVsn</c> contains the boot script <c>Name.boot</c> renamed to <c>start.boot</c> and, if found, - the files <c>relup</c> and <c>sys.config</c>. These files + the files <c>relup</c> and <c>sys.config</c> or <c>sys.config.src</c>. These files are searched for in the same directory as <c>Name.rel</c>, in the current working directory, and in any directories - specified using option <c>path</c>.</p> + specified using option <c>path</c>. In the case of <c>sys.config</c> + it is not included if <c>sys.config.src</c> is found.</p> <p>If the release package is to contain a new Erlang runtime system, the <c>bin</c> directory of the specified runtime system <c>{erts,Dir}</c> is copied to <c>erts-ErtsVsn/bin</c>.</p> @@ -397,4 +398,3 @@ myapp-1/ebin/myapp.app <seealso marker="script"><c>script(4)</c></seealso></p> </section> </erlref> - diff --git a/lib/sasl/src/Makefile b/lib/sasl/src/Makefile index ac7ee51100..45cd814bf8 100644 --- a/lib/sasl/src/Makefile +++ b/lib/sasl/src/Makefile @@ -37,7 +37,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/sasl-$(VSN) MODULES= alarm_handler sasl sasl_report \ sasl_report_file_h sasl_report_tty_h format_lib_supp \ misc_supp rb rb_format_supp release_handler \ - release_handler_1 si si_sasl_supp systools \ + release_handler_1 systools \ systools_make systools_rc systools_relup systools_lib \ erlsrv diff --git a/lib/sasl/src/erlsrv.erl b/lib/sasl/src/erlsrv.erl index 29d40d362f..e0bbd37ee3 100644 --- a/lib/sasl/src/erlsrv.erl +++ b/lib/sasl/src/erlsrv.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2016. All Rights Reserved. +%% Copyright Ericsson AB 1998-2017. 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. @@ -34,7 +34,7 @@ erlsrv(EVer) -> filename:join([Root, "erts-" ++ EVer, "bin", "erlsrv.exe"]). current_version() -> - hd(string:tokens(erlang:system_info(version),"_ ")). + hd(string:lexemes(erlang:system_info(version),"_ ")). %%% Returns {ok, Output} | failed | {error, Reason} run_erlsrv(Command) -> @@ -107,7 +107,7 @@ get_all_services() -> []; {ok, [_H|T]} -> F = fun(X) -> - hd(string:tokens(X,"\t ")) + hd(string:lexemes(X,"\t ")) end, lists:map(F,T); _ -> @@ -191,8 +191,8 @@ get_service(EVer, ServiceName) -> %%% have in the environment list... EnvParts = lists:map( fun(S) -> - X = string:strip(S,left,$\t), - case hd(string:tokens(X,"=")) of + X = string:trim(S, leading, "$\t"), + case hd(string:lexemes(X,"=")) of X -> %% Can this happen? {X,""}; @@ -371,7 +371,7 @@ split_arglist([H|T]) -> parse_arglist(Str) -> lists:reverse(parse_arglist(Str,[])). parse_arglist(Str,Accum) -> - Stripped = string:strip(Str,left), + Stripped = string:trim(Str, leading), case length(Stripped) of 0 -> Accum; @@ -432,14 +432,9 @@ split_by_env(Data) -> splitline(Line) -> - case string:chr(Line,$:) of - 0 -> + case string:split(Line, ":") of + [_] -> {Line, ""}; - N -> - case length(string:substr(Line,N)) of - 1 -> - {string:substr(Line,1,N-1),""}; - _ -> - {string:substr(Line,1,N-1),string:substr(Line,N+2)} - end + [N, V] -> + {N, string:slice(V, 1)} end. diff --git a/lib/sasl/src/format_lib_supp.erl b/lib/sasl/src/format_lib_supp.erl index 00ce1b4e33..2d37dfe117 100644 --- a/lib/sasl/src/format_lib_supp.erl +++ b/lib/sasl/src/format_lib_supp.erl @@ -102,13 +102,13 @@ print_newlines(Device, N) when N > 0 -> print_one_line(Device, Line, Key, Value) -> Modifier = misc_supp:modifier(Device), StrKey = term_to_string(Key,Modifier), - KeyLen = lists:min([length(StrKey), Line]), + KeyLen = lists:min([string:length(StrKey), Line]), ValueLen = Line - KeyLen, Format1 = lists:concat(["~-", KeyLen, Modifier, "s"]), Format2 = lists:concat(["~", ValueLen, Modifier, "s~n"]), io:format(Device, Format1, [StrKey]), Try = term_to_string(Value,Modifier), - Length = length(Try), + Length = string:length(Try), if Length < ValueLen -> io:format(Device, Format2, [Try]); @@ -119,7 +119,7 @@ print_one_line(Device, Line, Key, Value) -> end. term_to_string(Value,Modifier) -> - lists:flatten(io_lib:format(get_format(Value,Modifier), [Value])). + io_lib:format(get_format(Value,Modifier), [Value]). get_format([],_) -> "~p"; diff --git a/lib/sasl/src/rb.erl b/lib/sasl/src/rb.erl index 6595d29a9c..28829132a1 100644 --- a/lib/sasl/src/rb.erl +++ b/lib/sasl/src/rb.erl @@ -586,14 +586,14 @@ find_widths([], _Modifier, DescrWidth, DateWidth, Data) -> {DescrWidth+1, DateWidth+1, lists:reverse(Data)}; find_widths([H|T], Modifier, DescrWidth, DateWidth, Data) -> DescrTerm = element(3,H), - Descr = lists:flatten(io_lib:format("~"++Modifier++"w", [DescrTerm])), - DescrTry = length(Descr), + Descr = io_lib:format("~"++Modifier++"w", [DescrTerm]), + DescrTry = string:length(Descr), NewDescrWidth = if DescrTry > DescrWidth -> DescrTry; true -> DescrWidth end, - DateTry = length(element(4, H)), + DateTry = string:length(element(4, H)), NewDateWitdh = if DateTry > DateWidth -> DateTry; diff --git a/lib/sasl/src/rb_format_supp.erl b/lib/sasl/src/rb_format_supp.erl index 1eda43dae4..b5b7aba151 100644 --- a/lib/sasl/src/rb_format_supp.erl +++ b/lib/sasl/src/rb_format_supp.erl @@ -108,7 +108,7 @@ print(Date, Report, Device) -> format_h(Line, Header, Pid, Date) -> NHeader = lists:flatten(io_lib:format("~s ~w", [Header, Pid])), - DateLen = length(Date), + DateLen = string:length(Date), HeaderLen = Line - DateLen, Format = lists:concat(["~-", HeaderLen, "s~", DateLen, "s"]), io_lib:format(Format, [NHeader, Date]). diff --git a/lib/sasl/src/release_handler.erl b/lib/sasl/src/release_handler.erl index 49756f5799..4fd3fc0d36 100644 --- a/lib/sasl/src/release_handler.erl +++ b/lib/sasl/src/release_handler.erl @@ -420,7 +420,7 @@ upgrade_app(App, NewDir) -> %% located in the ebin dir of the _current_ version %%----------------------------------------------------------------- downgrade_app(App, OldDir) -> - case string:tokens(filename:basename(OldDir), "-") of + case string:lexemes(filename:basename(OldDir), "-") of [_AppS, OldVsn] -> downgrade_app(App, OldVsn, OldDir); _ -> @@ -1170,8 +1170,8 @@ new_emulator_rm_tmp_release(_,_,_,_,Releases,_) -> %% Rename the tempoarary service (for erts ugprade) to the real ToVsn rename_tmp_service(EVsn,TmpVsn,NewVsn) -> - FromName = hd(string:tokens(atom_to_list(node()),"@")) ++ "_" ++ TmpVsn, - ToName = hd(string:tokens(atom_to_list(node()),"@")) ++ "_" ++ NewVsn, + FromName = hd(string:lexemes(atom_to_list(node()),"@")) ++ "_" ++ TmpVsn, + ToName = hd(string:lexemes(atom_to_list(node()),"@")) ++ "_" ++ NewVsn, case erlsrv:get_service(EVsn,ToName) of {error, _Error} -> ok; @@ -1203,9 +1203,9 @@ rename_service(EVsn,FromName,ToName) -> %%% in which case we try to rename the old service to the new name and try %%% to update heart's view of what service we are really running. do_make_services_permanent(PermanentVsn,Vsn, PermanentEVsn, EVsn) -> - PermName = hd(string:tokens(atom_to_list(node()),"@")) + PermName = hd(string:lexemes(atom_to_list(node()),"@")) ++ "_" ++ PermanentVsn, - Name = hd(string:tokens(atom_to_list(node()),"@")) + Name = hd(string:lexemes(atom_to_list(node()),"@")) ++ "_" ++ Vsn, case erlsrv:get_service(EVsn,Name) of {error, _Error} -> @@ -1292,7 +1292,7 @@ do_make_permanent(#state{releases = Releases, do_back_service(OldVersion, CurrentVersion,OldEVsn,CurrentEVsn) -> - NN = hd(string:tokens(atom_to_list(node()),"@")), + NN = hd(string:lexemes(atom_to_list(node()),"@")), OldName = NN ++ "_" ++ OldVersion, CurrentName = NN ++ "_" ++ CurrentVersion, UpdData = case erlsrv:get_service(CurrentEVsn,CurrentName) of @@ -1381,7 +1381,7 @@ do_remove_service(Vsn) -> %% Very unconditionally remove the service. %% Note that the service could already have been removed when %% making another release permanent. - ServiceName = hd(string:tokens(atom_to_list(node()),"@")) + ServiceName = hd(string:lexemes(atom_to_list(node()),"@")) ++ "_" ++ Vsn, case erlsrv:get_service(ServiceName) of {error, _Error} -> @@ -1666,9 +1666,9 @@ flush() -> prepare_restart_nt(#release{erts_vsn = EVsn, vsn = Vsn}, #release{erts_vsn = PermEVsn, vsn = PermVsn}, DataFileName) -> - CurrentServiceName = hd(string:tokens(atom_to_list(node()),"@")) + CurrentServiceName = hd(string:lexemes(atom_to_list(node()),"@")) ++ "_" ++ PermVsn, - FutureServiceName = hd(string:tokens(atom_to_list(node()),"@")) + FutureServiceName = hd(string:lexemes(atom_to_list(node()),"@")) ++ "_" ++ Vsn, CurrentService = case erlsrv:get_service(PermEVsn,CurrentServiceName) of {error, _} = Error1 -> diff --git a/lib/sasl/src/sasl.app.src b/lib/sasl/src/sasl.app.src index b7bb9133ff..60d08ffa54 100644 --- a/lib/sasl/src/sasl.app.src +++ b/lib/sasl/src/sasl.app.src @@ -32,8 +32,6 @@ sasl_report, sasl_report_tty_h, sasl_report_file_h, - si, - si_sasl_supp, systools, systools_make, systools_rc, @@ -42,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 0cef762bcf..221427874c 100644 --- a/lib/sasl/src/sasl.appup.src +++ b/lib/sasl/src/sasl.appup.src @@ -18,11 +18,11 @@ %% %CopyrightEnd% {"%VSN%", %% Up from - max one major revision back - [{<<"3\\.0((\\.[0-3])(\\.[0-9]+)*)?">>,[restart_new_emulator]}, % OTP-19.* - {<<"3\\.0\\.[4-9](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-20.0* - {<<"3\\.1(\\.[0-2]+)*">>,[restart_new_emulator]}], % OTP-20.[1-3]* + [{<<"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((\\.[0-3])(\\.[0-9]+)*)?">>,[restart_new_emulator]}, % OTP-19.* - {<<"3\\.0\\.[4-9](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-20.0* - {<<"3\\.1(\\.[0-2]+)*">>,[restart_new_emulator]}] % OTP-20.[1-3]* + [{<<"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..2bf11bdcdf 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,33 @@ 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, + single_line=>false, + 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/si.erl b/lib/sasl/src/si.erl deleted file mode 100644 index 275c6d508b..0000000000 --- a/lib/sasl/src/si.erl +++ /dev/null @@ -1,169 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2016. 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% -%% -%%----------------------------------------------------------------- -%% l(format_lib_supp), l(si_sasl_supp), l(si), l(si_ms_aos_supp), l(misc_supp). -%% c(format_lib_supp), c(si_sasl_supp), c(si), c(si_ms_aos_supp), c(misc_supp). -%%----------------------------------------------------------------- - - -%%-------------------------------------------------- -%% Description: -%% Status Inspection, main module. -%%-------------------------------------------------- - --module(si). - - -%% External exports --export([h/0, help/0, start/0, start/1, start_log/1, stop_log/0, - abbrevs/0, pi/1, pi/2, pi/3, pi/4, ppi/1, ppi/3, stop/0]). - -%% Internal exports --export([pi_impl/2, test/0]). - - -%%-------------------------------------------------- -%% Table of contents -%% 1. Interface -%% 2. Implementation - - --import(si_sasl_supp, [status_info/1, make_pid/1, p/1]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% 1. Interface -%%-------------------------------------------------- - -h() -> print_help(). -help() -> print_help(). - -start() -> si_sasl_supp:start(). -start(Options) -> si_sasl_supp:start(Options). - -stop() -> si_sasl_supp:stop(). - -start_log(FileName) -> - si_sasl_supp:start_log(FileName). - -stop_log() -> - si_sasl_supp:stop_log(). - -%%%----------------------------------------------------------------- -%%% All functions can be called with an option 'normal' or 'all'; -%%% default is 'normal'. -%%%----------------------------------------------------------------- - -abbrevs() -> - io:format("~p", [lists:append(si_sasl_supp:process_abbrevs(), - process_abbrevs())]). - -%%----------------------------------------------------------------- -%% Process Info that tries to determine processtype (=Module), then -%% it uses this Module:format_info to format data from status_info/1. -%%----------------------------------------------------------------- -pi(XPid) -> - si_sasl_supp:si_exec({si, pi_impl}, [normal, XPid]). - -pi(Opt, XPid) -> - si_sasl_supp:si_exec({si, pi_impl}, [si_sasl_supp:valid_opt(Opt), XPid]). - -pi(A, B, C) when is_integer(A), is_integer(B), is_integer(C) -> - si_sasl_supp:si_exec({si, pi_impl}, [normal, {A, B, C}]). - -pi(Opt, A, B, C) when is_integer(A), is_integer(B), is_integer(C) -> - si_sasl_supp:si_exec({si, pi_impl}, [si_sasl_supp:valid_opt(Opt), {A, B, C}]). - -%%----------------------------------------------------------------- -%% Pretty print Process_Info. -%%----------------------------------------------------------------- -ppi(XPid) -> - si_sasl_supp:ppi(XPid). -ppi(A, B, C) -> - si_sasl_supp:ppi(A, B, C). - - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% 2. Implementation -%%-------------------------------------------------- - -print_help() -> - p("~nStatus Inspection tool - usage"), - p("=============================="), - p(" For all these functions, Opt is an optional argument"), - p(" which can be 'normal' or 'all'; default is 'normal'."), - p(" If 'all', all information will be printed."), - p(" A Pid can be: \"<A.B.C>\", {A, B, C}, B, a registered_name or an abbrev."), - p("ANY PROCESS"), - p("si:pi([Opt,] Pid) - Formatted information about any process that"), - p(" SI recognises."), - p("si:pi([Opt,] A,B,C) - Same as si:pi({A, B, C})."), - p("si:ppi(Pid) - Pretty formating of process_info."), - p(" Works for any process."), - p("MISC"), - p("si:abbrevs() - Lists valid abbreviations."), - p("si:start_log(Filename) - Logging to file."), - p("si:stop_log()"), - p("si:start() - Starts Status Inspection (the si_server)."), - p("si:start([{start_log, FileName}])"), - p("si:stop() - Shut down SI."). - - -%%-------------------------------------------------- -%% Copied (and modified) code from si_sasl_supp. -%%-------------------------------------------------- -pi_impl(Opt, XPid) -> - case make_pid(try_local_expand_abbrev(XPid)) of - Pid when is_pid(Pid) -> - case status_info(Pid) of - {status_info, Pid, {module, Module}, Data} -> - si_sasl_supp:do_best_printout(Opt, Pid, Module, Data); - {error, Reason} -> - _ = si_sasl_supp:ppi_impl(Pid), - {error, {"can not get status info from process:", - XPid, - Reason}}; - Else -> - {error, {"unknown status info", Else}} - end; - {error, Reason} -> - {error, Reason} - end. - -%%-------------------------------------------------- -%% Functions for handling of abbreviations -%%-------------------------------------------------- -try_local_expand_abbrev(Abbrev) -> - case si_sasl_supp:expand_abbrev(Abbrev, process_abbrevs()) of - {value, {_, RealName}} -> RealName; - _ -> Abbrev - end. - -process_abbrevs() -> - []. - -%% Test get_status_info/format_status_info for all implemented servers. -test() -> - lists:foreach(fun test_all_registered/1, - lists:append(si_sasl_supp:process_abbrevs(), - process_abbrevs())). - -test_all_registered({Al, _Ful}) -> - si:pi(all, Al). diff --git a/lib/sasl/src/si_sasl_supp.erl b/lib/sasl/src/si_sasl_supp.erl deleted file mode 100644 index cce628f8c4..0000000000 --- a/lib/sasl/src/si_sasl_supp.erl +++ /dev/null @@ -1,380 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2016. 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% -%% --module(si_sasl_supp). - --behaviour(gen_server). - -%%%--------------------------------------------------------------------------- -%%% Description: -%%% This module contains the BOS specific parts of the Status Inspection Tool. -%%%--------------------------------------------------------------------------- - - -%% user interface --export([h/0, help/0, start_log/1, stop_log/0, abbrevs/0, pi/1, pi/2, pi/3, - pi/4, ppi/1, ppi/3, start/0, start/1, stop/0, start_link/1]). - -%% intermodule exports --export([make_pid/1, make_pid/3, process_abbrevs/0, expand_abbrev/2, - status_info/1, valid_opt/1, p/1, do_best_printout/4, - si_exec/2, handle_call/3, terminate/2]). - -%% exports for use within module --export([init/1, start_log_impl/1, pi_impl/2, ppi_impl/1]). - -%% other gen_server callbacks (not used) --export([handle_cast/2, handle_info/2, code_change/3]). - -%%-------------------------------------------------- -%% Table of contents -%% 1. Interface -%% 2. SI - Server -%% 3. Code -%% 4. Selectors -%%-------------------------------------------------- - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% 1. Interface -%% ----------------------------------------------------- - -h() -> print_help(). -help() -> print_help(). - -si_exec(Fun, Args) -> call({si_exec, Fun, Args}). - -start_log(FileName) -> - call({start_log, FileName}). - -stop_log() -> - call(stop_log). - -abbrevs() -> - io:format("~p", [process_abbrevs()]). - -%%----------------------------------------------------------------- -%% All functions can be called with an option 'normal' or 'all'; -%% default is 'normal'. -%%----------------------------------------------------------------- -%% Process Info that tries to determine processtype (=Module), then -%% it uses this Module:format_info to format data from status_info/1. -%%----------------------------------------------------------------- -pi(XPid) -> - si_exec({si_sasl_supp, pi_impl}, [normal, XPid]). - -pi(Opt, XPid) -> - si_exec({si_sasl_supp, pi_impl}, [valid_opt(Opt), XPid]). - -pi(A, B, C) when is_integer(A), is_integer(B), is_integer(C) -> - si_exec({si_sasl_supp, pi_impl}, [normal, {A, B, C}]). - -pi(Opt, A, B, C) when is_integer(A), is_integer(B), is_integer(C) -> - si_exec({si_sasl_supp, pi_impl}, [valid_opt(Opt), {A, B, C}]). - -%%----------------------------------------------------------------- -%% Pretty print Process_Info. -%%----------------------------------------------------------------- -ppi(XPid) -> - case whereis(si_server) of - undefined -> % You can always run ppi. - ppi_impl(XPid); % if si_server is down, use standard_io - _ -> - si_exec({si_sasl_supp, ppi_impl}, [XPid]) - end. -ppi(A, B, C) -> - case whereis(si_server) of - undefined -> % You can always run ppi. - ppi_impl({A, B, C}); % if si_server is down, use standard_io - _ -> - si_exec({si_sasl_supp, ppi_impl}, [{A, B, C}]) - end. - - - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% 2. SI - Server -%%-------------------------------------------------- --record(state, {}). - -start() -> start([]). -start(Options) -> - supervisor:start_child(sasl_sup, - {si_server, {si_sasl_supp, start_link, [Options]}, - temporary, brutal_kill, worker, [si_sasl_supp]}). - -start_link(_Options) -> - gen_server:start_link({local, si_server}, si_sasl_supp, [], []). - -stop() -> - call(stop), - supervisor:delete_child(sasl_sup, si_server). - - -init(Options) -> - process_flag(trap_exit, true), - start_log_impl(get_option(Options, start_log, standard_io)), - {ok, #state{}}. - -%%----------------------------------------------------------------- -%% If an error occurs and we're logging to file: write the error -%% to the file. -%% Always return the error. -%% The only data held by the si_server is the device in its process dictionary. -%%----------------------------------------------------------------- -handle_call({si_exec, Fun, Args}, _From, State) -> - case catch apply(Fun, Args) of - {'EXIT', Reason} -> - print_error(get(device), - "SI internal error. Reason: ~w~n", - [Reason]), - {stop, shutdown, {internal_error, Reason}, State}; - {error, Reason} -> - print_error(get(device), "~nSI error: ~w~n", [Reason]), - {reply, {error, Reason}, State}; - X -> - {reply, X, State} - end; -handle_call({start_log, FileName}, _From, State) -> - start_log_impl(FileName), - {reply, ok, State}; -handle_call(stop_log, _From, State) -> - start_log_impl(standard_io), - {reply, ok, State}; -handle_call(stop, _From, State) -> - start_log_impl(standard_io), - {stop, normal, stopped, State}. - -terminate(_Reason, _State) -> - _ = close_device(get(device)), - ok. - -handle_cast(_Msg, State) -> - {noreply, State}. -handle_info(_Info, State) -> - {noreply, State}. -code_change(_OldVsn, State, _Extra) -> - {ok, State}. - -close_device(standard_io) -> ok; -close_device(Fd) -> file:close(Fd). - -print_error(standard_io, _, _) -> ok; -print_error(Device, Format, Args) -> - io:format(Device, Format, Args). - -get_option(Options, Key, Default) -> - case lists:keysearch(Key, 1, Options) of - {value, {_Key, Value}} -> Value; - _ -> Default - end. - -open_log_file(undefined, NewFile) -> - open_log_file(NewFile); -open_log_file(standard_io, NewFile) -> - open_log_file(NewFile); -open_log_file(OldFile, NewFile) -> - _ = file:close(OldFile), - open_log_file(NewFile). - -open_log_file(standard_io) -> standard_io; -open_log_file(FileName) -> - case file:open(FileName, [write]) of - {ok, Fd} -> Fd; - Error -> - io:format("si_sasl_supp: Cannot open file '~s' (~w).~n", - [FileName, Error]), - io:format("si_sasl_supp: Using standard_io~n"), - standard_io - end. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% 3. Code -%%-------------------------------------------------- - -%%----------------------------------------------------------------- -%% call(Request) -> Term -%%----------------------------------------------------------------- -call(Req) -> - gen_server:call(si_server, Req, infinity). - -%%-------------------------------------------------- -%% Makes a Pid of almost anything. -%% Returns: Pid|{error, Reason} -%% Fails: Never. -%%-------------------------------------------------- -make_pid(A,B,C) when is_integer(A), is_integer(B), is_integer(C) -> - list_to_pid(lists:concat(["<",A,".",B,".",C,">"])). -make_pid(P) when is_pid(P) -> P; -make_pid(undefined) -> undefined; -make_pid(P) when is_atom(P) -> - case whereis(P) of - undefined -> - case expand_abbrev(P, process_abbrevs()) of - {error, Reason} -> {error, Reason}; - {value, {_Abbrev, FullName}} -> - case whereis(FullName) of - undefined -> - {error, {'process not registered', P}}; - Pid -> Pid - end - end; - Pid -> Pid - end; -make_pid(P) when is_list(P) -> list_to_pid(P); -make_pid({A, B, C}) -> make_pid(A, B, C); -make_pid(X) -> {error, {'can not make a pid of', X}}. - -process_abbrevs() -> - [{init, init}, - {fs, file_server}]. - -%%-------------------------------------------------- -%% Args: Abbrevs is an assoc-list of {Abbrev, RealName} -%% Returns: {value, {Abbrev, FullName}}|{error, Reason} -%%-------------------------------------------------- -expand_abbrev(ProcessName, Abbrevs) -> - case lists:keysearch(ProcessName, 1, Abbrevs) of - {value, {Abbrev, FullName}} -> - {value, {Abbrev, FullName}}; - _ -> - case lists:keysearch(ProcessName, 2, Abbrevs) of - {value, {Abbrev, FullName}} -> - {value, {Abbrev, FullName}}; - _ -> - {error, {'invalid process name', ProcessName}} - end - end. - -%%----------------------------------------------------------------- -%% This is the function that actually gets the information out -%% of the agent/server/... -%% Returns: {status_info, Pid, Type, Data} -%% | {error, Reason} -%%----------------------------------------------------------------- -status_info(Pid) when is_pid(Pid) -> - case catch sys:get_status(Pid, 5000) of - {status, Pid, Type, Info} -> - {status_info, Pid, Type, Info}; - _ -> - {error, {'process does not respond', Pid}} - end; - -status_info(X) -> - {error, {'not a pid', X}}. - -%%-------------------------------------------------- -%% Implementation starts here. -%%-------------------------------------------------- -start_log_impl(FileName) -> - put(device, open_log_file(get(device), FileName)). - -valid_opt(all) -> all; -valid_opt(_Opt) -> normal. - - -print_help() -> - p("- - - - - - - - PROCESSES - - - - - - - - - "), - p("si_sasl_supp:pi([Opt,] Pid) - Formatted information about any process that"), - p(" SI recognises."), - p("si_sasl_supp:pi([Opt,] A,B,C) - Same as si_sasl_supp:pi({A, B, C})."), - p("si_sasl_supp:ppi(Pid) - Pretty formating of process_info."), - p(" Works for any process."), - p("- - - - - - - - MISC - - - - - - - - - - - "), - p("si_sasl_supp:abbrevs() - Lists valid abbreviations."), - p("si_sasl_supp:start_log(FileNname)"), - p("si_sasl_supp:stop_log()"), - p("si_sasl_supp:start() - Starts Status Inspection (the si_server)."), - p("si_sasl_supp:start([{start_log, FileName}])"), - p("si_sasl_supp:stop() - Shut down SI."). - - - -%% Convenient shorthand -p(X) -> - io:format(lists:append(X, "~n")). - -pi_impl(Opt, XPid) -> - case make_pid(XPid) of - Pid when is_pid(Pid) -> - case status_info(Pid) of - {status_info, Pid, {module, Module}, Data} -> - do_best_printout(Opt, Pid, Module, Data); - {error, Reason} -> - _ = ppi_impl(Pid), - {error, {"can not get status info from process:", - XPid, - Reason}} - end; - {error, Reason} -> - {error, Reason} - end. - -%%-------------------------------------------------- -%% Is there a format_info for this process? In that case, run it! -%% Return ok|{error, Reason} -%% Fails: Never. -%%-------------------------------------------------- -do_best_printout(Opt, Pid, Mod, Data) when is_pid(Pid) -> - case print_info(get(device), Pid, {Mod, format_status}, Opt, Data) of - ok -> ok; - {error, Reason} -> - _ = ppi_impl(Pid), - {error, Reason} - end. - -ppi_impl(XPid) -> - case make_pid(XPid) of - P when is_pid(P) -> - case process_info(P) of - undefined -> - {error, {'dead process', P}}; - PI -> - Device = case get(device) of - undefined -> standard_io; - X -> X - end, - io:format(Device, "~nPretty Process Info~n", []), - io:format(Device, "-------------------~n", []), - io:format(Device, "~p~n", [PI]) - end; - _ -> {error, {no_pid, XPid}} - end. - -print_info(Device, Pid, {Module, Func}, Opt, Data) -> - case erlang:function_exported(Module, Func, 2) of - true -> - case catch apply(Module, Func, [Opt, Data]) of - Format when is_list(Format) -> - format_lib_supp:print_info(Device, 79, - add_pid_to_format(Pid, Format)), - ok; - Other -> {error, {'invalid format', Other}} - end; - _ -> - {error, {no_such_function, Module, Func}} - end. - -add_pid_to_format(Pid, [{header, H} | T]) -> - [{header, H}, {data, [{"Pid", Pid}]} | T]; -add_pid_to_format(Pid, List) -> - [{data, [{"Pid", Pid}]} | List]. - - diff --git a/lib/sasl/src/systools_make.erl b/lib/sasl/src/systools_make.erl index ffd5ecdf6d..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. @@ -367,6 +367,7 @@ add_apply_upgrade(Script,Args) -> %% RelVsn/start.boot %% relup %% sys.config +%% sys.config.src %% erts-EVsn[/bin] %%----------------------------------------------------------------- @@ -1545,6 +1546,12 @@ mandatory_modules() -> gen_server, heart, kernel, + logger, + logger_filters, + logger_server, + logger_backend, + logger_config, + logger_simple, lists, proc_lib, supervisor @@ -1556,9 +1563,9 @@ 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_eval,prim_file, + init,otp_ring0,prim_buffer,prim_eval,prim_file, prim_inet,prim_zip,zlib]. %%______________________________________________________________________ @@ -1569,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; @@ -1609,6 +1616,7 @@ create_kernel_procs(Appls) -> %% RelVsn/start.boot %% relup %% sys.config +%% sys.config.src %% erts-EVsn[/bin] %% %% The VariableN.tar.gz files can also be stored as own files not @@ -1764,14 +1772,18 @@ add_system_files(Tar, RelName, Release, Path1) -> add_to_tar(Tar, Relup, filename:join(RelVsnDir, "relup")) end, - case lookup_file("sys.config", Path) of - false -> - ignore; - Sys -> - check_sys_config(Sys), - add_to_tar(Tar, Sys, filename:join(RelVsnDir, "sys.config")) + case lookup_file("sys.config.src", Path) of + false -> + case lookup_file("sys.config", Path) of + false -> + ignore; + Sys -> + check_sys_config(Sys), + add_to_tar(Tar, Sys, filename:join(RelVsnDir, "sys.config")) + end; + SysSrc -> + add_to_tar(Tar, SysSrc, filename:join(RelVsnDir, "sys.config.src")) end, - ok. lookup_file(Name, [Dir|Path]) -> diff --git a/lib/sasl/test/release_handler_SUITE.erl b/lib/sasl/test/release_handler_SUITE.erl index 50932e89e4..edd2efdf05 100644 --- a/lib/sasl/test/release_handler_SUITE.erl +++ b/lib/sasl/test/release_handler_SUITE.erl @@ -22,7 +22,8 @@ -include_lib("common_test/include/ct.hrl"). -include("test_lib.hrl"). --compile(export_all). +-compile([export_all, nowarn_export_all]). +-export([scheduler_wall_time/0, garbage_collect/0]). %% rpc'ed % Default timetrap timeout (set in init_per_testcase). %-define(default_timeout, ?t:minutes(40)). @@ -1085,8 +1086,9 @@ otp_9395_update_many_mods(Conf) when is_list(Conf) -> Rel2Dir = filename:dirname(Rel2), %% Start a slave node + PA = filename:dirname(code:which(?MODULE)), {ok, Node} = t_start_node(otp_9395_update_many_mods, Rel1, - filename:join(Rel1Dir,"sys.config")), + filename:join(Rel1Dir,"sys.config"), "-pa " ++ PA), %% Start a lot of processes on the new node, all with refs to each %% module that will be updated @@ -1109,8 +1111,8 @@ otp_9395_update_many_mods(Conf) when is_list(Conf) -> [RelVsn2, filename:join(Rel2Dir, "sys.config")]), %% First, install release directly and check how much time it takes - rpc:call(Node,erlang,garbage_collect,[]), - rpc:call(Node,erlang,system_flag,[scheduler_wall_time,true]), + rpc:call(Node,?MODULE,garbage_collect,[]), + SWTFlag0 = spawn_link(Node, ?MODULE, scheduler_wall_time, []), {TInst0,{ok, _, []}} = timer:tc(rpc,call,[Node, release_handler, install_release, [RelVsn2]]), SWT0 = rpc:call(Node,erlang,statistics,[scheduler_wall_time]), @@ -1135,9 +1137,9 @@ otp_9395_update_many_mods(Conf) when is_list(Conf) -> %% Finally install release after check and purge, and check that %% this install was faster than the first. - rpc:call(Node,erlang,system_flag,[scheduler_wall_time,false]), - rpc:call(Node,erlang,garbage_collect,[]), - rpc:call(Node,erlang,system_flag,[scheduler_wall_time,true]), + SWTFlag0 ! die, + rpc:call(Node,?MODULE,garbage_collect,[]), + _SWTFlag1 = spawn_link(Node, ?MODULE, scheduler_wall_time, []), {TInst2,{ok, _RelVsn1, []}} = timer:tc(rpc,call,[Node, release_handler, install_release, [RelVsn2]]), SWT2 = rpc:call(Node,erlang,statistics,[scheduler_wall_time]), @@ -1161,6 +1163,15 @@ otp_9395_update_many_mods(Conf) when is_list(Conf) -> ok. +scheduler_wall_time() -> + erlang:system_flag(scheduler_wall_time,true), + receive _Msg -> normal end. + +garbage_collect() -> + Pids = processes(), + [erlang:garbage_collect(Pid) || Pid <- Pids]. + + otp_9395_update_many_mods(cleanup,_Conf) -> stop_node(node_name(otp_9395_update_many_mods)). @@ -1190,8 +1201,9 @@ otp_9395_rm_many_mods(Conf) when is_list(Conf) -> Rel2Dir = filename:dirname(Rel2), %% Start a slave node + PA = filename:dirname(code:which(?MODULE)), {ok, Node} = t_start_node(otp_9395_rm_many_mods, Rel1, - filename:join(Rel1Dir,"sys.config")), + filename:join(Rel1Dir,"sys.config"), "-pa " ++ PA), %% Start a lot of processes on the new node, all with refs to each %% module that will be updated @@ -1214,8 +1226,8 @@ otp_9395_rm_many_mods(Conf) when is_list(Conf) -> [RelVsn2, filename:join(Rel2Dir, "sys.config")]), %% First, install release directly and check how much time it takes - rpc:call(Node,erlang,garbage_collect,[]), - rpc:call(Node,erlang,system_flag,[scheduler_wall_time,true]), + rpc:call(Node,?MODULE,garbage_collect,[]), + SWTFlag0 = spawn_link(Node, ?MODULE, scheduler_wall_time, []), {TInst0,{ok, _, []}} = timer:tc(rpc,call,[Node, release_handler, install_release, [RelVsn2]]), SWT0 = rpc:call(Node,erlang,statistics,[scheduler_wall_time]), @@ -1240,9 +1252,9 @@ otp_9395_rm_many_mods(Conf) when is_list(Conf) -> %% Finally install release after check and purge, and check that %% this install was faster than the first. - rpc:call(Node,erlang,system_flag,[scheduler_wall_time,false]), - rpc:call(Node,erlang,garbage_collect,[]), - rpc:call(Node,erlang,system_flag,[scheduler_wall_time,true]), + SWTFlag0 ! die, + rpc:call(Node,?MODULE,garbage_collect,[]), + _SWTFlag1 = spawn_link(Node, ?MODULE, scheduler_wall_time, []), {TInst2,{ok, _RelVsn1, []}} = timer:tc(rpc,call,[Node, release_handler, install_release, [RelVsn2]]), SWT2 = rpc:call(Node,erlang,statistics,[scheduler_wall_time]), @@ -1384,9 +1396,9 @@ upgrade_supervisor(Conf) when is_list(Conf) -> %% Check that the restart strategy and child spec is updated {status, _, {module, _}, [_, _, _, _, [_,_,{data,[{"State",State}]}|_]]} = rpc:call(Node,sys,get_status,[a_sup]), - {state,_,RestartStrategy,[Child],_,_,_,_,_,_,_} = State, + {state,_,RestartStrategy,{[a],Db},_,_,_,_,_,_,_} = State, one_for_all = RestartStrategy, % changed from one_for_one - {child,_,_,_,_,brutal_kill,_,_} = Child, % changed from timeout 2000 + {child,_,_,_,_,brutal_kill,_,_} = maps:get(a,Db), % changed from timeout 2000 ok. @@ -1835,24 +1847,32 @@ otp_10463_upgrade_script_regexp(cleanup,Config) -> code:del_path(filename:join([DataDir,regexp_appup,app1,ebin])), ok. -no_dot_erlang(Conf) -> - PrivDir = ?config(data_dir,Conf), - {ok, OrigWd} = file:get_cwd(), - try - ok = file:set_cwd(PrivDir), - - {ok, Wd} = file:get_cwd(), - io:format("Dir ~ts~n", [Wd]), +no_dot_erlang(_Conf) -> + case init:get_argument(home) of + {ok,[[Home]]} when is_list(Home) -> + no_dot_erlang_1(Home); + _ -> ok + end. +no_dot_erlang_1(Home) -> + DotErlang = filename:join(Home, ".erlang"), + BupErlang = filename:join(Home, ".erlang_testbup"), + try + {ok, Wd} = file:get_cwd(), + case filelib:is_file(DotErlang) of + true -> {ok, _} = file:copy(DotErlang, BupErlang); + false -> ok + end, Erl0 = filename:join([code:root_dir(),"bin","erl"]), Erl = filename:nativename(Erl0), Quote = "\"", Args = " -noinput -run c pwd -run erlang halt", - ok = file:write_file(".erlang", <<"io:put_chars(\"DOT_ERLANG_READ\\n\").\n">>), + ok = file:write_file(DotErlang, <<"io:put_chars(\"DOT_ERLANG_READ\\n\").\n">>), CMD1 = Quote ++ Erl ++ Quote ++ Args , case os:cmd(CMD1) of - "DOT_ERLANG_READ" ++ _ -> ok; + "DOT_ERLANG_READ" ++ _ -> + io:format("~p: Success~n", [?LINE]); Other1 -> io:format("Failed: ~ts~n",[CMD1]), io:format("Expected: ~s ++ _~n",["DOT_ERLANG_READ "]), @@ -1862,7 +1882,7 @@ no_dot_erlang(Conf) -> NO_DOT_ERL = " -boot no_dot_erlang", CMD2 = Quote ++ Erl ++ Quote ++ NO_DOT_ERL ++ Args, case lists:prefix(Wd, Other2 = os:cmd(CMD2)) of - true -> ok; + true -> io:format("~p: Success~n", [?LINE]); false -> io:format("Failed: ~ts~n",[CMD2]), io:format("Expected: ~s~n",["TESTOK"]), @@ -1870,9 +1890,13 @@ no_dot_erlang(Conf) -> exit({failed_to_start, no_dot_erlang}) end after - _ = file:delete(".erlang"), - ok = file:set_cwd(OrigWd), - ok + case filelib:is_file(BupErlang) of + true -> + {ok, _} = file:copy(BupErlang, DotErlang), + _ = file:delete(BupErlang); + false -> + _ = file:delete(DotErlang) + end end. %%%----------------------------------------------------------------- @@ -2556,15 +2580,15 @@ check_gg_info(Node,OtherAlive,OtherDead,Synced,N) -> GGI = rpc:call(Node, global_group, info, []), GI = rpc:call(Node, global, info,[]), try do_check_gg_info(OtherAlive,OtherDead,Synced,GGI,GI) - catch _:E when N==0 -> + catch _:E:Stacktrace when N==0 -> ?t:format("~nERROR: check_gg_info failed for ~p:~n~p~n" "when GGI was: ~p~nand GI was: ~p~n", - [Node,{E,erlang:get_stacktrace()},GGI,GI]), + [Node,{E,Stacktrace},GGI,GI]), ?t:fail("check_gg_info failed"); - _:E -> + _:E:Stacktrace -> ?t:format("~nWARNING: check_gg_info failed for ~p:~n~p~n" "when GGI was: ~p~nand GI was: ~p~n", - [Node,{E,erlang:get_stacktrace()},GGI,GI]), + [Node,{E,Stacktrace},GGI,GI]), timer:sleep(1000), check_gg_info(Node,OtherAlive,OtherDead,Synced,N-1) end. 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 6e83b4c2e2..ad61186921 100644 --- a/lib/sasl/test/systools_SUITE.erl +++ b/lib/sasl/test/systools_SUITE.erl @@ -67,7 +67,7 @@ groups() -> otp_3065_circular_dependenies, included_and_used_sort_script]}, {tar, [], [tar_options, normal_tar, no_mod_vsn_tar, system_files_tar, - invalid_system_files_tar, variable_tar, + system_src_file_tar, invalid_system_files_tar, variable_tar, src_tests_tar, var_tar, exref_tar, link_tar, no_sasl_tar, otp_9507_path_ebin]}, {relup, [], @@ -945,12 +945,47 @@ system_files_tar(Config) -> ok. + system_files_tar(cleanup,Config) -> Dir = ?privdir, file:delete(filename:join(Dir,"sys.config")), file:delete(filename:join(Dir,"relup")), ok. +%% make_tar: Check that sys.config.src and not sys.config is included +system_src_file_tar(Config) -> + {ok, OldDir} = file:get_cwd(), + + {LatestDir, LatestName} = create_script(latest,Config), + + DataDir = filename:absname(?copydir), + LibDir = fname([DataDir, d_normal, lib]), + P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], + + ok = file:set_cwd(LatestDir), + + %% Add dummy sys.config and sys.config.src + ok = file:write_file("sys.config.src","[${SOMETHING}].\n"), + ok = file:write_file("sys.config","[].\n"), + + {ok, _, _} = systools:make_script(LatestName, [silent, {path, P}]), + ok = systools:make_tar(LatestName, [{path, P}]), + ok = check_tar(fname(["releases","LATEST","sys.config.src"]), LatestName), + {error, _} = check_tar(fname(["releases","LATEST","sys.config"]), LatestName), + {ok, _, _} = systools:make_tar(LatestName, [{path, P}, silent]), + ok = check_tar(fname(["releases","LATEST","sys.config.src"]), LatestName), + {error, _} = check_tar(fname(["releases","LATEST","sys.config"]), LatestName), + + ok = file:set_cwd(OldDir), + + ok. + +system_src_file_tar(cleanup,Config) -> + Dir = ?privdir, + file:delete(filename:join(Dir,"sys.config")), + file:delete(filename:join(Dir,"sys.config.src")), + ok. %% make_tar: Check that make_tar fails if relup or sys.config exist %% but do not have valid content diff --git a/lib/sasl/test/test_lib.hrl b/lib/sasl/test/test_lib.hrl index 9a54937f96..f5210d4f27 100644 --- a/lib/sasl/test/test_lib.hrl +++ b/lib/sasl/test/test_lib.hrl @@ -1,3 +1,3 @@ -define(ertsvsn,"4.4"). --define(kernelvsn,"5.0"). --define(stdlibvsn,"3.0"). +-define(kernelvsn,"5.3"). +-define(stdlibvsn,"3.4"). |