./ct_report/coverage/ejabberd_app.COVER.html

1 %%%----------------------------------------------------------------------
2 %%% File : ejabberd_app.erl
3 %%% Author : Alexey Shchepin <alexey@process-one.net>
4 %%% Purpose : ejabberd's application callback module
5 %%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
6 %%%
7 %%%
8 %%% ejabberd, Copyright (C) 2002-2011 ProcessOne
9 %%%
10 %%% This program is free software; you can redistribute it and/or
11 %%% modify it under the terms of the GNU General Public License as
12 %%% published by the Free Software Foundation; either version 2 of the
13 %%% License, or (at your option) any later version.
14 %%%
15 %%% This program is distributed in the hope that it will be useful,
16 %%% but WITHOUT ANY WARRANTY; without even the implied warranty of
17 %%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 %%% General Public License for more details.
19 %%%
20 %%% You should have received a copy of the GNU General Public License
21 %%% along with this program; if not, write to the Free Software
22 %%% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 %%%
24 %%%----------------------------------------------------------------------
25
26 -module(ejabberd_app).
27 -author('alexey@process-one.net').
28
29 -behaviour(application).
30
31 -export([start/2, prep_stop/1, stop/1]).
32
33 -ignore_xref([prep_stop/1]).
34
35 -include("mongoose.hrl").
36
37
38 %%%
39 %%% Application API
40 %%%
41
42 start(normal, _Args) ->
43 76 mongoose_fips:notify(),
44 76 write_pid_file(),
45 76 update_status_file(starting),
46 76 db_init(),
47 76 application:start(cache_tab),
48
49 76 mongoose_graphql:init(),
50 76 translate:start(),
51 76 ejabberd_node_id:start(),
52 76 ejabberd_ctl:init(),
53 76 ejabberd_commands:init(),
54 76 mongoose_commands:init(),
55 76 mongoose_config:start(),
56 76 mongoose_router:start(),
57 76 mongoose_logs:set_global_loglevel(mongoose_config:get_opt(loglevel)),
58 76 mongoose_deprecations:start(),
59 76 {ok, _} = Sup = ejabberd_sup:start_link(),
60 76 mongoose_domain_api:init(),
61 76 mongoose_wpool:ensure_started(),
62 76 mongoose_wpool:start_configured_pools(),
63 %% ejabberd_sm is started separately because it may use one of the outgoing_pools
64 %% but some outgoing_pools should be started only with ejabberd_sup already running
65 76 ejabberd_sm:start(),
66 76 ejabberd_auth:start(),
67 76 mongoose_cluster_id:start(),
68 76 mongoose_service:start(),
69 76 mongoose_modules:start(),
70 76 service_mongoose_system_metrics:verify_if_configured(),
71 76 mongoose_metrics:init(),
72 76 mongoose_listener:start(),
73 76 ejabberd_admin:start(),
74 76 update_status_file(started),
75 76 ?LOG_NOTICE(#{what => mongooseim_node_started, version => ?MONGOOSE_VERSION, node => node()}),
76 76 Sup;
77 start(_, _) ->
78
:-(
{error, badarg}.
79
80 %% @doc Prepare the application for termination.
81 %% This function is called when an application is about to be stopped,
82 %% before shutting down the processes of the application.
83 prep_stop(State) ->
84 76 mongoose_deprecations:stop(),
85 76 mongoose_listener:stop(),
86 76 mongoose_modules:stop(),
87 76 mongoose_service:stop(),
88 76 broadcast_c2s_shutdown(),
89 76 mongoose_wpool:stop(),
90 76 mongoose_metrics:remove_all_metrics(),
91 76 mongoose_config:stop(),
92 76 State.
93
94 %% All the processes were killed when this function is called
95 stop(_State) ->
96 76 ?LOG_NOTICE(#{what => mongooseim_node_stopped, version => ?MONGOOSE_VERSION, node => node()}),
97 76 delete_pid_file(),
98 76 update_status_file(stopped),
99 %%ejabberd_debug:stop(),
100 76 ok.
101
102
103 %%%
104 %%% Internal functions
105 %%%
106 db_init() ->
107 76 case mnesia:system_info(extra_db_nodes) of
108 [] ->
109 47 application:stop(mnesia),
110 47 mnesia:create_schema([node()]),
111 47 application:start(mnesia, permanent);
112 _ ->
113 29 ok
114 end,
115 76 mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity).
116
117 -spec broadcast_c2s_shutdown() -> 'ok'.
118 broadcast_c2s_shutdown() ->
119 76 Children = supervisor:which_children(ejabberd_c2s_sup),
120 76 lists:foreach(
121 fun({_, C2SPid, _, _}) ->
122
:-(
C2SPid ! system_shutdown
123 end, Children),
124 76 mongoose_lib:wait_until(
125 fun() ->
126 76 Res = supervisor:count_children(ejabberd_c2s_sup),
127 76 proplists:get_value(active, Res)
128 end, 0).
129
130 %%%
131 %%% PID file
132 %%%
133
134 -spec write_pid_file() -> 'ok' | {'error', atom()}.
135 write_pid_file() ->
136 76 case ejabberd:get_pid_file() of
137 false ->
138
:-(
ok;
139 PidFilename ->
140 76 write_pid_file(os:getpid(), PidFilename)
141 end.
142
143 -spec write_pid_file(Pid :: string(),
144 PidFilename :: nonempty_string()
145 ) -> 'ok' | {'error', atom()}.
146 write_pid_file(Pid, PidFilename) ->
147 76 case file:open(PidFilename, [write]) of
148 {ok, Fd} ->
149 76 io:format(Fd, "~s~n", [Pid]),
150 76 file:close(Fd);
151 {error, Reason} ->
152
:-(
?LOG_ERROR(#{what => cannot_write_to_pid_file,
153
:-(
pid_file => PidFilename, reason => Reason}),
154
:-(
throw({cannot_write_pid_file, PidFilename, Reason})
155 end.
156
157 update_status_file(Status) ->
158 228 case ejabberd:get_status_file() of
159 false ->
160
:-(
ok;
161 StatusFilename ->
162 228 file:write_file(StatusFilename, atom_to_list(Status))
163 end.
164
165 -spec delete_pid_file() -> 'ok' | {'error', atom()}.
166 delete_pid_file() ->
167 76 case ejabberd:get_pid_file() of
168 false ->
169
:-(
ok;
170 PidFilename ->
171 76 file:delete(PidFilename)
172 end.
Line Hits Source