2
%% <year>2008-2008</year>
3
%% <holder>Ericsson AB, All Rights Reserved</holder>
6
%% The contents of this file are subject to the Erlang Public License,
7
%% Version 1.1, (the "License"); you may not use this file except in
8
%% compliance with the License. You should have received a copy of the
9
%% Erlang Public License along with this software. If not, it can be
10
%% retrieved online at http://www.erlang.org/.
12
%% Software distributed under the License is distributed on an "AS IS"
13
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
%% the License for the specific language governing rights and limitations
17
%% The Initial Developer of the Original Code is Ericsson AB.
20
%%----------------------------------------------------------------------
21
%% Purpose: The ssh server instance supervisor, an instans of this supervisor
22
%% exists for every ip-address and port combination, hangs under
24
%%----------------------------------------------------------------------
26
-module(ssh_system_sup).
28
-behaviour(supervisor).
30
-export([start_link/1, stop_listener/1,
31
stop_listener/2, stop_system/1,
32
stop_system/2, system_supervisor/2,
33
subsystem_supervisor/1, channel_supervisor/1,
34
connection_supervisor/1,
35
acceptor_supervisor/1, connection_manager/1,
36
restart_subsystem/2, restart_acceptor/2]).
38
%% Supervisor callback
41
%%%=========================================================================
43
%%%=========================================================================
44
start_link(ServerOpts) ->
45
Address = proplists:get_value(address, ServerOpts),
46
Port = proplists:get_value(port, ServerOpts),
47
Name = make_name(Address, Port),
48
supervisor:start_link({local, Name}, ?MODULE, [ServerOpts]).
50
stop_listener(SysSup) ->
51
stop_acceptor(SysSup).
53
stop_listener(Address, Port) ->
54
Name = make_name(Address, Port),
55
stop_acceptor(whereis(Name)).
57
stop_system(SysSup) ->
58
Name = sshd_sup:system_name(SysSup),
59
sshd_sup:stop_child(Name).
61
stop_system(Address, Port) ->
62
sshd_sup:stop_child(Address, Port).
64
system_supervisor(Address, Port) ->
65
Name = make_name(Address, Port),
68
subsystem_supervisor(SystemSup) ->
69
ssh_subsystem_sup(supervisor:which_children(SystemSup)).
71
connection_manager(SystemSup) ->
72
SubSysSup = ssh_subsystem_sup(supervisor:which_children(SystemSup)),
73
ssh_subsystem_sup:connection_manager(SubSysSup).
75
channel_supervisor(SystemSup) ->
76
SubSysSup = ssh_subsystem_sup(supervisor:which_children(SystemSup)),
77
ssh_subsystem_sup:channel_supervisor(SubSysSup).
79
connection_supervisor(SystemSup) ->
80
SubSysSup = ssh_subsystem_sup(supervisor:which_children(SystemSup)),
81
ssh_subsystem_sup:connection_supervisor(SubSysSup).
83
acceptor_supervisor(SystemSup) ->
84
ssh_acceptor_sup(supervisor:which_children(SystemSup)).
86
restart_subsystem(Address, Port) ->
87
SysSupName = make_name(Address, Port),
88
SubSysName = id(ssh_subsystem_sup, Address, Port),
89
case supervisor:terminate_child(SysSupName, SubSysName) of
91
supervisor:restart_child(SysSupName, SubSysName);
96
restart_acceptor(Address, Port) ->
97
SysSupName = make_name(Address, Port),
98
AcceptorName = id(ssh_acceptor_sup, Address, Port),
99
supervisor:restart_child(SysSupName, AcceptorName).
101
%%%=========================================================================
102
%%% Supervisor callback
103
%%%=========================================================================
104
init([ServerOpts]) ->
105
RestartStrategy = one_for_one,
108
Children = child_specs(ServerOpts),
109
{ok, {{RestartStrategy, MaxR, MaxT}, Children}}.
111
%%%=========================================================================
112
%%% Internal functions
113
%%%=========================================================================
114
child_specs(ServerOpts) ->
115
[ssh_acceptor_child_spec(ServerOpts), ssh_subsystem_child_spec(ServerOpts)].
117
ssh_acceptor_child_spec(ServerOpts) ->
118
Address = proplists:get_value(address, ServerOpts),
119
Port = proplists:get_value(port, ServerOpts),
120
Name = id(ssh_acceptor_sup, Address, Port),
121
StartFunc = {ssh_acceptor_sup, start_link, [ServerOpts]},
124
Modules = [ssh_acceptor_sup],
126
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
128
ssh_subsystem_child_spec(ServerOpts) ->
129
Address = proplists:get_value(address, ServerOpts),
130
Port = proplists:get_value(port, ServerOpts),
131
Name = id(ssh_subsystem_sup, Address, Port),
132
StartFunc = {ssh_subsystem_sup, start_link, [ServerOpts]},
135
Modules = [ssh_subsystem_sup],
137
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
140
id(Sup, Address, Port) ->
141
{Sup, Address, Port}.
143
make_name(Address, Port) ->
144
list_to_atom(lists:flatten(io_lib:format("ssh_system_~p_~p_sup",
147
ssh_subsystem_sup([{_, Child, _, [ssh_subsystem_sup]} | _]) ->
149
ssh_subsystem_sup([_ | Rest]) ->
150
ssh_subsystem_sup(Rest).
152
ssh_acceptor_sup([{_, Child, _, [ssh_acceptor_sup]} | _]) ->
154
ssh_acceptor_sup([_ | Rest]) ->
155
ssh_acceptor_sup(Rest).
157
stop_acceptor(Sup) ->
159
[SupName || {SupName, _, _, [ssh_acceptor_sup]} <-
160
supervisor:which_children(Sup)],
161
supervisor:terminate_child(Sup, Name).