1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2008-2018. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20 21%% 22%%---------------------------------------------------------------------- 23%% Purpose: Ssh channel supervisor. 24%%---------------------------------------------------------------------- 25-module(ssh_channel_sup). 26 27-behaviour(supervisor). 28-include("ssh.hrl"). 29 30-export([start_link/1, start_child/8]). 31 32%% Supervisor callback 33-export([init/1]). 34 35%%%========================================================================= 36%%% Internal API 37%%%========================================================================= 38start_link(Args) -> 39 supervisor:start_link(?MODULE, [Args]). 40 41 42start_child(client, ChannelSup, ConnRef, Callback, Id, Args, Exec, _Opts) when is_pid(ConnRef) -> 43 start_the_child(ssh_client_channel, ChannelSup, ConnRef, Callback, Id, Args, Exec); 44start_child(server, ChannelSup, ConnRef, Callback, Id, Args, Exec, Opts) when is_pid(ConnRef) -> 45 case max_num_channels_not_exceeded(ChannelSup, Opts) of 46 true -> 47 start_the_child(ssh_server_channel, ChannelSup, ConnRef, Callback, Id, Args, Exec); 48 false -> 49 {error, max_num_channels_exceeded} 50 end. 51 52 53start_the_child(ChanMod, ChannelSup, ConnRef, Callback, Id, Args, Exec) -> 54 ChildSpec = 55 #{id => make_ref(), 56 start => {ChanMod, start_link, [ConnRef, Id, Callback, Args, Exec]}, 57 restart => temporary, 58 type => worker, 59 modules => [ChanMod] 60 }, 61 case supervisor:start_child(ChannelSup, ChildSpec) of 62 {ok, Pid} -> 63 {ok, Pid}; 64 {ok, Pid, _Info} -> 65 {ok,Pid}; 66 {error, {Error,_Info}} -> 67 {error, Error}; 68 {error, Error} -> 69 {error, Error} 70 end. 71 72%%%========================================================================= 73%%% Supervisor callback 74%%%========================================================================= 75init(_Args) -> 76 RestartStrategy = one_for_one, 77 MaxR = 10, 78 MaxT = 3600, 79 Children = [], 80 {ok, {{RestartStrategy, MaxR, MaxT}, Children}}. 81 82%%%========================================================================= 83%%% Internal functions 84%%%========================================================================= 85max_num_channels_not_exceeded(ChannelSup, Opts) -> 86 MaxNumChannels = ?GET_OPT(max_channels, Opts), 87 NumChannels = length([x || {_,_,worker,[ssh_server_channel]} <- 88 supervisor:which_children(ChannelSup)]), 89 %% Note that NumChannels is BEFORE starting a new one 90 NumChannels < MaxNumChannels. 91