summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Bakken <luke@bakken.io>2021-12-18 12:14:01 -0800
committermergify-bot <noreply@mergify.com>2021-12-21 14:53:33 +0000
commit6166d2756e81862252c04e87f88a16da44bbc6fc (patch)
tree809ac8fe33945436e28f56832f0fee364cffe85a
parentd68ff5f0d0bae5a80581984cde975d3729f8e5e4 (diff)
downloadrabbitmq-server-git-6166d2756e81862252c04e87f88a16da44bbc6fc.tar.gz
Restore old win32 free disk query using `dir` as a last resort
(cherry picked from commit a023908642a47a7b0b6cafe7a2764df3febf63c7) (cherry picked from commit 4bf1dcc7f8909fdccf1ef726956d5a500576bd9b)
-rw-r--r--deps/rabbit/src/rabbit_disk_monitor.erl34
1 files changed, 33 insertions, 1 deletions
diff --git a/deps/rabbit/src/rabbit_disk_monitor.erl b/deps/rabbit/src/rabbit_disk_monitor.erl
index 059e1fb68f..faafce7508 100644
--- a/deps/rabbit/src/rabbit_disk_monitor.erl
+++ b/deps/rabbit/src/rabbit_disk_monitor.erl
@@ -236,7 +236,11 @@ get_disk_free(Dir, {win32, _}) ->
case win32_get_drive_letter(Dir) of
error ->
rabbit_log:warning("Mnesia directory is not in the expected format (C:): '~p'", [Dir]),
- exit(could_not_determine_disk_free);
+ case win32_get_disk_free_dir(Dir) of
+ {ok, Free} ->
+ Free;
+ _ -> exit(could_not_determine_disk_free)
+ end;
DriveLetter ->
case win32_get_disk_free_fsutil(DriveLetter) of
{ok, Free0} -> Free0;
@@ -302,6 +306,34 @@ win32_get_disk_free_pwsh(DriveLetter) when
{ok, list_to_integer(PoshResult)}
end.
+win32_get_disk_free_dir(Dir) ->
+ %% On Windows, the Win32 API enforces a limit of 260 characters
+ %% (MAX_PATH). If we call `dir` with a path longer than that, it
+ %% fails with "File not found". Starting with Windows 10 version
+ %% 1607, this limit was removed, but the administrator has to
+ %% configure that.
+ %%
+ %% NTFS supports paths up to 32767 characters. Therefore, paths
+ %% longer than 260 characters exist but they are "inaccessible" to
+ %% `dir`.
+ %%
+ %% A workaround is to tell the Win32 API to not parse a path and
+ %% just pass it raw to the underlying filesystem. To do this, the
+ %% path must be prepended with "\\?\". That's what we do here.
+ %%
+ %% However, the underlying filesystem may not support forward
+ %% slashes transparently, as the Win32 API does. Therefore, we
+ %% convert all forward slashes to backslashes.
+ %%
+ %% See the following page to learn more about this:
+ %% https://ss64.com/nt/syntax-filenames.html
+ RawDir = "\\\\?\\" ++ string:replace(Dir, "/", "\\", all),
+ CommandResult = run_cmd("dir /-C /W \"" ++ RawDir ++ "\""),
+ LastLine = lists:last(string:tokens(CommandResult, "\r\n")),
+ {match, [Free]} = re:run(lists:reverse(LastLine), "(\\d+)",
+ [{capture, all_but_first, list}]),
+ {ok, list_to_integer(lists:reverse(Free))}.
+
interpret_limit({mem_relative, Relative})
when is_number(Relative) ->
round(Relative * vm_memory_monitor:get_total_memory());