diff options
Diffstat (limited to 'lib/ssh/src/ssh_connection.erl')
-rw-r--r-- | lib/ssh/src/ssh_connection.erl | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/lib/ssh/src/ssh_connection.erl b/lib/ssh/src/ssh_connection.erl index 64d2113125..a34478732c 100644 --- a/lib/ssh/src/ssh_connection.erl +++ b/lib/ssh/src/ssh_connection.erl @@ -662,7 +662,7 @@ handle_msg(#ssh_msg_channel_request{recipient_channel = ChannelId, ReplyMsg = {subsystem, ChannelId, WantReply, binary_to_list(SsName)}, try - {ok, Pid} = start_subsytem(SsName, Connection, Channel0, ReplyMsg), + {ok, Pid} = start_subsystem(SsName, Connection, Channel0, ReplyMsg), erlang:monitor(process, Pid), Channel = Channel0#channel{user = Pid}, ssh_channel:cache_update(Cache, Channel), @@ -935,14 +935,27 @@ encode_ip(Addr) when is_list(Addr) -> end end. -start_channel(Cb, Id, Args, SubSysSup) -> - start_channel(Cb, Id, Args, SubSysSup, undefined). +start_channel(Cb, Id, Args, SubSysSup, Opts) -> + start_channel(Cb, Id, Args, SubSysSup, undefined, Opts). -start_channel(Cb, Id, Args, SubSysSup, Exec) -> +start_channel(Cb, Id, Args, SubSysSup, Exec, Opts) -> ChildSpec = child_spec(Cb, Id, Args, Exec), ChannelSup = ssh_subsystem_sup:channel_supervisor(SubSysSup), + assert_limit_num_channels_not_exceeded(ChannelSup, Opts), ssh_channel_sup:start_child(ChannelSup, ChildSpec). +assert_limit_num_channels_not_exceeded(ChannelSup, Opts) -> + MaxNumChannels = proplists:get_value(max_channels, Opts, infinity), + NumChannels = length([x || {_,_,worker,[ssh_channel]} <- + supervisor:which_children(ChannelSup)]), + if + %% Note that NumChannels is BEFORE starting a new one + NumChannels < MaxNumChannels -> + ok; + true -> + throw(max_num_channels_exceeded) + end. + %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- @@ -998,17 +1011,19 @@ child_spec(Callback, Id, Args, Exec) -> start_cli(#connection{cli_spec = no_cli}, _) -> {error, cli_disabled}; -start_cli(#connection{cli_spec = {CbModule, Args}, exec = Exec, +start_cli(#connection{options = Options, + cli_spec = {CbModule, Args}, + exec = Exec, sub_system_supervisor = SubSysSup}, ChannelId) -> - start_channel(CbModule, ChannelId, Args, SubSysSup, Exec). + start_channel(CbModule, ChannelId, Args, SubSysSup, Exec, Options). -start_subsytem(BinName, #connection{options = Options, +start_subsystem(BinName, #connection{options = Options, sub_system_supervisor = SubSysSup}, #channel{local_id = ChannelId}, _ReplyMsg) -> Name = binary_to_list(BinName), case check_subsystem(Name, Options) of {Callback, Opts} when is_atom(Callback), Callback =/= none -> - start_channel(Callback, ChannelId, Opts, SubSysSup); + start_channel(Callback, ChannelId, Opts, SubSysSup, Options); {Other, _} when Other =/= none -> {error, legacy_option_not_supported} end. |