%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 1997-2009. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. %% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. %% %% %CopyrightEnd% %% -module(snmpa_agent_sup). -include("snmp_debug.hrl"). -behaviour(supervisor). %% External exports -export([start_link/0, start_link/1, start_subagent/3, stop_subagent/1]). %% Internal exports -export([init/1]). -define(SERVER, ?MODULE). -ifdef(snmp_debug). -define(DEFAULT_OPTS, [{verbosity, trace}]). -else. -define(DEFAULT_OPTS, []). -endif. %%%----------------------------------------------------------------- %%% This is a supervisor for the mib processes. Each agent has one %%% mib process. %%%----------------------------------------------------------------- start_link() -> ?d("start_link -> entry", []), supervisor:start_link({local, ?SERVER}, ?MODULE, [[]]). start_link(AgentSpec) -> ?d("start_link -> entry with" "~n AgentSpec: ~p", [AgentSpec]), supervisor:start_link({local, ?SERVER}, ?MODULE, [[AgentSpec]]). start_subagent(ParentAgent, Subtree, Mibs) -> ?d("start_subagent -> entry with" "~n ParentAgent: ~p" "~n Subtree: ~p" "~n Mibs: ~p", [ParentAgent, Subtree, Mibs]), Children = supervisor:which_children(?SERVER), ?d("start_subagent -> Children: ~n~p", [Children]), Max = find_max(Children, 1), ?d("start_subagent -> Max: ~p", [Max]), [{_, Prio}] = ets:lookup(snmp_agent_table, priority), ?d("start_subagent -> Prio: ~p", [Prio]), Ref = make_ref(), ?d("start_subagent -> Ref: ~p", [Ref]), Options = [{priority, Prio}, {mibs, Mibs}, {misc_sup, snmpa_misc_sup} | ?DEFAULT_OPTS], Agent = {{sub_agent, Max}, {snmpa_agent, start_link, [Prio, ParentAgent, Ref, Options]}, permanent, 2000, worker, [snmpa_agent]}, case supervisor:start_child(?SERVER, Agent) of {ok, SA} -> ?d("start_subagent -> SA: ~p", [SA]), snmpa_agent:register_subagent(ParentAgent, Subtree, SA), {ok, SA}; Error -> ?d("start_subagent -> Error: ~p", [Error]), Error end. stop_subagent(SubAgentPid) -> case find_name(supervisor:which_children(?SERVER), SubAgentPid) of undefined -> no_such_child; Name -> supervisor:terminate_child(?SERVER, Name), supervisor:delete_child(?SERVER, Name), ok end. init([Children]) -> ?d("init -> entry with" "~n Children: ~p", [Children]), %% 20 restarts in ten minutes. If the agent crashes and restarts, %% it may very well crash again, because the management application %% tries to resend the very same request. This depends on the resend %% strategy used by the management application. SupFlags = {one_for_one, 20, 600}, {ok, {SupFlags, Children}}. find_max([{{sub_agent, N}, _, _, _} | T], M) when N >= M -> find_max(T, N+1); find_max([_|T], M) -> find_max(T, M); find_max([], M) -> M. find_name([{Name, Pid, _, _} | _T], Pid)-> Name; find_name([_|T], Pid) -> find_name(T, Pid); find_name([], _Pid) -> undefined. % i(F) -> % i(F, []). % i(F, A) -> % io:format("~p:~p: " ++ F ++ "~n", [node(),?MODULE|A]).