[PATCH 1/1] libxfs: provide a memfd_create() wrapper if not present in libc

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxx>
---
 configure.ac          |  1 +
 include/builddefs.in  |  1 +
 libxfs/Makefile       |  4 ++++
 libxfs/xfile.c        | 16 ++++++++++++++++
 m4/package_libcdev.m4 | 18 ++++++++++++++++++
 5 files changed, 40 insertions(+)

diff --git a/configure.ac b/configure.ac
index b84234b5..8a9ddb3f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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
diff --git a/include/builddefs.in b/include/builddefs.in
index 734bd95e..1647d2cd 100644
--- a/include/builddefs.in
+++ b/include/builddefs.in
@@ -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@
diff --git a/libxfs/Makefile b/libxfs/Makefile
index 2f2791ca..833c6509 100644
--- a/libxfs/Makefile
+++ b/libxfs/Makefile
@@ -128,6 +128,10 @@ CFILES = buf_mem.c \
 #
 #LCFLAGS +=
 
+ifeq ($(HAVE_MEMFD_CREATE),yes)
+LCFLAGS += -DHAVE_MEMFD_CREATE
+endif
+
 FCFLAGS = -I.
 
 LTLIBS = $(LIBPTHREAD) $(LIBRT)
diff --git a/libxfs/xfile.c b/libxfs/xfile.c
index b4908b49..b8379775 100644
--- a/libxfs/xfile.c
+++ b/libxfs/xfile.c
@@ -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>
 
@@ -36,6 +39,19 @@
 # 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
diff --git a/m4/package_libcdev.m4 b/m4/package_libcdev.m4
index de64c9af..6de8b33e 100644
--- a/m4/package_libcdev.m4
+++ b/m4/package_libcdev.m4
@@ -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"
-- 
2.46.0





[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux