~clint-fewbar/ubuntu/precise/erlang/merge-15b

« back to all changes in this revision

Viewing changes to lib/snmp/src/agent/snmpa_agent.erl

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-11-06 18:54:42 UTC
  • mfrom: (3.3.4 sid)
  • Revision ID: james.westby@ubuntu.com-20091106185442-bqxb11qghumvmvx2
Tags: 1:13.b.2.1-dfsg-1ubuntu1
* Merge with Debian testing; remaining Ubuntu changes:
  - Drop libwxgtk2.8-dev build dependency. Wx isn't in main, and not
    supposed to. (LP #438365)
  - Drop erlang-wx binary.
  - Drop erlang-wx dependency from -megaco, -common-test, and -reltool, they
    do not really need wx. Also drop it from -debugger; the GUI needs wx,
    but it apparently has CLI bits as well, and is also needed by -megaco,
    so let's keep the package for now.

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
         which_notification_filter/1,
37
37
         get_net_if/1]).
38
38
-export([
39
 
         discovery/5, 
 
39
         discovery/6, 
40
40
         is_originating_discovery_enabled/0,
41
41
         is_terminating_discovery_enabled/0,
42
 
         terminating_discovery_stage2/0
 
42
         terminating_discovery_stage2/0,
 
43
         terminating_trigger_username/0
43
44
        ]).
44
45
-export([verbosity/2, dump_mibs/1, dump_mibs/2]).
45
46
-export([validate_err/3, make_value_a_correct_value/3, 
46
47
         do_get/3, do_get/4, 
47
48
         get/2, get/3, get_next/2, get_next/3]).
48
49
-export([mib_of/1, mib_of/2, me_of/1, me_of/2,
49
 
         invalidate_mibs_cache/1]).
 
50
         invalidate_mibs_cache/1,
 
51
         enable_mibs_cache/1, disable_mibs_cache/1,
 
52
         gc_mibs_cache/1, gc_mibs_cache/2, gc_mibs_cache/3,
 
53
         enable_mibs_cache_autogc/1, disable_mibs_cache_autogc/1,
 
54
         update_mibs_cache_age/2, 
 
55
         update_mibs_cache_gclimit/2]).
50
56
-export([get_agent_mib_storage/0, db/1, 
51
57
         backup/2]).
52
58
-export([get_log_type/1,      set_log_type/2]).
71
77
-define(vt(_F, _A), ok).
72
78
-endif.
73
79
 
 
80
-define(DISCO_TERMINATING_TRIGGER_USERNAME, "").
 
81
 
74
82
 
75
83
-ifdef(snmp_debug).
76
84
-define(GS_START_LINK3(Prio, Parent, Ref, Opts),
91
99
 
92
100
-record(notification_filter, {id, mod, data}).
93
101
-record(disco, 
94
 
        {from, rec, sender, target, sec_level, ctx, ivbs, stage, handler}).
 
102
        {from, rec, sender, target, engine_id, 
 
103
         sec_level, ctx, ivbs, stage, handler, extra}).
95
104
 
96
105
 
97
106
%%-----------------------------------------------------------------
124
133
                net_if,       %% Currently unused
125
134
                net_if_mod,   
126
135
                backup,
127
 
                disco}).
 
136
                disco,
 
137
                mibs_cache_request}).
 
138
 
128
139
 
129
140
%%%-----------------------------------------------------------------
130
141
%%% This module implements the agent machinery; both for the master
211
222
me_of(Agent, Oid) when is_list(Oid) ->
212
223
    call(Agent, {me_of, Oid}).
213
224
 
 
225
 
214
226
invalidate_mibs_cache(Agent) ->
215
 
    call(Agent, invalidate_mibs_cache).
216
 
 
217
 
 
 
227
    call(Agent, {mibs_cache_request, invalidate_cache}).
 
228
 
 
229
 
 
230
gc_mibs_cache(Agent) ->
 
231
    call(Agent, {mibs_cache_request, gc_cache}).
 
232
 
 
233
gc_mibs_cache(Agent, Age) ->
 
234
    call(Agent, {mibs_cache_request, {gc_cache, Age}}).
 
235
 
 
236
gc_mibs_cache(Agent, Age, GcLimit) ->
 
237
    call(Agent, {mibs_cache_request, {gc_cache, Age, GcLimit}}).
 
238
 
 
239
 
 
240
enable_mibs_cache(Agent) ->
 
241
    call(Agent, {mibs_cache_request, enable_cache}).
 
242
 
 
243
disable_mibs_cache(Agent) ->
 
244
    call(Agent, {mibs_cache_request, disable_cache}).
 
245
 
 
246
 
 
247
enable_mibs_cache_autogc(Agent) ->
 
248
    call(Agent, {mibs_cache_request, enable_autogc}).
 
249
 
 
250
disable_mibs_cache_autogc(Agent) ->
 
251
    call(Agent, {mibs_cache_request, disable_autogc}).
 
252
 
 
253
 
 
254
update_mibs_cache_gclimit(Agent, GcLimit) ->
 
255
    call(Agent, {mibs_cache_request, {update_gclimit, GcLimit}}).
 
256
 
 
257
 
 
258
update_mibs_cache_age(Agent, Age) ->
 
259
    call(Agent, {mibs_cache_request, {update_age, Age}}).
218
260
 
219
261
 
220
262
init([Prio, Parent, Ref, Options]) ->
477
519
 
478
520
%% -- Discovery functions --
479
521
 
 
522
disco_opts() ->
 
523
    case ets:lookup(snmp_agent_table, discovery) of
 
524
        [] -> 
 
525
            [];
 
526
        [{discovery, DiscoOptions}] ->
 
527
            DiscoOptions
 
528
    end.
 
529
    
 
530
originating_disco_opts() ->
 
531
    DiscoOpts = disco_opts(),
 
532
    case lists:keysearch(originating, 1, DiscoOpts) of
 
533
        {value, {originating, OrigDisco}} ->
 
534
            OrigDisco;
 
535
        _ ->
 
536
            []
 
537
    end.
 
538
        
480
539
is_originating_discovery_enabled() ->
481
 
    case ets:lookup(snmp_agent_table, discovery) of
482
 
        [] -> % upgrade
483
 
            true;
484
 
        [{discovery, DiscoOptions}] ->
485
 
            case lists:keysearch(originating, 1, DiscoOptions) of
486
 
                {value, {originating, OrigDisco}} ->
487
 
                    case lists:keysearch(enable, 1, OrigDisco) of
488
 
                        {value, {enable, false}} ->
489
 
                            false;
490
 
                        _ ->
491
 
                            true
492
 
                    end;
493
 
                _ ->
494
 
                    true
495
 
            end
 
540
    OrigDisco = originating_disco_opts(), 
 
541
    case lists:keysearch(enable, 1, OrigDisco) of
 
542
        {value, {enable, false}} ->
 
543
            false;
 
544
        _ ->
 
545
            true
496
546
    end.
497
547
    
 
548
terminating_disco_opts() ->
 
549
    DiscoOpts = disco_opts(),
 
550
    case lists:keysearch(terminating, 1, DiscoOpts) of
 
551
        {value, {terminating, TermDisco}} ->
 
552
            TermDisco;
 
553
        _ ->
 
554
            []
 
555
    end.
 
556
        
498
557
is_terminating_discovery_enabled() ->
499
 
    Default = true,
500
 
    case ets:lookup(snmp_agent_table, discovery) of
501
 
        [] -> % upgrade
502
 
            Default;
503
 
        [{discovery, DiscoOptions}] ->
504
 
            case lists:keysearch(terminating, 1, DiscoOptions) of
505
 
                {value, {terminating, TermDisco}} ->
506
 
                    case lists:keysearch(enable, 1, TermDisco) of
507
 
                        {value, {enable, false}} ->
508
 
                            false;
509
 
                        _ ->
510
 
                            Default
511
 
                    end;
512
 
                _ ->
513
 
                    Default
514
 
            end
 
558
    TermDisco = terminating_disco_opts(),
 
559
    case lists:keysearch(enable, 1, TermDisco) of
 
560
        {value, {enable, false}} ->
 
561
            false;
 
562
        _ ->
 
563
            true
515
564
    end.
516
 
                    
 
565
    
517
566
terminating_discovery_stage2() ->
518
 
    Default = discovery, 
519
 
    case ets:lookup(snmp_agent_table, discovery) of
520
 
        [] -> % upgrade
521
 
            Default;
522
 
        [{discovery, DiscoOptions}] ->
523
 
            case lists:keysearch(terminating, 1, DiscoOptions) of
524
 
                {value, {terminating, TermDisco}} ->
525
 
                    case lists:keysearch(stage2, 1, TermDisco) of
526
 
                        {value, {stage2, Stage2}} when ((Stage2 =:= discovery) orelse (Stage2 =:= plain)) ->
527
 
                            Stage2;
528
 
                        _ ->
529
 
                           Default 
530
 
                    end;
531
 
                _ ->
532
 
                    Default
533
 
            end
534
 
    end.
535
 
 
536
 
 
 
567
    Default   = discovery, 
 
568
    TermDisco = terminating_disco_opts(),
 
569
    case lists:keysearch(stage2, 1, TermDisco) of
 
570
        {value, {stage2, Stage2}} when ((Stage2 =:= discovery) orelse (Stage2 =:= plain)) ->
 
571
            Stage2;
 
572
        _ ->
 
573
            Default 
 
574
    end.
 
575
 
 
576
terminating_trigger_username() ->
 
577
    Default   = ?DISCO_TERMINATING_TRIGGER_USERNAME,
 
578
    TermDisco = terminating_disco_opts(),
 
579
    case lists:keysearch(trigger_username, 1, TermDisco) of
 
580
        {value, {trigger_username, Trigger}} when is_list(Trigger) ->
 
581
            Trigger;
 
582
        _ ->
 
583
            Default
 
584
    end.
 
585
 
 
586
    
537
587
discovery(TargetName, Notification, ContextName, Varbinds, 
538
 
          DiscoHandler) ->
 
588
          DiscoHandler, ExtraInfo) ->
539
589
    case is_originating_discovery_enabled() of
540
590
        true ->
541
591
            Agent = snmp_master_agent, 
542
592
            call(Agent, 
543
593
                 {discovery, 
544
 
                  TargetName, Notification, ContextName, Varbinds, DiscoHandler});
 
594
                  TargetName, Notification, ContextName, Varbinds, 
 
595
                  DiscoHandler, ExtraInfo});
545
596
        false ->
546
597
            {error, not_enabled}
547
598
    end.
748
799
            end,
749
800
            {noreply, S}
750
801
    end;
 
802
handle_info({'DOWN', Ref, process, Pid, {mibs_cache_reply, Reply}}, 
 
803
            #state{mibs_cache_request = {Pid, Ref, From}} = S) ->
 
804
    ?vlog("reply from the mibs cache request handler (~p): ~n~p", 
 
805
          [Pid, Reply]),
 
806
    gen_server:reply(From, Reply),
 
807
    {noreply, S#state{mibs_cache_request = undefined}};
751
808
 
752
809
handle_info(Info, S) ->
753
810
    warning_msg("received unexpected info: ~n~p", [Info]),
796
853
            {reply, {error, send_failed}, S}
797
854
    end;
798
855
handle_call({discovery, 
799
 
             TargetName, Notification, ContextName, Vbs, DiscoHandler}, 
 
856
             TargetName, Notification, ContextName, Vbs, DiscoHandler, ExtraInfo}, 
800
857
            From, 
801
858
            #state{disco = undefined} = S) ->
802
859
    ?vlog("[handle_call] initiate discovery process:"
804
861
          "~n   Notification: ~p"
805
862
          "~n   ContextName:  ~p"
806
863
          "~n   Vbs:          ~p"
807
 
          "~n   DiscoHandler: ~p", 
808
 
          [TargetName, Notification, ContextName, Vbs, DiscoHandler]),
 
864
          "~n   DiscoHandler: ~p"
 
865
          "~n   ExtraInfo:    ~p", 
 
866
          [TargetName, Notification, ContextName, Vbs, 
 
867
           DiscoHandler, ExtraInfo]),
809
868
    case handle_discovery(S, From, TargetName, 
810
 
                          Notification, ContextName, Vbs, DiscoHandler) of
 
869
                          Notification, ContextName, Vbs, DiscoHandler, 
 
870
                          ExtraInfo) of
811
871
        {ok, NewS} ->
812
872
            ?vtrace("[handle_call] first stage of discovery process initiated",
813
873
                    []),
815
875
        {error, _} = Error ->
816
876
            {reply, Error, S}
817
877
    end;
818
 
handle_call({discovery, _TargetName, _Notification, _ContextName, _Vbs, _DiscoHandler}, _From, 
 
878
handle_call({discovery, _TargetName, _Notification, _ContextName, _Vbs, _DiscoHandler, _ExtraInfo}, _From, 
819
879
            #state{disco = DiscoData} = S) ->
820
880
    Reply = {error, {discovery_in_progress, DiscoData}}, 
821
881
    {reply, Reply, S};
945
1005
    ?vlog("whereis mib ~p", [Mib]),
946
1006
    {reply, snmpa_mib:whereis_mib(get(mibserver), Mib), S};
947
1007
 
948
 
handle_call(invalidate_mibs_cache, _From, S) ->
949
 
    ?vlog("invalidate_mibs_cache", []),
950
 
    snmpa_mib:invalidate_cache(get(mibserver)),
951
 
    {reply, ignore, S};
 
1008
handle_call({mibs_cache_request, MibsCacheReq}, From, S) ->
 
1009
    ?vlog("mibs_cache_request: ~p", [MibsCacheReq]),
 
1010
    {MibsCacheWorker, Ref} = 
 
1011
        handle_mibs_cache_request(get(mibserver), MibsCacheReq),
 
1012
    NewS = S#state{mibs_cache_request = {MibsCacheWorker, Ref, From}},
 
1013
    {noreply, NewS};
952
1014
 
953
1015
handle_call(info, _From, S) ->
954
1016
    ?vlog("info", []),
1119
1181
    ok.
1120
1182
 
1121
1183
 
 
1184
handle_mibs_cache_request(MibServer, Req) ->
 
1185
    {MibsCacheWorker, MibsCacheRef} = 
 
1186
        spawn_monitor(
 
1187
          fun() -> 
 
1188
                  Reply = 
 
1189
                      case Req of
 
1190
                          invalidate_cache ->
 
1191
                              snmpa_mib:invalidate_cache(MibServer);
 
1192
                          gc_cache ->
 
1193
                              snmpa_mib:gc_cache(MibServer);
 
1194
                          {gc_cache, Age} ->
 
1195
                              snmpa_mib:gc_cache(MibServer, Age);
 
1196
                          {gc_cache, Age, GcLimit} ->
 
1197
                              snmpa_mib:gc_cache(MibServer, Age, GcLimit);
 
1198
                          enable_cache ->
 
1199
                              snmpa_mib:enable_cache(MibServer);
 
1200
                          disable_cache ->
 
1201
                              snmpa_mib:disable_cache(MibServer);
 
1202
                          enable_autogc ->
 
1203
                              snmpa_mib:enable_cache_autogc(MibServer);
 
1204
                          disable_autogc ->
 
1205
                              snmpa_mib:disable_cache_autogc(MibServer);
 
1206
                          {update_gclimit, GcLimit} ->
 
1207
                              snmpa_mib:update_cache_gclimit(MibServer, 
 
1208
                                                              GcLimit);
 
1209
                          {update_age, Age} ->
 
1210
                              snmpa_mib:update_cache_age(MibServer, Age);
 
1211
                          _ ->
 
1212
                              {error, {unknown_mibs_cache_request, Req}}
 
1213
                      end,
 
1214
                  exit({mibs_cache_reply, Reply})
 
1215
          end),
 
1216
    {MibsCacheWorker, MibsCacheRef}.
 
1217
 
 
1218
                        
1122
1219
%%-----------------------------------------------------------------
1123
1220
%% Code replacement
1124
1221
%% 
1730
1827
 
1731
1828
handle_discovery(#state{type = master_agent} = S, From, 
1732
1829
                 TargetName, Notification, ContextName, Varbinds, 
1733
 
                 DiscoHandler) ->
 
1830
                 DiscoHandler, ExtraInfo) ->
1734
1831
    ?vtrace("handle_discovery -> entry with"
1735
1832
            "~n   TargetName:   ~p" 
1736
1833
            "~n   Notification: ~p" 
1743
1840
                    "~n   Record:   ~p"
1744
1841
                    "~n   InitVars: ~p", [Record, InitVars]),
1745
1842
            send_discovery(S, From, TargetName, 
1746
 
                           Record, ContextName, InitVars, DiscoHandler);
 
1843
                           Record, ContextName, InitVars, 
 
1844
                           DiscoHandler, ExtraInfo);
1747
1845
        error ->
1748
1846
            {error, failed_constructing_notification}
1749
1847
    end;
1750
1848
handle_discovery(_S, _From, 
1751
1849
                 _TargetName, _Notification, _ContextName, _Varbinds, 
1752
 
                 _DiscoHandler) ->
 
1850
                 _DiscoHandler, _ExtraInfo) ->
1753
1851
    {error, only_master_discovery}.
1754
1852
                                
1755
1853
%% We ignore if the master agent is multi-threaded or not.
1756
1854
%% 
1757
1855
send_discovery(S, From, 
1758
 
               TargetName, Record, ContextName, InitVars, DiscoHandler) ->
 
1856
               TargetName, Record, ContextName, InitVars, 
 
1857
               DiscoHandler, ExtraInfo) ->
1759
1858
    case snmpa_trap:send_discovery(TargetName, Record, ContextName,
1760
1859
                                   InitVars, get(net_if)) of
1761
1860
        {ok, Sender, SecLevel} ->
1767
1866
                           ctx       = ContextName,
1768
1867
                           ivbs      = InitVars, 
1769
1868
                           stage     = 1,
1770
 
                           handler   = DiscoHandler}, 
 
1869
                           handler   = DiscoHandler,
 
1870
                           extra     = ExtraInfo}, 
1771
1871
            {ok, S#state{disco = Disco}};
1772
1872
        Error ->
1773
1873
            ?vlog("send_discovery -> failed sending discovery: "
1785
1885
    S#state{disco = undefined};
1786
1886
 
1787
1887
handle_discovery_response(#state{disco = #disco{target = TargetName, 
1788
 
                                                stage  = 1} = Disco} = S, 
 
1888
                                                stage  = 1,
 
1889
                                                extra  = ExtraInfo} = Disco} = S, 
1789
1890
                          {ok, _Pdu, ManagerEngineId}) 
1790
1891
  when is_record(Disco, disco) ->
1791
1892
    ?vlog("handle_discovery_response(1) -> entry with"
1798
1899
    case snmp_target_mib:set_target_engine_id(TargetName, ManagerEngineId) of
1799
1900
        true when Disco#disco.sec_level =:= ?'SnmpSecurityLevel_noAuthNoPriv' ->
1800
1901
            %% Ok, we are done
1801
 
            From = Disco#disco.from,
 
1902
            From    = Disco#disco.from,
1802
1903
            Handler = Disco#disco.handler, 
1803
 
            Reply = handle_discovery_stage1_finish(Handler, 
1804
 
                                                   TargetName, ManagerEngineId),
 
1904
            Reply   = 
 
1905
                case handle_discovery_stage1_finish(Handler, 
 
1906
                                                    TargetName, 
 
1907
                                                    ManagerEngineId, 
 
1908
                                                    ExtraInfo) of
 
1909
                    {ok, _} ->
 
1910
                        {ok, ManagerEngineId};
 
1911
                    Error ->
 
1912
                        Error
 
1913
                end,
1805
1914
            gen_server:reply(From, Reply),
1806
1915
            S#state{disco = undefined};
1807
1916
 
1808
1917
        true when Disco#disco.sec_level =/= ?'SnmpSecurityLevel_noAuthNoPriv' ->
1809
1918
            %% Ok, time for stage 2
1810
 
            %% Send the same inform again, this time we have the proper EngineId
 
1919
            %% Send the same inform again, 
 
1920
            %% this time we have the proper EngineId
1811
1921
 
1812
 
            From = Disco#disco.from,
 
1922
            From    = Disco#disco.from,
1813
1923
            Handler = Disco#disco.handler, 
1814
1924
 
1815
1925
            case handle_discovery_stage1_finish(Handler, 
1816
 
                                                TargetName, ManagerEngineId) of
1817
 
                ok ->
 
1926
                                                TargetName, 
 
1927
                                                ManagerEngineId, 
 
1928
                                                ExtraInfo) of
 
1929
                {ok, NewExtraInfo} ->
1818
1930
                    ?vdebug("handle_discovery_response(1) -> "
1819
1931
                            "we are done with stage 1 - "
1820
1932
                            "continue with stage 2", []),
1821
 
                    #disco{target = TargetName, 
1822
 
                           rec    = Record,
1823
 
                           ctx    = ContextName,
1824
 
                           ivbs   = InitVars} = Disco, 
1825
 
                    case snmpa_trap:send_discovery(TargetName, Record, ContextName,
 
1933
                    #disco{rec  = Record,
 
1934
                           ctx  = ContextName,
 
1935
                           ivbs = InitVars} = Disco, 
 
1936
                    case snmpa_trap:send_discovery(TargetName, Record, 
 
1937
                                                   ContextName,
1826
1938
                                                   InitVars, get(net_if)) of
1827
1939
                        {ok, Sender, _SecLevel} ->
1828
1940
                            ?vdebug("handle_discovery_response(1) -> "
1829
1941
                                    "stage 2 trap sent", []),
1830
 
                            Disco2 = Disco#disco{sender = Sender, 
1831
 
                                                 stage  = 2}, 
1832
 
                            {ok, S#state{disco = Disco2}};
 
1942
                            Disco2 = Disco#disco{sender    = Sender, 
 
1943
                                                 engine_id = ManagerEngineId, 
 
1944
                                                 stage     = 2,
 
1945
                                                 extra     = NewExtraInfo}, 
 
1946
                            S#state{disco = Disco2};
1833
1947
                        Error ->
1834
1948
                            ?vlog("handle_discovery_response(1) -> "
1835
1949
                                  "failed sending stage 2 trap: "
1836
1950
                                  "~n   ~p", [Error]),
1837
 
                            Error
 
1951
                            error_msg("failed sending second "
 
1952
                                      "discovery message: "
 
1953
                                      "~n   ~p", [Error]),
 
1954
                            Reply = {error, {second_send_failed, Error}}, 
 
1955
                            gen_server:reply(From, Reply),
 
1956
                            S#state{disco = undefined}
1838
1957
                    end;
1839
1958
                {error, Reason} = Error ->
1840
1959
                    ?vlog("handle_discovery_response(1) -> "
1854
1973
 
1855
1974
    end;
1856
1975
 
1857
 
handle_discovery_response(#state{disco = #disco{from = From, stage = 2}} = S, 
 
1976
handle_discovery_response(#state{disco = #disco{from = From, 
 
1977
                                                engine_id = EngineID, 
 
1978
                                                stage = 2}} = S, 
1858
1979
                          {ok, _Pdu}) ->
1859
1980
    ?vlog("handle_discovery_response(2) -> entry with"
1860
1981
          "~n   From: ~p", [From]),
1861
 
    gen_server:reply(From, ok),
 
1982
    gen_server:reply(From, {ok, EngineID}),
1862
1983
    S#state{disco = undefined};
1863
1984
 
1864
1985
handle_discovery_response(#state{disco = #disco{from = From}} = S, Crap) ->
1870
1991
    warning_msg("Received unexpected discovery response: ~p", [Crap]),
1871
1992
    S.
1872
1993
 
1873
 
 
1874
 
handle_discovery_stage1_finish(Handler, TargetName, ManagerEngineID) ->
1875
 
    case (catch Handler:stage1_finish(TargetName, ManagerEngineID)) of
 
1994
handle_discovery_stage1_finish(Handler, TargetName, ManagerEngineID, 
 
1995
                               ExtraInfo) ->
 
1996
    case (catch Handler:stage1_finish(TargetName, ManagerEngineID, 
 
1997
                                      ExtraInfo)) of
1876
1998
        ignore ->
1877
1999
            ?vtrace("handle_discovery_stage1_finish -> "
1878
 
                  "we are done - [ignore] inform the user", []),
1879
 
            {ok, ManagerEngineID};
 
2000
                    "we are done - [ignore] inform the user", []),
 
2001
            {ok, ExtraInfo};
 
2002
 
1880
2003
        {ok, UsmEntry} when is_tuple(UsmEntry) ->
1881
2004
            ?vtrace("handle_discovery_stage1_finish -> "
1882
 
                    "received usm entry - attempt to add entry", []),
1883
 
            case snmp_user_based_sm_mib:add_user(UsmEntry) of
1884
 
                {ok, _} ->
1885
 
                    ok;
1886
 
                {error, Reason} ->
1887
 
                    ?vlog("handle_discovery_stage1_finish -> "
1888
 
                          "failed adding usm entry: "
1889
 
                          "~n   ~p", [Reason]),
1890
 
                    {error, {failed_adding_entry, Reason, ManagerEngineID}}
1891
 
            end;
 
2005
                    "received usm entry - attempt to add it", []),
 
2006
            case add_usm_users([UsmEntry]) of
 
2007
                ok ->
 
2008
                    {ok,  ExtraInfo};
 
2009
                Error ->
 
2010
                    Error
 
2011
            end;
 
2012
 
 
2013
        {ok, UsmEntry, NewExtraInfo} when is_tuple(UsmEntry) ->
 
2014
            ?vtrace("handle_discovery_stage1_finish -> "
 
2015
                    "received usm entry - attempt to add it", []),
 
2016
            case add_usm_users([UsmEntry]) of
 
2017
                ok ->
 
2018
                    {ok, NewExtraInfo};
 
2019
                Error ->
 
2020
                    Error
 
2021
            end;
 
2022
 
 
2023
        {ok, UsmEntries} when is_list(UsmEntries) ->
 
2024
            ?vtrace("handle_discovery_stage1_finish -> "
 
2025
                    "received usm entries - attempt to add them", []),
 
2026
            case add_usm_users(UsmEntries) of
 
2027
                ok ->
 
2028
                    {ok, ExtraInfo};
 
2029
                Error ->
 
2030
                    Error
 
2031
            end;
 
2032
 
 
2033
        {ok, UsmEntries, NewExtraInfo} when is_list(UsmEntries) ->
 
2034
            ?vtrace("handle_discovery_stage1_finish -> "
 
2035
                    "received usm entries - attempt to add them", []),
 
2036
            case add_usm_users(UsmEntries) of
 
2037
                ok ->
 
2038
                    {ok, NewExtraInfo};
 
2039
                Error ->
 
2040
                    Error
 
2041
            end;
 
2042
 
1892
2043
        {'EXIT', Reason} ->
1893
2044
            ?vlog("handle_discovery_stage1_finish -> stage 1 function exited: "
1894
2045
                  "~n   ~p", [Reason]),
1895
2046
            {error, {finish_exit, Reason, ManagerEngineID}};
 
2047
 
1896
2048
        {error, Reason} ->
1897
2049
            ?vlog("handle_discovery_stage1_finish -> stage 1 function error: "
1898
2050
                  "~n   ~p", [Reason]),
1899
2051
            {error, {finish_error, Reason, ManagerEngineID}};
 
2052
 
1900
2053
        Unknown ->
1901
2054
            ?vlog("handle_discovery_stage1_finish -> stage 1 function unknown: "
1902
2055
                  "~n   ~p", [Unknown]),
1903
2056
            {error, {finish_failed, Unknown, ManagerEngineID}}
1904
2057
    end.
1905
2058
 
 
2059
add_usm_users([]) ->
 
2060
    ok;
 
2061
add_usm_users([UsmEntry|UsmEntries]) when is_tuple(UsmEntry) ->
 
2062
    ?vtrace("add_usm_users -> attempt to add entry (~w)", 
 
2063
            [element(1, UsmEntry)]),
 
2064
    case snmp_user_based_sm_mib:add_user(UsmEntry) of
 
2065
        {ok, _} ->
 
2066
            add_usm_users(UsmEntries);
 
2067
        {error, Reason} ->
 
2068
            ?vlog("add_usm_users -> failed adding usm entry: "
 
2069
                  "~n   ~p", [Reason]),
 
2070
            {error, {failed_adding_entry, Reason, UsmEntry}}
 
2071
    end.
 
2072
 
1906
2073
    
1907
2074
handle_me_of(MibServer, Oid) ->
1908
2075
    case snmpa_mib:lookup(MibServer, Oid) of