diff options
| author | Hans Nilsson <[email protected]> | 2016-03-30 17:37:12 +0200 | 
|---|---|---|
| committer | Hans Nilsson <[email protected]> | 2016-03-30 17:37:12 +0200 | 
| commit | e88b37d27cae4e823ece1ba8d94ecea4a49b824e (patch) | |
| tree | b74de06cca7472d2099781fff56df0003eb6a0f1 | |
| parent | d166fec5d5c901a93e21a1ea7b3165b6fe68d320 (diff) | |
| parent | fb8f1f1b53f57744c86e60ee6b02d8d86d298fdf (diff) | |
| download | otp-e88b37d27cae4e823ece1ba8d94ecea4a49b824e.tar.gz otp-e88b37d27cae4e823ece1ba8d94ecea4a49b824e.tar.bz2 otp-e88b37d27cae4e823ece1ba8d94ecea4a49b824e.zip | |
Merge branch 'hans/ssh/ssh_info_additions'
| -rw-r--r-- | lib/ssh/src/ssh_info.erl | 288 | 
1 files changed, 173 insertions, 115 deletions
| diff --git a/lib/ssh/src/ssh_info.erl b/lib/ssh/src/ssh_info.erl index 2dfc55cd92..67130d5eac 100644 --- a/lib/ssh/src/ssh_info.erl +++ b/lib/ssh/src/ssh_info.erl @@ -31,134 +31,168 @@  	 collect_pids/0  	]). +-include("ssh_connect.hrl"). +  print() -> -    print(user). +    io:format("~s", [string()]). +print(File) when is_list(File) -> +    {ok,D} = file:open(File, write), +    print(D), +    file:close(D);  print(D) -> +    io:format(D, "~s", [string()]). + +string() ->      try supervisor:which_children(ssh_sup)      of  	_ -> -	    io__nl(D), -	    print_general(D), -	    io__nl(D), -	    underline(D, "Client part", $=), -	    print_clients(D), -	    io__nl(D), -	    underline(D, "Server part", $=), -	    print_servers(D), -	    io__nl(D), -	    underline(D, "Supervisors", $=), -	    walk_sups(D, ssh_sup), -	    io__nl(D) +	    [io_lib:nl(), +	     print_general(), +	     io_lib:nl(), +	     underline("Client part", $=), +	     print_clients(), +	     io_lib:nl(), +	     underline("Server part", $=), +	     print_servers(), +	     io_lib:nl(), +	     underline("Supervisors", $=), +	     walk_sups(ssh_sup), +	     io_lib:nl()]      catch  	_:_ -> -	    io__format(D,"Ssh not found~n",[]) +	    io_lib:format("Ssh not found~n",[])      end. -string() -> -    Pid = spawn(fun init/0), -    print(Pid), -    Pid ! {get,self()}, -    receive -	{result,R} -> R -    end. - -%%%================================================================ -print_general(D) -> -    {_Name, Slogan, Ver} = lists:keyfind(ssh,1,application:which_applications()), -    underline(D, io_lib:format("~s  ~s", [Slogan, Ver]), $=), -    io__format(D, 'This printout is generated ~s. ~n',[datetime()]).  %%%================================================================  -define(INDENT, "    "). -print_clients(D) -> -    PrintClient = fun(X) -> print_client(D,X) end, +print_general() -> +    {_Name, Slogan, Ver} = lists:keyfind(ssh,1,application:which_applications()), +    [underline(io_lib:format("~s  ~s", [Slogan, Ver]), $=), +     io_lib:format('This printout is generated ~s. ~n',[datetime()]) +    ]. + +print_clients() ->      try -	lists:foreach(PrintClient, supervisor:which_children(sshc_sup)) +	lists:map(fun print_client/1, +		  supervisor:which_children(sshc_sup))      catch  	C:E -> -	    io__format(D, '***FAILED: ~p:~p~n',[C,E]) +	    io_lib:format('***print_clients FAILED: ~p:~p~n',[C,E])      end. -print_client(D, {undefined,Pid,supervisor,[ssh_connection_handler]}) -> +print_client({undefined,Pid,supervisor,[ssh_connection_handler]}) ->      {{Local,Remote},_Str} = ssh_connection_handler:get_print_info(Pid), -    io__format(D, ?INDENT"Local: ~s  Remote: ~s  ConnectionRef = ~p~n",[fmt_host_port(Local),fmt_host_port(Remote),Pid]); -print_client(D, Other) -> -    io__format(D, "    [[Other 1: ~p]]~n",[Other]). +    [io_lib:format(?INDENT"Local: ~s  Remote: ~s  ConnectionRef = ~p~n", +		   [fmt_host_port(Local), fmt_host_port(Remote), Pid]), +     case channels(Pid) of +	 {ok,Channels=[_|_]} -> +	     [print_ch(ChPid) || #channel{user=ChPid} <- Channels]; +	_ -> +	    io_lib:format(?INDENT?INDENT?INDENT"No channels~n",[]) +     end]; + +print_client(Other) -> +    io_lib:format("    [[Other 1: ~p]]~n",[Other]).  %%%================================================================ -print_servers(D) -> -    PrintServer = fun(X) -> print_server(D,X) end, +print_servers() ->      try -	lists:foreach(PrintServer, supervisor:which_children(sshd_sup)) +	lists:map(fun print_server/1, +		  supervisor:which_children(sshd_sup))      catch  	C:E -> -	    io__format(D, '***FAILED: ~p:~p~n',[C,E]) +	    io_lib:format('***print_servers FAILED: ~p:~p~n',[C,E])      end. -print_server(D, {{server,ssh_system_sup,LocalHost,LocalPort,Profile},Pid,supervisor,[ssh_system_sup]}) when is_pid(Pid) -> -    io__format(D, ?INDENT"Listen: ~s (~p children) Profile ~p~n",[fmt_host_port({LocalHost,LocalPort}), -								  ssh_acceptor:number_of_connections(Pid), -								  Profile]), -    PrintSystemSup = fun(X) -> print_system_sup(D,X) end, -    lists:foreach(PrintSystemSup, supervisor:which_children(Pid)). +print_server({{server,ssh_system_sup,LocalHost,LocalPort,Profile},Pid,supervisor,[ssh_system_sup]}) when is_pid(Pid) -> +    Children = supervisor:which_children(Pid), +    [io_lib:format(?INDENT"Listen: ~s (~p children) Profile ~p",[fmt_host_port({LocalHost,LocalPort}), +								 ssh_acceptor:number_of_connections(Pid), +								 Profile]), +     case [AccPid  +	   || {{ssh_acceptor_sup,_LocalHost,_LocalPort,_Profile}, AccPid, supervisor, [ssh_acceptor_sup]}  +		  <- Children] of +	 AcceptorPids = [_|_] -> +	     [io_lib:format("  [Acceptor Pid", []), +	      [io_lib:format(" ~p",[AccPid]) || AccPid <- AcceptorPids], +	      io_lib:format("]~n", []) +	     ]; +	 [] -> +	     io_lib:nl() +     end, +     lists:map(fun print_system_sup/1, +	       supervisor:which_children(Pid)) +    ]. + + +print_system_sup({Ref,Pid,supervisor,[ssh_subsystem_sup]}) when is_reference(Ref), +								is_pid(Pid) -> +    lists:map(fun print_channels/1, +		  supervisor:which_children(Pid)); +print_system_sup({{ssh_acceptor_sup,_LocalHost,_LocalPort,_Profile}, Pid, supervisor, [ssh_acceptor_sup]}) when is_pid(Pid) -> +    []. -print_system_sup(D, {Ref,Pid,supervisor,[ssh_subsystem_sup]}) when is_reference(Ref), -								   is_pid(Pid) -> -    PrintChannels =  fun(X) -> print_channels(D,X) end, -    lists:foreach(PrintChannels, supervisor:which_children(Pid)); -print_system_sup(D, {{ssh_acceptor_sup,_LocalHost,_LocalPort,_Profile}, Pid, supervisor, [ssh_acceptor_sup]}) when is_pid(Pid) -> -    io__format(D, ?INDENT?INDENT"[Acceptor Pid ~p]~n",[Pid]). -print_channels(D, {{server,ssh_channel_sup,_,_},Pid,supervisor,[ssh_channel_sup]}) when is_pid(Pid) -> +print_channels({{server,ssh_channel_sup,_,_},Pid,supervisor,[ssh_channel_sup]}) when is_pid(Pid) ->      Children =  supervisor:which_children(Pid),      ChannelPids = [P || {R,P,worker,[ssh_channel]} <- Children,  			is_pid(P),  			is_reference(R)],      case ChannelPids of -	[] -> io__format(D, ?INDENT?INDENT"No channels~n",[]); +	[] -> io_lib:format(?INDENT?INDENT"No channels~n",[]);  	[Ch1Pid|_] ->  	    {{ConnManager,_}, _Str} = ssh_channel:get_print_info(Ch1Pid),  	    {{_,Remote},_} = ssh_connection_handler:get_print_info(ConnManager), -	    io__format(D, ?INDENT?INDENT"Remote: ~s ConnectionRef = ~p~n",[fmt_host_port(Remote),ConnManager]), -	    lists:foreach(fun(P) -> print_ch(D,P) end, ChannelPids) +	    [io_lib:format(?INDENT?INDENT"Remote: ~s ConnectionRef = ~p~n",[fmt_host_port(Remote),ConnManager]), +	     lists:map(fun print_ch/1, ChannelPids) +	    ]      end; -print_channels(_D, {{server,ssh_connection_sup,_,_},Pid,supervisor,[ssh_connection_sup]}) when is_pid(Pid) -> -    ok. % The supervisor of the connections socket owning process - -print_ch(D, Pid) ->  -    {{ConnManager,ChannelID}, Str} = ssh_channel:get_print_info(Pid), -    {_LocalRemote,StrM} = ssh_connection_handler:get_print_info(ConnManager), -    io__format(D, ?INDENT?INDENT?INDENT"ch ~p: ~s ~s~n",[ChannelID, StrM, Str]). -     +print_channels({{server,ssh_connection_sup,_,_},Pid,supervisor,[ssh_connection_sup]}) when is_pid(Pid) -> +    []. % The supervisor of the connections socket owning process + +print_ch(Pid) -> +    try +	{{ConnManager,ChannelID}, Str} = ssh_channel:get_print_info(Pid), +	{_LocalRemote,StrM} = ssh_connection_handler:get_print_info(ConnManager), +	io_lib:format(?INDENT?INDENT?INDENT"ch ~p ~p: ~s ~s~n",[ChannelID, Pid, StrM, Str]) +    catch +	C:E -> +	    io_lib:format('****print_ch FAILED for ChanPid ~p: ~p:~p~n',[Pid, C, E]) +    end. + +  %%%================================================================  -define(inc(N), (N+4)). -walk_sups(D, StartPid) -> -    io__format(D, "Start at ~p, ~s.~n",[StartPid,dead_or_alive(StartPid)]), -    walk_sups(D, children(StartPid), _Indent=?inc(0)). - -walk_sups(D, [H={_,Pid,_,_}|T], Indent) -> -    indent(D, Indent), io__format(D, '~200p  ~p is ~s~n',[H,Pid,dead_or_alive(Pid)]), -    case H of -	{_,_,supervisor,[ssh_connection_handler]} -> ok; -	{_,Pid,supervisor,_} -> walk_sups(D, children(Pid), ?inc(Indent)); -	_ -> ok -    end, -    walk_sups(D, T, Indent); -walk_sups(_D, [], _) -> -    ok. +walk_sups(StartPid) -> +    io_lib:format("Start at ~p, ~s.~n",[StartPid,dead_or_alive(StartPid)]), +    walk_sups(children(StartPid), _Indent=?inc(0)). + +walk_sups([H={_,Pid,_,_}|T], Indent) -> +    [indent(Indent), +     io_lib:format('~200p  ~p is ~s~n',[H,Pid,dead_or_alive(Pid)]), +     case H of +	 {_,_,supervisor,[ssh_connection_handler]} -> ""; +	 {_,Pid,supervisor,_} -> walk_sups(children(Pid), ?inc(Indent)); +	 _ -> "" +     end, +     walk_sups(T, Indent) +    ]; +walk_sups([], _) -> +    "".  dead_or_alive(Name) when is_atom(Name) ->      case whereis(Name) of -	undefined ->  +	undefined ->  	    "**UNDEFINED**"; -	Pid ->  +	Pid ->  	    dead_or_alive(Pid)      end;  dead_or_alive(Pid) when is_pid(Pid) -> @@ -167,7 +201,8 @@ dead_or_alive(Pid) when is_pid(Pid) ->  	_ -> "alive"      end. -indent(D, I) -> io__format(D,'~*c',[I,$ ]).  +indent(I) -> io_lib:format('~*c',[I,$ ]). +  children(Pid) ->      Parent = self(), @@ -178,20 +213,39 @@ children(Pid) ->  	{Helper,L} when is_list(L) ->  	    L      after -	2000 ->  +	2000 ->  	    catch exit(Helper, kill),  	    []      end. +is_connection_handler(Pid) -> +    try +	{ssh_connection_handler,init,_} = +	    proplists:get_value( +	      '$initial_call', +	      proplists:get_value( +		dictionary, +		process_info(Pid, [dictionary]))) +    of +	_ -> true + +    catch +	_:_ -> +	    false +    end. + +channels(Pid) -> +    case is_connection_handler(Pid) of +	true -> +	    ssh_connection_handler:info(Pid,all); +	false -> +	    false +    end. +  %%%================================================================ -underline(D, Str, LineChar) -> -    Len = lists:flatlength(Str), -    io__format(D, '~s~n',[Str]), -    line(D,Len,LineChar). +underline(Str, LineChar) -> +    io_lib:format('~s~n~*c~n',[Str, lists:flatlength(Str), LineChar]). -line(D, Len, Char) -> -    io__format(D, '~*c~n', [Len,Char]). -	      datetime() ->      {{YYYY,MM,DD}, {H,M,S}} = calendar:now_to_universal_time(erlang:timestamp()), @@ -202,28 +256,9 @@ fmt_host_port({{A,B,C,D},Port}) -> io_lib:format('~p.~p.~p.~p:~p',[A,B,C,D,Port]  fmt_host_port({Host,Port}) -> io_lib:format('~s:~p',[Host,Port]).  %%%################################################################ - -io__nl(D) when is_atom(D) -> io:nl(D); -io__nl(P) when is_pid(P) -> P ! {string,io_lib:nl()}. - -io__format(D, Fmt, Args) when is_atom(D) -> io:format(D, Fmt, Args); -io__format(P, Fmt, Args) when is_pid(P) -> P ! {string,io_lib:format(Fmt, Args)}. - - -init() -> loop([]). - -loop(Acc) -> -    receive -	{string,Str} -> -	    loop([Str|Acc]); -	{get,Who} -> -	    Who ! {result,lists:flatten(lists:reverse(Acc))} -    end. -	 -%%%################################################################  collect_pids() -> collect_pids(ssh_sup). -collect_pids(P) ->  +collect_pids(P) ->      Collector = pcollect_pids(P, spawn(fun init_collector/0)),      Collector ! {get_values,self()},      receive @@ -231,7 +266,7 @@ collect_pids(P) ->  	    Values      end. -%%%----------------     +%%%----------------  pcollect_pids(undefined, Collector) ->      Collector; @@ -249,17 +284,43 @@ pcollect_pids(Pid, Collector) when is_pid(Pid) ->  	  end),      Collector; -pcollect_pids({_,Pid,supervisor,_}, Collector) when is_pid(Pid) -> +pcollect_pids({Ref,Pid,supervisor,_}, Collector) when is_pid(Pid), +						      is_reference(Ref) ->      pcollect_pids(Pid, Collector); -pcollect_pids({_,Pid,worker,_}, Collector) when is_pid(Pid) -> +pcollect_pids({sshc_sup,Pid,supervisor,_}, Collector) when is_pid(Pid) -> +    pcollect_pids(Pid, Collector); + +pcollect_pids({sshd_sup,Pid,supervisor,_}, Collector) when is_pid(Pid) -> +    pcollect_pids(Pid, Collector); + +pcollect_pids({{ssh_acceptor_sup,_,_,_},Pid,supervisor,_}, Collector) when is_pid(Pid) -> +    pcollect_pids(Pid, Collector); + +pcollect_pids({{server,_,_,_},Pid,supervisor,_}, Collector) when is_pid(Pid) -> +    pcollect_pids(Pid, Collector); + +pcollect_pids({{server,_,_,_,_},Pid,supervisor,_}, Collector) when is_pid(Pid) -> +    pcollect_pids(Pid, Collector); + +pcollect_pids({undefined,Pid,supervisor,[ssh_connection_handler]}, Collector) -> +    Collector ! {value,Pid,Pid}, +    case channels(Pid) of +	{ok,L} -> +	    [Collector!{value,P,P} || #channel{user=P} <- L]; +	_ -> +	    ok +    end, +    Collector; + +pcollect_pids({_,Pid,_,_}, Collector) when is_pid(Pid) ->      Collector ! {value,Pid,Pid},      Collector;  pcollect_pids(_, Collector) ->      Collector. -%%%----------------     +%%%----------------  init_collector() ->      loop_collector([],[]). @@ -273,6 +334,3 @@ loop_collector(Expects, Values) ->  %%				Values=/=[] ->  	    From ! {values,Values}      end. - -     - | 
