diff options
| author | Luke Bakken <luke@bakken.io> | 2021-12-18 12:14:01 -0800 |
|---|---|---|
| committer | Luke Bakken <luke@bakken.io> | 2021-12-20 08:41:03 -0800 |
| commit | a023908642a47a7b0b6cafe7a2764df3febf63c7 (patch) | |
| tree | bb8636fa921de38ece0a20d059b993553ef1319a | |
| parent | fad573cd93d0e539c76cf9e8e4a57d0a76033013 (diff) | |
| download | rabbitmq-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.erl | 34 |
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()); |
