mirror of
https://github.com/trapexit/mergerfs.git
synced 2026-10-26 19:01:56 -04:00
Compare commits
No commits in common. "master" and "2.40.2" have entirely different histories.
1142 changed files with 79134 additions and 119102 deletions
527
.cirrus.yml
Normal file
527
.cirrus.yml
Normal file
|
|
@ -0,0 +1,527 @@
|
||||||
|
freebsd_task:
|
||||||
|
name: "freebsd:11.4"
|
||||||
|
freebsd_instance:
|
||||||
|
image_family: freebsd-11-4
|
||||||
|
env:
|
||||||
|
ASSUME_ALWAYS_YES: yes
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- gmake -j4
|
||||||
|
|
||||||
|
freebsd_task:
|
||||||
|
name: "freebsd:12.1"
|
||||||
|
freebsd_instance:
|
||||||
|
image_family: freebsd-12-1
|
||||||
|
env:
|
||||||
|
ASSUME_ALWAYS_YES: yes
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- gmake -j4
|
||||||
|
|
||||||
|
freebsd_task:
|
||||||
|
name: "freebsd:12.2"
|
||||||
|
freebsd_instance:
|
||||||
|
image_family: freebsd-12-2
|
||||||
|
env:
|
||||||
|
ASSUME_ALWAYS_YES: yes
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- gmake -j4
|
||||||
|
|
||||||
|
freebsd_task:
|
||||||
|
name: "freebsd:13.0"
|
||||||
|
freebsd_instance:
|
||||||
|
image_family: freebsd-13-0
|
||||||
|
env:
|
||||||
|
ASSUME_ALWAYS_YES: yes
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- gmake -j4
|
||||||
|
|
||||||
|
|
||||||
|
#macos_task:
|
||||||
|
# osx_instance:
|
||||||
|
# image: catalina-base
|
||||||
|
# script:
|
||||||
|
# - buildtools/install-build-pkgs
|
||||||
|
# - gmake -j4
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "alpine:3.11"
|
||||||
|
container:
|
||||||
|
image: alpine:3.11
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make STATIC=1 LTO=1
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "alpine:3.12"
|
||||||
|
container:
|
||||||
|
image: alpine:3.12
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make STATIC=1 LTO=1
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "alpine:3.13"
|
||||||
|
container:
|
||||||
|
image: alpine:3.13
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make STATIC=1 LTO=1
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "alpine:3.14"
|
||||||
|
container:
|
||||||
|
image: alpine:3.14
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make STATIC=1 LTO=1
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "alpine:3.15"
|
||||||
|
container:
|
||||||
|
image: alpine:3.15
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make STATIC=1 LTO=1
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "alpine:3.16"
|
||||||
|
container:
|
||||||
|
image: alpine:3.16
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make STATIC=1 LTO=1
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "alpine:3.17"
|
||||||
|
container:
|
||||||
|
image: alpine:3.17
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make STATIC=1 LTO=1
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "alpine:latest"
|
||||||
|
container:
|
||||||
|
image: alpine:latest
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make STATIC=1 LTO=1
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "alpine-arm:latest"
|
||||||
|
arm_container:
|
||||||
|
image: alpine:latest
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make STATIC=1 LTO=1
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "centos:7"
|
||||||
|
container:
|
||||||
|
image: centos:7
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make
|
||||||
|
- make rpm
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "rocky:8"
|
||||||
|
container:
|
||||||
|
image: rocky:8
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make
|
||||||
|
- make rpm
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "fedora:30"
|
||||||
|
container:
|
||||||
|
image: fedora:30
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make
|
||||||
|
- make rpm
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "fedora:31"
|
||||||
|
container:
|
||||||
|
image: fedora:31
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make
|
||||||
|
- make rpm
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "fedora:32"
|
||||||
|
container:
|
||||||
|
image: fedora:32
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make
|
||||||
|
- make rpm
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "fedora:33"
|
||||||
|
container:
|
||||||
|
image: fedora:33
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make
|
||||||
|
- make rpm
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "fedora:34"
|
||||||
|
container:
|
||||||
|
image: fedora:34
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make
|
||||||
|
- make rpm
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "fedora:35"
|
||||||
|
container:
|
||||||
|
image: fedora:35
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make
|
||||||
|
- make rpm
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "fedora:36"
|
||||||
|
container:
|
||||||
|
image: fedora:36
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make
|
||||||
|
- make rpm
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "fedora:37"
|
||||||
|
container:
|
||||||
|
image: fedora:37
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make
|
||||||
|
- make rpm
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "fedora:38"
|
||||||
|
container:
|
||||||
|
image: fedora:38
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make
|
||||||
|
- make rpm
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "fedora:latest"
|
||||||
|
container:
|
||||||
|
image: fedora:latest
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make
|
||||||
|
- make rpm
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "fedora-arm:latest"
|
||||||
|
arm_container:
|
||||||
|
image: fedora:latest
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- make
|
||||||
|
- make rpm
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "ubuntu:14.04"
|
||||||
|
container:
|
||||||
|
image: ubuntu:14.04
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- git fetch
|
||||||
|
- make deb
|
||||||
|
- apt-get -y install fuse
|
||||||
|
- dpkg -i ../*.deb
|
||||||
|
- mergerfs -v || true
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "ubuntu:16.04"
|
||||||
|
container:
|
||||||
|
image: ubuntu:16.04
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- git fetch
|
||||||
|
- make deb
|
||||||
|
- apt-get -y install fuse
|
||||||
|
- dpkg -i ../*.deb
|
||||||
|
- mergerfs -v || true
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "ubuntu:18.04"
|
||||||
|
container:
|
||||||
|
image: ubuntu:18.04
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- git fetch
|
||||||
|
- make deb
|
||||||
|
- apt-get -y install fuse
|
||||||
|
- dpkg -i ../*.deb
|
||||||
|
- mergerfs -v || true
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "ubuntu:20.04"
|
||||||
|
container:
|
||||||
|
image: ubuntu:20.04
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- git fetch
|
||||||
|
- make deb
|
||||||
|
- apt-get -y install fuse
|
||||||
|
- dpkg -i ../*.deb
|
||||||
|
- mergerfs -v || true
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "ubuntu:22.04"
|
||||||
|
container:
|
||||||
|
image: ubuntu:22.04
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- git fetch
|
||||||
|
- make deb
|
||||||
|
- apt-get -y install fuse
|
||||||
|
- dpkg -i ../*.deb
|
||||||
|
- mergerfs -v || true
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "ubuntu:latest"
|
||||||
|
container:
|
||||||
|
image: ubuntu:latest
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- git fetch
|
||||||
|
- make deb
|
||||||
|
- apt-get -y install fuse
|
||||||
|
- dpkg -i ../*.deb
|
||||||
|
- mergerfs -v || true
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "ubuntu-arm:latest"
|
||||||
|
arm_container:
|
||||||
|
image: ubuntu:latest
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- git fetch
|
||||||
|
- make deb
|
||||||
|
- apt-get -y install fuse
|
||||||
|
- dpkg -i ../*.deb
|
||||||
|
- mergerfs -v || true
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "debian:7"
|
||||||
|
container:
|
||||||
|
image: debian:8
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- git fetch
|
||||||
|
- make deb
|
||||||
|
- apt-get -y install fuse
|
||||||
|
- dpkg -i ../*.deb
|
||||||
|
- mergerfs -v || true
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "debian:8"
|
||||||
|
container:
|
||||||
|
image: debian:8
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- git fetch
|
||||||
|
- make deb
|
||||||
|
- apt-get -y install fuse
|
||||||
|
- dpkg -i ../*.deb
|
||||||
|
- mergerfs -v || true
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "debian:9"
|
||||||
|
container:
|
||||||
|
image: debian:9
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- git fetch
|
||||||
|
- make deb
|
||||||
|
- apt-get -y install fuse
|
||||||
|
- dpkg -i ../*.deb
|
||||||
|
- mergerfs -v || true
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "debian:10"
|
||||||
|
container:
|
||||||
|
image: debian:10
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- git fetch
|
||||||
|
- make deb
|
||||||
|
- apt-get -y install fuse
|
||||||
|
- dpkg -i ../*.deb
|
||||||
|
- mergerfs -v || true
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "debian:11"
|
||||||
|
container:
|
||||||
|
image: debian:11
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- git fetch
|
||||||
|
- make deb
|
||||||
|
- apt-get -y install fuse
|
||||||
|
- dpkg -i ../*.deb
|
||||||
|
- mergerfs -v || true
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "debian:12"
|
||||||
|
container:
|
||||||
|
image: debian:12
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- git fetch
|
||||||
|
- make deb
|
||||||
|
- apt-get -y install fuse
|
||||||
|
- dpkg -i ../*.deb
|
||||||
|
- mergerfs -v || true
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "debian:latest"
|
||||||
|
container:
|
||||||
|
image: debian:latest
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- git fetch
|
||||||
|
- make deb
|
||||||
|
- apt-get -y install fuse
|
||||||
|
- dpkg -i ../*.deb
|
||||||
|
- mergerfs -v || true
|
||||||
|
|
||||||
|
linux_task:
|
||||||
|
name: "debian-arm:latest"
|
||||||
|
arm_container:
|
||||||
|
image: debian:latest
|
||||||
|
cpu: 4
|
||||||
|
memory: 4G
|
||||||
|
timeout_in: 15m
|
||||||
|
script:
|
||||||
|
- buildtools/install-build-pkgs
|
||||||
|
- git fetch
|
||||||
|
- make deb
|
||||||
|
- apt-get -y install fuse
|
||||||
|
- dpkg -i ../*.deb
|
||||||
|
- mergerfs -v || true
|
||||||
7
.github/FUNDING.yml
vendored
7
.github/FUNDING.yml
vendored
|
|
@ -1,2 +1,7 @@
|
||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
github: [trapexit]
|
github: [trapexit]
|
||||||
custom: ['https://github.com/trapexit/support']
|
patreon: trapexit
|
||||||
|
custom: ['https://paypal.me/trapexit','https://buymeacoff.ee/trapexit']
|
||||||
|
ko_fi: trapexit
|
||||||
|
open_collective: trapexit
|
||||||
|
|
|
||||||
60
.github/ISSUE_TEMPLATE/bug_report.md
vendored
60
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
|
@ -7,31 +7,22 @@ assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
See also https://trapexit.github.io/mergerfs/latest/support
|
|
||||||
|
|
||||||
**Describe the bug**
|
**Describe the bug**
|
||||||
|
|
||||||
A clear and concise description of the unexpected behavior.
|
A clear and concise description of the unexpected behavior.
|
||||||
|
|
||||||
**Please be sure to use latest release of mergerfs to ensure the issue
|
**Please be sure to use latest release of mergerfs to ensure the issue still exists. Not your distro's latest but the latest official release.**
|
||||||
still exists. Not your distro's latest but the latest official
|
|
||||||
release. Support will NOT be provided for old versions.**
|
|
||||||
|
|
||||||
The `master` branch is **not** to be considered production ready. Feel
|
The master branch is **not** to be considered production ready. Feel free to file bug reports but do so indicating clearly that you are testing unreleased code.
|
||||||
free to file bug reports but do so indicating clearly that you are
|
|
||||||
testing unreleased code.
|
|
||||||
|
|
||||||
|
|
||||||
**To Reproduce**
|
**To Reproduce**
|
||||||
|
|
||||||
Provide steps to reproduce the behavior. List **all** steps to
|
Steps to reproduce the behavior. List **all** steps to reproduce. **All** settings.
|
||||||
reproduce. **All** settings. The version of all software involved.
|
|
||||||
|
|
||||||
Please simplify the reproduction as much as possible.
|
Please simplify the reproduction as much as possible.
|
||||||
* Unless it is dependenat on multiple branches, use a single branch
|
- Unless it is dependenat on multiple branches, use a single branch
|
||||||
* Reproduce with standard tooling if possible
|
- Reproduce with standard tooling if possible (touch,truncate,rm,rmdir,ln,etc.) Having to install 3rd party software will make debugging more difficult.
|
||||||
(touch,truncate,rm,rmdir,ln,etc.) Having to install 3rd party
|
|
||||||
software will make debugging more difficult.
|
|
||||||
|
|
||||||
|
|
||||||
**Expected behavior**
|
**Expected behavior**
|
||||||
|
|
@ -39,38 +30,19 @@ Please simplify the reproduction as much as possible.
|
||||||
A clear and concise description of the expected behavior.
|
A clear and concise description of the expected behavior.
|
||||||
|
|
||||||
|
|
||||||
**Workarounds already tested**
|
|
||||||
|
|
||||||
Please list all workarounds attempted and why they were ruled out as
|
|
||||||
options.
|
|
||||||
|
|
||||||
|
|
||||||
**System information:**
|
**System information:**
|
||||||
|
|
||||||
* Attach output from
|
- OS, kernel version: `uname -a`
|
||||||
[mergerfs.collect-info](https://trapexit.github.io/mergerfs/latest/tooling/#mergerfscollect-info)
|
- mergerfs version: `mergerfs -V`
|
||||||
tool.
|
- mergerfs settings
|
||||||
* Alternatively:
|
- List of drives, filesystems, & sizes:
|
||||||
* OS: `lsb_release -a`
|
- `df -h`
|
||||||
* kernel version: `uname -a`
|
- `lsblk -f`
|
||||||
* mergerfs version: `mergerfs --version`
|
- A strace of the application having a problem:
|
||||||
* mergerfs settings / arguments: from fstab, systemd unit, command
|
- `strace -fvTtt -s 256 -o /tmp/app.strace.txt <cmd>`
|
||||||
line, OMV plugin, etc.
|
- `strace -fvTtt -s 256 -o /tmp/app.strace.txt -p <appPID>`
|
||||||
* List of drives, filesystems, & sizes:
|
- strace of mergerfs while app tried to do it's thing:
|
||||||
* `df -h`
|
- `strace -fvTtt -s 256 -p <mergerfsPID> -o /tmp/mergerfs.strace.txt`
|
||||||
* `lsblk -o NAME,FSTYPE,FSSIZE,SIZE,MOUNTPOINTS,RM,RO,ROTA`
|
|
||||||
* All information about the relevant paths and files: permissions,
|
|
||||||
ownership, etc.
|
|
||||||
* All information about the application making the requests:
|
|
||||||
version, uid/gid
|
|
||||||
* Is mergerfs running within a container or used with container
|
|
||||||
technologies?
|
|
||||||
* Are the client apps using mergerfs running in a container?
|
|
||||||
* A strace of the application having a problem:
|
|
||||||
* `strace -fvTtt -s 256 -o /tmp/app.strace.txt <cmd>`
|
|
||||||
* `strace -fvTtt -s 256 -o /tmp/app.strace.txt -p <appPID>`
|
|
||||||
* strace of mergerfs while app tried to do it's thing:
|
|
||||||
* `strace -fvTtt -s 256 -p <mergerfsPID> -o /tmp/mergerfs.strace.txt`
|
|
||||||
|
|
||||||
**Additional context**
|
**Additional context**
|
||||||
|
|
||||||
|
|
|
||||||
42
.github/workflows/codeql.yml
vendored
Normal file
42
.github/workflows/codeql.yml
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
name: "CodeQL"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "master" ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ "master" ]
|
||||||
|
schedule:
|
||||||
|
- cron: "7 3 * * 6"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
language: [ python, cpp ]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v2
|
||||||
|
with:
|
||||||
|
languages: ${{ matrix.language }}
|
||||||
|
queries: +security-and-quality
|
||||||
|
|
||||||
|
- name: Autobuild
|
||||||
|
uses: github/codeql-action/autobuild@v2
|
||||||
|
if: ${{ matrix.language == 'python' || matrix.language == 'cpp' }}
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v2
|
||||||
|
with:
|
||||||
|
category: "/language:${{ matrix.language }}"
|
||||||
10
.gitignore
vendored
10
.gitignore
vendored
|
|
@ -14,20 +14,12 @@
|
||||||
|
|
||||||
# build artifacts
|
# build artifacts
|
||||||
mergerfs
|
mergerfs
|
||||||
build/
|
obj/
|
||||||
src/version.hpp
|
src/version.hpp
|
||||||
VERSION
|
|
||||||
|
|
||||||
# Debian files
|
# Debian files
|
||||||
debian/files
|
debian/files
|
||||||
debian/changelog
|
debian/changelog
|
||||||
debian/debhelper-build-stamp
|
|
||||||
debian/mergerfs.debhelper.log
|
|
||||||
debian/mergerfs.substvars
|
|
||||||
|
|
||||||
# RPM files
|
# RPM files
|
||||||
rpmbuild/
|
rpmbuild/
|
||||||
|
|
||||||
# mkdocs files
|
|
||||||
mkdocs/venv
|
|
||||||
__pycache__/
|
|
||||||
|
|
|
||||||
12
DEPENDENCIES
12
DEPENDENCIES
|
|
@ -3,15 +3,9 @@
|
||||||
### included in repo
|
### included in repo
|
||||||
|
|
||||||
* libfuse: https://github.com/libfuse/libfuse (heavily modified fork of v2.x)
|
* libfuse: https://github.com/libfuse/libfuse (heavily modified fork of v2.x)
|
||||||
* rapidhash: https://github.com/Nicoshev/rapidhash
|
* wyhash: https://github.com/wangyi-fudan/wyhash
|
||||||
|
* ghc::filesystem: https://github.com/gulrak/filesystem
|
||||||
|
* nonstd::optional: https://github.com/martinmoene/optional-lite
|
||||||
* fmt: https://github.com/fmtlib/fmt
|
* fmt: https://github.com/fmtlib/fmt
|
||||||
* concurrentqueue: https://github.com/cameron314/concurrentqueue
|
* concurrentqueue: https://github.com/cameron314/concurrentqueue
|
||||||
* scope_guard: https://github.com/Neargye/scope_guard
|
* scope_guard: https://github.com/Neargye/scope_guard
|
||||||
* subprocess: https://github.com/arun11299/cpp-subprocess
|
|
||||||
* CLI11: https://github.com/CLIUtils/CLI11
|
|
||||||
* string-lite: https://github.com/martinmoene/string-lite
|
|
||||||
* boost
|
|
||||||
* download boost
|
|
||||||
* ./bootstrap.sh
|
|
||||||
* ./b2 tools/bcp
|
|
||||||
* ./dist/bin/bcp unordered/concurrent_flat_map.hpp <target_dir>
|
|
||||||
|
|
|
||||||
2
LICENSE
2
LICENSE
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
ISC License
|
ISC License
|
||||||
|
|
||||||
Copyright (c) 2026, Antonio SJ Musumeci <trapexit@spawn.link>
|
Copyright (c) 2024, Antonio SJ Musumeci <trapexit@spawn.link>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
|
|
||||||
389
Makefile
389
Makefile
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2025, Antonio SJ Musumeci <trapexit@spawn.link>
|
# Copyright (c) 2024, Antonio SJ Musumeci <trapexit@spawn.link>
|
||||||
#
|
#
|
||||||
# Permission to use, copy, modify, and/or distribute this software for any
|
# Permission to use, copy, modify, and/or distribute this software for any
|
||||||
# purpose with or without fee is hereby granted, provided that the above
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
|
@ -12,279 +12,197 @@
|
||||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
$(info mergerfs MAKEFLAGS: $(MAKEFLAGS))
|
GIT = git
|
||||||
|
TAR = tar
|
||||||
|
MKDIR = mkdir
|
||||||
|
TOUCH = touch
|
||||||
|
CP = cp
|
||||||
|
RM = rm
|
||||||
|
LN = ln
|
||||||
|
FIND = find
|
||||||
|
INSTALL = install
|
||||||
|
MKTEMP = mktemp
|
||||||
|
STRIP = strip
|
||||||
|
PANDOC = pandoc
|
||||||
|
SED = sed
|
||||||
|
RPMBUILD = rpmbuild
|
||||||
|
GIT2DEBCL = ./buildtools/git2debcl
|
||||||
|
PKGCONFIG = pkg-config
|
||||||
|
|
||||||
ifeq ($(shell id -u),0)
|
GIT_REPO = 0
|
||||||
FAKEROOT ?=
|
|
||||||
endif
|
|
||||||
|
|
||||||
CP ?= cp
|
|
||||||
FAKEROOT ?= fakeroot
|
|
||||||
FIND ?= find
|
|
||||||
GIT ?= git
|
|
||||||
GIT2DEBCL ?= buildtools/git2debcl
|
|
||||||
INSTALL ?= install
|
|
||||||
LN ?= ln
|
|
||||||
MKDIR ?= mkdir
|
|
||||||
MKTEMP ?= mktemp
|
|
||||||
MV ?= mv
|
|
||||||
RM ?= rm
|
|
||||||
RPMBUILD ?= rpmbuild
|
|
||||||
RPMBUILD_FLAGS ?=
|
|
||||||
SED ?= sed
|
|
||||||
STRIP ?= strip
|
|
||||||
TAR ?= tar
|
|
||||||
TOUCH ?= touch
|
|
||||||
|
|
||||||
BUILDDIR := build
|
|
||||||
GITHUB_REPO ?= "https://github.com/trapexit/mergerfs"
|
|
||||||
|
|
||||||
DEFAULT_TARGET := debian:13.amd64
|
|
||||||
|
|
||||||
ifndef GIT_REPO
|
|
||||||
ifneq ($(shell $(GIT) --version 2> /dev/null),)
|
ifneq ($(shell $(GIT) --version 2> /dev/null),)
|
||||||
ifeq ($(shell test -e .git; echo $$?),0)
|
ifeq ($(shell test -e .git; echo $$?),0)
|
||||||
GIT_REPO = 1
|
GIT_REPO = 1
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
|
||||||
|
|
||||||
USE_XATTR ?= 1
|
USE_XATTR = 1
|
||||||
|
UGID_USE_RWLOCK = 0
|
||||||
|
|
||||||
ifdef SANITIZE
|
ifeq ($(DEBUG),1)
|
||||||
ifeq ($(SANITIZE),1)
|
OPT_FLAGS := -O0 -g -fsanitize=undefined
|
||||||
override SANITIZE := -fsanitize=address,undefined,leak
|
|
||||||
else ifeq ($(filter -fsanitize=%,$(SANITIZE)),)
|
|
||||||
override SANITIZE := -fsanitize=$(SANITIZE)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
COMMON_OPT_FLAGS += \
|
|
||||||
-fstack-protector-strong \
|
|
||||||
-Wextra \
|
|
||||||
-Wno-unused-parameter
|
|
||||||
|
|
||||||
DEBUG_OPT_FLAGS += \
|
|
||||||
-O0 \
|
|
||||||
-g3 \
|
|
||||||
-fno-omit-frame-pointer \
|
|
||||||
$(SANITIZE)
|
|
||||||
|
|
||||||
ifdef RELEASE
|
|
||||||
OPT_FLAGS := -O3 $(COMMON_OPT_FLAGS)
|
|
||||||
else
|
else
|
||||||
OPT_FLAGS ?= $(DEBUG_OPT_FLAGS) $(COMMON_OPT_FLAGS)
|
OPT_FLAGS := -O2 -DNDEBUG
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef STATIC
|
ifeq ($(STATIC),1)
|
||||||
STATIC_FLAGS := -static
|
STATIC_FLAGS := -static
|
||||||
else
|
else
|
||||||
STATIC_FLAGS :=
|
STATIC_FLAGS :=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef LTO
|
ifeq ($(LTO),1)
|
||||||
LTO_FLAGS := -flto
|
LTO_FLAGS := -flto
|
||||||
else
|
else
|
||||||
LTO_FLAGS :=
|
LTO_FLAGS :=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SRC := $(wildcard src/*.cpp)
|
SRC = $(wildcard src/*.cpp)
|
||||||
OBJS := $(SRC:src/%.cpp=build/.objs/%.cpp.o)
|
OBJS = $(SRC:src/%.cpp=build/.src/%.o)
|
||||||
DEPS := $(SRC:src/%.cpp=build/.objs/%.cpp.d)
|
DEPS = $(SRC:src/%.cpp=build/.src/%.d)
|
||||||
|
|
||||||
TESTS := $(wildcard tests/*.cpp)
|
TESTS = $(wildcard tests/*.cpp)
|
||||||
TESTS_OBJS := $(filter-out build/.objs/mergerfs.cpp.o,$(OBJS))
|
TESTS_OBJS = $(filter-out build/.src/mergerfs.o,$(OBJS))
|
||||||
TESTS_OBJS += $(TESTS:tests/%.cpp=build/.test_objs/%.cpp.o)
|
TESTS_OBJS += $(TESTS:tests/%.cpp=build/.tests/%.o)
|
||||||
TESTS_DEPS := $(TESTS:tests/%.cpp=build/.test_objs/%.cpp.d)
|
TESTS_DEPS = $(TESTS:tests/%.cpp=build/.tests/%.d)
|
||||||
TESTS_DEPS += $(DEPS)
|
TESTS_DEPS += $(DEPS)
|
||||||
|
|
||||||
MANPAGE := mergerfs.1
|
MANPAGE = mergerfs.1
|
||||||
CPPFLAGS ?=
|
CFLAGS ?= ${OPT_FLAGS}
|
||||||
override CPPFLAGS += \
|
CFLAGS := ${CFLAGS} \
|
||||||
-D_FILE_OFFSET_BITS=64 \
|
-Wall \
|
||||||
-DBOOST_UNORDERED_DISABLE_PARALLEL_ALGORITHMS
|
-Wno-unused-result
|
||||||
CFLAGS ?= \
|
CXXFLAGS ?= ${OPT_FLAGS}
|
||||||
$(OPT_FLAGS) \
|
CXXFLAGS := \
|
||||||
-Wall \
|
${CXXFLAGS} \
|
||||||
-Wno-unused-result \
|
-std=c++11 \
|
||||||
-pipe
|
$(STATIC_FLAGS) \
|
||||||
override CFLAGS += \
|
$(LTO_FLAGS) \
|
||||||
-MMD \
|
-Wall \
|
||||||
-MP
|
-Wno-unused-result \
|
||||||
CXXFLAGS ?= \
|
-MMD
|
||||||
$(OPT_FLAGS) \
|
FUSE_FLAGS = \
|
||||||
$(STATIC_FLAGS) \
|
-Ilibfuse/include \
|
||||||
$(LTO_FLAGS) \
|
-D_FILE_OFFSET_BITS=64
|
||||||
-Wall \
|
MFS_FLAGS = \
|
||||||
-Wpessimizing-move \
|
-DUSE_XATTR=$(USE_XATTR) \
|
||||||
-Werror=pessimizing-move \
|
-DUGID_USE_RWLOCK=$(UGID_USE_RWLOCK)
|
||||||
-Wredundant-move \
|
TESTS_FLAGS = \
|
||||||
-Werror=redundant-move \
|
-Isrc \
|
||||||
-Wno-unused-result \
|
-DTESTS
|
||||||
-pipe
|
|
||||||
override CXXFLAGS += \
|
|
||||||
-std=c++20 \
|
|
||||||
-MMD \
|
|
||||||
-MP
|
|
||||||
override INC_FLAGS := \
|
|
||||||
-Isrc \
|
|
||||||
-Ivendored \
|
|
||||||
-Ivendored/libfuse/include
|
|
||||||
override MFS_FLAGS := \
|
|
||||||
-DUSE_XATTR=$(USE_XATTR)
|
|
||||||
override TESTS_FLAGS := \
|
|
||||||
-Isrc \
|
|
||||||
-Ivendored \
|
|
||||||
-Ivendored/acutest \
|
|
||||||
-DTESTS
|
|
||||||
|
|
||||||
LIBFUSE := vendored/libfuse/$(BUILDDIR)/libfuse.a
|
LDFLAGS := \
|
||||||
LDFLAGS ?=
|
${LDFLAGS} \
|
||||||
LDLIBS := \
|
-pthread \
|
||||||
-lrt \
|
-lrt
|
||||||
-pthread
|
|
||||||
override LDLIBS += \
|
|
||||||
$(LIBFUSE)
|
|
||||||
ifeq ($(CXX),g++)
|
|
||||||
GCC_VERSION := $(shell $(CXX) -dumpversion | cut -f1 -d.)
|
|
||||||
ifeq ($(shell test $(GCC_VERSION) -lt 9; echo $$?),0)
|
|
||||||
override LDLIBS += -lstdc++fs
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
# https://www.gnu.org/prep/standards/html_node/Directory-Variables.html
|
# https://www.gnu.org/prep/standards/html_node/Directory-Variables.html
|
||||||
DESTDIR ?=
|
DESTDIR =
|
||||||
PREFIX ?= /usr/local
|
PREFIX = /usr/local
|
||||||
EXEC_PREFIX ?= $(PREFIX)
|
EXEC_PREFIX = $(PREFIX)
|
||||||
DATAROOTDIR ?= $(PREFIX)/share
|
DATAROOTDIR = $(PREFIX)/share
|
||||||
DATADIR ?= $(DATAROOTDIR)
|
DATADIR = $(DATAROOTDIR)
|
||||||
BINDIR ?= $(EXEC_PREFIX)/bin
|
BINDIR = $(EXEC_PREFIX)/bin
|
||||||
SBINDIR ?= $(EXEC_PREFIX)/sbin
|
SBINDIR = $(EXEC_PREFIX)/sbin
|
||||||
LIBDIR ?= $(EXEC_PREFIX)/lib
|
LIBDIR = $(EXEC_PREFIX)/lib
|
||||||
MANDIR ?= $(DATAROOTDIR)/man
|
MANDIR = $(DATAROOTDIR)/man
|
||||||
MAN1DIR ?= $(MANDIR)/man1
|
MAN1DIR = $(MANDIR)/man1
|
||||||
|
|
||||||
INSTALLBINDIR ?= $(DESTDIR)$(BINDIR)
|
|
||||||
INSTALLSBINDIR ?= $(DESTDIR)$(SBINDIR)
|
|
||||||
INSTALLLIBDIR ?= $(DESTDIR)$(LIBDIR)/mergerfs
|
|
||||||
INSTALLMAN1DIR ?= $(DESTDIR)$(MAN1DIR)
|
|
||||||
|
|
||||||
|
INSTALLBINDIR = $(DESTDIR)$(BINDIR)
|
||||||
|
INSTALLSBINDIR = $(DESTDIR)$(SBINDIR)
|
||||||
|
INSTALLLIBDIR = $(DESTDIR)$(LIBDIR)/mergerfs
|
||||||
|
INSTALLMAN1DIR = $(DESTDIR)$(MAN1DIR)
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: libfuse $(BUILDDIR)/mergerfs $(BUILDDIR)/fsck.mergerfs $(BUILDDIR)/mergerfs.collect-info
|
all: mergerfs
|
||||||
|
|
||||||
.PHONY: help
|
.PHONY: help
|
||||||
help:
|
help:
|
||||||
@echo "usage: make ARG\n"
|
@echo "usage: make\n"
|
||||||
@echo "USE_XATTR=0 - build program without xattrs functionality"
|
@echo "make USE_XATTR=0 - build program without xattrs functionality"
|
||||||
@echo "STATIC=1 - build static binary"
|
@echo "make STATIC=1 - build static binary"
|
||||||
@echo "LTO=1 - build with link time optimization"
|
@echo "make LTO=1 - build with link time optimization"
|
||||||
@echo "SANITIZE=1 - build with sanitizers (address,undefined,leak)"
|
|
||||||
@echo "SANITIZE=list - build with custom sanitizers (comma separated)"
|
|
||||||
@echo "CLEANUP=1 - cleanup images between release build process"
|
|
||||||
@echo "PKGDIR=/dir/ - location for release build pkgs"
|
|
||||||
@echo "GITREF=gitref - gitref to use for release builds"
|
|
||||||
|
|
||||||
|
objects: version build/stamp
|
||||||
|
$(MAKE) $(OBJS)
|
||||||
|
|
||||||
$(BUILDDIR)/mergerfs: $(LIBFUSE) src/version.hpp $(OBJS)
|
tests-objects:
|
||||||
$(CXX) $(CXXFLAGS) $(INC_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) $(OBJS) -o $@ $(LDFLAGS) $(LDLIBS)
|
$(MAKE) $(TESTS_OBJS)
|
||||||
|
|
||||||
$(BUILDDIR)/fsck.mergerfs: $(BUILDDIR)/mergerfs
|
build/mergerfs: libfuse objects
|
||||||
$(LN) -sf "mergerfs" $@
|
$(CXX) $(CXXFLAGS) $(FUSE_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) $(OBJS) -o $@ libfuse/build/libfuse.a $(LDFLAGS)
|
||||||
|
|
||||||
$(BUILDDIR)/mergerfs.collect-info: $(BUILDDIR)/mergerfs
|
build/tests: build/mergerfs tests-objects
|
||||||
$(LN) -sf "mergerfs" $@
|
$(CXX) $(CXXFLAGS) $(TESTS_FLAGS) $(FUSE_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) $(TESTS_OBJS) -o $@ libfuse/build/libfuse.a $(LDFLAGS)
|
||||||
|
|
||||||
$(BUILDDIR)/tests: $(BUILDDIR)/mergerfs $(TESTS_OBJS)
|
mergerfs: build/mergerfs
|
||||||
$(CXX) $(CXXFLAGS) $(TESTS_FLAGS) $(INC_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) $(TESTS_OBJS) -o $@ $(LDFLAGS) $(LDLIBS)
|
|
||||||
|
|
||||||
.PHONY: libfuse
|
tests: build/tests
|
||||||
libfuse: $(LIBFUSE)
|
|
||||||
$(MAKE) -C vendored/libfuse
|
|
||||||
|
|
||||||
$(LIBFUSE):
|
|
||||||
$(MAKE) -C vendored/libfuse $(BUILDDIR)/libfuse.a RELEASE=$(RELEASE)
|
|
||||||
|
|
||||||
tests: $(BUILDDIR)/tests
|
|
||||||
|
|
||||||
.PHONY:
|
|
||||||
changelog:
|
changelog:
|
||||||
ifdef GIT_REPO
|
ifeq ($(GIT_REPO),1)
|
||||||
$(GIT2DEBCL) --name mergerfs > ChangeLog
|
$(GIT2DEBCL) --name mergerfs > ChangeLog
|
||||||
else
|
else
|
||||||
@echo "WARNING: need git repo to generate ChangeLog"
|
@echo "WARNING: need git repo to generate ChangeLog"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
.PHONY: version
|
.PHONY: version
|
||||||
version: src/version.hpp
|
version:
|
||||||
|
|
||||||
src/version.hpp:
|
|
||||||
./buildtools/update-version
|
./buildtools/update-version
|
||||||
|
|
||||||
$(BUILDDIR)/stamp:
|
build/stamp:
|
||||||
$(MKDIR) -p $(BUILDDIR)/.objs
|
$(MKDIR) -p build/.src build/.tests
|
||||||
$(MKDIR) -p $(BUILDDIR)/.test_objs
|
|
||||||
$(TOUCH) $@
|
$(TOUCH) $@
|
||||||
|
|
||||||
$(BUILDDIR)/.objs/%.cpp.o: src/%.cpp $(BUILDDIR)/stamp
|
build/.src/%.o: src/%.cpp
|
||||||
$(CXX) $(CXXFLAGS) $(INC_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) -c $< -o $@
|
$(CXX) $(CXXFLAGS) $(FUSE_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(BUILDDIR)/.test_objs/%.cpp.o: tests/%.cpp | $(BUILDDIR)/stamp
|
build/.tests/%.o: tests/%.cpp
|
||||||
$(CXX) $(CXXFLAGS) $(TESTS_FLAGS) $(INC_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) -c $< -o $@
|
$(CXX) $(CXXFLAGS) $(TESTS_FLAGS) $(FUSE_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(BUILDDIR)/preload.so: $(BUILDDIR)/stamp tools/preload.c
|
build/preload.so: build/stamp tools/preload.c
|
||||||
$(CC) -shared -fPIC $(CFLAGS) -o $@ tools/preload.c
|
$(CC) -shared -fPIC $(CFLAGS) $(CPPFLAGS) -o $@ tools/preload.c
|
||||||
|
|
||||||
preload: $(BUILDDIR)/preload.so
|
preload: build/preload.so
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean: rpm-clean
|
clean: rpm-clean
|
||||||
$(RM) -rf $(BUILDDIR)
|
$(RM) -rf build
|
||||||
$(FIND) . -name "*~" -delete
|
$(FIND) . -name "*~" -delete
|
||||||
$(MAKE) -C vendored/libfuse clean
|
$(MAKE) -C libfuse clean
|
||||||
|
|
||||||
.PHONY: distclean
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
ifdef GIT_REPO
|
ifeq ($(GIT_REPO),1)
|
||||||
$(GIT) clean -xfd
|
$(GIT) clean -xfd
|
||||||
endif
|
endif
|
||||||
|
|
||||||
.PHONY: install
|
.PHONY: install
|
||||||
install: install-base install-mount-tools install-preload install-man
|
install: install-base install-mount-tools install-preload install-man
|
||||||
|
|
||||||
.PHONY: install-base
|
install-base: build/mergerfs
|
||||||
install-base: all
|
|
||||||
$(MKDIR) -p "$(INSTALLBINDIR)"
|
$(MKDIR) -p "$(INSTALLBINDIR)"
|
||||||
$(INSTALL) -v -m 0755 "$(BUILDDIR)/mergerfs" "$(INSTALLBINDIR)/mergerfs"
|
$(INSTALL) -v -m 0755 build/mergerfs "$(INSTALLBINDIR)/mergerfs"
|
||||||
$(LN) -fs "mergerfs" "${INSTALLBINDIR}/fsck.mergerfs"
|
|
||||||
$(LN) -fs "mergerfs" "${INSTALLBINDIR}/mergerfs.collect-info"
|
|
||||||
|
|
||||||
.PHONY: install-mount-tools
|
|
||||||
install-mount-tools: install-base
|
install-mount-tools: install-base
|
||||||
$(MKDIR) -p "$(INSTALLBINDIR)"
|
$(MKDIR) -p "$(INSTALLBINDIR)"
|
||||||
$(MAKE) -C vendored/libfuse install
|
$(MAKE) -C libfuse install
|
||||||
|
|
||||||
.PHONY: install-man
|
install-man: $(MANPAGE)
|
||||||
install-man: man/$(MANPAGE)
|
|
||||||
$(MKDIR) -p "$(INSTALLMAN1DIR)"
|
$(MKDIR) -p "$(INSTALLMAN1DIR)"
|
||||||
$(INSTALL) -v -m 0644 "man/$(MANPAGE)" "$(INSTALLMAN1DIR)/$(MANPAGE)"
|
$(INSTALL) -v -m 0644 "man/$(MANPAGE)" "$(INSTALLMAN1DIR)/$(MANPAGE)"
|
||||||
|
|
||||||
.PHONY: install-preload
|
|
||||||
install-preload: preload
|
install-preload: preload
|
||||||
$(MKDIR) -p "$(INSTALLLIBDIR)"
|
$(MKDIR) -p "$(INSTALLLIBDIR)"
|
||||||
$(INSTALL) -v -m 444 "$(BUILDDIR)/preload.so" "$(INSTALLLIBDIR)/preload.so"
|
$(INSTALL) -v -m 444 "build/preload.so" "$(INSTALLLIBDIR)/preload.so"
|
||||||
|
|
||||||
.PHONY: install-strip
|
|
||||||
install-strip: install-base
|
install-strip: install-base
|
||||||
$(STRIP) "$(INSTALLBINDIR)/mergerfs"
|
$(STRIP) "$(INSTALLBINDIR)/mergerfs"
|
||||||
|
|
||||||
.PHONY: uninstall
|
.PHONY: uninstall
|
||||||
uninstall: uninstall-base uninstall-mount.mergerfs uninstall-preload uninstall-man
|
uninstall: uninstall-base uninstall-mount.mergerfs uninstall-man
|
||||||
|
|
||||||
uninstall-base:
|
uninstall-base:
|
||||||
$(RM) -f "$(INSTALLBINDIR)/mergerfs"
|
$(RM) -f "$(INSTALLBINDIR)/mergerfs"
|
||||||
$(RM) -f "$(INSTALLBINDIR)/fsck.mergerfs"
|
|
||||||
$(RM) -f "$(INSTALLBINDIR)/mergerfs.collect-info"
|
|
||||||
|
|
||||||
uninstall-mount.mergerfs:
|
uninstall-mount.mergerfs:
|
||||||
$(RM) -f "$(INSTALLBINDIR)/mount.mergerfs"
|
$(RM) -f "$(INSTALLBINDIR)/mount.mergerfs"
|
||||||
|
|
@ -292,11 +210,17 @@ uninstall-mount.mergerfs:
|
||||||
uninstall-man:
|
uninstall-man:
|
||||||
$(RM) -f "$(INSTALLMAN1DIR)/$(MANPAGE)"
|
$(RM) -f "$(INSTALLMAN1DIR)/$(MANPAGE)"
|
||||||
|
|
||||||
uninstall-preload:
|
$(MANPAGE): README.md
|
||||||
$(RM) -f "$(INSTALLLIBDIR)/preload.so"
|
ifneq ($(shell $(PANDOC) --version 2> /dev/null),)
|
||||||
|
$(PANDOC) -s -t man -o "man/$(MANPAGE)" README.md
|
||||||
|
else
|
||||||
|
$(warning "pandoc does not appear available: unable to build manpage")
|
||||||
|
endif
|
||||||
|
|
||||||
|
man: $(MANPAGE)
|
||||||
|
|
||||||
.PHONY: tarball
|
.PHONY: tarball
|
||||||
tarball: changelog version
|
tarball: man changelog version
|
||||||
$(eval VERSION := $(shell cat VERSION))
|
$(eval VERSION := $(shell cat VERSION))
|
||||||
$(eval VERSION := $(subst -,_,$(VERSION)))
|
$(eval VERSION := $(subst -,_,$(VERSION)))
|
||||||
$(eval FILENAME := mergerfs-$(VERSION))
|
$(eval FILENAME := mergerfs-$(VERSION))
|
||||||
|
|
@ -306,38 +230,29 @@ tarball: changelog version
|
||||||
$(TAR) --exclude=.git -cz -C $(TMPDIR) -f $(FILENAME).tar.gz $(FILENAME)
|
$(TAR) --exclude=.git -cz -C $(TMPDIR) -f $(FILENAME).tar.gz $(FILENAME)
|
||||||
$(RM) -rf $(TMPDIR)
|
$(RM) -rf $(TMPDIR)
|
||||||
|
|
||||||
.PHONY: debian-changelog
|
|
||||||
debian-changelog:
|
debian-changelog:
|
||||||
ifdef GIT_REPO
|
ifeq ($(GIT_REPO),1)
|
||||||
$(GIT2DEBCL) --name mergerfs > debian/changelog
|
$(GIT2DEBCL) --name mergerfs > debian/changelog
|
||||||
else
|
else
|
||||||
$(CP) -v ChangeLog debian/changelog
|
cp ChangeLog debian/changelog
|
||||||
$(eval DISTRO := $(shell lsb_release -i -s | tr '[:upper:]' '[:lower:]'))
|
|
||||||
$(eval CODENAME := $(shell lsb_release -c -s | tr '[:upper:]' '[:lower:]'))
|
|
||||||
sed -i 's/~unknown-unknown/~$(DISTRO)-$(CODENAME)/g' debian/changelog
|
|
||||||
sed -i 's/ unknown; / $(CODENAME); /g' debian/changelog
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
.PHONY: signed-deb
|
|
||||||
signed-deb:
|
signed-deb:
|
||||||
$(MAKE) distclean
|
$(MAKE) distclean
|
||||||
$(MAKE) debian-changelog
|
$(MAKE) debian-changelog
|
||||||
$(FAKEROOT) dpkg-buildpackage -nc
|
# dpkg-source -b .
|
||||||
|
dpkg-buildpackage -nc
|
||||||
|
|
||||||
.PHONY: deb
|
|
||||||
deb:
|
deb:
|
||||||
$(MAKE) distclean
|
$(MAKE) distclean
|
||||||
$(MAKE) debian-changelog
|
$(MAKE) debian-changelog
|
||||||
$(MAKE) version
|
# dpkg-source -b .
|
||||||
$(FAKEROOT) dpkg-buildpackage -nc -uc -us
|
dpkg-buildpackage -nc -uc -us
|
||||||
$(MKDIR) -p ./$(BUILDDIR)/pkgs/
|
|
||||||
$(MV) -v ../mergerfs*deb ./$(BUILDDIR)/pkgs/
|
|
||||||
|
|
||||||
.PHONY: rpm-clean
|
.PHONY: rpm-clean
|
||||||
rpm-clean:
|
rpm-clean:
|
||||||
$(RM) -rf rpmbuild
|
$(RM) -rf rpmbuild
|
||||||
|
|
||||||
.PHONY: rpm
|
|
||||||
rpm: tarball
|
rpm: tarball
|
||||||
$(eval VERSION := $(shell cat VERSION))
|
$(eval VERSION := $(shell cat VERSION))
|
||||||
$(eval VERSION := $(subst -,_,$(VERSION)))
|
$(eval VERSION := $(subst -,_,$(VERSION)))
|
||||||
|
|
@ -345,65 +260,15 @@ rpm: tarball
|
||||||
$(SED) 's/__VERSION__/$(VERSION)/g' mergerfs.spec > \
|
$(SED) 's/__VERSION__/$(VERSION)/g' mergerfs.spec > \
|
||||||
rpmbuild/SOURCES/mergerfs.spec
|
rpmbuild/SOURCES/mergerfs.spec
|
||||||
cp -ar mergerfs-$(VERSION).tar.gz rpmbuild/SOURCES
|
cp -ar mergerfs-$(VERSION).tar.gz rpmbuild/SOURCES
|
||||||
$(RPMBUILD) $(RPMBUILD_FLAGS) -ba rpmbuild/SOURCES/mergerfs.spec \
|
$(RPMBUILD) -ba rpmbuild/SOURCES/mergerfs.spec \
|
||||||
--define "_topdir $(CURDIR)/rpmbuild"
|
--define "_topdir $(CURDIR)/rpmbuild"
|
||||||
|
|
||||||
.PHONY: install-build-pkgs
|
.PHONY: install-build-pkgs
|
||||||
install-build-pkgs:
|
install-build-pkgs:
|
||||||
./buildtools/install-build-pkgs
|
./buildtools/install-build-pkgs
|
||||||
|
|
||||||
.PHONY: install-build-tools
|
.PHONY: libfuse
|
||||||
install-build-tools:
|
libfuse:
|
||||||
./buildtools/install-build-tools
|
$(MAKE) DEBUG=$(DEBUG) -C libfuse
|
||||||
|
|
||||||
define build_release
|
|
||||||
$(eval GITREF ?= $(shell git describe --exact-match --tags HEAD 2>/dev/null || git symbolic-ref --short HEAD 2>/dev/null || git rev-parse --short HEAD))
|
|
||||||
@echo "GITREF=$(GITREF)"
|
|
||||||
./buildtools/build-release \
|
|
||||||
--target=$(1) \
|
|
||||||
$(if $(CLEANUP),--cleanup) \
|
|
||||||
$(if $(PKGDIR),--pkgdirpath=$(PKGDIR)) \
|
|
||||||
--git-repo=$(if $(REMOTE_REPO),$(GITHUB_REPO),".") \
|
|
||||||
--branch=$(GITREF)
|
|
||||||
endef
|
|
||||||
|
|
||||||
.PHONY: release release-all
|
|
||||||
.PHONY: release-amd64 release-arm64 release-armhf release-riscv64
|
|
||||||
.PHONY: release-sample release-static release-tarball release-installer
|
|
||||||
release:
|
|
||||||
$(MAKE) RELEASE=1 CPPFLAGS="$(CPPFLAGS) -DNDEBUG" all
|
|
||||||
release-all:
|
|
||||||
$(call build_release,"all")
|
|
||||||
release-sample:
|
|
||||||
$(if $(TARGET),,$(eval TARGET := $(shell ./buildtools/detect-local-target 2>/dev/null)))
|
|
||||||
$(call build_release,$(if $(TARGET),$(TARGET),$(DEFAULT_TARGET)))
|
|
||||||
release-amd64:
|
|
||||||
$(call build_release,"amd64")
|
|
||||||
release-arm64:
|
|
||||||
$(call build_release,"arm64")
|
|
||||||
release-armhf:
|
|
||||||
$(call build_release,"armhf")
|
|
||||||
release-riscv64:
|
|
||||||
$(call build_release,"riscv64")
|
|
||||||
release-static:
|
|
||||||
$(call build_release,"static")
|
|
||||||
release-tarball:
|
|
||||||
$(call build_release,"tarball")
|
|
||||||
release-installer:
|
|
||||||
$(call build_release,"installer")
|
|
||||||
|
|
||||||
container:
|
|
||||||
$(eval GITREF ?= $(shell git describe --exact-match --tags HEAD 2>/dev/null || git symbolic-ref --short HEAD 2>/dev/null || git rev-parse --short HEAD))
|
|
||||||
@echo "GITREF=$(GITREF)"
|
|
||||||
./buildtools/build-containerimage "$(GITREF)"
|
|
||||||
|
|
||||||
.PHONY: tags
|
|
||||||
tags:
|
|
||||||
rm -fv TAGS
|
|
||||||
find . -name "*.c" -print | etags --append -
|
|
||||||
find . -name "*.h" -print | etags --append -
|
|
||||||
find . -name "*.cpp" -print | etags --append -
|
|
||||||
find . -name "*.hpp" -print | etags --append -
|
|
||||||
|
|
||||||
|
|
||||||
-include $(DEPS)
|
-include $(DEPS)
|
||||||
|
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
GIT_BRANCH="${1:-master}"
|
|
||||||
|
|
||||||
set -x
|
|
||||||
podman \
|
|
||||||
build \
|
|
||||||
--squash \
|
|
||||||
--no-cache \
|
|
||||||
--force-rm \
|
|
||||||
--build-arg="GIT_REPO=file:///mnt" \
|
|
||||||
--build-arg="BRANCH=${GIT_BRANCH}" \
|
|
||||||
-v "${PWD}":/mnt:ro \
|
|
||||||
-f "buildtools/containerimage/Containerfile" \
|
|
||||||
--tag "ghcr.io/trapexit/mergerfs:${GIT_BRANCH}" \
|
|
||||||
buildtools/
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
set -e
|
|
||||||
|
|
||||||
if [ -e /tmp/build-env ]; then
|
|
||||||
. /tmp/build-env
|
|
||||||
fi
|
|
||||||
|
|
||||||
rpmbuild_flags()
|
|
||||||
{
|
|
||||||
case "$(command -v "${CXX:-g++}")" in
|
|
||||||
/opt/rh/*)
|
|
||||||
printf '%s' '--undefine _annotated_build'
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ $# -ne 2 ]; then
|
|
||||||
echo "usage: $0 <branch> <git_repo>"
|
|
||||||
echo "argv: $@"
|
|
||||||
echo "argc: $#"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
GIT_REPO="${1}"
|
|
||||||
BRANCH="${2}"
|
|
||||||
BUILDDIR="/tmp/build"
|
|
||||||
|
|
||||||
echo "Clone source from ${GIT_REPO} to ${BUILDDIR}"
|
|
||||||
git \
|
|
||||||
clone \
|
|
||||||
--single-branch \
|
|
||||||
--branch="${BRANCH}" \
|
|
||||||
"${GIT_REPO}" \
|
|
||||||
"${BUILDDIR}"
|
|
||||||
|
|
||||||
cd "${BUILDDIR}"
|
|
||||||
|
|
||||||
git log HEAD^1..
|
|
||||||
|
|
||||||
mkdir "/build"
|
|
||||||
if [ -e /usr/bin/apt-get ]; then
|
|
||||||
make deb
|
|
||||||
elif [ -e /usr/bin/dnf ]; then
|
|
||||||
make RPMBUILD_FLAGS="$(rpmbuild_flags)" rpm
|
|
||||||
elif [ -e /usr/bin/yum ]; then
|
|
||||||
make RPMBUILD_FLAGS="$(rpmbuild_flags)" rpm
|
|
||||||
elif [ -e /sbin/apk ]; then
|
|
||||||
echo "NOT YET SUPPORTED"
|
|
||||||
exit 1
|
|
||||||
elif [ -e /usr/sbin/pkg ]; then
|
|
||||||
echo "NOT YET SUPPORTED"
|
|
||||||
exit 1
|
|
||||||
elif [ -e /usr/bin/pacman ]; then
|
|
||||||
make tarball
|
|
||||||
else
|
|
||||||
echo "NOT YET SUPPORTED"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Copy packages to host..."
|
|
||||||
if [ -e /usr/bin/pacman ]; then
|
|
||||||
find "${BUILDDIR}" \
|
|
||||||
-type f \
|
|
||||||
-name "*.tar.gz" \
|
|
||||||
-exec cp -v {} /build/ \;
|
|
||||||
else
|
|
||||||
find "${BUILDDIR}" \
|
|
||||||
-type f \
|
|
||||||
\( -name "*.deb" -or -name "*.rpm" \) \
|
|
||||||
-not -name "*dbgsym*" \
|
|
||||||
-not -name "*sym*" \
|
|
||||||
-not -name "*src.rpm" \
|
|
||||||
-exec cp -v {} /build/ \;
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
|
|
@ -1,178 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import argparse
|
|
||||||
import time
|
|
||||||
|
|
||||||
|
|
||||||
def build(git_repo,
|
|
||||||
branch,
|
|
||||||
containerfile,
|
|
||||||
pkgdirpath):
|
|
||||||
timestamp = time.time_ns()
|
|
||||||
args = ['podman',
|
|
||||||
'build',
|
|
||||||
'--pull=always',
|
|
||||||
'--force-rm']
|
|
||||||
if os.path.exists(git_repo):
|
|
||||||
git_repo = os.path.realpath(git_repo)
|
|
||||||
args += ['-v',f'{git_repo}:/tmp/mergerfs.git:ro:z']
|
|
||||||
args += ['--build-arg=GIT_REPO=file:///tmp/mergerfs.git']
|
|
||||||
else:
|
|
||||||
args += [f'--build-arg=GIT_REPO={git_repo}']
|
|
||||||
os.makedirs(pkgdirpath,exist_ok=True)
|
|
||||||
args += ['-v',f'{os.path.realpath(pkgdirpath)}:/pkgs:ro']
|
|
||||||
args += ['-o',pkgdirpath,
|
|
||||||
'-f',containerfile,
|
|
||||||
f'--build-arg=BRANCH={branch}',
|
|
||||||
f'--build-arg=BUILD_TIMESTAMP={timestamp}',
|
|
||||||
'buildtools/']
|
|
||||||
# TODO: Capture output and write to log
|
|
||||||
print(args)
|
|
||||||
rv = subprocess.run(args)
|
|
||||||
report_filepath = os.path.join(pkgdirpath,"build-report.txt")
|
|
||||||
with open(report_filepath,"a+") as f:
|
|
||||||
build = os.path.basename(containerfile)
|
|
||||||
f.write(build + ": ")
|
|
||||||
f.write(f"branch={branch}; ")
|
|
||||||
f.write(f"timestamp={timestamp}; ")
|
|
||||||
f.write("rv=")
|
|
||||||
if rv.returncode == 0:
|
|
||||||
f.write("success;")
|
|
||||||
else:
|
|
||||||
f.write("fail;")
|
|
||||||
f.write("\n")
|
|
||||||
|
|
||||||
|
|
||||||
def setup():
|
|
||||||
# Detect distribution
|
|
||||||
if os.path.exists('/usr/bin/apt-get'):
|
|
||||||
args = ['sudo',
|
|
||||||
'apt-get',
|
|
||||||
'install',
|
|
||||||
'-fy',
|
|
||||||
'qemu-user-static',
|
|
||||||
'qemu-user-binfmt']
|
|
||||||
elif os.path.exists('/usr/bin/pacman'):
|
|
||||||
args = ['sudo',
|
|
||||||
'pacman',
|
|
||||||
'-Sy',
|
|
||||||
'--noconfirm',
|
|
||||||
'qemu-user-static']
|
|
||||||
else:
|
|
||||||
print("Unsupported distribution for setup")
|
|
||||||
sys.exit(1)
|
|
||||||
print(args)
|
|
||||||
subprocess.run(args)
|
|
||||||
setup_binfmt()
|
|
||||||
|
|
||||||
|
|
||||||
def setup_binfmt():
|
|
||||||
"""Register qemu-user-static binfmt handlers (needed on Arch, etc.)."""
|
|
||||||
binfmt_conf = """\
|
|
||||||
:qemu-aarch64:M::\\x7fELF\\x02\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\xb7\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:/usr/bin/qemu-aarch64-static:F
|
|
||||||
:qemu-arm:M::\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x28\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:/usr/bin/qemu-arm-static:F
|
|
||||||
:qemu-armeb:M::\\x7fELF\\x01\\x02\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x28:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff:/usr/bin/qemu-armeb-static:F
|
|
||||||
:qemu-riscv64:M::\\x7fELF\\x02\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\xf3\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:/usr/bin/qemu-riscv64-static:F
|
|
||||||
:qemu-i386:M::\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x03\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:/usr/bin/qemu-i386-static:F
|
|
||||||
"""
|
|
||||||
conf_path = '/etc/binfmt.d/qemu-static.conf'
|
|
||||||
print(f"Writing {conf_path}")
|
|
||||||
try:
|
|
||||||
with open(conf_path, 'w') as f:
|
|
||||||
f.write(binfmt_conf)
|
|
||||||
except PermissionError:
|
|
||||||
print(f"Permission denied writing {conf_path}; trying with sudo...")
|
|
||||||
subprocess.run(['sudo', 'tee', conf_path],
|
|
||||||
input=binfmt_conf.encode(), check=True)
|
|
||||||
|
|
||||||
print("Restarting systemd-binfmt...")
|
|
||||||
subprocess.run(['sudo', 'systemctl', 'restart', 'systemd-binfmt'])
|
|
||||||
|
|
||||||
|
|
||||||
def podman_cleanup():
|
|
||||||
args = ['podman',
|
|
||||||
'system',
|
|
||||||
'prune',
|
|
||||||
'-af']
|
|
||||||
print(args)
|
|
||||||
subprocess.run(args)
|
|
||||||
|
|
||||||
|
|
||||||
def parse_args():
|
|
||||||
p = argparse.ArgumentParser()
|
|
||||||
p.add_argument('--target',
|
|
||||||
default='debian:13.amd64')
|
|
||||||
p.add_argument('--pkgdirpath',
|
|
||||||
default='build/pkgs/')
|
|
||||||
p.add_argument('--branch',
|
|
||||||
default='master')
|
|
||||||
p.add_argument('--setup',
|
|
||||||
required=False,
|
|
||||||
action='store_true')
|
|
||||||
p.add_argument('--cleanup',
|
|
||||||
required=False,
|
|
||||||
action='store_true')
|
|
||||||
p.add_argument('--git-repo',
|
|
||||||
required=False,
|
|
||||||
type=str)
|
|
||||||
|
|
||||||
return p.parse_args()
|
|
||||||
|
|
||||||
|
|
||||||
def should_skip(filename):
|
|
||||||
if filename.endswith('~'):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
args = parse_args()
|
|
||||||
print(args)
|
|
||||||
|
|
||||||
if args.setup:
|
|
||||||
setup()
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
if not args.git_repo:
|
|
||||||
print("error: the following arguments are required: --git-repo")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
containerfiles = []
|
|
||||||
basepath = 'buildtools/containerfiles'
|
|
||||||
if os.path.exists(f'{basepath}/{args.target}'):
|
|
||||||
containerfiles.append(f'{basepath}/{args.target}')
|
|
||||||
elif args.target == 'all':
|
|
||||||
for root,dirnames,filenames in os.walk(basepath):
|
|
||||||
filenames.sort()
|
|
||||||
for filename in filenames:
|
|
||||||
if should_skip(filename):
|
|
||||||
continue
|
|
||||||
containerfile = f'buildtools/containerfiles/{filename}'
|
|
||||||
containerfiles.append(containerfile)
|
|
||||||
else:
|
|
||||||
for root,dirnames,filenames in os.walk(basepath):
|
|
||||||
filenames.sort()
|
|
||||||
for filename in filenames:
|
|
||||||
if args.target not in filename:
|
|
||||||
continue
|
|
||||||
if should_skip(filename):
|
|
||||||
continue
|
|
||||||
containerfile = f'buildtools/containerfiles/{filename}'
|
|
||||||
containerfiles.append(containerfile)
|
|
||||||
|
|
||||||
for containerfile in containerfiles:
|
|
||||||
if args.cleanup:
|
|
||||||
podman_cleanup()
|
|
||||||
build(git_repo=args.git_repo,
|
|
||||||
branch=args.branch,
|
|
||||||
containerfile=containerfile,
|
|
||||||
pkgdirpath=args.pkgdirpath)
|
|
||||||
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=amd64 debian:11 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=arm64 debian:11 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=armhf debian:11 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=i386 debian:11 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=amd64 debian:12 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=arm64 debian:12 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=armhf debian:12 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=i386 debian:12 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=amd64 debian:13 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=arm64 debian:13 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=armhf debian:13 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=i386 debian:13 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=riscv64 debian:13 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=amd64 fedora:40 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=arm64 fedora:40 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=amd64 fedora:41 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=arm64 fedora:41 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=amd64 fedora:42 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=arm64 fedora:42 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=amd64 fedora:43 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=arm64 fedora:43 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=amd64 fedora:44 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=arm64 fedora:44 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=amd64 quay.io/rockylinux/rockylinux:10 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=arm64 quay.io/rockylinux/rockylinux:10 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=amd64 quay.io/rockylinux/rockylinux:8 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=arm64 quay.io/rockylinux/rockylinux:8 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=amd64 quay.io/rockylinux/rockylinux:9 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=arm64 quay.io/rockylinux/rockylinux:9 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
FROM --platform=linux/amd64 alpine:latest as build
|
|
||||||
COPY install-build-pkgs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN git clone --single-branch --branch="${BRANCH}" ${GIT_REPO} /tmp/mergerfs
|
|
||||||
WORKDIR /tmp/mergerfs
|
|
||||||
RUN make NDEBUG=1 LTO=1 STATIC=1 DESTDIR=/tmp -j$(nproc) install
|
|
||||||
RUN mkdir /build
|
|
||||||
RUN /tmp/usr/local/bin/mergerfs --version | head -n1 | cut -c 11- | tee /tmp/version
|
|
||||||
RUN tar cvfz /build/mergerfs-$(cat /tmp/version)-static-linux_amd64.tar.gz --directory=/tmp usr sbin
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
FROM --platform=linux/arm64 alpine:latest as build
|
|
||||||
COPY install-build-pkgs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN git clone --single-branch --branch="${BRANCH}" ${GIT_REPO} /tmp/mergerfs
|
|
||||||
WORKDIR /tmp/mergerfs
|
|
||||||
RUN make NDEBUG=1 LTO=1 STATIC=1 DESTDIR=/tmp -j$(nproc) install
|
|
||||||
RUN mkdir /build
|
|
||||||
RUN /tmp/usr/local/bin/mergerfs --version | head -n1 | cut -c 11- | tee /tmp/version
|
|
||||||
RUN tar cvfz /build/mergerfs-$(cat /tmp/version)-static-linux_arm64.tar.gz --directory=/tmp usr sbin
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
FROM --platform=linux/armhf alpine:latest as build
|
|
||||||
COPY install-build-pkgs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN git clone --single-branch --branch="${BRANCH}" ${GIT_REPO} /tmp/mergerfs
|
|
||||||
WORKDIR /tmp/mergerfs
|
|
||||||
RUN make NDEBUG=1 LTO=1 STATIC=1 DESTDIR=/tmp -j$(nproc) install
|
|
||||||
RUN mkdir /build
|
|
||||||
RUN /tmp/usr/local/bin/mergerfs --version | head -n1 | cut -c 11- | tee /tmp/version
|
|
||||||
RUN tar cvfz /build/mergerfs-$(cat /tmp/version)-static-linux_armhf.tar.gz --directory=/tmp usr sbin
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
FROM --platform=linux/i386 alpine:latest as build
|
|
||||||
COPY install-build-pkgs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN git clone --single-branch --branch="${BRANCH}" ${GIT_REPO} /tmp/mergerfs
|
|
||||||
WORKDIR /tmp/mergerfs
|
|
||||||
RUN make NDEBUG=1 LTO=1 STATIC=1 DESTDIR=/tmp -j$(nproc) install
|
|
||||||
RUN mkdir /build
|
|
||||||
RUN /tmp/usr/local/bin/mergerfs --version | head -n1 | cut -c 11- | tee /tmp/version
|
|
||||||
RUN tar cvfz /build/mergerfs-$(cat /tmp/version)-static-linux_i386.tar.gz --directory=/tmp usr sbin
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
FROM --platform=linux/amd64 ubuntu:latest as build
|
|
||||||
COPY install-build-pkgs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs && \
|
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get -qy --no-install-suggests --no-install-recommends install \
|
|
||||||
makeself
|
|
||||||
RUN mkdir -p /tmp/mergerfs/
|
|
||||||
RUN ls -lhd /pkgs
|
|
||||||
RUN cp -v /pkgs/*static*.gz /tmp/mergerfs/
|
|
||||||
RUN mkdir -p /build
|
|
||||||
RUN makeself /tmp/mergerfs/ /build/mergerfs-installer.run "mergerfs" echo "foo"
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
FROM --platform=linux/riscv64 alpine:latest as build
|
|
||||||
COPY install-build-pkgs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN git clone --single-branch --branch="${BRANCH}" ${GIT_REPO} /tmp/mergerfs
|
|
||||||
WORKDIR /tmp/mergerfs
|
|
||||||
RUN make NDEBUG=1 LTO=1 STATIC=1 DESTDIR=/tmp -j$(nproc) install
|
|
||||||
RUN mkdir /build
|
|
||||||
RUN /tmp/usr/local/bin/mergerfs --version | head -n1 | cut -c 11- | tee /tmp/version
|
|
||||||
RUN tar cvfz /build/mergerfs-$(cat /tmp/version)-static-linux_riscv64.tar.gz --directory=/tmp usr sbin
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
FROM alpine:latest as tarball
|
|
||||||
|
|
||||||
COPY install-build-pkgs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG BRANCH=master
|
|
||||||
ARG GIT_REPO
|
|
||||||
|
|
||||||
RUN git clone --single-branch "${GIT_REPO}" /tmp/mergerfs --branch="${BRANCH}"
|
|
||||||
RUN cd /tmp/mergerfs && make version tarball
|
|
||||||
|
|
||||||
RUN mkdir /build
|
|
||||||
RUN cp -v /tmp/mergerfs/*.tar.gz /build/
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=tarball /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=amd64 ubuntu:22.04 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=arm64 ubuntu:22.04 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=armhf ubuntu:22.04 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=riscv64 ubuntu:22.04 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=amd64 ubuntu:24.04 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=arm64 ubuntu:24.04 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=armhf ubuntu:24.04 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=riscv64 ubuntu:24.04 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=amd64 ubuntu:25.04 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=arm64 ubuntu:25.04 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=armhf ubuntu:25.04 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=riscv64 ubuntu:25.04 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=amd64 ubuntu:25.10 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=arm64 ubuntu:25.10 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=armhf ubuntu:25.10 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=riscv64 ubuntu:25.10 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=amd64 ubuntu:26.04 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=arm64 ubuntu:26.04 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=armhf ubuntu:26.04 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM --platform=riscv64 ubuntu:26.04 as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
FROM --platform=linux/amd64 alpine:latest as build
|
|
||||||
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
|
|
||||||
RUN <<EOF
|
|
||||||
apk add git gcc g++ make linux-headers
|
|
||||||
git clone --single-branch --branch="${BRANCH}" "${GIT_REPO}" /tmp/mergerfs
|
|
||||||
cd /tmp/mergerfs
|
|
||||||
make NDEBUG=1 LTO=1 STATIC=1 DESTDIR=/tmp/install -j$(nproc) install
|
|
||||||
tar cvfz /tmp/mergerfs.tgz --directory=/tmp/install usr sbin
|
|
||||||
EOF
|
|
||||||
|
|
||||||
FROM --platform=linux/amd64 alpine:latest
|
|
||||||
RUN --mount=from=build,source=/tmp/mergerfs.tgz,target=/tmp/mergerfs.tgz <<EOF
|
|
||||||
tar xvf /tmp/mergerfs.tgz -C /
|
|
||||||
EOF
|
|
||||||
ENTRYPOINT ["/usr/local/bin/mergerfs"]
|
|
||||||
CMD ["--help"]
|
|
||||||
|
|
@ -1,119 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# Detects local OS and maps to containerfiles target
|
|
||||||
# Returns target if found in buildtools/containerfiles/, empty string otherwise
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
CONTAINERFILES_DIR="buildtools/containerfiles"
|
|
||||||
|
|
||||||
# Detect system architecture and map to containerfiles format
|
|
||||||
detect_arch() {
|
|
||||||
local arch
|
|
||||||
arch=$(uname -m)
|
|
||||||
case "$arch" in
|
|
||||||
x86_64) echo "amd64" ;;
|
|
||||||
aarch64) echo "arm64" ;;
|
|
||||||
armv7l) echo "armhf" ;;
|
|
||||||
i686|i386) echo "i386" ;;
|
|
||||||
riscv64) echo "riscv64" ;;
|
|
||||||
*) echo "" ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Detect distro and version from os-release
|
|
||||||
detect_distro() {
|
|
||||||
local os_release="${1:-}"
|
|
||||||
if [[ ! -r "$os_release" ]]; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Source the file safely - ID and VERSION_ID are environment variables
|
|
||||||
. "$os_release"
|
|
||||||
|
|
||||||
local distro="$ID"
|
|
||||||
local version="$VERSION_ID"
|
|
||||||
|
|
||||||
# Map distro ID to containerfiles naming convention
|
|
||||||
case "$distro" in
|
|
||||||
ubuntu|debian|fedora) ;;
|
|
||||||
rocky|rhel|centos|almalinux) distro="rockylinux" ;;
|
|
||||||
*)
|
|
||||||
# Fallback to ID_LIKE for derivatives
|
|
||||||
if [[ -n "${ID_LIKE:-}" ]]; then
|
|
||||||
case "$ID_LIKE" in
|
|
||||||
*ubuntu*) distro="ubuntu" ;;
|
|
||||||
*debian*) distro="debian" ;;
|
|
||||||
*fedora*) distro="fedora" ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Only return if we have valid distro and version
|
|
||||||
if [[ -n "$distro" && -n "$version" ]]; then
|
|
||||||
echo "$distro:$version"
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Try to find a matching containerfile target
|
|
||||||
find_containerfile() {
|
|
||||||
local target="$1"
|
|
||||||
local containerfile="${CONTAINERFILES_DIR}/${target}"
|
|
||||||
|
|
||||||
# Direct match
|
|
||||||
if [[ -d "$containerfile" || -f "$containerfile" ]]; then
|
|
||||||
echo "$target"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main detection logic
|
|
||||||
main() {
|
|
||||||
local arch
|
|
||||||
|
|
||||||
# Detect architecture
|
|
||||||
arch=$(detect_arch)
|
|
||||||
if [[ -z "$arch" ]]; then
|
|
||||||
echo "WARNING: Could not detect system architecture" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Try to detect distro from multiple locations
|
|
||||||
local distro_ver
|
|
||||||
distro_ver=$(detect_distro "/etc/os-release") || \
|
|
||||||
distro_ver=$(detect_distro "/usr/lib/os-release") || {
|
|
||||||
echo "WARNING: Could not detect distro from os-release" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Build target string
|
|
||||||
local target="${distro_ver}.${arch}"
|
|
||||||
|
|
||||||
# Try to find matching containerfile
|
|
||||||
if find_containerfile "$target"; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Try with partial version matching (e.g., 25.10 → 25)
|
|
||||||
local distro="${distro_ver%%:*}"
|
|
||||||
local version="${distro_ver##*:}"
|
|
||||||
|
|
||||||
# Strip last minor version number and try again
|
|
||||||
local short_version="${version%.*}"
|
|
||||||
if [[ -n "$short_version" ]]; then
|
|
||||||
target="${distro}:${short_version}.${arch}"
|
|
||||||
if find_containerfile "$target"; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# No match found
|
|
||||||
echo "WARNING: No containerfile found for target: ${distro_ver}.${arch}" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
input_file="${1}"
|
|
||||||
|
|
||||||
while IFS= read -r line || [ -n "$line" ]; do
|
|
||||||
# Skip empty lines
|
|
||||||
if [ -z "$line" ]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
image=$(echo "$line" | cut -d' ' -f1)
|
|
||||||
platform=$(echo "$line" | cut -d' ' -f2-)
|
|
||||||
|
|
||||||
echo "${image} ${platform}"
|
|
||||||
cat <<EOF > "containerfiles/${image##*/}.${platform}"
|
|
||||||
FROM --platform=${platform} ${image} as build
|
|
||||||
COPY install-build-pkgs build-mergerfs /tmp/
|
|
||||||
RUN /tmp/install-build-pkgs
|
|
||||||
ARG BUILD_TIMESTAMP=0
|
|
||||||
ARG GIT_REPO
|
|
||||||
ARG BRANCH
|
|
||||||
RUN /tmp/build-mergerfs \$GIT_REPO \$BRANCH
|
|
||||||
|
|
||||||
FROM scratch
|
|
||||||
COPY --from=build /build/ /
|
|
||||||
EOF
|
|
||||||
done < "$input_file"
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/sh
|
#!/usr/bin/env python
|
||||||
|
|
||||||
# Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
|
# Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
|
||||||
|
|
||||||
|
|
@ -14,189 +14,99 @@
|
||||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
# Default values
|
import sys
|
||||||
NAME=""
|
import subprocess
|
||||||
VERSION="::guess::"
|
import argparse
|
||||||
DISTRO="::guess::"
|
|
||||||
CODENAME="::guess::"
|
|
||||||
URGENCY="medium"
|
|
||||||
|
|
||||||
# Function to display usage
|
def call(args):
|
||||||
usage() {
|
return subprocess.Popen(args,stdout=subprocess.PIPE).communicate()[0].decode()
|
||||||
cat << EOF
|
|
||||||
Usage: $0 --name NAME [OPTIONS]
|
|
||||||
|
|
||||||
Generated debian/changelog from git log
|
def git_tags():
|
||||||
|
args = ["git", "tag", '-l']
|
||||||
|
tags = call(args)
|
||||||
|
tags = [[int(X) for X in tag.split(".")] for tag in tags.split()]
|
||||||
|
tags.sort()
|
||||||
|
tags.reverse()
|
||||||
|
tags = [".".join([str(X) for X in tag]) for tag in tags]
|
||||||
|
return tags
|
||||||
|
|
||||||
Options:
|
def git_log(fromtag,totag):
|
||||||
--name NAME Name of package (required)
|
args = ['git','log','--no-merges','--oneline',fromtag+'...'+totag]
|
||||||
--version VERSION Place in git history to include upto (default: ::guess::)
|
return call(args).strip().split('\n')
|
||||||
--distro DISTRO Distribution name (default: ::guess::)
|
|
||||||
--codename NAME Distribution codename (default: ::guess::)
|
|
||||||
--urgency URGENCY Urgency (default: medium)
|
|
||||||
-h, --help Show this help message
|
|
||||||
EOF
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse command line arguments
|
def git_author_and_time(tag):
|
||||||
while [ $# -gt 0 ]; do
|
args = ['git','log','-1','--format=-- %an <%ae> %cD',tag]
|
||||||
case "$1" in
|
return call(args).strip()
|
||||||
--name)
|
|
||||||
NAME="$2"
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
--version)
|
|
||||||
VERSION="$2"
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
--distro)
|
|
||||||
DISTRO="$2"
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
--codename)
|
|
||||||
CODENAME="$2"
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
--urgency)
|
|
||||||
URGENCY="$2"
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
-h|--help)
|
|
||||||
usage
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Unknown option: $1" >&2
|
|
||||||
usage
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
# Check required arguments
|
def git_version():
|
||||||
if [ -z "$NAME" ]; then
|
args = ['git','describe','--always','--tags','--dirty']
|
||||||
echo "Error: --name is required" >&2
|
return call(args).strip()
|
||||||
usage
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Function to get git tags sorted in reverse order
|
def guess_distro():
|
||||||
git_tags() {
|
try:
|
||||||
git tag -l | sort -rV
|
args = ['lsb_release','-i','-s']
|
||||||
}
|
return call(args).strip().lower()
|
||||||
|
except:
|
||||||
|
return 'unknown'
|
||||||
|
|
||||||
# Function to get git log between two tags
|
|
||||||
git_log() {
|
|
||||||
local fromtag="$1"
|
|
||||||
local totag="$2"
|
|
||||||
git log --no-merges --oneline "${fromtag}...${totag}" 2>/dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to get author and time for a tag
|
def guess_codename():
|
||||||
git_author_and_time() {
|
try:
|
||||||
local tag="$1"
|
args = ['lsb_release','-c','-s']
|
||||||
git log -1 --format="-- %an <%ae> %cD" "$tag"
|
return call(args).strip().lower()
|
||||||
}
|
except:
|
||||||
|
return 'unknown'
|
||||||
|
|
||||||
# Function to get git version
|
|
||||||
git_version() {
|
|
||||||
git describe --always --tags --dirty 2>/dev/null || echo "unknown"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to guess distribution
|
def main():
|
||||||
guess_distro() {
|
parser = argparse.ArgumentParser(description='Generated debian/changelog from git log')
|
||||||
if command -v lsb_release >/dev/null 2>&1; then
|
parser.add_argument('--name',type=str,help='Name of package',required=True)
|
||||||
lsb_release -i -s 2>/dev/null | tr '[:upper:]' '[:lower:]'
|
parser.add_argument('--version',type=str,help='Place in git history to include upto',default='::guess::')
|
||||||
else
|
parser.add_argument('--distro',type=str,help='Distribution name',default='::guess::')
|
||||||
echo "unknown"
|
parser.add_argument('--codename',type=str,help='Distribution codename',default='::guess::')
|
||||||
fi
|
parser.add_argument('--urgency',type=str,help='Urgency',default='medium')
|
||||||
}
|
|
||||||
|
|
||||||
# Function to guess codename
|
args = parser.parse_args()
|
||||||
guess_codename() {
|
|
||||||
if command -v lsb_release >/dev/null 2>&1; then
|
|
||||||
lsb_release -c -s 2>/dev/null | tr '[:upper:]' '[:lower:]'
|
|
||||||
else
|
|
||||||
echo "unknown"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Handle guessing of values
|
if args.distro == '::guess::':
|
||||||
if [ "$DISTRO" = "::guess::" ]; then
|
args.distro = guess_distro()
|
||||||
DISTRO=$(guess_distro)
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$CODENAME" = "::guess::" ]; then
|
if args.codename == '::guess::':
|
||||||
CODENAME=$(guess_codename)
|
args.codename = guess_codename()
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$VERSION" = "::guess::" ]; then
|
versuffix = "~"+args.distro+"-"+args.codename
|
||||||
VERSION=$(git_version)
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Version suffix
|
if args.version == '::guess::':
|
||||||
VERSUFFIX="~${DISTRO}-${CODENAME}"
|
args.version = git_version()
|
||||||
|
|
||||||
# Get all tags
|
tags = git_tags()
|
||||||
TAGS=$(git_tags)
|
if args.version in tags:
|
||||||
|
idx = tags.index(args.version)
|
||||||
|
tags = tags[idx:]
|
||||||
|
tags = list(zip(tags,tags))
|
||||||
|
else:
|
||||||
|
tags = list(zip(tags,tags))
|
||||||
|
tags.insert(0,(args.version,'HEAD'))
|
||||||
|
|
||||||
# Create temporary file for tag pairs
|
for i in range(0,len(tags)):
|
||||||
TMPFILE=$(mktemp)
|
tags[i] = (tags[i][0] + versuffix,tags[i][1])
|
||||||
trap 'rm -f "$TMPFILE"' EXIT
|
|
||||||
|
|
||||||
# Check if version is in tags
|
tag = tags[0]
|
||||||
if echo "$TAGS" | grep -q "^${VERSION}$"; then
|
for prev in tags[1:]:
|
||||||
# If version is a tag, start from that tag
|
lines = git_log(tag[1],prev[1])
|
||||||
echo "$TAGS" | awk -v ver="$VERSION" 'BEGIN{found=0} {if($0==ver)found=1; if(found)print}' > "$TMPFILE"
|
if lines == ['']:
|
||||||
else
|
tag = prev
|
||||||
# If version is not a tag, use HEAD as starting point
|
|
||||||
echo "$VERSION HEAD" > "$TMPFILE"
|
|
||||||
echo "$TAGS" >> "$TMPFILE"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Process tags and generate changelog
|
|
||||||
PREV_TAG=""
|
|
||||||
PREV_REF=""
|
|
||||||
FIRST=1
|
|
||||||
|
|
||||||
while IFS= read -r line; do
|
|
||||||
if [ -z "$line" ]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Handle the special case of VERSION HEAD
|
|
||||||
if [ "$line" = "$VERSION HEAD" ]; then
|
|
||||||
TAG="$VERSION"
|
|
||||||
REF="HEAD"
|
|
||||||
else
|
|
||||||
TAG="$line"
|
|
||||||
REF="$line"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$PREV_TAG" ]; then
|
|
||||||
# Get log entries between current and previous tag
|
|
||||||
LOG_ENTRIES=$(git_log "$REF" "$PREV_REF")
|
|
||||||
|
|
||||||
# Skip if no changes
|
|
||||||
if [ -z "$LOG_ENTRIES" ] || [ "$LOG_ENTRIES" = "" ]; then
|
|
||||||
PREV_TAG="$TAG"
|
|
||||||
PREV_REF="$REF"
|
|
||||||
continue
|
continue
|
||||||
fi
|
|
||||||
|
|
||||||
# Print package header
|
print('{0} ({1}) {2}; urgency={3}\n'.format(args.name,tag[0],args.codename,args.urgency))
|
||||||
printf "%s (%s%s) %s; urgency=%s\n\n" "$NAME" "$PREV_TAG" "$VERSUFFIX" "$CODENAME" "$URGENCY"
|
|
||||||
|
|
||||||
# Print each log entry
|
for line in lines:
|
||||||
echo "$LOG_ENTRIES" | while IFS= read -r entry; do
|
print(" * " + line)
|
||||||
if [ -n "$entry" ]; then
|
|
||||||
printf " * %s\n" "$entry"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Print author and time
|
authorandtime = git_author_and_time(tag[1])
|
||||||
AUTHOR_TIME=$(git_author_and_time "$PREV_REF")
|
print(' {0}\n'.format(authorandtime))
|
||||||
printf "\n %s\n\n" "$AUTHOR_TIME"
|
|
||||||
fi
|
|
||||||
|
|
||||||
PREV_TAG="$TAG"
|
tag = prev
|
||||||
PREV_REF="$REF"
|
|
||||||
done < "$TMPFILE"
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
|
||||||
|
|
@ -1,162 +1,46 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
BUILD_ENV=/tmp/build-env
|
|
||||||
|
|
||||||
write_gcc_env()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
printf 'export CC=%s\n' "$1"
|
|
||||||
printf 'export CXX=%s\n' "$2"
|
|
||||||
} > "$BUILD_ENV"
|
|
||||||
}
|
|
||||||
|
|
||||||
write_toolset_env()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
printf '. %s\n' "$1"
|
|
||||||
printf 'export CC=gcc\n'
|
|
||||||
printf 'export CXX=g++\n'
|
|
||||||
} > "$BUILD_ENV"
|
|
||||||
}
|
|
||||||
|
|
||||||
latest_apt_gxx()
|
|
||||||
{
|
|
||||||
apt-cache --names-only search '^g[+][+]-[0-9]' \
|
|
||||||
| sed -n 's/^\(g++-[0-9][0-9]*\) .*/\1/p' \
|
|
||||||
| sort -t- -k2,2V \
|
|
||||||
| tail -n 1
|
|
||||||
}
|
|
||||||
|
|
||||||
latest_dnf_toolset()
|
|
||||||
{
|
|
||||||
dnf -q list --showduplicates 'gcc-toolset-*-gcc-c++' 2>/dev/null \
|
|
||||||
| sed -n 's/^gcc-toolset-\([0-9][0-9]*\)-gcc-c++\..*/\1/p' \
|
|
||||||
| sort -V \
|
|
||||||
| tail -n 1
|
|
||||||
}
|
|
||||||
|
|
||||||
latest_yum_toolset()
|
|
||||||
{
|
|
||||||
yum -q list available 'devtoolset-*-gcc-c++' 2>/dev/null \
|
|
||||||
| sed -n 's/^devtoolset-\([0-9][0-9]*\)-gcc-c++\..*/\1/p' \
|
|
||||||
| sort -V \
|
|
||||||
| tail -n 1
|
|
||||||
}
|
|
||||||
|
|
||||||
version_gt()
|
|
||||||
{
|
|
||||||
highest="$(printf '%s\n%s\n' "$1" "$2" | sort -V | tail -n 1)"
|
|
||||||
[ "$highest" = "$1" ] && [ "$1" != "$2" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
check_cxx20()
|
|
||||||
{
|
|
||||||
cxx="${CXX:-g++}"
|
|
||||||
test_src=/tmp/mergerfs-cxx20-check.cpp
|
|
||||||
test_bin=/tmp/mergerfs-cxx20-check
|
|
||||||
|
|
||||||
cat > "$test_src" <<'EOF'
|
|
||||||
template <typename T>
|
|
||||||
concept Incrementable = requires(T value) { value + 1; };
|
|
||||||
|
|
||||||
static_assert(Incrementable<int>);
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
if ! "$cxx" -std=c++20 "$test_src" -o "$test_bin" >/dev/null 2>&1; then
|
|
||||||
echo "error: $cxx does not support C++20" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -f "$test_src" "$test_bin"
|
|
||||||
}
|
|
||||||
|
|
||||||
: > "$BUILD_ENV"
|
|
||||||
|
|
||||||
if [ -e /usr/bin/apt-get ]; then
|
if [ -e /usr/bin/apt-get ]; then
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
apt-get -qy update
|
apt-get -qy update
|
||||||
cxx_pkg="$(latest_apt_gxx)"
|
|
||||||
if [ -n "$cxx_pkg" ]; then
|
|
||||||
gcc_pkg="gcc-${cxx_pkg#g++-}"
|
|
||||||
compiler_pkgs="$gcc_pkg $cxx_pkg"
|
|
||||||
write_gcc_env "$gcc_pkg" "$cxx_pkg"
|
|
||||||
else
|
|
||||||
compiler_pkgs="g++"
|
|
||||||
write_gcc_env gcc g++
|
|
||||||
fi
|
|
||||||
apt-get -qy --force-yes --no-install-suggests --no-install-recommends \
|
apt-get -qy --force-yes --no-install-suggests --no-install-recommends \
|
||||||
install \
|
install \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
build-essential \
|
build-essential \
|
||||||
dpkg-dev \
|
|
||||||
git \
|
git \
|
||||||
$compiler_pkgs \
|
g++ \
|
||||||
debhelper \
|
debhelper \
|
||||||
lsb-release \
|
automake \
|
||||||
fakeroot
|
fakeroot \
|
||||||
. "$BUILD_ENV"
|
libtool \
|
||||||
check_cxx20
|
lsb-release
|
||||||
|
apt-get -qy --no-install-suggests --no-install-recommends install python
|
||||||
|
apt-get -qy --no-install-suggests --no-install-recommends install python3
|
||||||
elif [ -e /usr/bin/dnf ]; then
|
elif [ -e /usr/bin/dnf ]; then
|
||||||
dnf -y update
|
dnf -y update
|
||||||
toolset="$(latest_dnf_toolset)"
|
|
||||||
dnf -y install \
|
dnf -y install \
|
||||||
git rpm-build gcc-c++ make which libatomic
|
git rpm-build gcc-c++ make which python3 automake \
|
||||||
default_gxx_major="$(g++ -dumpversion | cut -f1 -d.)"
|
libtool gettext-devel
|
||||||
if [ -n "$toolset" ] && version_gt "$toolset" "$default_gxx_major"; then
|
|
||||||
dnf -y install \
|
|
||||||
"gcc-toolset-${toolset}-gcc" \
|
|
||||||
"gcc-toolset-${toolset}-gcc-c++"
|
|
||||||
write_toolset_env "/opt/rh/gcc-toolset-${toolset}/enable"
|
|
||||||
else
|
|
||||||
write_gcc_env gcc g++
|
|
||||||
fi
|
|
||||||
. "$BUILD_ENV"
|
|
||||||
check_cxx20
|
|
||||||
elif [ -e /usr/bin/yum ]; then
|
elif [ -e /usr/bin/yum ]; then
|
||||||
yum -y update
|
yum -y update
|
||||||
yum -y install \
|
yum -y install \
|
||||||
git rpm-build gcc-c++ make which
|
git rpm-build gcc-c++ make which \
|
||||||
yum -y install centos-release-scl || true
|
python python-argparse \
|
||||||
yum -y update
|
automake libtool gettext-devel
|
||||||
toolset="$(latest_yum_toolset)"
|
|
||||||
default_gxx_major="$(g++ -dumpversion | cut -f1 -d.)"
|
|
||||||
if [ -n "$toolset" ] && version_gt "$toolset" "$default_gxx_major"; then
|
|
||||||
yum -y install \
|
|
||||||
"devtoolset-${toolset}-gcc" \
|
|
||||||
"devtoolset-${toolset}-gcc-c++"
|
|
||||||
write_toolset_env "/opt/rh/devtoolset-${toolset}/enable"
|
|
||||||
else
|
|
||||||
write_gcc_env gcc g++
|
|
||||||
fi
|
|
||||||
. "$BUILD_ENV"
|
|
||||||
check_cxx20
|
|
||||||
elif [ -e /usr/bin/zypper ]; then
|
|
||||||
zypper update -y
|
|
||||||
zypper install -y \
|
|
||||||
git rpm-build gcc-c++ make which
|
|
||||||
write_gcc_env gcc g++
|
|
||||||
. "$BUILD_ENV"
|
|
||||||
check_cxx20
|
|
||||||
elif [ -e /sbin/apk ]; then
|
elif [ -e /sbin/apk ]; then
|
||||||
apk add \
|
apk add \
|
||||||
abuild git gcc g++ make \
|
abuild git gcc g++ make autoconf \
|
||||||
linux-headers
|
automake libtool gettext-dev linux-headers
|
||||||
write_gcc_env gcc g++
|
|
||||||
. "$BUILD_ENV"
|
|
||||||
check_cxx20
|
|
||||||
elif [ -e /usr/sbin/pkg ]; then
|
elif [ -e /usr/sbin/pkg ]; then
|
||||||
pkg install \
|
pkg install \
|
||||||
git gmake gcc
|
git gmake gcc autoconf automake libtool \
|
||||||
elif [ -e /usr/bin/pacman ]; then
|
gettext-tools
|
||||||
pacman -Sy --noconfirm base-devel git fakeroot
|
fi
|
||||||
write_gcc_env gcc g++
|
|
||||||
. "$BUILD_ENV"
|
if [ ! -e /usr/bin/python ]; then
|
||||||
check_cxx20
|
if [ -e /usr/bin/python3 ]; then
|
||||||
|
ln -s /usr/bin/python3 /usr/bin/python
|
||||||
|
elif [ -e /usr/bin/python2 ]; then
|
||||||
|
ln -s /usr/bin/python2 /usr/bin/python
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
if [ "$(id -u)" -eq 0 ]; then
|
|
||||||
SUDO=
|
|
||||||
elif command -v sudo >/dev/null 2>&1; then
|
|
||||||
SUDO=sudo
|
|
||||||
elif command -v doas >/dev/null 2>&1; then
|
|
||||||
SUDO=doas
|
|
||||||
else
|
|
||||||
printf '%s\n' "error: need root privileges; run as root or install sudo/doas" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -e /usr/bin/apt-get ]; then
|
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
|
||||||
${SUDO} apt-get -qy update
|
|
||||||
${SUDO} apt-get -qy --no-install-suggests --no-install-recommends install \
|
|
||||||
qemu-user-static \
|
|
||||||
podman
|
|
||||||
elif [ -e /usr/bin/dnf ]; then
|
|
||||||
${SUDO} dnf -y update
|
|
||||||
${SUDO} dnf -y install \
|
|
||||||
qemu-user-static \
|
|
||||||
podman
|
|
||||||
elif [ -e /sbin/apk ]; then
|
|
||||||
${SUDO} apk add \
|
|
||||||
python3 \
|
|
||||||
qemu-user-static \
|
|
||||||
podman
|
|
||||||
elif [ -e /usr/bin/pacman ]; then
|
|
||||||
${SUDO} pacman -Sy --noconfirm qemu-user-static podman
|
|
||||||
fi
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
debian:11 amd64
|
|
||||||
debian:11 arm64
|
|
||||||
debian:11 armhf
|
|
||||||
debian:11 i386
|
|
||||||
debian:12 amd64
|
|
||||||
debian:12 arm64
|
|
||||||
debian:12 armhf
|
|
||||||
debian:12 i386
|
|
||||||
debian:13 amd64
|
|
||||||
debian:13 arm64
|
|
||||||
debian:13 armhf
|
|
||||||
debian:13 i386
|
|
||||||
debian:13 riscv64
|
|
||||||
fedora:40 amd64
|
|
||||||
fedora:40 arm64
|
|
||||||
fedora:41 amd64
|
|
||||||
fedora:41 arm64
|
|
||||||
fedora:42 amd64
|
|
||||||
fedora:42 arm64
|
|
||||||
fedora:43 amd64
|
|
||||||
fedora:43 arm64
|
|
||||||
quay.io/rockylinux/rockylinux:10 amd64
|
|
||||||
quay.io/rockylinux/rockylinux:10 arm64
|
|
||||||
quay.io/rockylinux/rockylinux:8 amd64
|
|
||||||
quay.io/rockylinux/rockylinux:8 arm64
|
|
||||||
quay.io/rockylinux/rockylinux:9 amd64
|
|
||||||
quay.io/rockylinux/rockylinux:9 arm64
|
|
||||||
ubuntu:22.04 amd64
|
|
||||||
ubuntu:22.04 arm64
|
|
||||||
ubuntu:22.04 armhf
|
|
||||||
ubuntu:22.04 riscv64
|
|
||||||
ubuntu:24.04 amd64
|
|
||||||
ubuntu:24.04 arm64
|
|
||||||
ubuntu:24.04 armhf
|
|
||||||
ubuntu:24.04 riscv64
|
|
||||||
ubuntu:25.04 amd64
|
|
||||||
ubuntu:25.04 arm64
|
|
||||||
ubuntu:25.04 armhf
|
|
||||||
ubuntu:25.04 riscv64
|
|
||||||
|
|
@ -9,12 +9,10 @@ if [ "${VERSION}" = "" ]; then
|
||||||
VERSION="unknown"
|
VERSION="unknown"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "version = ${VERSION}"
|
|
||||||
echo -n "${VERSION}" > VERSION
|
echo -n "${VERSION}" > VERSION
|
||||||
grep -sq \"${VERSION}\" src/version.hpp
|
grep -q \"${VERSION}\" src/version.hpp
|
||||||
RV=$?
|
RV=$?
|
||||||
if [ $RV -ne 0 ]; then
|
if [ $RV -ne 0 ]; then
|
||||||
echo "Writing 'src/version.hpp'"
|
|
||||||
echo "#pragma once" > src/version.hpp
|
echo "#pragma once" > src/version.hpp
|
||||||
echo "static const char MERGERFS_VERSION[] = \"${VERSION}\";" >> src/version.hpp
|
echo "static const char MERGERFS_VERSION[] = \"${VERSION}\";" >> src/version.hpp
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
1
debian/compat
vendored
Normal file
1
debian/compat
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
9
|
||||||
2
debian/control
vendored
2
debian/control
vendored
|
|
@ -2,7 +2,7 @@ Source: mergerfs
|
||||||
Section: utils
|
Section: utils
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Maintainer: Antonio SJ Musumeci <trapexit@spawn.link>
|
Maintainer: Antonio SJ Musumeci <trapexit@spawn.link>
|
||||||
Build-Depends: debhelper-compat (= 10)
|
Build-Depends: debhelper (>= 8.0.0)
|
||||||
Standards-Version: 3.9.4
|
Standards-Version: 3.9.4
|
||||||
Homepage: http://github.com/trapexit/mergerfs
|
Homepage: http://github.com/trapexit/mergerfs
|
||||||
|
|
||||||
|
|
|
||||||
11
debian/rules
vendored
11
debian/rules
vendored
|
|
@ -1,16 +1,11 @@
|
||||||
#!/usr/bin/make -f
|
#!/usr/bin/make -f
|
||||||
# -*- makefile -*-
|
# -*- makefile -*-
|
||||||
|
|
||||||
|
# Uncomment this to turn on verbose mode.
|
||||||
export DH_VERBOSE=1
|
export DH_VERBOSE=1
|
||||||
|
|
||||||
%:
|
%:
|
||||||
dh $@
|
dh $@ --parallel
|
||||||
|
|
||||||
override_dh_auto_build:
|
|
||||||
$(MAKE) release
|
|
||||||
|
|
||||||
override_dh_auto_install:
|
override_dh_auto_install:
|
||||||
$(MAKE) \
|
$(MAKE) DESTDIR=$(CURDIR)/debian/mergerfs PREFIX=/usr install
|
||||||
DESTDIR=$(CURDIR)/debian/mergerfs \
|
|
||||||
PREFIX=/usr \
|
|
||||||
install
|
|
||||||
|
|
|
||||||
146
libfuse/Makefile
Normal file
146
libfuse/Makefile
Normal file
|
|
@ -0,0 +1,146 @@
|
||||||
|
VERSION = 2.9.7-mergerfs_2.30.0
|
||||||
|
|
||||||
|
OS := $(shell uname -s)
|
||||||
|
ifeq ($(OS),Linux)
|
||||||
|
UTILS := utils
|
||||||
|
INSTALLUTILS := install-utils
|
||||||
|
else
|
||||||
|
UTILS :=
|
||||||
|
INSTALLUTILS :=
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(DEBUG),1)
|
||||||
|
OPT_FLAGS := -O0 -g -fsanitize=undefined
|
||||||
|
else
|
||||||
|
OPT_FLAGS := -O2
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(LTO),1)
|
||||||
|
LTO_FLAGS := -flto
|
||||||
|
else
|
||||||
|
LTO_FLAGS :=
|
||||||
|
endif
|
||||||
|
|
||||||
|
DESTDIR =
|
||||||
|
PREFIX = /usr/local
|
||||||
|
EXEC_PREFIX = $(PREFIX)
|
||||||
|
DATAROOTDIR = $(PREFIX)/share
|
||||||
|
DATADIR = $(DATAROOTDIR)
|
||||||
|
BINDIR = $(EXEC_PREFIX)/bin
|
||||||
|
SBINDIR = /sbin
|
||||||
|
MANDIR = $(DATAROOTDIR)/man
|
||||||
|
MAN1DIR = $(MANDIR)/man1
|
||||||
|
|
||||||
|
INSTALLBINDIR = $(DESTDIR)$(BINDIR)
|
||||||
|
INSTALLSBINDIR = $(DESTDIR)$(SBINDIR)
|
||||||
|
INSTALLMAN1DIR = $(DESTDIR)$(MAN1DIR)
|
||||||
|
|
||||||
|
AR ?= ar
|
||||||
|
|
||||||
|
SRC_C = \
|
||||||
|
lib/buffer.c \
|
||||||
|
lib/crc32b.c \
|
||||||
|
lib/debug.c \
|
||||||
|
lib/fuse.c \
|
||||||
|
lib/fuse_dirents.c \
|
||||||
|
lib/fuse_lowlevel.c \
|
||||||
|
lib/node.c \
|
||||||
|
lib/fuse_node.c \
|
||||||
|
lib/fuse_opt.c \
|
||||||
|
lib/fuse_session.c \
|
||||||
|
lib/fuse_signals.c \
|
||||||
|
lib/helper.c \
|
||||||
|
lib/mount.c
|
||||||
|
SRC_CPP = \
|
||||||
|
lib/format.cpp \
|
||||||
|
lib/os.cpp \
|
||||||
|
lib/cpu.cpp \
|
||||||
|
lib/fuse_config.cpp \
|
||||||
|
lib/fuse_loop.cpp \
|
||||||
|
lib/fuse_msgbuf.cpp
|
||||||
|
OBJS_C = $(SRC_C:lib/%.c=build/%.o)
|
||||||
|
OBJS_CPP = $(SRC_CPP:lib/%.cpp=build/%.o)
|
||||||
|
DEPS_C = $(SRC_C:lib/%.c=build/%.d)
|
||||||
|
DEPS_CPP = $(SRC_CPP:lib/%.cpp=build/%.d)
|
||||||
|
CFLAGS ?= \
|
||||||
|
$(OPT_FLAGS)
|
||||||
|
CFLAGS := \
|
||||||
|
${CFLAGS} \
|
||||||
|
$(LTO_FLAGS) \
|
||||||
|
-std=gnu99 \
|
||||||
|
-Wall \
|
||||||
|
-pipe \
|
||||||
|
-MMD
|
||||||
|
CXXFLAGS := \
|
||||||
|
${CXXFLAGS} \
|
||||||
|
$(LTO_FLAGS) \
|
||||||
|
-std=c++11 \
|
||||||
|
-Wall \
|
||||||
|
-pipe \
|
||||||
|
-MMD
|
||||||
|
FUSERMOUNT_DIR = $(BINDIR)
|
||||||
|
FUSE_FLAGS = \
|
||||||
|
-Iinclude \
|
||||||
|
-Ibuild \
|
||||||
|
-D_REENTRANT \
|
||||||
|
-D_FILE_OFFSET_BITS=64 \
|
||||||
|
-DPACKAGE_VERSION=\"$(VERSION)\" \
|
||||||
|
-DFUSERMOUNT_DIR=\"$(FUSERMOUNT_DIR)\"
|
||||||
|
LDFLAGS := \
|
||||||
|
${LDFLAGS} \
|
||||||
|
-lrt \
|
||||||
|
-pthread
|
||||||
|
|
||||||
|
all: build/libfuse.a $(UTILS)
|
||||||
|
|
||||||
|
build/config.h: build/stamp
|
||||||
|
ecfd/build | tee build/config.h
|
||||||
|
|
||||||
|
build/stamp:
|
||||||
|
mkdir -p build
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
objects: build/config.h
|
||||||
|
$(MAKE) $(OBJS_C) $(OBJS_CPP)
|
||||||
|
|
||||||
|
build/libfuse.a: objects
|
||||||
|
${AR} rcs build/libfuse.a $(OBJS_C) $(OBJS_CPP)
|
||||||
|
|
||||||
|
utils: mergerfs-fusermount mount.mergerfs
|
||||||
|
|
||||||
|
build/mergerfs-fusermount: build/config.h util/fusermount.c lib/mount_util.c
|
||||||
|
$(CC) $(CFLAGS) $(FUSE_FLAGS) -Ilib -o build/mergerfs-fusermount util/fusermount.c lib/mount_util.c
|
||||||
|
|
||||||
|
mergerfs-fusermount: build/mergerfs-fusermount
|
||||||
|
|
||||||
|
build/mount.mergerfs: build/libfuse.a util/mount.mergerfs.c
|
||||||
|
$(CC) $(CFLAGS) $(FUSE_FLAGS) -o build/mount.mergerfs util/mount.mergerfs.c build/libfuse.a $(LDFLAGS)
|
||||||
|
|
||||||
|
mount.mergerfs: build/mount.mergerfs
|
||||||
|
|
||||||
|
build/%.o: lib/%.c
|
||||||
|
$(CC) $(CFLAGS) $(FUSE_FLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
build/%.o: lib/%.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) $(FUSE_FLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf build
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
|
||||||
|
strip:
|
||||||
|
strip --strip-all build/mount.mergerfs
|
||||||
|
strip --strip-all build/mergerfs-fusermount
|
||||||
|
|
||||||
|
install-utils: mergerfs-fusermount mount.mergerfs strip
|
||||||
|
install -D build/mergerfs-fusermount "$(INSTALLBINDIR)/mergerfs-fusermount"
|
||||||
|
install -D build/mount.mergerfs "$(INSTALLSBINDIR)/mount.mergerfs"
|
||||||
|
chown root "$(INSTALLBINDIR)/mergerfs-fusermount"
|
||||||
|
chmod u+s "$(INSTALLBINDIR)/mergerfs-fusermount"
|
||||||
|
|
||||||
|
install: $(INSTALLUTILS)
|
||||||
|
|
||||||
|
.PHONY: objects strip utils install install-utils
|
||||||
|
|
||||||
|
-include $(DEPS_C) $(DEPS_CPP)
|
||||||
|
|
@ -27,8 +27,7 @@ Because the high-level interface is path based, it is not possible to
|
||||||
delegate looking up by inode to the filesystem.
|
delegate looking up by inode to the filesystem.
|
||||||
|
|
||||||
To work around this, currently a "noforget" option is provided, which
|
To work around this, currently a "noforget" option is provided, which
|
||||||
makes the library remember nodes until they are unlinked or otherwise
|
makes the library remember nodes forever. This will make the NFS
|
||||||
removed. This will make the NFS server happy, but also results in a
|
server happy, but also results in an ever growing memory footprint for
|
||||||
larger memory footprint for the filesystem. For this reason if the
|
the filesystem. For this reason if the filesystem is large (or the
|
||||||
filesystem is large (or the memory is small), then this option is not
|
memory is small), then this option is not recommended.
|
||||||
recommended.
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
ISC License
|
ISC License
|
||||||
|
|
||||||
Copyright (c) 2026, Antonio SJ Musumeci <trapexit@spawn.link>
|
Copyright (c) 2018, Antonio SJ Musumeci <trapexit@spawn.link>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
|
@ -14,11 +14,4 @@
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace caps
|
|
||||||
{
|
|
||||||
int setup();
|
|
||||||
}
|
|
||||||
16
libfuse/ecfd/README.md
Normal file
16
libfuse/ecfd/README.md
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
# ecfd: embeddable C feature discovery
|
||||||
|
|
||||||
|
This is a simple script and set of tests to help with what would traditionally be the `configure` step of most C/C++. It is intended to be simple to be embedded into a project and only depends on the C compiler and /bin/sh.
|
||||||
|
|
||||||
|
|
||||||
|
## USAGE
|
||||||
|
|
||||||
|
First copy `ecfd` into your project. Next simply call the build script which will run the tests and output a `config.` style file to `stdout`. Compile errors will output to `stderr` which can be used to understand why they aren't working.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./ecfd/build > include/config.h
|
||||||
|
```
|
||||||
|
|
||||||
|
## TESTS
|
||||||
|
|
||||||
|
Each test is in a single module. The build script will try to compile each module and on success will execute the program. If anything is printed to `stdout` it will be appended to the `#define` printed to the build script's `stdout`. If the compilation fails nothing will be printed. Look at the tests directory for examples.
|
||||||
32
libfuse/ecfd/build
Executable file
32
libfuse/ecfd/build
Executable file
|
|
@ -0,0 +1,32 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
PWD=$(pwd)
|
||||||
|
BASEPATH="${PWD}/${0%/*}"
|
||||||
|
|
||||||
|
CC=${CC:-cc}
|
||||||
|
OUTPUT="/dev/null"
|
||||||
|
|
||||||
|
echo "#ifndef CONFIG_H_INCLUDED"
|
||||||
|
echo "#define CONFIG_H_INCLUDED"
|
||||||
|
echo
|
||||||
|
|
||||||
|
IFS=
|
||||||
|
for file in "${BASEPATH}/tests/"*.c
|
||||||
|
do
|
||||||
|
binary="${file%.c}"
|
||||||
|
basename=$(basename ${binary})
|
||||||
|
|
||||||
|
${CC} -o "${binary}" "${file}" 1>&2
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
STDOUT=$(${binary})
|
||||||
|
if [ "${STDOUT}" != "" ]; then
|
||||||
|
echo "#define ${basename} ${STDOUT}"
|
||||||
|
else
|
||||||
|
echo "#define ${basename}"
|
||||||
|
fi
|
||||||
|
rm -f "${binary}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "#endif"
|
||||||
10
libfuse/ecfd/tests/HAVE_FORK.c
Normal file
10
libfuse/ecfd/tests/HAVE_FORK.c
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
(void)fork;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
7
libfuse/ecfd/tests/HAVE_MALLOC_TRIM.c
Normal file
7
libfuse/ecfd/tests/HAVE_MALLOC_TRIM.c
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
malloc_trim(0);
|
||||||
|
}
|
||||||
14
libfuse/ecfd/tests/HAVE_STRUCT_STAT_ST_ATIM.c
Normal file
14
libfuse/ecfd/tests/HAVE_STRUCT_STAT_ST_ATIM.c
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
(void)st.st_atim;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
11
libfuse/ecfd/tests/HAVE_UTIMENSAT.c
Normal file
11
libfuse/ecfd/tests/HAVE_UTIMENSAT.c
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
(void)utimensat;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
4
libfuse/ecfd/tests/static_assert.h
Normal file
4
libfuse/ecfd/tests/static_assert.h
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define STATIC_ASSERT(condition) \
|
||||||
|
((void)sizeof(char[1 - 2*!(condition)]))
|
||||||
784
libfuse/include/fuse.h
Normal file
784
libfuse/include/fuse.h
Normal file
|
|
@ -0,0 +1,784 @@
|
||||||
|
/*
|
||||||
|
FUSE: Filesystem in Userspace
|
||||||
|
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
||||||
|
|
||||||
|
This program can be distributed under the terms of the GNU LGPLv2.
|
||||||
|
See the file COPYING.LIB.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _FUSE_H_
|
||||||
|
#define _FUSE_H_
|
||||||
|
|
||||||
|
#include "extern_c.h"
|
||||||
|
#include "fuse_common.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <utime.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------- *
|
||||||
|
* Basic FUSE API *
|
||||||
|
* ----------------------------------------------------------- */
|
||||||
|
|
||||||
|
/** Handle for a FUSE filesystem */
|
||||||
|
struct fuse;
|
||||||
|
|
||||||
|
/** Structure containing a raw command */
|
||||||
|
struct fuse_cmd;
|
||||||
|
|
||||||
|
struct fuse_dirents_t;
|
||||||
|
typedef struct fuse_dirents_t fuse_dirents_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The file system operations:
|
||||||
|
*
|
||||||
|
* Most of these should work very similarly to the well known UNIX
|
||||||
|
* file system operations. A major exception is that instead of
|
||||||
|
* returning an error in 'errno', the operation should return the
|
||||||
|
* negated error value (-errno) directly.
|
||||||
|
*
|
||||||
|
* All methods are optional, but some are essential for a useful
|
||||||
|
* filesystem (e.g. getattr). Open, flush, release, fsync, opendir,
|
||||||
|
* releasedir, fsyncdir, access, create, ftruncate, fgetattr, lock,
|
||||||
|
* init and destroy are special purpose methods, without which a full
|
||||||
|
* featured filesystem can still be implemented.
|
||||||
|
*
|
||||||
|
* Almost all operations take a path which can be of any length.
|
||||||
|
*
|
||||||
|
* Changed in fuse 2.8.0 (regardless of API version)
|
||||||
|
* Previously, paths were limited to a length of PATH_MAX.
|
||||||
|
*
|
||||||
|
* See http://fuse.sourceforge.net/wiki/ for more information. There
|
||||||
|
* is also a snapshot of the relevant wiki pages in the doc/ folder.
|
||||||
|
*/
|
||||||
|
struct fuse_operations
|
||||||
|
{
|
||||||
|
/** Get file attributes.
|
||||||
|
*
|
||||||
|
* Similar to stat(). The 'st_dev' and 'st_blksize' fields are
|
||||||
|
* ignored. The 'st_ino' field is ignored except if the 'use_ino'
|
||||||
|
* mount option is given.
|
||||||
|
*/
|
||||||
|
int (*getattr) (const char *, struct stat *, fuse_timeouts_t *);
|
||||||
|
|
||||||
|
/** Read the target of a symbolic link
|
||||||
|
*
|
||||||
|
* The buffer should be filled with a null terminated string. The
|
||||||
|
* buffer size argument includes the space for the terminating
|
||||||
|
* null character. If the linkname is too long to fit in the
|
||||||
|
* buffer, it should be truncated. The return value should be 0
|
||||||
|
* for success.
|
||||||
|
*/
|
||||||
|
int (*readlink) (const char *, char *, size_t);
|
||||||
|
|
||||||
|
/** Create a file node
|
||||||
|
*
|
||||||
|
* This is called for creation of all non-directory, non-symlink
|
||||||
|
* nodes. If the filesystem defines a create() method, then for
|
||||||
|
* regular files that will be called instead.
|
||||||
|
*/
|
||||||
|
int (*mknod) (const char *, mode_t, dev_t);
|
||||||
|
|
||||||
|
/** Create a directory
|
||||||
|
*
|
||||||
|
* Note that the mode argument may not have the type specification
|
||||||
|
* bits set, i.e. S_ISDIR(mode) can be false. To obtain the
|
||||||
|
* correct directory type bits use mode|S_IFDIR
|
||||||
|
* */
|
||||||
|
int (*mkdir) (const char *, mode_t);
|
||||||
|
|
||||||
|
/** Hide files unlinked / renamed over
|
||||||
|
*
|
||||||
|
* Allows storing of a file handle when a file is unlinked
|
||||||
|
* while open. Helps manage the fact the kernel usually does
|
||||||
|
* not send fh with getattr requests.
|
||||||
|
*/
|
||||||
|
int (*prepare_hide)(const char *name_, uint64_t *fh_);
|
||||||
|
int (*free_hide)(const uint64_t fh_);
|
||||||
|
|
||||||
|
/** Remove a file */
|
||||||
|
int (*unlink) (const char *);
|
||||||
|
|
||||||
|
/** Remove a directory */
|
||||||
|
int (*rmdir) (const char *);
|
||||||
|
|
||||||
|
/** Create a symbolic link */
|
||||||
|
int (*symlink) (const char *, const char *, struct stat *, fuse_timeouts_t *);
|
||||||
|
|
||||||
|
/** Rename a file */
|
||||||
|
int (*rename) (const char *, const char *);
|
||||||
|
|
||||||
|
/** Create a hard link to a file */
|
||||||
|
int (*link) (const char *, const char *, struct stat *, fuse_timeouts_t *);
|
||||||
|
|
||||||
|
/** Change the permission bits of a file */
|
||||||
|
int (*chmod) (const char *, mode_t);
|
||||||
|
int (*fchmod)(const fuse_file_info_t *, const mode_t);
|
||||||
|
|
||||||
|
/** Change the owner and group of a file */
|
||||||
|
int (*chown) (const char *, uid_t, gid_t);
|
||||||
|
int (*fchown)(const fuse_file_info_t *, const uid_t, const gid_t);
|
||||||
|
|
||||||
|
/** Change the size of a file */
|
||||||
|
int (*truncate) (const char *, off_t);
|
||||||
|
|
||||||
|
/** File open operation
|
||||||
|
*
|
||||||
|
* No creation (O_CREAT, O_EXCL) and by default also no
|
||||||
|
* truncation (O_TRUNC) flags will be passed to open(). If an
|
||||||
|
* application specifies O_TRUNC, fuse first calls truncate()
|
||||||
|
* and then open(). Only if 'atomic_o_trunc' has been
|
||||||
|
* specified and kernel version is 2.6.24 or later, O_TRUNC is
|
||||||
|
* passed on to open.
|
||||||
|
*
|
||||||
|
* Unless the 'default_permissions' mount option is given,
|
||||||
|
* open should check if the operation is permitted for the
|
||||||
|
* given flags. Optionally open may also return an arbitrary
|
||||||
|
* filehandle in the fuse_file_info structure, which will be
|
||||||
|
* passed to all file operations.
|
||||||
|
*
|
||||||
|
* Changed in version 2.2
|
||||||
|
*/
|
||||||
|
int (*open) (const char *, fuse_file_info_t *);
|
||||||
|
|
||||||
|
/** Get file system statistics
|
||||||
|
*
|
||||||
|
* The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored
|
||||||
|
*
|
||||||
|
* Replaced 'struct statfs' parameter with 'struct statvfs' in
|
||||||
|
* version 2.5
|
||||||
|
*/
|
||||||
|
int (*statfs) (const char *, struct statvfs *);
|
||||||
|
|
||||||
|
/** Possibly flush cached data
|
||||||
|
*
|
||||||
|
* BIG NOTE: This is not equivalent to fsync(). It's not a
|
||||||
|
* request to sync dirty data.
|
||||||
|
*
|
||||||
|
* Flush is called on each close() of a file descriptor. So if a
|
||||||
|
* filesystem wants to return write errors in close() and the file
|
||||||
|
* has cached dirty data, this is a good place to write back data
|
||||||
|
* and return any errors. Since many applications ignore close()
|
||||||
|
* errors this is not always useful.
|
||||||
|
*
|
||||||
|
* NOTE: The flush() method may be called more than once for each
|
||||||
|
* open(). This happens if more than one file descriptor refers
|
||||||
|
* to an opened file due to dup(), dup2() or fork() calls. It is
|
||||||
|
* not possible to determine if a flush is final, so each flush
|
||||||
|
* should be treated equally. Multiple write-flush sequences are
|
||||||
|
* relatively rare, so this shouldn't be a problem.
|
||||||
|
*
|
||||||
|
* Filesystems shouldn't assume that flush will always be called
|
||||||
|
* after some writes, or that if will be called at all.
|
||||||
|
*
|
||||||
|
* Changed in version 2.2
|
||||||
|
*/
|
||||||
|
int (*flush) (const fuse_file_info_t *);
|
||||||
|
|
||||||
|
/** Release an open file
|
||||||
|
*
|
||||||
|
* Release is called when there are no more references to an open
|
||||||
|
* file: all file descriptors are closed and all memory mappings
|
||||||
|
* are unmapped.
|
||||||
|
*
|
||||||
|
* For every open() call there will be exactly one release() call
|
||||||
|
* with the same flags and file descriptor. It is possible to
|
||||||
|
* have a file opened more than once, in which case only the last
|
||||||
|
* release will mean, that no more reads/writes will happen on the
|
||||||
|
* file. The return value of release is ignored.
|
||||||
|
*
|
||||||
|
* Changed in version 2.2
|
||||||
|
*/
|
||||||
|
int (*release) (const fuse_file_info_t *);
|
||||||
|
|
||||||
|
/** Synchronize file contents
|
||||||
|
*
|
||||||
|
* If the datasync parameter is non-zero, then only the user data
|
||||||
|
* should be flushed, not the meta data.
|
||||||
|
*
|
||||||
|
* Changed in version 2.2
|
||||||
|
*/
|
||||||
|
int (*fsync) (const fuse_file_info_t *, int);
|
||||||
|
|
||||||
|
/** Set extended attributes */
|
||||||
|
int (*setxattr) (const char *, const char *, const char *, size_t, int);
|
||||||
|
|
||||||
|
/** Get extended attributes */
|
||||||
|
int (*getxattr) (const char *, const char *, char *, size_t);
|
||||||
|
|
||||||
|
/** List extended attributes */
|
||||||
|
int (*listxattr) (const char *, char *, size_t);
|
||||||
|
|
||||||
|
/** Remove extended attributes */
|
||||||
|
int (*removexattr) (const char *, const char *);
|
||||||
|
|
||||||
|
/** Open directory
|
||||||
|
*
|
||||||
|
* Unless the 'default_permissions' mount option is given,
|
||||||
|
* this method should check if opendir is permitted for this
|
||||||
|
* directory. Optionally opendir may also return an arbitrary
|
||||||
|
* filehandle in the fuse_file_info structure, which will be
|
||||||
|
* passed to readdir, closedir and fsyncdir.
|
||||||
|
*
|
||||||
|
* Introduced in version 2.3
|
||||||
|
*/
|
||||||
|
int (*opendir) (const char *,
|
||||||
|
fuse_file_info_t *);
|
||||||
|
|
||||||
|
/** Read directory
|
||||||
|
*
|
||||||
|
* This supersedes the old getdir() interface. New applications
|
||||||
|
* should use this.
|
||||||
|
*
|
||||||
|
* The filesystem may choose between two modes of operation:
|
||||||
|
*
|
||||||
|
* 1) The readdir implementation ignores the offset parameter, and
|
||||||
|
* passes zero to the filler function's offset. The filler
|
||||||
|
* function will not return '1' (unless an error happens), so the
|
||||||
|
* whole directory is read in a single readdir operation. This
|
||||||
|
* works just like the old getdir() method.
|
||||||
|
*
|
||||||
|
* 2) The readdir implementation keeps track of the offsets of the
|
||||||
|
* directory entries. It uses the offset parameter and always
|
||||||
|
* passes non-zero offset to the filler function. When the buffer
|
||||||
|
* is full (or an error happens) the filler function will return
|
||||||
|
* '1'.
|
||||||
|
*
|
||||||
|
* Introduced in version 2.3
|
||||||
|
*/
|
||||||
|
int (*readdir)(const fuse_file_info_t *,
|
||||||
|
fuse_dirents_t *);
|
||||||
|
|
||||||
|
int (*readdir_plus)(const fuse_file_info_t *,
|
||||||
|
fuse_dirents_t *);
|
||||||
|
|
||||||
|
|
||||||
|
/** Release directory
|
||||||
|
*
|
||||||
|
* Introduced in version 2.3
|
||||||
|
*/
|
||||||
|
int (*releasedir) (const fuse_file_info_t *);
|
||||||
|
|
||||||
|
/** Synchronize directory contents
|
||||||
|
*
|
||||||
|
* If the datasync parameter is non-zero, then only the user data
|
||||||
|
* should be flushed, not the meta data
|
||||||
|
*
|
||||||
|
* Introduced in version 2.3
|
||||||
|
*/
|
||||||
|
int (*fsyncdir) (const fuse_file_info_t *, int);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize filesystem
|
||||||
|
*
|
||||||
|
* The return value will passed in the private_data field of
|
||||||
|
* fuse_context to all file operations and as a parameter to the
|
||||||
|
* destroy() method.
|
||||||
|
*
|
||||||
|
* Introduced in version 2.3
|
||||||
|
* Changed in version 2.6
|
||||||
|
*/
|
||||||
|
void *(*init) (struct fuse_conn_info *conn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean up filesystem
|
||||||
|
*
|
||||||
|
* Called on filesystem exit.
|
||||||
|
*
|
||||||
|
* Introduced in version 2.3
|
||||||
|
*/
|
||||||
|
void (*destroy) (void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check file access permissions
|
||||||
|
*
|
||||||
|
* This will be called for the access() system call. If the
|
||||||
|
* 'default_permissions' mount option is given, this method is not
|
||||||
|
* called.
|
||||||
|
*
|
||||||
|
* This method is not called under Linux kernel versions 2.4.x
|
||||||
|
*
|
||||||
|
* Introduced in version 2.5
|
||||||
|
*/
|
||||||
|
int (*access) (const char *, int);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and open a file
|
||||||
|
*
|
||||||
|
* If the file does not exist, first create it with the specified
|
||||||
|
* mode, and then open it.
|
||||||
|
*
|
||||||
|
* If this method is not implemented or under Linux kernel
|
||||||
|
* versions earlier than 2.6.15, the mknod() and open() methods
|
||||||
|
* will be called instead.
|
||||||
|
*
|
||||||
|
* Introduced in version 2.5
|
||||||
|
*/
|
||||||
|
int (*create) (const char *, mode_t, fuse_file_info_t *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the size of an open file
|
||||||
|
*
|
||||||
|
* This method is called instead of the truncate() method if the
|
||||||
|
* truncation was invoked from an ftruncate() system call.
|
||||||
|
*
|
||||||
|
* If this method is not implemented or under Linux kernel
|
||||||
|
* versions earlier than 2.6.15, the truncate() method will be
|
||||||
|
* called instead.
|
||||||
|
*
|
||||||
|
* Introduced in version 2.5
|
||||||
|
*/
|
||||||
|
int (*ftruncate) (const fuse_file_info_t *, off_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get attributes from an open file
|
||||||
|
*
|
||||||
|
* This method is called instead of the getattr() method if the
|
||||||
|
* file information is available.
|
||||||
|
*
|
||||||
|
* Currently this is only called after the create() method if that
|
||||||
|
* is implemented (see above). Later it may be called for
|
||||||
|
* invocations of fstat() too.
|
||||||
|
*
|
||||||
|
* Introduced in version 2.5
|
||||||
|
*/
|
||||||
|
int (*fgetattr) (const fuse_file_info_t *, struct stat *, fuse_timeouts_t *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform POSIX file locking operation
|
||||||
|
*
|
||||||
|
* The cmd argument will be either F_GETLK, F_SETLK or F_SETLKW.
|
||||||
|
*
|
||||||
|
* For the meaning of fields in 'struct flock' see the man page
|
||||||
|
* for fcntl(2). The l_whence field will always be set to
|
||||||
|
* SEEK_SET.
|
||||||
|
*
|
||||||
|
* For checking lock ownership, the 'fuse_file_info->owner'
|
||||||
|
* argument must be used.
|
||||||
|
*
|
||||||
|
* For F_GETLK operation, the library will first check currently
|
||||||
|
* held locks, and if a conflicting lock is found it will return
|
||||||
|
* information without calling this method. This ensures, that
|
||||||
|
* for local locks the l_pid field is correctly filled in. The
|
||||||
|
* results may not be accurate in case of race conditions and in
|
||||||
|
* the presence of hard links, but it's unlikely that an
|
||||||
|
* application would rely on accurate GETLK results in these
|
||||||
|
* cases. If a conflicting lock is not found, this method will be
|
||||||
|
* called, and the filesystem may fill out l_pid by a meaningful
|
||||||
|
* value, or it may leave this field zero.
|
||||||
|
*
|
||||||
|
* For F_SETLK and F_SETLKW the l_pid field will be set to the pid
|
||||||
|
* of the process performing the locking operation.
|
||||||
|
*
|
||||||
|
* Note: if this method is not implemented, the kernel will still
|
||||||
|
* allow file locking to work locally. Hence it is only
|
||||||
|
* interesting for network filesystems and similar.
|
||||||
|
*
|
||||||
|
* Introduced in version 2.6
|
||||||
|
*/
|
||||||
|
int (*lock) (const fuse_file_info_t *,
|
||||||
|
int cmd,
|
||||||
|
struct flock *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the access and modification times of a file with
|
||||||
|
* nanosecond resolution
|
||||||
|
*
|
||||||
|
* This supersedes the old utime() interface. New applications
|
||||||
|
* should use this.
|
||||||
|
*
|
||||||
|
* See the utimensat(2) man page for details.
|
||||||
|
*
|
||||||
|
* Introduced in version 2.6
|
||||||
|
*/
|
||||||
|
int (*utimens)(const char *, const struct timespec tv[2]);
|
||||||
|
int (*futimens)(const fuse_file_info_t *ffi_, const struct timespec tv_[2]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map block index within file to block index within device
|
||||||
|
*
|
||||||
|
* Note: This makes sense only for block device backed filesystems
|
||||||
|
* mounted with the 'blkdev' option
|
||||||
|
*
|
||||||
|
* Introduced in version 2.6
|
||||||
|
*/
|
||||||
|
int (*bmap) (const char *, size_t blocksize, uint64_t *idx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ioctl
|
||||||
|
*
|
||||||
|
* flags will have FUSE_IOCTL_COMPAT set for 32bit ioctls in
|
||||||
|
* 64bit environment. The size and direction of data is
|
||||||
|
* determined by _IOC_*() decoding of cmd. For _IOC_NONE,
|
||||||
|
* data will be NULL, for _IOC_WRITE data is out area, for
|
||||||
|
* _IOC_READ in area and if both are set in/out area. In all
|
||||||
|
* non-NULL cases, the area is of _IOC_SIZE(cmd) bytes.
|
||||||
|
*
|
||||||
|
* If flags has FUSE_IOCTL_DIR then the fuse_file_info refers to a
|
||||||
|
* directory file handle.
|
||||||
|
*
|
||||||
|
* Introduced in version 2.8
|
||||||
|
*/
|
||||||
|
int (*ioctl) (const fuse_file_info_t *ffi,
|
||||||
|
unsigned long cmd,
|
||||||
|
void *arg,
|
||||||
|
unsigned int flags,
|
||||||
|
void *data,
|
||||||
|
uint32_t *out_bufsz);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Poll for IO readiness events
|
||||||
|
*
|
||||||
|
* Note: If ph is non-NULL, the client should notify
|
||||||
|
* when IO readiness events occur by calling
|
||||||
|
* fuse_notify_poll() with the specified ph.
|
||||||
|
*
|
||||||
|
* Regardless of the number of times poll with a non-NULL ph
|
||||||
|
* is received, single notification is enough to clear all.
|
||||||
|
* Notifying more times incurs overhead but doesn't harm
|
||||||
|
* correctness.
|
||||||
|
*
|
||||||
|
* The callee is responsible for destroying ph with
|
||||||
|
* fuse_pollhandle_destroy() when no longer in use.
|
||||||
|
*
|
||||||
|
* Introduced in version 2.8
|
||||||
|
*/
|
||||||
|
int (*poll) (const fuse_file_info_t *ffi,
|
||||||
|
fuse_pollhandle_t *ph,
|
||||||
|
unsigned *reventsp);
|
||||||
|
|
||||||
|
/** Write contents of buffer to an open file
|
||||||
|
*
|
||||||
|
* Similar to the write() method, but data is supplied in a
|
||||||
|
* generic buffer. Use fuse_buf_copy() to transfer data to
|
||||||
|
* the destination.
|
||||||
|
*
|
||||||
|
* Introduced in version 2.9
|
||||||
|
*/
|
||||||
|
int (*write) (const fuse_file_info_t *ffi,
|
||||||
|
const char *data,
|
||||||
|
size_t size,
|
||||||
|
off_t off);
|
||||||
|
|
||||||
|
/** Store data from an open file in a buffer
|
||||||
|
*
|
||||||
|
* Similar to the read() method, but data is stored and
|
||||||
|
* returned in a generic buffer.
|
||||||
|
*
|
||||||
|
* No actual copying of data has to take place, the source
|
||||||
|
* file descriptor may simply be stored in the buffer for
|
||||||
|
* later data transfer.
|
||||||
|
*
|
||||||
|
* The buffer must be allocated dynamically and stored at the
|
||||||
|
* location pointed to by bufp. If the buffer contains memory
|
||||||
|
* regions, they too must be allocated using malloc(). The
|
||||||
|
* allocated memory will be freed by the caller.
|
||||||
|
*
|
||||||
|
* Introduced in version 2.9
|
||||||
|
*/
|
||||||
|
int (*read)(const fuse_file_info_t *ffi,
|
||||||
|
char *buf,
|
||||||
|
size_t size,
|
||||||
|
off_t off);
|
||||||
|
/**
|
||||||
|
* Perform BSD file locking operation
|
||||||
|
*
|
||||||
|
* The op argument will be either LOCK_SH, LOCK_EX or LOCK_UN
|
||||||
|
*
|
||||||
|
* Nonblocking requests will be indicated by ORing LOCK_NB to
|
||||||
|
* the above operations
|
||||||
|
*
|
||||||
|
* For more information see the flock(2) manual page.
|
||||||
|
*
|
||||||
|
* Additionally fi->owner will be set to a value unique to
|
||||||
|
* this open file. This same value will be supplied to
|
||||||
|
* ->release() when the file is released.
|
||||||
|
*
|
||||||
|
* Note: if this method is not implemented, the kernel will still
|
||||||
|
* allow file locking to work locally. Hence it is only
|
||||||
|
* interesting for network filesystems and similar.
|
||||||
|
*
|
||||||
|
* Introduced in version 2.9
|
||||||
|
*/
|
||||||
|
int (*flock) (const fuse_file_info_t *, int op);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates space for an open file
|
||||||
|
*
|
||||||
|
* This function ensures that required space is allocated for specified
|
||||||
|
* file. If this function returns success then any subsequent write
|
||||||
|
* request to specified range is guaranteed not to fail because of lack
|
||||||
|
* of space on the file system media.
|
||||||
|
*
|
||||||
|
* Introduced in version 2.9.1
|
||||||
|
*/
|
||||||
|
int (*fallocate) (const fuse_file_info_t *, int, off_t, off_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy a range of data from one file to another
|
||||||
|
*
|
||||||
|
* Performs an optimized copy between two file descriptors without
|
||||||
|
* the additional cost of transferring data through the FUSE kernel
|
||||||
|
* module to user space (glibc) and then back into the FUSE filesystem
|
||||||
|
* again.
|
||||||
|
*
|
||||||
|
* In case this method is not implemented, glibc falls back to
|
||||||
|
* reading data from the source and writing to the
|
||||||
|
* destination. Effectively doing an inefficient copy of the
|
||||||
|
* data.
|
||||||
|
*/
|
||||||
|
ssize_t (*copy_file_range)(const fuse_file_info_t *fi_in,
|
||||||
|
off_t offset_in,
|
||||||
|
const fuse_file_info_t *fi_out,
|
||||||
|
off_t offset_out,
|
||||||
|
size_t size,
|
||||||
|
int flags);
|
||||||
|
|
||||||
|
ssize_t (*setupmapping)(uint64_t *fh_,
|
||||||
|
uint64_t foffset_,
|
||||||
|
uint64_t len_,
|
||||||
|
uint64_t flags_,
|
||||||
|
uint64_t moffset_);
|
||||||
|
|
||||||
|
int (*removemapping)();
|
||||||
|
int (*syncfs)();
|
||||||
|
int (*tmpfile)(const char *, mode_t, fuse_file_info_t *);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Extra context that may be needed by some filesystems
|
||||||
|
*
|
||||||
|
* The uid, gid and pid fields are not filled in case of a writepage
|
||||||
|
* operation.
|
||||||
|
*/
|
||||||
|
struct fuse_context
|
||||||
|
{
|
||||||
|
/** Pointer to the fuse object */
|
||||||
|
struct fuse *fuse;
|
||||||
|
|
||||||
|
/** User ID of the calling process */
|
||||||
|
uid_t uid;
|
||||||
|
|
||||||
|
/** Group ID of the calling process */
|
||||||
|
gid_t gid;
|
||||||
|
|
||||||
|
/** Thread ID of the calling process */
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
/** Umask of the calling process (introduced in version 2.8) */
|
||||||
|
mode_t umask;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main function of FUSE.
|
||||||
|
*
|
||||||
|
* This is for the lazy. This is all that has to be called from the
|
||||||
|
* main() function.
|
||||||
|
*
|
||||||
|
* This function does the following:
|
||||||
|
* - parses command line options (-d -s and -h)
|
||||||
|
* - passes relevant mount options to the fuse_mount()
|
||||||
|
* - installs signal handlers for INT, HUP, TERM and PIPE
|
||||||
|
* - registers an exit handler to unmount the filesystem on program exit
|
||||||
|
* - creates a fuse handle
|
||||||
|
* - registers the operations
|
||||||
|
* - calls either the single-threaded or the multi-threaded event loop
|
||||||
|
*
|
||||||
|
* Note: this is currently implemented as a macro.
|
||||||
|
*
|
||||||
|
* @param argc the argument counter passed to the main() function
|
||||||
|
* @param argv the argument vector passed to the main() function
|
||||||
|
* @param op the file system operation
|
||||||
|
* @return 0 on success, nonzero on failure
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
int fuse_main(int argc, char *argv[], const struct fuse_operations *op);
|
||||||
|
*/
|
||||||
|
#define fuse_main(argc, argv, op) \
|
||||||
|
fuse_main_real(argc, argv, op, sizeof(*(op)))
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------- *
|
||||||
|
* More detailed API *
|
||||||
|
* ----------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new FUSE filesystem.
|
||||||
|
*
|
||||||
|
* @param ch the communication channel
|
||||||
|
* @param args argument vector
|
||||||
|
* @param op the filesystem operations
|
||||||
|
* @param op_size the size of the fuse_operations structure
|
||||||
|
* @return the created FUSE handle
|
||||||
|
*/
|
||||||
|
struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
|
||||||
|
const struct fuse_operations *op, size_t op_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy the FUSE handle.
|
||||||
|
*
|
||||||
|
* The communication channel attached to the handle is also destroyed.
|
||||||
|
*
|
||||||
|
* NOTE: This function does not unmount the filesystem. If this is
|
||||||
|
* needed, call fuse_unmount() before calling this function.
|
||||||
|
*
|
||||||
|
* @param f the FUSE handle
|
||||||
|
*/
|
||||||
|
void fuse_destroy(struct fuse *f);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exit from event loop
|
||||||
|
*
|
||||||
|
* @param f the FUSE handle
|
||||||
|
*/
|
||||||
|
void fuse_exit(struct fuse *f);
|
||||||
|
|
||||||
|
int fuse_config_read_thread_count(const struct fuse *f);
|
||||||
|
int fuse_config_process_thread_count(const struct fuse *f);
|
||||||
|
int fuse_config_process_thread_queue_depth(const struct fuse *f);
|
||||||
|
const char* fuse_config_pin_threads(const struct fuse *f);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FUSE event loop with multiple threads
|
||||||
|
*
|
||||||
|
* Requests from the kernel are processed, and the appropriate
|
||||||
|
* operations are called. Request are processed in parallel by
|
||||||
|
* distributing them between multiple threads.
|
||||||
|
*
|
||||||
|
* Calling this function requires the pthreads library to be linked to
|
||||||
|
* the application.
|
||||||
|
*
|
||||||
|
* @param f the FUSE handle
|
||||||
|
* @return 0 if no error occurred, -1 otherwise
|
||||||
|
*/
|
||||||
|
int fuse_loop_mt(struct fuse *f);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current context
|
||||||
|
*
|
||||||
|
* The context is only valid for the duration of a filesystem
|
||||||
|
* operation, and thus must not be stored and used later.
|
||||||
|
*
|
||||||
|
* @return the context
|
||||||
|
*/
|
||||||
|
struct fuse_context *fuse_get_context(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the current request has already been interrupted
|
||||||
|
*
|
||||||
|
* @return 1 if the request has been interrupted, 0 otherwise
|
||||||
|
*/
|
||||||
|
int fuse_interrupted(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obsolete, doesn't do anything
|
||||||
|
*
|
||||||
|
* @return -EINVAL
|
||||||
|
*/
|
||||||
|
int fuse_invalidate(struct fuse *f, const char *path);
|
||||||
|
|
||||||
|
/* Deprecated, don't use */
|
||||||
|
int fuse_is_lib_option(const char *opt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The real main function
|
||||||
|
*
|
||||||
|
* Do not call this directly, use fuse_main()
|
||||||
|
*/
|
||||||
|
int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op, size_t op_size);
|
||||||
|
|
||||||
|
int fuse_start_maintenance_thread(struct fuse *fuse);
|
||||||
|
void fuse_stop_maintenance_thread(struct fuse *fuse);
|
||||||
|
|
||||||
|
int fuse_log_metrics_get(void);
|
||||||
|
void fuse_log_metrics_set(int enabled);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterate over cache removing stale entries
|
||||||
|
* use in conjunction with "-oremember"
|
||||||
|
*
|
||||||
|
* NOTE: This is already done for the standard sessions
|
||||||
|
*
|
||||||
|
* @param fuse struct fuse pointer for fuse instance
|
||||||
|
* @return the number of seconds until the next cleanup
|
||||||
|
*/
|
||||||
|
int fuse_clean_cache(struct fuse *fuse);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stacking API
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fuse filesystem object
|
||||||
|
*
|
||||||
|
* This is opaque object represents a filesystem layer
|
||||||
|
*/
|
||||||
|
struct fuse_fs;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These functions call the relevant filesystem operation, and return
|
||||||
|
* the result.
|
||||||
|
*
|
||||||
|
* If the operation is not defined, they return -ENOSYS, with the
|
||||||
|
* exception of fuse_fs_open, fuse_fs_release, fuse_fs_opendir,
|
||||||
|
* fuse_fs_releasedir and fuse_fs_statfs, which return 0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int fuse_notify_poll(fuse_pollhandle_t *ph);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new fuse filesystem object
|
||||||
|
*
|
||||||
|
* This is usually called from the factory of a fuse module to create
|
||||||
|
* a new instance of a filesystem.
|
||||||
|
*
|
||||||
|
* @param op the filesystem operations
|
||||||
|
* @param op_size the size of the fuse_operations structure
|
||||||
|
* @return a new filesystem object
|
||||||
|
*/
|
||||||
|
struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size);
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------- *
|
||||||
|
* Advanced API for event handling, don't worry about this... *
|
||||||
|
* ----------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* NOTE: the following functions are deprecated, and will be removed
|
||||||
|
from the 3.0 API. Use the lowlevel session functions instead */
|
||||||
|
|
||||||
|
/** Function type used to process commands */
|
||||||
|
typedef void (*fuse_processor_t)(struct fuse *, struct fuse_cmd *, void *);
|
||||||
|
|
||||||
|
/** This is the part of fuse_main() before the event loop */
|
||||||
|
struct fuse *fuse_setup(int argc, char *argv[],
|
||||||
|
const struct fuse_operations *op, size_t op_size,
|
||||||
|
char **mountpoint);
|
||||||
|
|
||||||
|
/** This is the part of fuse_main() after the event loop */
|
||||||
|
void fuse_teardown(struct fuse *fuse, char *mountpoint);
|
||||||
|
|
||||||
|
/** Multi threaded event loop, which calls the custom command
|
||||||
|
processor function */
|
||||||
|
int fuse_loop_mt_proc(struct fuse *f, fuse_processor_t proc, void *data);
|
||||||
|
|
||||||
|
/** Return the exited flag, which indicates if fuse_exit() has been
|
||||||
|
called */
|
||||||
|
int fuse_exited(struct fuse *f);
|
||||||
|
|
||||||
|
/** This function is obsolete and implemented as a no-op */
|
||||||
|
void fuse_set_getcontext_func(struct fuse_context *(*func)(void));
|
||||||
|
|
||||||
|
/** Get session from fuse object */
|
||||||
|
struct fuse_session *fuse_get_session(struct fuse *f);
|
||||||
|
|
||||||
|
void fuse_gc1();
|
||||||
|
void fuse_gc();
|
||||||
|
void fuse_invalidate_all_nodes();
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
|
#endif /* _FUSE_H_ */
|
||||||
|
|
@ -1,20 +1,43 @@
|
||||||
#pragma once
|
/*
|
||||||
|
FUSE: Filesystem in Userspace
|
||||||
|
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
||||||
|
|
||||||
|
This program can be distributed under the terms of the GNU LGPLv2.
|
||||||
|
See the file COPYING.LIB.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file */
|
||||||
|
|
||||||
|
#if !defined(_FUSE_H_) && !defined(_FUSE_LOWLEVEL_H_)
|
||||||
|
#error "Never include <fuse_common.h> directly; use <fuse.h> or <fuse_lowlevel.h> instead."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _FUSE_COMMON_H_
|
||||||
|
#define _FUSE_COMMON_H_
|
||||||
|
|
||||||
#include "extern_c.h"
|
#include "extern_c.h"
|
||||||
#include "fuse_conn_info.hpp"
|
|
||||||
#include "fuse_opt.h"
|
#include "fuse_opt.h"
|
||||||
#include "fuse_timeouts.h"
|
#include "fuse_timeouts.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
/** Major version of FUSE library interface */
|
||||||
|
#define FUSE_MAJOR_VERSION 2
|
||||||
|
|
||||||
|
/** Minor version of FUSE library interface */
|
||||||
|
#define FUSE_MINOR_VERSION 9
|
||||||
|
|
||||||
|
#define FUSE_MAKE_VERSION(maj, min) ((maj) * 10 + (min))
|
||||||
|
#define FUSE_VERSION FUSE_MAKE_VERSION(FUSE_MAJOR_VERSION, FUSE_MINOR_VERSION)
|
||||||
|
|
||||||
/* This interface uses 64 bit off_t */
|
/* This interface uses 64 bit off_t */
|
||||||
#if _FILE_OFFSET_BITS != 64
|
#if _FILE_OFFSET_BITS != 64
|
||||||
#error Please add -D_FILE_OFFSET_BITS=64 to your compile flags!
|
#error Please add -D_FILE_OFFSET_BITS=64 to your compile flags!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FUSE_DEFAULT_MAX_PAGES_PER_REQ 32
|
#define FUSE_DEFAULT_MAX_PAGES_PER_REQ 32
|
||||||
#define FUSE_DEFAULT_MAX_MAX_PAGES 256
|
#define FUSE_MAX_MAX_PAGES 256
|
||||||
|
|
||||||
EXTERN_C_BEGIN
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
|
@ -64,20 +87,17 @@ struct fuse_file_info_t
|
||||||
uint32_t parallel_direct_writes:1;
|
uint32_t parallel_direct_writes:1;
|
||||||
|
|
||||||
uint32_t noflush:1;
|
uint32_t noflush:1;
|
||||||
uint32_t passthrough:1;
|
|
||||||
|
|
||||||
/** File handle. May be filled in by filesystem in open().
|
/** File handle. May be filled in by filesystem in open().
|
||||||
Available in all other file operations */
|
Available in all other file operations */
|
||||||
uint64_t fh;
|
uint64_t fh;
|
||||||
|
|
||||||
int32_t backing_id;
|
|
||||||
|
|
||||||
/** Lock owner id. Available in locking operations and flush */
|
/** Lock owner id. Available in locking operations and flush */
|
||||||
uint64_t lock_owner;
|
uint64_t lock_owner;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Capability bits for 'fuse_conn_info_t.capable' and 'fuse_conn_info_t.want'
|
* Capability bits for 'fuse_conn_info.capable' and 'fuse_conn_info.want'
|
||||||
*
|
*
|
||||||
* FUSE_CAP_ASYNC_READ: filesystem supports asynchronous read requests
|
* FUSE_CAP_ASYNC_READ: filesystem supports asynchronous read requests
|
||||||
* FUSE_CAP_POSIX_LOCKS: filesystem supports "remote" locking
|
* FUSE_CAP_POSIX_LOCKS: filesystem supports "remote" locking
|
||||||
|
|
@ -88,29 +108,23 @@ struct fuse_file_info_t
|
||||||
* FUSE_CAP_IOCTL_DIR: ioctl support on directories
|
* FUSE_CAP_IOCTL_DIR: ioctl support on directories
|
||||||
* FUSE_CAP_CACHE_SYMLINKS: cache READLINK responses
|
* FUSE_CAP_CACHE_SYMLINKS: cache READLINK responses
|
||||||
*/
|
*/
|
||||||
#define FUSE_CAP_ASYNC_READ (1ULL << 0)
|
#define FUSE_CAP_ASYNC_READ (1 << 0)
|
||||||
#define FUSE_CAP_POSIX_LOCKS (1ULL << 1)
|
#define FUSE_CAP_POSIX_LOCKS (1 << 1)
|
||||||
#define FUSE_CAP_ATOMIC_O_TRUNC (1ULL << 3)
|
#define FUSE_CAP_ATOMIC_O_TRUNC (1 << 3)
|
||||||
#define FUSE_CAP_EXPORT_SUPPORT (1ULL << 4)
|
#define FUSE_CAP_EXPORT_SUPPORT (1 << 4)
|
||||||
#define FUSE_CAP_BIG_WRITES (1ULL << 5)
|
#define FUSE_CAP_BIG_WRITES (1 << 5)
|
||||||
#define FUSE_CAP_DONT_MASK (1ULL << 6)
|
#define FUSE_CAP_DONT_MASK (1 << 6)
|
||||||
#define FUSE_CAP_FLOCK_LOCKS (1ULL << 10)
|
#define FUSE_CAP_FLOCK_LOCKS (1 << 10)
|
||||||
#define FUSE_CAP_IOCTL_DIR (1ULL << 11)
|
#define FUSE_CAP_IOCTL_DIR (1 << 11)
|
||||||
#define FUSE_CAP_READDIR_PLUS (1ULL << 13)
|
#define FUSE_CAP_READDIR_PLUS (1 << 13)
|
||||||
#define FUSE_CAP_READDIR_PLUS_AUTO (1ULL << 14)
|
#define FUSE_CAP_READDIR_PLUS_AUTO (1 << 14)
|
||||||
#define FUSE_CAP_ASYNC_DIO (1ULL << 15)
|
#define FUSE_CAP_ASYNC_DIO (1 << 15)
|
||||||
#define FUSE_CAP_WRITEBACK_CACHE (1ULL << 16)
|
#define FUSE_CAP_WRITEBACK_CACHE (1 << 16)
|
||||||
#define FUSE_CAP_PARALLEL_DIROPS (1ULL << 18)
|
#define FUSE_CAP_PARALLEL_DIROPS (1 << 18)
|
||||||
#define FUSE_CAP_POSIX_ACL (1ULL << 19)
|
#define FUSE_CAP_POSIX_ACL (1 << 19)
|
||||||
#define FUSE_CAP_CACHE_SYMLINKS (1ULL << 20)
|
#define FUSE_CAP_CACHE_SYMLINKS (1 << 20)
|
||||||
#define FUSE_CAP_MAX_PAGES (1ULL << 21)
|
#define FUSE_CAP_MAX_PAGES (1 << 21)
|
||||||
#define FUSE_CAP_SETXATTR_EXT (1ULL << 22)
|
#define FUSE_CAP_SETXATTR_EXT (1 << 22)
|
||||||
#define FUSE_CAP_DIRECT_IO_ALLOW_MMAP (1ULL << 23)
|
|
||||||
#define FUSE_CAP_CREATE_SUPP_GROUP (1ULL << 24)
|
|
||||||
#define FUSE_CAP_PASSTHROUGH (1ULL << 25)
|
|
||||||
#define FUSE_CAP_HANDLE_KILLPRIV (1ULL << 26)
|
|
||||||
#define FUSE_CAP_HANDLE_KILLPRIV_V2 (1ULL << 27)
|
|
||||||
#define FUSE_CAP_ALLOW_IDMAP (1ULL << 28)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ioctl flags
|
* Ioctl flags
|
||||||
|
|
@ -129,30 +143,90 @@ struct fuse_file_info_t
|
||||||
|
|
||||||
#define FUSE_IOCTL_MAX_IOV 256
|
#define FUSE_IOCTL_MAX_IOV 256
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connection information, passed to the ->init() method
|
||||||
|
*
|
||||||
|
* Some of the elements are read-write, these can be changed to
|
||||||
|
* indicate the value requested by the filesystem. The requested
|
||||||
|
* value must usually be smaller than the indicated value.
|
||||||
|
*/
|
||||||
|
struct fuse_conn_info {
|
||||||
|
/**
|
||||||
|
* Major version of the protocol (read-only)
|
||||||
|
*/
|
||||||
|
unsigned proto_major;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minor version of the protocol (read-only)
|
||||||
|
*/
|
||||||
|
unsigned proto_minor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum size of the write buffer
|
||||||
|
*/
|
||||||
|
unsigned max_write;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum readahead
|
||||||
|
*/
|
||||||
|
unsigned max_readahead;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Capability flags, that the kernel supports
|
||||||
|
*/
|
||||||
|
unsigned capable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Capability flags, that the filesystem wants to enable
|
||||||
|
*/
|
||||||
|
unsigned want;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum number of backgrounded requests
|
||||||
|
*/
|
||||||
|
unsigned max_background;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kernel congestion threshold parameter
|
||||||
|
*/
|
||||||
|
unsigned congestion_threshold;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Max pages
|
||||||
|
*/
|
||||||
|
uint16_t max_pages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For future use.
|
||||||
|
*/
|
||||||
|
unsigned reserved[22];
|
||||||
|
};
|
||||||
|
|
||||||
struct fuse_session;
|
struct fuse_session;
|
||||||
struct fuse_chan;
|
struct fuse_chan;
|
||||||
struct fuse_pollhandle_t;
|
struct fuse_pollhandle_t;
|
||||||
typedef struct fuse_pollhandle_t fuse_pollhandle_t;
|
typedef struct fuse_pollhandle_t fuse_pollhandle_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mount a FUSE filesystem.
|
* Create a FUSE mountpoint
|
||||||
*
|
*
|
||||||
* This function creates a FUSE mount and returns the /dev/fuse file descriptor.
|
* Returns a control file descriptor suitable for passing to
|
||||||
* The file descriptor is stored in the session for internal use.
|
* fuse_new()
|
||||||
*
|
*
|
||||||
* @param mountpoint the mount point path
|
* @param mountpoint the mount point path
|
||||||
* @param args argument vector
|
* @param args argument vector
|
||||||
* @return the /dev/fuse file descriptor on success, -1 on failure
|
* @return the communication channel on success, NULL on failure
|
||||||
*/
|
*/
|
||||||
int fuse_mount(const char *mountpoint, struct fuse_args *args);
|
struct fuse_chan *fuse_mount(const char *mountpoint,
|
||||||
|
struct fuse_args *args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Umount a FUSE mountpoint
|
* Umount a FUSE mountpoint
|
||||||
*
|
*
|
||||||
* @param mountpoint the mount point path
|
* @param mountpoint the mount point path
|
||||||
* @param fd the /dev/fuse file descriptor (or -1 if already closed)
|
* @param ch the communication channel
|
||||||
*/
|
*/
|
||||||
void fuse_unmount(const char *mountpoint, int fd);
|
void fuse_unmount(const char *mountpoint, struct fuse_chan *ch);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse common options
|
* Parse common options
|
||||||
|
|
@ -315,6 +389,70 @@ struct fuse_buf {
|
||||||
off_t pos;
|
off_t pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data buffer vector
|
||||||
|
*
|
||||||
|
* An array of data buffers, each containing a memory pointer or a
|
||||||
|
* file descriptor.
|
||||||
|
*
|
||||||
|
* Allocate dynamically to add more than one buffer.
|
||||||
|
*/
|
||||||
|
struct fuse_bufvec {
|
||||||
|
/**
|
||||||
|
* Number of buffers in the array
|
||||||
|
*/
|
||||||
|
size_t count;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Index of current buffer within the array
|
||||||
|
*/
|
||||||
|
size_t idx;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current offset within the current buffer
|
||||||
|
*/
|
||||||
|
size_t off;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of buffers
|
||||||
|
*/
|
||||||
|
struct fuse_buf buf[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Initialize bufvec with a single buffer of given size */
|
||||||
|
#define FUSE_BUFVEC_INIT(size__) \
|
||||||
|
((struct fuse_bufvec) { \
|
||||||
|
/* .count= */ 1, \
|
||||||
|
/* .idx = */ 0, \
|
||||||
|
/* .off = */ 0, \
|
||||||
|
/* .buf = */ { /* [0] = */ { \
|
||||||
|
/* .size = */ (size__), \
|
||||||
|
/* .flags = */ (enum fuse_buf_flags) 0, \
|
||||||
|
/* .mem = */ NULL, \
|
||||||
|
/* .fd = */ -1, \
|
||||||
|
/* .pos = */ 0, \
|
||||||
|
} } \
|
||||||
|
} )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get total size of data in a fuse buffer vector
|
||||||
|
*
|
||||||
|
* @param bufv buffer vector
|
||||||
|
* @return size of data
|
||||||
|
*/
|
||||||
|
size_t fuse_buf_size(const struct fuse_bufvec *bufv);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy data from one buffer vector to another
|
||||||
|
*
|
||||||
|
* @param dst destination buffer vector
|
||||||
|
* @param src source buffer vector
|
||||||
|
* @param flags flags controlling the copy
|
||||||
|
* @return actual number of bytes copied or -errno on error
|
||||||
|
*/
|
||||||
|
ssize_t fuse_buf_copy(struct fuse_bufvec *dst, struct fuse_bufvec *src,
|
||||||
|
enum fuse_buf_copy_flags flags);
|
||||||
|
|
||||||
/* ----------------------------------------------------------- *
|
/* ----------------------------------------------------------- *
|
||||||
* Signal handling *
|
* Signal handling *
|
||||||
* ----------------------------------------------------------- */
|
* ----------------------------------------------------------- */
|
||||||
|
|
@ -341,3 +479,5 @@ int fuse_set_signal_handlers(struct fuse_session *se);
|
||||||
void fuse_remove_signal_handlers(struct fuse_session *se);
|
void fuse_remove_signal_handlers(struct fuse_session *se);
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
|
#endif /* _FUSE_COMMON_H_ */
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
ISC License
|
ISC License
|
||||||
|
|
||||||
Copyright (c) 2026, Antonio SJ Musumeci <trapexit@spawn.link>
|
Copyright (c) 2023, Antonio SJ Musumeci <trapexit@spawn.link>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
|
@ -16,32 +16,16 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config_log_file.hpp"
|
#pragma once
|
||||||
|
|
||||||
#include "debug.hpp"
|
|
||||||
#include "fuse_cfg.hpp"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
LogFile::LogFile(const std::string &s_)
|
int fuse_config_get_read_thread_count();
|
||||||
{
|
int fuse_config_get_process_thread_count();
|
||||||
if(!s_.empty())
|
int fuse_config_get_process_thread_queue_depth();
|
||||||
fuse_debug_set_output(s_);
|
std::string fuse_config_get_pin_threads();
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
void fuse_config_set_read_thread_count(int const);
|
||||||
LogFile::to_string(void) const
|
void fuse_config_set_process_thread_count(int const);
|
||||||
{
|
void fuse_config_set_process_thread_queue_depth(int const);
|
||||||
auto filepath = fuse_cfg.log_filepath();
|
void fuse_config_set_pin_threads(std::string const);
|
||||||
|
|
||||||
return (filepath ? *filepath : "");
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
LogFile::from_string(const std::string_view s_)
|
|
||||||
{
|
|
||||||
const std::string s{s_};
|
|
||||||
|
|
||||||
return fuse_debug_set_output(s);
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue