aboutsummaryrefslogtreecommitdiffstats
path: root/lib/snmp/src/agent/snmpa_vacm.erl
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2012-01-10 14:52:00 +0100
committerMicael Karlberg <[email protected]>2012-01-12 12:13:18 +0100
commit411f6240932aab3721ff842c674d9610216cfd88 (patch)
tree348e767c70bae544a5b30d96aaf1bd7159f7f578 /lib/snmp/src/agent/snmpa_vacm.erl
parentdaf5b0eeb6f0d8c805f7a0e2fc117c8c788b855c (diff)
downloadotp-411f6240932aab3721ff842c674d9610216cfd88.tar.gz
otp-411f6240932aab3721ff842c674d9610216cfd88.tar.bz2
otp-411f6240932aab3721ff842c674d9610216cfd88.zip
[snmp/agent] Synchronization feature added
OTP-9851
Diffstat (limited to 'lib/snmp/src/agent/snmpa_vacm.erl')
-rw-r--r--lib/snmp/src/agent/snmpa_vacm.erl77
1 files changed, 46 insertions, 31 deletions
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.
%% </SUGGESTION>
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