From 31b06641f692641f82c489069584220609e1e840 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 21 May 2013 11:17:44 +0200 Subject: [snmp/agent] backup --- lib/snmp/doc/src/snmp_app.xml | 48 ++-- lib/snmp/src/agent/depend.mk | 12 + lib/snmp/src/agent/modules.mk | 4 + lib/snmp/src/agent/snmpa_mib_storage.erl | 181 ++++++++++++++ lib/snmp/src/agent/snmpa_mib_storage_dets.erl | 298 ++++++++++++++++++++++++ lib/snmp/src/agent/snmpa_mib_storage_ets.erl | 298 ++++++++++++++++++++++++ lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl | 265 +++++++++++++++++++++ lib/snmp/src/agent/snmpa_supervisor.erl | 103 ++++++-- 8 files changed, 1172 insertions(+), 37 deletions(-) create mode 100644 lib/snmp/src/agent/snmpa_mib_storage.erl create mode 100644 lib/snmp/src/agent/snmpa_mib_storage_dets.erl create mode 100644 lib/snmp/src/agent/snmpa_mib_storage_ets.erl create mode 100644 lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl (limited to 'lib/snmp') diff --git a/lib/snmp/doc/src/snmp_app.xml b/lib/snmp/doc/src/snmp_app.xml index c7a74f0ca6..9cdbcc91c5 100644 --- a/lib/snmp/doc/src/snmp_app.xml +++ b/lib/snmp/doc/src/snmp_app.xml @@ -312,29 +312,31 @@ - ]]> - -

Specifies how info retrieved from the mibs will be stored.

-

If mib_storage is {ets, Dir}, the table will also be - stored on file. If Dir is default, then db_dir - will be used.

-

If mib_storage is dets or if Dir is - default, then db_dir will be used for Dir.

-

If mib_storage is mnesia then erlang:nodes() - will be used for Nodes.

-

Default is ets.

-

Dir = default | string(). Dir is the directory where the - files will be stored. If default, then db_dir will be - used.

-

Nodes = visible | connected | [node()]. - Nodes = visible is translated to - erlang:nodes(visible). - Nodes = connected is translated to - erlang:nodes(connected). - If Nodes = [] then the own node is assumed.

-

Action = clear | keep. Default is keep. - Action is used to specify what shall be done if the - mnesia/dets table already exist.

+ + +

mib_storage_opt() = {module, mib_storage_module()} | {options, list()}

+

This option specifies how basic mib data is stored. + This option is used by two parts of the snmp agent: + The mib-server and the symbolic-store.

+

Default is [{module, snmpa_mib_storage_ets}].

+
+ + + ]]> + +

Defines the callback mib data storage module of the + SNMP agent mib-server as defined by the + snmpa_mib_data + behaviour.

+

At present only the default module is provided with the agent, + snmpa_mib_data_tttn.

+ +

Default module is snmpa_mib_data_tttn.

diff --git a/lib/snmp/src/agent/depend.mk b/lib/snmp/src/agent/depend.mk index 096182a626..283de54078 100644 --- a/lib/snmp/src/agent/depend.mk +++ b/lib/snmp/src/agent/depend.mk @@ -88,6 +88,18 @@ $(EBIN)/snmpa_local_db.$(EMULATOR): \ ../../include/snmp_types.hrl \ ../../include/STANDARD-MIB.hrl +$(EBIN)/snmpa_mib_storage.$(EMULATOR): \ + snmpa_mib_storage.erl + +$(EBIN)/snmpa_mib_storage_ets.$(EMULATOR): \ + snmpa_mib_storage_ets.erl + +$(EBIN)/snmpa_mib_storage_dets.$(EMULATOR): \ + snmpa_mib_storage_dets.erl + +$(EBIN)/snmpa_mib_storage_mnesia.$(EMULATOR): \ + snmpa_mib_storage_mnesia.erl + $(EBIN)/snmpa_mib.$(EMULATOR): \ snmpa_mib.erl \ ../misc/snmp_debug.hrl \ diff --git a/lib/snmp/src/agent/modules.mk b/lib/snmp/src/agent/modules.mk index da9f6d6b4c..e8d1593a79 100644 --- a/lib/snmp/src/agent/modules.mk +++ b/lib/snmp/src/agent/modules.mk @@ -21,6 +21,7 @@ BEHAVIOUR_MODULES = \ snmpa_authentication_service \ snmpa_discovery_handler \ snmpa_error_report \ + snmpa_mib_storage \ snmpa_mib_data \ snmpa_network_interface \ snmpa_network_interface_filter \ @@ -45,6 +46,9 @@ MODULES = \ snmpa_error_logger \ snmpa_general_db \ snmpa_local_db \ + snmpa_mib_storage_ets \ + snmpa_mib_storage_dets \ + snmpa_mib_storage_mnesia \ snmpa_mib \ snmpa_mib_data_tttn \ snmpa_mib_lib \ diff --git a/lib/snmp/src/agent/snmpa_mib_storage.erl b/lib/snmp/src/agent/snmpa_mib_storage.erl new file mode 100644 index 0000000000..bbb9516ecb --- /dev/null +++ b/lib/snmp/src/agent/snmpa_mib_storage.erl @@ -0,0 +1,181 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2013-2013. 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_storage). + +-export_type([ + mib_storage_fields/0, + mib_storage_table_type/0, + mib_storage_table_id/0, + + void/0 + ]). + + +%%% ---------------------------------------------------------------- +%%% This behaviour module defines the API for the mib-storage. +%%% This is how the agent stores its internal mib-data +%%% (symbolic-store and mib-server). +%%%----------------------------------------------------------------- + +-type mib_storage_fields() :: [atom()]. +-type mib_storage_table_type() :: set | bag. +-type mib_storage_table_id() :: term(). +-type void() :: term(). + + +%% --------------------------------------------------------------- +%% open +%% +%% Open or create a mib-storage table. +%% If any extra info needs to be communicated to the implementor +%% (of the behaviour), this is done using the *Options* argument. +%% --------------------------------------------------------------- + +%% Options is callback module dependant + +-callback open(Name :: atom(), + RecName :: atom(), + Fields :: mib_storage_fields(), + Type :: mib_storage_table_type(), + Options :: list()) -> + {ok, TabId :: mib_storage_table_id()} | {error, Reason :: term()}. + + +%% --------------------------------------------------------------- +%% close +%% +%% Close the mib-storage table. What this does is up to the +%% implementor (when using mnesia it may be a no-op but for ets +%% it may actually delete the table). +%% --------------------------------------------------------------- + +-callback close(TabId :: mib_storage_table_id()) -> + term(). + + +%% --------------------------------------------------------------- +%% read/2 +%% +%% Retrieve a record from the mib-storage table. +%% --------------------------------------------------------------- + +-callback read(TabId :: mib_storage_table_id(), + Key :: term()) -> + false | {value, Record :: tuple()}. + + +%% --------------------------------------------------------------- +%% write/2 +%% +%% Write a record to the mib-storage table. +%% --------------------------------------------------------------- + +-callback write(TabId :: mib_storage_table_id(), + Record :: tuple()) -> + ok | {error, Reason :: term()}. + + +%% --------------------------------------------------------------- +%% delete/1 +%% +%% Delete the mib-storage table. +%% --------------------------------------------------------------- + +-callback delete(TabId :: mib_storage_table_id()) -> + void(). + + +%% --------------------------------------------------------------- +%% delete/2 +%% +%% Delete a record from the mib-storage table. +%% --------------------------------------------------------------- + +-callback delete(TabId :: mib_storage_table_id(), + Key :: term()) -> + ok | {error, Reason :: term()}. + + +%% --------------------------------------------------------------- +%% match_object +%% +%% Search the mib-storage table for records which matches +%% the pattern. +%% --------------------------------------------------------------- + +-callback match_object(TabId :: mib_storage_table_id(), + Pattern :: ets:match_pattern()) -> + {ok, Recs :: [tuple()]} | {error, Reason :: term()}. + + +%% --------------------------------------------------------------- +%% match_delete +%% +%% Search the mib-storage table for records which matches the +%% pattern and deletes them from the database and return the +%5 deleted records. +%% --------------------------------------------------------------- + +-callback match_delete(TabId :: mib_storage_table_id(), + Pattern :: ets:match_pattern()) -> + {ok, Recs :: [tuple()]} | {error, Reason :: term()}. + + +%% --------------------------------------------------------------- +%% tab2list +%% +%% Return all records in the table in the form of a list. +%% --------------------------------------------------------------- + +-callback tab2list(TabId :: mib_storage_table_id()) -> + [tuple()]. + + +%% --------------------------------------------------------------- +%% info +%% +%% Retrieve implementation dependent mib-storage table +%% information. +%% --------------------------------------------------------------- + +-callback info(TabId :: mib_storage_table_id()) -> + {ok, Info :: term()} | {error, Reason :: term()}. + + +%% --------------------------------------------------------------- +%% sync +%% +%% Dump mib-storage table to disc (if it has a disk component). +%% --------------------------------------------------------------- + +-callback sync(TabId :: mib_storage_table_id()) -> + ok. + + +%% --------------------------------------------------------------- +%% backup +%% +%% Make a backup copy of the mib-storage table. +%% --------------------------------------------------------------- + +-callback backup(TabId :: mib_storage_table_id(), + Dir :: file:filename()) -> + ok | {error, Reason :: term()}. + diff --git a/lib/snmp/src/agent/snmpa_mib_storage_dets.erl b/lib/snmp/src/agent/snmpa_mib_storage_dets.erl new file mode 100644 index 0000000000..6062f4327e --- /dev/null +++ b/lib/snmp/src/agent/snmpa_mib_storage_dets.erl @@ -0,0 +1,298 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2013-2013. 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_storage_dets). + +-behaviour(snmpa_mib_storage). + + +%%%----------------------------------------------------------------- +%%% This module implements the snmpa_mib_storage behaviour. +%%% It uses dets for storage. +%%%----------------------------------------------------------------- + +-export([ + open/5, + close/1, + read/2, + write/2, + delete/1, + delete/2, + sync/1, + backup/2, + match_object/2, + match_delete/2, + tab2list/1, + info/1 + ]). + + +-define(VMODULE, "MS-DETS"). +-include("snmp_verbosity.hrl"). + +-record(tab, {id}). + + +%% --------------------------------------------------------------- +%% open +%% +%% Open or create a mib-storage (dets) table. +%% +%% Opts - A list of implementation dependent options +%% dets_open_options() = [dets_open_option()] +%% dets_open_option() = {dir, filename()} | +%% {action, keep | clear} | +%% {auto_save, default | pos_integer()} | +%% {repair, force | boolean()} +%% +%% --------------------------------------------------------------- + +open(Name, _RecName, _Fields, Type, Opts) -> + Dir = snmp_misc:get_option(dir, Opts), + Action = snmp_misc:get_option(action, Opts, keep), + AutoSave = snmp_misc:get_option(auto_save, Opts, default), + Repair = snmp_misc:get_option(repair, Opts, false), + File = dets_filename(Name, Dir), + OpenOpts = [{file, File}, + {type, Type}, + {keypos, 2}, + {repair, Repair}] ++ + case AutoSave of + default -> + []; + _ -> + [{auto_save, AutoSave}] + end, + case dets:open_file(Name, OpenOpts) of + {ok, ID} when (Action =:= keep) -> + {ok, #tab{id = ID}}; + {ok, ID} when (Action =:= clear) -> + dets:match_delete(ID, '_'), + {ok, #tab{id = ID}}; + {error, Reason} -> + {error, {dets_open, Reason}} + end. + +dets_filename(Name, Dir) -> + Dir1 = dets_filename1(Dir), + Dir2 = string:strip(Dir1, right, $/), + io_lib:format("~s/~p.dat", [Dir2, Name]). + +dets_filename1([]) -> "."; +dets_filename1(Dir) -> Dir. + + +%% --------------------------------------------------------------- +%% close +%% +%% Close the table. +%% --------------------------------------------------------------- + +close(#tab{id = ID}) -> + ?vtrace("close database ~p", [ID]), + dets:close(ID). + + +%% --------------------------------------------------------------- +%% read +%% +%% Retrieve a record from the database table. +%% --------------------------------------------------------------- + +read(#tab{id = ID}, Key) -> + ?vtrace("read from table ~p: ~p", [ID, Key]), + case dets:lookup(ID, Key) of + [Rec|_] -> {value, Rec}; + _ -> false + end. + + +%% --------------------------------------------------------------- +%% write +%% +%% Write a record to the database table. +%% --------------------------------------------------------------- + +write(#tab{id = ID}, Rec) -> + ?vtrace("write to table ~p", [ID]), + dets:insert(ID, Rec). + + +%% --------------------------------------------------------------- +%% delete +%% +%% Delete the database table. +%% --------------------------------------------------------------- + +delete(#tab{id = ID}) -> + ?vtrace("delete database ~p", [ID]), + File = dets:info(ID, filename), + case dets:close(ID) of + ok -> + file:delete(File); + Error -> + Error + end. + + +%% --------------------------------------------------------------- +%% delete +%% +%% Delete a record from the database table. +%% --------------------------------------------------------------- + +delete(#tab{id = ID}, Key) -> + ?vtrace("delete from table ~p: ~p", [ID, Key]), + dets:delete(ID, Key). + + +%% --------------------------------------------------------------- +%% match_object +%% +%% Search the database table for records witch matches the pattern. +%% --------------------------------------------------------------- + +match_object(#tab{id = ID}, Pattern) -> + ?vtrace("match_object in ~p of ~p", [ID, Pattern]), + dets:match_object(ID, Pattern). + + +%% --------------------------------------------------------------- +%% match_delete +%% +%% Search the database table for records witch matches the +%% pattern and deletes them from the database table. +%% --------------------------------------------------------------- + +match_delete(#tab{id = ID}, Pattern) -> + ?vtrace("match_delete in ~p with pattern ~p", [ID, Pattern]), + Recs = dets:match_object(ID, Pattern), + dets:match_delete(ID, Pattern), + Recs. + + +%% --------------------------------------------------------------- +%% tab2list +%% +%% Return all records in the table in the form of a list. +%% --------------------------------------------------------------- + +tab2list(#tab{id = ID} = Tab) -> + ?vtrace("tab2list -> list of ~p", [ID]), + match_object(Tab, '_'). + + +%% --------------------------------------------------------------- +%% info +%% +%% Retrieve implementation dependent mib-storage table +%% information. +%% --------------------------------------------------------------- + +info(#tab{id = ID}) -> + ?vtrace("info -> info of ~p", [ID]), + dets:info(ID). + + +%% --------------------------------------------------------------- +%% sync +%% +%% Dump mib-storage table to disc (if it has a disk component) +%% --------------------------------------------------------------- + +sync(#tab{id = ID}) -> + ?vtrace("sync -> sync ~p", [ID]), + dets:sync(ID). + + +%% --------------------------------------------------------------- +%% backup +%% +%% Make a backup copy of the mib-storage table. +%% --------------------------------------------------------------- + +backup(#tab{id = ID}, BackupDir) -> + ?vtrace("backup -> backup of ~p to ~p", [ID, BackupDir]), + case dets:info(ID, filename) of + undefined -> + {error, no_file}; + Filename -> + case filename:dirname(Filename) of + BackupDir -> + {error, db_dir}; + _ -> + Type = dets:info(ID, type), + KP = dets:info(ID, keypos), + dets_backup(ID, + filename:basename(Filename), + BackupDir, Type, KP) + end + end. + + +dets_backup(ID, Filename, BackupDir, Type, KP) -> + ?vtrace("dets_backup -> entry with" + "~n ID: ~p" + "~n Filename: ~p" + "~n BackupDir: ~p" + "~n Type: ~p" + "~n KP: ~p", [ID, Filename, BackupDir, Type, KP]), + BackupFile = filename:join(BackupDir, Filename), + ?vtrace("dets_backup -> " + "~n BackupFile: ~p", [BackupFile]), + Backup = list_to_atom(atom_to_list(ID) ++ "_backup"), + Opts = [{file, BackupFile}, {type, Type}, {keypos, KP}], + case dets:open_file(Backup, Opts) of + {ok, B} -> + ?vtrace("dets_backup -> create fun", []), + F = fun(Arg) -> + dets_backup(Arg, start, ID, B) + end, + dets:safe_fixtable(ID, true), + Res = dets:init_table(Backup, F, [{format, bchunk}]), + dets:safe_fixtable(ID, false), + ?vtrace("dets_backup -> Res: ~p", [Res]), + Res; + Error -> + ?vinfo("dets_backup -> open_file failed: " + "~n ~p", [Error]), + Error + end. + +dets_backup(close, _Cont, _ID, B) -> + dets:close(B), + ok; +dets_backup(read, Cont1, ID, B) -> + case dets:bchunk(ID, Cont1) of + {Cont2, Data} -> + F = fun(Arg) -> + dets_backup(Arg, Cont2, ID, B) + end, + {Data, F}; + '$end_of_table' -> + dets:close(B), + end_of_input; + Error -> + Error + end. + + +%%---------------------------------------------------------------------- + +%% user_err(F, A) -> +%% snmpa_error:user_err(F, A). diff --git a/lib/snmp/src/agent/snmpa_mib_storage_ets.erl b/lib/snmp/src/agent/snmpa_mib_storage_ets.erl new file mode 100644 index 0000000000..fcf5e12043 --- /dev/null +++ b/lib/snmp/src/agent/snmpa_mib_storage_ets.erl @@ -0,0 +1,298 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2013-2013. 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_storage_ets). + +-behaviour(snmpa_mib_storage). + +%%%----------------------------------------------------------------- +%%% This module implements the snmpa_mib_storage behaviour. +%%% It uses ets for storage. +%%%----------------------------------------------------------------- + +-export([ + open/5, + close/1, + read/2, + write/2, + delete/1, + delete/2, + sync/1, + backup/2, + match_object/2, + match_delete/2, + tab2list/1, + info/1 + ]). + + +-define(VMODULE,"MS-ETS"). +-include("snmp_verbosity.hrl"). + +-record(tab, {id, file, checksum = false}). + + +%% --------------------------------------------------------------- +%% open +%% +%% Open or create an ets table. +%% Possibly also read data from a (specified) file (mirror) and +%% populate the table from that (the dir option). +%% +%% Opts - A list of implementation dependent options +%% ets_open_options() = [ets_open_option()] +%% ets_open_option() = {dir, filename()} | +%% {action, keep | clear} | +%% {checksum, boolean()} +%% +%% The RecName and Fields arguments are not used in this +%% implementation. +%% +%% --------------------------------------------------------------- + +%% This function creates the ets table +open(Name, _RecName, _Fields, Type, Opts) -> + ?vtrace("open table ~p", [Name]), + case lists:keysearch(dir, 1, Opts) of + {value, {dir, Dir}} -> + Action = snmp_misc:get_option(action, Opts, keep), + Checksum = snmp_misc:get_option(checksum, Opts, false), + ?vtrace("open ~p database ~p", [Type, Name]), + File = filename:join(Dir, atom_to_list(Name) ++ ".db"), + case file:read_file_info(File) of + {ok, _} -> + case ets:file2tab(File, [{verify, Checksum}]) of + {ok, ID} -> + {ok, #tab{id = ID, + file = File, + checksum = Checksum}}; + {error, Reason} when (Action =:= keep) -> + {error, {file2tab, Reason}}; + {error, Reason} -> + user_err("Warning: could not read file - " + "create new (empty): " + "~n File: ~p" + "~n Reason: ~p", [File, Reason]), + ID = ets:new(Name, [Type, protected, {keypos, 2}]), + write_ets_file(ID, File, Checksum), + {ok, #tab{id = ID, + file = File, + checksum = Checksum}} + end; + {error, Reason} when (Action =:= keep) -> + {error, {read_file_info, Reason}}; + {error, Reason} -> + user_err("Warning: could not read file info - " + "create new: " + "~n File: ~p" + "~n Reason: ~p", [File, Reason]), + ID = ets:new(Name, [Type, protected, {keypos, 2}]), + write_ets_file(ID, File, Checksum), + {ok, #tab{id = ID, + file = File, + checksum = Checksum}} + end; + false -> + ID = ets:new(Name, [Type, protected, {keypos, 2}]), + {ok, #tab{id = ID}} + end. + + +%% --------------------------------------------------------------- +%% close +%% +%% Close the mib-storage table. +%% We will delete the table and if there is a file component, +%% will also be written to file. +%% --------------------------------------------------------------- +close(#tab{id = ID, file = undefined}) -> + ?vtrace("close (delete) table ~p", [ID]), + ets:delete(ID); +close(#tab{id = ID, file = File, checksum = Checksum}) -> + ?vtrace("close (delete) table ~p", [ID]), + write_ets_file(ID, File, Checksum), + ets:delete(ID). + + +%% --------------------------------------------------------------- +%% read +%% +%% Retrieve a record from the mib-storage table. +%% --------------------------------------------------------------- + +read(#tab{id = ID}, Key) -> + ?vtrace("read from table ~p: ~p", [ID, Key]), + case ets:lookup(ID, Key) of + [Rec|_] -> {value, Rec}; + _ -> false + end. + + +%% --------------------------------------------------------------- +%% write +%% +%% Write a record to the mib-storage table. +%% --------------------------------------------------------------- + +write(#tab{id = ID}, Rec) -> + ?vtrace("write to table ~p", [ID]), + ets:insert(ID, Rec). + + +%% --------------------------------------------------------------- +%% delete +%% +%% Delete the mib-storage table. +%% --------------------------------------------------------------- +delete(#tab{id = ID, file = undefined}) -> + ?vtrace("delete table ~p", [ID]), + ets:delete(ID); +delete(#tab{id = ID, file = File}) -> + ?vtrace("delete table ~p", [ID]), + file:delete(File), + ets:delete(ID). + + +%% --------------------------------------------------------------- +%% delete +%% +%% Delete a record from the mib-storage table. +%% --------------------------------------------------------------- +delete(#tab{id = ID}, Key) -> + ?vtrace("delete from table ~p: ~p", [ID, Key]), + ets:delete(ID, Key). + + +%% --------------------------------------------------------------- +%% match_object +%% +%% Search the mib-storage table for records witch matches +%% the pattern. +%% --------------------------------------------------------------- + +match_object(#tab{id = ID}, Pattern) -> + ?vtrace("match_object in ~p of ~p", [ID, Pattern]), + ets:match_object(ID, Pattern). + + +%% --------------------------------------------------------------- +%% match_delete +%% +%% Search the mib-storage table for records witch matches +%% the pattern and deletes them from the table. +%% --------------------------------------------------------------- + +match_delete(#tab{id = ID}, Pattern) -> + ?vtrace("match_delete in ~p with pattern ~p", [ID, Pattern]), + Recs = ets:match_object(ID, Pattern), + ets:match_delete(ID, Pattern), + Recs. + + +%% --------------------------------------------------------------- +%% tab2list +%% +%% Return all records in the mib-storage table in the form +%% of a list. +%% --------------------------------------------------------------- + +tab2list(#tab{id = ID}) -> + ?vtrace("tab2list -> list of ~p", [ID]), + ets:tab2list(ID). + + + +%% --------------------------------------------------------------- +%% info +%% +%% Retrieve implementation dependent mib-storage table +%% information. +%% --------------------------------------------------------------- +info(#tab{id = ID}) -> + ?vtrace("info on ~p", [ID]), + case ets:info(ID) of + undefined -> + []; + L -> + L + end. + + +%% --------------------------------------------------------------- +%% sync +%% +%% Dump mib-storage table to disc (if there is a file compionent) +%% --------------------------------------------------------------- + +sync(#tab{file = undefined}) -> + ok; +sync(#tab{id = ID, file = File, checksum = Checksum}) -> + ?vtrace("sync ~p", [ID]), + write_ets_file(ID, File, Checksum). + + +%% --------------------------------------------------------------- +%% backup +%% +%% Make a backup copy of the mib-storage table. Only valid id +%% there is a file component. +%% --------------------------------------------------------------- + +backup(#tab{file = undefined}, _BackupDir) -> + ok; +backup(#tab{id = ID, file = File, checksum = Checksum}, BackupDir) -> + ?vtrace("backup ~p to ~p", [ID, BackupDir]), + Filename = filename:basename(File), + case filename:join(BackupDir, Filename) of + File -> + %% Oups: backup-dir and db-dir the same + {error, db_dir}; + BackupFile -> + write_ets_file(ID, BackupFile, Checksum) + end. + + +%%---------------------------------------------------------------------- + +write_ets_file(ID, File, Checksum) when (Checksum =:= true) -> + do_write_ets_file(ID, File, [{extended_info, [md5sum]}]); +write_ets_file(ID, File, Checksum) when (Checksum =:= false) -> + do_write_ets_file(ID, File, []). + +do_write_ets_file(ID, File, Options) -> + TmpFile = File ++ ".tmp", + case ets:tab2file(ID, TmpFile, Options) of + ok -> + case file:rename(TmpFile, File) of + ok -> + ok; + Else -> + user_err("Warning: could not move file ~p" + " (~p)", [File, Else]) + end; + {error, Reason} -> + user_err("Warning: could not save file ~p (~p)", + [File, Reason]) + end. + + +%%---------------------------------------------------------------------- + +user_err(F, A) -> + snmpa_error:user_err(F, A). diff --git a/lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl b/lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl new file mode 100644 index 0000000000..aee2192b24 --- /dev/null +++ b/lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl @@ -0,0 +1,265 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2013-2013. 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_storage_mnesia). + + +-behaviour(snmpa_mib_storage). + +%%%----------------------------------------------------------------- +%%% This module implements the snmpa_mib_storage behaviour. +%%% It uses mnesia for storage. +%%%----------------------------------------------------------------- + +-export([ + open/5, + close/1, + read/2, + write/2, + delete/1, + delete/2, + sync/1, + backup/2, + match_object/2, + match_delete/2, + tab2list/1, + info/1 + ]). + + +-define(VMODULE,"MS-MNESIA"). +-include("snmp_verbosity.hrl"). + +-record(tab, {id}). + + +%% --------------------------------------------------------------- +%% open +%% +%% Open or create a mnesia table. +%% +%% Opts - A list of implementation dependent options +%% mnesia_open_options() = [mnesia_open_option()] +%% mnesia_open_option() = {action, keep | clear} | +%% {nodes, [node()]} +%% +%% --------------------------------------------------------------- + +open(Name, RecName, Fields, Type, Opts) -> + ?vtrace("open ~p table ~p for record ~p", + [Type, Name, RecName]), + Action = snmp_misc:get_option(action, Opts, keep), + Nodes = snmp_misc:get_option(nodes, Opts, [node()]), + case table_exists(Name) of + true when (Action =:= keep) -> + {ok, #tab{id = Name}}; + true when (Action =:= clear) -> + F = fun() -> mnesia:clear_table(Name) end, + case mnesia:transaction(F) of + {aborted, Reason} -> + {error, {clear, Reason}}; + {atomic, _} -> + {ok, #tab{id = Name}} + end; + false -> + Args = [{record_name, RecName}, + {attributes, Fields}, + {type, Type}, + {disc_copies, Nodes}], + case mnesia:create_table(Name, Args) of + {atomic, ok} -> + {ok, #tab{id = Name}}; + {aborted, Reason} -> + {error, {create, Reason}} + end + end. + +table_exists(Name) -> + case (catch mnesia:table_info(Name, type)) of + {'EXIT', _Reason} -> + false; + _ -> + true + end. + + +%% --------------------------------------------------------------- +%% close +%% +%% Close the mib-storage table. +%% This does nothing in the mnesia case. +%% --------------------------------------------------------------- + +close(_) -> + ?vtrace("close mib-storage - ignore",[]), + ok. + + +%% --------------------------------------------------------------- +%% read +%% +%% Retrieve a record from the mib-storage table. +%% --------------------------------------------------------------- + +read(#tab{id = ID}, Key) -> + ?vtrace("read (dirty) from database ~p: ~p", [ID, Key]), + case (catch mnesia:dirty_read(ID, Key)) of + [Rec|_] -> {value,Rec}; + _ -> false + end. + + +%% --------------------------------------------------------------- +%% write +%% +%% Write a record to the mib-storage table. +%% --------------------------------------------------------------- + +write(#tab{id = ID}, Rec) -> + ?vtrace("write to database ~p", [ID]), + F = fun() -> mnesia:write(ID, Rec, write) end, + case mnesia:transaction(F) of + {aborted, _Reason} = ABORTED -> + {error, ABORTED}; + {atomic,_} -> + ok + end. + + +%% --------------------------------------------------------------- +%% delete +%% +%% Delete the mib-storage table. +%% --------------------------------------------------------------- + +delete(#tab{id = ID}) -> + ?vtrace("delete database: ~p", [ID]), + mnesia:delete_table(ID). + + +%% --------------------------------------------------------------- +%% delete +%% +%% Delete a record from the mib-storage table. +%% --------------------------------------------------------------- + +delete(#tab{id = ID}, Key) -> + ?vtrace("delete from database ~p: ~p", [ID, Key]), + F = fun() -> mnesia:delete(ID, Key, write) end, + case mnesia:transaction(F) of + {aborted, _Reason} = ABORTED -> + {error, ABORTED}; + {atomic, _} -> + ok + end. + + +%% --------------------------------------------------------------- +%% match_object +%% +%% Search the mib-storage table for records witch matches +%% the pattern. +%% --------------------------------------------------------------- + +match_object(#tab{id = ID}, Pattern) -> + ?vtrace("match_object in ~p of ~p", [ID, Pattern]), + F = fun() -> mnesia:match_object(ID, Pattern, read) end, + case mnesia:transaction(F) of + {aborted, _Reason} = ABORTED -> + {error, ABORTED}; + {atomic, Rs} -> + Rs + end. + + +%% --------------------------------------------------------------- +%% match_delete +%% +%% Search the mib-storage table for records witch matches +%% the pattern and deletes them from the table. +%% --------------------------------------------------------------- + +match_delete(#tab{id = ID}, Pattern) -> + ?vtrace("match_delete in ~p with pattern ~p", [ID, Pattern]), + F = fun() -> + Recs = mnesia:match_object(ID, Pattern, read), + lists:foreach(fun(Rec) -> + mnesia:delete_object(ID, Rec, write) + end, Recs), + Recs + end, + case mnesia:transaction(F) of + {aborted, _Reason} = ABORTED -> + {error, ABORTED}; + {atomic, Rs} -> + Rs + end. + + +%% --------------------------------------------------------------- +%% tab2list +%% +%% Return all records in the mib-storage table in the form of +%% a list. +%% --------------------------------------------------------------- + +tab2list(#tab{id = ID} = Tab) -> + ?vtrace("tab2list -> list of ~p", [ID]), + match_object(Tab, mnesia:table_info(ID, wild_pattern)). + + +%% --------------------------------------------------------------- +%% info +%% +%% Retrieve implementation dependent mib-storage table +%% information. +%% --------------------------------------------------------------- + +info(#tab{id = ID}) -> + case (catch mnesia:table_info(ID, all)) of + Info when is_list(Info) -> + Info; + {'EXIT', {aborted, Reason}} -> + {error, Reason} + end. + + +%% --------------------------------------------------------------- +%% sync +%% +%% Ignore +%% --------------------------------------------------------------- + +sync(_) -> + ok. + + +%% --------------------------------------------------------------- +%% backup +%% +%% Ignore. Mnesia handles its own backups. +%% --------------------------------------------------------------- + +backup(_, _) -> + ok. + + +%%---------------------------------------------------------------------- + +%% user_err(F, A) -> +%% snmpa_error:user_err(F, A). diff --git a/lib/snmp/src/agent/snmpa_supervisor.erl b/lib/snmp/src/agent/snmpa_supervisor.erl index 886fd074bc..1c8db7ff07 100644 --- a/lib/snmp/src/agent/snmpa_supervisor.erl +++ b/lib/snmp/src/agent/snmpa_supervisor.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2012. All Rights Reserved. +%% Copyright Ericsson AB 1996-2013. 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 @@ -224,25 +224,100 @@ init([AgentType, Opts]) -> ets:insert(snmp_agent_table, {error_report_mod, ErrorReportMod}), %% -- mib storage -- + %% MibStorage has only one mandatory part: module + %% Everything else is module dependent and therefor + %% put in a special option: options MibStorage = - case get_opt(mib_storage, Opts, ets) of + case get_opt(mib_storage, Opts, [{module, snmpa_mib_storage_ets}]) of + + %% --- ETS wrappers --- + + ets -> + [{module, snmpa_mib_storage_ets}]; + {ets, default} -> + [{module, snmpa_mib_storage_ets}, + {options, [{dir, filename:join([DbDir])}, + {action, keep}]}]; + {ets, Dir} when is_list(Dir) -> + [{module, snmpa_mib_storage_ets}, + {options, [{dir, filename:join([Dir])}, + {action, keep}]}]; + {ets, default, Action} when ((Action =:= keep) orelse + (Action =:= clear)) -> + [{module, snmpa_mib_storage_ets}, + {options, [{dir, filename:join([DbDir])}, + {action, Action}]}]; + {ets, Dir, Action} when is_list(Dir) andalso + ((Action =:= keep) orelse + (Action =:= clear)) -> + [{module, snmpa_mib_storage_ets}, + {options, [{dir, filename:join([Dir])}, + {action, Action}]}]; + + %% --- DETS wrappers --- + dets -> - {dets, DbDir}; + [{module, snmpa_mib_storage_dets}, + {options, [{dir, filename:join([DbDir])}, + {action, keep}]}]; {dets, default} -> - {dets, DbDir}; - {dets, default, Act} -> - {dets, DbDir, Act}; - {ets, default} -> - {ets, DbDir}; + [{module, snmpa_mib_storage_dets}, + {options, [{dir, filename:join([DbDir])}, + {action, keep}]}]; + {dets, default, Action} when ((Action =:= keep) orelse + (Action =:= clear)) -> + [{module, snmpa_mib_storage_dets}, + {options, [{dir, filename:join([DbDir])}, + {action, Action}]}]; + {dets, Dir, Action} when is_list(Dir) andalso + ((Action =:= keep) orelse + (Action =:= clear)) -> + [{module, snmpa_mib_storage_dets}, + {options, [{dir, filename:join([Dir])}, + {action, Action}]}]; + + %% --- Mnesia wrappers --- + mnesia -> - {mnesia, erlang:nodes()}; - {mnesia, visible} -> - {mnesia, erlang:nodes(visible)}; - {mnesia, connected} -> - {mnesia, erlang:nodes(connected)}; - Other -> + [{module, snmpa_mib_storage_mnesia}, + {options, [{nodes, erlang:nodes()}, + {action, keep}]}]; + {mnesia, Nodes0} -> + Nodes = + if + Nodes0 =:= visible -> + erlang:nodes(visible); + Nodes0 =:= connected -> + erlang:nodes(connected); + Nodes0 =:= [] -> + [node()]; + true -> + Nodes0 + end, + [{module, snmpa_mib_storage_mnesia}, + {options, [{nodes, Nodes}, + {action, keep}]}]; + {mnesia, Nodes0, Action} when ((Action =:= keep) orelse + (Action =:= clear)) -> + Nodes = + if + Nodes0 =:= visible -> + erlang:nodes(visible); + Nodes0 =:= connected -> + erlang:nodes(connected); + Nodes0 =:= [] -> + [node()]; + true -> + Nodes0 + end, + [{module, snmpa_mib_storage_mnesia}, + {options, [{nodes, Nodes}, + {action, Action}]}]; + + Other when is_list(Other) -> Other end, + ?vdebug("[agent table] store mib storage: ~w",[MibStorage]), ets:insert(snmp_agent_table, {mib_storage, MibStorage}), -- cgit v1.2.3 From 4e7bd62bf3b38b40eee02766b0ad68fdf75fa1c9 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 21 May 2013 15:00:42 +0200 Subject: [snmp/agent] Add mib-storage behaviour ref-man documentation --- lib/snmp/doc/src/files.mk | 1 + lib/snmp/doc/src/notes.xml | 13 +++++ lib/snmp/doc/src/ref_man.xml | 1 + lib/snmp/doc/src/snmp_app.xml | 94 +++++++++++++++++++++++++++++------ lib/snmp/doc/src/snmp_config.xml | 98 +++++++++++++++++++++++++++++++++++++ lib/snmp/doc/src/snmpa_mib_data.xml | 2 +- 6 files changed, 193 insertions(+), 16 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/doc/src/files.mk b/lib/snmp/doc/src/files.mk index e215143b03..494c550fff 100644 --- a/lib/snmp/doc/src/files.mk +++ b/lib/snmp/doc/src/files.mk @@ -42,6 +42,7 @@ XML_AGENT_REF3_FILES = \ snmpa_error_logger.xml \ snmpa_local_db.xml \ snmpa_mib_data.xml \ + snmpa_mib_storage.xml \ snmpa_mpd.xml \ snmpa_network_interface.xml \ snmpa_network_interface_filter.xml \ diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml index 2dfe347e42..b6c7c22fb0 100644 --- a/lib/snmp/doc/src/notes.xml +++ b/lib/snmp/doc/src/notes.xml @@ -56,6 +56,19 @@ data_module.

Own Id: OTP-11101

+ + +

[agent] Introduced a documented behaviour for the + mib storage. + At present there are three simple modules + (snmpa_mib_storage_ets, snmpa_mib_storage_dets and + snmpa_mib_storage_mnesia) implementíng this behaviour, + provided with the app.

+

A config option for the (agent) + mib storage + has been added to the agent config options.

+

Own Id: OTP-11107

+
diff --git a/lib/snmp/doc/src/ref_man.xml b/lib/snmp/doc/src/ref_man.xml index 2c12ac665a..628b30b11a 100644 --- a/lib/snmp/doc/src/ref_man.xml +++ b/lib/snmp/doc/src/ref_man.xml @@ -45,6 +45,7 @@ + diff --git a/lib/snmp/doc/src/snmp_app.xml b/lib/snmp/doc/src/snmp_app.xml index 9cdbcc91c5..c62c8f1541 100644 --- a/lib/snmp/doc/src/snmp_app.xml +++ b/lib/snmp/doc/src/snmp_app.xml @@ -311,8 +311,8 @@

Default is [].

- - + + ]]>

mib_storage_opt() = {module, mib_storage_module()} | {options, list()}

This option specifies how basic mib data is stored. @@ -322,21 +322,85 @@ - ]]> + -

Defines the callback mib data storage module of the - SNMP agent mib-server as defined by the - snmpa_mib_data +

Defines the mib storage module of the SNMP agent as defined by the + snmpa_mib_storage behaviour.

-

At present only the default module is provided with the agent, - snmpa_mib_data_tttn.

- -

Default module is snmpa_mib_data_tttn.

+

Several entities (mib-server via the its data module and + the symbolic-store) of the snmp agent uses this for storage + of miscelaneous mib data.

+

There are several implementations provided with the agent: + snmpa_mib_storage_ets, snmpa_mib_storage_dets and + snmpa_mib_storage_mnesia.

+

Default module is snmpa_mib_storage_ets.

+
+ + + ]]> + +

This is implementattion depended. That is, it depends on the + module. For each module a specific set of options are valid:

+ + +

snmpa_mib_storage_ets: {dir, filename()} | {action, keep | clear}, {checksum, boolean()}

+ + +

dir - If present, points to a directory where a file + to which all data in the ets table is "synced".

+

Also, when a table is opened this file is read, + if it exists.

+

By default, this will not be used.

+
+ +

action - Specifies the behaviour when a non-empty + file is found: Keep its content or clear it out.

+

Default is keep.

+
+ +

checksum - Defines if the file is checksummed + or not.

+

Default is false.

+
+
+
+ +

snmpa_mib_storage_dets: {dir, filename()} | {action, keep | clear}, {auto_save, default | pos_integer()} | {repair, force | boolean()}

+ + +

dir - This mandatory option points to a + directory where to place the file of a dets table.

+
+ +

action - Specifies the behaviour when a non-empty + file is found: Keep its content or clear it out.

+

Default is keep.

+
+ +

auto_save - Defines the dets auto-save frequency.

+

Default is default.

+
+ +

repair - Defines the dets repair behaviour.

+

Default is false.

+
+
+
+ +

snmpa_mib_storage_mnesia: {action, keep | clear}, {nodes, [node()]}

+ + +

action - Specifies the behaviour when a non-empty, + already existing, table: Keep its content or clear it out.

+

Default is keep.

+
+ +

nodes - Defines where to open the table.

+

Default is the result of the call: erlang:nodes().

+
+
+
+
diff --git a/lib/snmp/doc/src/snmp_config.xml b/lib/snmp/doc/src/snmp_config.xml index 28bfcbb3de..a88111085f 100644 --- a/lib/snmp/doc/src/snmp_config.xml +++ b/lib/snmp/doc/src/snmp_config.xml @@ -308,6 +308,103 @@

Default is [].

+ + ]]> + +

mib_storage_opt() = {module, mib_storage_module()} | {options, list()}

+

This option specifies how basic mib data is stored. + This option is used by two parts of the snmp agent: + The mib-server and the symbolic-store.

+

Default is [{module, snmpa_mib_storage_ets}].

+
+ + + + +

Defines the mib storage module of the SNMP agent as defined by the + snmpa_mib_storage + behaviour.

+

Several entities (mib-server via the its data module and + the symbolic-store) of the snmp agent uses this for storage + of miscelaneous mib data.

+

There are several implementations provided with the agent: + snmpa_mib_storage_ets, snmpa_mib_storage_dets and + snmpa_mib_storage_mnesia.

+

Default module is snmpa_mib_storage_ets.

+
+ + + ]]> + +

This is implementattion depended. That is, it depends on the + module. For each module a specific set of options are valid:

+ + +

snmpa_mib_storage_ets: {dir, filename()} | {action, keep | clear}, {checksum, boolean()}

+ + +

dir - If present, points to a directory where a file + to which all data in the ets table is "synced".

+

Also, when a table is opened this file is read, + if it exists.

+

By default, this will not be used.

+
+ +

action - Specifies the behaviour when a non-empty + file is found: Keep its content or clear it out.

+

Default is keep.

+
+ +

checksum - Defines if the file is checksummed + or not.

+

Default is false.

+
+
+
+ +

snmpa_mib_storage_dets: {dir, filename()} | {action, keep | clear}, {auto_save, default | pos_integer()} | {repair, force | boolean()}

+ + +

dir - This mandatory option points to a + directory where to place the file of a dets table.

+
+ +

action - Specifies the behaviour when a non-empty + file is found: Keep its content or clear it out.

+

Default is keep.

+
+ +

auto_save - Defines the dets auto-save frequency.

+

Default is default.

+
+ +

repair - Defines the dets repair behaviour.

+

Default is false.

+
+
+
+ +

snmpa_mib_storage_mnesia: {action, keep | clear}, {nodes, [node()]}

+ + +

action - Specifies the behaviour when a non-empty, + already existing, table: Keep its content or clear it out.

+

Default is keep.

+
+ +

nodes - Defines where to open the table.

+

Default is the result of the call: erlang:nodes().

+
+
+
+
+
+ + ]]> diff --git a/lib/snmp/doc/src/snmpa_mib_data.xml b/lib/snmp/doc/src/snmpa_mib_data.xml index 4c971ec5d9..ff07a03b98 100644 --- a/lib/snmp/doc/src/snmpa_mib_data.xml +++ b/lib/snmp/doc/src/snmpa_mib_data.xml @@ -122,7 +122,7 @@ Module:close(State) -> void() - Close the mib-storage + Close the mib-server data instance State = term() -- cgit v1.2.3 From ed33fe0a82077f3c9120cc8729d1c869a74c5bd8 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 22 May 2013 13:52:48 +0200 Subject: [snmp/agent] Removed module from app-file and make file(s) The module snmpa_general_db is no longer used (replaced by the behaviour snmpa_mib_storage and the modules implementing this behaviour). --- lib/snmp/src/agent/depend.mk | 4 ---- lib/snmp/src/agent/modules.mk | 1 - lib/snmp/src/app/snmp.app.src | 5 ++++- 3 files changed, 4 insertions(+), 6 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/depend.mk b/lib/snmp/src/agent/depend.mk index 283de54078..4b12b66e3b 100644 --- a/lib/snmp/src/agent/depend.mk +++ b/lib/snmp/src/agent/depend.mk @@ -77,10 +77,6 @@ $(EBIN)/snmpa_error_logger.$(EMULATOR): \ snmpa_error_report.erl \ snmpa_error_logger.erl -$(EBIN)/snmpa_general_db.$(EMULATOR): \ - snmpa_general_db.erl \ - ../misc/snmp_verbosity.hrl - $(EBIN)/snmpa_local_db.$(EMULATOR): \ snmpa_local_db.erl \ ../misc/snmp_debug.hrl \ diff --git a/lib/snmp/src/agent/modules.mk b/lib/snmp/src/agent/modules.mk index e8d1593a79..ea43904f4a 100644 --- a/lib/snmp/src/agent/modules.mk +++ b/lib/snmp/src/agent/modules.mk @@ -44,7 +44,6 @@ MODULES = \ snmpa_error \ snmpa_error_io \ snmpa_error_logger \ - snmpa_general_db \ snmpa_local_db \ snmpa_mib_storage_ets \ snmpa_mib_storage_dets \ diff --git a/lib/snmp/src/app/snmp.app.src b/lib/snmp/src/app/snmp.app.src index dc5acbd4a0..904d17954b 100644 --- a/lib/snmp/src/app/snmp.app.src +++ b/lib/snmp/src/app/snmp.app.src @@ -48,12 +48,15 @@ snmpa_error_io, snmpa_error_logger, snmpa_error_report, - snmpa_general_db, snmpa_local_db, snmpa_mib, snmpa_mib_data, snmpa_mib_data_tttn, snmpa_mib_lib, + snmpa_mib_storage, + snmpa_mib_storage_ets, + snmpa_mib_storage_dets, + snmpa_mib_storage_mnesia, snmpa_misc_sup, snmpa_mpd, snmpa_net_if, -- cgit v1.2.3 From b90e858649c07e6e744a2adee95f6f2d22cb63f9 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 22 May 2013 13:55:36 +0200 Subject: [snmp/agent] Deprecate *old* info conversion function --- lib/snmp/src/agent/snmpa.erl | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmpa.erl b/lib/snmp/src/agent/snmpa.erl index 785276c73d..a22f1b2eb4 100644 --- a/lib/snmp/src/agent/snmpa.erl +++ b/lib/snmp/src/agent/snmpa.erl @@ -115,6 +115,7 @@ me/0 ]). +-deprecated([{old_info_format, 1}]). -include("snmpa_atl.hrl"). -- cgit v1.2.3 From ba93ba22b3f7092a1a4ea3c10bae1e591162ba21 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 22 May 2013 14:00:16 +0200 Subject: [snmp/agent] Add default value for mib_storage for sub-agent When starting a sub-agent we previously did not provide a value for mib_storage, which was alright because ets was assumed as a default in every place where it was used. Now we expect the value to be defined and therefor we must explicitly add the default value for sub-agents when staring them. --- lib/snmp/src/agent/snmpa_agent_sup.erl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmpa_agent_sup.erl b/lib/snmp/src/agent/snmpa_agent_sup.erl index 9b8c4d12a6..2805e2dc0d 100644 --- a/lib/snmp/src/agent/snmpa_agent_sup.erl +++ b/lib/snmp/src/agent/snmpa_agent_sup.erl @@ -29,10 +29,12 @@ -export([init/1]). -define(SERVER, ?MODULE). +%% Always use plain ets for sub-agents -ifdef(snmp_debug). --define(DEFAULT_OPTS, [{verbosity, trace}]). +-define(DEFAULT_SA_OPTS, [{mib_storage, [{module, snmpa_mib_storage_ets}]}, + {verbosity, trace}]). -else. --define(DEFAULT_OPTS, []). +-define(DEFAULT_SA_OPTS, [{mib_storage, [{module, snmpa_mib_storage_ets}]}]). -endif. @@ -63,8 +65,8 @@ start_subagent(ParentAgent, Subtree, Mibs) -> Ref = make_ref(), ?d("start_subagent -> Ref: ~p", [Ref]), Options = [{priority, Prio}, - {mibs, Mibs}, - {misc_sup, snmpa_misc_sup} | ?DEFAULT_OPTS], + {mibs, Mibs}, + {misc_sup, snmpa_misc_sup} | ?DEFAULT_SA_OPTS], Agent = {{sub_agent, Max}, {snmpa_agent, start_link, [Prio, ParentAgent, Ref, Options]}, -- cgit v1.2.3 From fabfc0acd2a95178b88ce2d72714c6f8ada36558 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 22 May 2013 14:06:37 +0200 Subject: [snmp/agent] Mib server assumes no default value for mib_storage --- lib/snmp/src/agent/snmpa_mib.erl | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmpa_mib.erl b/lib/snmp/src/agent/snmpa_mib.erl index 1bd7398a69..031309b990 100644 --- a/lib/snmp/src/agent/snmpa_mib.erl +++ b/lib/snmp/src/agent/snmpa_mib.erl @@ -257,7 +257,7 @@ init([Prio, Mibs, Opts]) -> do_init(Prio, Mibs, Opts) -> process_flag(priority, Prio), process_flag(trap_exit, true), - put(sname,ms), + put(sname, ms), put(verbosity, ?vvalidate(get_verbosity(Opts))), ?vlog("starting",[]), @@ -291,8 +291,12 @@ do_init(Prio, Mibs, Opts) -> TeOverride = get_te_override(Opts), MibStorage = get_mib_storage(Opts), MibDataMod = get_data_mod(Opts), + ?vtrace("init -> try create mib data with" + "~n MeOverride: ~p" + "~n TeOverride: ~p" + "~n MibStorage: ~p", [MeOverride, TeOverride, MibStorage]), Data = MibDataMod:new(MibStorage), - ?vtrace("init -> mib data created",[]), + ?vdebug("init -> mib data created", []), case (catch mib_operations(MibDataMod, load_mib, Mibs, Data, MeOverride, TeOverride, true)) of @@ -704,7 +708,7 @@ get_te_override(Options) -> get_opt(trapentry_override, Options, false). get_mib_storage(Options) -> - get_opt(mib_storage, Options, ets). + get_opt(mib_storage, Options). get_data_mod(Options) -> get_opt(data_module, Options, snmpa_mib_data_tttn). @@ -894,6 +898,9 @@ timestamp() -> %% ---------------------------------------------------------------- +get_opt(Key, Options) -> + snmp_misc:get_option(Key, Options). + get_opt(Key, Options, Default) -> snmp_misc:get_option(Key, Options, Default). -- cgit v1.2.3 From cac3dbfed3b3f703a012f52cd7093392a70a53cc Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 22 May 2013 14:07:30 +0200 Subject: [snmp/agent] Make use of new mib_storage The new mib-storage is now used by both the mib-server and the symbolic-store. --- lib/snmp/src/agent/snmpa_mib_data_tttn.erl | 293 +++++++++++++++++----------- lib/snmp/src/agent/snmpa_symbolic_store.erl | 283 +++++++++++++++------------ 2 files changed, 337 insertions(+), 239 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmpa_mib_data_tttn.erl b/lib/snmp/src/agent/snmpa_mib_data_tttn.erl index c24cff43e5..f0bd5dabfd 100644 --- a/lib/snmp/src/agent/snmpa_mib_data_tttn.erl +++ b/lib/snmp/src/agent/snmpa_mib_data_tttn.erl @@ -18,6 +18,7 @@ %% -module(snmpa_mib_data_tttn). + %%%----------------------------------------------------------------- %%% %%% TTTN - TupleTreeTupleNodes @@ -33,7 +34,9 @@ %%% %%% When a mib is loaded, the tree is built from the plain list %%% in the binary file. +%%% %%%----------------------------------------------------------------- + -include("snmp_types.hrl"). -include("snmp_debug.hrl"). @@ -73,11 +76,15 @@ %% subagents is a list of {SAPid, Oid} %%---------------------------------------------------------------------- --record(mib_data, {mib_db, % table of #mib_info - node_db, % table of #node_info - tree_db, % table of #tree - tree, % The actual tree - subagents = []}). +-record(mib_data, + { + module, % Mib storage module + mib_db, % table of #mib_info + node_db, % table of #node_info + tree_db, % table of #tree + tree, % The actual tree + subagents = [] + }). -record(mib_info, {name, symbolic, file_name}). -record(node_info, {oid, mib_name, me}). @@ -121,7 +128,7 @@ %% This record is what is stored in the database. The 'tree' part %% is described above... --record(tree,{generation = ?DUMMY_TREE_GENERATION, root = ?DEFAULT_TREE}). +-record(tree, {generation = ?DUMMY_TREE_GENERATION, root = ?DEFAULT_TREE}). %%%====================================================================== @@ -134,32 +141,54 @@ %%----------------------------------------------------------------- %% Where -> A list of nodes where the tables will be created -new(Storage) -> +new(MibStorage) -> + Mod = snmp_misc:get_option(module, MibStorage), + Opts = snmp_misc:get_option(options, MibStorage, []), + %% First we must check if there is already something to read %% If a database already exists, then the tree structure has to be read ?vtrace("open (mib) database",[]), - MibDb = snmpa_general_db:open(Storage, ?MIB_DATA, - mib_info, - record_info(fields,mib_info), set), + MibDb = + case Mod:open(?MIB_DATA, mib_info, record_info(fields, mib_info), + set, Opts) of + {ok, T1} -> + T1; + {error, Reason1} -> + throw({error, {open, mib_data, Reason1}}) + end, + ?vtrace("open (mib) node database",[]), - NodeDb = snmpa_general_db:open(Storage, ?MIB_NODE, - node_info, - record_info(fields,node_info), set), + NodeDb = + case Mod:open(?MIB_NODE, node_info, record_info(fields, node_info), + set, Opts) of + {ok, T2} -> + T2; + {error, Reason2} -> + throw({error, {open, mib_node, Reason2}}) + end, + ?vtrace("open (mib) tree database",[]), - TreeDb = snmpa_general_db:open(Storage, ?MIB_TREE, - tree, - record_info(fields,tree), set), + TreeDb = + case Mod:open(?MIB_TREE, tree, record_info(fields, tree), + set, Opts) of + {ok, T3} -> + T3; + {error, Reason3} -> + throw({error, {open, mib_tree, Reason3}}) + end, + Tree = - case snmpa_general_db:read(TreeDb, ?DUMMY_TREE_GENERATION) of + case Mod:read(TreeDb, ?DUMMY_TREE_GENERATION) of false -> T = #tree{}, - snmpa_general_db:write(TreeDb, T), + Mod:write(TreeDb, T), T; {value, T} -> T end, - install_mibs(MibDb, NodeDb), - #mib_data{mib_db = MibDb, + install_mibs(Mod, MibDb, NodeDb), + #mib_data{module = Mod, + mib_db = MibDb, node_db = NodeDb, tree_db = TreeDb, tree = Tree}. @@ -168,7 +197,7 @@ new(Storage) -> %%---------------------------------------------------------------------- %% Returns: new mib data | {error, Reason} %%---------------------------------------------------------------------- -load_mib(MibData,FileName,MeOverride,TeOverride) +load_mib(MibData, FileName, MeOverride, TeOverride) when is_record(MibData,mib_data) andalso is_list(FileName) -> ?vlog("load mib file: ~p",[FileName]), ActualFileName = filename:rootname(FileName, ".bin") ++ ".bin", @@ -180,13 +209,14 @@ do_load_mib(MibData, ActualFileName, MibName, MeOverride, TeOverride) -> ?vtrace("do_load_mib -> entry with" "~n ActualFileName: ~s" "~n MibName: ~p",[ActualFileName, MibName]), - #mib_data{mib_db = MibDb, + #mib_data{module = Mod, + mib_db = MibDb, node_db = NodeDb, %% tree_db = TreeDb, tree = Tree} = MibData, - verify_not_loaded(MibDb, MibName), + verify_not_loaded(Mod, MibDb, MibName), ?vtrace("do_load_mib -> already loaded mibs:" - "~n ~p",[loaded(MibDb)]), + "~n ~p", [loaded(Mod, MibDb)]), Mib = do_read_mib(ActualFileName), ?vtrace("do_load_mib -> read mib ~s",[Mib#mib.name]), NonInternalMes = @@ -208,12 +238,12 @@ do_load_mib(MibData, ActualFileName, MibName, MeOverride, TeOverride) -> case (catch check_notif_and_mes(TeOverride, MeOverride, Symbolic, Mib#mib.traps, NonInternalMes)) of true -> - install_mes(NodeDb, MibName, NonInternalMes), - install_mib(MibDb, Symbolic, Mib, + install_mes(Mod, NodeDb, MibName, NonInternalMes), + install_mib(Mod, + MibDb, Symbolic, Mib, MibName, ActualFileName, NonInternalMes), ?vtrace("installed mib ~s", [Mib#mib.name]), Tree2 = Tree#tree{root = NewRoot}, - %% snmpa_general_db:write(TreeDb, Tree2), %% Store later? {ok, MibData#mib_data{tree = Tree2}}; Else -> Else @@ -221,10 +251,10 @@ do_load_mib(MibData, ActualFileName, MibName, MeOverride, TeOverride) -> end. -verify_not_loaded(Db, Name) -> - case snmpa_general_db:read(Db, Name) of +verify_not_loaded(Mod, Tab, Name) -> + case Mod:read(Tab, Name) of {value, #mib_info{name = Name}} -> - throw({error, 'already loaded'}); + throw({error, already_loaded}); false -> ok end. @@ -233,26 +263,28 @@ do_read_mib(ActualFileName) -> case snmp_misc:read_mib(ActualFileName) of {error, Reason} -> ?vlog("Failed reading mib file ~p with reason: ~p", - [ActualFileName,Reason]), + [ActualFileName, Reason]), throw({error, Reason}); {ok, Mib} -> Mib end. %% The Tree DB is handled in a special way since it can be very large. -sync(#mib_data{mib_db = M, +sync(#mib_data{module = Mod, + mib_db = M, node_db = N, tree_db = T, tree = Tree, subagents = []}) -> - snmpa_general_db:sync(M), - snmpa_general_db:sync(N), - snmpa_general_db:write(T, Tree), - snmpa_general_db:sync(T); -sync(#mib_data{mib_db = M, + Mod:sync(M), + Mod:sync(N), + Mod:write(T, Tree), + Mod:sync(T); +sync(#mib_data{module = Mod, + mib_db = M, node_db = N, tree_db = T, tree = Tree, subagents = SAs}) -> - snmpa_general_db:sync(M), - snmpa_general_db:sync(N), + Mod:sync(M), + Mod:sync(N), %% Ouch. Since the subagent info is dynamic we do not %% want to store the tree containing subagent info. So, we @@ -260,8 +292,8 @@ sync(#mib_data{mib_db = M, case delete_subagents(Tree, SAs) of {ok, TreeWithoutSAs} -> - snmpa_general_db:write(T, TreeWithoutSAs), - snmpa_general_db:sync(T); + Mod:write(T, TreeWithoutSAs), + Mod:sync(T); Error -> Error end. @@ -350,30 +382,34 @@ unload_mib(MibData, FileName, _, _) when is_list(FileName) -> do_unload_mib(MibData, MibName) -> ?vtrace("do_unload_mib -> entry with" "~n MibName: ~p", [MibName]), - #mib_data{mib_db = MibDb, + #mib_data{module = Mod, + mib_db = MibDb, node_db = NodeDb, %% tree_db = TreeDb, tree = Tree} = MibData, - #mib_info{symbolic = Symbolic} = verify_loaded(MibDb, MibName), + #mib_info{symbolic = Symbolic} = verify_loaded(Mod, MibDb, MibName), NewRoot = delete_mib_from_tree(MibName, Tree#tree.root), - MEs = uninstall_mes(NodeDb, MibName), - uninstall_mib(MibDb, Symbolic, MibName, MEs), + MEs = uninstall_mes(Mod, NodeDb, MibName), + uninstall_mib(Mod, MibDb, Symbolic, MibName, MEs), NewMibData = MibData#mib_data{tree = Tree#tree{root = NewRoot}}, {ok, NewMibData}. -verify_loaded(Db, Name) -> - case snmpa_general_db:read(Db, Name) of +verify_loaded(Mod, Tab, Name) -> + case Mod:read(Tab, Name) of {value, MibInfo} -> MibInfo; false -> - throw({error, 'not loaded'}) + throw({error, not_loaded}) end. -close(#mib_data{mib_db = MibDb, node_db = NodeDb, tree_db = TreeDb}) -> - snmpa_general_db:close(MibDb), - snmpa_general_db:close(NodeDb), - snmpa_general_db:close(TreeDb), +close(#mib_data{module = Mod, + mib_db = MibDb, + node_db = NodeDb, + tree_db = TreeDb}) -> + Mod:close(MibDb), + Mod:close(NodeDb), + Mod:close(TreeDb), ok. register_subagent(#mib_data{tree = T} = MibData, Oid, Pid) -> @@ -392,8 +428,8 @@ register_subagent(#mib_data{tree = T} = MibData, Oid, Pid) -> %% Returns: [{Name, File}] %%---------------------------------------------------------------------- -which_mibs(#mib_data{mib_db = Db}) -> - Mibs = snmpa_general_db:tab2list(Db), +which_mibs(#mib_data{module = Mod, mib_db = Db}) -> + Mibs = Mod:tab2list(Db), [{Name, File} || #mib_info{name = Name, file_name = File} <- Mibs]. @@ -402,8 +438,8 @@ which_mibs(#mib_data{mib_db = Db}) -> %% Returns: [{Name, File}] %%---------------------------------------------------------------------- -whereis_mib(#mib_data{mib_db = Db}, Name) -> - case snmpa_general_db:read(Db, Name) of +whereis_mib(#mib_data{module = Mod, mib_db = Db}, Name) -> + case Mod:read(Db, Name) of {value, #mib_info{file_name = File}} -> {ok, File}; false -> @@ -451,32 +487,39 @@ unregister_subagent(#mib_data{tree = T} = MibData, Oid) when is_list(Oid) -> %%---------------------------------------------------------------------- info(MibData) -> ?vtrace("retrieve info",[]), - #mib_data{mib_db = MibDb, node_db = NodeDb, tree_db = TreeDb, - tree = Tree, subagents = SAs} = MibData, - LoadedMibs = old_format(snmpa_general_db:tab2list(MibDb)), + #mib_data{module = Mod, + mib_db = MibDb, + node_db = NodeDb, + tree_db = TreeDb, + tree = Tree, + subagents = SAs} = MibData, + LoadedMibs = old_format(Mod:tab2list(MibDb)), TreeSize = snmp_misc:mem_size(Tree), - {memory, ProcSize} = erlang:process_info(self(),memory), - MibDbSize = snmpa_general_db:info(MibDb, memory), - NodeDbSize = snmpa_general_db:info(NodeDb, memory), - TreeDbSize = snmpa_general_db:info(TreeDb, memory), + {memory, ProcSize} = erlang:process_info(self(), memory), + MibDbSize = Mod:info(MibDb, memory), + NodeDbSize = Mod:info(NodeDb, memory), + TreeDbSize = Mod:info(TreeDb, memory), [{loaded_mibs, LoadedMibs}, {subagents, SAs}, {tree_size_bytes, TreeSize}, {process_memory, ProcSize}, {db_memory, [{mib,MibDbSize},{node,NodeDbSize},{tree,TreeDbSize}]}]. -info(#mib_data{mib_db = MibDb}, loaded_mibs) -> - Mibs = snmpa_general_db:tab2list(MibDb), +info(#mib_data{module = Mod, mib_db = MibDb}, loaded_mibs) -> + Mibs = Mod:tab2list(MibDb), [filename:rootname(FN, ".bin") || #mib_info{file_name = FN} <- Mibs]; info(#mib_data{tree = Tree}, tree_size_bytes) -> snmp_misc:mem_size(Tree); info(_, process_memory) -> {memory, ProcSize} = erlang:process_info(self(),memory), ProcSize; -info(#mib_data{mib_db = MibDb, node_db = NodeDb, tree_db = TreeDb}, +info(#mib_data{module = Mod, + mib_db = MibDb, + node_db = NodeDb, + tree_db = TreeDb}, db_memory) -> - MibDbSize = snmpa_general_db:info(MibDb, memory), - NodeDbSize = snmpa_general_db:info(NodeDb, memory), - TreeDbSize = snmpa_general_db:info(TreeDb, memory), - [{mib,MibDbSize},{node,NodeDbSize},{tree,TreeDbSize}]; + MibDbSize = Mod:info(MibDb, memory), + NodeDbSize = Mod:info(NodeDb, memory), + TreeDbSize = Mod:info(TreeDb, memory), + [{mib, MibDbSize}, {node, NodeDbSize}, {tree, TreeDbSize}]; info(#mib_data{subagents = SAs}, subagents) -> SAs. @@ -489,17 +532,19 @@ old_format(LoadedMibs) -> %% A total dump for debugging. %%---------------------------------------------------------------------- -dump(#mib_data{mib_db = MibDb, +dump(#mib_data{module = Mod, + mib_db = MibDb, node_db = NodeDb, tree = Tree}, io) -> (catch io:format("MIB-tables:~n~p~n~n", - [snmpa_general_db:tab2list(MibDb)])), + [Mod:tab2list(MibDb)])), (catch io:format("MIB-entries:~n~p~n~n", - [snmpa_general_db:tab2list(NodeDb)])), + [Mod:tab2list(NodeDb)])), (catch io:format("Tree:~n~p~n", [Tree])), % good luck reading it! ok; -dump(#mib_data{mib_db = MibDb, +dump(#mib_data{module = Mod, + mib_db = MibDb, node_db = NodeDb, tree = Tree}, File) -> case file:open(File, [write]) of @@ -507,9 +552,9 @@ dump(#mib_data{mib_db = MibDb, io:format(Fd,"~s~n", [snmp:date_and_time_to_string(snmp:date_and_time())]), (catch io:format(Fd,"MIB-tables:~n~p~n~n", - [snmpa_general_db:tab2list(MibDb)])), + [Mod:tab2list(MibDb)])), (catch io:format(Fd, "MIB-entries:~n~p~n~n", - [snmpa_general_db:tab2list(NodeDb)])), + [Mod:tab2list(NodeDb)])), io:format(Fd,"Tree:~n~p~n", [Tree]), % good luck reading it! file:close(Fd), ok; @@ -520,10 +565,13 @@ dump(#mib_data{mib_db = MibDb, end. -backup(#mib_data{mib_db = M, node_db = N, tree_db = T}, BackupDir) -> - MRes = snmpa_general_db:backup(M, BackupDir), - NRes = snmpa_general_db:backup(N, BackupDir), - TRes = snmpa_general_db:backup(T, BackupDir), +backup(#mib_data{module = Mod, + mib_db = M, + node_db = N, + tree_db = T}, BackupDir) -> + MRes = Mod:backup(M, BackupDir), + NRes = Mod:backup(N, BackupDir), + TRes = Mod:backup(T, BackupDir), handle_backup_res([{mib_db, MRes}, {node_db, NRes}, {tree_db, TRes}]). handle_backup_res(Res) -> @@ -632,9 +680,9 @@ find_node(D, {tree, Tree, {table_entry, _}}, RestOfOid, RevOid) -> ?vtrace("find_node(tree,table_entry) -> entry with" "~n RestOfOid: ~p" "~n RevOid: ~p",[RestOfOid, RevOid]), - #mib_data{node_db = Db} = D, + #mib_data{module = Mod, node_db = Db} = D, Oid = lists:reverse(RevOid), - case snmpa_general_db:read(Db, Oid) of + case Mod:read(Db, Oid) of {value, #node_info{me = ME, mib_name = Mib}} -> case find_node(D, {tree, Tree, internal}, RestOfOid, RevOid) of {false, ErrorCode} -> {false, ErrorCode}; @@ -659,13 +707,13 @@ find_node(D, {node, {table_column, _}}, RestOfOid, [ColInt | RevOid]) -> "~n RestOfOid: ~p" "~n ColInt: ~p" "~n RevOid: ~p",[RestOfOid, ColInt, RevOid]), - #mib_data{node_db = Db} = D, + #mib_data{module = Mod, node_db = Db} = D, Oid = lists:reverse([ColInt | RevOid]), - case snmpa_general_db:read(Db, Oid) of + case Mod:read(Db, Oid) of {value, #node_info{me = ME}} -> {ME, lists:reverse(RevOid)}; false -> - X = snmpa_general_db:read(Db, lists:reverse([ColInt | RevOid])), + X = Mod:read(Db, lists:reverse([ColInt | RevOid])), ?vinfo("find_node -> could not find table_column ME with" "~n RevOid: ~p" "~n trying [~p|~p]" @@ -676,10 +724,9 @@ find_node(D, {node, {table_column, _}}, RestOfOid, [ColInt | RevOid]) -> find_node(D, {node, {variable, _MibName}}, [0], RevOid) -> ?vtrace("find_node(tree,variable,[0]) -> entry with" "~n RevOid: ~p",[RevOid]), - #mib_data{node_db = Db} = D, + #mib_data{module = Mod, node_db = Db} = D, Oid = lists:reverse(RevOid), - %% {value, #node_info{me = ME}} = snmpa_general_db:read(Db, Oid), - case snmpa_general_db:read(Db, Oid) of + case Mod:read(Db, Oid) of {value, #node_info{me = ME, mib_name = Mib}} -> {variable, ME, Mib}; false -> @@ -761,8 +808,8 @@ next_node(D, {tree, Tree, {table_entry, _MibName}}, ?vdebug("next_node(tree,table_entry) -> not in mib view",[]), false; _ -> - #mib_data{node_db = Db} = D, - case snmpa_general_db:read(Db, OidSoFar) of + #mib_data{module = Mod, node_db = Db} = D, + case Mod:read(Db, OidSoFar) of false -> ?vinfo("next_node -> could not find table_entry with" "~n OidSoFar: ~p", [OidSoFar]), @@ -834,8 +881,8 @@ next_node(D, {node, {variable, _MibName}}, [], RevOidSoFar, MibView) -> OidSoFar = lists:reverse([0 | RevOidSoFar]), case snmpa_acm:validate_mib_view(OidSoFar, MibView) of true -> - #mib_data{node_db = Db} = D, - case snmpa_general_db:read(Db, lists:reverse(RevOidSoFar)) of + #mib_data{module = Mod, node_db = Db} = D, + case Mod:read(Db, lists:reverse(RevOidSoFar)) of false -> ?vinfo("next_node -> could not find variable with" "~n RevOidSoFar: ~p", [RevOidSoFar]), @@ -851,6 +898,7 @@ next_node(_D, {node, {variable, _MibName}}, _Oid, _RevOidSoFar, _MibView) -> ?vtrace("next_node(node,variable) -> entry", []), false. + %%----------------------------------------------------------------- %% This function is used to find the first leaf from where we %% are. @@ -882,8 +930,8 @@ find_next(D, {tree, _Tree, {table_entry, _MibName}}, _Index, true -> false; _ -> - #mib_data{node_db = Db} = D, - case snmpa_general_db:read(Db, OidSoFar) of + #mib_data{module = Mod, node_db = Db} = D, + case Mod:read(Db, OidSoFar) of false -> ?vinfo("find_next -> could not find table_entry ME with" "~n OidSoFar: ~p", [OidSoFar]), @@ -896,8 +944,8 @@ find_next(D, {node, {variable, _MibName}}, _Idx, RevOidSoFar, MibView) -> OidSoFar = lists:reverse([0 | RevOidSoFar]), case snmpa_acm:validate_mib_view(OidSoFar, MibView) of true -> - #mib_data{node_db = Db} = D, - case snmpa_general_db:read(Db, lists:reverse(RevOidSoFar)) of + #mib_data{module = Mod, node_db = Db} = D, + case Mod:read(Db, lists:reverse(RevOidSoFar)) of false -> ?vinfo("find_next -> could not find variable with" "~n RevOidSoFar: ~p", [RevOidSoFar]), @@ -1213,9 +1261,11 @@ build_tree_for_subagent([Index]) -> build_tree_for_subagent([Index | T]) -> [{Index, {tree, build_tree_for_subagent(T), internal}}]. + %%---------------------------------------------------------------------- %% Returns: A new tree where the subagent at Oid (2nd arg) has been deleted. %%---------------------------------------------------------------------- + delete_subagent({tree, Tree, Info}, [Index]) -> {node, subagent} = element(Index+1, Tree), {tree, setelement(Index+1, Tree, undefined_node), Info}; @@ -1223,6 +1273,7 @@ delete_subagent({tree, Tree, Info}, [Index | TI]) -> {tree, setelement(Index+1, Tree, delete_subagent(element(Index+1, Tree), TI)), Info}. + %%%====================================================================== %%% 7. Misc functions %%%====================================================================== @@ -1232,35 +1283,35 @@ delete_subagent({tree, Tree, Info}, [Index | TI]) -> %% Basically calls the instrumentation functions for all non-internal %% mib-entries %%---------------------------------------------------------------------- -install_mibs(MibDb, NodeDb) -> - MibNames = loaded(MibDb), +install_mibs(Mod, MibDb, NodeDb) -> + MibNames = loaded(Mod, MibDb), ?vtrace("install_mibs -> found following mibs in database: ~n" "~p", [MibNames]), - install_mibs2(NodeDb, MibNames). + install_mibs2(Mod, NodeDb, MibNames). -install_mibs2(_, []) -> +install_mibs2(_, _, []) -> ok; -install_mibs2(NodeDb, [MibName|MibNames]) -> +install_mibs2(Mod, NodeDb, [MibName|MibNames]) -> Pattern = #node_info{oid = '_', mib_name = MibName, me = '_'}, - Nodes = snmpa_general_db:match_object(NodeDb, Pattern), + Nodes = Mod:match_object(NodeDb, Pattern), MEs = [ME || #node_info{me = ME} <- Nodes], ?vtrace("install_mibs2 -> installing ~p MEs for mib ~p", - [length(MEs),MibName]), + [length(MEs), MibName]), NewF = fun(ME) -> call_instrumentation(ME, new) end, lists:foreach(NewF, MEs), - install_mibs2(NodeDb, MibNames). + install_mibs2(Mod, NodeDb, MibNames). %%---------------------------------------------------------------------- %% Does all side effect stuff during load_mib. %%---------------------------------------------------------------------- -install_mib(Db, Symbolic, Mib, MibName, FileName, NonInternalMes) -> +install_mib(Mod, Db, Symbolic, Mib, MibName, FileName, NonInternalMes) -> ?vdebug("install_mib -> entry with" "~n Symbolic: ~p" "~n MibName: ~p" "~n FileName: ~p", [Symbolic, MibName, FileName]), Rec = #mib_info{name = MibName, symbolic = Symbolic, file_name = FileName}, - snmpa_general_db:write(Db, Rec), + Mod:write(Db, Rec), install_mib2(Symbolic, MibName, Mib), NewF = fun(ME) -> call_instrumentation(ME, new) end, lists:foreach(NewF, NonInternalMes). @@ -1282,23 +1333,31 @@ install_mib2(true, MibName, Mib) -> install_mib2(_, _, _) -> ok. -install_mes(_Db, _MibName, []) -> +install_mes(Mod, Db, MibName, MEs) -> + Write = fun(#me{oid = Oid} = ME) -> + Node = #node_info{oid = Oid, + mib_name = MibName, + me = ME}, + Mod:write(Db, Node) + end, + install_mes(Write, MEs). + +install_mes(_Write, []) -> ok; -install_mes(Db, MibName, [ME|MEs]) -> - Node = #node_info{oid = ME#me.oid, mib_name = MibName, me = ME}, - snmpa_general_db:write(Db, Node), - install_mes(Db, MibName, MEs). +install_mes(Write, [ME|MEs]) -> + Write(ME), + install_mes(Write, MEs). %%---------------------------------------------------------------------- %% Does all side effect stuff during unload_mib. %%---------------------------------------------------------------------- -uninstall_mib(Db, Symbolic, MibName, MEs) -> +uninstall_mib(Mod, Db, Symbolic, MibName, MEs) -> ?vtrace("uninstall_mib -> entry with" "~n Db: ~p" "~n Symbolic: ~p" "~n MibName: ~p", [Db, Symbolic, MibName]), - Res = snmpa_general_db:delete(Db, MibName), + Res = Mod:delete(Db, MibName), ?vtrace("uninstall_mib -> (mib) db delete result: ~p", [Res]), uninstall_mib2(Symbolic, MibName), DelF = fun(ME) -> call_instrumentation(ME, delete) end, @@ -1313,16 +1372,16 @@ uninstall_mib2(true, MibName) -> uninstall_mib2(_, _) -> ok. -uninstall_mes(Db, MibName) -> +uninstall_mes(Mod, Db, MibName) -> Pattern = #node_info{oid = '_', mib_name = MibName, me = '_'}, - snmpa_general_db:match_delete(Db, Pattern). + Mod:match_delete(Db, Pattern). %%---------------------------------------------------------------------- %% Create a list of the names of all the loaded mibs %%---------------------------------------------------------------------- -loaded(Db) -> - [N || #mib_info{name = N} <- snmpa_general_db:tab2list(Db)]. +loaded(Mod, Db) -> + [N || #mib_info{name = N} <- Mod:tab2list(Db)]. %%---------------------------------------------------------------------- diff --git a/lib/snmp/src/agent/snmpa_symbolic_store.erl b/lib/snmp/src/agent/snmpa_symbolic_store.erl index 6c58ffde41..00178f4bcd 100644 --- a/lib/snmp/src/agent/snmpa_symbolic_store.erl +++ b/lib/snmp/src/agent/snmpa_symbolic_store.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. +%% Copyright Ericsson AB 1996-2013. 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 @@ -78,7 +78,7 @@ gen_server:start_link({local, ?SERVER}, ?MODULE, [Prio, Opts], [])). -endif. --record(state, {db, backup}). +-record(state, {module, db, backup}). -record(symbol, {key, mib_name, info}). @@ -112,6 +112,9 @@ backup(BackupDir) -> get_db() -> call(get_db). +which_module() -> + call(which_module). + %%---------------------------------------------------------------------- %% Returns: {value, Oid} | false @@ -202,49 +205,63 @@ verbosity(Verbosity) -> %%---------------------------------------------------------------------- %% DB access (read) functions: Returns: {value, Oid} | false %%---------------------------------------------------------------------- + aliasname_to_oid(Db, Aliasname) -> - case snmpa_general_db:read(Db, {alias, Aliasname}) of + Mod = which_module(), + aliasname_to_oid(Mod, Db, Aliasname). + +aliasname_to_oid(Mod, Db, Aliasname) -> + case Mod:read(Db, {alias, Aliasname}) of {value,#symbol{info = {Oid, _Enums}}} -> {value, Oid}; false -> false end. -oid_to_aliasname(Db,Oid) -> - case snmpa_general_db:read(Db, {oid, Oid}) of +oid_to_aliasname(Db, Oid) -> + Mod = which_module(), + oid_to_aliasname(Mod, Db, Oid). + +oid_to_aliasname(Mod, Db, Oid) -> + case Mod:read(Db, {oid, Oid}) of {value,#symbol{info = Aliasname}} -> {value, Aliasname}; _ -> false end. -which_notifications(Db) -> +which_notifications(Mod, Db) -> Pattern = #symbol{key = {trap, '_'}, _ = '_'}, - Symbols = snmpa_general_db:match_object(Db, Pattern), + Symbols = Mod:match_object(Db, Pattern), [{Name, Mib, Rec} || #symbol{key = {trap, Name}, mib_name = Mib, info = Rec} <- Symbols]. -which_aliasnames(Db) -> +which_aliasnames(Mod, Db) -> Pattern = #symbol{key = {alias, '_'}, _ = '_'}, - Symbols = snmpa_general_db:match_object(Db, Pattern), + Symbols = Mod:match_object(Db, Pattern), [Alias || #symbol{key = {alias, Alias}} <- Symbols]. -which_tables(Db) -> +which_tables(Mod, Db) -> Pattern = #symbol{key = {table_info, '_'}, _ = '_'}, - Symbols = snmpa_general_db:match_object(Db, Pattern), + Symbols = Mod:match_object(Db, Pattern), [Name || #symbol{key = {table_info, Name}} <- Symbols]. -which_variables(Db) -> +which_variables(Mod, Db) -> Pattern = #symbol{key = {variable_info, '_'}, _ = '_'}, - Symbols = snmpa_general_db:match_object(Db, Pattern), + Symbols = Mod:match_object(Db, Pattern), [Name || #symbol{key = {variable_info, Name}} <- Symbols]. -int_to_enum(Db,TypeOrObjName,Int) -> - case snmpa_general_db:read(Db, {alias, TypeOrObjName}) of + +int_to_enum(Db, TypeOrObjName, Int) -> + Mod = which_module(), + int_to_enum(Mod, Db, TypeOrObjName, Int). + +int_to_enum(Mod, Db, TypeOrObjName, Int) -> + case Mod:read(Db, {alias, TypeOrObjName}) of {value,#symbol{info = {_Oid, Enums}}} -> case lists:keysearch(Int, 2, Enums) of {value, {Enum, _Int}} -> {value, Enum}; false -> false end; false -> % Not an Aliasname -> - case snmpa_general_db:read(Db, {type, TypeOrObjName}) of + case Mod:read(Db, {type, TypeOrObjName}) of {value,#symbol{info = Enums}} -> case lists:keysearch(Int, 2, Enums) of {value, {Enum, _Int}} -> {value, Enum}; @@ -256,14 +273,18 @@ int_to_enum(Db,TypeOrObjName,Int) -> end. enum_to_int(Db, TypeOrObjName, Enum) -> - case snmpa_general_db:read(Db, {alias, TypeOrObjName}) of + Mod = which_module(), + enum_to_int(Mod, Db, TypeOrObjName, Enum). + +enum_to_int(Mod, Db, TypeOrObjName, Enum) -> + case Mod:read(Db, {alias, TypeOrObjName}) of {value,#symbol{info = {_Oid, Enums}}} -> case lists:keysearch(Enum, 1, Enums) of {value, {_Enum, Int}} -> {value, Int}; false -> false end; false -> % Not an Aliasname - case snmpa_general_db:read(Db, {type, TypeOrObjName}) of + case Mod:read(Db, {type, TypeOrObjName}) of {value,#symbol{info = Enums}} -> case lists:keysearch(Enum, 1, Enums) of {value, {_Enum, Int}} -> {value, Int}; @@ -278,8 +299,9 @@ enum_to_int(Db, TypeOrObjName, Enum) -> %%---------------------------------------------------------------------- %% DB access (read) functions: Returns: false|{value, Info} %%---------------------------------------------------------------------- -table_info(Db,TableName) -> - case snmpa_general_db:read(Db, {table_info, TableName}) of + +table_info(Mod, Db, TableName) -> + case Mod:read(Db, {table_info, TableName}) of {value,#symbol{info = Info}} -> {value, Info}; false -> false end. @@ -288,8 +310,8 @@ table_info(Db,TableName) -> %%---------------------------------------------------------------------- %% DB access (read) functions: Returns: false|{value, Info} %%---------------------------------------------------------------------- -variable_info(Db,VariableName) -> - case snmpa_general_db:read(Db, {variable_info, VariableName}) of +variable_info(Mod, Db, VariableName) -> + case Mod:read(Db, {variable_info, VariableName}) of {value,#symbol{info = Info}} -> {value, Info}; false -> false end. @@ -299,7 +321,7 @@ variable_info(Db,VariableName) -> %% Implementation %%---------------------------------------------------------------------- -init([Prio,Opts]) -> +init([Prio, Opts]) -> ?d("init -> entry with" "~n Prio: ~p" "~n Opts: ~p", [Prio,Opts]), @@ -317,102 +339,125 @@ do_init(Prio, Opts) -> put(sname,ss), put(verbosity,get_verbosity(Opts)), ?vlog("starting",[]), - Storage = get_mib_storage(Opts), + MibStorage = get_mib_storage(Opts), + Mod = snmp_misc:get_option(module, MibStorage), + MsOpts = snmp_misc:get_option(options, MibStorage, []), + %% type = bag solves the problem with import and multiple %% object/type definitions. - Db = snmpa_general_db:open(Storage, snmpa_symbolic_store, - symbol, record_info(fields,symbol), bag), - S = #state{db = Db}, - ?vdebug("started",[]), - {ok, S}. + case Mod:open(?MODULE, symbol, record_info(fields, symbol), bag, MsOpts) of + {ok, Db} -> + S = #state{module = Mod, db = Db}, + ?vdebug("started",[]), + {ok, S}; + {error, _} = ERROR -> + ERROR + end. handle_call(get_db, _From, #state{db = DB} = S) -> ?vlog("get db",[]), {reply, DB, S}; -handle_call({table_info, TableName}, _From, #state{db = DB} = S) -> +handle_call(which_module, _From, #state{module = Mod} = S) -> + ?vlog("which module",[]), + {reply, Mod, S}; + +handle_call({table_info, TableName}, _From, + #state{module = Mod, db = DB} = S) -> ?vlog("table info: ~p",[TableName]), - Res = table_info(DB, TableName), + Res = table_info(Mod, DB, TableName), ?vdebug("table info result: ~p",[Res]), {reply, Res, S}; -handle_call({variable_info, VariableName}, _From, #state{db = DB} = S) -> +handle_call({variable_info, VariableName}, _From, + #state{module = Mod, db = DB} = S) -> ?vlog("variable info: ~p",[VariableName]), - Res = variable_info(DB, VariableName), + Res = variable_info(Mod, DB, VariableName), ?vdebug("variable info result: ~p",[Res]), {reply, Res, S}; -handle_call({aliasname_to_oid, Aliasname}, _From, #state{db = DB} = S) -> +handle_call({aliasname_to_oid, Aliasname}, _From, + #state{module = Mod, db = DB} = S) -> ?vlog("aliasname to oid: ~p",[Aliasname]), - Res = aliasname_to_oid(DB,Aliasname), + Res = aliasname_to_oid(Mod, DB, Aliasname), ?vdebug("aliasname to oid result: ~p",[Res]), {reply, Res, S}; -handle_call({oid_to_aliasname, Oid}, _From, #state{db = DB} = S) -> +handle_call({oid_to_aliasname, Oid}, _From, + #state{module = Mod, db = DB} = S) -> ?vlog("oid to aliasname: ~p",[Oid]), - Res = oid_to_aliasname(DB, Oid), + Res = oid_to_aliasname(Mod, DB, Oid), ?vdebug("oid to aliasname result: ~p",[Res]), {reply, Res, S}; -handle_call(which_aliasnames, _From, #state{db = DB} = S) -> +handle_call(which_aliasnames, _From, + #state{module = Mod, db = DB} = S) -> ?vlog("which aliasnames",[]), - Res = which_aliasnames(DB), + Res = which_aliasnames(Mod, DB), ?vdebug("which aliasnames: ~p",[Res]), {reply, Res, S}; -handle_call(which_tables, _From, #state{db = DB} = S) -> +handle_call(which_tables, _From, + #state{module = Mod, db = DB} = S) -> ?vlog("which tables",[]), - Res = which_tables(DB), + Res = which_tables(Mod, DB), ?vdebug("which tables: ~p",[Res]), {reply, Res, S}; -handle_call(which_variables, _From, #state{db = DB} = S) -> +handle_call(which_variables, _From, + #state{module = Mod, db = DB} = S) -> ?vlog("which variables",[]), - Res = which_variables(DB), + Res = which_variables(Mod, DB), ?vdebug("which variables: ~p",[Res]), {reply, Res, S}; -handle_call({enum_to_int, TypeOrObjName, Enum}, _From, #state{db = DB} = S) -> +handle_call({enum_to_int, TypeOrObjName, Enum}, _From, + #state{module = Mod, db = DB} = S) -> ?vlog("enum to int: ~p, ~p",[TypeOrObjName,Enum]), - Res = enum_to_int(DB, TypeOrObjName, Enum), + Res = enum_to_int(Mod, DB, TypeOrObjName, Enum), ?vdebug("enum to int result: ~p",[Res]), {reply, Res, S}; -handle_call({int_to_enum, TypeOrObjName, Int}, _From, #state{db = DB} = S) -> +handle_call({int_to_enum, TypeOrObjName, Int}, _From, + #state{module = Mod, db = DB} = S) -> ?vlog("int to enum: ~p, ~p",[TypeOrObjName,Int]), - Res = int_to_enum(DB, TypeOrObjName, Int), + Res = int_to_enum(Mod, DB, TypeOrObjName, Int), ?vdebug("int to enum result: ~p",[Res]), {reply, Res, S}; -handle_call({set_notification, MibName, Trap}, _From, #state{db = DB} = S) -> +handle_call({set_notification, MibName, Trap}, _From, + #state{module = Mod, db = DB} = S) -> ?vlog("set notification:" "~n ~p~n ~p", [MibName,Trap]), - set_notif(DB, MibName, Trap), + set_notif(Mod, DB, MibName, Trap), {reply, true, S}; -handle_call({delete_notifications, MibName}, _From, #state{db = DB} = S) -> +handle_call({delete_notifications, MibName}, _From, + #state{module = Mod, db = DB} = S) -> ?vlog("delete notification: ~p",[MibName]), - delete_notif(DB, MibName), + delete_notif(Mod, DB, MibName), {reply, true, S}; -handle_call(which_notifications, _From, #state{db = DB} = S) -> +handle_call(which_notifications, _From, + #state{module = Mod, db = DB} = S) -> ?vlog("which notifications", []), - Reply = which_notifications(DB), + Reply = which_notifications(Mod, DB), {reply, Reply, S}; -handle_call({get_notification, Key}, _From, #state{db = DB} = S) -> +handle_call({get_notification, Key}, _From, + #state{module = Mod, db = DB} = S) -> ?vlog("get notification: ~p",[Key]), - Res = get_notif(DB, Key), + Res = get_notif(Mod, DB, Key), ?vdebug("get notification result: ~p",[Res]), {reply, Res, S}; -handle_call(info, _From, #state{db = DB} = S) -> +handle_call(info, _From, #state{module = Mod, db = DB} = S) -> ?vlog("info",[]), - Info = get_info(DB), + Info = get_info(Mod, DB), {reply, Info, S}; -handle_call({backup, BackupDir}, From, #state{db = DB} = S) -> +handle_call({backup, BackupDir}, From, #state{module = Mod, db = DB} = S) -> ?vlog("info to ~p",[BackupDir]), Pid = self(), V = get(verbosity), @@ -424,7 +469,7 @@ handle_call({backup, BackupDir}, From, #state{db = DB} = S) -> put(sname, albs), put(verbosity, V), Dir = filename:join([BackupDir]), - Reply = snmpa_general_db:backup(DB, Dir), + Reply = Mod:backup(DB, Dir), Pid ! {backup_done, Reply}, unlink(Pid) end), @@ -446,7 +491,7 @@ handle_call(Req, _From, S) -> {reply, Reply, S}. -handle_cast({add_types, MibName, Types}, #state{db = DB} = S) -> +handle_cast({add_types, MibName, Types}, #state{module = Mod, db = DB} = S) -> ?vlog("add types for ~p:",[MibName]), F = fun(#asn1_type{assocList = Alist, aliasname = Name}) -> case snmp_misc:assq(enums, Alist) of @@ -455,20 +500,21 @@ handle_cast({add_types, MibName, Types}, #state{db = DB} = S) -> Rec = #symbol{key = {type, Name}, mib_name = MibName, info = Es}, - snmpa_general_db:write(DB, Rec); + Mod:write(DB, Rec); false -> done end end, lists:foreach(F, Types), {noreply, S}; -handle_cast({delete_types, MibName}, #state{db = DB} = S) -> +handle_cast({delete_types, MibName}, #state{module = Mod, db = DB} = S) -> ?vlog("delete types: ~p",[MibName]), Pattern = #symbol{key = {type, '_'}, mib_name = MibName, info = '_'}, - snmpa_general_db:match_delete(DB, Pattern), + Mod:match_delete(DB, Pattern), {noreply, S}; -handle_cast({add_aliasnames, MibName, MEs}, #state{db = DB} = S) -> +handle_cast({add_aliasnames, MibName, MEs}, + #state{module = Mod, db = DB} = S) -> ?vlog("add aliasnames for ~p:",[MibName]), F = fun(#me{aliasname = AN, oid = Oid, asn1_type = AT}) -> Enums = @@ -480,20 +526,21 @@ handle_cast({add_aliasnames, MibName, MEs}, #state{db = DB} = S) -> end; _ -> [] end, - write_alias(AN, DB, Enums, MibName, Oid) + write_alias(Mod, AN, DB, Enums, MibName, Oid) end, lists:foreach(F, MEs), {noreply, S}; -handle_cast({delete_aliasname, MibName}, #state{db = DB} = S) -> +handle_cast({delete_aliasname, MibName}, #state{module = Mod, db = DB} = S) -> ?vlog("delete aliasname: ~p",[MibName]), Pattern1 = #symbol{key = {alias, '_'}, mib_name = MibName, info = '_'}, - snmpa_general_db:match_delete(DB, Pattern1), + Mod:match_delete(DB, Pattern1), Pattern2 = #symbol{key = {oid, '_'}, mib_name = MibName, info = '_'}, - snmpa_general_db:match_delete(DB, Pattern2), + Mod:match_delete(DB, Pattern2), {noreply, S}; -handle_cast({add_table_infos, MibName, TableInfos}, #state{db = DB} = S) -> +handle_cast({add_table_infos, MibName, TableInfos}, + #state{module = Mod, db = DB} = S) -> ?vlog("add table infos for ~p:",[MibName]), F = fun({Name, TableInfo}) -> ?vlog("add table info~n ~p -> ~p", @@ -501,19 +548,20 @@ handle_cast({add_table_infos, MibName, TableInfos}, #state{db = DB} = S) -> Rec = #symbol{key = {table_info, Name}, mib_name = MibName, info = TableInfo}, - snmpa_general_db:write(DB, Rec) + Mod:write(DB, Rec) end, lists:foreach(F, TableInfos), {noreply, S}; -handle_cast({delete_table_infos, MibName}, #state{db = DB} = S) -> +handle_cast({delete_table_infos, MibName}, + #state{module = Mod, db = DB} = S) -> ?vlog("delete table infos: ~p",[MibName]), Pattern = #symbol{key = {table_info, '_'}, mib_name = MibName, info = '_'}, - snmpa_general_db:match_delete(DB, Pattern), + Mod:match_delete(DB, Pattern), {noreply, S}; handle_cast({add_variable_infos, MibName, VariableInfos}, - #state{db = DB} = S) -> + #state{module = Mod, db = DB} = S) -> ?vlog("add variable infos for ~p:",[MibName]), F = fun({Name, VariableInfo}) -> ?vlog("add variable info~n ~p -> ~p", @@ -521,17 +569,18 @@ handle_cast({add_variable_infos, MibName, VariableInfos}, Rec = #symbol{key = {variable_info, Name}, mib_name = MibName, info = VariableInfo}, - snmpa_general_db:write(DB, Rec) + Mod:write(DB, Rec) end, lists:foreach(F, VariableInfos), {noreply, S}; -handle_cast({delete_variable_infos, MibName}, #state{db = DB} = S) -> +handle_cast({delete_variable_infos, MibName}, + #state{module = Mod, db = DB} = S) -> ?vlog("delete variable infos: ~p",[MibName]), Pattern = #symbol{key = {variable_info,'_'}, mib_name = MibName, info = '_'}, - snmpa_general_db:match_delete(DB, Pattern), + Mod:match_delete(DB, Pattern), {noreply, S}; handle_cast({verbosity,Verbosity}, State) -> @@ -565,9 +614,9 @@ handle_info(Info, S) -> {noreply, S}. -terminate(Reason, S) -> - ?vlog("terminate: ~p",[Reason]), - snmpa_general_db:close(S#state.db). +terminate(Reason, #state{module = Mod, db = DB}) -> + ?vlog("terminate: ~p", [Reason]), + Mod:close(DB). %%---------------------------------------------------------- @@ -575,18 +624,18 @@ terminate(Reason, S) -> %%---------------------------------------------------------- % downgrade -code_change({down, _Vsn}, #state{db = DB, backup = B}, downgrade_to_pre_4_7) -> - ?d("code_change(down) -> entry", []), - stop_backup_server(B), - S = {state, DB}, - {ok, S}; - -% upgrade -code_change(_Vsn, S, upgrade_from_pre_4_7) -> - ?d("code_change(up) -> entry", []), - {state, DB} = S, - S1 = #state{db = DB}, - {ok, S1}; +%% code_change({down, _Vsn}, #state{db = DB, backup = B}, downgrade_to_pre_4_7) -> +%% ?d("code_change(down) -> entry", []), +%% stop_backup_server(B), +%% S = {state, DB}, +%% {ok, S}; + +%% % upgrade +%% code_change(_Vsn, S, upgrade_from_pre_4_7) -> +%% ?d("code_change(up) -> entry", []), +%% {state, DB} = S, +%% S1 = #state{db = DB}, +%% {ok, S1}; code_change(_Vsn, S, _Extra) -> ?d("code_change -> entry [do nothing]", []), @@ -609,13 +658,13 @@ stop_backup_server({Pid, _}) when is_pid(Pid) -> %%----------------------------------------------------------------- %% Returns: {value, Value} | undefined %%----------------------------------------------------------------- -get_notif(Db, Key) -> - case snmpa_general_db:read(Db, {trap, Key}) of +get_notif(Mod, Db, Key) -> + case Mod:read(Db, {trap, Key}) of {value,#symbol{info = Value}} -> {value, Value}; false -> undefined end. -set_notif(Db, MibName, Trap) when is_record(Trap, trap) -> +set_notif(Mod, Db, MibName, Trap) when is_record(Trap, trap) -> #trap{trapname = Name} = Trap, Rec = #symbol{key = {trap, Name}, mib_name = MibName, info = Trap}, %% convert old v1 trap to oid @@ -625,40 +674,41 @@ set_notif(Db, MibName, Trap) when is_record(Trap, trap) -> Oid0 -> Oid0 ++ [0, Trap#trap.specificcode] end, - write_alias(Name, Db, MibName, Oid), - snmpa_general_db:write(Db, Rec); -set_notif(Db, MibName, Trap) -> + write_alias(Mod, Name, Db, MibName, Oid), + Mod:write(Db, Rec); +set_notif(Mod, Db, MibName, Trap) -> #notification{trapname = Name, oid = Oid} = Trap, Rec = #symbol{key = {trap, Name}, mib_name = MibName, info = Trap}, - write_alias(Name, Db, MibName, Oid), - snmpa_general_db:write(Db, Rec). + write_alias(Mod, Name, Db, MibName, Oid), + Mod:write(Db, Rec). -delete_notif(Db, MibName) -> +delete_notif(Mod, Db, MibName) -> Pattern = #symbol{key = {trap, '_'}, mib_name = MibName, info = '_'}, - snmpa_general_db:match_delete(Db, Pattern). + Mod:match_delete(Db, Pattern). -write_alias(AN, DB, MibName, Oid) -> - write_alias(AN, DB, [], MibName, Oid). +write_alias(Mod, AN, DB, MibName, Oid) -> + write_alias(Mod, AN, DB, [], MibName, Oid). -write_alias(AN, DB, Enums, MibName, Oid) -> +write_alias(Mod, AN, DB, Enums, MibName, Oid) -> ?vlog("add alias~n ~p -> {~p,~p}",[AN, Oid, Enums]), Rec1 = #symbol{key = {alias, AN}, mib_name = MibName, info = {Oid,Enums}}, - snmpa_general_db:write(DB, Rec1), + Mod:write(DB, Rec1), ?vlog("add oid~n ~p -> ~p",[Oid, AN]), Rec2 = #symbol{key = {oid, Oid}, mib_name = MibName, info = AN}, - snmpa_general_db:write(DB, Rec2). + Mod:write(DB, Rec2). + %% ------------------------------------- -get_info(DB) -> +get_info(Mod, DB) -> ProcSize = proc_mem(self()), - DbSz = tab_size(DB), - [{process_memory, ProcSize}, {db_memory, DbSz}]. + DbMemory = Mod:info(DB, memory), + [{process_memory, ProcSize}, {db_memory, DbMemory}]. proc_mem(P) when is_pid(P) -> case (catch erlang:process_info(P, memory)) of @@ -667,26 +717,15 @@ proc_mem(P) when is_pid(P) -> _ -> undefined end. -%% proc_mem(_) -> -%% undefined. - -tab_size(DB) -> - case (catch snmpa_general_db:info(DB, memory)) of - Sz when is_integer(Sz) -> - Sz; - _ -> - undefined - end. - %% ------------------------------------- get_verbosity(L) -> - snmp_misc:get_option(verbosity,L,?default_verbosity). + snmp_misc:get_option(verbosity, L, ?default_verbosity). get_mib_storage(L) -> - snmp_misc:get_option(mib_storage,L,ets). + snmp_misc:get_option(mib_storage, L). %% ------------------------------------- -- cgit v1.2.3 From 58309771ca695ed74dc92c72cca471b93eda8282 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 22 May 2013 14:11:35 +0200 Subject: [snmp/agent] Add info/2 and some record checks Add a new function/2 to behaviour. Also changed returnj type for info/1. Also make sure even ets and dets implementation(s) check that the correct type is written. --- lib/snmp/src/agent/snmpa_mib_storage.erl | 16 +++++++------- lib/snmp/src/agent/snmpa_mib_storage_dets.erl | 27 +++++++++++++++++------- lib/snmp/src/agent/snmpa_mib_storage_ets.erl | 28 ++++++++++++++++++------- lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl | 10 ++++++--- 4 files changed, 54 insertions(+), 27 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmpa_mib_storage.erl b/lib/snmp/src/agent/snmpa_mib_storage.erl index bbb9516ecb..5c3f76d89b 100644 --- a/lib/snmp/src/agent/snmpa_mib_storage.erl +++ b/lib/snmp/src/agent/snmpa_mib_storage.erl @@ -22,9 +22,7 @@ -export_type([ mib_storage_fields/0, mib_storage_table_type/0, - mib_storage_table_id/0, - - void/0 + mib_storage_table_id/0 ]). @@ -37,7 +35,6 @@ -type mib_storage_fields() :: [atom()]. -type mib_storage_table_type() :: set | bag. -type mib_storage_table_id() :: term(). --type void() :: term(). %% --------------------------------------------------------------- @@ -99,7 +96,7 @@ %% --------------------------------------------------------------- -callback delete(TabId :: mib_storage_table_id()) -> - void(). + snmp:void(). %% --------------------------------------------------------------- @@ -149,14 +146,17 @@ %% --------------------------------------------------------------- -%% info +%% info/1,2 %% %% Retrieve implementation dependent mib-storage table %% information. %% --------------------------------------------------------------- -callback info(TabId :: mib_storage_table_id()) -> - {ok, Info :: term()} | {error, Reason :: term()}. + Info :: term(). + +-callback info(TabId :: mib_storage_table_id(), Item :: atom()) -> + Info :: term(). %% --------------------------------------------------------------- @@ -166,7 +166,7 @@ %% --------------------------------------------------------------- -callback sync(TabId :: mib_storage_table_id()) -> - ok. + snmp:void(). %% --------------------------------------------------------------- diff --git a/lib/snmp/src/agent/snmpa_mib_storage_dets.erl b/lib/snmp/src/agent/snmpa_mib_storage_dets.erl index 6062f4327e..e84e18e7ea 100644 --- a/lib/snmp/src/agent/snmpa_mib_storage_dets.erl +++ b/lib/snmp/src/agent/snmpa_mib_storage_dets.erl @@ -33,19 +33,19 @@ write/2, delete/1, delete/2, - sync/1, - backup/2, match_object/2, match_delete/2, tab2list/1, - info/1 + info/1, info/2, + sync/1, + backup/2 ]). -define(VMODULE, "MS-DETS"). -include("snmp_verbosity.hrl"). --record(tab, {id}). +-record(tab, {id, rec_name}). %% --------------------------------------------------------------- @@ -62,7 +62,7 @@ %% %% --------------------------------------------------------------- -open(Name, _RecName, _Fields, Type, Opts) -> +open(Name, RecName, _Fields, Type, Opts) -> Dir = snmp_misc:get_option(dir, Opts), Action = snmp_misc:get_option(action, Opts, keep), AutoSave = snmp_misc:get_option(auto_save, Opts, default), @@ -80,10 +80,10 @@ open(Name, _RecName, _Fields, Type, Opts) -> end, case dets:open_file(Name, OpenOpts) of {ok, ID} when (Action =:= keep) -> - {ok, #tab{id = ID}}; + {ok, #tab{id = ID, rec_name = RecName}}; {ok, ID} when (Action =:= clear) -> dets:match_delete(ID, '_'), - {ok, #tab{id = ID}}; + {ok, #tab{id = ID, rec_name = RecName}}; {error, Reason} -> {error, {dets_open, Reason}} end. @@ -128,7 +128,8 @@ read(#tab{id = ID}, Key) -> %% Write a record to the database table. %% --------------------------------------------------------------- -write(#tab{id = ID}, Rec) -> +write(#tab{id = ID, rec_name = RecName}, Rec) + when (is_tuple(Rec) andalso (element(1, Rec) =:= RecName)) -> ?vtrace("write to table ~p", [ID]), dets:insert(ID, Rec). @@ -209,6 +210,16 @@ info(#tab{id = ID}) -> dets:info(ID). +info(TabId, all = _Item) -> + info(TabId); +info(#tab{id = ID}, memory = _Item) -> + ?vtrace("info on ~p (~w)", [ID, _Item]), + dets:info(ID, file_size); +info(#tab{id = ID}, Item) -> + ?vtrace("info on ~p (~w)", [ID, Item]), + dets:info(ID, Item). + + %% --------------------------------------------------------------- %% sync %% diff --git a/lib/snmp/src/agent/snmpa_mib_storage_ets.erl b/lib/snmp/src/agent/snmpa_mib_storage_ets.erl index fcf5e12043..4afdc76ee5 100644 --- a/lib/snmp/src/agent/snmpa_mib_storage_ets.erl +++ b/lib/snmp/src/agent/snmpa_mib_storage_ets.erl @@ -33,19 +33,19 @@ write/2, delete/1, delete/2, - sync/1, - backup/2, match_object/2, match_delete/2, tab2list/1, - info/1 + info/1, info/2, + sync/1, + backup/2 ]). -define(VMODULE,"MS-ETS"). -include("snmp_verbosity.hrl"). --record(tab, {id, file, checksum = false}). +-record(tab, {id, rec_name, file, checksum = false}). %% --------------------------------------------------------------- @@ -67,7 +67,7 @@ %% --------------------------------------------------------------- %% This function creates the ets table -open(Name, _RecName, _Fields, Type, Opts) -> +open(Name, RecName, _Fields, Type, Opts) -> ?vtrace("open table ~p", [Name]), case lists:keysearch(dir, 1, Opts) of {value, {dir, Dir}} -> @@ -80,6 +80,7 @@ open(Name, _RecName, _Fields, Type, Opts) -> case ets:file2tab(File, [{verify, Checksum}]) of {ok, ID} -> {ok, #tab{id = ID, + rec_name = RecName, file = File, checksum = Checksum}}; {error, Reason} when (Action =:= keep) -> @@ -92,6 +93,7 @@ open(Name, _RecName, _Fields, Type, Opts) -> ID = ets:new(Name, [Type, protected, {keypos, 2}]), write_ets_file(ID, File, Checksum), {ok, #tab{id = ID, + rec_name = RecName, file = File, checksum = Checksum}} end; @@ -105,12 +107,13 @@ open(Name, _RecName, _Fields, Type, Opts) -> ID = ets:new(Name, [Type, protected, {keypos, 2}]), write_ets_file(ID, File, Checksum), {ok, #tab{id = ID, + rec_name = RecName, file = File, checksum = Checksum}} end; false -> ID = ets:new(Name, [Type, protected, {keypos, 2}]), - {ok, #tab{id = ID}} + {ok, #tab{id = ID, rec_name = RecName}} end. @@ -150,7 +153,9 @@ read(#tab{id = ID}, Key) -> %% Write a record to the mib-storage table. %% --------------------------------------------------------------- -write(#tab{id = ID}, Rec) -> +%% This is a very crude guard test is used instead of: is_record(Rec, RecName) +write(#tab{id = ID, rec_name = RecName}, Rec) + when (is_tuple(Rec) andalso (element(1, Rec) =:= RecName)) -> ?vtrace("write to table ~p", [ID]), ets:insert(ID, Rec). @@ -219,7 +224,7 @@ tab2list(#tab{id = ID}) -> %% --------------------------------------------------------------- -%% info +%% info/1,2 %% %% Retrieve implementation dependent mib-storage table %% information. @@ -234,6 +239,13 @@ info(#tab{id = ID}) -> end. +info(TabId, all = _Item) -> + info(TabId); +info(#tab{id = ID}, Item) -> + ?vtrace("info on ~p", [ID]), + ets:info(ID, Item). + + %% --------------------------------------------------------------- %% sync %% diff --git a/lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl b/lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl index aee2192b24..a1f2be9af3 100644 --- a/lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl +++ b/lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl @@ -33,12 +33,12 @@ write/2, delete/1, delete/2, - sync/1, - backup/2, match_object/2, match_delete/2, tab2list/1, - info/1 + info/1, info/2, + sync/1, + backup/2 ]). @@ -239,6 +239,10 @@ info(#tab{id = ID}) -> end. +info(#tab{id = ID}, Item) -> + mnesia:table_info(ID, Item). + + %% --------------------------------------------------------------- %% sync %% -- cgit v1.2.3 From bed8ac264d7d8fec56ceaa31a76404a5609dbadf Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 22 May 2013 14:15:17 +0200 Subject: [snmp/agent] No default value for mib_storage and some cleanup --- lib/snmp/src/agent/snmpa_agent.erl | 185 +++++++++++++++++++------------------ 1 file changed, 94 insertions(+), 91 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmpa_agent.erl b/lib/snmp/src/agent/snmpa_agent.erl index 57846db13b..c267ce5a70 100644 --- a/lib/snmp/src/agent/snmpa_agent.erl +++ b/lib/snmp/src/agent/snmpa_agent.erl @@ -159,12 +159,15 @@ %% it is sent to the worker, and the worker is marked as busy. %% If a request is received when the worker is busy, a new temporary %% worker is spawned. +%% %% Code change %% =========== %% Note that the worker(s) execute the same module as the master %% agent. For code change we have two options - ignore the workers, %% or send them a code change message. +%% %%----------------------------------------------------------------- + -record(state, {type, parent, worker, @@ -219,22 +222,19 @@ %%----------------------------------------------------------------- start_link(Prio, Parent, Ref, Options) -> ?d("start_link -> entry with" - "~n Prio: ~p" - "~n Parent: ~p" - "~n Ref: ~p" - "~n Options: ~p", [Prio, Parent, Ref, Options]), - %% gen_server:start_link(?MODULE, [Prio, Parent, Ref, Options], []). + "~n Prio: ~p" + "~n Parent: ~p" + "~n Ref: ~p" + "~n Options: ~p", [Prio, Parent, Ref, Options]), ?GS_START_LINK3(Prio, Parent, Ref, Options). start_link(Prio, Name, Parent, Ref, Options) -> ?d("start_link -> entry with" - "~n Prio: ~p" - "~n Name: ~p" - "~n Parent: ~p" - "~n Ref: ~p" - "~n Options: ~p", [Prio, Name, Parent, Ref, Options]), -% gen_server:start_link({local, Name}, ?MODULE, -% [Prio, Parent, Ref, Options], []). + "~n Prio: ~p" + "~n Name: ~p" + "~n Parent: ~p" + "~n Ref: ~p" + "~n Options: ~p", [Prio, Name, Parent, Ref, Options]), ?GS_START_LINK4(Prio, Name, Parent, Ref, Options). stop(Agent) -> call(Agent, stop). @@ -335,10 +335,10 @@ increment_counter(Counter, Initial, Max) -> init([Prio, Parent, Ref, Options]) -> ?d("init -> entry with" - "~n Prio: ~p" - "~n Parent: ~p" - "~n Ref: ~p" - "~n Options: ~p", [Prio, Parent, Ref, Options]), + "~n Prio: ~p" + "~n Parent: ~p" + "~n Ref: ~p" + "~n Options: ~p", [Prio, Parent, Ref, Options]), case (catch do_init(Prio, Parent, Ref, Options)) of {ok, State} -> ?vdebug("started",[]), @@ -1457,80 +1457,80 @@ handle_mibs_cache_request(MibServer, Req) -> %% Downgrade %% -code_change({down, _Vsn}, S1, downgrade_to_pre_4_17_3) -> - #state{type = Type, - parent = Parent, - worker = Worker, - worker_state = WorkerState, - set_worker = SetWorker, - multi_threaded = MT, - ref = Ref, - vsns = Vsns, - nfilters = NF, - note_store = NoteStore, - mib_server = MS, - net_if = NetIf, - net_if_mod = NetIfMod, - backup = Backup, - disco = Disco, - mibs_cache_request = MCR} = S1, - S2 = {state, - type = Type, - parent = Parent, - worker = Worker, - worker_state = WorkerState, - set_worker = SetWorker, - multi_threaded = MT, - ref = Ref, - vsns = Vsns, - nfilters = NF, - note_store = NoteStore, - mib_server = MS, - net_if = NetIf, - net_if_mod = NetIfMod, - backup = Backup, - disco = Disco, - mibs_cache_request = MCR}, - {ok, S2}; - -%% Upgrade -%% -code_change(_Vsn, S1, upgrade_from_pre_4_17_3) -> - {state, - type = Type, - parent = Parent, - worker = Worker, - worker_state = WorkerState, - set_worker = SetWorker, - multi_threaded = MT, - ref = Ref, - vsns = Vsns, - nfilters = NF, - note_store = NoteStore, - mib_server = MS, - net_if = NetIf, - net_if_mod = NetIfMod, - backup = Backup, - disco = Disco, - mibs_cache_request = MCR} = S1, - S2 = #state{type = Type, - parent = Parent, - worker = Worker, - worker_state = WorkerState, - set_worker = SetWorker, - multi_threaded = MT, - ref = Ref, - vsns = Vsns, - nfilters = NF, - note_store = NoteStore, - mib_server = MS, - net_if = NetIf, - net_if_mod = NetIfMod, - backup = Backup, - disco = Disco, - mibs_cache_request = MCR, - gb_max_vbs = ?DEFAULT_GB_MAX_VBS}, - {ok, S2}; +%% code_change({down, _Vsn}, S1, downgrade_to_pre_4_17_3) -> +%% #state{type = Type, +%% parent = Parent, +%% worker = Worker, +%% worker_state = WorkerState, +%% set_worker = SetWorker, +%% multi_threaded = MT, +%% ref = Ref, +%% vsns = Vsns, +%% nfilters = NF, +%% note_store = NoteStore, +%% mib_server = MS, +%% net_if = NetIf, +%% net_if_mod = NetIfMod, +%% backup = Backup, +%% disco = Disco, +%% mibs_cache_request = MCR} = S1, +%% S2 = {state, +%% type = Type, +%% parent = Parent, +%% worker = Worker, +%% worker_state = WorkerState, +%% set_worker = SetWorker, +%% multi_threaded = MT, +%% ref = Ref, +%% vsns = Vsns, +%% nfilters = NF, +%% note_store = NoteStore, +%% mib_server = MS, +%% net_if = NetIf, +%% net_if_mod = NetIfMod, +%% backup = Backup, +%% disco = Disco, +%% mibs_cache_request = MCR}, +%% {ok, S2}; + +%% %% Upgrade +%% %% +%% code_change(_Vsn, S1, upgrade_from_pre_4_17_3) -> +%% {state, +%% type = Type, +%% parent = Parent, +%% worker = Worker, +%% worker_state = WorkerState, +%% set_worker = SetWorker, +%% multi_threaded = MT, +%% ref = Ref, +%% vsns = Vsns, +%% nfilters = NF, +%% note_store = NoteStore, +%% mib_server = MS, +%% net_if = NetIf, +%% net_if_mod = NetIfMod, +%% backup = Backup, +%% disco = Disco, +%% mibs_cache_request = MCR} = S1, +%% S2 = #state{type = Type, +%% parent = Parent, +%% worker = Worker, +%% worker_state = WorkerState, +%% set_worker = SetWorker, +%% multi_threaded = MT, +%% ref = Ref, +%% vsns = Vsns, +%% nfilters = NF, +%% note_store = NoteStore, +%% mib_server = MS, +%% net_if = NetIf, +%% net_if_mod = NetIfMod, +%% backup = Backup, +%% disco = Disco, +%% mibs_cache_request = MCR, +%% gb_max_vbs = ?DEFAULT_GB_MAX_VBS}, +%% {ok, S2}; code_change(_Vsn, S, _Extra) -> {ok, S}. @@ -4411,7 +4411,7 @@ get_mibs(Opts) -> get_option(mibs, Opts, []). get_mib_storage(Opts) -> - get_option(mib_storage, Opts, ets). + get_option(mib_storage, Opts). get_set_mechanism(Opts) -> get_option(set_mechanism, Opts, snmpa_set). @@ -4450,6 +4450,9 @@ net_if_verbosity(_Pid,_Verbosity) -> ok. +get_option(Key, Opts) -> + snmp_misc:get_option(Key, Opts). + get_option(Key, Opts, Default) -> snmp_misc:get_option(Key, Opts, Default). -- cgit v1.2.3 From ba6cdcc9a0a477938c99d92a7526b61ec2c70400 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 22 May 2013 14:16:10 +0200 Subject: [snmp/agent] Cosmetic --- lib/snmp/src/agent/snmpa_supervisor.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmpa_supervisor.erl b/lib/snmp/src/agent/snmpa_supervisor.erl index 1c8db7ff07..aebcdbaa84 100644 --- a/lib/snmp/src/agent/snmpa_supervisor.erl +++ b/lib/snmp/src/agent/snmpa_supervisor.erl @@ -318,7 +318,7 @@ init([AgentType, Opts]) -> Other end, - ?vdebug("[agent table] store mib storage: ~w",[MibStorage]), + ?vdebug("[agent table] store mib storage: ~w", [MibStorage]), ets:insert(snmp_agent_table, {mib_storage, MibStorage}), %% -- Agent mib storage -- @@ -463,7 +463,7 @@ init([AgentType, Opts]) -> AgentSpec = worker_spec(snmpa_agent, - [Prio,snmp_master_agent,none,Ref,AgentOpts], + [Prio, snmp_master_agent, none, Ref, AgentOpts], Restart, 15000), AgentSupSpec = sup_spec(snmpa_agent_sup, [AgentSpec], -- cgit v1.2.3 From dccaf2ca6b85ceaf05ea43262e18af9f63a76b02 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Thu, 23 May 2013 11:16:04 +0200 Subject: [snmp/agent] Add more verbosity printouts to the mnesia mib-storage module --- lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl b/lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl index a1f2be9af3..dca44d3c33 100644 --- a/lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl +++ b/lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl @@ -64,11 +64,13 @@ open(Name, RecName, Fields, Type, Opts) -> ?vtrace("open ~p table ~p for record ~p", [Type, Name, RecName]), Action = snmp_misc:get_option(action, Opts, keep), - Nodes = snmp_misc:get_option(nodes, Opts, [node()]), + Nodes = snmp_misc:get_option(nodes, Opts, erlang:nodes()), case table_exists(Name) of true when (Action =:= keep) -> + ?vtrace("open table ~p - exist (keep)", [Name]), {ok, #tab{id = Name}}; true when (Action =:= clear) -> + ?vtrace("open table ~p - exist (clear)", [Name]), F = fun() -> mnesia:clear_table(Name) end, case mnesia:transaction(F) of {aborted, Reason} -> @@ -77,14 +79,18 @@ open(Name, RecName, Fields, Type, Opts) -> {ok, #tab{id = Name}} end; false -> + ?vtrace("open table ~p - does not exist", [Name]), Args = [{record_name, RecName}, {attributes, Fields}, {type, Type}, {disc_copies, Nodes}], case mnesia:create_table(Name, Args) of {atomic, ok} -> + ?vtrace("open table ~p - ok", [Name]), {ok, #tab{id = Name}}; {aborted, Reason} -> + ?vinfo("open table ~p - aborted" + "~n Reason: ~p", [Name, Reason]), {error, {create, Reason}} end end. -- cgit v1.2.3 From 6703fc56a382e62530ba23cb5452da6f4cccbe91 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Thu, 23 May 2013 11:17:21 +0200 Subject: [snmp/agent] Updated the config tool with new mib-storage format --- lib/snmp/src/app/snmp_app.erl | 14 +++++++------- lib/snmp/src/misc/snmp_config.erl | 22 +++++++++++++++------- 2 files changed, 22 insertions(+), 14 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/app/snmp_app.erl b/lib/snmp/src/app/snmp_app.erl index deb42cc373..0cfbb22a5a 100644 --- a/lib/snmp/src/app/snmp_app.erl +++ b/lib/snmp/src/app/snmp_app.erl @@ -62,17 +62,17 @@ entities([], []) -> ?d("entities -> converted config: ~n~p", [Conf]), [{agent, Conf}] end; -entities([], E) -> +entities([], Acc) -> ?d("entities -> done", []), - lists:reverse(E); -entities([ET|ETs], E) -> + lists:reverse(Acc); +entities([Ent|Ents], Acc) -> ?d("entities -> entry with" - "~n ET: ~p", [ET]), - case application:get_env(snmp, ET) of + "~n Ent: ~p", [Ent]), + case application:get_env(snmp, Ent) of {ok, Conf} -> - entities(ETs, [{ET, Conf}|E]); + entities(Ents, [{Ent, Conf}|Acc]); _ -> - entities(ETs, E) + entities(Ents, Acc) end. start_entities(_Type, []) -> diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl index 0bed097b62..22fe25941c 100644 --- a/lib/snmp/src/misc/snmp_config.erl +++ b/lib/snmp/src/misc/snmp_config.erl @@ -238,7 +238,7 @@ config_agent_sys() -> MibStorage = case MibStorageType of ets -> - ets; + [{module, snmpa_mib_storage_ets}]; dets -> DetsDir = ask("6b. Mib storage directory (absolute path)?", DbDir, fun verify_dir/1), @@ -248,13 +248,14 @@ config_agent_sys() -> "default", fun verify_mib_storage_action/1), case DetsAction of default -> - {dets, DetsDir}; + [{module, snmpa_mib_storage_dets}, + {options, [{dir, DetsDir}]}]; _ -> - {dets, DetsDir, DetsAction} + [{module, snmpa_mib_storage_dets}, + {options, [{dir, DetsDir}, + {action, DetsAction}]}] end; mnesia -> -% Nodes = ask("Mib storage nodes?", "none", -% fun verify_mib_storage_nodes/1), Nodes = [], MnesiaAction = ask("6b. Mib storage [mnesia] database start " "action " @@ -262,11 +263,18 @@ config_agent_sys() -> "default", fun verify_mib_storage_action/1), case MnesiaAction of default -> - {mnesia, Nodes}; + [{module, snmpa_mib_storage_mnesia}, + {options, [{nodes, Nodes}]}]; _ -> - {mnesia, Nodes, MnesiaAction} + [{module, snmpa_mib_storage_mnesia}, + {options, [{nodes, Nodes}, + {action, MnesiaAction}]}] end end, + + %% Here we should ask about mib-server data module, + %% but as we only have one at the moment... + TargetCacheVerb = ask("7. Target cache verbosity " "(silence/info/log/debug/trace)?", "silence", fun verify_verbosity/1), -- cgit v1.2.3 From 69981c172621ed6f2e9fa7495b583af42f64c027 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Thu, 23 May 2013 11:18:54 +0200 Subject: [snmp/agent] Update agent test (sub-) suite The agent test (sub-) suite updated according to the new mib-storage format. Also changed config of started agent to the "new" format. --- lib/snmp/test/snmp_agent_test.erl | 207 ++++++++++++++++++++++------------ lib/snmp/test/snmp_agent_test_lib.erl | 102 ++++++++--------- 2 files changed, 185 insertions(+), 124 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl index a8e921d67d..5216b82cf8 100644 --- a/lib/snmp/test/snmp_agent_test.erl +++ b/lib/snmp/test/snmp_agent_test.erl @@ -456,14 +456,14 @@ end_per_testcase2(_Case, Config) -> cases() -> [ - {group, misc}, - {group, test_v1}, - {group, test_v2}, - {group, test_v1_v2}, - {group, test_v3}, - {group, test_multi_threaded}, - {group, mib_storage}, - {group, tickets1} + {group, misc}, + {group, test_v1}, + {group, test_v2}, + {group, test_v1_v2}, + {group, test_v3}, + {group, test_multi_threaded}, + {group, mib_storage}, + {group, tickets1} ]. @@ -549,7 +549,7 @@ delete_tables() -> mnesia:delete_table(kompissTable2), mnesia:delete_table(snmp_variables). -%% Creation is done in runtime! +%% Tables are created in runtime! delete_mib_storage_mnesia_tables() -> mnesia:delete_table(snmpa_mib_data), mnesia:delete_table(snmpa_mib_tree), @@ -572,40 +572,77 @@ delete_mib_storage_mnesia_tables() -> %% versions as well, _N. %%----------------------------------------------------------------- - - - - - - - - mib_storage_ets_cases() -> -[mse_simple, mse_v1_processing, mse_big, mse_big2, - mse_loop_mib, mse_api, mse_sa_register, mse_v1_trap, - mse_sa_error, mse_next_across_sa, mse_undo, - mse_standard_mib, mse_community_mib, mse_framework_mib, - mse_target_mib, mse_notification_mib, - mse_view_based_acm_mib, mse_sparse_table, mse_me_of, - mse_mib_of]. + [ + mse_simple, + mse_v1_processing, + mse_big, + mse_big2, + mse_loop_mib, + mse_api, + mse_sa_register, + mse_v1_trap, + mse_sa_error, + mse_next_across_sa, + mse_undo, + mse_standard_mib, + mse_community_mib, + mse_framework_mib, + mse_target_mib, + mse_notification_mib, + mse_view_based_acm_mib, + mse_sparse_table, + mse_me_of, + mse_mib_of + ]. mib_storage_dets_cases() -> -[msd_simple, msd_v1_processing, msd_big, msd_big2, - msd_loop_mib, msd_api, msd_sa_register, msd_v1_trap, - msd_sa_error, msd_next_across_sa, msd_undo, - msd_standard_mib, msd_community_mib, msd_framework_mib, - msd_target_mib, msd_notification_mib, - msd_view_based_acm_mib, msd_sparse_table, msd_me_of, - msd_mib_of]. + [ + msd_simple, + msd_v1_processing, + msd_big, + msd_big2, + msd_loop_mib, + msd_api, + msd_sa_register, + msd_v1_trap, + msd_sa_error, + msd_next_across_sa, + msd_undo, + msd_standard_mib, + msd_community_mib, + msd_framework_mib, + msd_target_mib, + msd_notification_mib, + msd_view_based_acm_mib, + msd_sparse_table, + msd_me_of, + msd_mib_of + ]. mib_storage_mnesia_cases() -> -[msm_simple, msm_v1_processing, msm_big, msm_big2, - msm_loop_mib, msm_api, msm_sa_register, msm_v1_trap, - msm_sa_error, msm_next_across_sa, msm_undo, - msm_standard_mib, msm_community_mib, msm_framework_mib, - msm_target_mib, msm_notification_mib, - msm_view_based_acm_mib, msm_sparse_table, msm_me_of, - msm_mib_of]. + [ + msm_simple, + msm_v1_processing, + msm_big, + msm_big2, + msm_loop_mib, + msm_api, + msm_sa_register, + msm_v1_trap, + msm_sa_error, + msm_next_across_sa, + msm_undo, + msm_standard_mib, + msm_community_mib, + msm_framework_mib, + msm_target_mib, + msm_notification_mib, + msm_view_based_acm_mib, + msm_sparse_table, + msm_me_of, + msm_mib_of + ]. mse_size_check_cases() -> [mse_size_check]. @@ -624,18 +661,21 @@ varm_mib_storage_mnesia_cases() -> init_mib_storage_ets(Config) when is_list(Config) -> ?LOG("init_mib_storage_ets -> entry", []), - MibStorage = {snmp_mib_storage,ets}, + MibStorage = {mib_storage, [{module, snmpa_mib_storage_ets}]}, init_ms(Config, [MibStorage]). init_mib_storage_dets(Config) when is_list(Config) -> ?LOG("init_mib_storage_dets -> entry", []), ?line AgentDbDir = ?GCONF(agent_db_dir, Config), - MibStorage = {snmp_mib_storage, {dets, AgentDbDir}}, + MibStorage = {mib_storage, [{module, snmpa_mib_storage_dets}, + {options, [{dir, AgentDbDir}]}]}, init_ms(Config, [MibStorage]). init_mib_storage_mnesia(Config) when is_list(Config) -> ?LOG("init_mib_storage_mnesia -> entry", []), - MibStorage = {snmp_mib_storage, {mnesia,[]}}, + ?line AgentNode = ?GCONF(snmp_master, Config), + MibStorage = {mib_storage, [{module, snmpa_mib_storage_mnesia}, + {options, [{nodes, [AgentNode]}]}]}, init_ms(Config, [MibStorage]). init_ms(Config, Opts) when is_list(Config) -> @@ -649,23 +689,26 @@ init_ms(Config, Opts) when is_list(Config) -> ?line Ip = ?GCONF(ip, Config), ?line config([v1], MgrDir, AgentConfDir, tuple_to_list(Ip), tuple_to_list(Ip)), - MasterAgentVerbosity = {snmp_master_agent_verbosity, trace}, - MibsVerbosity = {snmp_mibserver_verbosity, trace}, - SymStoreVerbosity = {snmp_symbolic_store_verbosity, trace}, + MasterAgentVerbosity = {agent_verbosity, trace}, + MibsVerbosity = {mib_server, [{verbosity, trace}]}, + SymStoreVerbosity = {symbolic_store, [{verbosity, trace}]}, Opts1 = [MasterAgentVerbosity, MibsVerbosity, SymStoreVerbosity | Opts], [{vsn, v1} | start_v1_agent(Config, Opts1)]. init_size_check_mse(Config) when is_list(Config) -> - MibStorage = {snmp_mib_storage, ets}, + MibStorage = {mib_storage, [{module, snmpa_mib_storage_ets}]}, init_size_check_ms(Config, [MibStorage]). init_size_check_msd(Config) when is_list(Config) -> AgentDbDir = ?GCONF(agent_db_dir, Config), - MibStorage = {snmp_mib_storage, {dets, AgentDbDir}}, + MibStorage = {mib_storage, [{module, snmpa_mib_storage_dets}, + {options, [{dir, AgentDbDir}]}]}, init_size_check_ms(Config, [MibStorage]). init_size_check_msm(Config) when is_list(Config) -> - MibStorage = {snmp_mib_storage, {mnesia,[]}}, + ?line AgentNode = ?GCONF(snmp_master, Config), + MibStorage = {mib_storage, [{module, snmpa_mib_storage_mnesia}, + {options, [{nodes, [AgentNode]}]}]}, init_size_check_ms(Config, [MibStorage]). init_size_check_ms(Config, Opts) when is_list(Config) -> @@ -700,12 +743,16 @@ init_varm_mib_storage_dets(Config) when is_list(Config) -> ?line Ip = ?GCONF(ip, Config), ?line config([v1], MgrDir, AgentConfDir, tuple_to_list(Ip), tuple_to_list(Ip)), - MibStorage = {snmp_mib_storage, {dets, AgentDbDir}}, - MasterAgentVerbosity = {snmp_master_agent_verbosity, trace}, - MibsVerbosity = {snmp_mibserver_verbosity, trace}, - SymStoreVerbosity = {snmp_symbolic_store_verbosity, trace}, - Opts = [MibStorage,MasterAgentVerbosity,MibsVerbosity,SymStoreVerbosity], - [{vsn, v1}, {agent_opts,Opts} | Config]. + MibStorage = {mib_storage, [{module, snmpa_mib_storage_dets}, + {options, [{dir, AgentDbDir}]}]}, + MasterAgentVerbosity = {agent_verbosity, trace}, + MibsVerbosity = {mib_server, [{verbosity, trace}]}, + SymStoreVerbosity = {symbolic_store, [{verbosity, trace}]}, + Opts = [MibStorage, + MasterAgentVerbosity, + MibsVerbosity, + SymStoreVerbosity], + [{vsn, v1}, {agent_opts, Opts} | Config]. init_varm_mib_storage_mnesia(Config) when is_list(Config) -> ?LOG("init_varm_mib_storage_mnesia -> entry", []), @@ -716,12 +763,17 @@ init_varm_mib_storage_mnesia(Config) when is_list(Config) -> ?line Ip = ?GCONF(ip, Config), ?line config([v1], MgrDir, AgentConfDir, tuple_to_list(Ip), tuple_to_list(Ip)), - MibStorage = {snmp_mib_storage,{mnesia,[]}}, - MasterAgentVerbosity = {snmp_master_agent_verbosity, trace}, - MibsVerbosity = {snmp_mibserver_verbosity, trace}, - SymStoreVerbosity = {snmp_symbolic_store_verbosity, trace}, - Opts = [MibStorage,MasterAgentVerbosity,MibsVerbosity,SymStoreVerbosity], - [{vsn, v1}, {agent_opts,Opts} | Config]. + ?line AgentNode = ?GCONF(snmp_master, Config), + MibStorage = {mib_storage, [{module, snmpa_mib_storage_mnesia}, + {options, [{nodes, [AgentNode]}]}]}, + MasterAgentVerbosity = {agent_verbosity, trace}, + MibsVerbosity = {mib_server, [{verbosity, trace}]}, + SymStoreVerbosity = {symbolic_store, [{verbosity, trace}]}, + Opts = [MibStorage, + MasterAgentVerbosity, + MibsVerbosity, + SymStoreVerbosity], + [{vsn, v1}, {agent_opts, Opts} | Config]. finish_mib_storage_ets(Config) when is_list(Config) -> ?LOG("finish_mib_storage_ets -> entry", []), @@ -1117,7 +1169,10 @@ finish_misc(Config) -> finish_v1(Config). misc_cases() -> -[app_info, info_test]. + [ + app_info, + info_test + ]. app_info(suite) -> []; app_info(Config) when is_list(Config) -> @@ -1816,23 +1871,38 @@ mnesia_2(X) -> ?P(mnesia_2), mnesia(X). mnesia_3(X) -> ?P(mnesia_3), mnesia(X). - mul_cases() -> -[mul_get, mul_get_err, mul_next, mul_next_err, - mul_set_err]. - + [ + mul_get, + mul_get_err, + mul_next, + mul_next_err, + mul_set_err + ]. + multiple_reqs_3(_X) -> {req, [], {conf, init_mul, mul_cases_3(), finish_mul}}. mul_cases_2() -> -[mul_get_2, mul_get_err_2, mul_next_2, mul_next_err_2, - mul_set_err_2]. - + [ + mul_get_2, + mul_get_err_2, + mul_next_2, + mul_next_err_2, + mul_set_err_2 + ]. + mul_cases_3() -> - [mul_get_3, mul_get_err_3, mul_next_3, mul_next_err_3, mul_set_err_3]. + [ + mul_get_3, + mul_get_err_3, + mul_next_3, + mul_next_err_3, + mul_set_err_3 + ]. init_mul(Config) when is_list(Config) -> @@ -2055,7 +2125,6 @@ v3_trap(Config) when is_list(Config) -> v3_inform(_X) -> - %% v2_inform(X). {req, [], {conf, init_v3_inform, [v3_inform_i], finish_v3_inform}}. init_v2_inform(Config) when is_list(Config) -> diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl index 757aebfa9b..5261a9c40e 100644 --- a/lib/snmp/test/snmp_agent_test_lib.erl +++ b/lib/snmp/test/snmp_agent_test_lib.erl @@ -28,7 +28,7 @@ start_mt_agent/1, start_mt_agent/2, stop_agent/1, - start_sup/0, stop_sup/2, + %% start_sup/0, stop_sup/2, start_subagent/3, stop_subagent/1, start_sub_sup/1, start_sub_sup/2, @@ -418,10 +418,10 @@ start_bilingual_agent(Config, Opts) start_agent(Config, [v1,v2], Opts). start_mt_agent(Config) when is_list(Config) -> - start_agent(Config, [v2], [{snmp_multi_threaded, true}]). + start_agent(Config, [v2], [{multi_threaded, true}]). start_mt_agent(Config, Opts) when is_list(Config) andalso is_list(Opts) -> - start_agent(Config, [v2], [{snmp_multi_threaded, true}|Opts]). + start_agent(Config, [v2], [{multi_threaded, true}|Opts]). start_agent(Config, Vsns) -> start_agent(Config, Vsns, []). @@ -437,65 +437,53 @@ start_agent(Config, Vsns, Opts) -> ?line AgentDbDir = ?config(agent_db_dir, Config), ?line SaNode = ?config(snmp_sa, Config), - app_env_init(vsn_init(Vsns) ++ - [{audit_trail_log, read_write_log}, - {audit_trail_log_dir, AgentLogDir}, - {audit_trail_log_size, {10240, 10}}, - {force_config_reload, false}, - {snmp_agent_type, master}, - {snmp_config_dir, AgentConfDir}, - {snmp_db_dir, AgentDbDir}, - {snmp_local_db_auto_repair, true}, - {snmp_local_db_verbosity, log}, - {snmp_master_agent_verbosity, trace}, - {snmp_supervisor_verbosity, trace}, - {snmp_mibserver_verbosity, log}, - {snmp_symbolic_store_verbosity, log}, - {snmp_note_store_verbosity, log}, - {snmp_net_if_verbosity, trace}], - Opts), - + Env = app_agent_env_init( + [{versions, Vsns}, + {agent_type, master}, + {agent_verbosity, trace}, + {audit_trail_log, [{type, read_write}, + {dir, AgentLogDir}, + {size, {10240, 10}}]}, + {config, [{dir, AgentConfDir}, + {force_load, false}, + {verbosity, trace}]}, + {db_dir, AgentDbDir}, + {local_db, [{repair, true}, + {verbosity, log}]}, + {mib_server, [{verbosity, log}]}, + {symbolic_store, [{verbosity, log}]}, + {note_store, [{verbosity, log}]}, + {net_if, [{verbosity, trace}]}], + Opts), + process_flag(trap_exit,true), {ok, AppSup} = snmp_app_sup:start_link(), unlink(AppSup), - ?DBG("start_agent -> snmp app supervisor: ~p",[AppSup]), + ?DBG("start_agent -> snmp app supervisor: ~p", [AppSup]), - ?DBG("start_agent -> start master agent (old style)",[]), - ?line Sup = start_sup(), + ?DBG("start_agent -> start master agent",[]), + ?line Sup = start_sup(Env), - ?DBG("start_agent -> unlink from supervisor",[]), + ?DBG("start_agent -> unlink from supervisor", []), ?line unlink(Sup), ?line SaDir = ?config(sa_dir, Config), - ?DBG("start_agent -> (rpc) start sub on ~p",[SaNode]), + ?DBG("start_agent -> (rpc) start sub on ~p", [SaNode]), ?line {ok, Sub} = start_sub_sup(SaNode, SaDir), ?DBG("start_agent -> done",[]), ?line [{snmp_sup, {Sup, self()}}, {snmp_sub, Sub} | Config]. -vsn_init(Vsn) -> - vsn_init([v1,v2,v3], Vsn, []). - -vsn_init([], _Vsn, Acc) -> - Acc; -vsn_init([V|Vsns], Vsn, Acc) -> - case lists:member(V, Vsn) of - true -> - vsn_init(Vsns, Vsn, [{V, true}|Acc]); - false -> - vsn_init(Vsns, Vsn, [{V, false}|Acc]) - end. - -app_env_init(Env0, Opts) -> - ?DBG("app_env_init -> unload snmp",[]), +app_agent_env_init(Env0, Opts) -> + ?DBG("app_agent_env_init -> unload snmp",[]), ?line application:unload(snmp), - ?DBG("app_env_init -> load snmp",[]), + ?DBG("app_agent_env_init -> load snmp",[]), ?line application:load(snmp), - ?DBG("app_env_init -> initiate (snmp) application env",[]), + ?DBG("app_agent_env_init -> initiate (snmp agent) application env",[]), F1 = fun({Key, Val} = New, Acc0) -> - ?DBG("app_env_init -> " - "updating setting ~p to ~p", [Key, Val]), + ?DBG("app_agent_env_init -> " + "updating setting ~p to ~p", [Key, Val]), case lists:keyreplace(Key, 1, Acc0, New) of Acc0 -> [New|Acc0]; @@ -504,12 +492,16 @@ app_env_init(Env0, Opts) -> end end, Env = lists:foldr(F1, Env0, Opts), - ?DBG("app_env_init -> Env: ~p",[Env]), - F2 = fun({Key,Val}) -> - ?DBG("app_env_init -> setting ~p to ~p",[Key, Val]), - application_controller:set_env(snmp, Key, Val) - end, - lists:foreach(F2, Env). + ?DBG("app_agent_env_init -> Env: ~p", [Env]), + %% We put it into the app environment just as + %% a precaution, since when starting normally, + %% there is where the environment is taken from. + app_set_agent_env(Env), + Env. + +app_set_agent_env(Value) -> + application_controller:set_env(snmp, agent, Value). + stop_agent(Config) when is_list(Config) -> @@ -544,8 +536,8 @@ stop_agent(Config) when is_list(Config) -> lists:keydelete(snmp_sub, 1, C1). -start_sup() -> - case (catch snmpa_app:start(normal)) of +start_sup(Env) -> + case (catch snmp_app_sup:start_agent(normal, Env)) of {ok, S} -> ?DBG("start_agent -> started, Sup: ~p",[S]), S; @@ -553,7 +545,7 @@ start_sup() -> Else -> ?DBG("start_agent -> unknown result: ~n~p",[Else]), %% Get info about the apps we depend on - ?FAIL({start_failed,Else, ?IS_MNESIA_RUNNING()}) + ?FAIL({start_failed, Else, ?IS_MNESIA_RUNNING()}) end. stop_sup(Pid, _) when (node(Pid) =:= node()) -> @@ -594,7 +586,7 @@ start_sub_sup(Node, Dir) -> start_sub_sup(Dir) -> ?DBG("start_sub -> entry",[]), - Opts = [{db_dir, Dir}, + Opts = [{db_dir, Dir}, {supervisor, [{verbosity, trace}]}], {ok, P} = snmpa_supervisor:start_sub_sup(Opts), unlink(P), -- cgit v1.2.3 From 39540e7c380f6cb218a2ec6324f6296fa8327dba Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Thu, 23 May 2013 12:35:38 +0200 Subject: [snmp/agent] Updated open options for the mnesia mib-storage module Updated the snmpa_mib_storage_mnesia module to handle alias atoms for the nodes option. Also, (git) added mib-storage behaviour ref-man. --- lib/snmp/doc/src/snmp_app.xml | 29 ++- lib/snmp/doc/src/snmp_config.xml | 29 ++- lib/snmp/doc/src/snmpa_mib_storage.xml | 292 ++++++++++++++++++++++++ lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl | 31 ++- 4 files changed, 373 insertions(+), 8 deletions(-) create mode 100644 lib/snmp/doc/src/snmpa_mib_storage.xml (limited to 'lib/snmp') diff --git a/lib/snmp/doc/src/snmp_app.xml b/lib/snmp/doc/src/snmp_app.xml index c62c8f1541..f5a6de1099 100644 --- a/lib/snmp/doc/src/snmp_app.xml +++ b/lib/snmp/doc/src/snmp_app.xml @@ -329,7 +329,7 @@ behaviour.

Several entities (mib-server via the its data module and the symbolic-store) of the snmp agent uses this for storage - of miscelaneous mib data.

+ of miscelaneous mib related data retrieved while loading a mib.

There are several implementations provided with the agent: snmpa_mib_storage_ets, snmpa_mib_storage_dets and snmpa_mib_storage_mnesia.

@@ -340,7 +340,8 @@ ]]>

This is implementattion depended. That is, it depends on the - module. For each module a specific set of options are valid:

+ module. For each module a specific set of options are valid. + For the module provided with the app, these options are supported:

snmpa_mib_storage_ets: {dir, filename()} | {action, keep | clear}, {checksum, boolean()}

@@ -395,7 +396,29 @@

Default is keep.

-

nodes - Defines where to open the table.

+

nodes - A list of node names (or an atom + describing a list of nodes) defining where to open the table. + Its up to the user to ensure that mnesia is actually running + on the specified nodes.

+

The following distinct values are recognised:

+ + +

[] - Translated into a list of the own node: [node()]

+
+ +

all - erlang:nodes()

+
+ +

visible - erlang:nodes(visible)

+
+ +

connected - erlang:nodes(connected)

+
+ +

db_nodes - mnesia:system_info(db_nodes)

+
+
+

Default is the result of the call: erlang:nodes().

diff --git a/lib/snmp/doc/src/snmp_config.xml b/lib/snmp/doc/src/snmp_config.xml index a88111085f..f1acebf2f7 100644 --- a/lib/snmp/doc/src/snmp_config.xml +++ b/lib/snmp/doc/src/snmp_config.xml @@ -326,7 +326,7 @@ behaviour.

Several entities (mib-server via the its data module and the symbolic-store) of the snmp agent uses this for storage - of miscelaneous mib data.

+ of miscelaneous mib related data dataretrieved while loading a mib.

There are several implementations provided with the agent: snmpa_mib_storage_ets, snmpa_mib_storage_dets and snmpa_mib_storage_mnesia.

@@ -337,7 +337,8 @@ ]]>

This is implementattion depended. That is, it depends on the - module. For each module a specific set of options are valid:

+ module. For each module a specific set of options are valid. + For the module provided with the app, these options are supported:

snmpa_mib_storage_ets: {dir, filename()} | {action, keep | clear}, {checksum, boolean()}

@@ -392,7 +393,29 @@

Default is keep.

-

nodes - Defines where to open the table.

+

nodes - A list of node names (or an atom + describing a list of nodes) defining where to open the table. + Its up to the user to ensure that mnesia is actually running + on the specified nodes.

+

The following distinct values are recognised:

+ + +

[] - Translated into a list of the own node: [node()]

+
+ +

all - erlang:nodes()

+
+ +

visible - erlang:nodes(visible)

+
+ +

connected - erlang:nodes(connected)

+
+ +

db_nodes - mnesia:system_info(db_nodes)

+
+
+

Default is the result of the call: erlang:nodes().

diff --git a/lib/snmp/doc/src/snmpa_mib_storage.xml b/lib/snmp/doc/src/snmpa_mib_storage.xml new file mode 100644 index 0000000000..a857ce79e8 --- /dev/null +++ b/lib/snmp/doc/src/snmpa_mib_storage.xml @@ -0,0 +1,292 @@ + + + + +
+ + 20132013 + Ericsson AB. 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. + + + + snmpa_mib_storage + + + + + snmpa_mib_storage.xml +
+ + snmpa_mib_storage + + Behaviour module for the SNMP agent mib storage. + + +

This module defines the behaviour of the SNMP agent mib storage.

+

The mib storage is used by the agent to store internal mib- + related information. The mib storage module is used by several entities, + not just the mib-server.

+ +

A snmpa_mib_storage compliant module + must export the following functions:

+ + + open/5 + + + close/1 + + + read/2 + + + write/2 + + + delete/1 + + + delete/2 + + + match_object/2 + + + match_delete/2 + + + tab2list/1 + + + info/1 + + + sync/1 + + + backup/2 + + + +

The semantics of them and their exact signatures are + explained below.

+ +
+ +
+ CALLBACK FUNCTIONS +

The following functions must be exported from a + mib-server data callback module:

+ + +
+ + + + Module:open(Name, RecordName, Fields, Type, Options) -> {ok, TabId} | {error, Reason} + Create new (mib-server) data instance + + Name = atom() + RecordName = atom() + Fields = [atom()] + Type = set | bag() + Options = list() + TabId = term() + Reason = term() + + +

Create or open a mib storage table.

+

Note that the RecordName and Fields arguments + my not be used in all implementations (they are actually only + needed for mnesia-based implementations).

+ +

Note also that the Options argument comes from + the options config option of the mib-storage config option, + and is passed on as is.

+ + +
+
+ + + Module:close(TabId) -> void() + Close the mib-storage table + + State = term() + + +

Close the mib-storage table.

+ + +
+
+ + + Module:read(TabId, Key) -> false | {value, Record} + Read a record from the mib-storage table + + TabId = term() + Key = term() + Record = tuple() + + +

Read a record from the mib-storage table.

+ + +
+
+ + + Module:write(TabId, Record) -> ok | {error, Reason} + Write a record to the mib-storage table + + TabId = term() + Record = tuple() + Reason = term() + + +

Write a record to the mib-storage table.

+ + +
+
+ + + Module:delete(TabId) -> void() + Delete an entire mib-storage table + + TabId = term() + + +

Delete an entire mib-storage table.

+ + +
+
+ + + Module:delete(TabId, Key) -> ok | {error, Reason} + Delete a record from the mib-storage table + + TabId = term() + Key = term() + Reason = term() + + +

Delete a record from the mib-storage table.

+ + +
+
+ + + Module:match_object(TabId, Pattern) -> {ok, Recs} | {error, Reason} + Search the mib-storage table for record matching pattern + + TabId = term() + Pattern = match_pattern() + Recs = [tuple()] + Reason = term() + + +

Search the mib-storage table for record that match the + specified pattern.

+ + +
+
+ + + Module:match_delete(TabId, Pattern) -> {ok, Recs} | {error, Reason} + Delete records in the mib-storage table matching pattern + + TabId = term() + Pattern = match_pattern() + Recs = [tuple()] + Reason = term() + + +

Search the mib-storage table for record that match the + specified pattern and then delete them. The records deleted are + also returned.

+ + +
+
+ + + Module:tab2list(TabId) -> Recs + Return all records of the mib-storage table + + TabId = term() + Recs = [tuple()] + + +

Return all records in the mib-storage table in the form + of a list.

+ + +
+
+ + + Module:info(TabId) -> {ok, Info} | {error, Reason} + Returns information about the mib-storage table. + + TabId = term() + Info = term() + Reason = term() + + +

Retrieve implementation dependent mib-storage table + information.

+ + +
+
+ + + Module:sync(TabId) -> void() + Synchronize mib-storage table + + TabId = term() + + +

Synchronize the mib-storage table.

+

What this means, if anything, is implementation dependent.

+ + +
+
+ + + Module:backup(TabId, BackupDir) -> ok | {error, Reason} + Perform a backup of the mib-storage table + + TabId = term() + BackupDir = string() + Reason = term() + + +

Perform a backup of the mib-storage table.

+

What this means, if anything, is implementation dependent.

+ +
+
+ +
+ +
+ diff --git a/lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl b/lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl index dca44d3c33..192b5aa26e 100644 --- a/lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl +++ b/lib/snmp/src/agent/snmpa_mib_storage_mnesia.erl @@ -63,8 +63,8 @@ open(Name, RecName, Fields, Type, Opts) -> ?vtrace("open ~p table ~p for record ~p", [Type, Name, RecName]), - Action = snmp_misc:get_option(action, Opts, keep), - Nodes = snmp_misc:get_option(nodes, Opts, erlang:nodes()), + Action = get_action(Opts), + Nodes = get_nodes(Opts), case table_exists(Name) of true when (Action =:= keep) -> ?vtrace("open table ~p - exist (keep)", [Name]), @@ -271,5 +271,32 @@ backup(_, _) -> %%---------------------------------------------------------------------- +get_action(Opts) -> + snmp_misc:get_option(action, Opts, keep). + +get_nodes(Opts) -> + case snmp_misc:get_option(nodes, Opts, erlang:nodes()) of + [] -> + [node()]; + Nodes when is_list(Nodes) -> + Nodes; + all -> + erlang:nodes(); + visible -> + erlang:nodes(visible); + connected -> + erlang:nodes(connected); + db_nodes -> + try mnesia:system_info(db_nodes) of + DbNodes when is_list(DbNodes) -> + DbNodes; + _ -> + erlang:nodes() + catch + _:_ -> + erlang:nodes() + end + end. + %% user_err(F, A) -> %% snmpa_error:user_err(F, A). -- cgit v1.2.3 From 38472ca2c30906d55dc0bee8f9fc2ed97b8576f3 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Thu, 23 May 2013 15:45:57 +0200 Subject: [snmp/agent] Merging test case specific and common config env There is a set of default agent config environment values used when starting an agent. For specififc group of test cases, other values is used. These two groups of environment is now merged in a more controlled way. Also test case grouping make use of more test cases functions (in order to make the groups() function more readable). --- lib/snmp/test/snmp_agent_test.erl | 255 ++++++++++++++++++---------------- lib/snmp/test/snmp_agent_test_lib.erl | 194 +++++++++++++++++++++++--- 2 files changed, 314 insertions(+), 135 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl index 5216b82cf8..01f0e58bc2 100644 --- a/lib/snmp/test/snmp_agent_test.erl +++ b/lib/snmp/test/snmp_agent_test.erl @@ -94,19 +94,8 @@ all() -> groups() -> [ - {all_tcs, [], cases()}, - {mib_storage, [], - [ - {group, mib_storage_ets}, - {group, mib_storage_dets}, - {group, mib_storage_mnesia}, - {group, mib_storage_size_check_ets}, - {group, mib_storage_size_check_dets}, - {group, mib_storage_size_check_mnesia}, - {group, mib_storage_varm_dets}, - {group, mib_storage_varm_mnesia} - ] - }, + {all_tcs, [], cases()}, + {mib_storage, [], mib_storage_cases()}, {mib_storage_ets, [], mib_storage_ets_cases()}, {mib_storage_dets, [], mib_storage_dets_cases()}, {mib_storage_mnesia, [], mib_storage_mnesia_cases()}, @@ -123,109 +112,18 @@ groups() -> {test_multi_threaded, [], mt_cases()}, {multiple_reqs, [], mul_cases()}, {multiple_reqs_2, [], mul_cases_2()}, - {v2_inform, [], - [ - v2_inform_i - ] - }, - {v3_security, [], - [ - v3_crypto_basic, - v3_md5_auth, - v3_sha_auth, - v3_des_priv - ] - }, - {standard_mibs, [], - [ - snmp_standard_mib, - snmp_community_mib, - snmp_framework_mib, - snmp_target_mib, - snmp_notification_mib, - snmp_view_based_acm_mib - ] - }, - {standard_mibs_2, [], - [ - snmpv2_mib_2, - snmp_community_mib_2, - snmp_framework_mib_2, - snmp_target_mib_2, - snmp_notification_mib_2, - snmp_view_based_acm_mib_2 - ] - }, - {standard_mibs_3, [], - [ - snmpv2_mib_3, - snmp_framework_mib_3, - snmp_mpd_mib_3, - snmp_target_mib_3, - snmp_notification_mib_3, - snmp_view_based_acm_mib_3, - snmp_user_based_sm_mib_3 - ] - }, - {reported_bugs, [], - [ - otp_1128, - otp_1129, - otp_1131, - otp_1162, - otp_1222, - otp_1298, - otp_1331, - otp_1338, - otp_1342, - otp_2776, - otp_2979, - otp_3187, - otp_3725 - ] - }, - {reported_bugs_2, [], - [ - otp_1128_2, - otp_1129_2, - otp_1131_2, - otp_1162_2, - otp_1222_2, - otp_1298_2, - otp_1331_2, - otp_1338_2, - otp_1342_2, - otp_2776_2, - otp_2979_2, - otp_3187_2 - ] - }, - {reported_bugs_3, [], - [ - otp_1128_3, - otp_1129_3, - otp_1131_3, - otp_1162_3, - otp_1222_3, - otp_1298_3, - otp_1331_3, - otp_1338_3, - otp_1342_3, - otp_2776_3, - otp_2979_3, - otp_3187_3, - otp_3542 - ] - }, - {tickets1, [], - [ - {group, otp_4394}, - {group, otp_7157} - ] - }, - {tickets2, [], [otp8395, otp9884]}, - {otp_4394, [], [otp_4394_test]}, - {otp_7157, [], [otp_7157_test]} + {v2_inform, [], v2_inform_cases()}, + {v3_security, [], v3_security_cases()}, + {standard_mibs, [], standard_mibs_cases()}, + {standard_mibs_2, [], standard_mibs2_cases()}, + {standard_mibs_3, [], standard_mibs3_cases()}, + {reported_bugs, [], reported_bugs_cases()}, + {reported_bugs_2, [], reported_bugs2_cases()}, + {reported_bugs_3, [], reported_bugs3_cases()}, + {tickets1, [], tickets1_cases()}, + {tickets2, [], tickets2_cases()}, + {otp_4394, [], [otp_4394_test]}, + {otp_7157, [], [otp_7157_test]} ]. @@ -572,6 +470,18 @@ delete_mib_storage_mnesia_tables() -> %% versions as well, _N. %%----------------------------------------------------------------- +mib_storage_cases() -> + [ + {group, mib_storage_ets}, + {group, mib_storage_dets}, + {group, mib_storage_mnesia}, + {group, mib_storage_size_check_ets}, + {group, mib_storage_size_check_dets}, + {group, mib_storage_size_check_mnesia}, + {group, mib_storage_varm_dets}, + {group, mib_storage_varm_mnesia} + ]. + mib_storage_ets_cases() -> [ mse_simple, @@ -2144,6 +2054,10 @@ finish_v3_inform(X) -> finish_v2_inform(X). +v2_inform_cases() -> + [ + v2_inform_i + ]. v2_inform_i(suite) -> []; v2_inform_i(Config) when is_list(Config) -> @@ -2382,6 +2296,15 @@ v3_processing(Config) when is_list(Config) -> %% report, which makes it in sync. The notification-generating %% application times out, and send again. This time it'll work. +v3_security_cases() -> + [ + v3_crypto_basic, + v3_md5_auth, + v3_sha_auth, + v3_des_priv + ]. + + v3_crypto_basic(suite) -> []; v3_crypto_basic(_Config) -> ?P(v3_crypto_basic), @@ -4262,7 +4185,16 @@ bad_return() -> %%% already tested by the normal tests. %%%----------------------------------------------------------------- - +standard_mibs_cases() -> + [ + snmp_standard_mib, + snmp_community_mib, + snmp_framework_mib, + snmp_target_mib, + snmp_notification_mib, + snmp_view_based_acm_mib + ]. + %%----------------------------------------------------------------- %% For this test, the agent is configured for v1. @@ -4346,6 +4278,18 @@ std_mib_write() -> std_mib_asn_err() -> snmp_test_mgr:send_bytes([48,99,67,12,0,0,0,0,0,0,5]). + +standard_mibs2_cases() -> + [ + snmpv2_mib_2, + snmp_community_mib_2, + snmp_framework_mib_2, + snmp_target_mib_2, + snmp_notification_mib_2, + snmp_view_based_acm_mib_2 + ]. + + %%----------------------------------------------------------------- %% For this test, the agent is configured for v2 and v3. %% o Test the counters and control objects in SNMPv2-MIB @@ -4394,6 +4338,19 @@ snmpv2_mib_2(Config) when is_list(Config) -> ?LOG("snmpv2_mib_2 -> done",[]). + +standard_mibs3_cases() -> + [ + snmpv2_mib_3, + snmp_framework_mib_3, + snmp_mpd_mib_3, + snmp_target_mib_3, + snmp_notification_mib_3, + snmp_view_based_acm_mib_3, + snmp_user_based_sm_mib_3 + ]. + + %% Req. SNMPv2-MIB snmpv2_mib_3(suite) -> []; snmpv2_mib_3(Config) when is_list(Config) -> @@ -5306,7 +5263,57 @@ loop_it_2(Oid, N) -> %%% Testing of reported bugs and other tickets. %%%----------------------------------------------------------------- +reported_bugs_cases() -> + [ + otp_1128, + otp_1129, + otp_1131, + otp_1162, + otp_1222, + otp_1298, + otp_1331, + otp_1338, + otp_1342, + otp_2776, + otp_2979, + otp_3187, + otp_3725 + ]. + +reported_bugs2_cases() -> + [ + otp_1128_2, + otp_1129_2, + otp_1131_2, + otp_1162_2, + otp_1222_2, + otp_1298_2, + otp_1331_2, + otp_1338_2, + otp_1342_2, + otp_2776_2, + otp_2979_2, + otp_3187_2 + ]. +reported_bugs3_cases() -> + [ + otp_1128_3, + otp_1129_3, + otp_1131_3, + otp_1162_3, + otp_1222_3, + otp_1298_3, + otp_1331_3, + otp_1338_3, + otp_1342_3, + otp_2776_3, + otp_2979_3, + otp_3187_3, + otp_3542 + ]. + + %%----------------------------------------------------------------- %% Ticket: OTP-1128 %% Slogan: Bug in handling of createAndWait set-requests. @@ -5783,7 +5790,12 @@ otp_3725_test(MaNode) -> %% Slogan: Target mib tag list check invalid %%----------------------------------------------------------------- - +tickets1_cases() -> + [ + {group, otp_4394}, + {group, otp_7157} + ]. + init_otp_4394(Config) when is_list(Config) -> ?DBG("init_otp_4394 -> entry with" @@ -5945,6 +5957,13 @@ otp_7157_test1(MA) -> %% These cases are started in the new way %%----------------------------------------------------------------- +tickets2_cases() -> + [ + otp8395, + otp9884 + ]. + + otp8395({init, Config}) when is_list(Config) -> ?DBG("otp8395(init) -> entry with" "~n Config: ~p", [Config]), diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl index 5261a9c40e..2c24dd3712 100644 --- a/lib/snmp/test/snmp_agent_test_lib.erl +++ b/lib/snmp/test/snmp_agent_test_lib.erl @@ -441,13 +441,13 @@ start_agent(Config, Vsns, Opts) -> [{versions, Vsns}, {agent_type, master}, {agent_verbosity, trace}, + {db_dir, AgentDbDir}, {audit_trail_log, [{type, read_write}, {dir, AgentLogDir}, {size, {10240, 10}}]}, {config, [{dir, AgentConfDir}, {force_load, false}, {verbosity, trace}]}, - {db_dir, AgentDbDir}, {local_db, [{repair, true}, {verbosity, log}]}, {mib_server, [{verbosity, log}]}, @@ -478,30 +478,190 @@ start_agent(Config, Vsns, Opts) -> app_agent_env_init(Env0, Opts) -> ?DBG("app_agent_env_init -> unload snmp",[]), ?line application:unload(snmp), + ?DBG("app_agent_env_init -> load snmp",[]), ?line application:load(snmp), - ?DBG("app_agent_env_init -> initiate (snmp agent) application env",[]), - F1 = fun({Key, Val} = New, Acc0) -> - ?DBG("app_agent_env_init -> " - "updating setting ~p to ~p", [Key, Val]), - case lists:keyreplace(Key, 1, Acc0, New) of - Acc0 -> - [New|Acc0]; - Acc -> - Acc - end - end, - Env = lists:foldr(F1, Env0, Opts), - ?DBG("app_agent_env_init -> Env: ~p", [Env]), + + ?DBG("app_agent_env_init -> " + "merge or maybe replace (snmp agent) app env",[]), + Env = add_or_maybe_merge_agent_env(Opts, Env0), + ?DBG("app_agent_env_init -> merged env: " + "~n ~p", [Env]), + %% We put it into the app environment just as %% a precaution, since when starting normally, - %% there is where the environment is taken from. - app_set_agent_env(Env), + %% this is where the environment is extracted from. + app_agent_set_env(Env), Env. -app_set_agent_env(Value) -> +app_agent_set_env(Value) -> application_controller:set_env(snmp, agent, Value). +add_or_maybe_merge_agent_env([], Env) -> + ?DBG("merging agent env -> merged", []), + lists:keysort(1, Env); +add_or_maybe_merge_agent_env([{Key, Value1}|Opts], Env) -> + ?DBG("merging agent env -> add, replace or merge ~p", [Key]), + case lists:keysearch(Key, 1, Env) of + {value, {Key, Value1}} -> + %% Identical, move on + ?DBG("merging agent env -> " + "no need to merge ~p - identical - keep: " + "~n ~p", [Key, Value1]), + add_or_maybe_merge_agent_env(Opts, Env); + {value, {Key, Value2}} -> + %% Another value, merge or replace + NewValue = merge_or_replace_agent_env(Key, Value1, Value2), + Env2 = lists:keyreplace(Key, 1, Env, {Key, NewValue}), + add_or_maybe_merge_agent_env(Opts, Env2); + false -> + ?DBG("merging agent env -> no old ~p to merge with - add: " + "~n ~p", [Key, Value1]), + add_or_maybe_merge_agent_env(Opts, [{Key, Value1}|Env]) + end. + +merge_or_replace_agent_env(versions, NewVersions, _OldVersions) -> + ?DBG("merging agent env -> versions replaced: ~p -> ~p", + [NewVersions, _OldVersions]), + NewVersions; +merge_or_replace_agent_env(agent_type, NewType, _OldType) -> + ?DBG("merging agent env -> agent type replaced: ~p -> ~p", + [NewType, _OldType]), + NewType; +merge_or_replace_agent_env(agent_verbosity, NewVerbosity, _OldVerbosity) -> + ?DBG("merging agent env -> agent verbosity replaced: ~p -> ~p", + [NewVerbosity, _OldVerbosity]), + NewVerbosity; +merge_or_replace_agent_env(db_dir, NewDbDir, _OldDbDir) -> + ?DBG("merging agent env -> db-dir replaced: ~p -> ~p", + [NewDbDir, _OldDbDir]), + NewDbDir; +merge_or_replace_agent_env(audit_trail_log, NewATL, OldATL) -> + merge_or_replace_agent_env_atl(NewATL, OldATL); +merge_or_replace_agent_env(config, NewConfig, OldConfig) -> + merge_or_replace_agent_env_config(NewConfig, OldConfig); +merge_or_replace_agent_env(local_db, NewLdb, OldLdb) -> + merge_or_replace_agent_env_ldb(NewLdb, OldLdb); +merge_or_replace_agent_env(mib_storage, NewMst, OldMst) -> + merge_or_replace_agent_env_mib_storage(NewMst, OldMst); +merge_or_replace_agent_env(mib_server, NewMibs, OldMibs) -> + merge_or_replace_agent_env_mib_server(NewMibs, OldMibs); +merge_or_replace_agent_env(symbolic_store, NewSymStore, OldSymStore) -> + merge_or_replace_agent_env_symbolic_store(NewSymStore, OldSymStore); +merge_or_replace_agent_env(note_store, NewNoteStore, OldNoteStore) -> + merge_or_replace_agent_env_note_store(NewNoteStore, OldNoteStore); +merge_or_replace_agent_env(net_if, NewNetIf, OldNetIf) -> + merge_or_replace_agent_env_net_if(NewNetIf, OldNetIf); +merge_or_replace_agent_env(Key, NewValue, OldValue) -> + ?FAIL({not_implemented_merge_or_replace, + Key, NewValue, OldValue}). + +merge_or_replace_agent_env_atl(New, Old) -> + ATL = merge_agent_options(New, Old), + ?DBG("merging agent env -> audit-trail-log merged: " + "~n ~p | ~p -> ~p", [New, Old, ATL]), + ATL. + +merge_or_replace_agent_env_config(New, Old) -> + Config = merge_agent_options(New, Old), + case lists:keymember(dir, 1, Config) of + true -> + ?DBG("merging agent env -> config merged: " + "~n ~p | ~p -> ~p", [New, Old, Config]), + Config; + false -> + ?FAIL({missing_mandatory_option, {config, dir}}) + end. + +merge_or_replace_agent_env_ldb(New, Old) -> + LDB = merge_agent_options(New, Old), + ?DBG("merging agent env -> local-db merged: " + "~n ~p | ~p -> ~p", [New, Old, LDB]), + LDB. + +merge_or_replace_agent_env_mib_storage(NewMibStorage, OldMibStorage) -> + %% Shall we merge or replace? + %% module is mandatory. We will only merge if NewModule is + %% equal to OldModule. + NewModule = + case lists:keysearch(module, 1, NewMibStorage) of + {value, {module, M}} -> + M; + false -> + ?FAIL({missing_mandatory_option, {mib_storage, module}}) + end, + case lists:keysearch(module, 1, OldMibStorage) of + {value, {module, NewModule}} -> + %% Same module => merge + %% Non-ex new options => remove + %% Ex new options and non-ex old options => replace + %% Otherwise merge + case lists:keysearch(options, 1, NewMibStorage) of + false -> + ?DBG("merging agent env -> " + "no mib-storage ~p merge needed - " + "no new options (= remove old options)", [NewModule]), + NewMibStorage; + {value, {options, NewOptions}} -> + case lists:keysearch(options, 1, OldMibStorage) of + false -> + ?DBG("merging agent env -> " + "no mib-storage ~p merge needed - " + "no old options", [NewModule]), + NewMibStorage; + {value, {options, OldOptions}} -> + MergedOptions = + merge_agent_options(NewOptions, OldOptions), + ?DBG("merging agent env -> mib-storage ~p merged: " + "~n Options: ~p | ~p -> ~p", + [NewModule, + NewOptions, OldOptions, MergedOptions]), + [{module, NewModule}, + {options, MergedOptions}] + end + end; + _ -> + %% Diff module => replace + ?DBG("merging agent env -> " + "no mib-storage ~p merge needed - " + "new module", [NewModule]), + NewMibStorage + end. + +merge_or_replace_agent_env_mib_server(New, Old) -> + MibServer = merge_agent_options(New, Old), + ?DBG("merging agent env -> mib-server merged: " + "~n ~p | ~p -> ~p", [New, Old, MibServer]), + MibServer. + +merge_or_replace_agent_env_symbolic_store(New, Old) -> + SymbolicStore = merge_agent_options(New, Old), + ?DBG("merging agent env -> symbolic-store merged: " + "~n ~p | ~p -> ~p", [New, Old, SymbolicStore]), + SymbolicStore. + +merge_or_replace_agent_env_note_store(New, Old) -> + NoteStore = merge_agent_options(New, Old), + ?DBG("merging agent env -> note-store merged: " + "~n ~p | ~p -> ~p", [New, Old, NoteStore]), + NoteStore. + +merge_or_replace_agent_env_net_if(New, Old) -> + NetIf = merge_agent_options(New, Old), + ?DBG("merging agent env -> net-if merged: " + "~n ~p | ~p -> ~p", [New, Old, NetIf]), + NetIf. + +merge_agent_options([], Options) -> + lists:keysort(1, Options); +merge_agent_options([{Key, _Value} = Opt|Opts], Options) -> + case lists:keysearch(Key, 1, Options) of + {value, _} -> + NewOptions = lists:keyreplace(Key, 1, Options, Opt), + merge_agent_options(Opts, NewOptions); + false -> + merge_agent_options(Opts, [Opt|Options]) + end. stop_agent(Config) when is_list(Config) -> -- cgit v1.2.3 From 2fa265b38aeac7c4f29a878af6a7d3c49fe50931 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Thu, 23 May 2013 17:03:17 +0200 Subject: [snmp/agent] Handle mib-storage ets module non-ex file Make sure snmpa_mib_storage_ets can handle a non-ex file whe n openning a table (it should simply create it). --- lib/snmp/src/agent/snmpa_mib_storage_ets.erl | 30 +++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmpa_mib_storage_ets.erl b/lib/snmp/src/agent/snmpa_mib_storage_ets.erl index 4afdc76ee5..852df06fa0 100644 --- a/lib/snmp/src/agent/snmpa_mib_storage_ets.erl +++ b/lib/snmp/src/agent/snmpa_mib_storage_ets.erl @@ -73,19 +73,29 @@ open(Name, RecName, _Fields, Type, Opts) -> {value, {dir, Dir}} -> Action = snmp_misc:get_option(action, Opts, keep), Checksum = snmp_misc:get_option(checksum, Opts, false), - ?vtrace("open ~p database ~p", [Type, Name]), + ?vtrace("open ~p database ~p - check if file exist", [Type, Name]), File = filename:join(Dir, atom_to_list(Name) ++ ".db"), case file:read_file_info(File) of {ok, _} -> + ?vdebug("open ~p database ~p - file exist - try reading", + [Type, Name]), case ets:file2tab(File, [{verify, Checksum}]) of {ok, ID} -> + ?vtrace("open ~p database ~p - " + "data read from file", [Type, Name]), {ok, #tab{id = ID, rec_name = RecName, file = File, checksum = Checksum}}; {error, Reason} when (Action =:= keep) -> + ?vinfo("open ~p database ~p - " + "failed reading from file (keep)", + [Type, Name, Reason]), {error, {file2tab, Reason}}; {error, Reason} -> + ?vlog("open ~p database ~p - " + "failed reading from file (clear)", + [Type, Name, Reason]), user_err("Warning: could not read file - " "create new (empty): " "~n File: ~p" @@ -97,9 +107,26 @@ open(Name, RecName, _Fields, Type, Opts) -> file = File, checksum = Checksum}} end; + {error, enoent} -> + %% No such file - create it + ?vdebug("open ~p database ~p - " + "file does *not* exist - create", + [Type, Name]), + ID = ets:new(Name, [Type, protected, {keypos, 2}]), + write_ets_file(ID, File, Checksum), + {ok, #tab{id = ID, + rec_name = RecName, + file = File, + checksum = Checksum}}; {error, Reason} when (Action =:= keep) -> + ?vinfo("open ~p database ~p - " + "failed reading file info (keep)", + [Type, Name, Reason]), {error, {read_file_info, Reason}}; {error, Reason} -> + ?vlog("open ~p database ~p - " + "failed reading file info (clear)", + [Type, Name, Reason]), user_err("Warning: could not read file info - " "create new: " "~n File: ~p" @@ -112,6 +139,7 @@ open(Name, RecName, _Fields, Type, Opts) -> checksum = Checksum}} end; false -> + ?vdebug("open ~p database ~p - ok", [Type, Name]), ID = ets:new(Name, [Type, protected, {keypos, 2}]), {ok, #tab{id = ID, rec_name = RecName}} end. -- cgit v1.2.3 From 246afa772b2fed132ee236fe335045164a8de56f Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Thu, 23 May 2013 17:04:39 +0200 Subject: [snmp/agent] Make the mib-server test (sub-) suite use new mib-storage --- lib/snmp/test/snmp_agent_mibs_test.erl | 137 ++++++++++++++++++++++++--------- 1 file changed, 102 insertions(+), 35 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/test/snmp_agent_mibs_test.erl b/lib/snmp/test/snmp_agent_mibs_test.erl index 3e48130fac..4569be0b5a 100644 --- a/lib/snmp/test/snmp_agent_mibs_test.erl +++ b/lib/snmp/test/snmp_agent_mibs_test.erl @@ -19,13 +19,16 @@ %% %%---------------------------------------------------------------------- -%% Purpose: +%% Purpose: Test suite of the agent mib-server. %%---------------------------------------------------------------------- + -module(snmp_agent_mibs_test). + %%---------------------------------------------------------------------- %% Include files %%---------------------------------------------------------------------- + -include_lib("test_server/include/test_server.hrl"). -include("snmp_test_lib.hrl"). -include_lib("snmp/include/snmp_types.hrl"). @@ -39,13 +42,23 @@ %% External exports %%---------------------------------------------------------------------- -export([ - all/0,groups/0,init_per_group/2,end_per_group/2, - init_per_testcase/2, end_per_testcase/2, - init_per_suite/1, end_per_suite/1, + all/0, + groups/0, + + init_per_suite/1, + end_per_suite/1, + + init_per_group/2, + end_per_group/2, + + init_per_testcase/2, + end_per_testcase/2, start_and_stop/1, - size_check_ets/1, + size_check_ets1/1, + size_check_ets2/1, + size_check_ets3/1, size_check_dets/1, size_check_mnesia/1, load_unload/1, @@ -55,6 +68,7 @@ ]). + %%---------------------------------------------------------------------- %% Internal exports %%---------------------------------------------------------------------- @@ -71,6 +85,16 @@ %% External functions %%====================================================================== +init_per_testcase(size_check_ets2, Config) when is_list(Config) -> + Dir = ?config(priv_dir, Config), + EtsDir = join(Dir, "ets_dir2/"), + ?line ok = file:make_dir(EtsDir), + [{ets_dir, EtsDir}|Config]; +init_per_testcase(size_check_ets3, Config) when is_list(Config) -> + Dir = ?config(priv_dir, Config), + EtsDir = join(Dir, "ets_dir3/"), + ?line ok = file:make_dir(EtsDir), + [{ets_dir, EtsDir}|Config]; init_per_testcase(size_check_dets, Config) when is_list(Config) -> Dir = ?config(priv_dir, Config), DetsDir = join(Dir, "dets_dir/"), @@ -98,6 +122,13 @@ init_per_testcase(cache_test, Config) when is_list(Config) -> init_per_testcase(_Case, Config) when is_list(Config) -> Config. +end_per_testcase(EtsCase, Config) + when (is_list(Config) andalso + ((EtsCase =:= size_check_ets2) orelse + (EtsCase =:= size_check_ets3))) -> + Dir = ?config(ets_dir, Config), + ?line ok = ?DEL_DIR(Dir), + lists:keydelete(ets_dir, 1, Config); end_per_testcase(size_check_dets, Config) when is_list(Config) -> Dir = ?config(dets_dir, Config), ?line ok = ?DEL_DIR(Dir), @@ -124,18 +155,31 @@ cases(). groups() -> [{size_check, [], - [size_check_ets, size_check_dets, size_check_mnesia]}]. + [ + size_check_ets1, % Plain ets + size_check_ets2, % ets with a file + size_check_ets3, % ets with a checksummed file + size_check_dets, % Plain dets + size_check_mnesia % Plain mnesia + ] + }]. init_per_group(_GroupName, Config) -> - Config. + Config. end_per_group(_GroupName, Config) -> - Config. + Config. cases() -> -[start_and_stop, load_unload, {group, size_check}, - me_lookup, which_mib, cache_test]. + [ + start_and_stop, + load_unload, + {group, size_check}, + me_lookup, + which_mib, + cache_test + ]. init_per_suite(Config) when is_list(Config) -> %% Data dir points wrong @@ -175,7 +219,6 @@ load_unload(suite) -> []; load_unload(Config) when is_list(Config) -> Prio = normal, Verbosity = log, - %% MibStorage = ets, MibDir = ?config(snmp_data_dir, Config), ?DBG("load_unload -> start symbolic store", []), @@ -221,21 +264,42 @@ load_unload(Config) when is_list(Config) -> %% --------------------------------------------------------------------- -size_check_ets(suite) -> +size_check_ets1(suite) -> + []; +size_check_ets1(Config) when is_list(Config) -> + MibStorage = [{module, snmpa_mib_storage_ets}], + do_size_check([{mib_storage, MibStorage}|Config]). + +size_check_ets2(suite) -> + []; +size_check_ets2(Config) when is_list(Config) -> + Dir = ?config(ets_dir, Config), + MibStorage = [{module, snmpa_mib_storage_ets}, + {options, [{dir, Dir}]}], + do_size_check([{mib_storage, MibStorage}|Config]). + +size_check_ets3(suite) -> []; -size_check_ets(Config) when is_list(Config) -> - do_size_check([{mib_storage, ets}|Config]). +size_check_ets3(Config) when is_list(Config) -> + Dir = ?config(ets_dir, Config), + MibStorage = [{module, snmpa_mib_storage_ets}, + {options, [{dir, Dir}, {checksum, true}]}], + do_size_check([{mib_storage, MibStorage}|Config]). size_check_dets(suite) -> []; size_check_dets(Config) when is_list(Config) -> Dir = ?config(dets_dir, Config), - do_size_check([{mib_storage, {dets, Dir}}|Config]). + MibStorage = [{module, snmpa_mib_storage_dets}, + {options, [{dir, Dir}]}], + do_size_check([{mib_storage, MibStorage}|Config]). size_check_mnesia(suite) -> []; size_check_mnesia(Config) when is_list(Config) -> - do_size_check([{mib_storage, {mnesia, [node()]}}|Config]). + MibStorage = [{module, snmpa_mib_storage_mnesia}, + {options, [{nodes, [node()]}]}], + do_size_check([{mib_storage, MibStorage}|Config]). do_size_check(Config) -> ?DBG("do_size_check -> start", []), @@ -294,7 +358,6 @@ me_lookup(suite) -> []; me_lookup(Config) when is_list(Config) -> Prio = normal, Verbosity = trace, - %% MibStorage = ets, MibDir = ?config(snmp_data_dir, Config), StdMibDir = filename:join(code:priv_dir(snmp), "mibs") ++ "/", Mibs = ["Test2", "TestTrap", "TestTrapv2"], @@ -348,7 +411,6 @@ which_mib(suite) -> []; which_mib(Config) when is_list(Config) -> Prio = normal, Verbosity = trace, - %% MibStorage = ets, MibDir = ?config(snmp_data_dir, Config), StdMibDir = filename:join(code:priv_dir(snmp), "mibs") ++ "/", Mibs = ["Test2", "TestTrap", "TestTrapv2"], @@ -406,28 +468,28 @@ cache_test(Config) when is_list(Config) -> ?DBG("cache_test -> start", []), Prio = normal, Verbosity = trace, - MibStorage = ets, + MibStorage = [{module, snmpa_mib_storage_ets}], MibDir = ?config(snmp_data_dir, Config), StdMibDir = filename:join(code:priv_dir(snmp), "mibs") ++ "/", - Mibs = ["Test2", "TestTrap", "TestTrapv2"], - StdMibs = ["OTP-SNMPEA-MIB", - "SNMP-COMMUNITY-MIB", - "SNMP-FRAMEWORK-MIB", - "SNMP-MPD-MIB", - "SNMP-NOTIFICATION-MIB", - "SNMP-TARGET-MIB", - %% "SNMP-USER-BASED-SM-MIB", - "SNMP-VIEW-BASED-ACM-MIB", - "SNMPv2-MIB", - "SNMPv2-TC", - "SNMPv2-TM"], + Mibs = ["Test2", "TestTrap", "TestTrapv2"], + StdMibs = ["OTP-SNMPEA-MIB", + "SNMP-COMMUNITY-MIB", + "SNMP-FRAMEWORK-MIB", + "SNMP-MPD-MIB", + "SNMP-NOTIFICATION-MIB", + "SNMP-TARGET-MIB", + %% "SNMP-USER-BASED-SM-MIB", + "SNMP-VIEW-BASED-ACM-MIB", + "SNMPv2-MIB", + "SNMPv2-TC", + "SNMPv2-TM"], ?DBG("cache_test -> start symbolic store", []), ?line sym_start(Prio, MibStorage, Verbosity), ?DBG("cache_test -> start mib server", []), - GcLimit = 2, - Age = timer:seconds(10), + GcLimit = 2, + Age = timer:seconds(10), CacheOpts = [{autogc, false}, {age, Age}, {gclimit, GcLimit}], ?line MibsPid = mibs_start(Prio, MibStorage, [], Verbosity, CacheOpts), @@ -537,7 +599,7 @@ mnesia_stop() -> %% - Symbolic Store mini interface sym_start(Prio, Verbosity) -> - sym_start(Prio, ets, Verbosity). + sym_start(Prio, mib_storage(), Verbosity). sym_start(Prio, MibStorage, Verbosity) -> Opts = [{mib_storage, MibStorage}, {verbosity,Verbosity}], @@ -554,7 +616,7 @@ sym_info() -> %% -- MIB server mini interface mibs_start(Prio, Verbosity) when is_atom(Prio) andalso is_atom(Verbosity) -> - mibs_start(Prio, ets, [], Verbosity). + mibs_start(Prio, mib_storage(), [], Verbosity). mibs_start(Prio, MibStorage, Verbosity) when is_atom(Prio) andalso is_atom(Verbosity) -> @@ -671,6 +733,11 @@ which_mib(M1, M2) -> {error, {invalid_mib, M1, M2}}. +%% Default mib-storage +mib_storage() -> + [{module, snmpa_mib_storage_ets}]. + + %% -- display_memory_usage(MibsPid) -> -- cgit v1.2.3 From 49d1609d1ccdd967f20140a2285f118df887f3e9 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Fri, 24 May 2013 15:40:46 +0200 Subject: [snmp/agent] Improved mib-storage ets module error handling Also fixed some of the debug printouts. --- lib/snmp/src/agent/snmpa_mib_storage_ets.erl | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmpa_mib_storage_ets.erl b/lib/snmp/src/agent/snmpa_mib_storage_ets.erl index 852df06fa0..04faf46864 100644 --- a/lib/snmp/src/agent/snmpa_mib_storage_ets.erl +++ b/lib/snmp/src/agent/snmpa_mib_storage_ets.erl @@ -89,13 +89,14 @@ open(Name, RecName, _Fields, Type, Opts) -> checksum = Checksum}}; {error, Reason} when (Action =:= keep) -> ?vinfo("open ~p database ~p - " - "failed reading from file (keep)", + "failed reading from file (keep): " + "~n ~p", [Type, Name, Reason]), {error, {file2tab, Reason}}; {error, Reason} -> ?vlog("open ~p database ~p - " - "failed reading from file (clear)", - [Type, Name, Reason]), + "failed reading from file (clear): " + "~n ~p", [Type, Name, Reason]), user_err("Warning: could not read file - " "create new (empty): " "~n File: ~p" @@ -120,15 +121,17 @@ open(Name, RecName, _Fields, Type, Opts) -> checksum = Checksum}}; {error, Reason} when (Action =:= keep) -> ?vinfo("open ~p database ~p - " - "failed reading file info (keep)", + "failed reading file info (keep): " + "~n ~p", [Type, Name, Reason]), {error, {read_file_info, Reason}}; {error, Reason} -> ?vlog("open ~p database ~p - " - "failed reading file info (clear)", + "failed reading file info (clear): " + "~n ~p", [Type, Name, Reason]), user_err("Warning: could not read file info - " - "create new: " + "create new file: " "~n File: ~p" "~n Reason: ~p", [File, Reason]), ID = ets:new(Name, [Type, protected, {keypos, 2}]), -- cgit v1.2.3 From fd747e9088186657a29fa252cae06a7d7c08761a Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Fri, 24 May 2013 15:41:43 +0200 Subject: [snmp/agent] Some restructuring and some new test cases of mib-server suite --- lib/snmp/test/snmp_agent_mibs_test.erl | 186 ++++++++++++++++++++------------- 1 file changed, 115 insertions(+), 71 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/test/snmp_agent_mibs_test.erl b/lib/snmp/test/snmp_agent_mibs_test.erl index 4569be0b5a..248fe7d83e 100644 --- a/lib/snmp/test/snmp_agent_mibs_test.erl +++ b/lib/snmp/test/snmp_agent_mibs_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2010. All Rights Reserved. +%% Copyright Ericsson AB 2003-2013. 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 @@ -20,6 +20,7 @@ %% %%---------------------------------------------------------------------- %% Purpose: Test suite of the agent mib-server. +%% Some of these tests should really be in a mib-storage suite. %%---------------------------------------------------------------------- -module(snmp_agent_mibs_test). @@ -58,7 +59,9 @@ size_check_ets1/1, size_check_ets2/1, + size_check_ets2_bad_file1/1, size_check_ets3/1, + size_check_ets3_bad_file1/1, size_check_dets/1, size_check_mnesia/1, load_unload/1, @@ -85,28 +88,51 @@ %% External functions %%====================================================================== -init_per_testcase(size_check_ets2, Config) when is_list(Config) -> - Dir = ?config(priv_dir, Config), - EtsDir = join(Dir, "ets_dir2/"), - ?line ok = file:make_dir(EtsDir), - [{ets_dir, EtsDir}|Config]; -init_per_testcase(size_check_ets3, Config) when is_list(Config) -> - Dir = ?config(priv_dir, Config), - EtsDir = join(Dir, "ets_dir3/"), - ?line ok = file:make_dir(EtsDir), - [{ets_dir, EtsDir}|Config]; -init_per_testcase(size_check_dets, Config) when is_list(Config) -> - Dir = ?config(priv_dir, Config), - DetsDir = join(Dir, "dets_dir/"), - ?line ok = file:make_dir(DetsDir), - [{dets_dir, DetsDir}|Config]; -init_per_testcase(size_check_mnesia, Config) when is_list(Config) -> - Dir = ?config(priv_dir, Config), - MnesiaDir = join(Dir, "mnesia_dir/"), - ?line ok = file:make_dir(MnesiaDir), - mnesia_start([{dir, MnesiaDir}]), - [{mnesia_dir, MnesiaDir}|Config]; -init_per_testcase(cache_test, Config) when is_list(Config) -> +init_per_suite(Config0) when is_list(Config0) -> + + ?DBG("init_per_suite -> entry with" + "~n Config0: ~p", [Config0]), + + Config1 = snmp_test_lib:init_suite_top_dir(?MODULE, Config0), + + ?DBG("init_per_suite -> done when" + "~n Config1: ~p", [Config1]), + + Config1. + +end_per_suite(Config) when is_list(Config) -> + + ?DBG("end_per_suite -> entry with" + "~n Config: ~p", [Config]), + + Config. + + +init_per_testcase(Case, Config0) when is_list(Config0) -> + Config1 = snmp_test_lib:fix_data_dir(Config0), + CaseTopDir = snmp_test_lib:init_testcase_top_dir(Case, Config1), + DbDir = join(CaseTopDir, "db_dir/"), + ?line ok = file:make_dir(DbDir), + init_per_testcase2(Case, [{db_dir, DbDir}, + {case_top_dir, CaseTopDir} | Config1]). + +init_per_testcase2(size_check_ets2_bad_file1, Config) when is_list(Config) -> + DbDir = ?config(db_dir, Config), + %% Create a ad file + ok = file:write_file(join(DbDir, "snmpa_symbolic_store.db"), + "calvin and hoppes play chess"), + Config; +init_per_testcase2(size_check_ets3_bad_file1, Config) when is_list(Config) -> + DbDir = ?config(db_dir, Config), + %% Create a ad file + ok = file:write_file(join(DbDir, "snmpa_symbolic_store.db"), + "calvin and hoppes play chess"), + Config; +init_per_testcase2(size_check_mnesia, Config) when is_list(Config) -> + DbDir = ?config(db_dir, Config), + mnesia_start([{dir, DbDir}]), + Config; +init_per_testcase2(cache_test, Config) when is_list(Config) -> Min = timer:minutes(5), Timeout = case lists:keysearch(tc_timeout, 1, Config) of @@ -119,25 +145,26 @@ init_per_testcase(cache_test, Config) when is_list(Config) -> end, Dog = test_server:timetrap(Timeout), [{watchdog, Dog} | Config]; -init_per_testcase(_Case, Config) when is_list(Config) -> +init_per_testcase2(_Case, Config) when is_list(Config) -> Config. -end_per_testcase(EtsCase, Config) - when (is_list(Config) andalso - ((EtsCase =:= size_check_ets2) orelse - (EtsCase =:= size_check_ets3))) -> - Dir = ?config(ets_dir, Config), - ?line ok = ?DEL_DIR(Dir), - lists:keydelete(ets_dir, 1, Config); -end_per_testcase(size_check_dets, Config) when is_list(Config) -> - Dir = ?config(dets_dir, Config), - ?line ok = ?DEL_DIR(Dir), - lists:keydelete(dets_dir, 1, Config); +%% end_per_testcase(EtsCase, Config) +%% when (is_list(Config) andalso +%% ((EtsCase =:= size_check_ets2) orelse +%% (EtsCase =:= size_check_ets3))) -> +%% Dir = ?config(ets_dir, Config), +%% ?line ok = ?DEL_DIR(Dir), +%% lists:keydelete(ets_dir, 1, Config); +%% end_per_testcase(size_check_dets, Config) when is_list(Config) -> +%% Dir = ?config(dets_dir, Config), +%% ?line ok = ?DEL_DIR(Dir), +%% lists:keydelete(dets_dir, 1, Config); end_per_testcase(size_check_mnesia, Config) when is_list(Config) -> mnesia_stop(), - Dir = ?config(mnesia_dir, Config), - ?line ok = ?DEL_DIR(Dir), - lists:keydelete(mnesia_dir, 1, Config); + %% Dir = ?config(db_dir, Config), + %% ?line ok = ?DEL_DIR(Dir), + %% lists:keydelete(mnesia_dir, 1, Config); + Config; end_per_testcase(cache_test, Config) when is_list(Config) -> Dog = ?config(watchdog, Config), test_server:timetrap_cancel(Dog), @@ -151,23 +178,28 @@ end_per_testcase(_Case, Config) when is_list(Config) -> %%====================================================================== all() -> -cases(). + cases(). groups() -> [{size_check, [], [ - size_check_ets1, % Plain ets - size_check_ets2, % ets with a file - size_check_ets3, % ets with a checksummed file - size_check_dets, % Plain dets - size_check_mnesia % Plain mnesia + size_check_ets1, % Plain ets + size_check_ets2, % ets with a file + size_check_ets2_bad_file1, % ets with a bad file + size_check_ets3, % ets with a checksummed file + size_check_ets3_bad_file1, % ets with bad file (checksummed) + size_check_dets, % Plain dets + size_check_mnesia % Plain mnesia ] }]. -init_per_group(_GroupName, Config) -> - Config. + +init_per_group(GroupName, Config) -> + snmp_test_lib:init_group_top_dir(GroupName, Config). end_per_group(_GroupName, Config) -> + %% Do we really need to do this? + %% lists:keydelete(snmp_group_top_dir, 1, Config). Config. @@ -181,17 +213,6 @@ cases() -> cache_test ]. -init_per_suite(Config) when is_list(Config) -> - %% Data dir points wrong - DataDir0 = ?config(data_dir, Config), - DataDir1 = filename:split(filename:absname(DataDir0)), - [_|DataDir2] = lists:reverse(DataDir1), - DataDir = filename:join(lists:reverse(DataDir2) ++ [?snmp_test_data]), - [{snmp_data_dir, DataDir ++ "/"}|Config]. - -end_per_suite(Config) when is_list(Config) -> - lists:keydelete(snmp_data_dir, 1, Config). - %%====================================================================== %% Test functions @@ -219,7 +240,7 @@ load_unload(suite) -> []; load_unload(Config) when is_list(Config) -> Prio = normal, Verbosity = log, - MibDir = ?config(snmp_data_dir, Config), + MibDir = ?config(data_dir, Config), ?DBG("load_unload -> start symbolic store", []), ?line sym_start(Prio, Verbosity), @@ -273,42 +294,65 @@ size_check_ets1(Config) when is_list(Config) -> size_check_ets2(suite) -> []; size_check_ets2(Config) when is_list(Config) -> - Dir = ?config(ets_dir, Config), - MibStorage = [{module, snmpa_mib_storage_ets}, + Dir = ?config(db_dir, Config), + MibStorage = [{module, snmpa_mib_storage_ets}, {options, [{dir, Dir}]}], do_size_check([{mib_storage, MibStorage}|Config]). +size_check_ets2_bad_file1(suite) -> + []; +size_check_ets2_bad_file1(Config) when is_list(Config) -> + Dir = ?config(db_dir, Config), + %% Ensure that the bad file does not cause any problems (action = clear) + MibStorage = [{module, snmpa_mib_storage_ets}, + {options, [{dir, Dir}, + {action, clear}]}], + do_size_check([{mib_storage, MibStorage}|Config]). + size_check_ets3(suite) -> []; size_check_ets3(Config) when is_list(Config) -> - Dir = ?config(ets_dir, Config), - MibStorage = [{module, snmpa_mib_storage_ets}, - {options, [{dir, Dir}, {checksum, true}]}], + Dir = ?config(db_dir, Config), + MibStorage = [{module, snmpa_mib_storage_ets}, + {options, [{dir, Dir}, + {checksum, true}]}], + do_size_check([{mib_storage, MibStorage}|Config]). + +size_check_ets3_bad_file1(suite) -> + []; +size_check_ets3_bad_file1(Config) when is_list(Config) -> + Dir = ?config(db_dir, Config), + %% Ensure that the bad file does not cause any problems (action = clear) + MibStorage = [{module, snmpa_mib_storage_ets}, + {options, [{dir, Dir}, + {action, clear}, + {checksum, true}]}], do_size_check([{mib_storage, MibStorage}|Config]). size_check_dets(suite) -> []; size_check_dets(Config) when is_list(Config) -> - Dir = ?config(dets_dir, Config), - MibStorage = [{module, snmpa_mib_storage_dets}, + Dir = ?config(db_dir, Config), + MibStorage = [{module, snmpa_mib_storage_dets}, {options, [{dir, Dir}]}], do_size_check([{mib_storage, MibStorage}|Config]). size_check_mnesia(suite) -> []; size_check_mnesia(Config) when is_list(Config) -> - MibStorage = [{module, snmpa_mib_storage_mnesia}, + MibStorage = [{module, snmpa_mib_storage_mnesia}, {options, [{nodes, [node()]}]}], do_size_check([{mib_storage, MibStorage}|Config]). do_size_check(Config) -> - ?DBG("do_size_check -> start", []), + ?DBG("do_size_check -> start with" + "~n Config: ~p", [Config]), Prio = normal, Verbosity = trace, MibStorage = ?config(mib_storage, Config), ?DBG("do_size_check -> MibStorage: ~p", [MibStorage]), - MibDir = ?config(snmp_data_dir, Config), + MibDir = ?config(data_dir, Config), StdMibDir = filename:join(code:priv_dir(snmp), "mibs") ++ "/", ?DBG("do_size_check -> start symbolic store", []), @@ -358,7 +402,7 @@ me_lookup(suite) -> []; me_lookup(Config) when is_list(Config) -> Prio = normal, Verbosity = trace, - MibDir = ?config(snmp_data_dir, Config), + MibDir = ?config(data_dir, Config), StdMibDir = filename:join(code:priv_dir(snmp), "mibs") ++ "/", Mibs = ["Test2", "TestTrap", "TestTrapv2"], StdMibs = ["OTP-SNMPEA-MIB", @@ -411,7 +455,7 @@ which_mib(suite) -> []; which_mib(Config) when is_list(Config) -> Prio = normal, Verbosity = trace, - MibDir = ?config(snmp_data_dir, Config), + MibDir = ?config(data_dir, Config), StdMibDir = filename:join(code:priv_dir(snmp), "mibs") ++ "/", Mibs = ["Test2", "TestTrap", "TestTrapv2"], StdMibs = ["OTP-SNMPEA-MIB", @@ -469,7 +513,7 @@ cache_test(Config) when is_list(Config) -> Prio = normal, Verbosity = trace, MibStorage = [{module, snmpa_mib_storage_ets}], - MibDir = ?config(snmp_data_dir, Config), + MibDir = ?config(data_dir, Config), StdMibDir = filename:join(code:priv_dir(snmp), "mibs") ++ "/", Mibs = ["Test2", "TestTrap", "TestTrapv2"], StdMibs = ["OTP-SNMPEA-MIB", -- cgit v1.2.3 From 0b2501e1a98c7cfe87813b542d8ac7a876c85072 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 28 May 2013 12:31:05 +0200 Subject: [snmp/agent] Updated deprecated attribute --- lib/snmp/src/agent/snmpa.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmpa.erl b/lib/snmp/src/agent/snmpa.erl index a22f1b2eb4..0ce1f611b2 100644 --- a/lib/snmp/src/agent/snmpa.erl +++ b/lib/snmp/src/agent/snmpa.erl @@ -115,7 +115,7 @@ me/0 ]). --deprecated([{old_info_format, 1}]). +-deprecated([{old_info_format, 1, next_major_release}]). -include("snmpa_atl.hrl"). -- cgit v1.2.3