%global crate foxing %global version 0.10.0 Name: foxing Version: %{version} Release: 3%{?dist} Summary: eBPF-powered filesystem replication daemon and smart copy tool License: GPL-2.0-or-later URL: https://codeberg.org/aenertia/foxing Source0: %{url}/archive/v%{version}.tar.gz#/%{crate}-%{version}.tar.gz Source1: %{crate}-%{version}-vendor.tar.gz BuildRequires: clang BuildRequires: llvm BuildRequires: elfutils-libelf-devel BuildRequires: openssl-devel BuildRequires: zlib-devel BuildRequires: systemd-rpm-macros BuildRequires: dbus-devel BuildRequires: curl BuildRequires: selinux-policy-devel BuildRequires: policycoreutils # Rust nightly installed via rustup during %%build # foxingd requires BPF toolchain — only available on architectures with # mature kernel BTF and libbpf BPF_KPROBE register definitions. # riscv64 builds fxcp only (no foxingd). %ifarch riscv64 %global build_foxingd 0 %else %global build_foxingd 1 BuildRequires: libbpf-devel BuildRequires: bpftool %endif ExclusiveArch: x86_64 aarch64 ppc64le s390x riscv64 # Disable debuginfo/debugsource — binaries are stripped by cargo %global debug_package %{nil} %description Foxing is an eBPF-powered filesystem replication system. It provides foxingd, a BPF-based replication daemon, and fxcp, a smart filesystem copy tool with CoW/reflink and io_uring support. # ---- Subpackage: fxcp ---- %package -n fxcp Summary: Smart filesystem copy tool with CoW/reflink support Requires: glibc %description -n fxcp fxcp is a smart filesystem copy tool — an rsync replacement with CoW/reflink, io_uring, BLAKE3 delta detection, and adaptive tuning. Does not require root or BPF. # ---- Subpackage: foxingd (not built on riscv64) ---- %if %{build_foxingd} %package -n foxingd Summary: eBPF filesystem replication daemon Conflicts: fxcp Requires: openssl-libs Requires: elfutils-libelf Requires: zlib Requires: libzstd Requires: libbpf Requires: bpftool Requires(pre): systemd Requires(post): systemd Requires(preun): systemd Requires(postun): systemd Requires(post): policycoreutils Requires(postun): policycoreutils %description -n foxingd foxingd is an eBPF-powered filesystem replication daemon that watches filesystem events via BPF kprobes and replicates changes to one or more targets with adaptive tuning, versioning, and Prometheus metrics. foxingd is a superset of fxcp — it provides fxcp via symlink dispatch. Requires Linux kernel 6.12+ with BTF support. %endif %prep %autosetup -n %{crate}-%{version} -p1 tar xf %{SOURCE1} # Vendor tarball extracts as foxing-vendor/ but cargo config expects vendor/ if [ -d foxing-vendor ] && [ ! -d vendor ]; then mv foxing-vendor vendor fi mkdir -p .cargo cat > .cargo/config.toml << 'EOF' [source.crates-io] replace-with = "vendored-sources" [source.vendored-sources] directory = "vendor" EOF # Disable numkong SME + FP8 probes on aarch64. # numkong 7.6.0 has an upstream bug: SME dispatch code uses SVE intrinsics # without per-function target("sve") attributes. This breaks on GCC 16 # (Fedora 44+) which is stricter about ISA requirements, and raising the # base -march breaks always_inline cross-target inlining (a different GCC # bug). Until upstream adds proper target attributes, disable SME probes # so NK_TARGET_SME*=0 and SME code paths are not compiled. # NEON + SVE + SVE2 paths are fully preserved — only SME is affected. # Cloud aarch64 (Graviton 4, Axion) still gets SVE2 vector search perf. %ifarch aarch64 sed -i 's/armv8-a+sme/armv8-a+FOXING_DISABLED_SME/g' vendor/numkong/build.rs sed -i 's/armv8-a+simd+fp8dot4/armv8-a+FOXING_DISABLED_FP8/g' vendor/numkong/build.rs sed -i 's/"files":{[^}]*}/"files":{}/' vendor/numkong/.cargo-checksum.json %endif # Disable numkong RVV probes on riscv64. # Same upstream bug as aarch64: RVV probes pass but dispatch files compiled # with -march=rv64gc (no V extension) include rvv.h intrinsics that GCC # rejects. usearch falls back to scalar — functional, no vector acceleration. %ifarch riscv64 sed -i 's/rv64gcv/rv64gc_FOXING_DISABLED_RVV/g' vendor/numkong/build.rs sed -i 's/"files":{[^}]*}/"files":{}/' vendor/numkong/.cargo-checksum.json %endif %build export RUSTUP_HOME=%{_builddir}/.rustup export CARGO_HOME=%{_builddir}/.cargo-home curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \ sh -s -- -y --default-toolchain nightly --profile minimal --no-modify-path export PATH="$CARGO_HOME/bin:$PATH" rustup component add rustfmt # Override Fedora RUSTFLAGS which set -Cstrip=none and specs that # may not be compatible with nightly Rust FOXING_RUSTFLAGS="-Copt-level=3 -Cforce-frame-pointers=yes" # io-uring prebuilt bindings are x86_64/aarch64/riscv64 only; on s390x/ppc64le # the struct layouts are identical (io_uring is arch-independent), so # skip the arch check rather than using bindgen (which needs newer headers) %ifarch s390x ppc64le FOXING_RUSTFLAGS="$FOXING_RUSTFLAGS --cfg=io_uring_skip_arch_check" %endif export RUSTFLAGS="$FOXING_RUSTFLAGS" # fxcp feature set is arch-dependent: # - all-ai includes ort-backend which requires ONNX Runtime prebuilt binaries # (available for x86_64, aarch64 only; missing on riscv64, ppc64le, s390x) # - riscv64/ppc64le/s390x get AI features that don't depend on ORT %ifarch x86_64 aarch64 cargo build --release -p fxcp --features all-ai,nfs-bypass --offline %else cargo build --release -p fxcp --features nfs-bypass,enrichment,media-metadata,docling,pgvector --offline %endif %if %{build_foxingd} cargo build --release -p foxingd --offline %endif # Compile SELinux policy module %if %{build_foxingd} make -C dist/selinux -f /usr/share/selinux/devel/Makefile foxingd.pp %endif # Generate man pages and shell completions # Skip on riscv64: xtask compilation under QEMU adds ~60min to an already # 276min build, pushing past the COPR 5-hour timeout. Man pages and # completions are arch-independent text — riscv64 users can generate # from source via `cargo run -p xtask -- all`. %ifnarch riscv64 cargo run -p xtask --offline -- all %endif %install # fxcp (all architectures) install -Dpm 755 target/release/fxcp %{buildroot}%{_bindir}/fxcp # Man pages and completions (not available on riscv64 — xtask skipped) %ifnarch riscv64 install -Dpm 644 dist/man/fxcp.1 %{buildroot}%{_mandir}/man1/fxcp.1 install -Dpm 644 dist/completions/fxcp.bash %{buildroot}%{_datadir}/bash-completion/completions/fxcp install -Dpm 644 dist/completions/fxcp.zsh %{buildroot}%{_datadir}/zsh/site-functions/_fxcp install -Dpm 644 dist/completions/fxcp.fish %{buildroot}%{_datadir}/fish/vendor_completions.d/fxcp.fish %endif # foxingd (not on riscv64) %if %{build_foxingd} install -Dpm 755 target/release/foxingd %{buildroot}%{_bindir}/foxingd install -Dpm 644 config.toml.example %{buildroot}%{_sysconfdir}/foxing/config.toml.example install -Dpm 644 dist/systemd/foxingd.service %{buildroot}%{_unitdir}/foxingd.service install -Dpm 644 dist/systemd/foxingd-sysusers.conf %{buildroot}%{_sysusersdir}/foxingd.conf install -Dpm 644 dist/systemd/foxingd-tmpfiles.conf %{buildroot}%{_tmpfilesdir}/foxingd.conf # D-Bus policy for Stratis integration install -Dpm 644 dist/foxing-replication.conf %{buildroot}%{_sysconfdir}/dbus-1/system.d/foxing-replication.conf # sysctl: enable io_uring (RHEL 10 disables it by default) install -Dpm 644 dist/sysctl/foxingd-iouring.conf %{buildroot}%{_sysctldir}/99-foxingd-iouring.conf # OCF resource agent for Pacemaker integration install -Dpm 755 dist/pacemaker/foxingd-replica %{buildroot}%{_prefix}/lib/ocf/resource.d/foxing/foxingd-replica # Prometheus alerting rules install -Dpm 644 dist/prometheus/foxingd-alerts.yml %{buildroot}%{_datadir}/foxing/prometheus/foxingd-alerts.yml # Install SELinux policy module install -d %{buildroot}%{_datadir}/selinux/targeted install -m 644 dist/selinux/foxingd.pp %{buildroot}%{_datadir}/selinux/targeted/foxingd.pp install -Dpm 644 dist/man/foxingd.1 %{buildroot}%{_mandir}/man1/foxingd.1 install -Dpm 644 dist/completions/foxingd.bash %{buildroot}%{_datadir}/bash-completion/completions/foxingd install -Dpm 644 dist/completions/foxingd.zsh %{buildroot}%{_datadir}/zsh/site-functions/_foxingd install -Dpm 644 dist/completions/foxingd.fish %{buildroot}%{_datadir}/fish/vendor_completions.d/foxingd.fish %endif %files -n fxcp %license LICENSE %doc README.md %{_bindir}/fxcp %ifnarch riscv64 %{_mandir}/man1/fxcp.1* %{_datadir}/bash-completion/completions/fxcp %{_datadir}/zsh/site-functions/_fxcp %{_datadir}/fish/vendor_completions.d/fxcp.fish %endif %if %{build_foxingd} %pre -n foxingd %sysusers_create_compat dist/systemd/foxingd-sysusers.conf %post -n foxingd %systemd_post foxingd.service %tmpfiles_create foxingd.conf # Enable io_uring (RHEL 10 disables it by default, foxingd requires it) %sysctl_apply 99-foxingd-iouring.conf # Create fxcp symlink (foxingd is a superset) ln -sf foxingd %{_bindir}/fxcp 2>/dev/null || : # Install SELinux policy module if [ -f %{_datadir}/selinux/targeted/foxingd.pp ]; then semodule -i %{_datadir}/selinux/targeted/foxingd.pp 2>/dev/null || : fi %preun -n foxingd %systemd_preun foxingd.service # Remove fxcp symlink if it points to foxingd if [ "$(readlink %{_bindir}/fxcp 2>/dev/null)" = "foxingd" ]; then rm -f %{_bindir}/fxcp fi %postun -n foxingd %systemd_postun_with_restart foxingd.service # Remove SELinux policy module on uninstall if [ $1 -eq 0 ]; then semodule -r foxingd 2>/dev/null || : fi %files -n foxingd %license LICENSE %doc README.md config.toml.example %{_bindir}/foxingd %ghost %{_bindir}/fxcp %dir %{_sysconfdir}/foxing %config(noreplace) %{_sysconfdir}/foxing/config.toml.example %{_unitdir}/foxingd.service %{_sysusersdir}/foxingd.conf %{_tmpfilesdir}/foxingd.conf %{_mandir}/man1/foxingd.1* %{_mandir}/man1/fxcp.1* %{_datadir}/bash-completion/completions/foxingd %{_datadir}/bash-completion/completions/fxcp %{_datadir}/zsh/site-functions/_foxingd %{_datadir}/zsh/site-functions/_fxcp %{_datadir}/fish/vendor_completions.d/foxingd.fish %{_datadir}/fish/vendor_completions.d/fxcp.fish %config(noreplace) %{_sysconfdir}/dbus-1/system.d/foxing-replication.conf %{_sysctldir}/99-foxingd-iouring.conf %dir %{_prefix}/lib/ocf/resource.d/foxing %{_prefix}/lib/ocf/resource.d/foxing/foxingd-replica %dir %{_datadir}/foxing %dir %{_datadir}/foxing/prometheus %{_datadir}/foxing/prometheus/foxingd-alerts.yml %{_datadir}/selinux/targeted/foxingd.pp %endif %changelog * Sun Aug 31 2026 Joel Wirāmu Pauling - 0.10.0-3 - Final stable release. TUI v0.10.0 parity (AI page, per-stage drops, EventBus), xtask mirror parity (9 new subcommands), release notes finalized, full benchmark validation on koero + fox-test. * Sat Aug 30 2026 Joel Wirāmu Pauling - 0.10.0-2 - RC1: clippy clean, domain-level lookup tables (filetypes v3.3.0), per-entry CollisionEntry scoring, TOML is_text fix, BPF amplification fix, source enrichment engine, DirectoryProfile domain-vote + parent inheritance, docs grounding sweep, semantic-data-recovery ADR, config.toml.example update - All tests pass: 1117 unit, 18/18 daemon, 19/19 adversarial on koero bare-metal * Sat Aug 02 2026 Joel Wirāmu Pauling - 0.10.0-1 - Development branch 0.10-dev (renamed from 0.9.6-dev due to breaking changes) * Wed Jul 30 2026 Joel Wiramu Pauling - 0.9.5-3 - rc3: bare-metal test campaign on koero NVMe XFS (all phases PASS) - New metadata preservation tests: SELinux context, owner/group, permission modes - Test harness: replace fragile sleep() with condition polling (3 locations) - REFERENCES.md: 30+ SOTA references (eBPF, io_uring, CDC, AI/ML, observability) - New MONITORING.md guide (PCP, Grafana, OTel Collector integration) - BENCHMARKS.md consolidated around rc3 bare-metal data, dev-era to appendices - AI pipeline benchmarks: indexing, search (usearch/pgvector), enrichment by effort - Documentation cleanup: stale claims corrected, test counts updated, env notes added * Sat May 17 2026 Joel Wiramu Pauling - 0.9.5-2 - Add riscv64 architecture support (fxcp only, foxingd requires eBPF) - Architecture-conditional feature flags: ort-backend on x86_64/aarch64 only - Disable numkong SME probes on aarch64 (GCC 16 compat, upstream bug) - Fix %prep directory name for Codeberg archive layout * Sat May 17 2026 Joel Wiramu Pauling - 0.9.5-1 - Release v0.9.5 * Thu May 01 2026 Joel Wirāmu Pauling - 0.9.5~rc1-1 - BPF CO-RE fentry/kprobe mutual exclusion for vfs_fsync - systemd journal best practices (tracing-journald, sd_notify lifecycle) - ENOSPC emergency pruning with correct .foxing_versions/live path - fxcp symlink replication with lchown - --delete preserves dangling symlinks and .foxing_* internal directories - 6 new adversarial tests (ENOSPC, mount-drop, --delete, symlinks, multi-target, ACL) - 737 unit tests, 8 test phases * Sun Apr 20 2026 Joel Wirāmu Pauling - 0.9.4~dev-3 - Tuner v2: workload-aware adaptive I/O (BBR+AIMD hybrid) - StorageClassification: 9-variant device profiling with per-class QD/batch ranges - SystemGovernor: fine-grained PSI+memory+CPU+IO backpressure - TuningBoardManager: cross-worker coordination via broadcast channel - WorkloadDetector: online I/O pattern classification driving parameter overlays - Config: storage_type_hint and latency_sla_us target settings - 15 bug fixes: io_uring OOB, FXAR/qcow2 bounds, Governor init, Mutex poison - 145 tests (was 88), zero performance regressions vs v0.9.3 * Tue Mar 17 2026 Joel Wirāmu Pauling - 0.9.4~dev-2 - OCF resource agent for Pacemaker HA integration (foxingd-replica) - Prometheus alerting rules (foxingd-alerts.yml) - HA failover documentation (Pacemaker + libvirt/KVM + Stratis) * Sun Mar 16 2026 Joel Wirāmu Pauling - 0.9.4~dev-1 - Stratis D-Bus integration (pool monitoring, snapshot management, fs-verity) - D-Bus service: org.foxing.Replica1 + org.foxing.Versioning1 - foxingd stratis CLI subcommand group (status, pool-info, checkpoint, snapshots, seal) - Worker-to-D-Bus replica state bridge (live replication status) - Governor pool-level capacity check via Stratis metrics - fs-verity snapshot sealing (mount → seal → unmount) - Fix resolve_stratis_target to accept mount paths - D-Bus policy file for org.foxing.replication - 84 tests, Stratis adversarial suite (32 PASS, 1 FAIL known baseline) - Stratis performance: -2% to -20% overhead vs plain XFS (faster) * Fri Mar 14 2026 Joel Wirāmu Pauling - 0.8.3-1 - CAS store: content-addressable chunk store for any filesystem - FXAR<->CAS interchange (import_fxar, export_fxar) - fxcp snap import --generate-sigs for foxingd-ready target seeding - Streaming pipe test + adversarial Phase 11 - Atomic FXAR export (.tmp + rename), FXAR parser fuzz targets - 77 tests total (11 new CAS/fxar/metadata tests) * Thu Mar 13 2026 Joel Wirāmu Pauling - 0.8.1-1 - FXAR v2: gear-hash variable chunking + BLAKE3 CAS + binary index - True chunk-level deduplication (replaces whole-file tar dedup) - Random-access seekable archive with selective file restore - Streaming pipe support (export | ssh import) - Auto-detect archive format (FXAR v2 / tar) - --format tar backward compatibility for legacy exports - 19 new tests (66 total) * Wed Mar 12 2026 Joel Wirāmu Pauling - 0.7.2-1 - fxcp snap browse: MC-style dual-pane TUI file/snapshot browser - BLAKE3 content dedup stats alongside CoW reflink savings - Unified MARS versioning path (.foxing_versions/live/) - TUI feature-gated behind ratatui optional dependency * Wed Mar 12 2026 Joel Wirāmu Pauling - 0.7.1-1 - fxcp snap: dirvish-style point-in-time snapshots with JSON index - fxcp snap prune: maintenance by age, count, and size - fxcp --snapshot: reflink versioning during copy - fxcp --throttle: PSI-based system stress pacing - Machine-readable --json output for web UI integration * Thu Mar 12 2026 Joel Wirāmu Pauling - 0.7.0-1 - fxcp: multi-source CLI (fxcp src1 src2 dest/) - fxcp: --include, --exclude-from, --include-from filtering - foxingd: hydration deletes stale target files on resync - foxingd: post-recovery full scan for unjournaled changes - Test harness fixes for metric snapshot collection * Wed Mar 11 2026 Joel Wirāmu Pauling - 0.6.1-1 - Expand architecture support: ppc64le, s390x, riscv64 - Fix aarch64 build: portable pointer types in btrfs ioctls - Add fxcp symlink in foxingd package - Add man pages, shell completions (bash/zsh/fish) - Stripped release builds with thin LTO * Tue Mar 10 2026 Joel Wirāmu Pauling - 0.6.0-1 - Initial package