rofiles-fuse: Build using FUSE 3 if possible, falling back to FUSE 2
authorSimon McVittie <smcv@collabora.com>
Tue, 4 Jan 2022 09:41:38 +0000 (09:41 +0000)
committerLuca BRUNO <luca.bruno@coreos.com>
Tue, 4 Jan 2022 09:41:38 +0000 (09:41 +0000)
This adds build-time configuration logic to automatically detect
and switch between libfuse 2.x and 3.x.

Signed-off-by: Simon McVittie <smcv@collabora.com>
Co-authored-by: Luca BRUNO <luca.bruno@coreos.com>
.github/workflows/tests.yml
ci/gh-install.sh
configure.ac
src/rofiles-fuse/main.c

index c17a1c0dfb5d1df6d6f853d0da3ca67c55f3717b..5fd14bde9ce3d70c8c44b4a4b1025a6fe0d854c2 100644 (file)
@@ -44,22 +44,24 @@ jobs:
           # oldstable-backports and unstable.
           #
           # https://hub.docker.com/_/debian
-          - name: Debian Stable with sign-ed25519
+          - name: Debian Stable with sign-ed25519 and FUSE 2
             image: debian:stable-slim
             pre-checkout-setup: |
               apt-get update
               apt-get install -y git
             extra-packages: >-
+              libfuse-dev
               libsodium-dev
             configure-options: >-
               --with-ed25519-libsodium
 
-          - name: Debian Stable with curl, sign-ed25519 and no gpgme
+          - name: Debian Stable with curl, sign-ed25519, no gpgme, FUSE 3
             image: debian:stable-slim
             pre-checkout-setup: |
               apt-get update
               apt-get install -y git
             extra-packages: >-
+              libfuse3-dev
               libsodium-dev
             configure-options: >-
               --with-curl
index 9902a94ec2a0211e29c43557580aa3c2af570d9f..f39331b140b76eddd1e32a41603a7dc419497a99 100755 (executable)
@@ -43,6 +43,19 @@ case "$ID" in
         # Ubuntu package data:
         # https://packages.ubuntu.com/source/impish/ostree
         #
+        # Use libfuse3-dev unless otherwise specified
+        case " $* " in
+            (*\ libfuse-dev\ *)
+                ;;
+
+            (*\ libfuse3-dev\ *)
+                ;;
+
+            (*)
+                set -- "$@" libfuse3-dev
+                ;;
+        esac
+
         # TODO: fetch this list from the Debian packaging git repository?
 
         # First construct a list of Build-Depends common to all
index 7dea7d2bdf464c0dddbdff666ad5d5525b902c24..551fc445cbdcb645faa7aa9fbedd17384c821f39 100644 (file)
@@ -254,6 +254,7 @@ AS_IF([test x$with_ed25519_libsodium != xno], [
 AM_CONDITIONAL(USE_LIBSODIUM, test "x$have_libsodium" = xyes)
 
 LIBARCHIVE_DEPENDENCY="libarchive >= 2.8.0"
+FUSE3_DEPENDENCY="fuse3 >= 3.1.1"
 # What's in RHEL7.2.
 FUSE_DEPENDENCY="fuse >= 2.9.2"
 
@@ -448,8 +449,22 @@ AC_ARG_ENABLE(rofiles-fuse,
                               [generate rofiles-fuse helper [default=yes]])],,
               enable_rofiles_fuse=yes)
 AS_IF([ test x$enable_rofiles_fuse != xno ], [
-    PKG_CHECK_MODULES(BUILDOPT_FUSE, $FUSE_DEPENDENCY)
-], [enable_rofiles_fuse=no])
+    PKG_CHECK_MODULES([FUSE3], [$FUSE3_DEPENDENCY],
+                      [
+                        FUSE_USE_VERSION=31
+                        BUILDOPT_FUSE_CFLAGS="$FUSE3_CFLAGS"
+                        BUILDOPT_FUSE_LIBS="$FUSE3_LIBS"
+                      ],
+                      [PKG_CHECK_MODULES([FUSE], [$FUSE_DEPENDENCY],
+                                         [
+                                           FUSE_USE_VERSION=26
+                                           BUILDOPT_FUSE_CFLAGS="$FUSE_CFLAGS"
+                                           BUILDOPT_FUSE_LIBS="$FUSE_LIBS"
+                                         ])])
+    AC_DEFINE_UNQUOTED([FUSE_USE_VERSION], [$FUSE_USE_VERSION], [Define to the FUSE API version])
+    AC_SUBST([BUILDOPT_FUSE_CFLAGS])
+    AC_SUBST([BUILDOPT_FUSE_LIBS])
+    ], [enable_rofiles_fuse=no])
 AM_CONDITIONAL(BUILDOPT_FUSE, test x$enable_rofiles_fuse = xyes)
 
 AC_ARG_WITH(dracut,
index e8c916fa3b863959afa6305d565533fe28658d82..7f49dd88eb60d65102807f9c4ca69c87cc757284 100644 (file)
  * License along with this library. If not, see <https://www.gnu.org/licenses/>.
  */
 
-#define FUSE_USE_VERSION 26
+#include "config.h"
+
+#ifndef FUSE_USE_VERSION
+#error config.h needs to define FUSE_USE_VERSION
+#endif
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -55,7 +59,11 @@ ENSURE_RELPATH (const char *path)
 }
 
 static int
+#if FUSE_USE_VERSION >= 31
+callback_getattr (const char *path, struct stat *st_data, struct fuse_file_info *finfo)
+#else
 callback_getattr (const char *path, struct stat *st_data)
+#endif
 {
   path = ENSURE_RELPATH (path);
   if (!*path)
@@ -89,8 +97,13 @@ callback_readlink (const char *path, char *buf, size_t size)
 }
 
 static int
+#if FUSE_USE_VERSION >= 31
+callback_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
+                  off_t offset, struct fuse_file_info *fi, enum fuse_readdir_flags flags)
+#else
 callback_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
                   off_t offset, struct fuse_file_info *fi)
+#endif
 {
   DIR *dp;
   struct dirent *de;
@@ -123,8 +136,14 @@ callback_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
       memset (&st, 0, sizeof (st));
       st.st_ino = de->d_ino;
       st.st_mode = de->d_type << 12;
+
+#if FUSE_USE_VERSION >= 31
+      if (filler (buf, de->d_name, &st, 0, 0))
+        break;
+#else
       if (filler (buf, de->d_name, &st, 0))
         break;
+#endif
     }
 
   (void) closedir (dp);
@@ -184,11 +203,21 @@ callback_symlink (const char *from, const char *to)
 }
 
 static int
+#if FUSE_USE_VERSION >= 31
+callback_rename (const char *from, const char *to, unsigned int flags)
+#else
 callback_rename (const char *from, const char *to)
+#endif
 {
+#if FUSE_USE_VERSION < 31
+  unsigned int flags = 0;
+#endif
+
   from = ENSURE_RELPATH (from);
   to = ENSURE_RELPATH (to);
-  if (renameat (basefd, from, basefd, to) == -1)
+
+  /* This assumes Linux 3.15+ */
+  if (renameat2 (basefd, from, basefd, to, flags) == -1)
     return -errno;
   return 0;
 }
@@ -299,7 +328,11 @@ verify_write_or_copyup (const char *path, const struct stat *stbuf,
   } while (0)
 
 static int
+#if FUSE_USE_VERSION >= 31
+callback_chmod (const char *path, mode_t mode, struct fuse_file_info *finfo)
+#else
 callback_chmod (const char *path, mode_t mode)
+#endif
 {
   PATH_WRITE_ENTRYPOINT (path);
 
@@ -313,7 +346,11 @@ callback_chmod (const char *path, mode_t mode)
 }
 
 static int
+#if FUSE_USE_VERSION >= 31
+callback_chown (const char *path, uid_t uid, gid_t gid, struct fuse_file_info *finfo)
+#else
 callback_chown (const char *path, uid_t uid, gid_t gid)
+#endif
 {
   PATH_WRITE_ENTRYPOINT (path);
 
@@ -323,7 +360,11 @@ callback_chown (const char *path, uid_t uid, gid_t gid)
 }
 
 static int
+#if FUSE_USE_VERSION >= 31
+callback_truncate (const char *path, off_t size, struct fuse_file_info *finfo)
+#else
 callback_truncate (const char *path, off_t size)
+#endif
 {
   PATH_WRITE_ENTRYPOINT (path);
 
@@ -338,7 +379,11 @@ callback_truncate (const char *path, off_t size)
 }
 
 static int
+#if FUSE_USE_VERSION >= 31
+callback_utimens (const char *path, const struct timespec tv[2], struct fuse_file_info *finfo)
+#else
 callback_utimens (const char *path, const struct timespec tv[2])
+#endif
 {
   /* This one isn't write-verified, we support changing times
    * even for hardlinked files.