#!/usr/bin/env python3 import ctypes import errno import fcntl import os import struct import sys import tempfile from posix_parity import cleanup_dir from posix_parity import compare_calls from posix_parity import fail from posix_parity import join from posix_parity import mergerfs_mount from posix_parity import temp_dir from posix_parity import touch FIBMAP = 1 def fibmap(fd, block=0): buf = struct.pack("i", block) out = fcntl.ioctl(fd, FIBMAP, buf) return struct.unpack("i", out)[0] def main(): try: with mergerfs_mount() as (mount, _): with tempfile.TemporaryDirectory() as native: merge_base = temp_dir(mount) try: native_base = join(native, os.path.basename(merge_base)) os.makedirs(native_base, exist_ok=True) merge_file = join(merge_base, "file") native_file = join(native_base, "file") touch(merge_file, b"x" * 8192) touch(native_file, b"x" * 8192) mfd = os.open(merge_file, os.O_RDONLY) nfd = os.open(native_file, os.O_RDONLY) try: err = compare_calls( "ioctl FIBMAP block0", lambda: fibmap(mfd, 0), lambda: fibmap(nfd, 0), lambda a, b: (a >= 0) == (b >= 0), ) if err: return fail(err) finally: os.close(mfd) os.close(nfd) err = compare_calls( "ioctl FIBMAP EBADF", lambda: fibmap(mfd, 0), lambda: fibmap(nfd, 0), ) if err: return fail(err) return 0 finally: cleanup_dir(merge_base) except RuntimeError as exc: print(str(exc), end="") return 77 if __name__ == "__main__": raise SystemExit(main())