A CLI is not an API. Driving storage by running losetup, dmsetup, btrfs(8) or zfs and reading what they print means parsing a human-readable format that was never promised to you, in a subprocess that may not be installed. Every module here opens the control device and issues the subsystem's ioctls โ the same call the reference tool makes. Pure Go, CGO_ENABLED=0. BSD-3-Clause.
# clone a 512 MiB image on APFS $ go run ./clonedemo cloned 512 MiB in 381ยตs clone.img is 512 MiB and independent # du counts it twice โ it cannot see shared blocks $ du -sh . 1.0G # the filesystem gave up nothing $ df -k . # before and after delta: 0 MiB for a 512 MiB clone
Every module talks to the kernel the way the reference CLI does โ by opening a control device and issuing the subsystem's ioctls. What that removes is not just a dependency; it is a parser for output nobody promised to keep stable.
No losetup, dmsetup, btrfs(8) or libzfs to install, and no output format to re-learn when it changes. A missing binary cannot break a program that never ran one.
Each is its own Go module with no dependency on the others and none but golang.org/x/sys. Take loop without taking a filesystem stack.
CGO_ENABLED=0No C toolchain, so cross-compiling is the ordinary Go story and a static binary stays static. The kernel interface is a syscall, which Go can make by itself.
6 of 7 modules fail CI under 100% โ a floor the workflow enforces rather than a number in a badge. blk is the exception: vet, tests, the race detector and cross-builds, without a coverage gate.
The ioctl modules are Linux, as their subsystems are. cowclone also speaks APFS clonefile(2) on macOS and falls back to a byte copy anywhere else, so one call works wherever the program runs.
The integration tests drive real kernel objects โ /dev/loop-control, a device-mapper target โ and skip when the device is absent or the process is not root, rather than passing against a mock. A green run on a machine without them is honest about what it did not prove.
loop libLoop devices via /dev/loop-control and LOOP_* ioctls โ attach, detach, query status and resize backing files. No losetup, no cgo.
linux
dm libDevice-mapper via /dev/mapper/control and DM_* ioctls โ linear, striped, crypt, thin and verity targets with scrub-style status. No dmsetup.
linux
btrfs libbtrfs via BTRFS_IOC_* ioctls on directory fds โ subvolumes, snapshots, scrub, balance, qgroups and send. No btrfs(8).
linux
zfs libOpenZFS via /dev/zfs and ZFS_IOC_* ioctls โ pools, datasets, encryption, send/recv and clone. No libzfs, no cgo.
linux
blk libBlock devices via BLKGETSIZE64, BLKDISCARD, BLKZEROOUT, BLKPG and the rest โ size, block and I/O geometry, discard, and adding or removing partitions without re-reading the table.
linux ยท no coverage gate
cowclone libCopy-on-write file cloning via APFS clonefile(2) and Linux FICLONE reflink (btrfs, XFS, OpenZFS 2.2+), with a transparent byte-copy fallback everywhere else. No cgo.
linux, darwin, and a byte-copy fallback everywhere else
projquota libPure-Go Linux project quotas for XFS and ext4: give a directory tree a project id, limit its space and inodes, and read its usage, straight through the kernel โ FS_IOC_FSGETXATTR / FS_IOC_FSSETXATTR and quotactl_fd(2) โ with no cgo and no shelling out to xfs_quota, setquota or chattr.
linux
No cgo, no C toolchain, no CLI to install, nothing but golang.org/x/sys. Each module is the kernel's own interface, in Go, and usable without the other 6.