Name
psync — run sync(1) with live write-back progress, a completion summary, and optional follow mode
Synopsis
psync [-d] [-f] [-i interval] [-F] [-w] [--debounce dur] [--min-interval dur] [FILE...] psync demo [--duration dur] [--size-mb n]
Description
sync(1) flushes every dirty page in the kernel's page cache to disk,
blocking until it's done — with no indication of how much data is left or how
fast it's draining. psync starts sync(1) in the background and polls
Dirty/Writeback from /proc/meminfo while it
runs, printing a live progress line and a summary once the flush completes.
On fast local disks a real flush is often too quick to watch — the kernel starts
flushing dirty pages in the background well before sync(1) is even called,
once vm.dirty_background_ratio is crossed. Run psync demo to
see the display in action without needing slow media, root, or leftover files.
Options
- -i, --interval duration
- Polling interval for /proc/meminfo. Default 500ms.
- -d, --data
- Sync only file data, no unneeded metadata (passed through to sync(1)).
- -f, --file-system
- Sync the file systems that contain the given FILEs, instead of just the files.
- -F, --follow
- Stay running: after each sync, watch FILEs and resync whenever they change again. See FOLLOW MODE below.
- -w, --watch
- Watch write-back progress without calling sync.
- --debounce duration
- Follow mode: quiet window after a change before resyncing. Default 500ms.
- --min-interval duration
- Follow mode: minimum time between resyncs, independent of event volume. Default 1s.
Follow mode (-F)
-F keeps psync running: after each sync it watches the given FILEs (or a directory's direct entries — non-recursive) via inotify(7), and resyncs whenever they change again, until interrupted.
Follow mode always needs a scoped target. There is deliberately no target-less
"watch everything" mode: /proc/meminfo's Dirty counter is
system-wide, so triggering resyncs off it would fire on unrelated writes from any
process — the opposite of what was asked for, and needless extra write cycles on
the underlying media. If psync -F is run with no target, it lists real
mounted filesystems (from /proc/self/mountinfo) and prompts for one,
which becomes an implicit -f target.
Two independent guards keep repeated syncing safe rather than trigger-happy: --debounce coalesces a burst of writes into a single resync, and --min-interval enforces a hard floor between syncs regardless of how often changes arrive.
Commands
- demo [--duration dur] [--size-mb n]
- Watch a simulated flush — a synthetic, deterministic drain instead of a real sync(1) call. No real disk I/O, no root, no leftover files. Default: ~2GB over 8s.
Examples
$ psync dirty 21.9 MiB, writeback 0 B (0s elapsed, -- left) sync complete duration: 142ms ... $ psync -f /mnt/secure # sync only the file system containing this path $ psync -F important-file.db # sync, then keep watching and resync on changes $ psync -F # no target: pick a mounted filesystem to watch $ psync demo --duration 15s --size-mb 4096 # try the live display without touching a real disk
How it works
Key components live in Go packages under internal/:
- meminfo
- reads Dirty/Writeback from /proc/meminfo; defines the Reader type real and simulated sources satisfy.
- monitor
- polls a Reader on an interval, tracking the peak unflushed total.
- simulate
- synthetic Reader that decays a given size to zero over a given duration — backs
demoand monitor's tests. - watch
- raw inotify wrapper reporting changes to a fixed set of files/directories — the resync trigger for follow mode.
- pick
- lists real mounted filesystems and prompts for one — backs bare
psync -F. - app
- orchestration: runs sync(1), drives the monitor, formats output, runs the follow loop.
Installation
# via go install $ go install codeberg.org/ubunatic/psync@latest # or from source $ git clone https://codeberg.org/ubunatic/psync $ cd psync $ make install
See also
sync(1), fsync(2), inotify(7), proc(5)
Author
Uwe Jugel <uwe@ubunatic.com>