diff options
author | Alexandru Scvortov <alexandru@rabbitmq.com> | 2011-09-22 12:08:33 +0100 |
---|---|---|
committer | Alexandru Scvortov <alexandru@rabbitmq.com> | 2011-09-22 12:08:33 +0100 |
commit | 7a91b6262b2616a2a394b2395ceb66e4ebf8121e (patch) | |
tree | 258ffcce7240d1c30e357367555d8399434f36a1 | |
parent | 5a682e5fd6752a596df837d4443893e1b92e0fc3 (diff) | |
parent | f203e2fa14812e82166d6cab72909135a26036fb (diff) | |
download | rabbitmq-server-bug24332.tar.gz |
merge default into bug24332bug24332
-rw-r--r-- | src/file_handle_cache.erl | 114 | ||||
-rw-r--r-- | src/rabbit_binding.erl | 2 | ||||
-rw-r--r-- | src/rabbit_error_logger_file_h.erl | 6 | ||||
-rw-r--r-- | src/rabbit_file.erl | 287 | ||||
-rw-r--r-- | src/rabbit_guid.erl | 4 | ||||
-rw-r--r-- | src/rabbit_misc.erl | 165 | ||||
-rw-r--r-- | src/rabbit_mnesia.erl | 12 | ||||
-rw-r--r-- | src/rabbit_msg_store.erl | 8 | ||||
-rw-r--r-- | src/rabbit_prelaunch.erl | 4 | ||||
-rw-r--r-- | src/rabbit_queue_index.erl | 34 | ||||
-rw-r--r-- | src/rabbit_sasl_report_file_h.erl | 6 | ||||
-rw-r--r-- | src/rabbit_tests.erl | 6 | ||||
-rw-r--r-- | src/rabbit_upgrade.erl | 4 | ||||
-rw-r--r-- | src/rabbit_version.erl | 4 |
14 files changed, 402 insertions, 254 deletions
diff --git a/src/file_handle_cache.erl b/src/file_handle_cache.erl index e14dfe22..6c3f1b5f 100644 --- a/src/file_handle_cache.erl +++ b/src/file_handle_cache.erl @@ -120,37 +120,39 @@ %% do not need to worry about their handles being closed by the server %% - reopening them when necessary is handled transparently. %% -%% The server also supports obtain and transfer. obtain/0 blocks until -%% a file descriptor is available, at which point the requesting -%% process is considered to 'own' one more descriptor. transfer/1 -%% transfers ownership of a file descriptor between processes. It is -%% non-blocking. Obtain is used to obtain permission to accept file -%% descriptors. Obtain has a lower limit, set by the ?OBTAIN_LIMIT/1 -%% macro. File handles can use the entire limit, but will be evicted -%% by obtain calls up to the point at which no more obtain calls can -%% be satisfied by the obtains limit. Thus there will always be some -%% capacity available for file handles. Processes that use obtain are -%% never asked to return them, and they are not managed in any way by -%% the server. It is simply a mechanism to ensure that processes that -%% need file descriptors such as sockets can do so in such a way that -%% the overall number of open file descriptors is managed. +%% The server also supports obtain, release and transfer. obtain/0 +%% blocks until a file descriptor is available, at which point the +%% requesting process is considered to 'own' one more +%% descriptor. release/0 is the inverse operation and releases a +%% previously obtained descriptor. transfer/1 transfers ownership of a +%% file descriptor between processes. It is non-blocking. Obtain is +%% used to obtain permission to accept file descriptors. Obtain has a +%% lower limit, set by the ?OBTAIN_LIMIT/1 macro. File handles can use +%% the entire limit, but will be evicted by obtain calls up to the +%% point at which no more obtain calls can be satisfied by the obtains +%% limit. Thus there will always be some capacity available for file +%% handles. Processes that use obtain are never asked to return them, +%% and they are not managed in any way by the server. It is simply a +%% mechanism to ensure that processes that need file descriptors such +%% as sockets can do so in such a way that the overall number of open +%% file descriptors is managed. %% %% The callers of register_callback/3, obtain/0, and the argument of %% transfer/1 are monitored, reducing the count of handles in use %% appropriately when the processes terminate. --behaviour(gen_server). +-behaviour(gen_server2). -export([register_callback/3]). -export([open/3, close/1, read/2, append/2, sync/1, position/2, truncate/1, current_virtual_offset/1, current_raw_offset/1, flush/1, copy/3, set_maximum_since_use/1, delete/1, clear/1]). --export([obtain/0, transfer/1, set_limit/1, get_limit/0, info_keys/0, info/0, - info/1]). +-export([obtain/0, release/0, transfer/1, set_limit/1, get_limit/0, info_keys/0, + info/0, info/1]). -export([ulimit/0]). -export([start_link/0, init/1, handle_call/3, handle_cast/2, handle_info/2, - terminate/2, code_change/3]). + terminate/2, code_change/3, prioritise_cast/2]). -define(SERVER, ?MODULE). -define(RESERVED_FOR_OTHERS, 100). @@ -248,6 +250,7 @@ -spec(clear/1 :: (ref()) -> ok_or_error()). -spec(set_maximum_since_use/1 :: (non_neg_integer()) -> 'ok'). -spec(obtain/0 :: () -> 'ok'). +-spec(release/0 :: () -> 'ok'). -spec(transfer/1 :: (pid()) -> 'ok'). -spec(set_limit/1 :: (non_neg_integer()) -> 'ok'). -spec(get_limit/0 :: () -> non_neg_integer()). @@ -266,11 +269,11 @@ %%---------------------------------------------------------------------------- start_link() -> - gen_server:start_link({local, ?SERVER}, ?MODULE, [], [{timeout, infinity}]). + gen_server2:start_link({local, ?SERVER}, ?MODULE, [], [{timeout, infinity}]). register_callback(M, F, A) when is_atom(M) andalso is_atom(F) andalso is_list(A) -> - gen_server:cast(?SERVER, {register_callback, self(), {M, F, A}}). + gen_server2:cast(?SERVER, {register_callback, self(), {M, F, A}}). open(Path, Mode, Options) -> Path1 = filename:absname(Path), @@ -318,7 +321,7 @@ read(Ref, Count) -> fun ([#handle { is_read = false }]) -> {error, not_open_for_reading}; ([Handle = #handle { hdl = Hdl, offset = Offset }]) -> - case file:read(Hdl, Count) of + case prim_file:read(Hdl, Count) of {ok, Data} = Obj -> Offset1 = Offset + iolist_size(Data), {Obj, [Handle #handle { offset = Offset1 }]}; @@ -338,7 +341,7 @@ append(Ref, Data) -> write_buffer_size_limit = 0, at_eof = true } = Handle1} -> Offset1 = Offset + iolist_size(Data), - {file:write(Hdl, Data), + {prim_file:write(Hdl, Data), [Handle1 #handle { is_dirty = true, offset = Offset1 }]}; {{ok, _Offset}, #handle { write_buffer = WriteBuffer, write_buffer_size = Size, @@ -365,7 +368,7 @@ sync(Ref) -> ok; ([Handle = #handle { hdl = Hdl, is_dirty = true, write_buffer = [] }]) -> - case file:sync(Hdl) of + case prim_file:sync(Hdl) of ok -> {ok, [Handle #handle { is_dirty = false }]}; Error -> {Error, [Handle]} end @@ -382,7 +385,7 @@ truncate(Ref) -> with_flushed_handles( [Ref], fun ([Handle1 = #handle { hdl = Hdl }]) -> - case file:truncate(Hdl) of + case prim_file:truncate(Hdl) of ok -> {ok, [Handle1 #handle { at_eof = true }]}; Error -> {Error, [Handle1]} end @@ -409,7 +412,7 @@ copy(Src, Dest, Count) -> fun ([SHandle = #handle { is_read = true, hdl = SHdl, offset = SOffset }, DHandle = #handle { is_write = true, hdl = DHdl, offset = DOffset }] ) -> - case file:copy(SHdl, DHdl, Count) of + case prim_file:copy(SHdl, DHdl, Count) of {ok, Count1} = Result1 -> {Result1, [SHandle #handle { offset = SOffset + Count1 }, @@ -429,7 +432,7 @@ delete(Ref) -> Handle = #handle { path = Path } -> case hard_close(Handle #handle { is_dirty = false, write_buffer = [] }) of - ok -> file:delete(Path); + ok -> prim_file:delete(Path); {Error, Handle1} -> put_handle(Ref, Handle1), Error end @@ -444,7 +447,7 @@ clear(Ref) -> case maybe_seek(bof, Handle #handle { write_buffer = [], write_buffer_size = 0 }) of {{ok, 0}, Handle1 = #handle { hdl = Hdl }} -> - case file:truncate(Hdl) of + case prim_file:truncate(Hdl) of ok -> {ok, [Handle1 #handle { at_eof = true }]}; Error -> {Error, [Handle1]} end; @@ -471,21 +474,28 @@ set_maximum_since_use(MaximumAge) -> end. obtain() -> - gen_server:call(?SERVER, {obtain, self()}, infinity). + %% If the FHC isn't running, obtains succeed immediately. + case whereis(?SERVER) of + undefined -> ok; + _ -> gen_server2:call(?SERVER, {obtain, self()}, infinity) + end. + +release() -> + gen_server2:cast(?SERVER, {release, self()}). transfer(Pid) -> - gen_server:cast(?SERVER, {transfer, self(), Pid}). + gen_server2:cast(?SERVER, {transfer, self(), Pid}). set_limit(Limit) -> - gen_server:call(?SERVER, {set_limit, Limit}, infinity). + gen_server2:call(?SERVER, {set_limit, Limit}, infinity). get_limit() -> - gen_server:call(?SERVER, get_limit, infinity). + gen_server2:call(?SERVER, get_limit, infinity). info_keys() -> ?INFO_KEYS. info() -> info(?INFO_KEYS). -info(Items) -> gen_server:call(?SERVER, {info, Items}, infinity). +info(Items) -> gen_server2:call(?SERVER, {info, Items}, infinity). %%---------------------------------------------------------------------------- %% Internal functions @@ -539,8 +549,8 @@ get_or_reopen(RefNewOrReopens) -> {ok, [Handle || {_Ref, Handle} <- OpenHdls]}; {OpenHdls, ClosedHdls} -> Oldest = oldest(get_age_tree(), fun () -> now() end), - case gen_server:call(?SERVER, {open, self(), length(ClosedHdls), - Oldest}, infinity) of + case gen_server2:call(?SERVER, {open, self(), length(ClosedHdls), + Oldest}, infinity) of ok -> case reopen(ClosedHdls) of {ok, RefHdls} -> sort_handles(RefNewOrReopens, @@ -567,10 +577,10 @@ reopen([{Ref, NewOrReopen, Handle = #handle { hdl = closed, offset = Offset, last_used_at = undefined }} | RefNewOrReopenHdls] = ToOpen, Tree, RefHdls) -> - case file:open(Path, case NewOrReopen of - new -> Mode; - reopen -> [read | Mode] - end) of + case prim_file:open(Path, case NewOrReopen of + new -> Mode; + reopen -> [read | Mode] + end) of {ok, Hdl} -> Now = now(), {{ok, _Offset}, Handle1} = @@ -583,7 +593,7 @@ reopen([{Ref, NewOrReopen, Handle = #handle { hdl = closed, Error -> %% NB: none of the handles in ToOpen are in the age tree Oldest = oldest(Tree, fun () -> undefined end), - [gen_server:cast(?SERVER, {close, self(), Oldest}) || _ <- ToOpen], + [gen_server2:cast(?SERVER, {close, self(), Oldest}) || _ <- ToOpen], put_age_tree(Tree), Error end. @@ -632,7 +642,7 @@ age_tree_delete(Then) -> fun (Tree) -> Tree1 = gb_trees:delete_any(Then, Tree), Oldest = oldest(Tree1, fun () -> undefined end), - gen_server:cast(?SERVER, {close, self(), Oldest}), + gen_server2:cast(?SERVER, {close, self(), Oldest}), Tree1 end). @@ -642,7 +652,7 @@ age_tree_change() -> case gb_trees:is_empty(Tree) of true -> Tree; false -> {Oldest, _Ref} = gb_trees:smallest(Tree), - gen_server:cast(?SERVER, {update, self(), Oldest}) + gen_server2:cast(?SERVER, {update, self(), Oldest}) end, Tree end). @@ -694,10 +704,10 @@ soft_close(Handle) -> is_dirty = IsDirty, last_used_at = Then } = Handle1 } -> ok = case IsDirty of - true -> file:sync(Hdl); + true -> prim_file:sync(Hdl); false -> ok end, - ok = file:close(Hdl), + ok = prim_file:close(Hdl), age_tree_delete(Then), {ok, Handle1 #handle { hdl = closed, is_dirty = false, @@ -732,7 +742,7 @@ maybe_seek(NewOffset, Handle = #handle { hdl = Hdl, offset = Offset, at_eof = AtEoF }) -> {AtEoF1, NeedsSeek} = needs_seek(AtEoF, Offset, NewOffset), case (case NeedsSeek of - true -> file:position(Hdl, NewOffset); + true -> prim_file:position(Hdl, NewOffset); false -> {ok, Offset} end) of {ok, Offset1} = Result -> @@ -769,7 +779,7 @@ write_buffer(Handle = #handle { hdl = Hdl, offset = Offset, write_buffer = WriteBuffer, write_buffer_size = DataSize, at_eof = true }) -> - case file:write(Hdl, lists:reverse(WriteBuffer)) of + case prim_file:write(Hdl, lists:reverse(WriteBuffer)) of ok -> Offset1 = Offset + DataSize, {ok, Handle #handle { offset = Offset1, is_dirty = true, @@ -785,7 +795,7 @@ i(obtain_limit, #fhc_state{obtain_limit = Limit}) -> Limit; i(Item, _) -> throw({bad_argument, Item}). %%---------------------------------------------------------------------------- -%% gen_server callbacks +%% gen_server2 callbacks %%---------------------------------------------------------------------------- init([]) -> @@ -814,6 +824,12 @@ init([]) -> clients = Clients, timer_ref = undefined }}. +prioritise_cast(Msg, _State) -> + case Msg of + {release, _} -> 5; + _ -> 0 + end. + handle_call({open, Pid, Requested, EldestUnusedSince}, From, State = #fhc_state { open_count = Count, open_pending = Pending, @@ -893,6 +909,10 @@ handle_cast({update, Pid, EldestUnusedSince}, %% storm of messages {noreply, State}; +handle_cast({release, Pid}, State) -> + {noreply, adjust_alarm(State, process_pending( + update_counts(obtain, Pid, -1, State)))}; + handle_cast({close, Pid, EldestUnusedSince}, State = #fhc_state { elders = Elders, clients = Clients }) -> true = case EldestUnusedSince of @@ -1048,7 +1068,7 @@ run_pending_item(#pending { kind = Kind, requested = Requested, from = From }, State = #fhc_state { clients = Clients }) -> - gen_server:reply(From, ok), + gen_server2:reply(From, ok), true = ets:update_element(Clients, Pid, {#cstate.blocked, false}), update_counts(Kind, Pid, Requested, State). diff --git a/src/rabbit_binding.erl b/src/rabbit_binding.erl index 43c26941..e625a427 100644 --- a/src/rabbit_binding.erl +++ b/src/rabbit_binding.erl @@ -40,7 +40,7 @@ 'source_and_destination_not_found')). -type(bind_ok_or_error() :: 'ok' | bind_errors() | rabbit_types:error('binding_not_found')). --type(bind_res() :: bind_ok_or_error() | rabbit_misc:const(bind_ok_or_error())). +-type(bind_res() :: bind_ok_or_error() | rabbit_misc:thunk(bind_ok_or_error())). -type(inner_fun() :: fun((rabbit_types:exchange(), rabbit_types:exchange() | rabbit_types:amqqueue()) -> diff --git a/src/rabbit_error_logger_file_h.erl b/src/rabbit_error_logger_file_h.erl index f481c21e..7b6e07c1 100644 --- a/src/rabbit_error_logger_file_h.erl +++ b/src/rabbit_error_logger_file_h.erl @@ -33,7 +33,7 @@ %% Used only when swapping handlers in log rotation init({{File, Suffix}, []}) -> - case rabbit_misc:append_file(File, Suffix) of + case rabbit_file:append_file(File, Suffix) of ok -> file:delete(File), ok; {error, Error} -> @@ -54,10 +54,10 @@ init({File, []}) -> init({{File, []}, _}) -> init(File); init({File, {error_logger, Buf}}) -> - rabbit_misc:ensure_parent_dirs_exist(File), + rabbit_file:ensure_parent_dirs_exist(File), init_file(File, {error_logger, Buf}); init(File) -> - rabbit_misc:ensure_parent_dirs_exist(File), + rabbit_file:ensure_parent_dirs_exist(File), init_file(File, []). init_file(File, {error_logger, Buf}) -> diff --git a/src/rabbit_file.erl b/src/rabbit_file.erl new file mode 100644 index 00000000..7b3a3e75 --- /dev/null +++ b/src/rabbit_file.erl @@ -0,0 +1,287 @@ +%% The contents of this file are subject to the Mozilla Public License +%% Version 1.1 (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.mozilla.org/MPL/ +%% +%% 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. +%% +%% The Original Code is RabbitMQ. +%% +%% The Initial Developer of the Original Code is VMware, Inc. +%% Copyright (c) 2011 VMware, Inc. All rights reserved. +%% + +-module(rabbit_file). + +-include_lib("kernel/include/file.hrl"). + +-export([is_file/1, is_dir/1, file_size/1, ensure_dir/1, wildcard/2, list_dir/1]). +-export([read_term_file/1, write_term_file/2, write_file/2, write_file/3]). +-export([append_file/2, ensure_parent_dirs_exist/1]). +-export([rename/2, delete/1, recursive_delete/1, recursive_copy/2]). +-export([lock_file/1]). + +%%---------------------------------------------------------------------------- + +-ifdef(use_specs). + +-type(ok_or_error() :: rabbit_types:ok_or_error(any())). + +-spec(is_file/1 :: ((file:filename())) -> boolean()). +-spec(is_dir/1 :: ((file:filename())) -> boolean()). +-spec(file_size/1 :: ((file:filename())) -> non_neg_integer()). +-spec(ensure_dir/1 :: ((file:filename())) -> ok_or_error()). +-spec(wildcard/2 :: (string(), file:filename()) -> [file:filename()]). +-spec(list_dir/1 :: (file:filename()) -> rabbit_types:ok_or_error2( + [file:filename()], any())). +-spec(read_term_file/1 :: + (file:filename()) -> {'ok', [any()]} | rabbit_types:error(any())). +-spec(write_term_file/2 :: (file:filename(), [any()]) -> ok_or_error()). +-spec(write_file/2 :: (file:filename(), iodata()) -> ok_or_error()). +-spec(write_file/3 :: (file:filename(), iodata(), [any()]) -> ok_or_error()). +-spec(append_file/2 :: (file:filename(), string()) -> ok_or_error()). +-spec(ensure_parent_dirs_exist/1 :: (string()) -> 'ok'). +-spec(rename/2 :: + (file:filename(), file:filename()) -> ok_or_error()). +-spec(delete/1 :: ([file:filename()]) -> ok_or_error()). +-spec(recursive_delete/1 :: + ([file:filename()]) + -> rabbit_types:ok_or_error({file:filename(), any()})). +-spec(recursive_copy/2 :: + (file:filename(), file:filename()) + -> rabbit_types:ok_or_error({file:filename(), file:filename(), any()})). +-spec(lock_file/1 :: (file:filename()) -> rabbit_types:ok_or_error('eexist')). + +-endif. + +%%---------------------------------------------------------------------------- + +is_file(File) -> + case read_file_info(File) of + {ok, #file_info{type=regular}} -> true; + {ok, #file_info{type=directory}} -> true; + _ -> false + end. + +is_dir(Dir) -> is_dir_internal(read_file_info(Dir)). + +is_dir_no_handle(Dir) -> is_dir_internal(prim_file:read_file_info(Dir)). + +is_dir_internal({ok, #file_info{type=directory}}) -> true; +is_dir_internal(_) -> false. + +file_size(File) -> + case read_file_info(File) of + {ok, #file_info{size=Size}} -> Size; + _ -> 0 + end. + +ensure_dir(File) -> with_fhc_handle(fun () -> ensure_dir_internal(File) end). + +ensure_dir_internal("/") -> + ok; +ensure_dir_internal(File) -> + Dir = filename:dirname(File), + case is_dir_no_handle(Dir) of + true -> ok; + false -> ensure_dir_internal(Dir), + prim_file:make_dir(Dir) + end. + +wildcard(Pattern, Dir) -> + {ok, Files} = list_dir(Dir), + {ok, RE} = re:compile(Pattern, [anchored]), + [File || File <- Files, match =:= re:run(File, RE, [{capture, none}])]. + +list_dir(Dir) -> with_fhc_handle(fun () -> prim_file:list_dir(Dir) end). + +read_file_info(File) -> + with_fhc_handle(fun () -> prim_file:read_file_info(File) end). + +with_fhc_handle(Fun) -> + ok = file_handle_cache:obtain(), + try Fun() + after ok = file_handle_cache:release() + end. + +read_term_file(File) -> + try + {ok, Data} = with_fhc_handle(fun () -> prim_file:read_file(File) end), + {ok, Tokens, _} = erl_scan:string(binary_to_list(Data)), + TokenGroups = group_tokens(Tokens), + {ok, [begin + {ok, Term} = erl_parse:parse_term(Tokens1), + Term + end || Tokens1 <- TokenGroups]} + catch + error:{badmatch, Error} -> Error + end. + +group_tokens(Ts) -> lists:reverse([lists:reverse(G) || G <- group_tokens1(Ts)]). + +group_tokens1([]) -> []; +group_tokens1([{_, N, _} | _] = Tokens) -> group_tokens([], N, Tokens); +group_tokens1([{_, N} | _] = Tokens) -> group_tokens([], N, Tokens). + +group_tokens(Cur, _, []) -> [Cur]; +group_tokens(Cur, N, [T = {_, N} | Ts]) -> group_tokens([T | Cur], N, Ts); +group_tokens(Cur, _, [{_, M} | _] = Ts) -> [Cur | group_tokens([], M, Ts)]; +group_tokens(Cur, N, [T = {_, N, _} | Ts]) -> group_tokens([T | Cur], N, Ts); +group_tokens(Cur, _, [{_, M, _} | _] = Ts) -> [Cur | group_tokens([], M, Ts)]. + +write_term_file(File, Terms) -> + write_file(File, list_to_binary([io_lib:format("~w.~n", [Term]) || + Term <- Terms])). + +write_file(Path, Data) -> write_file(Path, Data, []). + +%% write_file/3 and make_binary/1 are both based on corresponding +%% functions in the kernel/file.erl module of the Erlang R14B02 +%% release, which is licensed under the EPL. That implementation of +%% write_file/3 does not do an fsync prior to closing the file, hence +%% the existence of this version. APIs are otherwise identical. +write_file(Path, Data, Modes) -> + Modes1 = [binary, write | (Modes -- [binary, write])], + case make_binary(Data) of + Bin when is_binary(Bin) -> + with_fhc_handle( + fun () -> case prim_file:open(Path, Modes1) of + {ok, Hdl} -> try prim_file:write(Hdl, Bin) of + ok -> prim_file:sync(Hdl); + {error, _} = E -> E + after + prim_file:close(Hdl) + end; + {error, _} = E -> E + end + end); + {error, _} = E -> E + end. + +make_binary(Bin) when is_binary(Bin) -> + Bin; +make_binary(List) -> + try + iolist_to_binary(List) + catch error:Reason -> + {error, Reason} + end. + + +append_file(File, Suffix) -> + case read_file_info(File) of + {ok, FInfo} -> append_file(File, FInfo#file_info.size, Suffix); + {error, enoent} -> append_file(File, 0, Suffix); + Error -> Error + end. + +append_file(_, _, "") -> + ok; +append_file(File, 0, Suffix) -> + with_fhc_handle(fun () -> + case prim_file:open([File, Suffix], [append]) of + {ok, Fd} -> prim_file:close(Fd); + Error -> Error + end + end); +append_file(File, _, Suffix) -> + case with_fhc_handle(fun () -> prim_file:read_file(File) end) of + {ok, Data} -> write_file([File, Suffix], Data, [append]); + Error -> Error + end. + +ensure_parent_dirs_exist(Filename) -> + case ensure_dir(Filename) of + ok -> ok; + {error, Reason} -> + throw({error, {cannot_create_parent_dirs, Filename, Reason}}) + end. + +rename(Old, New) -> with_fhc_handle(fun () -> prim_file:rename(Old, New) end). + +delete(File) -> with_fhc_handle(fun () -> prim_file:delete(File) end). + +recursive_delete(Files) -> + with_fhc_handle( + fun () -> lists:foldl(fun (Path, ok) -> recursive_delete1(Path); + (_Path, {error, _Err} = Error) -> Error + end, ok, Files) + end). + +recursive_delete1(Path) -> + case is_dir_no_handle(Path) and not(is_symlink_no_handle(Path)) of + false -> case prim_file:delete(Path) of + ok -> ok; + {error, enoent} -> ok; %% Path doesn't exist anyway + {error, Err} -> {error, {Path, Err}} + end; + true -> case prim_file:list_dir(Path) of + {ok, FileNames} -> + case lists:foldl( + fun (FileName, ok) -> + recursive_delete1( + filename:join(Path, FileName)); + (_FileName, Error) -> + Error + end, ok, FileNames) of + ok -> + case prim_file:del_dir(Path) of + ok -> ok; + {error, Err} -> {error, {Path, Err}} + end; + {error, _Err} = Error -> + Error + end; + {error, Err} -> + {error, {Path, Err}} + end + end. + +is_symlink_no_handle(File) -> + case prim_file:read_link(File) of + {ok, _} -> true; + _ -> false + end. + +recursive_copy(Src, Dest) -> + %% Note that this uses the 'file' module and, hence, shouldn't be + %% run on many processes at once. + case is_dir(Src) of + false -> case file:copy(Src, Dest) of + {ok, _Bytes} -> ok; + {error, enoent} -> ok; %% Path doesn't exist anyway + {error, Err} -> {error, {Src, Dest, Err}} + end; + true -> case file:list_dir(Src) of + {ok, FileNames} -> + case file:make_dir(Dest) of + ok -> + lists:foldl( + fun (FileName, ok) -> + recursive_copy( + filename:join(Src, FileName), + filename:join(Dest, FileName)); + (_FileName, Error) -> + Error + end, ok, FileNames); + {error, Err} -> + {error, {Src, Dest, Err}} + end; + {error, Err} -> + {error, {Src, Dest, Err}} + end + end. + +%% TODO: When we stop supporting Erlang prior to R14, this should be +%% replaced with file:open [write, exclusive] +lock_file(Path) -> + case is_file(Path) of + true -> {error, eexist}; + false -> with_fhc_handle( + fun () -> {ok, Lock} = prim_file:open(Path, [write]), + ok = prim_file:close(Lock) + end) + end. diff --git a/src/rabbit_guid.erl b/src/rabbit_guid.erl index 234bc55b..cf3fea1a 100644 --- a/src/rabbit_guid.erl +++ b/src/rabbit_guid.erl @@ -52,13 +52,13 @@ start_link() -> update_disk_serial() -> Filename = filename:join(rabbit_mnesia:dir(), ?SERIAL_FILENAME), - Serial = case rabbit_misc:read_term_file(Filename) of + Serial = case rabbit_file:read_term_file(Filename) of {ok, [Num]} -> Num; {error, enoent} -> 0; {error, Reason} -> throw({error, {cannot_read_serial_file, Filename, Reason}}) end, - case rabbit_misc:write_term_file(Filename, [Serial + 1]) of + case rabbit_file:write_term_file(Filename, [Serial + 1]) of ok -> ok; {error, Reason1} -> throw({error, {cannot_write_serial_file, Filename, Reason1}}) diff --git a/src/rabbit_misc.erl b/src/rabbit_misc.erl index 0b39a209..d47041d6 100644 --- a/src/rabbit_misc.erl +++ b/src/rabbit_misc.erl @@ -18,8 +18,6 @@ -include("rabbit.hrl"). -include("rabbit_framing.hrl"). --include_lib("kernel/include/file.hrl"). - -export([method_record_type/1, polite_pause/0, polite_pause/1]). -export([die/1, frame_error/2, amqp_error/4, protocol_error/3, protocol_error/4, protocol_error/1]). @@ -40,19 +38,16 @@ -export([upmap/2, map_in_order/2]). -export([table_filter/3]). -export([dirty_read_all/1, dirty_foreach_key/2, dirty_dump_log/1]). --export([read_term_file/1, write_term_file/2, write_file/2, write_file/3]). --export([append_file/2, ensure_parent_dirs_exist/1]). -export([format_stderr/2, with_local_io/1]). -export([start_applications/1, stop_applications/1]). -export([unfold/2, ceil/1, queue_fold/3]). -export([sort_field_table/1]). -export([pid_to_string/1, string_to_pid/1]). -export([version_compare/2, version_compare/3]). --export([recursive_delete/1, recursive_copy/2, dict_cons/3, orddict_cons/3]). +-export([dict_cons/3, orddict_cons/3]). -export([get_options/2]). -export([all_module_attributes/1, build_acyclic_graph/3]). -export([now_ms/0]). --export([lock_file/1]). -export([const_ok/0, const/1]). -export([ntoa/1, ntoab/1]). -export([is_process_alive/1]). @@ -158,13 +153,6 @@ -spec(dirty_foreach_key/2 :: (fun ((any()) -> any()), atom()) -> 'ok' | 'aborted'). -spec(dirty_dump_log/1 :: (file:filename()) -> ok_or_error()). --spec(read_term_file/1 :: - (file:filename()) -> {'ok', [any()]} | rabbit_types:error(any())). --spec(write_term_file/2 :: (file:filename(), [any()]) -> ok_or_error()). --spec(write_file/2 :: (file:filename(), iodata()) -> ok_or_error()). --spec(write_file/3 :: (file:filename(), iodata(), [any()]) -> ok_or_error()). --spec(append_file/2 :: (file:filename(), string()) -> ok_or_error()). --spec(ensure_parent_dirs_exist/1 :: (string()) -> 'ok'). -spec(format_stderr/2 :: (string(), [any()]) -> 'ok'). -spec(with_local_io/1 :: (fun (() -> A)) -> A). -spec(start_applications/1 :: ([atom()]) -> 'ok'). @@ -180,12 +168,6 @@ -spec(version_compare/3 :: (string(), string(), ('lt' | 'lte' | 'eq' | 'gte' | 'gt')) -> boolean()). --spec(recursive_delete/1 :: - ([file:filename()]) - -> rabbit_types:ok_or_error({file:filename(), any()})). --spec(recursive_copy/2 :: - (file:filename(), file:filename()) - -> rabbit_types:ok_or_error({file:filename(), file:filename(), any()})). -spec(dict_cons/3 :: (any(), any(), dict()) -> dict()). -spec(orddict_cons/3 :: (any(), any(), orddict:orddict()) -> orddict:orddict()). -spec(get_options/2 :: ([optdef()], [string()]) @@ -199,7 +181,6 @@ {bad_edge, [digraph:vertex()]}), digraph:vertex(), digraph:vertex()})). -spec(now_ms/0 :: () -> non_neg_integer()). --spec(lock_file/1 :: (file:filename()) -> rabbit_types:ok_or_error('eexist')). -spec(const_ok/0 :: () -> 'ok'). -spec(const/1 :: (A) -> thunk(A)). -spec(ntoa/1 :: (inet:ip_address()) -> string()). @@ -525,74 +506,6 @@ dirty_dump_log1(LH, {K, Terms, BadBytes}) -> io:format("Bad Chunk, ~p: ~p~n", [BadBytes, Terms]), dirty_dump_log1(LH, disk_log:chunk(LH, K)). - -read_term_file(File) -> file:consult(File). - -write_term_file(File, Terms) -> - write_file(File, list_to_binary([io_lib:format("~w.~n", [Term]) || - Term <- Terms])). - -write_file(Path, Data) -> - write_file(Path, Data, []). - -%% write_file/3 and make_binary/1 are both based on corresponding -%% functions in the kernel/file.erl module of the Erlang R14B02 -%% release, which is licensed under the EPL. That implementation of -%% write_file/3 does not do an fsync prior to closing the file, hence -%% the existence of this version. APIs are otherwise identical. -write_file(Path, Data, Modes) -> - Modes1 = [binary, write | (Modes -- [binary, write])], - case make_binary(Data) of - Bin when is_binary(Bin) -> - case file:open(Path, Modes1) of - {ok, Hdl} -> try file:write(Hdl, Bin) of - ok -> file:sync(Hdl); - {error, _} = E -> E - after - file:close(Hdl) - end; - {error, _} = E -> E - end; - {error, _} = E -> E - end. - -make_binary(Bin) when is_binary(Bin) -> - Bin; -make_binary(List) -> - try - iolist_to_binary(List) - catch error:Reason -> - {error, Reason} - end. - - -append_file(File, Suffix) -> - case file:read_file_info(File) of - {ok, FInfo} -> append_file(File, FInfo#file_info.size, Suffix); - {error, enoent} -> append_file(File, 0, Suffix); - Error -> Error - end. - -append_file(_, _, "") -> - ok; -append_file(File, 0, Suffix) -> - case file:open([File, Suffix], [append]) of - {ok, Fd} -> file:close(Fd); - Error -> Error - end; -append_file(File, _, Suffix) -> - case file:read_file(File) of - {ok, Data} -> write_file([File, Suffix], Data, [append]); - Error -> Error - end. - -ensure_parent_dirs_exist(Filename) -> - case filelib:ensure_dir(Filename) of - ok -> ok; - {error, Reason} -> - throw({error, {cannot_create_parent_dirs, Filename, Reason}}) - end. - format_stderr(Fmt, Args) -> case os:type() of {unix, _} -> @@ -743,73 +656,6 @@ version_compare(A, B) -> dropdot(A) -> lists:dropwhile(fun (X) -> X =:= $. end, A). -recursive_delete(Files) -> - lists:foldl(fun (Path, ok ) -> recursive_delete1(Path); - (_Path, {error, _Err} = Error) -> Error - end, ok, Files). - -recursive_delete1(Path) -> - case filelib:is_dir(Path) and not(is_symlink(Path)) of - false -> case file:delete(Path) of - ok -> ok; - {error, enoent} -> ok; %% Path doesn't exist anyway - {error, Err} -> {error, {Path, Err}} - end; - true -> case file:list_dir(Path) of - {ok, FileNames} -> - case lists:foldl( - fun (FileName, ok) -> - recursive_delete1( - filename:join(Path, FileName)); - (_FileName, Error) -> - Error - end, ok, FileNames) of - ok -> - case file:del_dir(Path) of - ok -> ok; - {error, Err} -> {error, {Path, Err}} - end; - {error, _Err} = Error -> - Error - end; - {error, Err} -> - {error, {Path, Err}} - end - end. - -is_symlink(Name) -> - case file:read_link(Name) of - {ok, _} -> true; - _ -> false - end. - -recursive_copy(Src, Dest) -> - case filelib:is_dir(Src) of - false -> case file:copy(Src, Dest) of - {ok, _Bytes} -> ok; - {error, enoent} -> ok; %% Path doesn't exist anyway - {error, Err} -> {error, {Src, Dest, Err}} - end; - true -> case file:list_dir(Src) of - {ok, FileNames} -> - case file:make_dir(Dest) of - ok -> - lists:foldl( - fun (FileName, ok) -> - recursive_copy( - filename:join(Src, FileName), - filename:join(Dest, FileName)); - (_FileName, Error) -> - Error - end, ok, FileNames); - {error, Err} -> - {error, {Src, Dest, Err}} - end; - {error, Err} -> - {error, {Src, Dest, Err}} - end - end. - dict_cons(Key, Value, Dict) -> dict:update(Key, fun (List) -> [Value | List] end, [Value], Dict). @@ -899,15 +745,6 @@ build_acyclic_graph(VertexFun, EdgeFun, Graph) -> {error, Reason} end. -%% TODO: When we stop supporting Erlang prior to R14, this should be -%% replaced with file:open [write, exclusive] -lock_file(Path) -> - case filelib:is_file(Path) of - true -> {error, eexist}; - false -> {ok, Lock} = file:open(Path, [write]), - ok = file:close(Lock) - end. - const_ok() -> ok. const(X) -> fun () -> X end. diff --git a/src/rabbit_mnesia.erl b/src/rabbit_mnesia.erl index 665b15c5..9348896a 100644 --- a/src/rabbit_mnesia.erl +++ b/src/rabbit_mnesia.erl @@ -434,7 +434,7 @@ cluster_nodes_config_filename() -> create_cluster_nodes_config(ClusterNodes) -> FileName = cluster_nodes_config_filename(), - case rabbit_misc:write_term_file(FileName, [ClusterNodes]) of + case rabbit_file:write_term_file(FileName, [ClusterNodes]) of ok -> ok; {error, Reason} -> throw({error, {cannot_create_cluster_nodes_config, @@ -443,7 +443,7 @@ create_cluster_nodes_config(ClusterNodes) -> read_cluster_nodes_config() -> FileName = cluster_nodes_config_filename(), - case rabbit_misc:read_term_file(FileName) of + case rabbit_file:read_term_file(FileName) of {ok, [ClusterNodes]} -> ClusterNodes; {error, enoent} -> {ok, ClusterNodes} = application:get_env(rabbit, cluster_nodes), @@ -471,12 +471,12 @@ record_running_nodes() -> Nodes = running_clustered_nodes() -- [node()], %% Don't check the result: we're shutting down anyway and this is %% a best-effort-basis. - rabbit_misc:write_term_file(FileName, [Nodes]), + rabbit_file:write_term_file(FileName, [Nodes]), ok. read_previously_running_nodes() -> FileName = running_nodes_filename(), - case rabbit_misc:read_term_file(FileName) of + case rabbit_file:read_term_file(FileName) of {ok, [Nodes]} -> Nodes; {error, enoent} -> []; {error, Reason} -> throw({error, {cannot_read_previous_nodes_file, @@ -638,7 +638,7 @@ move_db() -> copy_db(Destination) -> ok = ensure_mnesia_not_running(), - rabbit_misc:recursive_copy(dir(), Destination). + rabbit_file:recursive_copy(dir(), Destination). create_tables() -> create_tables(disc). @@ -745,7 +745,7 @@ reset(Force) -> end, ok = delete_cluster_nodes_config(), %% remove persisted messages and any other garbage we find - ok = rabbit_misc:recursive_delete(filelib:wildcard(dir() ++ "/*")), + ok = rabbit_file:recursive_delete(filelib:wildcard(dir() ++ "/*")), ok. leave_cluster([], _) -> ok; diff --git a/src/rabbit_msg_store.erl b/src/rabbit_msg_store.erl index cc12eb5d..fc3cbebd 100644 --- a/src/rabbit_msg_store.erl +++ b/src/rabbit_msg_store.erl @@ -589,7 +589,7 @@ init([Server, BaseDir, ClientRefs, StartupFunState]) -> AttemptFileSummaryRecovery = case ClientRefs of - undefined -> ok = rabbit_misc:recursive_delete([Dir]), + undefined -> ok = rabbit_file:recursive_delete([Dir]), ok = filelib:ensure_dir(filename:join(Dir, "nothing")), false; _ -> ok = filelib:ensure_dir(filename:join(Dir, "nothing")), @@ -1340,11 +1340,11 @@ recover_index_and_client_refs(IndexModule, true, ClientRefs, Dir, Server) -> end. store_recovery_terms(Terms, Dir) -> - rabbit_misc:write_term_file(filename:join(Dir, ?CLEAN_FILENAME), Terms). + rabbit_file:write_term_file(filename:join(Dir, ?CLEAN_FILENAME), Terms). read_recovery_terms(Dir) -> Path = filename:join(Dir, ?CLEAN_FILENAME), - case rabbit_misc:read_term_file(Path) of + case rabbit_file:read_term_file(Path) of {ok, Terms} -> case file:delete(Path) of ok -> {true, Terms}; {error, Error} -> {false, Error} @@ -1901,7 +1901,7 @@ transform_dir(BaseDir, Store, TransformFun) -> end. transform_msg_file(FileOld, FileNew, TransformFun) -> - ok = rabbit_misc:ensure_parent_dirs_exist(FileNew), + ok = rabbit_file:ensure_parent_dirs_exist(FileNew), {ok, RefOld} = file_handle_cache:open(FileOld, [raw, binary, read], []), {ok, RefNew} = file_handle_cache:open(FileNew, [raw, binary, write], [{write_buffer, diff --git a/src/rabbit_prelaunch.erl b/src/rabbit_prelaunch.erl index 9fe073d9..cd0c322b 100644 --- a/src/rabbit_prelaunch.erl +++ b/src/rabbit_prelaunch.erl @@ -70,7 +70,7 @@ start() -> AppVersions}, %% Write it out to $RABBITMQ_PLUGINS_EXPAND_DIR/rabbit.rel - rabbit_misc:write_file(RootName ++ ".rel", io_lib:format("~p.~n", [RDesc])), + rabbit_file:write_file(RootName ++ ".rel", io_lib:format("~p.~n", [RDesc])), %% We exclude mochiweb due to its optional use of fdsrv. XRefExclude = [mochiweb], @@ -139,7 +139,7 @@ determine_version(App) -> {App, Vsn}. delete_recursively(Fn) -> - case rabbit_misc:recursive_delete([Fn]) of + case rabbit_file:recursive_delete([Fn]) of ok -> ok; {error, {Path, E}} -> {error, {cannot_delete, Path, E}}; Error -> Error diff --git a/src/rabbit_queue_index.erl b/src/rabbit_queue_index.erl index 636913b5..f1751e95 100644 --- a/src/rabbit_queue_index.erl +++ b/src/rabbit_queue_index.erl @@ -229,7 +229,7 @@ init(Name, OnSyncFun) -> State = #qistate { dir = Dir } = blank_state(Name), - false = filelib:is_file(Dir), %% is_file == is file or dir + false = rabbit_file:is_file(Dir), %% is_file == is file or dir State #qistate { on_sync = OnSyncFun }. shutdown_terms(Name) -> @@ -256,7 +256,7 @@ terminate(Terms, State) -> delete_and_terminate(State) -> {_SegmentCounts, State1 = #qistate { dir = Dir }} = terminate(State), - ok = rabbit_misc:recursive_delete([Dir]), + ok = rabbit_file:recursive_delete([Dir]), State1. publish(MsgId, SeqId, MsgProps, IsPersistent, @@ -359,16 +359,16 @@ recover(DurableQueues) -> {[dict:fetch(QueueDirName, DurableDict) | DurableAcc], TermsAcc1}; false -> - ok = rabbit_misc:recursive_delete([QueueDirPath]), + ok = rabbit_file:recursive_delete([QueueDirPath]), {DurableAcc, TermsAcc} end end, {[], []}, QueueDirNames), {DurableTerms, {fun queue_index_walker/1, {start, DurableQueueNames}}}. all_queue_directory_names(Dir) -> - case file:list_dir(Dir) of + case rabbit_file:list_dir(Dir) of {ok, Entries} -> [ Entry || Entry <- Entries, - filelib:is_dir( + rabbit_file:is_dir( filename:join(Dir, Entry)) ]; {error, enoent} -> [] end. @@ -392,18 +392,18 @@ blank_state(QueueName) -> clean_file_name(Dir) -> filename:join(Dir, ?CLEAN_FILENAME). detect_clean_shutdown(Dir) -> - case file:delete(clean_file_name(Dir)) of + case rabbit_file:delete(clean_file_name(Dir)) of ok -> true; {error, enoent} -> false end. read_shutdown_terms(Dir) -> - rabbit_misc:read_term_file(clean_file_name(Dir)). + rabbit_file:read_term_file(clean_file_name(Dir)). store_clean_shutdown(Terms, Dir) -> CleanFileName = clean_file_name(Dir), - ok = filelib:ensure_dir(CleanFileName), - rabbit_misc:write_term_file(CleanFileName, Terms). + ok = rabbit_file:ensure_dir(CleanFileName), + rabbit_file:write_term_file(CleanFileName, Terms). init_clean(RecoveredCounts, State) -> %% Load the journal. Since this is a clean recovery this (almost) @@ -603,8 +603,8 @@ flush_journal(State = #qistate { segments = Segments }) -> Segments1 = segment_fold( fun (#segment { unacked = 0, path = Path }, SegmentsN) -> - case filelib:is_file(Path) of - true -> ok = file:delete(Path); + case rabbit_file:is_file(Path) of + true -> ok = rabbit_file:delete(Path); false -> ok end, SegmentsN; @@ -630,7 +630,7 @@ append_journal_to_segment(#segment { journal_entries = JEntries, get_journal_handle(State = #qistate { journal_handle = undefined, dir = Dir }) -> Path = filename:join(Dir, ?JOURNAL_FILENAME), - ok = filelib:ensure_dir(Path), + ok = rabbit_file:ensure_dir(Path), {ok, Hdl} = file_handle_cache:open(Path, ?WRITE_MODE, [{write_buffer, infinity}]), {Hdl, State #qistate { journal_handle = Hdl }}; @@ -735,7 +735,7 @@ all_segment_nums(#qistate { dir = Dir, segments = Segments }) -> lists:takewhile(fun (C) -> $0 =< C andalso C =< $9 end, SegName)), Set) end, sets:from_list(segment_nums(Segments)), - filelib:wildcard("*" ++ ?SEGMENT_EXTENSION, Dir)))). + rabbit_file:wildcard(".*\\" ++ ?SEGMENT_EXTENSION, Dir)))). segment_find_or_new(Seg, Dir, Segments) -> case segment_find(Seg, Segments) of @@ -836,7 +836,7 @@ segment_entries_foldr(Fun, Init, %% %% Does not do any combining with the journal at all. load_segment(KeepAcked, #segment { path = Path }) -> - case filelib:is_file(Path) of + case rabbit_file:is_file(Path) of false -> {array_new(), 0}; true -> {ok, Hdl} = file_handle_cache:open(Path, ?READ_AHEAD_MODE, []), {ok, 0} = file_handle_cache:position(Hdl, bof), @@ -1040,12 +1040,12 @@ foreach_queue_index(Funs) -> transform_queue(Dir, Gatherer, {JournalFun, SegmentFun}) -> ok = transform_file(filename:join(Dir, ?JOURNAL_FILENAME), JournalFun), [ok = transform_file(filename:join(Dir, Seg), SegmentFun) - || Seg <- filelib:wildcard("*" ++ ?SEGMENT_EXTENSION, Dir)], + || Seg <- rabbit_file:wildcard(".*\\" ++ ?SEGMENT_EXTENSION, Dir)], ok = gatherer:finish(Gatherer). transform_file(Path, Fun) -> PathTmp = Path ++ ".upgrade", - case filelib:file_size(Path) of + case rabbit_file:file_size(Path) of 0 -> ok; Size -> {ok, PathTmpHdl} = file_handle_cache:open(PathTmp, ?WRITE_MODE, @@ -1059,7 +1059,7 @@ transform_file(Path, Fun) -> ok = drive_transform_fun(Fun, PathTmpHdl, Content), ok = file_handle_cache:close(PathTmpHdl), - ok = file:rename(PathTmp, Path) + ok = rabbit_file:rename(PathTmp, Path) end. drive_transform_fun(Fun, Hdl, Contents) -> diff --git a/src/rabbit_sasl_report_file_h.erl b/src/rabbit_sasl_report_file_h.erl index cdd3287f..963294d9 100644 --- a/src/rabbit_sasl_report_file_h.erl +++ b/src/rabbit_sasl_report_file_h.erl @@ -34,7 +34,7 @@ %% Used only when swapping handlers and performing %% log rotation init({{File, Suffix}, []}) -> - case rabbit_misc:append_file(File, Suffix) of + case rabbit_file:append_file(File, Suffix) of ok -> file:delete(File), ok; {error, Error} -> @@ -52,10 +52,10 @@ init({{File, _}, error}) -> init({File, []}) -> init(File); init({File, _Type} = FileInfo) -> - rabbit_misc:ensure_parent_dirs_exist(File), + rabbit_file:ensure_parent_dirs_exist(File), init_file(FileInfo); init(File) -> - rabbit_misc:ensure_parent_dirs_exist(File), + rabbit_file:ensure_parent_dirs_exist(File), init_file({File, sasl_error_logger_type()}). init_file({File, Type}) -> diff --git a/src/rabbit_tests.erl b/src/rabbit_tests.erl index 3b129fbe..ba67730e 100644 --- a/src/rabbit_tests.erl +++ b/src/rabbit_tests.erl @@ -1753,7 +1753,11 @@ test_file_handle_cache() -> [filename:join(TmpDir, Str) || Str <- ["file1", "file2", "file3", "file4"]], Content = <<"foo">>, CopyFun = fun (Src, Dst) -> - ok = rabbit_misc:write_file(Src, Content), + {ok, Hdl} = prim_file:open(Src, [binary, write]), + ok = prim_file:write(Hdl, Content), + ok = prim_file:sync(Hdl), + prim_file:close(Hdl), + {ok, SrcHdl} = file_handle_cache:open(Src, [read], []), {ok, DstHdl} = file_handle_cache:open(Dst, [write], []), Size = size(Content), diff --git a/src/rabbit_upgrade.erl b/src/rabbit_upgrade.erl index e7a302f8..717d94a8 100644 --- a/src/rabbit_upgrade.erl +++ b/src/rabbit_upgrade.erl @@ -115,7 +115,7 @@ ensure_backup_removed() -> end. remove_backup() -> - ok = rabbit_misc:recursive_delete([backup_dir()]), + ok = rabbit_file:recursive_delete([backup_dir()]), info("upgrades: Mnesia backup removed~n", []). maybe_upgrade_mnesia() -> @@ -249,7 +249,7 @@ maybe_upgrade_local() -> %% ------------------------------------------------------------------- apply_upgrades(Scope, Upgrades, Fun) -> - ok = rabbit_misc:lock_file(lock_filename()), + ok = rabbit_file:lock_file(lock_filename()), info("~s upgrades: ~w to apply~n", [Scope, length(Upgrades)]), rabbit_misc:ensure_ok(mnesia:start(), cannot_start_mnesia), Fun(), diff --git a/src/rabbit_version.erl b/src/rabbit_version.erl index 400abc10..f6bcbb7f 100644 --- a/src/rabbit_version.erl +++ b/src/rabbit_version.erl @@ -49,12 +49,12 @@ %% ------------------------------------------------------------------- -recorded() -> case rabbit_misc:read_term_file(schema_filename()) of +recorded() -> case rabbit_file:read_term_file(schema_filename()) of {ok, [V]} -> {ok, V}; {error, _} = Err -> Err end. -record(V) -> ok = rabbit_misc:write_term_file(schema_filename(), [V]). +record(V) -> ok = rabbit_file:write_term_file(schema_filename(), [V]). recorded_for_scope(Scope) -> case recorded() of |