]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
libxfs: provide a memfd_create() wrapper if not present in libc
authorJulien Olivain <ju.o@free.fr>
Sat, 17 Aug 2024 16:00:52 +0000 (18:00 +0200)
committerCarlos Maiolino <cem@kernel.org>
Mon, 16 Sep 2024 07:13:57 +0000 (09:13 +0200)
Commit 1cb2e387 "libxfs: add xfile support" introduced
a use of the memfd_create() system call, included in version
xfsprogs v6.9.0.

This system call was introduced in kernel commit [1], first included
in kernel v3.17 (released on 2014-10-05).

The memfd_create() glibc wrapper function was added much later in
commit [2], first included in glibc version 2.27 (released on
2018-02-01).

This direct use memfd_create() introduced a requirement on
Kernel >= 3.17 and glibc >= 2.27.

There is old toolchains like [3] for example (which ships gcc 7.3.1,
glibc 2.25 and includes kernel v4.10 headers), that can still be used
to build newer kernels. Even if such toolchains can be seen as
outdated, they are still claimed as supported by recent kernel.
For example, Kernel v6.10.5 has a requirement on gcc version 5.1 and
greater. See [4].

When compiling xfsprogs v6.9.0 with a toolchain not providing the
memfd_create() syscall wrapper, the compilation fail with message:

    xfile.c: In function 'xfile_create_fd':
    xfile.c:56:7: warning: implicit declaration of function 'memfd_create'; did you mean 'timer_create'? [-Wimplicit-function-declaration]
      fd = memfd_create(description, MFD_CLOEXEC | MFD_NOEXEC_SEAL);
           ^~~~~~~~~~~~

    ../libxfs/.libs/libxfs.a(xfile.o): In function 'xfile_create_fd':
    /build/xfsprogs-6.9.0/libxfs/xfile.c:56: undefined reference to 'memfd_create'

In order to let xfsprogs compile in a wider range of configurations,
this commit adds a memfd_create() function check in autoconf configure
script, and adds a system call wrapper which will be used if the
function is not available. With this commit, the environment
requirement is relaxed to only kernel >= v3.17.

Note: this issue was found in xfsprogs integration in Buildroot [5]
using the command "utils/test-pkg -a -p xfsprogs", which tests many
toolchain/arch combinations.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=9183df25fe7b194563db3fec6dc3202a5855839c
[2] https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=59d2cbb1fe4b8601d5cbd359c3806973eab6c62d
[3] https://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/aarch64-linux-gnu/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu.tar.xz
[4] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation/process/changes.rst?h=v6.10.5#n32
[5] https://buildroot.org/

Signed-off-by: Julien Olivain <ju.o@free.fr>
Reviewed-by: Christoph Hellwig <hch@lst.de>
configure.ac
include/builddefs.in
libxfs/Makefile
libxfs/xfile.c
m4/package_libcdev.m4

index 29dc374b7de7c2d6f3d708665c1eb8281c59883a..33b01399ae3b002135826313966a7d8416a0a9a0 100644 (file)
@@ -151,6 +151,7 @@ AC_HAVE_MAP_SYNC
 AC_HAVE_DEVMAPPER
 AC_HAVE_MALLINFO
 AC_HAVE_MALLINFO2
+AC_HAVE_MEMFD_CREATE
 AC_PACKAGE_WANT_ATTRIBUTES_H
 AC_HAVE_LIBATTR
 if test "$enable_scrub" = "yes"; then
index 734bd95ecb0b339e9d0ccf3409978912fdf8f870..1647d2cd1690903edf2f1577a26e451e86d7fd0f 100644 (file)
@@ -101,6 +101,7 @@ HAVE_MAP_SYNC = @have_map_sync@
 HAVE_DEVMAPPER = @have_devmapper@
 HAVE_MALLINFO = @have_mallinfo@
 HAVE_MALLINFO2 = @have_mallinfo2@
+HAVE_MEMFD_CREATE = @have_memfd_create@
 HAVE_LIBATTR = @have_libattr@
 HAVE_LIBICU = @have_libicu@
 HAVE_SYSTEMD = @have_systemd@
index 2f2791cae5873c962e9f6e1e65fba72e1a6bae66..833c65092bb3b0819bffcb6e286012f40beaf287 100644 (file)
@@ -128,6 +128,10 @@ CFILES = buf_mem.c \
 #
 #LCFLAGS +=
 
+ifeq ($(HAVE_MEMFD_CREATE),yes)
+LCFLAGS += -DHAVE_MEMFD_CREATE
+endif
+
 FCFLAGS = -I.
 
 LTLIBS = $(LIBPTHREAD) $(LIBRT)
index b4908b49b6d5e03339dea0cbbd8c537373b56d15..b83797751b87ba63d3a61a7b0f7f44bfbd0297d6 100644 (file)
@@ -8,6 +8,9 @@
 #include "libxfs/xfile.h"
 #include <linux/memfd.h>
 #include <sys/mman.h>
+#ifndef HAVE_MEMFD_CREATE
+#include <sys/syscall.h>
+#endif
 #include <sys/types.h>
 #include <sys/wait.h>
 
 # define MFD_NOEXEC_SEAL       (0x0008U)
 #endif
 
+/*
+ * The memfd_create system call was added to kernel 3.17 (2014), but
+ * its corresponding glibc wrapper was only added in glibc 2.27
+ * (2018).  In case a libc is not providing the wrapper, we provide
+ * one here.
+ */
+#ifndef HAVE_MEMFD_CREATE
+static int memfd_create(const char *name, unsigned int flags)
+{
+       return syscall(SYS_memfd_create, name, flags);
+}
+#endif
+
 /*
  * Open a memory-backed fd to back an xfile.  We require close-on-exec here,
  * because these memfd files function as windowed RAM and hence should never
index de64c9af7fdef2d50fd3fd27f3d4b8c34f0c0803..6de8b33ee29fd5c3018f1ba8cc6d4b9d7024c190 100644 (file)
@@ -177,6 +177,24 @@ test = mallinfo2();
     AC_SUBST(have_mallinfo2)
   ])
 
+#
+# Check if we have a memfd_create libc call (Linux)
+#
+AC_DEFUN([AC_HAVE_MEMFD_CREATE],
+  [ AC_MSG_CHECKING([for memfd_create])
+    AC_LINK_IFELSE(
+    [  AC_LANG_PROGRAM([[
+#define _GNU_SOURCE
+#include <sys/mman.h>
+       ]], [[
+memfd_create(0, 0);
+       ]])
+    ], have_memfd_create=yes
+       AC_MSG_RESULT(yes),
+       AC_MSG_RESULT(no))
+    AC_SUBST(have_memfd_create)
+  ])
+
 AC_DEFUN([AC_PACKAGE_CHECK_LTO],
   [ AC_MSG_CHECKING([if C compiler supports LTO])
     OLD_CFLAGS="$CFLAGS"