From b83bd5fd148c004f5d53fadafa4ef8e6cc97e3b2 Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Sun, 12 Jan 2025 14:55:04 -0600 Subject: [PATCH] Improve FreeBSD compatibility First draft. Need to investigate why upstream patches include certain function that appear to exist in FreeBSD 14.2. --- libfuse/lib/cpu.cpp | 35 +++++++++++++------ libfuse/lib/cpu.hpp | 9 +++-- mkdocs/docs/config/options.md | 3 +- .../faq/technical_behavior_and_limitations.md | 24 +++++++++++++ mkdocs/docs/related_projects.md | 7 ++-- mkdocs/docs/setup/build.md | 15 ++++++-- mkdocs/docs/setup/installation.md | 29 +++++++++++++-- src/fs_readahead.cpp | 6 +++- src/fs_umount2.hpp | 10 +++++- tools/preload.c | 6 +++- 10 files changed, 117 insertions(+), 27 deletions(-) diff --git a/libfuse/lib/cpu.cpp b/libfuse/lib/cpu.cpp index 31916490..15c71e46 100644 --- a/libfuse/lib/cpu.cpp +++ b/libfuse/lib/cpu.cpp @@ -1,22 +1,37 @@ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif +/* + ISC License + + Copyright (c) 2024, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ #include "cpu.hpp" #include "ghc/filesystem.hpp" #include "fmt/core.h" +#include #include #include int -CPU::getaffinity(const pthread_t thread_id_, - cpu_set_t *cpuset_) +CPU::getaffinity(cpu_set_t *cpuset_) { + const pid_t pid = 0; CPU_ZERO(cpuset_); - return sched_getaffinity(thread_id_, + return sched_getaffinity(pid, sizeof(cpu_set_t), cpuset_); } @@ -70,7 +85,7 @@ CPU::count() int rv; cpu_set_t cpuset; - rv = CPU::getaffinity(0,&cpuset); + rv = CPU::getaffinity(&cpuset); if(rv < 0) return rv; @@ -83,7 +98,7 @@ CPU::cpus() cpu_set_t cpuset; CPU::CPUVec cpuvec; - CPU::getaffinity(0,&cpuset); + CPU::getaffinity(&cpuset); for(int i = 0; i < CPU_SETSIZE; i++) { @@ -102,7 +117,7 @@ CPU::cpu2core() cpu_set_t cpuset; CPU::CPU2CoreMap c2c; - CPU::getaffinity(0,&cpuset); + CPU::getaffinity(&cpuset); for(int i = 0; i < CPU_SETSIZE; i++) { @@ -135,7 +150,7 @@ CPU::core2cpus() cpu_set_t cpuset; CPU::Core2CPUsMap c2c; - CPU::getaffinity(0,&cpuset); + CPU::getaffinity(&cpuset); for(int i = 0; i < CPU_SETSIZE; i++) { diff --git a/libfuse/lib/cpu.hpp b/libfuse/lib/cpu.hpp index c2d591fe..264c6153 100644 --- a/libfuse/lib/cpu.hpp +++ b/libfuse/lib/cpu.hpp @@ -1,10 +1,9 @@ #pragma once -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - #include +#ifdef __FreeBSD__ +#include +#endif #include #include @@ -22,7 +21,7 @@ public: public: static int count(); - static int getaffinity(const pthread_t thread_id, cpu_set_t *cpuset); + static int getaffinity(cpu_set_t *cpuset); static int setaffinity(const pthread_t thread_id, cpu_set_t *cpuset); static int setaffinity(const pthread_t thread_id, const int cpu); static int setaffinity(const pthread_t thread_id, const std::set cpus); diff --git a/mkdocs/docs/config/options.md b/mkdocs/docs/config/options.md index 21f8e130..7bdeb4f9 100644 --- a/mkdocs/docs/config/options.md +++ b/mkdocs/docs/config/options.md @@ -54,7 +54,8 @@ These options are the same regardless of whether you use them with the mergerfs. (default: false) - **lazy-umount-mountpoint=BOOL**: mergerfs will attempt to "lazy umount" the mountpoint before mounting itself. Useful when - performing live upgrades of mergerfs. (default: false) + performing live upgrades of mergerfs. May not work on + FreeBSD. (default: false) - **ignorepponrename=BOOL**: Ignore path preserving on rename. Typically rename and link act differently depending on the policy of `create` (read below). Enabling this will cause rename and diff --git a/mkdocs/docs/faq/technical_behavior_and_limitations.md b/mkdocs/docs/faq/technical_behavior_and_limitations.md index d7e1a57c..ec8d114a 100644 --- a/mkdocs/docs/faq/technical_behavior_and_limitations.md +++ b/mkdocs/docs/faq/technical_behavior_and_limitations.md @@ -213,3 +213,27 @@ at best, provide equivalent performance, and in some cases, worse performance. Splice is not supported on other platforms forcing a traditional read/write fallback to be provided. The splice code was removed to simplify the codebase. + + +## How does mergerfs handle credentials? + + +mergerfs is a multithreaded application in order to handle requests +from the kernel concurrently. Each FUSE message has a header with +certain details about the request include the process ID (pid) of the +requestion application, the process' effective user id (uid), and +group id (gid). To ensure proper POSIX filesystem behavior and +security mergerfs must change its identity to match that of the +requester when performing the core filesystem function on the +underlying filesystem. On most Unix/POSIX based system a process and +all its threads are under the same uid and gid. However, on Linux each +thread may have its own credentials. This allows mergerfs to be +multithreaded and for each thread to change to the credentials +(seteuid,setegid) as required by the incoming message it is +handling. However, on FreeBSD this is not possible at the moment +(though there has been +[discussions](https://wiki.freebsd.org/Per-Thread%20Credentials) and +as such must change the credentials of the whole application when +actioning messages. mergerfs does optimize this behavior by only +changing credentials and locking the thread to do so if the process is +currently not the same as what is necessary by the incoming request. diff --git a/mkdocs/docs/related_projects.md b/mkdocs/docs/related_projects.md index 1a84e1a0..a87f264e 100644 --- a/mkdocs/docs/related_projects.md +++ b/mkdocs/docs/related_projects.md @@ -37,8 +37,8 @@ mergerfs can be found in the [repositories](https://pkgs.org/download/mergerfs) of [many -Linux](https://repology.org/project/mergerfs/versions) (and maybe -FreeBSD) distributions. +Linux](https://repology.org/project/mergerfs/versions) distributions +and FreeBSD. Note: Any non-rolling release based distro is likely to have out-of-date versions. @@ -51,6 +51,7 @@ out-of-date versions. * [Gentoo](https://packages.gentoo.org/packages/sys-fs/mergerfs) * [Arch (AUR)](https://aur.archlinux.org/packages/mergerfs) * [Void](https://voidlinux.org/packages/?arch=x86_64&q=mergerfs) -* [NixOS](https://search.nixos.org/packages?channel=22.11&show=mergerfs&from=0&size=50&sort=relevance&type=packages&query=mergerfs) +* [NixOS](https://search.nixos.org/packages?type=packages&query=mergerfs) * [Guix]() * [Slackware](https://slackbuilds.org/repository/15.0/system/mergerfs/?search=mergerfs) +* [FreeBSD](https://www.freshports.org/filesystems/mergerfs) diff --git a/mkdocs/docs/setup/build.md b/mkdocs/docs/setup/build.md index b10c3e3f..2189994c 100644 --- a/mkdocs/docs/setup/build.md +++ b/mkdocs/docs/setup/build.md @@ -33,9 +33,9 @@ $ su - # rpm -i rpmbuild/RPMS//mergerfs-..rpm ``` -## Generic +## Generic Linux -Have git, g++, make, python installed. +Have git, g++ or clang, make, python installed. ``` @@ -44,6 +44,17 @@ $ make $ sudo make install ``` +## FreeBSD + +Have git, g++ or clang, gmake, python installed. + +``` +$ cd mergerfs +$ gmake +$ gmake install # as root +``` + + ## Build options ``` diff --git a/mkdocs/docs/setup/installation.md b/mkdocs/docs/setup/installation.md index ef1d2747..b84a3b97 100644 --- a/mkdocs/docs/setup/installation.md +++ b/mkdocs/docs/setup/installation.md @@ -81,6 +81,14 @@ wget https://github.com/trapexit/mergerfs/releases/download//mergerfs- sudo rpm -i mergerfs-.el..rpm ``` +## NixOS + +[search.nixos.org](https://search.nixos.org/packages?channel=unstable&show=mergerfs&from=0&size=50&sort=relevance&type=packages&query=mergerfs) + +``` +nix-env -iA nixos.mergerfs +``` + ## ArchLinux @@ -88,10 +96,15 @@ sudo rpm -i mergerfs-.el..rpm 2. `pacman -S mergerfs` -## Other +## Other Linux Distros + +[Check your distro.](../related_projects.md#distributions-including-mergerfs) + + +## Static Linux Binaries -Static binaries are provided for situations where native packages are -unavailable. +If your distro does not package mergerfs there are static binaries +provided. Get the tarball from the [releases page](https://github.com/trapexit/mergerfs/releases). @@ -99,3 +112,13 @@ Get the tarball from the [releases page](https://github.com/trapexit/mergerfs/re wget https://github.com/trapexit/mergerfs/releases/download//mergerfs-static-linux_.tar.gz sudo tar xvf mergerfs-static-linux_.tar.gz -C / ``` + + +## FreeBSD + +[https://www.freshports.org/filesystems/mergerfs](https://www.freshports.org/filesystems/mergerfs) + + +``` +pkg install filesystems/mergerfs +``` diff --git a/src/fs_readahead.cpp b/src/fs_readahead.cpp index 740c28a7..759983e4 100644 --- a/src/fs_readahead.cpp +++ b/src/fs_readahead.cpp @@ -25,7 +25,11 @@ #include #include -#include +#ifdef __FreeBSD__ +# include +#else +# include +#endif namespace l { diff --git a/src/fs_umount2.hpp b/src/fs_umount2.hpp index 7fc1c2c2..2d2dd047 100644 --- a/src/fs_umount2.hpp +++ b/src/fs_umount2.hpp @@ -18,8 +18,16 @@ #pragma once +#ifdef __FreeBSD__ +# include +# include +# define umount2(target,flags) unmount(target,flags) +# define MNT_DETACH 0 +#else +# include +#endif + #include -#include #include diff --git a/tools/preload.c b/tools/preload.c index c1db4cb3..886ad53b 100644 --- a/tools/preload.c +++ b/tools/preload.c @@ -16,8 +16,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifdef __FreeBSD__ +#define O_TMPFILE 0 +#else #define _GNU_SOURCE -#define _POSIX_C_SOURCE 200809L +//#define _POSIX_C_SOURCE 200809L +#endif #include #include