aboutsummaryrefslogtreecommitdiffstats
path: root/lib/cosTransactions/src/etrap_logmgr.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/cosTransactions/src/etrap_logmgr.erl')
-rw-r--r--lib/cosTransactions/src/etrap_logmgr.erl200
1 files changed, 200 insertions, 0 deletions
diff --git a/lib/cosTransactions/src/etrap_logmgr.erl b/lib/cosTransactions/src/etrap_logmgr.erl
new file mode 100644
index 0000000000..a418d782e3
--- /dev/null
+++ b/lib/cosTransactions/src/etrap_logmgr.erl
@@ -0,0 +1,200 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%----------------------------------------------------------------------
+%% File : etrap_logmgr.erl
+%% Purpose : Make it easier to use disk_log.
+%%----------------------------------------------------------------------
+
+-module(etrap_logmgr).
+
+%%--------------- INCLUDES -----------------------------------
+%% Local
+-include_lib("ETraP_Common.hrl").
+%%--------------- IMPORTS-------------------------------------
+%%--------------- EXPORTS-------------------------------------
+-export([start/1, stop/1, log_safe/2, log_lazy/2, get_next/2]).
+
+
+%%------------------------------------------------------------
+%% function : start
+%% Arguments: LogName - name of the disk_log.
+%% Returns :
+%% Effect : creating linked log
+%%------------------------------------------------------------
+
+start(LogName) ->
+ case catch disk_log:open([{name, LogName},
+ {file, LogName},
+ {type, halt},
+ {size, infinity}]) of
+ {ok, LogName} ->
+ ok;
+ {error, Reason} ->
+ ?tr_error_msg("Initiating internal log failed: ~p", [Reason]),
+ exit({error, Reason});
+ {repaired, LogName, {recovered, _Rec}, {badbytes, _Bad}} ->
+ ok;
+ Other ->
+ ?tr_error_msg("Initiating internal log failed: ~p", [Other]),
+ exit({error, Other})
+ end.
+
+%%------------------------------------------------------------
+%% function : stop
+%% Arguments: LogName - name of the disk_log.
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+
+stop(LogName) ->
+ case catch disk_log:close(LogName) of
+ ok ->
+ ok;
+ {error, Reason} ->
+ ?tr_error_msg("Stopping internal log failed: ~p", [Reason]),
+ {error, Reason};
+ Other ->
+ ?tr_error_msg("Stopping internal log failed: ~p", [Other]),
+ {error, Other}
+ end.
+
+
+%%------------------------------------------------------------
+%% function : log_safe
+%% Arguments: LogName - name of the disk_log. If 'dummy' is
+%% used nothing should be logged. Reason, reuse code.
+%% LogRecord - record to store in the log.
+%% Returns :
+%% Effect : Writes a logrecord and synchronizes to make sure
+%% that the record is stored.
+%%------------------------------------------------------------
+
+log_safe(dummy, _) ->
+ ok;
+log_safe(LogName, LogRecord) ->
+ case write_safe(LogName, LogRecord) of
+ ok ->
+ ok;
+ _ ->
+ %% We have to catch the exit because in some cases
+ %% it's not possible to abort action in the 2PC-protocol.
+ case catch start(LogName) of
+ ok ->
+ write_safe(LogName, LogRecord);
+ {'EXIT', Reason} ->
+ {error, Reason}
+ end
+ end.
+
+
+write_safe(LogName, LogRecord) ->
+ case catch disk_log:log(LogName, LogRecord) of
+ ok -> % wrote to kernel successfully
+ case catch disk_log:sync(LogName) of
+ ok -> % Written to disk successfully
+ ok;
+ {error, Reason} ->
+ ?tr_error_msg("Internal log write failed: ~p ~p",
+ [Reason, LogName]),
+ {error, Reason};
+ Other ->
+ ?tr_error_msg("Internal log write failed: ~p ~p",
+ [Other, LogName]),
+ {error, Other}
+ end;
+ {error, Reason} ->
+ ?tr_error_msg("Internal log write failed: ~p ~p", [Reason, LogName]),
+ {error, Reason};
+ Other ->
+ ?tr_error_msg("Internal log write failed: ~p ~p", [Other, LogName]),
+ {error, Other}
+ end.
+
+
+%%------------------------------------------------------------
+%% function : log_lazy
+%% Arguments: LogName - name of the disk_log. If 'dummy' is
+%% used nothing should be logged. Reason, reuse code.
+%% LogRecord - record to store in the log.
+%% Returns :
+%% Effect : Writes a logrecord. The record may be lost.
+%%------------------------------------------------------------
+
+log_lazy(dummy, _LogRecord) ->
+ ok;
+log_lazy(LogName, LogRecord) ->
+ case write_lazy(LogName, LogRecord) of
+ ok ->
+ ok;
+ _ ->
+ %% We have to catch the exit because in some cases
+ %% it's not possible to abort action in the 2PC-protocol.
+ case catch start(LogName) of
+ ok ->
+ write_lazy(LogName, LogRecord);
+ {'EXIT', Reason} ->
+ {error, Reason}
+ end
+ end.
+
+write_lazy(LogName, LogRecord) ->
+ case catch disk_log:log(LogName, LogRecord) of
+ ok ->
+ %% wrote to kernel successfully
+ ok;
+ {error, Reason} ->
+ %% Write to kernel failed with Reason
+ ?tr_error_msg("Internal log write failed: ~p", [Reason]),
+ {error, Reason};
+ Other ->
+ %% unknown message received.
+ ?tr_error_msg("Internal log write failed: ~p", [Other]),
+ {error, Other}
+ end.
+
+
+%%------------------------------------------------------------
+%% function : get_next
+%% Arguments: LogName - name of the disk_log.
+%% Cursor - place to read from.
+%% Returns : {Cursor, LogRecs} - A cursor and up to N logrecords.
+%% eof - the atom 'eof', indicating logfile empty.
+%% {error, Reason} - error.
+%% Effect :
+%% Purpose : Used when performing a REDO scan
+%%------------------------------------------------------------
+
+get_next(LogName, Cursor) ->
+ case catch disk_log:chunk(LogName, Cursor, 1) of
+ {NewCursor, [Data]} ->
+ {Data, NewCursor};
+ eof ->
+ eof;
+ {error, Reason} ->
+ ?tr_error_msg("Internal log '~p' read failed: ~p",
+ [LogName, Reason]),
+ exit({error, Reason});
+ _Other ->
+ ?tr_error_msg("Internal log '~p' read failed: 'log_corrupt'", [LogName]),
+ exit({error, "log_corrupt"})
+ end.
+
+%%--------------- END OF MODULE ------------------------------