Start/stop virtual hosts when reloading configuration file

This commit is contained in:
Evgeniy Khramtsov 2017-02-23 10:12:19 +03:00
parent ed34b04e9b
commit 7d68112265
14 changed files with 248 additions and 107 deletions

View File

@ -86,6 +86,7 @@ start() ->
{attributes, record_info(fields, access)}]),
mnesia:add_table_copy(acl, node(), ram_copies),
mnesia:add_table_copy(access, node(), ram_copies),
ejabberd_hooks:add(config_reloaded, ?MODULE, load_from_config, 20),
load_from_config(),
ok.

View File

@ -57,10 +57,10 @@ start(normal, _Args) ->
setup_if_elixir_conf_used(),
ejabberd_config:start(),
set_settings_from_config(),
acl:start(),
shaper:start(),
connect_nodes(),
Sup = ejabberd_sup:start_link(),
acl:start(),
shaper:start(),
ejabberd_rdbms:start(),
ejabberd_riak_sup:start(),
ejabberd_redis:start(),
@ -88,7 +88,7 @@ start(_, _) ->
prep_stop(State) ->
ejabberd_listener:stop_listeners(),
ejabberd_admin:stop(),
broadcast_c2s_shutdown(),
ejabberd_sm:stop(),
gen_mod:stop_modules(),
timer:sleep(5000),
State.
@ -164,16 +164,6 @@ add_windows_nameservers() ->
?INFO_MSG("Adding machine's DNS IPs to Erlang system:~n~p", [IPTs]),
lists:foreach(fun(IPT) -> inet_db:add_ns(IPT) end, IPTs).
broadcast_c2s_shutdown() ->
Children = ejabberd_sm:get_all_pids(),
lists:foreach(
fun(C2SPid) when node(C2SPid) == node() ->
ejabberd_c2s:send(C2SPid, xmpp:serr_system_shutdown());
(_) ->
ok
end, Children).
%%%
%%% PID file
%%%

View File

@ -48,7 +48,8 @@
%% API
-export([get_presence/1, get_subscription/2, get_subscribed/1,
open_session/1, call/3, send/2, close/1, close/2, stop/1,
reply/2, copy_state/2, set_timeout/2, route/2, add_hooks/1]).
reply/2, copy_state/2, set_timeout/2, route/2,
host_up/1, host_down/1]).
-include("ejabberd.hrl").
-include("xmpp.hrl").
@ -145,8 +146,8 @@ route(Pid, Term) ->
set_timeout(State, Timeout) ->
xmpp_stream_in:set_timeout(State, Timeout).
-spec add_hooks(binary()) -> ok.
add_hooks(Host) ->
-spec host_up(binary()) -> ok.
host_up(Host) ->
ejabberd_hooks:add(c2s_closed, Host, ?MODULE, process_closed, 100),
ejabberd_hooks:add(c2s_terminated, Host, ?MODULE,
process_terminated, 100),
@ -157,6 +158,18 @@ add_hooks(Host) ->
ejabberd_hooks:add(c2s_handle_cast, Host, ?MODULE,
handle_unexpected_cast, 100).
-spec host_down(binary()) -> ok.
host_down(Host) ->
ejabberd_hooks:delete(c2s_closed, Host, ?MODULE, process_closed, 100),
ejabberd_hooks:delete(c2s_terminated, Host, ?MODULE,
process_terminated, 100),
ejabberd_hooks:delete(c2s_unauthenticated_packet, Host, ?MODULE,
reject_unauthenticated_packet, 100),
ejabberd_hooks:delete(c2s_handle_info, Host, ?MODULE,
process_info, 100),
ejabberd_hooks:delete(c2s_handle_cast, Host, ?MODULE,
handle_unexpected_cast, 100).
%% Copies content of one c2s state to another.
%% This is needed for session migration from one pid to another.
-spec copy_state(state(), state()) -> state().

View File

@ -194,7 +194,17 @@ load_file(File) ->
reload_file() ->
Config = get_ejabberd_config_path(),
OldHosts = get_myhosts(),
load_file(Config),
NewHosts = get_myhosts(),
lists:foreach(
fun(Host) ->
ejabberd_hooks:run(host_up, [Host])
end, NewHosts -- OldHosts),
lists:foreach(
fun(Host) ->
ejabberd_hooks:run(host_down, [Host])
end, OldHosts -- NewHosts),
ejabberd_hooks:run(config_reloaded, []).
-spec convert_to_yaml(file:filename()) -> ok | {error, any()}.

View File

@ -36,7 +36,8 @@
process_iq_reply/1, get_features/1,
register_iq_handler/5, register_iq_response_handler/4,
register_iq_response_handler/5, unregister_iq_handler/2,
unregister_iq_response_handler/2, bounce_resource_packet/1]).
unregister_iq_response_handler/2, bounce_resource_packet/1,
host_up/1, host_down/1]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2,
@ -196,16 +197,9 @@ get_features(_, _, XMLNSs) ->
%%====================================================================
init([]) ->
lists:foreach(fun (Host) ->
ejabberd_router:register_route(Host,
Host,
{apply, ?MODULE,
route}),
ejabberd_hooks:add(local_send_to_resource_hook, Host,
?MODULE, bounce_resource_packet,
100)
end,
?MYHOSTS),
lists:foreach(fun host_up/1, ?MYHOSTS),
ejabberd_hooks:add(host_up, ?MODULE, host_up, 10),
ejabberd_hooks:add(host_down, ?MODULE, host_down, 100),
catch ets:new(?IQTABLE, [named_table, public, ordered_set]),
update_table(),
ejabberd_mnesia:create(?MODULE, iq_response,
@ -245,6 +239,9 @@ handle_info(Info, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
lists:foreach(fun host_down/1, ?MYHOSTS),
ejabberd_hooks:delete(host_up, ?MODULE, host_up, 10),
ejabberd_hooks:delete(host_down, ?MODULE, host_down, 100),
ok.
code_change(_OldVsn, State, _Extra) ->
@ -281,6 +278,16 @@ update_table() ->
ok
end.
host_up(Host) ->
ejabberd_router:register_route(Host, Host, {apply, ?MODULE, route}),
ejabberd_hooks:add(local_send_to_resource_hook, Host,
?MODULE, bounce_resource_packet, 100).
host_down(Host) ->
ejabberd_router:unregister_route(Host),
ejabberd_hooks:delete(local_send_to_resource_hook, Host,
?MODULE, bounce_resource_packet, 100).
-spec get_iq_callback(binary()) -> {ok, module(), atom() | function()} | error.
get_iq_callback(ID) ->
case mnesia:dirty_read(iq_response, ID) of

View File

@ -29,7 +29,7 @@
-author('alexey@process-one.net').
-export([start/0, opt_type/1]).
-export([start/0, opt_type/1, start_hosts/0, start_host/1, stop_host/1]).
-include("ejabberd.hrl").
-include("logger.hrl").
@ -38,6 +38,9 @@ start() ->
file:delete(ejabberd_sql:freetds_config()),
file:delete(ejabberd_sql:odbc_config()),
file:delete(ejabberd_sql:odbcinst_config()),
ejabberd_hooks:add(host_up, ?MODULE, start_host, 20),
ejabberd_hooks:add(host_down, ?MODULE, stop_host, 90),
ejabberd_hooks:add(config_reloaded, ?MODULE, start_hosts, 20),
case lists:any(fun(H) -> needs_sql(H) /= false end,
?MYHOSTS) of
true ->
@ -48,13 +51,21 @@ start() ->
%% Start relationnal DB module on the nodes where it is needed
start_hosts() ->
lists:foreach(fun (Host) ->
case needs_sql(Host) of
{true, App} -> start_sql(Host, App);
false -> ok
end
end,
?MYHOSTS).
lists:foreach(fun start_host/1, ?MYHOSTS).
-spec start_host(binary()) -> ok.
start_host(Host) ->
case needs_sql(Host) of
{true, App} -> start_sql(Host, App);
false -> ok
end.
-spec stop_host(binary()) -> ok.
stop_host(Host) ->
SupName = gen_mod:get_module_proc(Host, ejabberd_sql_sup),
supervisor:terminate_child(ejabberd_sup, SupName),
supervisor:delete_child(ejabberd_sup, SupName),
ok.
%% Start the SQL module on the given host
start_sql(Host, App) ->
@ -66,10 +77,12 @@ start_sql(Host, App) ->
infinity, supervisor, [ejabberd_sql_sup]},
case supervisor:start_child(ejabberd_sup, ChildSpec) of
{ok, _PID} -> ok;
{error, {already_started, _}} -> ok;
_Error ->
?ERROR_MSG("Start of supervisor ~p failed:~n~p~nRetrying."
"..~n",
[Supervisor_name, _Error]),
timer:sleep(5000),
start_sql(Host, App)
end.

View File

@ -28,7 +28,7 @@
-behaviour(ejabberd_config).
%% API
-export([start/0, start_link/0, q/1, qp/1, opt_type/1]).
-export([start/0, stop/0, start_link/0, q/1, qp/1, host_up/1, opt_type/1]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
@ -49,16 +49,16 @@ start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
start() ->
ejabberd_hooks:add(config_reloaded, ?MODULE, start, 20),
ejabberd_hooks:add(host_up, ?MODULE, host_up, 20),
case lists:any(
fun(Host) ->
is_redis_configured(Host)
end, ?MYHOSTS) of
true ->
Spec = {?MODULE, {?MODULE, start_link, []},
permanent, 2000, worker, [?MODULE]},
supervisor:start_child(ejabberd_sup, Spec);
do_start();
false ->
ok
stop()
end.
q(Command) ->
@ -71,6 +71,16 @@ qp(Pipeline) ->
catch _:Reason -> {error, Reason}
end.
stop() ->
supervisor:terminate_child(ejabberd_sup, ?MODULE),
supervisor:delete_child(ejabberd_sup, ?MODULE).
host_up(Host) ->
case is_redis_configured(Host) of
true -> do_start();
false -> ok
end.
%%%===================================================================
%%% gen_server callbacks
%%%===================================================================
@ -108,6 +118,11 @@ code_change(_OldVsn, State, _Extra) ->
%%%===================================================================
%%% Internal functions
%%%===================================================================
do_start() ->
Spec = {?MODULE, {?MODULE, start_link, []},
permanent, 5000, worker, [?MODULE]},
supervisor:start_child(ejabberd_sup, Spec).
is_redis_configured(Host) ->
ServerConfigured = ejabberd_config:has_option({redis_server, Host}),
PortConfigured = ejabberd_config:has_option({redis_port, Host}),

View File

@ -28,9 +28,9 @@
-behaviour(ejabberd_config).
-author('alexey@process-one.net').
-export([start/0, start_link/0, init/1, get_pids/0,
-export([start/0, stop/0, start_link/0, init/1, get_pids/0,
transform_options/1, get_random_pid/0, get_random_pid/1,
opt_type/1]).
host_up/1, opt_type/1]).
-include("ejabberd.hrl").
-include("logger.hrl").
@ -45,10 +45,26 @@
-define(CONNECT_TIMEOUT, 500). % milliseconds
start() ->
ejabberd_hooks:add(config_reloaded, ?MODULE, start, 20),
ejabberd_hooks:add(host_up, ?MODULE, host_up, 20),
case lists:any(
fun(Host) ->
is_riak_configured(Host)
end, ?MYHOSTS) of
true ->
ejabberd:start_app(riakc),
do_start();
false ->
stop()
end.
stop() ->
supervisor:terminate_child(ejabberd_sup, ?MODULE),
supervisor:delete_child(ejabberd_sup, ?MODULE),
ok.
host_up(Host) ->
case is_riak_configured(Host) of
true ->
ejabberd:start_app(riakc),
do_start();
@ -77,9 +93,8 @@ is_riak_configured(Host) ->
or AuthConfigured or ModuleWithRiakDBConfigured.
do_start() ->
SupervisorName = ?MODULE,
ChildSpec =
{SupervisorName,
{?MODULE,
{?MODULE, start_link, []},
transient,
infinity,
@ -88,9 +103,11 @@ do_start() ->
case supervisor:start_child(ejabberd_sup, ChildSpec) of
{ok, _PID} ->
ok;
{error, {already_started, _}} ->
ok;
_Error ->
?ERROR_MSG("Start of supervisor ~p failed:~n~p~nRetrying...~n",
[SupervisorName, _Error]),
[?MODULE, _Error]),
timer:sleep(5000),
start()
end.

View File

@ -44,7 +44,8 @@
list_temporarily_blocked_hosts/0,
external_host_overloaded/1, is_temporarly_blocked/1,
get_commands_spec/0, zlib_enabled/1, get_idle_timeout/1,
tls_required/1, tls_verify/1, tls_enabled/1, tls_options/2]).
tls_required/1, tls_verify/1, tls_enabled/1, tls_options/2,
host_up/1, host_down/1]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2,
@ -300,8 +301,9 @@ init([]) ->
ejabberd_mnesia:create(?MODULE, temporarily_blocked,
[{ram_copies, [node()]},
{attributes, record_info(fields, temporarily_blocked)}]),
ejabberd_s2s_in:add_hooks(),
ejabberd_s2s_out:add_hooks(),
ejabberd_hooks:add(host_up, ?MODULE, host_up, 50),
ejabberd_hooks:add(host_down, ?MODULE, host_down, 60),
lists:foreach(fun host_up/1, ?MYHOSTS),
{ok, #state{}}.
handle_call(_Request, _From, State) ->
@ -320,6 +322,9 @@ handle_info(_Info, State) -> {noreply, State}.
terminate(_Reason, _State) ->
ejabberd_commands:unregister_commands(get_commands_spec()),
lists:foreach(fun host_down/1, ?MYHOSTS),
ejabberd_hooks:delete(host_up, ?MODULE, host_up, 50),
ejabberd_hooks:delete(host_down, ?MODULE, host_down, 60),
ok.
code_change(_OldVsn, State, _Extra) ->
@ -328,6 +333,26 @@ code_change(_OldVsn, State, _Extra) ->
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
host_up(Host) ->
ejabberd_s2s_in:host_up(Host),
ejabberd_s2s_out:host_up(Host).
host_down(Host) ->
lists:foreach(
fun(#s2s{fromto = {From, _}, pid = Pid}) when node(Pid) == node() ->
case ejabberd_router:host_of_route(From) of
Host ->
ejabberd_s2s_out:send(Pid, xmpp:serr_system_shutdown()),
ejabberd_s2s_out:stop(Pid);
_ ->
ok
end;
(_) ->
ok
end, ets:tab2list(s2s)),
ejabberd_s2s_in:host_down(Host),
ejabberd_s2s_out:host_down(Host).
-spec clean_table_from_bad_node(node()) -> any().
clean_table_from_bad_node(Node) ->
F = fun() ->

View File

@ -42,7 +42,8 @@
-export([handle_unexpected_info/2, handle_unexpected_cast/2,
reject_unauthenticated_packet/2, process_closed/2]).
%% API
-export([stop/1, close/1, send/2, update_state/2, establish/1, add_hooks/0]).
-export([stop/1, close/1, send/2, update_state/2, establish/1,
host_up/1, host_down/1]).
-include("ejabberd.hrl").
-include("xmpp.hrl").
@ -90,19 +91,27 @@ establish(State) ->
update_state(Ref, Callback) ->
xmpp_stream_in:cast(Ref, {update_state, Callback}).
-spec add_hooks() -> ok.
add_hooks() ->
lists:foreach(
fun(Host) ->
ejabberd_hooks:add(s2s_in_closed, Host, ?MODULE,
process_closed, 100),
ejabberd_hooks:add(s2s_in_unauthenticated_packet, Host, ?MODULE,
reject_unauthenticated_packet, 100),
ejabberd_hooks:add(s2s_in_handle_info, Host, ?MODULE,
handle_unexpected_info, 100),
ejabberd_hooks:add(s2s_in_handle_cast, Host, ?MODULE,
handle_unexpected_cast, 100)
end, ?MYHOSTS).
-spec host_up(binary()) -> ok.
host_up(Host) ->
ejabberd_hooks:add(s2s_in_closed, Host, ?MODULE,
process_closed, 100),
ejabberd_hooks:add(s2s_in_unauthenticated_packet, Host, ?MODULE,
reject_unauthenticated_packet, 100),
ejabberd_hooks:add(s2s_in_handle_info, Host, ?MODULE,
handle_unexpected_info, 100),
ejabberd_hooks:add(s2s_in_handle_cast, Host, ?MODULE,
handle_unexpected_cast, 100).
-spec host_down(binary()) -> ok.
host_down(Host) ->
ejabberd_hooks:delete(s2s_in_closed, Host, ?MODULE,
process_closed, 100),
ejabberd_hooks:delete(s2s_in_unauthenticated_packet, Host, ?MODULE,
reject_unauthenticated_packet, 100),
ejabberd_hooks:delete(s2s_in_handle_info, Host, ?MODULE,
handle_unexpected_info, 100),
ejabberd_hooks:delete(s2s_in_handle_cast, Host, ?MODULE,
handle_unexpected_cast, 100).
%%%===================================================================
%%% Hooks

View File

@ -40,7 +40,7 @@
handle_unexpected_cast/2, process_downgraded/2]).
%% API
-export([start/3, start_link/3, connect/1, close/1, stop/1, send/2,
route/2, establish/1, update_state/2, add_hooks/0]).
route/2, establish/1, update_state/2, host_up/1, host_down/1]).
-include("ejabberd.hrl").
-include("xmpp.hrl").
@ -99,21 +99,31 @@ establish(State) ->
update_state(Ref, Callback) ->
xmpp_stream_out:cast(Ref, {update_state, Callback}).
-spec add_hooks() -> ok.
add_hooks() ->
lists:foreach(
fun(Host) ->
ejabberd_hooks:add(s2s_out_auth_result, Host, ?MODULE,
process_auth_result, 100),
ejabberd_hooks:add(s2s_out_closed, Host, ?MODULE,
process_closed, 100),
ejabberd_hooks:add(s2s_out_handle_info, Host, ?MODULE,
handle_unexpected_info, 100),
ejabberd_hooks:add(s2s_out_handle_cast, Host, ?MODULE,
handle_unexpected_cast, 100),
ejabberd_hooks:add(s2s_out_downgraded, Host, ?MODULE,
process_downgraded, 100)
end, ?MYHOSTS).
-spec host_up(binary()) -> ok.
host_up(Host) ->
ejabberd_hooks:add(s2s_out_auth_result, Host, ?MODULE,
process_auth_result, 100),
ejabberd_hooks:add(s2s_out_closed, Host, ?MODULE,
process_closed, 100),
ejabberd_hooks:add(s2s_out_handle_info, Host, ?MODULE,
handle_unexpected_info, 100),
ejabberd_hooks:add(s2s_out_handle_cast, Host, ?MODULE,
handle_unexpected_cast, 100),
ejabberd_hooks:add(s2s_out_downgraded, Host, ?MODULE,
process_downgraded, 100).
-spec host_down(binary()) -> ok.
host_down(Host) ->
ejabberd_hooks:delete(s2s_out_auth_result, Host, ?MODULE,
process_auth_result, 100),
ejabberd_hooks:delete(s2s_out_closed, Host, ?MODULE,
process_closed, 100),
ejabberd_hooks:delete(s2s_out_handle_info, Host, ?MODULE,
handle_unexpected_info, 100),
ejabberd_hooks:delete(s2s_out_handle_cast, Host, ?MODULE,
handle_unexpected_cast, 100),
ejabberd_hooks:delete(s2s_out_downgraded, Host, ?MODULE,
process_downgraded, 100).
%%%===================================================================
%%% Hooks

View File

@ -36,6 +36,7 @@
%% API
-export([start/0,
stop/0,
start_link/0,
route/1,
route/2,
@ -74,6 +75,8 @@
is_existing_resource/3,
get_commands_spec/0,
c2s_handle_info/2,
host_up/1,
host_down/1,
make_sid/0
]).
@ -109,9 +112,15 @@
start() ->
ChildSpec = {?MODULE, {?MODULE, start_link, []},
transient, 1000, worker, [?MODULE]},
transient, 5000, worker, [?MODULE]},
supervisor:start_child(ejabberd_sup, ChildSpec).
-spec stop() -> ok.
stop() ->
supervisor:terminate_child(ejabberd_sup, ?MODULE),
supervisor:delete_child(ejabberd_sup, ?MODULE),
ok.
start_link() ->
?GEN_SERVER:start_link({local, ?MODULE}, ?MODULE, [], []).
@ -388,20 +397,12 @@ c2s_handle_info(State, _) ->
%%====================================================================
init([]) ->
process_flag(trap_exit, true),
lists:foreach(fun(Mod) -> Mod:init() end, get_sm_backends()),
ets:new(sm_iqtable, [named_table, public]),
lists:foreach(
fun(Host) ->
ejabberd_hooks:add(c2s_handle_info, Host,
ejabberd_sm, c2s_handle_info, 50),
ejabberd_hooks:add(roster_in_subscription, Host,
ejabberd_sm, check_in_subscription, 20),
ejabberd_hooks:add(offline_message_hook, Host,
ejabberd_sm, bounce_offline_message, 100),
ejabberd_hooks:add(remove_user, Host,
ejabberd_sm, disconnect_removed_user, 100),
ejabberd_c2s:add_hooks(Host)
end, ?MYHOSTS),
ejabberd_hooks:add(host_up, ?MODULE, host_up, 50),
ejabberd_hooks:add(host_down, ?MODULE, host_down, 60),
lists:foreach(fun host_up/1, ?MYHOSTS),
ejabberd_commands:register_commands(get_commands_spec()),
{ok, #state{}}.
@ -433,17 +434,9 @@ handle_info(Info, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
lists:foreach(
fun(Host) ->
ejabberd_hooks:delete(c2s_handle_info, Host,
ejabberd_sm, c2s_handle_info, 50),
ejabberd_hooks:delete(roster_in_subscription, Host,
ejabberd_sm, check_in_subscription, 20),
ejabberd_hooks:delete(offline_message_hook, Host,
ejabberd_sm, bounce_offline_message, 100),
ejabberd_hooks:delete(remove_user, Host,
ejabberd_sm, disconnect_removed_user, 100)
end, ?MYHOSTS),
lists:foreach(fun host_down/1, ?MYHOSTS),
ejabberd_hooks:delete(host_up, ?MODULE, host_up, 50),
ejabberd_hooks:delete(host_down, ?MODULE, host_down, 60),
ejabberd_commands:unregister_commands(get_commands_spec()),
ok.
@ -452,6 +445,36 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}.
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-spec host_up(binary()) -> ok.
host_up(Host) ->
ejabberd_hooks:add(c2s_handle_info, Host,
ejabberd_sm, c2s_handle_info, 50),
ejabberd_hooks:add(roster_in_subscription, Host,
ejabberd_sm, check_in_subscription, 20),
ejabberd_hooks:add(offline_message_hook, Host,
ejabberd_sm, bounce_offline_message, 100),
ejabberd_hooks:add(remove_user, Host,
ejabberd_sm, disconnect_removed_user, 100),
ejabberd_c2s:host_up(Host).
-spec host_down(binary()) -> ok.
host_down(Host) ->
Mod = get_sm_backend(Host),
lists:foreach(
fun(#session{sid = {_, Pid}}) when node(Pid) == node() ->
ejabberd_c2s:send(Pid, xmpp:serr_system_shutdown());
(_) ->
ok
end, Mod:get_sessions(Host)),
ejabberd_hooks:delete(c2s_handle_info, Host,
ejabberd_sm, c2s_handle_info, 50),
ejabberd_hooks:delete(roster_in_subscription, Host,
ejabberd_sm, check_in_subscription, 20),
ejabberd_hooks:delete(offline_message_hook, Host,
ejabberd_sm, bounce_offline_message, 100),
ejabberd_hooks:delete(remove_user, Host,
ejabberd_sm, disconnect_removed_user, 100),
ejabberd_c2s:host_down(Host).
-spec set_session(sid(), binary(), binary(), binary(),
prio(), info()) -> ok.

View File

@ -33,7 +33,7 @@
%% API
-export([start_link/0, process_command/1, register_hook/1,
process_remote_command/1]).
unregister_hook/1, process_remote_command/1]).
-export([init/1, handle_call/3, handle_cast/2,
handle_info/2, terminate/2, code_change/3, opt_type/1]).
@ -86,6 +86,10 @@ register_hook(Host) ->
ejabberd_hooks:add(local_send_to_resource_hook, Host,
?MODULE, process_command, 50).
unregister_hook(Host) ->
ejabberd_hooks:delete(local_send_to_resource_hook, Host,
?MODULE, process_command, 50).
%%====================================================================
%% gen_server callbacks
%%====================================================================
@ -101,6 +105,8 @@ init(Opts) ->
LH = proplists:get_value(large_heap, Opts),
process_flag(priority, high),
erlang:system_monitor(self(), [{large_heap, LH}]),
ejabberd_hooks:add(host_up, ?MODULE, register_hook, 50),
ejabberd_hooks:add(host_down, ?MODULE, unregister_hook, 60),
lists:foreach(fun register_hook/1, ?MYHOSTS),
{ok, #state{}}.

View File

@ -80,6 +80,8 @@ start_link() ->
init([]) ->
ejabberd_hooks:add(config_reloaded, ?MODULE, config_reloaded, 50),
ejabberd_hooks:add(host_up, ?MODULE, start_modules, 40),
ejabberd_hooks:add(host_down, ?MODULE, stop_modules, 80),
ets:new(ejabberd_modules,
[named_table, public,
{keypos, #ejabberd_module.module_host}]),
@ -162,7 +164,7 @@ sort_modules(Host, ModOpts) ->
end, ModOpts),
[digraph:vertex(G, V) || V <- digraph_utils:topsort(G)].
-spec start_modules(binary()) -> any().
-spec start_modules(binary()) -> ok.
start_modules(Host) ->
Modules = sort_modules(Host, get_modules_options(Host)),
@ -171,7 +173,7 @@ start_modules(Host) ->
start_module(Host, Module, Opts)
end, Modules).
-spec start_module(binary(), atom()) -> any().
-spec start_module(binary(), atom()) -> ok | {ok, pid()} | {error, not_found_in_config}.
start_module(Host, Module) ->
Modules = get_modules_options(Host),
@ -293,7 +295,7 @@ is_app_running(AppName) ->
lists:keymember(AppName, 1,
application:which_applications(Timeout)).
-spec stop_modules() -> any().
-spec stop_modules() -> ok.
stop_modules() ->
lists:foreach(
@ -301,7 +303,7 @@ stop_modules() ->
stop_modules(Host)
end, ?MYHOSTS).
-spec stop_modules(binary()) -> any().
-spec stop_modules(binary()) -> ok.
stop_modules(Host) ->
Modules = get_modules_options(Host),