summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Bakken <luke@bakken.io>2021-12-18 12:14:01 -0800
committerLuke Bakken <luke@bakken.io>2021-12-20 08:41:03 -0800
commita023908642a47a7b0b6cafe7a2764df3febf63c7 (patch)
treebb8636fa921de38ece0a20d059b993553ef1319a
parentfad573cd93d0e539c76cf9e8e4a57d0a76033013 (diff)
downloadrabbitmq-server-git-a023908642a47a7b0b6cafe7a2764df3febf63c7.tar.gz
Restore old win32 free disk query using `dir` as a last resort
-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 53b8712d6a..24040280f1 100644
--- a/deps/rabbit/src/rabbit_disk_monitor.erl
+++ b/deps/rabbit/src/rabbit_disk_monitor.erl
@@ -237,7 +237,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;
@@ -303,6 +307,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());