From 411f6240932aab3721ff842c674d9610216cfd88 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 10 Jan 2012 14:52:00 +0100 Subject: [snmp/agent] Synchronization feature added OTP-9851 --- lib/snmp/src/agent/snmpa_vacm.erl | 77 +++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 31 deletions(-) (limited to 'lib/snmp/src/agent/snmpa_vacm.erl') diff --git a/lib/snmp/src/agent/snmpa_vacm.erl b/lib/snmp/src/agent/snmpa_vacm.erl index c31b8e61a3..efe6378105 100644 --- a/lib/snmp/src/agent/snmpa_vacm.erl +++ b/lib/snmp/src/agent/snmpa_vacm.erl @@ -276,45 +276,60 @@ dump_table(_) -> %% If there is already a running dumper process, instead increment %% the dump_request counter. %% When the dumper process exits, the master agent checks the -%% the dump_request counter, and if that is greated than zero, +%% the dump_request counter, and if that is greater than zero, %% create another dumper process and resets the counter. -%% In this way the dumping is serializede, but the master-agent -%% process is not burdened by the dumping. +%% In this way the dumping is serialized, but the master-agent +%% process is not burdend by the dumping. %% dump_table() -> - [{_, FName}] = ets:lookup(snmp_agent_table, snmpa_vacm_file), - TmpName = unique(FName), - case ets:tab2file(snmpa_vacm, TmpName) of - ok -> - case file:rename(TmpName, FName) of - ok -> - ok; - Else -> % What is this? Undocumented return code... - user_err("Warning: could not move VACM db ~p" - " (~p)", [FName, Else]) - end; - {error, Reason} -> - user_err("Warning: could not save vacm db ~p (~p)", - [FName, Reason]) - end. + %% The dumper fun is executed in a specially started process, + %% that does that one thing and then exits. + %% Also, to prevent the system to run "wild" (keep calling + %% dump function before they are done), the agents serialize + %% function return when that dump is done! + Dumper = + fun() -> + [{_, FName}] = ets:lookup(snmp_agent_table, snmpa_vacm_file), + %% TmpName = FName ++ ".tmp", + TmpName = unique_name(FName), + case ets:tab2file(snmpa_vacm, TmpName) of + ok -> + case file:rename(TmpName, FName) of + ok -> + ok; + Else -> % What is this? Undocumented return code... + user_err("Warning: could not move VACM db ~p" + " (~p)", [FName, Else]) + end; + {error, Reason} -> + user_err("Warning: could not save vacm db ~p (~p)", + [FName, Reason]) + end + end, + snmpa_agent:serialize(snmpa_vacm_dump_request, Dumper). + %% This little thing is an attempt to create a "unique" filename %% in order to minimize the risk of two processes at the same %% time dumping the table. -unique(Pre) -> - {A, B, C} = os:timestamp(), - {D, _} = erlang:statistics(reductions), - {E, _} = erlang:statistics(runtime), - {F, _} = erlang:statistics(wall_clock), - {G, H, _} = erlang:statistics(garbage_collection), - Data = [A, B, C, D, E, F, G, H], - unique(Pre, Data, 0). - -unique(Pre, [], Unique) -> +%% The serialization handled by the agent does this much better, +%% but this also gives us a "timestamp" which could be usefull for +%% debugging reasons. +unique_name(Pre) -> + unique_name(Pre, os:timestamp()). + +unique_name(Pre, {_A, _B, C} = Timestamp) -> + {Date, Time} = calendar:now_to_datetime(Timestamp), + {YYYY, MM, DD} = Date, + {Hour, Min, Sec} = Time, + FormatDate = + io_lib:format("~.4w~.2.0w~.2.0w_~.2.0w~.2.0w~.2.0w_~w", + [YYYY, MM, DD, Hour, Min, Sec, round(C/1000)]), + unique_name2(Pre, FormatDate). + +unique_name2(Pre, FormatedDate) -> PidPart = unique_pid(), - lists:flatten(io_lib:format("~s.~s~w.tmp", [Pre, PidPart, Unique])); -unique(Pre, [H|T], Unique) -> - unique(Pre, T, Unique bxor H). + lists:flatten(io_lib:format("~s.~s~s.tmp", [Pre, PidPart, FormatedDate])). unique_pid() -> case string:tokens(pid_to_list(self()), [$<,$.,$>]) of -- cgit v1.2.3