diff options
Diffstat (limited to 'src/ejabberd.erl')
| -rw-r--r-- | src/ejabberd.erl | 63 |
1 files changed, 40 insertions, 23 deletions
diff --git a/src/ejabberd.erl b/src/ejabberd.erl index a7de9ab11..f7157f61d 100644 --- a/src/ejabberd.erl +++ b/src/ejabberd.erl @@ -38,7 +38,7 @@ -protocol({xep, 270, '1.0'}). -export([start/0, stop/0, halt/0, start_app/1, start_app/2, - get_pid_file/0, check_app/1, module_name/1, is_loaded/0]). + get_pid_file/0, check_apps/0, module_name/1, is_loaded/0]). -include("logger.hrl"). @@ -49,8 +49,8 @@ stop() -> application:stop(ejabberd). halt() -> - application:stop(lager), - application:stop(sasl), + _ = application:stop(lager), + _ = application:stop(sasl), erlang:halt(1, [{flush, true}]). %% @spec () -> false | string() @@ -71,21 +71,15 @@ start_app(App, Type) -> StartFlag = not is_loaded(), start_app(App, Type, StartFlag). -check_app(App) -> - StartFlag = not is_loaded(), - spawn(fun() -> check_app_modules(App, StartFlag) end), - ok. - is_loaded() -> Apps = application:which_applications(), lists:keymember(ejabberd, 1, Apps). -start_app(App, Type, StartFlag) when not is_list(App) -> +start_app(App, Type, StartFlag) when is_atom(App) -> start_app([App], Type, StartFlag); start_app([App|Apps], Type, StartFlag) -> case application:start(App,Type) of ok -> - spawn(fun() -> check_app_modules(App, StartFlag) end), start_app(Apps, Type, StartFlag); {error, {already_started, _}} -> start_app(Apps, Type, StartFlag); @@ -93,23 +87,23 @@ start_app([App|Apps], Type, StartFlag) -> case lists:member(DepApp, [App|Apps]) of true -> Reason = io_lib:format( - "failed to start application '~p': " - "circular dependency on '~p' detected", + "Failed to start Erlang application '~s': " + "circular dependency with '~s' detected", [App, DepApp]), exit_or_halt(Reason, StartFlag); false -> start_app([DepApp,App|Apps], Type, StartFlag) end; - Err -> - Reason = io_lib:format("failed to start application '~p': ~p", - [App, Err]), + {error, Why} -> + Reason = io_lib:format( + "Failed to start Erlang application '~s': ~s. ~s", + [App, format_error(Why), hint()]), exit_or_halt(Reason, StartFlag) end; start_app([], _Type, _StartFlag) -> ok. check_app_modules(App, StartFlag) -> - sleep(5000), case application:get_key(App, modules) of {ok, Mods} -> lists:foreach( @@ -118,12 +112,12 @@ check_app_modules(App, StartFlag) -> non_existing -> File = get_module_file(App, Mod), Reason = io_lib:format( - "couldn't find module ~s " - "needed for application '~p'", - [File, App]), + "Couldn't find file ~s needed " + "for Erlang application '~s'. ~s", + [File, App, hint()]), exit_or_halt(Reason, StartFlag); _ -> - sleep(10) + ok end end, Mods); _ -> @@ -131,6 +125,23 @@ check_app_modules(App, StartFlag) -> ok end. +check_apps() -> + spawn( + fun() -> + Apps = [ejabberd | + [App || {App, _, _} <- application:which_applications(), + App /= ejabberd]], + ?DEBUG("Checking consistency of applications: ~s", + [misc:join_atoms(Apps, <<", ">>)]), + misc:peach( + fun(App) -> + check_app_modules(App, true) + end, Apps), + ?DEBUG("All applications are intact", []), + lists:foreach(fun erlang:garbage_collect/1, processes()) + end). + +-spec exit_or_halt(iodata(), boolean()) -> no_return(). exit_or_halt(Reason, StartFlag) -> ?CRITICAL_MSG(Reason, []), if StartFlag -> @@ -140,9 +151,6 @@ exit_or_halt(Reason, StartFlag) -> erlang:error(application_start_failed) end. -sleep(N) -> - timer:sleep(p1_rand:uniform(N)). - get_module_file(App, Mod) -> BaseName = atom_to_list(Mod), case code:lib_dir(App, ebin) of @@ -177,3 +185,12 @@ erlang_name(Atom) when is_atom(Atom) -> misc:atom_to_binary(Atom); erlang_name(Bin) when is_binary(Bin) -> Bin. + +format_error({Reason, File}) when is_list(Reason), is_list(File) -> + Reason ++ ": " ++ File; +format_error(Term) -> + io_lib:format("~p", [Term]). + +hint() -> + "This usually means that ejabberd or Erlang " + "was compiled/installed incorrectly.". |
