systemd
PolicyFS is designed to be operated via systemd:
pfs@<mount>.serviceis the long-running daemon (FUSE mount).pfs-index@<mount>.timerruns indexing periodically.pfs-move@<mount>.timerruns mover periodically.pfs-prune@<mount>.timerruns prune periodically.pfs-maint@<mount>.timerruns a batched maintenance flow.
Timer schedules
The Debian package ships these default schedules:
| Unit | Schedule | Notes |
|---|---|---|
pfs-move@<mount>.timer |
OnCalendar=*-*-* 00:30:00 |
RandomizedDelaySec=5m, Persistent=true |
pfs-maint@<mount>.timer |
OnCalendar=*-*-* 00:30:00 |
RandomizedDelaySec=10m, Persistent=true |
pfs-prune@<mount>.timer |
OnCalendar=*-*-* 04:15:00 |
RandomizedDelaySec=10m, Persistent=true |
pfs-index@<mount>.timer |
OnCalendar=*-*-* 05:30:00 |
RandomizedDelaySec=2m, Persistent=true |
You typically enable either:
- The maint timer (
pfs-maint) if you want one schedule and a single maintenance window. It runs a batched flow. - Individual timers (
pfs-index,pfs-move,pfs-prune) if you want to stagger work across the day or tune each phase separately.
I recommend starting with pfs-maint unless you have a reason to separate the phases.
Avoid enabling pfs-maint@<mount>.timer at the same time as the individual timers.
Inspect timer settings
Show the effective unit (including drop-ins):
sudo systemctl cat [email protected]
List next runs:
systemctl list-timers 'pfs-*@media.timer'
Directory layout
PolicyFS uses standard Linux locations:
- Config:
/etc/pfs/pfs.yaml - State:
/var/lib/pfs/<mount>/ - Runtime:
/run/pfs/<mount>/ - Logs: journald by default; optional file logging can be enabled via config.
Check job output
View the last run of a maintenance job:
journalctl -u [email protected] -n 50
Example output:
Mar 22 00:30:12 host pfs[1234]: move: moved 3 files (2.1 GB) from ssd1 → hdd1
Mar 22 00:30:15 host pfs[1234]: prune: applied 7 events (4 deletes, 3 renames)
Mar 22 00:30:18 host pfs[1234]: index: indexed 12483 files across hdd1, hdd2
Exit code 3 means the job ran but found nothing to do - this is normal when disks are not above the threshold or there are no deferred events.
Common operations
Start/restart a mount:
sudo systemctl restart [email protected]
Disable all scheduled jobs for a mount:
sudo systemctl disable --now [email protected]
sudo systemctl disable --now [email protected]
sudo systemctl disable --now [email protected]
sudo systemctl disable --now [email protected]
Package upgrades
Debian and Ubuntu package upgrades preserve existing pfs@<mount>.service and timer enablement.
During an upgrade, the package snapshots previously enabled mount services and timers before dpkg runs the old cleanup hooks, reloads systemd after unpack, and then restores those specific units. Aborted install or upgrade paths discard that transient snapshot instead of replaying it later.
That means a mount such as [email protected] and any enabled maintenance timers come back after the package upgrade without needing a manual systemctl enable pass.
Packaged unit files live in the distro-managed vendor unit directory; keep local changes in /etc/systemd/system/*.d/ drop-ins rather than editing vendor files in place.
Newer Debian and Ubuntu packages also migrate legacy packaged copies under /etc/systemd/system/pfs* back to the vendor unit directory and rewrite stale wants links, while leaving drop-ins under *.d/ alone.
Package removal and purge also clean up PolicyFS wants links so reinstall does not silently resurrect old enablement.
Overrides
Use drop-ins instead of editing vendor unit files:
sudo systemctl edit [email protected]
To change a timer schedule, edit the timer unit:
sudo systemctl edit [email protected]
Example override:
[Timer]
OnCalendar=
OnCalendar=*-*-* 03:00:00
RandomizedDelaySec=0
Then reload and restart the timer:
sudo systemctl daemon-reload
sudo systemctl restart [email protected]