aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/src/disk_log.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel/src/disk_log.erl')
-rw-r--r--lib/kernel/src/disk_log.erl168
1 files changed, 78 insertions, 90 deletions
diff --git a/lib/kernel/src/disk_log.erl b/lib/kernel/src/disk_log.erl
index 5b1efcd395..9b44021872 100644
--- a/lib/kernel/src/disk_log.erl
+++ b/lib/kernel/src/disk_log.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. 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.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -44,6 +45,8 @@
%% To be used for debugging only:
-export([pid2name/1]).
+-export_type([continuation/0]).
+
-type dlog_state_error() :: 'ok' | {'error', term()}.
-record(state, {queue = [],
@@ -1074,13 +1077,13 @@ log_end(S, [], [], Sync) ->
log_end(S, Pids, Bins, Sync) ->
case do_log(get(log), rflat(Bins)) of
N when is_integer(N) ->
- replies(Pids, ok),
+ ok = replies(Pids, ok),
S1 = (state_ok(S))#state{cnt = S#state.cnt+N},
log_end_sync(S1, Sync);
{error, {error, {full, _Name}}, N} when Pids =:= [] ->
log_end_sync(state_ok(S#state{cnt = S#state.cnt + N}), Sync);
{error, Error, N} ->
- replies(Pids, Error),
+ ok = replies(Pids, Error),
state_err(S#state{cnt = S#state.cnt + N}, Error)
end.
@@ -1089,7 +1092,7 @@ log_end_sync(S, []) ->
S;
log_end_sync(S, Sync) ->
Res = do_sync(get(log)),
- replies(Sync, Res),
+ ok = replies(Sync, Res),
state_err(S, Res).
%% Inlined.
@@ -1181,7 +1184,7 @@ do_exit(S, From, Message0, Reason) ->
_ -> Message0
end,
_ = disk_log_server:close(self()),
- replies(From, Message),
+ ok = replies(From, Message),
?PROFILE(ep:done()),
exit(Reason).
@@ -1307,13 +1310,20 @@ compare_arg(_Attr, _Val, _A) ->
%% -> {ok, Res, log(), Cnt} | Error
do_open(A) ->
- L = #log{name = A#arg.name,
- filename = A#arg.file,
- size = A#arg.size,
- head = mk_head(A#arg.head, A#arg.format),
- mode = A#arg.mode,
- version = A#arg.version},
- do_open2(L, A).
+ #arg{type = Type, format = Format, name = Name, head = Head0,
+ file = FName, repair = Repair, size = Size, mode = Mode,
+ version = V} = A,
+ Head = mk_head(Head0, Format),
+ case do_open2(Type, Format, Name, FName, Repair, Size, Mode, Head, V) of
+ {ok, Ret, Extra, FormatType, NoItems} ->
+ L = #log{name = Name, type = Type, format = Format,
+ filename = FName, size = Size,
+ format_type = FormatType, head = Head, mode = Mode,
+ version = V, extra = Extra},
+ {ok, Ret, L, NoItems};
+ Error ->
+ Error
+ end.
mk_head({head, Term}, internal) -> {ok, term_to_binary(Term)};
mk_head({head, Bytes}, external) -> {ok, check_bytes(Bytes)};
@@ -1429,57 +1439,44 @@ do_inc_wrap_file(L) ->
%%-----------------------------------------------------------------
%% -> {ok, Reply, log(), Cnt} | Error
%% Note: the header is always written, even if the log size is too small.
-do_open2(L, #arg{type = halt, format = internal, name = Name,
- file = FName, repair = Repair, size = Size, mode = Mode}) ->
- case catch disk_log_1:int_open(FName, Repair, Mode, L#log.head) of
+do_open2(halt, internal, Name, FName, Repair, Size, Mode, Head, _V) ->
+ case catch disk_log_1:int_open(FName, Repair, Mode, Head) of
{ok, {_Alloc, FdC, {NoItems, _NoBytes}, FileSize}} ->
Halt = #halt{fdc = FdC, curB = FileSize, size = Size},
- {ok, {ok, Name}, L#log{format_type = halt_int, extra = Halt},
- NoItems};
+ {ok, {ok, Name}, Halt, halt_int, NoItems};
{repaired, FdC, Rec, Bad, FileSize} ->
Halt = #halt{fdc = FdC, curB = FileSize, size = Size},
{ok, {repaired, Name, {recovered, Rec}, {badbytes, Bad}},
- L#log{format_type = halt_int, extra = Halt},
- Rec};
+ Halt, halt_int, Rec};
Error ->
Error
end;
-do_open2(L, #arg{type = wrap, format = internal, size = {MaxB, MaxF},
- name = Name, repair = Repair, file = FName, mode = Mode,
- version = V}) ->
+do_open2(wrap, internal, Name, FName, Repair, Size, Mode, Head, V) ->
+ {MaxB, MaxF} = Size,
case catch
- disk_log_1:mf_int_open(FName, MaxB, MaxF, Repair, Mode, L#log.head, V) of
+ disk_log_1:mf_int_open(FName, MaxB, MaxF, Repair, Mode, Head, V) of
{ok, Handle, Cnt} ->
- {ok, {ok, Name}, L#log{type = wrap,
- format_type = wrap_int,
- extra = Handle}, Cnt};
+ {ok, {ok, Name}, Handle, wrap_int, Cnt};
{repaired, Handle, Rec, Bad, Cnt} ->
{ok, {repaired, Name, {recovered, Rec}, {badbytes, Bad}},
- L#log{type = wrap, format_type = wrap_int, extra = Handle}, Cnt};
+ Handle, wrap_int, Cnt};
Error ->
Error
end;
-do_open2(L, #arg{type = halt, format = external, file = FName, name = Name,
- size = Size, repair = Repair, mode = Mode}) ->
- case catch disk_log_1:ext_open(FName, Repair, Mode, L#log.head) of
+do_open2(halt, external, Name, FName, Repair, Size, Mode, Head, _V) ->
+ case catch disk_log_1:ext_open(FName, Repair, Mode, Head) of
{ok, {_Alloc, FdC, {NoItems, _NoBytes}, FileSize}} ->
Halt = #halt{fdc = FdC, curB = FileSize, size = Size},
- {ok, {ok, Name},
- L#log{format_type = halt_ext, format = external, extra = Halt},
- NoItems};
+ {ok, {ok, Name}, Halt, halt_ext, NoItems};
Error ->
Error
end;
-do_open2(L, #arg{type = wrap, format = external, size = {MaxB, MaxF},
- name = Name, file = FName, repair = Repair, mode = Mode,
- version = V}) ->
+do_open2(wrap, external, Name, FName, Repair, Size, Mode, Head, V) ->
+ {MaxB, MaxF} = Size,
case catch
- disk_log_1:mf_ext_open(FName, MaxB, MaxF, Repair, Mode, L#log.head, V) of
+ disk_log_1:mf_ext_open(FName, MaxB, MaxF, Repair, Mode, Head, V) of
{ok, Handle, Cnt} ->
- {ok, {ok, Name}, L#log{type = wrap,
- format_type = wrap_ext,
- extra = Handle,
- format = external}, Cnt};
+ {ok, {ok, Name}, Handle, wrap_ext, Cnt};
Error ->
Error
end.
@@ -1525,48 +1522,48 @@ do_format_error({size_mismatch, OldSize, ArgSize}) ->
io_lib:format("The given size ~p does not match the size ~p found on "
"the disk log size file~n", [ArgSize, OldSize]);
do_format_error({read_only_mode, Log}) ->
- io_lib:format("The disk log ~p has been opened read-only, but the "
+ io_lib:format("The disk log ~tp has been opened read-only, but the "
"requested operation needs read-write access~n", [Log]);
do_format_error({format_external, Log}) ->
io_lib:format("The requested operation can only be applied on internally "
- "formatted disk logs, but ~p is externally formatted~n",
+ "formatted disk logs, but ~tp is externally formatted~n",
[Log]);
do_format_error({blocked_log, Log}) ->
- io_lib:format("The blocked disk log ~p does not queue requests, or "
+ io_lib:format("The blocked disk log ~tp does not queue requests, or "
"the log has been blocked by the calling process~n", [Log]);
do_format_error({full, Log}) ->
- io_lib:format("The halt log ~p is full~n", [Log]);
+ io_lib:format("The halt log ~tp is full~n", [Log]);
do_format_error({not_blocked, Log}) ->
- io_lib:format("The disk log ~p is not blocked~n", [Log]);
+ io_lib:format("The disk log ~tp is not blocked~n", [Log]);
do_format_error({not_owner, Pid}) ->
- io_lib:format("The pid ~p is not an owner of the disk log~n", [Pid]);
+ io_lib:format("The pid ~tp is not an owner of the disk log~n", [Pid]);
do_format_error({not_blocked_by_pid, Log}) ->
- io_lib:format("The disk log ~p is blocked, but only the blocking pid "
+ io_lib:format("The disk log ~tp is blocked, but only the blocking pid "
"can unblock a disk log~n", [Log]);
do_format_error({new_size_too_small, Log, CurrentSize}) ->
- io_lib:format("The current size ~p of the halt log ~p is greater than the "
+ io_lib:format("The current size ~p of the halt log ~tp is greater than the "
"requested new size~n", [CurrentSize, Log]);
do_format_error({halt_log, Log}) ->
- io_lib:format("The halt log ~p cannot be wrapped~n", [Log]);
+ io_lib:format("The halt log ~tp cannot be wrapped~n", [Log]);
do_format_error({same_file_name, Log}) ->
- io_lib:format("Current and new file name of the disk log ~p "
+ io_lib:format("Current and new file name of the disk log ~tp "
"are the same~n", [Log]);
do_format_error({arg_mismatch, Option, FirstValue, ArgValue}) ->
- io_lib:format("The value ~p of the disk log option ~p does not match "
- "the current value ~p~n", [ArgValue, Option, FirstValue]);
+ io_lib:format("The value ~tp of the disk log option ~p does not match "
+ "the current value ~tp~n", [ArgValue, Option, FirstValue]);
do_format_error({name_already_open, Log}) ->
- io_lib:format("The disk log ~p has already opened another file~n", [Log]);
+ io_lib:format("The disk log ~tp has already opened another file~n", [Log]);
do_format_error({node_already_open, Log}) ->
- io_lib:format("The distribution option of the disk log ~p does not match "
+ io_lib:format("The distribution option of the disk log ~tp does not match "
"already open log~n", [Log]);
do_format_error({open_read_write, Log}) ->
- io_lib:format("The disk log ~p has already been opened read-write~n",
+ io_lib:format("The disk log ~tp has already been opened read-write~n",
[Log]);
do_format_error({open_read_only, Log}) ->
- io_lib:format("The disk log ~p has already been opened read-only~n",
+ io_lib:format("The disk log ~tp has already been opened read-only~n",
[Log]);
do_format_error({not_internal_wrap, Log}) ->
- io_lib:format("The requested operation cannot be applied since ~p is not "
+ io_lib:format("The requested operation cannot be applied since ~tp is not "
"an internally formatted disk log~n", [Log]);
do_format_error(no_such_log) ->
io_lib:format("There is no disk log with the given name~n", []);
@@ -1577,13 +1574,13 @@ do_format_error(nodedown) ->
io_lib:format("There seems to be no node up that can handle "
"the request~n", []);
do_format_error({corrupt_log_file, FileName}) ->
- io_lib:format("The disk log file \"~s\" contains corrupt data~n",
+ io_lib:format("The disk log file \"~ts\" contains corrupt data~n",
[FileName]);
do_format_error({need_repair, FileName}) ->
- io_lib:format("The disk log file \"~s\" has not been closed properly and "
+ io_lib:format("The disk log file \"~ts\" has not been closed properly and "
"needs repair~n", [FileName]);
do_format_error({not_a_log_file, FileName}) ->
- io_lib:format("The file \"~s\" is not a wrap log file~n", [FileName]);
+ io_lib:format("The file \"~ts\" is not a wrap log file~n", [FileName]);
do_format_error({invalid_header, InvalidHeader}) ->
io_lib:format("The disk log header is not wellformed: ~p~n",
[InvalidHeader]);
@@ -1591,14 +1588,14 @@ do_format_error(end_of_log) ->
io_lib:format("An attempt was made to step outside a not yet "
"full wrap log~n", []);
do_format_error({invalid_index_file, FileName}) ->
- io_lib:format("The wrap log index file \"~s\" cannot be used~n",
+ io_lib:format("The wrap log index file \"~ts\" cannot be used~n",
[FileName]);
do_format_error({no_continuation, BadCont}) ->
io_lib:format("The term ~p is not a chunk continuation~n", [BadCont]);
do_format_error({file_error, FileName, Reason}) ->
- io_lib:format("\"~s\": ~p~n", [FileName, file:format_error(Reason)]);
+ io_lib:format("\"~ts\": ~tp~n", [FileName, file:format_error(Reason)]);
do_format_error(E) ->
- io_lib:format("~p~n", [E]).
+ io_lib:format("~tp~n", [E]).
do_info(L, Cnt) ->
#log{name = Name, type = Type, mode = Mode, filename = File,
@@ -1879,7 +1876,8 @@ replies(Pids, Reply) ->
send_reply(Pids, M).
send_reply(Pid, M) when is_pid(Pid) ->
- Pid ! M;
+ Pid ! M,
+ ok;
send_reply([Pid | Pids], M) ->
Pid ! M,
send_reply(Pids, M);
@@ -1912,13 +1910,8 @@ multi_req(Msg, Pids) ->
{'DOWN', Ref, process, Pid, _Info} ->
Reply;
{disk_log, Pid, _Reply} ->
- erlang:demonitor(Ref),
- receive
- {'DOWN', Ref, process, Pid, _Reason} ->
- ok
- after 0 ->
- ok
- end
+ erlang:demonitor(Ref, [flush]),
+ ok
end
end, {error, nonode}, Refs).
@@ -1963,13 +1956,8 @@ monitor_request(Pid, Req) ->
{error, no_such_log};
{disk_log, Pid, Reply} when not is_tuple(Reply) orelse
element(2, Reply) =/= disk_log_stopped ->
- erlang:demonitor(Ref),
- receive
- {'DOWN', Ref, process, Pid, _Reason} ->
- Reply
- after 0 ->
- Reply
- end
+ erlang:demonitor(Ref, [flush]),
+ Reply
end.
req2(Pid, R) ->
@@ -2030,7 +2018,7 @@ notify_owners(Note) ->
cache_error(S, Pids) ->
Error = S#state.cache_error,
- replies(Pids, Error),
+ ok = replies(Pids, Error),
state_err(S#state{cache_error = ok}, Error).
state_ok(S) ->