From daf5b0eeb6f0d8c805f7a0e2fc117c8c788b855c Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Mon, 9 Jan 2012 17:50:47 +0100 Subject: [snmp/agent] Creating a unique temporary file whe dumping vacm Attempting to create a unique temporary file when dumping the vacm table to disk. OTP-9851 --- lib/snmp/src/agent/snmpa_vacm.erl | 43 ++++++++++++++++++++++++++++++++++++++- lib/snmp/vsn.mk | 4 ++-- 2 files changed, 44 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/snmp/src/agent/snmpa_vacm.erl b/lib/snmp/src/agent/snmpa_vacm.erl index 892dc265f1..c31b8e61a3 100644 --- a/lib/snmp/src/agent/snmpa_vacm.erl +++ b/lib/snmp/src/agent/snmpa_vacm.erl @@ -266,9 +266,24 @@ dump_table(true) -> dump_table(_) -> ok. + +%% We should really make an effort to serialize the dumping +%% to ensure that several processes that dump at-the-same-time +%% do not trash each others dumps. +%% +%% Send the request to the master agent, which, if there is no +%% dumper already running, spawns a (temporary) dumper process. +%% 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, +%% 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. +%% dump_table() -> [{_, FName}] = ets:lookup(snmp_agent_table, snmpa_vacm_file), - TmpName = FName ++ ".tmp", + TmpName = unique(FName), case ets:tab2file(snmpa_vacm, TmpName) of ok -> case file:rename(TmpName, FName) of @@ -283,6 +298,32 @@ dump_table() -> [FName, Reason]) end. +%% 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) -> + 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). + +unique_pid() -> + case string:tokens(pid_to_list(self()), [$<,$.,$>]) of + [A, B, C] -> + A ++ B ++ C ++ "."; + _ -> + "" + end. + %%----------------------------------------------------------------- %% Alg. diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk index 43f67a744e..dafdcefe79 100644 --- a/lib/snmp/vsn.mk +++ b/lib/snmp/vsn.mk @@ -2,7 +2,7 @@ # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2011. All Rights Reserved. +# Copyright Ericsson AB 1997-2012. 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 @@ -18,6 +18,6 @@ # %CopyrightEnd% APPLICATION = snmp -SNMP_VSN = 4.21.3 +SNMP_VSN = 4.21.5 PRE_VSN = APP_VSN = "$(APPLICATION)-$(SNMP_VSN)$(PRE_VSN)" -- cgit v1.2.3