Don’t assume that posix_fallocate()
is available on Linux and not
available on other operating systems. At least FreeBSD has it and we
are not using it.
Properly check whether posix_fallocate()
is present and use it if it
is.
Don’t assume that posix_fallocate()
is available on Linux and not
available on other operating systems. At least FreeBSD has it and we
are not using it.
Properly check whether posix_fallocate()
is present and use it if it
is.
To verify that this works as intended:
Check if you have posix_fallocate()
./configure ... |grep posix_fallocate
- the result should coincide with 1.
Put something like this in src/util/system.cpp
and try to recompile:
0#if defined(HAVE_POSIX_FALLOCATE)
1#error posix_fallocate is present
2#else
3#error posix_fallocate is not present
4#endif
The printout should coincide with 1. and 2.
ACK 61d4bee72f3800edd00ec565313c820b536954ec
Good catch. Generally spoken the detection of specific features is preferable to OS-specific paths. As it is a POSIX function I suppose we can assume that the functionality and parameters are the same over all platforms that have it?
ACK 61d4bee72
Concept ACK on feature detection > OS detection. I looked for a Portable Operating System Interface compatibility/portability matrix and came up with https://en.wikipedia.org/wiki/POSIX#POSIX-oriented_operating_systems, https://www.opengroup.org/openbrand/register/, and the second answer in https://stackoverflow.com/questions/1780599/what-is-the-meaning-of-posix. One issue is that many distributions are compliant but don’t want to pay for certification.
Code review, verified man posix_fallocate
, reproduced #18437 (comment) with Debian 4.19
0checking for posix_fallocate... yes
1(pr/18437)$ make | grep posix_fallocate
2util/system.cpp:14:2: error: #error posix_fallocate is present
3 #error posix_fallocate is present
4 ^~~~~
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
No conflicts as of last run.
Concept ACK
Thanks for all nice contributions lately @vasild. Nice to have you as a recurring contributor!
Concept ACK
I think you may also need to adjust _POSIX_C_SOURCE
in your autoconf test - see:
https://github.com/bitcoin/bitcoin/blob/694f4cbd7853ffeb7b4576d42368920b0ef79b01/src/util/system.cpp#L20-L29
Context: https://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html#index-_005fPOSIX_005fC_005fSOURCE http://man7.org/linux/man-pages/man3/posix_fallocate.3.html#CONFORMING_TO
Perhaps we could check the defined version rather than adjusting it ourselves?
@Empact Right, good catch!
The patch had a deficiency that if run on a system that does not provide posix_fallocate()
by default but would make it available if the user explicitly asks for it (by defining _POSIX_C_SOURCE
to 200112
), then on such system the configure check would conclude that the function is not present and so it would not be used in the source code (even though it would have been available if we asked for it).
I updated the configure check to explicitly request for it, exactly like the source code does in src/util/system.cpp
.
Perhaps we could check the defined version rather than adjusting it ourselves?
That would miss the function in the above imaginary system (some old Linux?) - if it is available only if one asks for it (define _POSIX_C_SOURCE
to 200112
or higher). I think we are doing the right thing on Linux with the _POSIX_C_SOURCE
macro - we define it to ask for certain functions, not just peeking at it. From feature_test_macros(7):
Feature test macros allow the programmer to control the definitions that are exposed by system header files
Don't assume that `posix_fallocate()` is available on Linux and not
available on other operating systems. At least FreeBSD has it and we
are not using it.
Properly check whether `posix_fallocate()` is present and use it if it
is.
850@@ -851,6 +851,21 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <malloc.h>]],
851 [ AC_MSG_RESULT(no)]
852 )
853
854+dnl Check for posix_fallocate
855+AC_MSG_CHECKING(for posix_fallocate)
856+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
857+ #ifdef __linux__
#ifdef __linux__
here.
_POSIX_C_SOURCE
is not Linux or GCC specific. However, only the Linux man page for posix_fallocate()
mentions it as a requirement. FreeBSD and NetBSD man pages don’t, implying that the function is available without having to define _POSIX_C_SOURCE
to a specific value.
In any case, this is what the source code in src/util/system.cpp already does and it’s important to have the check and source code do the same thing.
I dislike the duplication of #ifdef
logic, but okay, as long as it’s commented…
ACK 182dbdf0f4b6e6484b0d4588aaefacc75862a99c
I dislike the duplication of
#ifdef
logic, but okay, as long as it’s commented…
I did consider putting this:
0#ifdef __linux__
1
2#ifdef _POSIX_C_SOURCE
3#undef _POSIX_C_SOURCE
4#endif
5
6#define _POSIX_C_SOURCE 200112L
7
8#endif // __linux__
in a separate header file and then including that header file from configure.ac
and from system.cpp
, but decided it would be an overkill. Something to keep in mind should we need to do similar thing again.