aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Nilsson <[email protected]>2017-03-23 16:53:53 +0100
committerHans Nilsson <[email protected]>2017-04-07 10:23:35 +0200
commit8f4bb9b0bd3aed663521371726ea3ec460e231a0 (patch)
tree78957c1854efbe5c556a1f2ef99dcbc72a3ac81a
parent6158cb432092c47e178b4dc1177b46cb8c310ab4 (diff)
downloadotp-8f4bb9b0bd3aed663521371726ea3ec460e231a0.tar.gz
otp-8f4bb9b0bd3aed663521371726ea3ec460e231a0.tar.bz2
otp-8f4bb9b0bd3aed663521371726ea3ec460e231a0.zip
ssh: Mappify supervisors
-rw-r--r--lib/ssh/src/ssh_acceptor_sup.erl30
-rw-r--r--lib/ssh/src/ssh_connection_sup.erl28
-rw-r--r--lib/ssh/src/ssh_subsystem_sup.erl39
-rw-r--r--lib/ssh/src/ssh_sup.erl30
-rw-r--r--lib/ssh/src/ssh_system_sup.erl159
-rw-r--r--lib/ssh/src/sshc_sup.erl35
-rw-r--r--lib/ssh/src/sshd_sup.erl73
7 files changed, 190 insertions, 204 deletions
diff --git a/lib/ssh/src/ssh_acceptor_sup.erl b/lib/ssh/src/ssh_acceptor_sup.erl
index 4606107f56..3ad842f98c 100644
--- a/lib/ssh/src/ssh_acceptor_sup.erl
+++ b/lib/ssh/src/ssh_acceptor_sup.erl
@@ -48,9 +48,12 @@ start_child(AccSup, Address, Port, Profile, Options) ->
Spec = child_spec(Address, Port, Profile, Options),
case supervisor:start_child(AccSup, Spec) of
{error, already_present} ->
+ %% Is this ever called?
stop_child(AccSup, Address, Port, Profile),
supervisor:start_child(AccSup, Spec);
Reply ->
+ %% Reply = {ok,SystemSupPid} when the user calls ssh:daemon
+ %% after having called ssh:stop_listening
Reply
end.
@@ -67,24 +70,27 @@ stop_child(AccSup, Address, Port, Profile) ->
%%% Supervisor callback
%%%=========================================================================
init([Address, Port, Profile, Options]) ->
- RestartStrategy = one_for_one,
- MaxR = 10,
- MaxT = 3600,
- Children = [child_spec(Address, Port, Profile, Options)],
- {ok, {{RestartStrategy, MaxR, MaxT}, Children}}.
+ %% Initial start of ssh_acceptor_sup for this port or new start after
+ %% ssh:stop_daemon
+ SupFlags = #{strategy => one_for_one,
+ intensity => 10,
+ period => 3600
+ },
+ ChildSpecs = [child_spec(Address, Port, Profile, Options)],
+ {ok, {SupFlags,ChildSpecs}}.
%%%=========================================================================
%%% Internal functions
%%%=========================================================================
child_spec(Address, Port, Profile, Options) ->
Timeout = ?GET_INTERNAL_OPT(timeout, Options, ?DEFAULT_TIMEOUT),
- Name = id(Address, Port, Profile),
- StartFunc = {ssh_acceptor, start_link, [Port, Address, Options, Timeout]},
- Restart = transient,
- Shutdown = brutal_kill,
- Modules = [ssh_acceptor],
- Type = worker,
- {Name, StartFunc, Restart, Shutdown, Type, Modules}.
+ #{id => id(Address, Port, Profile),
+ start => {ssh_acceptor, start_link, [Port, Address, Options, Timeout]},
+ restart => transient,
+ shutdown => brutal_kill,
+ type => worker,
+ modules => [ssh_acceptor]
+ }.
id(Address, Port, Profile) ->
{ssh_acceptor_sup, Address, Port, Profile}.
diff --git a/lib/ssh/src/ssh_connection_sup.erl b/lib/ssh/src/ssh_connection_sup.erl
index 0f54053f52..fad796f196 100644
--- a/lib/ssh/src/ssh_connection_sup.erl
+++ b/lib/ssh/src/ssh_connection_sup.erl
@@ -45,19 +45,17 @@ start_child(Sup, Args) ->
%%%=========================================================================
%%% Supervisor callback
%%%=========================================================================
--spec init( [term()] ) -> {ok,{supervisor:sup_flags(),[supervisor:child_spec()]}} | ignore .
-
init(_) ->
- RestartStrategy = simple_one_for_one,
- MaxR = 0,
- MaxT = 3600,
-
- Name = undefined, % As simple_one_for_one is used.
- StartFunc = {ssh_connection_handler, start_link, []},
- Restart = temporary, % E.g. should not be restarted
- Shutdown = 4000,
- Modules = [ssh_connection_handler],
- Type = worker,
-
- ChildSpec = {Name, StartFunc, Restart, Shutdown, Type, Modules},
- {ok, {{RestartStrategy, MaxR, MaxT}, [ChildSpec]}}.
+ SupFlags = #{strategy => simple_one_for_one,
+ intensity => 0,
+ period => 3600
+ },
+ ChildSpecs = [#{id => undefined, % As simple_one_for_one is used.
+ start => {ssh_connection_handler, start_link, []},
+ restart => temporary,
+ shutdown => 4000,
+ type => worker,
+ modules => [ssh_connection_handler]
+ }
+ ],
+ {ok, {SupFlags,ChildSpecs}}.
diff --git a/lib/ssh/src/ssh_subsystem_sup.erl b/lib/ssh/src/ssh_subsystem_sup.erl
index c5ab422265..cf409ade6b 100644
--- a/lib/ssh/src/ssh_subsystem_sup.erl
+++ b/lib/ssh/src/ssh_subsystem_sup.erl
@@ -54,11 +54,12 @@ channel_supervisor(SupPid) ->
%%% Supervisor callback
%%%=========================================================================
init([Role, Address, Port, Profile, Options]) ->
- RestartStrategy = one_for_all,
- MaxR = 0,
- MaxT = 3600,
- Children = child_specs(Role, Address, Port, Profile, Options),
- {ok, {{RestartStrategy, MaxR, MaxT}, Children}}.
+ SupFlags = #{strategy => one_for_all,
+ intensity => 0,
+ period => 3600
+ },
+ ChildSpecs = child_specs(Role, Address, Port, Profile, Options),
+ {ok, {SupFlags,ChildSpecs}}.
%%%=========================================================================
%%% Internal functions
@@ -70,22 +71,22 @@ child_specs(server, Address, Port, Profile, Options) ->
ssh_connection_child_spec(server, Address, Port, Profile, Options)].
ssh_connection_child_spec(Role, Address, Port, _Profile, Options) ->
- Name = id(Role, ssh_connection_sup, Address, Port),
- StartFunc = {ssh_connection_sup, start_link, [Options]},
- Restart = temporary,
- Shutdown = 5000,
- Modules = [ssh_connection_sup],
- Type = supervisor,
- {Name, StartFunc, Restart, Shutdown, Type, Modules}.
+ #{id => id(Role, ssh_connection_sup, Address, Port),
+ start => {ssh_connection_sup, start_link, [Options]},
+ restart => temporary,
+ shutdown => 5000,
+ type => supervisor,
+ modules => [ssh_connection_sup]
+ }.
ssh_channel_child_spec(Role, Address, Port, _Profile, Options) ->
- Name = id(Role, ssh_channel_sup, Address, Port),
- StartFunc = {ssh_channel_sup, start_link, [Options]},
- Restart = temporary,
- Shutdown = infinity,
- Modules = [ssh_channel_sup],
- Type = supervisor,
- {Name, StartFunc, Restart, Shutdown, Type, Modules}.
+ #{id => id(Role, ssh_channel_sup, Address, Port),
+ start => {ssh_channel_sup, start_link, [Options]},
+ restart => temporary,
+ shutdown => infinity,
+ type => supervisor,
+ modules => [ssh_channel_sup]
+ }.
id(Role, Sup, Address, Port) ->
{Role, Sup, Address, Port}.
diff --git a/lib/ssh/src/ssh_sup.erl b/lib/ssh/src/ssh_sup.erl
index 5463401dcd..6be809b1bd 100644
--- a/lib/ssh/src/ssh_sup.erl
+++ b/lib/ssh/src/ssh_sup.erl
@@ -32,19 +32,19 @@
%%% Supervisor callback
%%%=========================================================================
init(_) ->
- SupFlags = {one_for_one, 10, 3600},
- Children = [child_spec(sshd_sup), child_spec(sshc_sup)], %%children(),
- {ok, {SupFlags, Children}}.
-
-%%%=========================================================================
-%%% Internal functions
-%%%=========================================================================
-child_spec(Name) ->
- StartFunc = {Name, start_link, []},
- Restart = permanent,
- Shutdown = infinity,
- Modules = [Name],
- Type = supervisor,
- {Name, StartFunc, Restart, Shutdown, Type, Modules}.
-
+ SupFlags = #{strategy => one_for_one,
+ intensity => 10,
+ period => 3600
+ },
+ ChildSpecs = [#{id => Module,
+ start => {Module, start_link, []},
+ restart => permanent,
+ shutdown => brutal_kill,
+ type => supervisor,
+ modules => [Module]
+ }
+ || Module <- [sshd_sup,
+ sshc_sup]
+ ],
+ {ok, {SupFlags,ChildSpecs}}.
diff --git a/lib/ssh/src/ssh_system_sup.erl b/lib/ssh/src/ssh_system_sup.erl
index a923b5ef71..84b4cd3241 100644
--- a/lib/ssh/src/ssh_system_sup.erl
+++ b/lib/ssh/src/ssh_system_sup.erl
@@ -21,7 +21,7 @@
%%
%%----------------------------------------------------------------------
%% Purpose: The ssh server instance supervisor, an instans of this supervisor
-%% exists for every ip-address and port combination, hangs under
+%% exists for every ip-address and port combination, hangs under
%% sshd_sup.
%%----------------------------------------------------------------------
@@ -34,58 +34,100 @@
-export([start_link/4, stop_listener/1,
stop_listener/3, stop_system/1,
stop_system/3, system_supervisor/3,
- subsystem_supervisor/1, channel_supervisor/1,
- connection_supervisor/1,
- acceptor_supervisor/1, start_subsystem/6, restart_subsystem/3,
- restart_acceptor/3, stop_subsystem/2]).
+ subsystem_supervisor/1, channel_supervisor/1,
+ connection_supervisor/1,
+ acceptor_supervisor/1, start_subsystem/6,
+ stop_subsystem/2]).
%% Supervisor callback
-export([init/1]).
%%%=========================================================================
-%%% Internal API
+%%% API
%%%=========================================================================
start_link(Address, Port, Profile, Options) ->
Name = make_name(Address, Port, Profile),
supervisor:start_link({local, Name}, ?MODULE, [Address, Port, Profile, Options]).
-stop_listener(SysSup) ->
- stop_acceptor(SysSup).
+%%%=========================================================================
+%%% Supervisor callback
+%%%=========================================================================
+init([Address, Port, Profile, Options]) ->
+ SupFlags = #{strategy => one_for_one,
+ intensity => 0,
+ period => 3600
+ },
+ ChildSpecs =
+ case ?GET_INTERNAL_OPT(connected_socket,Options,undefined) of
+ undefined ->
+ [#{id => id(ssh_acceptor_sup, Address, Port, Profile),
+ start => {ssh_acceptor_sup, start_link, [Address, Port, Profile, Options]},
+ restart => transient,
+ shutdown => infinity,
+ type => supervisor,
+ modules => [ssh_acceptor_sup]
+ }];
+ _ ->
+ []
+ end,
+ {ok, {SupFlags,ChildSpecs}}.
+
+%%%=========================================================================
+%%% Service API
+%%%=========================================================================
+stop_listener(SystemSup) ->
+ {Name, AcceptorSup, _, _} = lookup(ssh_acceptor_sup, SystemSup),
+ case supervisor:terminate_child(AcceptorSup, Name) of
+ ok ->
+ supervisor:delete_child(AcceptorSup, Name);
+ Error ->
+ Error
+ end.
stop_listener(Address, Port, Profile) ->
- Name = make_name(Address, Port, Profile),
- stop_acceptor(whereis(Name)).
-
+ stop_listener(
+ system_supervisor(Address, Port, Profile)).
+
+
stop_system(SysSup) ->
- Name = sshd_sup:system_name(SysSup),
- spawn(fun() -> sshd_sup:stop_child(Name) end),
+ spawn(fun() -> sshd_sup:stop_child(SysSup) end),
ok.
-stop_system(Address, Port, Profile) ->
+stop_system(Address, Port, Profile) ->
spawn(fun() -> sshd_sup:stop_child(Address, Port, Profile) end),
ok.
+
system_supervisor(Address, Port, Profile) ->
Name = make_name(Address, Port, Profile),
whereis(Name).
subsystem_supervisor(SystemSup) ->
- ssh_subsystem_sup(supervisor:which_children(SystemSup)).
+ {_, Child, _, _} = lookup(ssh_subsystem_sup, SystemSup),
+ Child.
channel_supervisor(SystemSup) ->
- SubSysSup = ssh_subsystem_sup(supervisor:which_children(SystemSup)),
- ssh_subsystem_sup:channel_supervisor(SubSysSup).
+ ssh_subsystem_sup:channel_supervisor(
+ subsystem_supervisor(SystemSup)).
connection_supervisor(SystemSup) ->
- SubSysSup = ssh_subsystem_sup(supervisor:which_children(SystemSup)),
- ssh_subsystem_sup:connection_supervisor(SubSysSup).
+ ssh_subsystem_sup:connection_supervisor(
+ subsystem_supervisor(SystemSup)).
acceptor_supervisor(SystemSup) ->
- ssh_acceptor_sup(supervisor:which_children(SystemSup)).
+ {_, Child, _, _} = lookup(ssh_acceptor_sup, SystemSup),
+ Child.
+
start_subsystem(SystemSup, Role, Address, Port, Profile, Options) ->
- Spec = ssh_subsystem_child_spec(Role, Address, Port, Profile, Options),
- supervisor:start_child(SystemSup, Spec).
+ SubsystemSpec =
+ #{id => make_ref(),
+ start => {ssh_subsystem_sup, start_link, [Role, Address, Port, Profile, Options]},
+ restart => temporary,
+ shutdown => infinity,
+ type => supervisor,
+ modules => [ssh_subsystem_sup]},
+ supervisor:start_child(SystemSup, SubsystemSpec).
stop_subsystem(SystemSup, SubSys) ->
case catch lists:keyfind(SubSys, 2, supervisor:which_children(SystemSup)) of
@@ -103,60 +145,9 @@ stop_subsystem(SystemSup, SubSys) ->
ok
end.
-
-restart_subsystem(Address, Port, Profile) ->
- SysSupName = make_name(Address, Port, Profile),
- SubSysName = id(ssh_subsystem_sup, Address, Port, Profile),
- case supervisor:terminate_child(SysSupName, SubSysName) of
- ok ->
- supervisor:restart_child(SysSupName, SubSysName);
- Error ->
- Error
- end.
-
-restart_acceptor(Address, Port, Profile) ->
- SysSupName = make_name(Address, Port, Profile),
- AcceptorName = id(ssh_acceptor_sup, Address, Port, Profile),
- supervisor:restart_child(SysSupName, AcceptorName).
-
-%%%=========================================================================
-%%% Supervisor callback
-%%%=========================================================================
-init([Address, Port, Profile, Options]) ->
- RestartStrategy = one_for_one,
- MaxR = 0,
- MaxT = 3600,
- Children = case ?GET_INTERNAL_OPT(connected_socket,Options,undefined) of
- undefined -> child_specs(Address, Port, Profile, Options);
- _ -> []
- end,
- {ok, {{RestartStrategy, MaxR, MaxT}, Children}}.
-
%%%=========================================================================
%%% Internal functions
%%%=========================================================================
-child_specs(Address, Port, Profile, Options) ->
- [ssh_acceptor_child_spec(Address, Port, Profile, Options)].
-
-ssh_acceptor_child_spec(Address, Port, Profile, Options) ->
- Name = id(ssh_acceptor_sup, Address, Port, Profile),
- StartFunc = {ssh_acceptor_sup, start_link, [Address, Port, Profile, Options]},
- Restart = transient,
- Shutdown = infinity,
- Modules = [ssh_acceptor_sup],
- Type = supervisor,
- {Name, StartFunc, Restart, Shutdown, Type, Modules}.
-
-ssh_subsystem_child_spec(Role, Address, Port, Profile, Options) ->
- Name = make_ref(),
- StartFunc = {ssh_subsystem_sup, start_link, [Role, Address, Port, Profile, Options]},
- Restart = temporary,
- Shutdown = infinity,
- Modules = [ssh_subsystem_sup],
- Type = supervisor,
- {Name, StartFunc, Restart, Shutdown, Type, Modules}.
-
-
id(Sup, Address, Port, Profile) ->
{Sup, Address, Port, Profile}.
@@ -168,23 +159,7 @@ fmt_host(A) when is_atom(A) -> A;
fmt_host(S) when is_list(S) -> S.
-ssh_subsystem_sup([{_, Child, _, [ssh_subsystem_sup]} | _]) ->
- Child;
-ssh_subsystem_sup([_ | Rest]) ->
- ssh_subsystem_sup(Rest).
-
-ssh_acceptor_sup([{_, Child, _, [ssh_acceptor_sup]} | _]) ->
- Child;
-ssh_acceptor_sup([_ | Rest]) ->
- ssh_acceptor_sup(Rest).
+lookup(SupModule, SystemSup) ->
+ lists:keyfind([SupModule], 4,
+ supervisor:which_children(SystemSup)).
-stop_acceptor(Sup) ->
- [{Name, AcceptorSup}] =
- [{SupName, ASup} || {SupName, ASup, _, [ssh_acceptor_sup]} <-
- supervisor:which_children(Sup)],
- case supervisor:terminate_child(AcceptorSup, Name) of
- ok ->
- supervisor:delete_child(AcceptorSup, Name);
- Error ->
- Error
- end.
diff --git a/lib/ssh/src/sshc_sup.erl b/lib/ssh/src/sshc_sup.erl
index 9aab9d57e9..c71b81dc6d 100644
--- a/lib/ssh/src/sshc_sup.erl
+++ b/lib/ssh/src/sshc_sup.erl
@@ -32,18 +32,20 @@
%% Supervisor callback
-export([init/1]).
+-define(SSHC_SUP, ?MODULE).
+
%%%=========================================================================
%%% API
%%%=========================================================================
start_link() ->
- supervisor:start_link({local, ?MODULE}, ?MODULE, []).
+ supervisor:start_link({local,?SSHC_SUP}, ?MODULE, []).
start_child(Args) ->
supervisor:start_child(?MODULE, Args).
stop_child(Client) ->
spawn(fun() ->
- ClientSup = whereis(?MODULE),
+ ClientSup = whereis(?SSHC_SUP),
supervisor:terminate_child(ClientSup, Client)
end),
ok.
@@ -52,19 +54,16 @@ stop_child(Client) ->
%%% Supervisor callback
%%%=========================================================================
init(_) ->
- RestartStrategy = simple_one_for_one,
- MaxR = 0,
- MaxT = 3600,
- {ok, {{RestartStrategy, MaxR, MaxT}, [child_spec()]}}.
-
-%%%=========================================================================
-%%% Internal functions
-%%%=========================================================================
-child_spec() ->
- Name = undefined, % As simple_one_for_one is used.
- StartFunc = {ssh_connection_handler, start_link, []},
- Restart = temporary,
- Shutdown = 4000,
- Modules = [ssh_connection_handler],
- Type = worker,
- {Name, StartFunc, Restart, Shutdown, Type, Modules}.
+ SupFlags = #{strategy => simple_one_for_one,
+ intensity => 0,
+ period => 3600
+ },
+ ChildSpecs = [#{id => undefined, % As simple_one_for_one is used.
+ start => {ssh_connection_handler, start_link, []},
+ restart => temporary,
+ shutdown => 4000,
+ type => worker,
+ modules => [ssh_connection_handler]
+ }
+ ],
+ {ok, {SupFlags,ChildSpecs}}.
diff --git a/lib/ssh/src/sshd_sup.erl b/lib/ssh/src/sshd_sup.erl
index d4805e9465..449ba20d02 100644
--- a/lib/ssh/src/sshd_sup.erl
+++ b/lib/ssh/src/sshd_sup.erl
@@ -19,7 +19,7 @@
%%
%%
%%----------------------------------------------------------------------
-%% Purpose: The top supervisor for ssh servers hangs under
+%% Purpose: The top supervisor for ssh servers hangs under
%% ssh_sup.
%%----------------------------------------------------------------------
@@ -29,72 +29,79 @@
-include("ssh.hrl").
--export([start_link/0,
+-export([start_link/0,
start_child/4,
stop_child/1,
- stop_child/3,
- system_name/1]).
+ stop_child/3
+]).
%% Supervisor callback
-export([init/1]).
+-define(SSHD_SUP, ?MODULE).
+
%%%=========================================================================
%%% API
%%%=========================================================================
start_link() ->
- supervisor:start_link({local, ?MODULE}, ?MODULE, []).
+ %% No children are start now. We wait until the user calls ssh:daemon
+ %% and uses start_child/4 to create the children
+ supervisor:start_link({local,?SSHD_SUP}, ?MODULE, []).
start_child(Address, Port, Profile, Options) ->
-io:format("~p:~p ~p:~p~n",[?MODULE,?LINE,Address, Port]),
case ssh_system_sup:system_supervisor(Address, Port, Profile) of
undefined ->
-io:format("~p:~p undefined~n",[?MODULE,?LINE]),
+ %% Here we start listening on a new Host/Port/Profile
Spec = child_spec(Address, Port, Profile, Options),
- Reply = supervisor:start_child(?MODULE, Spec),
-io:format("~p:~p Reply=~p~n",[?MODULE,?LINE,Reply]),
- Reply;
+ supervisor:start_child(?SSHD_SUP, Spec);
Pid ->
-io:format("~p:~p Pid=~p~n",[?MODULE,?LINE,Pid]),
+ %% Here we resume listening on a new Host/Port/Profile after
+ %% haveing stopped listening to he same with ssh:stop_listen(Pid)
AccPid = ssh_system_sup:acceptor_supervisor(Pid),
ssh_acceptor_sup:start_child(AccPid, Address, Port, Profile, Options),
{ok,Pid}
end.
-stop_child(Name) ->
- supervisor:terminate_child(?MODULE, Name).
+stop_child(ChildId) when is_tuple(ChildId) ->
+ supervisor:terminate_child(?SSHD_SUP, ChildId);
+stop_child(ChildPid) when is_pid(ChildPid)->
+ stop_child(system_name(ChildPid)).
-stop_child(Address, Port, Profile) ->
- Name = id(Address, Port, Profile),
- stop_child(Name).
-system_name(SysSup) ->
- Children = supervisor:which_children(sshd_sup),
- system_name(SysSup, Children).
+stop_child(Address, Port, Profile) ->
+ Id = id(Address, Port, Profile),
+ stop_child(Id).
%%%=========================================================================
%%% Supervisor callback
%%%=========================================================================
init(_) ->
- {ok, {{one_for_one, 10, 3600}, []}}.
+ SupFlags = #{strategy => one_for_one,
+ intensity => 10,
+ period => 3600
+ },
+ ChildSpecs = [
+ ],
+ {ok, {SupFlags,ChildSpecs}}.
%%%=========================================================================
%%% Internal functions
%%%=========================================================================
child_spec(Address, Port, Profile, Options) ->
- Name = id(Address, Port,Profile),
- StartFunc = {ssh_system_sup, start_link, [Address, Port, Profile, Options]},
- Restart = temporary,
- Shutdown = infinity,
- Modules = [ssh_system_sup],
- Type = supervisor,
- {Name, StartFunc, Restart, Shutdown, Type, Modules}.
+ #{id => id(Address, Port, Profile),
+ start => {ssh_system_sup, start_link, [Address, Port, Profile, Options]},
+ restart => temporary,
+ shutdown => infinity,
+ type => supervisor,
+ modules => [ssh_system_sup]
+ }.
id(Address, Port, Profile) ->
{server, ssh_system_sup, Address, Port, Profile}.
-system_name([], _ ) ->
- undefined;
-system_name(SysSup, [{Name, SysSup, _, _} | _]) ->
- Name;
-system_name(SysSup, [_ | Rest]) ->
- system_name(SysSup, Rest).
+system_name(SysSup) ->
+ case lists:keyfind(SysSup, 2, supervisor:which_children(?SSHD_SUP)) of
+ {Name, SysSup, _, _} -> Name;
+ false -> undefind
+ end.
+