diff options
Diffstat (limited to 'lib/snmp/src/agent/snmpa_mib_lib.erl')
-rw-r--r-- | lib/snmp/src/agent/snmpa_mib_lib.erl | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/lib/snmp/src/agent/snmpa_mib_lib.erl b/lib/snmp/src/agent/snmpa_mib_lib.erl new file mode 100644 index 0000000000..441228b9ee --- /dev/null +++ b/lib/snmp/src/agent/snmpa_mib_lib.erl @@ -0,0 +1,207 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-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_mib_lib). + +-export([table_cre_row/3, table_del_row/2]). +-export([get_table/2, print_table/3, print_table/4, print_tables/1]). +-export([gc_tab/3, gc_tab/5]). + +-include("SNMPv2-TC.hrl"). +-include("snmp_types.hrl"). + +-define(VMODULE,"MIB-LIB"). +-include("snmp_verbosity.hrl"). + +-ifndef(default_verbosity). +-define(default_verbosity,silence). +-endif. + + +%%%----------------------------------------------------------------- +%%%----------------------------------------------------------------- + +%% returns: bool() +table_cre_row({Tab, mnesia}, Key, _Row) -> + ?vtrace("create mnesia table ~w row with Key: ~w",[Tab, Key]), + {error, mnesia_not_supported}; +table_cre_row({Tab, Db} = TabDb, Key, Row) -> + ?vtrace("create ~w table ~w row with Key: ~w",[Db, Tab, Key]), + snmpa_local_db:table_create_row(TabDb, Key, Row). + +%% returns: bool() +table_del_row({Tab, mnesia}, Key) -> + ?vtrace("delete mnesia table ~w row with Key: ~w",[Tab, Key]), + {error, mnesia_not_supported}; +table_del_row({Tab, Db} = TabDb, Key) -> + ?vtrace("delete ~w table ~w row with Key: ~w", [Db, Tab, Key]), + snmpa_local_db:table_delete_row(TabDb, Key). + + +%%%----------------------------------------------------------------- +%%% Retreives the entire table. Used for debugging +%%%----------------------------------------------------------------- + +get_table(NameDb, FOI) -> + (catch get_table(NameDb, FOI, [], [])). + +get_table(NameDb, FOI, Oid, Acc) -> + case table_next(NameDb, Oid) of + endOfTable -> + ?vdebug("end of table",[]), + {ok, lists:reverse(Acc)}; + Oid -> + %% Crap, circular ref + ?vinfo("cyclic reference: ~w -> ~w", [Oid,Oid]), + throw({error, {cyclic_db_reference, Oid, Acc}}); + NextOid -> + ?vtrace("get row for oid ~w", [NextOid]), + case table_get_row(NameDb, NextOid, FOI) of + undefined -> + throw({error, {invalid_rowindex, NextOid, Acc}}); + Row -> + ?vtrace("row: ~w", [Row]), + get_table(NameDb, FOI, NextOid, [{NextOid, Row}|Acc]) + end + end. + + +print_tables(Tables) when is_list(Tables) -> + lists:foreach(fun({Table, DB, FOI, PrintRow}) -> + print_table(Table, DB, FOI, PrintRow) + end, Tables), + ok. + +%% print_table(Table, DB, FOI, PrintRow) -> +%% TableInfo = get_table(DB(Table), FOI(Table)), +%% print_table(Table, TableInfo, PrintRow), +%% ok. + +print_table(Table, DB, FOI, PrintRow) -> + TableInfo = get_table(DB, FOI), + print_table(Table, TableInfo, PrintRow). + +print_table(Table, TableInfo, PrintRow) when is_function(PrintRow, 2) -> + io:format("~w => ~n", [Table]), + do_print_table(TableInfo, PrintRow). + +do_print_table({ok, TableInfo}, PrintRow) when is_function(PrintRow, 2) -> + lists:foreach(fun({RowIdx, Row}) -> + io:format(" ~w => ~n~s~n", + [RowIdx, PrintRow(" ", Row)]) + end, TableInfo), + io:format("~n", []); +do_print_table({error, {invalid_rowindex, BadRowIndex, []}}, _PrintRow) -> + io:format("Error: Bad rowindex ~w~n", [BadRowIndex]); +do_print_table({error, {invalid_rowindex, BadRowIndex, TableInfo}}, PrintRow) -> + io:format("Error: Bad rowindex ~w", [BadRowIndex]), + do_print_table(TableInfo, PrintRow); +do_print_table(Error, _PrintRow) -> + io:format("Error: ~p~n", [Error]). + + +%%%----------------------------------------------------------------- +%%% +%%%----------------------------------------------------------------- + +table_next({Name, mnesia}, RestOid) -> + snmp_generic_mnesia:table_next(Name, RestOid); +table_next(NameDb, RestOid) -> + snmpa_local_db:table_next(NameDb, RestOid). + + +table_get_row({Name, mnesia}, RowIndex) -> + snmp_generic_mnesia:table_get_row(Name, RowIndex); +table_get_row(NameDb, RowIndex) -> + snmpa_local_db:table_get_row(NameDb, RowIndex). + +table_get_row(NameDb, RowIndex, undefined) -> + table_get_row(NameDb, RowIndex); +table_get_row({Name, mnesia}, RowIndex, FOI) -> + snmp_generic_mnesia:table_get_row(Name, RowIndex, FOI); +table_get_row(NameDb, RowIndex, _FOI) -> + snmpa_local_db:table_get_row(NameDb, RowIndex). + + +%%%----------------------------------------------------------------- +%%% Utility module for the mib-implementation modules (such as +%%% snmp_target_mib). +%%%----------------------------------------------------------------- + +gc_tab(TabDb, STC, FOI) -> + InvalidateRow = fun(_) -> ok end, + UpdateRow = fun(_) -> ok end, + gc_tab(TabDb, STC, FOI, InvalidateRow, UpdateRow). + +gc_tab({Tab,mnesia} = TabDb, STC, FOI, InvalidateRow, UpdateRow) -> + F = fun(RowIndex, Row) -> + case element(STC, Row) of + ?'StorageType_volatile' -> + snmp_generic_mnesia:table_delete_row(Tab, RowIndex), + InvalidateRow(RowIndex); + _ -> + UpdateRow(RowIndex) + end + end, + gc_tab1(F, TabDb, FOI); + +gc_tab(TabDb, STC, FOI, InvalidateRow, UpdateRow) -> + F = fun(RowIndex, Row) -> + case element(STC, Row) of + ?'StorageType_volatile' -> + snmpa_local_db:table_delete_row(TabDb, RowIndex), + InvalidateRow(RowIndex); + _ -> + UpdateRow(RowIndex), + ok + end + end, + gc_tab1(F, TabDb, FOI). + + +gc_tab1(F, {Tab,_} = TabDb, FOI) -> + case (catch snmp_generic:table_foreach(TabDb, F, FOI)) of + {'EXIT',{cyclic_db_reference,Oid}} -> + %% Remove the row regardless of storage type since this + %% is a major error. This row must be removed. + case table_delete_row(TabDb, Oid) of + true -> + ?vlog("deleted cyclic ref row for: ~w;~w", + [Tab, Oid]), + config_err("cyclic reference in table ~w: " + "~w -> ~w. Row deleted", + [Tab, Oid, Oid]), + gc_tab1(F, TabDb, FOI); + false -> + ?vlog("unable to remove faulty row from table ~w", + [Tab]), + config_err("failed removing faulty row. " + "Giving up on table ~w cleanup", [Tab]) + end; + _ -> + ok + end. + +table_delete_row({Tab, mnesia}, Oid) -> + snmp_generic_mnesia:table_delete_row(Tab, Oid), + true; +table_delete_row(TabDb, Oid) -> + snmpa_local_db:table_delete_row(TabDb, Oid). + +config_err(F, A) -> + snmpa_error:config_err(F, A). |