./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 83 mongoose_fips:notify(),
44 83 write_pid_file(),
45 83 update_status_file(starting),
46 83 db_init(),
47 83 application:start(cache_tab),
48
49 83 mongoose_graphql:init(),
50 83 translate:start(),
51 83 ejabberd_node_id:start(),
52 83 ejabberd_ctl:init(),
53 83 ejabberd_commands:init(),
54 83 mongoose_commands:init(),
55 83 mongoose_config:start(),
56 83 mongoose_router:start(),
57 83 mongoose_logs:set_global_loglevel(mongoose_config:get_opt(loglevel)),
58 83 mongoose_deprecations:start(),
59 83 {ok, _} = Sup = ejabberd_sup:start_link(),
60 83 mongoose_domain_api:init(),
61 83 mongoose_wpool:ensure_started(),
62 83 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 83 ejabberd_sm:start(),
66 83 ejabberd_auth:start(),
67 83 mongoose_cluster_id:start(),
68 83 mongoose_service:start(),
69 83 mongoose_modules:start(),
70 83 service_mongoose_system_metrics:verify_if_configured(),
71 83 mongoose_metrics:init(),
72 83 mongoose_listener:start(),
73 83 ejabberd_admin:start(),
74 83 update_status_file(started),
75 83 ?LOG_NOTICE(#{what => mongooseim_node_started, version => ?MONGOOSE_VERSION, node => node()}),
76 83 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 83 mongoose_deprecations:stop(),
85 83 mongoose_listener:stop(),
86 83 mongoose_modules:stop(),
87 83 mongoose_service:stop(),
88 83 broadcast_c2s_shutdown(),
89 83 mongoose_wpool:stop(),
90 83 mongoose_metrics:remove_all_metrics(),
91 83 mongoose_config:stop(),
92 83 State.
93
94 %% All the processes were killed when this function is called
95 stop(_State) ->
96 83 ?LOG_NOTICE(#{what => mongooseim_node_stopped, version => ?MONGOOSE_VERSION, node => node()}),
97 83 delete_pid_file(),
98 83 update_status_file(stopped),
99 %%ejabberd_debug:stop(),
100 83 ok.
101
102
103 %%%
104 %%% Internal functions
105 %%%
106 db_init() ->
107 83 case mnesia:system_info(extra_db_nodes) of
108 [] ->
109 54 application:stop(mnesia),
110 54 mnesia:create_schema([node()]),
111 54 application:start(mnesia, permanent);
112 _ ->
113 29 ok
114 end,
115 83 mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity).
116
117 -spec broadcast_c2s_shutdown() -> 'ok'.
118 broadcast_c2s_shutdown() ->
119 83 Children = supervisor:which_children(ejabberd_c2s_sup),
120 83 lists:foreach(
121 fun({_, C2SPid, _, _}) ->
122 1 C2SPid ! system_shutdown
123 end, Children),
124 83 mongoose_lib:wait_until(
125 fun() ->
126 84 Res = supervisor:count_children(ejabberd_c2s_sup),
127 84 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 83 case ejabberd:get_pid_file() of
137 false ->
138
:-(
ok;
139 PidFilename ->
140 83 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 83 case file:open(PidFilename, [write]) of
148 {ok, Fd} ->
149 83 io:format(Fd, "~s~n", [Pid]),
150 83 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 249 case ejabberd:get_status_file() of
159 false ->
160
:-(
ok;
161 StatusFilename ->
162 249 file:write_file(StatusFilename, atom_to_list(Status))
163 end.
164
165 -spec delete_pid_file() -> 'ok' | {'error', atom()}.
166 delete_pid_file() ->
167 83 case ejabberd:get_pid_file() of
168 false ->
169
:-(
ok;
170 PidFilename ->
171 83 file:delete(PidFilename)
172 end.
Line Hits Source